use of io.crnk.core.engine.internal.repository.ResourceRepositoryAdapter in project crnk-framework by crnk-project.
the class ResourcePatch method handle.
@Override
public Response handle(JsonPath jsonPath, QueryAdapter queryAdapter, RepositoryMethodParameterProvider parameterProvider, Document requestDocument) {
RegistryEntry endpointRegistryEntry = getRegistryEntry(jsonPath);
final Resource resourceBody = getRequestBody(requestDocument, jsonPath, HttpMethod.PATCH);
RegistryEntry bodyRegistryEntry = resourceRegistry.getEntry(resourceBody.getType());
String idString = jsonPath.getIds().getIds().get(0);
ResourceInformation resourceInformation = bodyRegistryEntry.getResourceInformation();
Serializable resourceId = resourceInformation.parseIdString(idString);
verifyTypes(HttpMethod.PATCH, endpointRegistryEntry, bodyRegistryEntry);
ResourceRepositoryAdapter resourceRepository = endpointRegistryEntry.getResourceRepository(parameterProvider);
JsonApiResponse resourceFindResponse = resourceRepository.findOne(resourceId, queryAdapter);
Object resource = resourceFindResponse.getEntity();
if (resource == null) {
throw new ResourceNotFoundException(jsonPath.toString());
}
final Resource resourceFindData = documentMapper.toDocument(resourceFindResponse, queryAdapter, parameterProvider).getSingleData().get();
resourceInformation.verify(resource, requestDocument);
// extract current attributes from findOne without any manipulation by query params (such as sparse fieldsets)
ExceptionUtil.wrapCatchedExceptions(new Callable<Object>() {
@Override
public Object call() throws Exception {
String attributesFromFindOne = extractAttributesFromResourceAsJson(resourceFindData);
Map<String, Object> attributesToUpdate = new HashMap<>(emptyIfNull(objectMapper.readValue(attributesFromFindOne, Map.class)));
// deserialize the request JSON's attributes object into a map
String attributesAsJson = objectMapper.writeValueAsString(resourceBody.getAttributes());
Map<String, Object> attributesFromRequest = emptyIfNull(objectMapper.readValue(attributesAsJson, Map.class));
// remove attributes that were omitted in the request
Iterator<String> it = attributesToUpdate.keySet().iterator();
while (it.hasNext()) {
String key = it.next();
if (!attributesFromRequest.containsKey(key)) {
it.remove();
}
}
// walk the source map and apply target values from request
updateValues(attributesToUpdate, attributesFromRequest);
Map<String, JsonNode> upsertedAttributes = new HashMap<>();
for (Map.Entry<String, Object> entry : attributesToUpdate.entrySet()) {
JsonNode value = objectMapper.valueToTree(entry.getValue());
upsertedAttributes.put(entry.getKey(), value);
}
resourceBody.setAttributes(upsertedAttributes);
return null;
}
}, "failed to merge patched attributes");
JsonApiResponse updatedResource;
Set<String> loadedRelationshipNames;
if (resourceInformation.getResourceClass() == Resource.class) {
loadedRelationshipNames = getLoadedRelationshipNames(resourceBody);
updatedResource = resourceRepository.update(resourceBody, queryAdapter);
} else {
setAttributes(resourceBody, resource, bodyRegistryEntry.getResourceInformation());
setRelations(resource, bodyRegistryEntry, resourceBody, queryAdapter, parameterProvider, false);
loadedRelationshipNames = getLoadedRelationshipNames(resourceBody);
updatedResource = resourceRepository.update(resource, queryAdapter);
}
Document responseDocument = documentMapper.toDocument(updatedResource, queryAdapter, parameterProvider, loadedRelationshipNames);
return new Response(responseDocument, 200);
}
use of io.crnk.core.engine.internal.repository.ResourceRepositoryAdapter in project crnk-framework by crnk-project.
the class IncludeLookupSetter method lookupRelatedResourcesWithId.
private Set<Resource> lookupRelatedResourcesWithId(Collection<Resource> sourceResources, ResourceField relationshipField, QueryAdapter queryAdapter, RepositoryMethodParameterProvider parameterProvider, Map<ResourceIdentifier, Resource> resourceMap, Map<ResourceIdentifier, Object> entityMap, ResourceMappingConfig resourceMappingConfig) {
String oppositeResourceType = relationshipField.getOppositeResourceType();
RegistryEntry oppositeEntry = resourceRegistry.getEntry(oppositeResourceType);
if (oppositeEntry == null) {
throw new RepositoryNotFoundException("no resource with type " + oppositeResourceType + " found");
}
ResourceInformation oppositeResourceInformation = oppositeEntry.getResourceInformation();
ResourceRepositoryAdapter oppositeResourceRepository = oppositeEntry.getResourceRepository(parameterProvider);
if (oppositeResourceRepository == null) {
throw new RepositoryNotFoundException("no relationship repository found for " + oppositeResourceInformation.getResourceType());
}
Set<Resource> related = new HashSet<>();
Set<Object> relatedIdsToLoad = new HashSet<>();
for (Resource sourceResource : sourceResources) {
Relationship relationship = sourceResource.getRelationships().get(relationshipField.getJsonName());
PreconditionUtil.assertTrue("expected relationship data to be loaded for @JsonApiResourceId annotated field", relationship.getData().isPresent());
if (relationship.getData().get() != null) {
for (ResourceIdentifier id : relationship.getCollectionData().get()) {
if (resourceMap.containsKey(id)) {
// load from cache
related.add(resourceMap.get(id));
} else {
relatedIdsToLoad.add(oppositeResourceInformation.parseIdString(id.getId()));
}
}
}
}
if (!relatedIdsToLoad.isEmpty()) {
JsonApiResponse response = oppositeResourceRepository.findAll(relatedIdsToLoad, queryAdapter);
Collection responseList = (Collection) response.getEntity();
for (Object responseEntity : responseList) {
Resource relatedResource = mergeResource(responseEntity, queryAdapter, resourceMap, entityMap, resourceMappingConfig);
related.add(relatedResource);
Object responseEntityId = oppositeResourceInformation.getId(responseEntity);
relatedIdsToLoad.remove(responseEntityId);
}
if (!relatedIdsToLoad.isEmpty()) {
throw new ResourceNotFoundException("type=" + relationshipField.getOppositeResourceType() + ", " + "ids=" + relatedIdsToLoad);
}
}
return related;
}
use of io.crnk.core.engine.internal.repository.ResourceRepositoryAdapter in project crnk-framework by crnk-project.
the class RelationshipsResourceUpsert method handle.
@Override
public final Response handle(JsonPath jsonPath, QueryAdapter queryAdapter, RepositoryMethodParameterProvider parameterProvider, Document requestBody) {
String resourceName = jsonPath.getResourceType();
PathIds resourceIds = jsonPath.getIds();
RegistryEntry registryEntry = getRegistryEntry(resourceName);
assertRequestDocument(requestBody, HttpMethod.POST, resourceName);
Serializable castedResourceId = getResourceId(resourceIds, registryEntry);
ResourceField relationshipField = registryEntry.getResourceInformation().findRelationshipFieldByName(jsonPath.getElementName());
verifyFieldNotNull(relationshipField, jsonPath.getElementName());
ResourceRepositoryAdapter resourceRepository = registryEntry.getResourceRepository(parameterProvider);
@SuppressWarnings("unchecked") Object resource = resourceRepository.findOne(castedResourceId, queryAdapter).getEntity();
ResourceInformation targetInformation = getRegistryEntry(relationshipField.getOppositeResourceType()).getResourceInformation();
@SuppressWarnings("unchecked") RelationshipRepositoryAdapter relationshipRepositoryForClass = registryEntry.getRelationshipRepository(relationshipField, parameterProvider);
if (Iterable.class.isAssignableFrom(relationshipField.getType())) {
Iterable<ResourceIdentifier> dataBodies = (Iterable<ResourceIdentifier>) (requestBody.isMultiple() ? requestBody.getData().get() : Collections.singletonList(requestBody.getData().get()));
processToManyRelationship(resource, targetInformation, relationshipField, dataBodies, queryAdapter, relationshipRepositoryForClass);
} else {
if (requestBody.isMultiple()) {
throw new RequestBodyException(HttpMethod.POST, resourceName, "Multiple data in body");
}
ResourceIdentifier dataBody = (ResourceIdentifier) requestBody.getData().get();
processToOneRelationship(resource, targetInformation, relationshipField, dataBody, queryAdapter, relationshipRepositoryForClass);
}
return new Response(new Document(), HttpStatus.NO_CONTENT_204);
}
use of io.crnk.core.engine.internal.repository.ResourceRepositoryAdapter in project crnk-framework by crnk-project.
the class FieldResourcePost method handle.
@Override
public Response handle(JsonPath jsonPath, QueryAdapter queryAdapter, RepositoryMethodParameterProvider parameterProvider, Document requestDocument) {
RegistryEntry endpointRegistryEntry = getRegistryEntry(jsonPath);
Resource resourceBody = getRequestBody(requestDocument, jsonPath, HttpMethod.POST);
PathIds resourceIds = jsonPath.getIds();
RegistryEntry bodyRegistryEntry = resourceRegistry.getEntry(resourceBody.getType());
Serializable castedResourceId = getResourceId(resourceIds, endpointRegistryEntry);
ResourceField relationshipField = endpointRegistryEntry.getResourceInformation().findRelationshipFieldByName(jsonPath.getElementName());
verifyFieldNotNull(relationshipField, jsonPath.getElementName());
Class<?> baseRelationshipFieldClass = relationshipField.getType();
RegistryEntry relationshipRegistryEntry = resourceRegistry.getEntry(relationshipField.getOppositeResourceType());
String relationshipResourceType = relationshipField.getOppositeResourceType();
verifyTypes(HttpMethod.POST, relationshipRegistryEntry, bodyRegistryEntry);
Object newResource = buildNewResource(relationshipRegistryEntry, resourceBody, relationshipResourceType);
setAttributes(resourceBody, newResource, relationshipRegistryEntry.getResourceInformation());
ResourceRepositoryAdapter resourceRepository = relationshipRegistryEntry.getResourceRepository(parameterProvider);
Document savedResourceResponse = documentMapper.toDocument(resourceRepository.create(newResource, queryAdapter), queryAdapter, parameterProvider);
setRelations(newResource, bodyRegistryEntry, resourceBody, queryAdapter, parameterProvider, false);
ResourceIdentifier resourceId1 = savedResourceResponse.getSingleData().get();
RelationshipRepositoryAdapter relationshipRepositoryForClass = endpointRegistryEntry.getRelationshipRepository(relationshipField, parameterProvider);
@SuppressWarnings("unchecked") JsonApiResponse parent = endpointRegistryEntry.getResourceRepository(parameterProvider).findOne(castedResourceId, queryAdapter);
if (Iterable.class.isAssignableFrom(baseRelationshipFieldClass)) {
List<ResourceIdentifier> resourceIdList = Collections.singletonList(resourceId1);
for (ResourceModificationFilter filter : modificationFilters) {
resourceIdList = filter.modifyManyRelationship(parent.getEntity(), relationshipField, ResourceRelationshipModificationType.ADD, resourceIdList);
}
List<Serializable> parsedIds = new ArrayList<>();
for (ResourceIdentifier resourceId : resourceIdList) {
parsedIds.add(relationshipRegistryEntry.getResourceInformation().parseIdString(resourceId.getId()));
}
// noinspection unchecked
relationshipRepositoryForClass.addRelations(parent.getEntity(), parsedIds, relationshipField, queryAdapter);
} else {
// noinspection unchecked
for (ResourceModificationFilter filter : modificationFilters) {
resourceId1 = filter.modifyOneRelationship(parent.getEntity(), relationshipField, resourceId1);
}
Serializable parseId = relationshipRegistryEntry.getResourceInformation().parseIdString(resourceId1.getId());
relationshipRepositoryForClass.setRelation(parent.getEntity(), parseId, relationshipField, queryAdapter);
}
return new Response(savedResourceResponse, HttpStatus.CREATED_201);
}
use of io.crnk.core.engine.internal.repository.ResourceRepositoryAdapter in project crnk-framework by crnk-project.
the class ResourcePost method handle.
@Override
public Response handle(JsonPath jsonPath, QueryAdapter queryAdapter, RepositoryMethodParameterProvider parameterProvider, Document requestDocument) {
RegistryEntry endpointRegistryEntry = getRegistryEntry(jsonPath);
Resource resourceBody = getRequestBody(requestDocument, jsonPath, HttpMethod.POST);
RegistryEntry bodyRegistryEntry = resourceRegistry.getEntry(resourceBody.getType());
verifyTypes(HttpMethod.POST, endpointRegistryEntry, bodyRegistryEntry);
ResourceRepositoryAdapter resourceRepository = endpointRegistryEntry.getResourceRepository(parameterProvider);
JsonApiResponse apiResponse;
if (Resource.class.equals(resourceRepository.getResourceClass())) {
apiResponse = resourceRepository.create(resourceBody, queryAdapter);
} else {
Object newResource = newResource(bodyRegistryEntry.getResourceInformation(), resourceBody);
setId(resourceBody, newResource, bodyRegistryEntry.getResourceInformation());
setAttributes(resourceBody, newResource, bodyRegistryEntry.getResourceInformation());
setRelations(newResource, bodyRegistryEntry, resourceBody, queryAdapter, parameterProvider, false);
apiResponse = resourceRepository.create(newResource, queryAdapter);
}
if (apiResponse.getEntity() == null) {
throw new IllegalStateException("repository did not return the created resource");
}
Set<String> loadedRelationshipNames = getLoadedRelationshipNames(resourceBody);
Document responseDocument = documentMapper.toDocument(apiResponse, queryAdapter, parameterProvider, loadedRelationshipNames);
return new Response(responseDocument, HttpStatus.CREATED_201);
}
Aggregations