@Override public final BaseResponse<?> handle( JsonPath jsonPath, RequestParams requestParams, RequestBody requestBody) throws Exception { String resourceName = jsonPath.getResourceName(); PathIds resourceIds = jsonPath.getIds(); RegistryEntry registryEntry = resourceRegistry.getEntry(resourceName); if (registryEntry == null) { throw new ResourceNotFoundException(resourceName); } if (requestBody == null) { throw new RequestBodyNotFoundException(HttpMethod.POST, resourceName); } Serializable castedResourceId = getResourceId(resourceIds, registryEntry); ResourceField relationshipField = registryEntry .getResourceInformation() .findRelationshipFieldByName(jsonPath.getElementName()); if (relationshipField == null) { throw new ResourceFieldNotFoundException(jsonPath.getElementName()); } ResourceRepository resourceRepository = registryEntry.getResourceRepository(); @SuppressWarnings("unchecked") Object resource = resourceRepository.findOne(castedResourceId, requestParams); Class<?> baseRelationshipFieldClass = relationshipField.getType(); Class<?> relationshipFieldClass = Generics.getResourceClass(relationshipField.getGenericType(), baseRelationshipFieldClass); @SuppressWarnings("unchecked") Class<? extends Serializable> relationshipIdType = (Class<? extends Serializable>) resourceRegistry .getEntry(relationshipFieldClass) .getResourceInformation() .getIdField() .getType(); RelationshipRepository relationshipRepositoryForClass = registryEntry.getRelationshipRepositoryForClass(relationshipFieldClass); if (Iterable.class.isAssignableFrom(baseRelationshipFieldClass)) { if (!requestBody.isMultiple()) { throw new RequestBodyException(HttpMethod.POST, resourceName, "Non-multiple data in body"); } Iterable<DataBody> dataBodies = requestBody.getMultipleData(); processToManyRelationship( resource, relationshipIdType, jsonPath.getElementName(), dataBodies, relationshipRepositoryForClass); } else { if (requestBody.isMultiple()) { throw new RequestBodyException(HttpMethod.POST, resourceName, "Multiple data in body"); } DataBody dataBody = requestBody.getSingleData(); processToOneRelationship( resource, relationshipIdType, jsonPath.getElementName(), dataBody, relationshipRepositoryForClass); } MetaInformation metaInformation = getMetaInformation(resourceRepository, Collections.singletonList(resource), requestParams); return new ResourceResponse(metaInformation); }
@Test public void onExistingToOneRelationshipShouldRemoveIt() throws Exception { // GIVEN RequestBody newTaskBody = new RequestBody(); DataBody data = new DataBody(); newTaskBody.setData(data); data.setType("tasks"); data.setAttributes(OBJECT_MAPPER.createObjectNode().put("name", "sample task")); data.setRelationships(new ResourceRelationships()); JsonPath taskPath = pathBuilder.buildPath("/tasks"); ResourcePost resourcePost = new ResourcePost(resourceRegistry, typeParser, OBJECT_MAPPER); // WHEN -- adding a task BaseResponseContext taskResponse = resourcePost.handle(taskPath, new QueryParams(), null, newTaskBody); // THEN assertThat(taskResponse.getResponse().getEntity()).isExactlyInstanceOf(Task.class); Long taskId = ((Task) (taskResponse.getResponse().getEntity())).getId(); assertThat(taskId).isNotNull(); /* ------- */ // GIVEN RequestBody newProjectBody = new RequestBody(); data = new DataBody(); newProjectBody.setData(data); data.setType("projects"); data.setAttributes(OBJECT_MAPPER.createObjectNode().put("name", "sample project")); JsonPath projectPath = pathBuilder.buildPath("/projects"); // WHEN -- adding a project ResourceResponseContext projectResponse = resourcePost.handle(projectPath, new QueryParams(), null, newProjectBody); // THEN assertThat(projectResponse.getResponse().getEntity()).isExactlyInstanceOf(Project.class); assertThat(((Project) (projectResponse.getResponse().getEntity())).getId()).isNotNull(); assertThat(((Project) (projectResponse.getResponse().getEntity())).getName()) .isEqualTo("sample project"); Long projectId = ((Project) (projectResponse.getResponse().getEntity())).getId(); assertThat(projectId).isNotNull(); /* ------- */ // GIVEN RequestBody newTaskToProjectBody = new RequestBody(); data = new DataBody(); newTaskToProjectBody.setData(data); data.setType("projects"); data.setId(projectId.toString()); JsonPath savedTaskPath = pathBuilder.buildPath("/tasks/" + taskId + "/relationships/project"); RelationshipsResourcePost relationshipsResourcePost = new RelationshipsResourcePost(resourceRegistry, typeParser); // WHEN -- adding a relation between task and project BaseResponseContext projectRelationshipResponse = relationshipsResourcePost.handle( savedTaskPath, new QueryParams(), null, newTaskToProjectBody); assertThat(projectRelationshipResponse).isNotNull(); // THEN TaskToProjectRepository taskToProjectRepository = new TaskToProjectRepository(); Project project = taskToProjectRepository.findOneTarget(taskId, "project", REQUEST_PARAMS); assertThat(project.getId()).isEqualTo(projectId); /* ------- */ // GIVEN RelationshipsResourceDelete sut = new RelationshipsResourceDelete(resourceRegistry, typeParser); // WHEN -- removing a relation between task and project BaseResponseContext result = sut.handle(savedTaskPath, new QueryParams(), null, newTaskToProjectBody); assertThat(result).isNotNull(); // THEN assertThat(result.getHttpStatus()).isEqualTo(HttpStatus.NO_CONTENT_204); Project nullProject = taskToProjectRepository.findOneTarget(taskId, "project", REQUEST_PARAMS); assertThat(nullProject).isNull(); }