use of org.neo4j.ogm.context.DirectedRelationshipForType in project neo4j-ogm by neo4j.
the class EntityAccessManager method getIterableField.
/**
* Returns an FieldWriter for an iterable of a non-primitive scalar type defined by a ClassInfo
*
* @param classInfo the ClassInfo (or a superclass thereof) declaring the iterable relationship
* @param relationshipType the name of the relationship as it is in the graph
* @param relationshipDirection the direction of the relationship as it is in the graph
* @param parameterType the type that will be iterated over
* @return a valid FieldWriter or null if none is found
*/
public static FieldInfo getIterableField(ClassInfo classInfo, Class<?> parameterType, String relationshipType, Direction relationshipDirection) {
final ClassInfo lookupClassInfo = classInfo;
final DirectedRelationshipForType directedRelationshipForType = new DirectedRelationshipForType(relationshipType, relationshipDirection, parameterType);
final Map<DirectedRelationshipForType, FieldInfo> typeFieldInfoMap = iterableWriterCache.computeIfAbsent(lookupClassInfo, key -> new ConcurrentHashMap<>());
if (typeFieldInfoMap.containsKey(directedRelationshipForType)) {
return typeFieldInfoMap.get(directedRelationshipForType);
}
while (classInfo != null) {
// 1st find a field annotated with type and direction
FieldInfo fieldInfo = getIterableFieldInfo(classInfo, parameterType, relationshipType, relationshipDirection, STRICT_MODE);
if (fieldInfo != null) {
cacheIterableFieldWriter(lookupClassInfo, parameterType, relationshipType, relationshipDirection, directedRelationshipForType, fieldInfo, fieldInfo);
return fieldInfo;
}
if (relationshipDirection != Direction.INCOMING) {
// 3rd, find a field with implied type and direction
fieldInfo = getIterableFieldInfo(classInfo, parameterType, relationshipType, relationshipDirection, INFERRED_MODE);
if (fieldInfo != null) {
cacheIterableFieldWriter(lookupClassInfo, parameterType, relationshipType, relationshipDirection, directedRelationshipForType, fieldInfo, fieldInfo);
return fieldInfo;
}
}
classInfo = classInfo.directSuperclass();
}
return null;
}
use of org.neo4j.ogm.context.DirectedRelationshipForType in project neo4j-ogm by neo4j.
the class EntityAccessManager method getRelationalWriter.
/**
* Returns a FieldWriter for a scalar type on a ClassInfo that is not a primitive graph property
*
* @param classInfo the ClassInfo (or a superclass thereof) declaring the relationship
* @param relationshipType the name of the relationship as it is in the graph
* @param relationshipDirection the direction of the relationship as it is in the graph
* @param objectType the class the relationship is defined for
* @return a valid FieldWriter or null if none is found
*/
public static FieldInfo getRelationalWriter(ClassInfo classInfo, String relationshipType, Direction relationshipDirection, Class<?> objectType) {
final DirectedRelationshipForType directedRelationship = new DirectedRelationshipForType(relationshipType, relationshipDirection, objectType);
final Map<DirectedRelationshipForType, FieldInfo> typeFieldInfoMap = relationalWriterCache.computeIfAbsent(classInfo, key -> new ConcurrentHashMap<>());
if (typeFieldInfoMap.containsKey(directedRelationship)) {
return typeFieldInfoMap.get(directedRelationship);
}
while (classInfo != null) {
// 1st, try to find a scalar or vector field explicitly annotated as the neo4j relationship type and direction
for (FieldInfo fieldInfo : classInfo.candidateRelationshipFields(relationshipType, relationshipDirection, STRICT_MODE)) {
if (fieldInfo != null && !fieldInfo.getAnnotations().isEmpty()) {
if (fieldInfo.isTypeOf(objectType) || fieldInfo.isParameterisedTypeOf(objectType) || fieldInfo.isArrayOf(objectType)) {
typeFieldInfoMap.put(directedRelationship, fieldInfo);
return fieldInfo;
}
}
}
// If it's outgoing, then proceed to find other matches
if (relationshipDirection != Direction.INCOMING) {
// 2nd, try to find a scalar or vector field annotated as the neo4j relationship type and direction, allowing for implied relationships
final Set<FieldInfo> candidateRelationshipFields = classInfo.candidateRelationshipFields(relationshipType, relationshipDirection, INFERRED_MODE);
for (FieldInfo fieldInfo : candidateRelationshipFields) {
if (fieldInfo != null && !fieldInfo.getAnnotations().isEmpty()) {
if (fieldInfo.isTypeOf(objectType) || fieldInfo.isParameterisedTypeOf(objectType) || fieldInfo.isArrayOf(objectType)) {
typeFieldInfoMap.put(directedRelationship, fieldInfo);
return fieldInfo;
}
}
}
// 3rd, try to find a "XYZ" field name where XYZ is derived from the relationship type
for (FieldInfo fieldInfo : candidateRelationshipFields) {
if (fieldInfo != null) {
if (fieldInfo.isTypeOf(objectType) || fieldInfo.isParameterisedTypeOf(objectType) || fieldInfo.isArrayOf(objectType)) {
typeFieldInfoMap.put(directedRelationship, fieldInfo);
return fieldInfo;
}
}
}
// 4th, try to find a unique field that has the same type as the parameter
List<FieldInfo> fieldInfos = classInfo.findFields(objectType);
if (fieldInfos.size() == 1) {
FieldInfo candidateField = fieldInfos.iterator().next();
if (candidateField.relationshipDirectionOrDefault(Direction.UNDIRECTED) != Direction.INCOMING) {
if (candidateField.relationshipTypeAnnotation() == null) {
typeFieldInfoMap.put(directedRelationship, candidateField);
return candidateField;
}
}
}
}
// walk up the object hierarchy
classInfo = classInfo.directSuperclass();
}
return null;
}
Aggregations