use of io.crnk.core.engine.document.ResourceIdentifier in project crnk-framework by crnk-project.
the class IncludeLookupSetter method setupRelationId.
private void setupRelationId(Resource sourceResource, ResourceField relationshipField, Object targetEntityId) {
// set the relation
String relationshipName = relationshipField.getJsonName();
Map<String, Relationship> relationships = sourceResource.getRelationships();
Relationship relationship = relationships.get(relationshipName);
String oppositeType = relationshipField.getOppositeResourceType();
RegistryEntry entry = Objects.requireNonNull(resourceRegistry.getEntry(oppositeType));
ResourceInformation targetResourceInformation = entry.getResourceInformation();
if (targetEntityId instanceof Iterable) {
List<ResourceIdentifier> targetIds = new ArrayList<>();
for (Object targetElementId : (Iterable<?>) targetEntityId) {
targetIds.add(util.idToResourceId(targetResourceInformation, targetElementId));
}
relationship.setData(Nullable.of((Object) targetIds));
} else {
ResourceIdentifier targetResourceId = util.idToResourceId(targetResourceInformation, targetEntityId);
relationship.setData(Nullable.of((Object) targetResourceId));
}
}
use of io.crnk.core.engine.document.ResourceIdentifier in project crnk-framework by crnk-project.
the class IncludeLookupSetter method fetchRelationFromEntity.
/**
* No lookup specified for the field. Attempt to load relationship from
* original POJOs. Throw an InternalServerErrorException if the field is an
* Iterable and null.
*/
private Set<Resource> fetchRelationFromEntity(List<Resource> sourceResources, ResourceField relationshipField, QueryAdapter queryAdapter, Map<ResourceIdentifier, Resource> resourceMap, Map<ResourceIdentifier, Object> entityMap, boolean allowLookup, boolean fetchRelatedEntity, boolean mustInclude, ResourceMappingConfig resourceMappingConfig) {
Set<Resource> loadedResources = new HashSet<>();
for (Resource sourceResource : sourceResources) {
ResourceIdentifier id = sourceResource.toIdentifier();
Object sourceEntity = entityMap.get(id);
if (sourceEntity != null && !(sourceEntity instanceof Resource)) {
Object relatedEntity = null;
if (fetchRelatedEntity) {
relatedEntity = relationshipField.getAccessor().getValue(sourceEntity);
if (!allowLookup && Iterable.class.isAssignableFrom(relationshipField.getType()) && relatedEntity == null) {
// note that single-valued relations are allowed to be null
throw new InternalServerErrorException(id + " relationship field collection '" + relationshipField.getJsonName() + "' can not be null. Either set the relationship as an empty " + Iterable.class.getCanonicalName() + " or add annotation @" + JsonApiLookupIncludeAutomatically.class.getCanonicalName());
}
}
// attempt to work with full relationship and fallback to relationshipId where possible
if (relatedEntity != null) {
List<Resource> relatedResources = setupRelation(sourceResource, relationshipField, relatedEntity, queryAdapter, resourceMap, entityMap, resourceMappingConfig);
loadedResources.addAll(relatedResources);
} else if (relationshipField.hasIdField()) {
Object relatedEntityID = relationshipField.getIdAccessor().getValue(sourceEntity);
setupRelationId(sourceResource, relationshipField, relatedEntityID);
if (fetchRelatedEntity && relatedEntityID != null && !allowLookup && mustInclude) {
throw new IllegalStateException("inconsistent relationship '" + relationshipField.getUnderlyingName() + "' for " + id + ", id " + "set to " + relatedEntityID + ", but related object is null and lookup disabled");
}
}
}
}
return loadedResources;
}
use of io.crnk.core.engine.document.ResourceIdentifier in project crnk-framework by crnk-project.
the class RelationshipsResourcePost method processToManyRelationship.
@Override
public void processToManyRelationship(Object resource, ResourceInformation targetResourceInformation, ResourceField relationshipField, Iterable<ResourceIdentifier> dataBodies, QueryAdapter queryAdapter, RelationshipRepositoryAdapter relationshipRepositoryForClass) {
List<ResourceIdentifier> resourceIds = new ArrayList<>();
for (ResourceIdentifier dataBody : dataBodies) {
resourceIds.add(dataBody);
}
for (ResourceModificationFilter filter : modificationFilters) {
resourceIds = filter.modifyManyRelationship(resource, relationshipField, ResourceRelationshipModificationType.ADD, resourceIds);
}
List<Serializable> parsedIds = new LinkedList<>();
for (ResourceIdentifier resourceId : resourceIds) {
Serializable parsedId = targetResourceInformation.parseIdString(resourceId.getId());
parsedIds.add(parsedId);
}
// noinspection unchecked
relationshipRepositoryForClass.addRelations(resource, parsedIds, relationshipField, queryAdapter);
}
use of io.crnk.core.engine.document.ResourceIdentifier in project crnk-framework by crnk-project.
the class RelationshipsResourcePatch method processToManyRelationship.
@Override
public void processToManyRelationship(Object resource, ResourceInformation targetResourceInformation, ResourceField relationshipField, Iterable<ResourceIdentifier> dataBodies, QueryAdapter queryAdapter, RelationshipRepositoryAdapter relationshipRepositoryForClass) {
List<ResourceIdentifier> resourceIds = new ArrayList<>();
for (ResourceIdentifier dataBody : dataBodies) {
resourceIds.add(dataBody);
}
for (ResourceModificationFilter filter : modificationFilters) {
resourceIds = filter.modifyManyRelationship(resource, relationshipField, ResourceRelationshipModificationType.SET, resourceIds);
}
List<Serializable> parsedIds = new LinkedList<>();
for (ResourceIdentifier resourceId : resourceIds) {
Serializable parsedId = targetResourceInformation.parseIdString(resourceId.getId());
parsedIds.add(parsedId);
}
// noinspection unchecked
relationshipRepositoryForClass.setRelations(resource, parsedIds, relationshipField, queryAdapter);
}
use of io.crnk.core.engine.document.ResourceIdentifier in project crnk-framework by crnk-project.
the class RelationshipsResourcePostTest method onExistingResourcesShouldAddToOneRelationship.
@Test
public void onExistingResourcesShouldAddToOneRelationship() throws Exception {
// GIVEN
Document newTaskBody = new Document();
newTaskBody.setData(Nullable.of((Object) createTask()));
JsonPath taskPath = pathBuilder.build("/tasks");
ResourcePost resourcePost = new ResourcePost(resourceRegistry, PROPERTIES_PROVIDER, typeParser, OBJECT_MAPPER, documentMapper, modificationFilters);
// WHEN -- adding a task
Response taskResponse = resourcePost.handle(taskPath, emptyTaskQuery, null, newTaskBody);
// THEN
assertThat(taskResponse.getDocument().getSingleData().get().getType()).isEqualTo("tasks");
Long taskId = Long.parseLong(taskResponse.getDocument().getSingleData().get().getId());
assertThat(taskId).isNotNull();
/* ------- */
// GIVEN
Document newProjectBody = new Document();
newProjectBody.setData(Nullable.of((Object) createProject()));
JsonPath projectPath = pathBuilder.build("/projects");
// WHEN -- adding a project
Response projectResponse = resourcePost.handle(projectPath, emptyProjectQuery, null, newProjectBody);
// THEN
assertThat(projectResponse.getDocument().getSingleData().get().getType()).isEqualTo("projects");
assertThat(projectResponse.getDocument().getSingleData().get().getId()).isNotNull();
assertThat(projectResponse.getDocument().getSingleData().get().getAttributes().get("name").asText()).isEqualTo("sample project");
Long projectId = Long.parseLong(projectResponse.getDocument().getSingleData().get().getId());
assertThat(projectId).isNotNull();
/* ------- */
// GIVEN
Document newTaskToProjectBody = new Document();
newTaskToProjectBody.setData(Nullable.of((Object) createProject(Long.toString(projectId))));
JsonPath savedTaskPath = pathBuilder.build("/tasks/" + taskId + "/relationships/project");
RelationshipsResourcePost sut = new RelationshipsResourcePost(resourceRegistry, typeParser, modificationFilters);
// WHEN -- adding a relation between task and project
Response projectRelationshipResponse = sut.handle(savedTaskPath, emptyProjectQuery, null, newTaskToProjectBody);
assertThat(projectRelationshipResponse).isNotNull();
// THEN
TaskToProjectRepository taskToProjectRepository = new TaskToProjectRepository();
Project project = taskToProjectRepository.findOneTarget(taskId, "project", new QueryParams());
assertThat(project.getId()).isEqualTo(projectId);
ResourceIdentifier projectResourceId = new ResourceIdentifier(projectId.toString(), "projects");
// TODO properly implement ResourceIdentifier vs Resource in relationship repositories
// Mockito.validate(modificationFilter, Mockito.times(1)).modifyOneRelationship(Mockito.any(), Mockito.any(ResourceField.class), Mockito.eq(projectResourceId));
}
Aggregations