Search in sources :

Example 31 with ResourceIdentifier

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));
    }
}
Also used : ResourceIdentifier(io.crnk.core.engine.document.ResourceIdentifier) ResourceInformation(io.crnk.core.engine.information.resource.ResourceInformation) Relationship(io.crnk.core.engine.document.Relationship) ArrayList(java.util.ArrayList) RegistryEntry(io.crnk.core.engine.registry.RegistryEntry)

Example 32 with ResourceIdentifier

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;
}
Also used : ResourceIdentifier(io.crnk.core.engine.document.ResourceIdentifier) Resource(io.crnk.core.engine.document.Resource) InternalServerErrorException(io.crnk.core.exception.InternalServerErrorException) HashSet(java.util.HashSet)

Example 33 with ResourceIdentifier

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);
}
Also used : ResourceIdentifier(io.crnk.core.engine.document.ResourceIdentifier) Serializable(java.io.Serializable) ArrayList(java.util.ArrayList) ResourceModificationFilter(io.crnk.core.engine.filter.ResourceModificationFilter) LinkedList(java.util.LinkedList)

Example 34 with ResourceIdentifier

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);
}
Also used : ResourceIdentifier(io.crnk.core.engine.document.ResourceIdentifier) Serializable(java.io.Serializable) ArrayList(java.util.ArrayList) ResourceModificationFilter(io.crnk.core.engine.filter.ResourceModificationFilter) LinkedList(java.util.LinkedList)

Example 35 with ResourceIdentifier

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));
}
Also used : Response(io.crnk.core.engine.dispatcher.Response) Project(io.crnk.core.mock.models.Project) ResourceIdentifier(io.crnk.core.engine.document.ResourceIdentifier) TaskToProjectRepository(io.crnk.core.mock.repository.TaskToProjectRepository) QueryParams(io.crnk.legacy.queryParams.QueryParams) RelationshipsResourcePost(io.crnk.core.engine.internal.dispatcher.controller.RelationshipsResourcePost) Document(io.crnk.core.engine.document.Document) JsonPath(io.crnk.core.engine.internal.dispatcher.path.JsonPath) ResourcePost(io.crnk.core.engine.internal.dispatcher.controller.ResourcePost) RelationshipsResourcePost(io.crnk.core.engine.internal.dispatcher.controller.RelationshipsResourcePost) BaseControllerTest(io.crnk.core.engine.internal.dispatcher.controller.BaseControllerTest) Test(org.junit.Test)

Aggregations

ResourceIdentifier (io.crnk.core.engine.document.ResourceIdentifier)60 Resource (io.crnk.core.engine.document.Resource)42 Document (io.crnk.core.engine.document.Document)40 Test (org.junit.Test)33 Relationship (io.crnk.core.engine.document.Relationship)31 QuerySpec (io.crnk.core.queryspec.QuerySpec)25 Response (io.crnk.core.engine.dispatcher.Response)14 Task (io.crnk.core.mock.models.Task)13 BaseControllerTest (io.crnk.core.engine.internal.dispatcher.controller.BaseControllerTest)11 ResourcePost (io.crnk.core.engine.internal.dispatcher.controller.ResourcePost)11 JsonPath (io.crnk.core.engine.internal.dispatcher.path.JsonPath)11 RelationIdTestResource (io.crnk.core.mock.models.RelationIdTestResource)9 Serializable (java.io.Serializable)9 ResourceModificationFilter (io.crnk.core.engine.filter.ResourceModificationFilter)8 Project (io.crnk.core.mock.models.Project)8 ArrayList (java.util.ArrayList)8 ResourceField (io.crnk.core.engine.information.resource.ResourceField)6 RegistryEntry (io.crnk.core.engine.registry.RegistryEntry)6 LazyTask (io.crnk.core.mock.models.LazyTask)6 AbstractDocumentMapperTest (io.crnk.core.engine.internal.document.mapper.AbstractDocumentMapperTest)4