use of com.yahoo.elide.core.dictionary.RelationshipType in project elide by yahoo.
the class CollectionTerminalState method getData.
private Data getData(Set<PersistentResource> collection, EntityDictionary dictionary) {
Preconditions.checkNotNull(collection);
List<Resource> resources = collection.stream().map(PersistentResource::toResource).collect(Collectors.toList());
if (parent.isPresent()) {
Type<?> parentClass = parent.get().getResourceType();
String relationshipName = relationName.orElseThrow(IllegalStateException::new);
RelationshipType type = dictionary.getRelationshipType(parentClass, relationshipName);
return new Data<>(resources, type);
}
return new Data<>(resources);
}
use of com.yahoo.elide.core.dictionary.RelationshipType in project elide by yahoo.
the class RecordState method handle.
@Override
public void handle(StateContext state, SubCollectionReadCollectionContext ctx) {
String subCollection = ctx.term().getText();
EntityDictionary dictionary = state.getRequestScope().getDictionary();
Type<?> entityClass;
String entityName;
RelationshipType type = dictionary.getRelationshipType(resource.getObject(), subCollection);
Type<?> paramType = dictionary.getParameterizedType(resource.getObject(), subCollection);
entityName = dictionary.getJsonAliasFor(paramType);
entityClass = dictionary.getEntityClass(entityName, state.getRequestScope().getApiVersion());
if (entityClass == null) {
throw new IllegalArgumentException("Unknown type " + entityName);
}
final BaseState nextState;
final CollectionTerminalState collectionTerminalState = new CollectionTerminalState(entityClass, Optional.of(resource), Optional.of(subCollection), projection);
Observable<PersistentResource> collection = null;
if (type.isToOne()) {
collection = resource.getRelationCheckedFiltered(projection.getRelationship(subCollection).orElseThrow(IllegalStateException::new));
PersistentResource record = PersistentResource.firstOrNullIfEmpty(collection);
nextState = new RecordTerminalState(record, collectionTerminalState);
} else {
nextState = collectionTerminalState;
}
state.setState(nextState);
}
use of com.yahoo.elide.core.dictionary.RelationshipType in project elide by yahoo.
the class PersistentResource method clearRelation.
/**
* Clear all elements from a relation.
*
* @param relationName Name of relation to clear
* @return True if object updated, false otherwise
*/
public boolean clearRelation(String relationName) {
Set<PersistentResource> mine = filter(ReadPermission.class, Optional.empty(), ALL_FIELDS, getRelationUncheckedUnfiltered(relationName)).toList(LinkedHashSet::new).blockingGet();
checkFieldAwareDeferPermissions(UpdatePermission.class, relationName, Collections.emptySet(), mine.stream().map(PersistentResource::getObject).collect(Collectors.toSet()));
if (mine.isEmpty()) {
return false;
}
RelationshipType type = getRelationshipType(relationName);
if (type.isToOne()) {
PersistentResource oldValue = IterableUtils.first(mine);
if (oldValue != null && oldValue.getObject() != null) {
this.nullValue(relationName, oldValue);
oldValue.markDirty();
this.markDirty();
// hook for updateToOneRelation
transaction.updateToOneRelation(transaction, obj, relationName, null, requestScope);
}
} else {
Collection collection = (Collection) getValueUnchecked(relationName);
if (CollectionUtils.isNotEmpty(collection)) {
Set<Object> deletedRelationships = new LinkedHashSet<>();
mine.stream().forEach(toDelete -> {
deletedRelationships.add(toDelete.getObject());
});
modifyCollection(collection, relationName, Collections.emptySet(), deletedRelationships, true);
this.markDirty();
// hook for updateToManyRelation
transaction.updateToManyRelation(transaction, obj, relationName, new LinkedHashSet<>(), deletedRelationships, requestScope);
}
}
return true;
}
use of com.yahoo.elide.core.dictionary.RelationshipType in project elide by yahoo.
the class PersistentResource method removeRelation.
/**
* Remove a relationship.
*
* @param fieldName the field name
* @param removeResource the remove resource
*/
public void removeRelation(String fieldName, PersistentResource removeResource) {
Object relation = getValueUnchecked(fieldName);
Object original = relation;
Object modified = null;
if (relation instanceof Collection) {
original = copyCollection((Collection) relation);
}
if (relation instanceof Collection && removeResource != null) {
modified = CollectionUtils.disjunction((Collection) relation, Collections.singleton(removeResource.getObject()));
}
checkFieldAwareDeferPermissions(UpdatePermission.class, fieldName, modified, original);
if (relation instanceof Collection) {
if (removeResource == null || !((Collection) relation).contains(removeResource.getObject())) {
// Nothing to do
return;
}
modifyCollection((Collection) relation, fieldName, Collections.emptySet(), Set.of(removeResource.getObject()), true);
} else {
if (relation == null || removeResource == null || !relation.equals(removeResource.getObject())) {
// Nothing to do
return;
}
this.nullValue(fieldName, removeResource);
if (hasInverseRelation(fieldName)) {
deleteInverseRelation(fieldName, removeResource.getObject());
removeResource.markDirty();
}
}
if (!Objects.equals(original, modified)) {
this.markDirty();
}
RelationshipType type = getRelationshipType(fieldName);
if (type.isToOne()) {
// hook for updateToOneRelation
transaction.updateToOneRelation(transaction, obj, fieldName, null, requestScope);
} else {
// hook for updateToManyRelation
transaction.updateToManyRelation(transaction, obj, fieldName, new LinkedHashSet<>(), Sets.newHashSet(removeResource.getObject()), requestScope);
}
}
use of com.yahoo.elide.core.dictionary.RelationshipType in project elide by yahoo.
the class PersistentResource method updateRelation.
/**
* Perform a full replacement on relationships.
* Here is an example:
* The following are ids for a hypothetical relationship.
* GIVEN:
* all (all the ids in the DB) = 1,2,3,4,5
* mine (everything the current user has access to) = 1,2,3
* requested (what the user wants to change to) = 3,6
* THEN:
* deleted (what gets removed from the DB) = 1,2
* final (what get stored in the relationship) = 3,4,5,6
* BECAUSE:
* notMine = all - mine
* updated = (requested UNION mine) - (requested INTERSECT mine)
* deleted = (mine - requested)
* final = (notMine) UNION requested
*
* @param fieldName the field name
* @param resourceIdentifiers the resource identifiers
* @return True if object updated, false otherwise
*/
public boolean updateRelation(String fieldName, Set<PersistentResource> resourceIdentifiers) {
RelationshipType type = getRelationshipType(fieldName);
Set<PersistentResource> resources = filter(ReadPermission.class, Optional.empty(), ALL_FIELDS, getRelationUncheckedUnfiltered(fieldName)).toList(LinkedHashSet::new).blockingGet();
boolean isUpdated;
if (type.isToMany()) {
List<Object> modifiedResources = CollectionUtils.isEmpty(resourceIdentifiers) ? Collections.emptyList() : resourceIdentifiers.stream().map(PersistentResource::getObject).collect(Collectors.toList());
checkFieldAwareDeferPermissions(UpdatePermission.class, fieldName, modifiedResources, resources.stream().map(PersistentResource::getObject).collect(Collectors.toList()));
isUpdated = updateToManyRelation(fieldName, resourceIdentifiers, resources);
} else {
// To One Relationship
PersistentResource resource = firstOrNullIfEmpty(resources);
Object original = (resource == null) ? null : resource.getObject();
PersistentResource modifiedResource = firstOrNullIfEmpty(resourceIdentifiers);
Object modified = (modifiedResource == null) ? null : modifiedResource.getObject();
checkFieldAwareDeferPermissions(UpdatePermission.class, fieldName, modified, original);
isUpdated = updateToOneRelation(fieldName, resourceIdentifiers, resources);
}
return isUpdated;
}
Aggregations