Search in sources :

Example 1 with RelationshipType

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);
}
Also used : Resource(com.yahoo.elide.jsonapi.models.Resource) PersistentResource(com.yahoo.elide.core.PersistentResource) RelationshipType(com.yahoo.elide.core.dictionary.RelationshipType) Data(com.yahoo.elide.jsonapi.models.Data) ToString(lombok.ToString)

Example 2 with RelationshipType

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);
}
Also used : PersistentResource(com.yahoo.elide.core.PersistentResource) RelationshipType(com.yahoo.elide.core.dictionary.RelationshipType) EntityDictionary(com.yahoo.elide.core.dictionary.EntityDictionary)

Example 3 with RelationshipType

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;
}
Also used : LinkedHashSet(java.util.LinkedHashSet) RelationshipType(com.yahoo.elide.core.dictionary.RelationshipType) Collection(java.util.Collection)

Example 4 with RelationshipType

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);
    }
}
Also used : RelationshipType(com.yahoo.elide.core.dictionary.RelationshipType) Collection(java.util.Collection)

Example 5 with RelationshipType

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;
}
Also used : RelationshipType(com.yahoo.elide.core.dictionary.RelationshipType)

Aggregations

RelationshipType (com.yahoo.elide.core.dictionary.RelationshipType)15 GraphQLTypeReference (graphql.schema.GraphQLTypeReference)4 Collection (java.util.Collection)4 GraphQLList (graphql.schema.GraphQLList)3 GraphQLObjectType (graphql.schema.GraphQLObjectType)3 GraphQLOutputType (graphql.schema.GraphQLOutputType)3 GraphQLType (graphql.schema.GraphQLType)3 PersistentResource (com.yahoo.elide.core.PersistentResource)2 EntityDictionary (com.yahoo.elide.core.dictionary.EntityDictionary)2 InternalServerErrorException (com.yahoo.elide.core.exceptions.InternalServerErrorException)2 Resource (com.yahoo.elide.jsonapi.models.Resource)2 Sets (com.google.common.collect.Sets)1 Path (com.yahoo.elide.core.Path)1 DataStoreIterable (com.yahoo.elide.core.datastore.DataStoreIterable)1 InvalidAttributeException (com.yahoo.elide.core.exceptions.InvalidAttributeException)1 AndFilterExpression (com.yahoo.elide.core.filter.expression.AndFilterExpression)1 FilterExpression (com.yahoo.elide.core.filter.expression.FilterExpression)1 Pagination (com.yahoo.elide.core.request.Pagination)1 Sorting (com.yahoo.elide.core.request.Sorting)1 Type (com.yahoo.elide.core.type.Type)1