Search in sources :

Example 76 with FieldInfo

use of org.neo4j.ogm.metadata.FieldInfo in project neo4j-ogm by neo4j.

the class EntityUtils method labels.

/**
 * Returns the full set of labels, both static and dynamic, if any, to apply to a node.
 *
 * @param entity   entity to get the labels for
 * @param metaData metadata
 * @return collection of labels
 */
public static Collection<String> labels(Object entity, MetaData metaData) {
    ClassInfo classInfo = metaData.classInfo(entity);
    Collection<String> labels = new ArrayList<>(classInfo.staticLabels());
    FieldInfo labelFieldInfo = classInfo.labelFieldOrNull();
    if (labelFieldInfo != null) {
        Collection<String> dynamicLabels = (Collection<String>) labelFieldInfo.readProperty(entity);
        if (dynamicLabels != null) {
            labels.addAll(dynamicLabels);
        }
    }
    return labels;
}
Also used : ArrayList(java.util.ArrayList) Collection(java.util.Collection) FieldInfo(org.neo4j.ogm.metadata.FieldInfo) ClassInfo(org.neo4j.ogm.metadata.ClassInfo)

Example 77 with FieldInfo

use of org.neo4j.ogm.metadata.FieldInfo in project neo4j-ogm by neo4j.

the class EntityGraphMapper method newNodeBuilder.

/**
 * Returns a {@link NodeBuilder} responsible for handling new or updated nodes
 *
 * @param entity  the object to save
 * @param horizon current horizon
 * @return a new {@link NodeBuilder} object for a new node, null for transient classes or subclasses thereof
 */
private NodeBuilder newNodeBuilder(Object entity, int horizon) {
    ClassInfo classInfo = metaData.classInfo(entity);
    // transient or subclass of transient will not have class info
    if (classInfo == null) {
        return null;
    }
    CompileContext context = compiler.context();
    Long id = mappingContext.nativeId(entity);
    Collection<String> labels = EntityUtils.labels(entity, metaData);
    String primaryIndex = null;
    if (classInfo.hasPrimaryIndexField()) {
        FieldInfo primaryIndexField = classInfo.primaryIndexField();
        primaryIndex = joinPrimaryIndexAttributesIfNecessary(primaryIndexField.property(), primaryIndexField.hasCompositeConverter() ? primaryIndexField.readComposite(entity) : null);
    }
    NodeBuilder nodeBuilder;
    if (id < 0) {
        nodeBuilder = compiler.newNode(id).addLabels(labels).setPrimaryIndex(primaryIndex);
        context.registerNewObject(id, entity);
    } else {
        nodeBuilder = compiler.existingNode(id);
        nodeBuilder.addLabels(labels).setPrimaryIndex(primaryIndex);
        this.mappingContext.getSnapshotOf(entity).ifPresent(snapshot -> nodeBuilder.setPreviousDynamicLabels(snapshot.getDynamicLabels()).setPreviousCompositeProperties(snapshot.getDynamicCompositeProperties()));
    }
    LOGGER.debug("visiting: {}", entity);
    context.visit(entity, nodeBuilder, horizon);
    return nodeBuilder;
}
Also used : NodeBuilder(org.neo4j.ogm.cypher.compiler.NodeBuilder) CompileContext(org.neo4j.ogm.cypher.compiler.CompileContext) FieldInfo(org.neo4j.ogm.metadata.FieldInfo) ClassInfo(org.neo4j.ogm.metadata.ClassInfo)

Example 78 with FieldInfo

use of org.neo4j.ogm.metadata.FieldInfo 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)

Example 79 with FieldInfo

use of org.neo4j.ogm.metadata.FieldInfo in project neo4j-ogm by neo4j.

the class EntityGraphMapper method updateFieldsOnBuilder.

private <T> void updateFieldsOnBuilder(Object entity, PropertyContainerBuilder<T> builder, ClassInfo classInfo) {
    for (FieldInfo fieldInfo : classInfo.propertyFields()) {
        if (fieldInfo.isReadOnly()) {
            continue;
        }
        if (fieldInfo.isComposite()) {
            Map<String, ?> properties = fieldInfo.readComposite(entity);
            builder.addCompositeProperties(properties);
        } else if (fieldInfo.isVersionField()) {
            updateVersionField(entity, builder, fieldInfo);
        } else {
            builder.addProperty(fieldInfo.propertyName(), fieldInfo.readProperty(entity));
        }
    }
}
Also used : FieldInfo(org.neo4j.ogm.metadata.FieldInfo)

Example 80 with FieldInfo

use of org.neo4j.ogm.metadata.FieldInfo in project neo4j-ogm by neo4j.

the class GraphEntityMapper method getCompositeProperties.

/**
 * Finds the composite properties of an entity type and build their values using a property list.
 *
 * @param propertyList The properties to convert from.
 * @param classInfo    The class to inspect for composite attributes.
 * @return a map containing the values of the converted attributes, indexed by field object. Never null.
 */
private Map<FieldInfo, Object> getCompositeProperties(List<Property<String, Object>> propertyList, ClassInfo classInfo) {
    Map<FieldInfo, Object> compositeValues = new HashMap<>();
    Collection<FieldInfo> compositeFields = classInfo.fieldsInfo().compositeFields();
    if (compositeFields.size() > 0) {
        Map<String, ?> propertyMap = toMap(propertyList);
        for (FieldInfo field : compositeFields) {
            CompositeAttributeConverter<?> converter = field.getCompositeConverter();
            compositeValues.put(field, converter.toEntityAttribute(propertyMap));
        }
    }
    return compositeValues;
}
Also used : FieldInfo(org.neo4j.ogm.metadata.FieldInfo)

Aggregations

FieldInfo (org.neo4j.ogm.metadata.FieldInfo)142 Test (org.junit.Test)102 ClassInfo (org.neo4j.ogm.metadata.ClassInfo)100 ArrayList (java.util.ArrayList)12 Date (java.util.Date)7 HashSet (java.util.HashSet)6 HashMap (java.util.HashMap)5 Collection (java.util.Collection)4 Satellite (org.neo4j.ogm.domain.satellites.Satellite)4 MappingException (org.neo4j.ogm.exception.core.MappingException)4 CompileContext (org.neo4j.ogm.cypher.compiler.CompileContext)3 Person (org.neo4j.ogm.domain.convertible.enums.Person)3 Member (org.neo4j.ogm.domain.forum.Member)3 Topic (org.neo4j.ogm.domain.forum.Topic)3 Post (org.neo4j.ogm.domain.forum.activity.Post)3 MetaData (org.neo4j.ogm.metadata.MetaData)3 Collections (java.util.Collections)2 List (java.util.List)2 Map (java.util.Map)2 Optional (java.util.Optional)2