Search in sources :

Example 6 with Direction

use of org.neo4j.ogm.annotation.Relationship.Direction in project neo4j-ogm by neo4j.

the class EntityGraphMapper method mapEntityReferences.

/**
 * Finds all the objects that can be mapped via relationships from the object 'entity' and
 * links them in the graph.
 * This includes objects that are directly linked, as well as objects linked via a relationship entity
 *
 * @param entity      the node whose relationships will be updated
 * @param nodeBuilder a {@link NodeBuilder} that knows how to create node create/update cypher phrases
 * @param horizon     the depth in the tree. If this reaches 0, we stop mapping any deeper
 */
private void mapEntityReferences(final Object entity, NodeBuilder nodeBuilder, int horizon) {
    int depth = currentDepth.incrementAndGet();
    LOGGER.debug("mapping references declared by: {}, currently at depth {}", entity, depth);
    ClassInfo srcInfo = metaData.classInfo(entity);
    Long srcIdentity = mappingContext.nativeId(entity);
    for (FieldInfo reader : srcInfo.relationshipFields()) {
        String relationshipType = reader.relationshipType();
        Direction relationshipDirection = reader.relationshipDirection();
        Class startNodeType = srcInfo.getUnderlyingClass();
        Class endNodeType = DescriptorMappings.getType(reader.getTypeDescriptor());
        LOGGER.debug("{}: mapping reference type: {}", entity, relationshipType);
        DirectedRelationship directedRelationship = new DirectedRelationship(relationshipType, relationshipDirection);
        CompileContext context = compiler.context();
        if (srcIdentity >= 0) {
            List<Class<?>> potentiallyRelated = new ArrayList<>();
            potentiallyRelated.add(endNodeType);
            ClassInfo endNodeTypeClassInfo = metaData.classInfo(endNodeType);
            if (endNodeTypeClassInfo != null) {
                endNodeTypeClassInfo.allSubclasses().stream().map(ClassInfo::getUnderlyingClass).forEach(potentiallyRelated::add);
            }
            boolean cleared = false;
            for (Class<?> clazz : potentiallyRelated) {
                if (clearContextRelationships(context, srcIdentity, clazz, directedRelationship)) {
                    cleared = true;
                }
            }
            if (!cleared) {
                LOGGER.debug("this relationship is already being managed: {}-{}-{}-()", entity, relationshipType, relationshipDirection);
                continue;
            }
        }
        Object relatedObject = reader.read(entity);
        if (relatedObject != null) {
            if (isRelationshipEntity(relatedObject)) {
                ClassInfo declaredObjectInfo = metaData.classInfo(relationshipType);
                if (declaredObjectInfo.isAbstract()) {
                    final ClassInfo relatedObjectClassInfo = metaData.classInfo(relatedObject);
                    if (!relatedObjectClassInfo.neo4jName().equals(directedRelationship.type())) {
                        directedRelationship = new DirectedRelationship(relatedObjectClassInfo.neo4jName(), directedRelationship.direction());
                        relationshipType = directedRelationship.type();
                    }
                }
            }
            RelationshipNodes relNodes = new RelationshipNodes(entity, null, startNodeType, endNodeType);
            relNodes.sourceId = srcIdentity;
            Boolean mapBothWays = null;
            for (Object tgtObject : CollectionUtils.iterableOf(relatedObject)) {
                if (tgtObject == null) {
                    throw new InvalidRelationshipTargetException(startNodeType, relationshipType, reader.getName(), endNodeType);
                }
                if (mapBothWays == null) {
                    mapBothWays = bothWayMappingRequired(entity, relationshipType, tgtObject, relationshipDirection);
                }
                relNodes.target = tgtObject;
                link(directedRelationship, nodeBuilder, horizon, mapBothWays, relNodes);
            }
        }
    }
    currentDepth.decrementAndGet();
}
Also used : ArrayList(java.util.ArrayList) Direction(org.neo4j.ogm.annotation.Relationship.Direction) CompileContext(org.neo4j.ogm.cypher.compiler.CompileContext) InvalidRelationshipTargetException(org.neo4j.ogm.exception.core.InvalidRelationshipTargetException) FieldInfo(org.neo4j.ogm.metadata.FieldInfo) ClassInfo(org.neo4j.ogm.metadata.ClassInfo)

Aggregations

Direction (org.neo4j.ogm.annotation.Relationship.Direction)6 ClassInfo (org.neo4j.ogm.metadata.ClassInfo)3 ArrayList (java.util.ArrayList)2 FieldInfo (org.neo4j.ogm.metadata.FieldInfo)2 EndNode (org.neo4j.ogm.annotation.EndNode)1 StartNode (org.neo4j.ogm.annotation.StartNode)1 MappedRelationship (org.neo4j.ogm.context.MappedRelationship)1 Filter (org.neo4j.ogm.cypher.Filter)1 CompileContext (org.neo4j.ogm.cypher.compiler.CompileContext)1 InvalidRelationshipTargetException (org.neo4j.ogm.exception.core.InvalidRelationshipTargetException)1 MissingOperatorException (org.neo4j.ogm.exception.core.MissingOperatorException)1 AnnotationInfo (org.neo4j.ogm.metadata.AnnotationInfo)1