/
DefaultFactoryDefinition.java
180 lines (140 loc) · 5.26 KB
/
DefaultFactoryDefinition.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
/*
* Copyright (C) 2010-2023 Structr GmbH
*
* This file is part of Structr <http://structr.org>.
*
* Structr is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* Structr is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Structr. If not, see <http://www.gnu.org/licenses/>.
*/
package org.structr.common;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.structr.api.graph.Node;
import org.structr.api.graph.Relationship;
import org.structr.core.GraphObject;
import org.structr.core.app.StructrApp;
import org.structr.core.entity.AbstractNode;
import org.structr.core.entity.AbstractRelationship;
import org.structr.core.entity.GenericNode;
import org.structr.core.entity.GenericRelationship;
import org.structr.core.graph.TransactionCommand;
/**
* The default factory for unknown types in structr. When structr needs to
* instantiate a node with an unknown / unregistered type, this class is
* used.
*
*
*/
public class DefaultFactoryDefinition implements FactoryDefinition {
private static final Logger logger = LoggerFactory.getLogger(DefaultFactoryDefinition.class.getName());
public static final String COMBINED_RELATIONSHIP_KEY_SEP = " ";
public static final Class GENERIC_NODE_TYPE = GenericNode.class;
public static final Class GENERIC_REL_TYPE = GenericRelationship.class;
@Override
public AbstractRelationship createGenericRelationship() {
return new GenericRelationship();
}
@Override
public Class getGenericRelationshipType() {
return GENERIC_REL_TYPE;
}
@Override
public AbstractNode createGenericNode() {
return new GenericNode();
}
@Override
public Class getGenericNodeType() {
return GENERIC_NODE_TYPE;
}
@Override
public boolean isGeneric(Class<?> entityClass) {
return
GenericRelationship.class.isAssignableFrom(entityClass)
||
GenericNode.class.isAssignableFrom(entityClass);
}
@Override
public Class determineNodeType(final Node node) {
// check deletion first
if (TransactionCommand.isDeleted(node)) {
return null;
}
final String type = GraphObject.type.dbName();
if (node.hasProperty(type)) {
final Object obj = node.getProperty(type);
if (obj != null) {
final Class nodeType = StructrApp.getConfiguration().getNodeEntities().get(obj.toString());
if (nodeType != null) {
return nodeType;
}
}
}
return getGenericNodeType();
}
@Override
public Class determineRelationshipType(Relationship relationship) {
if (TransactionCommand.isDeleted(relationship)) {
return null;
}
final String type = GraphObject.type.dbName();
final Node startNode = relationship.getStartNode();
final Node endNode = relationship.getEndNode();
if (startNode == null || endNode == null) {
return null;
}
// first try: duck-typing
final String sourceType = startNode.hasProperty(type) ? startNode.getProperty(type).toString() : "";
final String targetType = endNode.hasProperty(type) ? endNode.getProperty(type).toString() : "";
final String relType = relationship.getType().name();
final Class entityType = getClassForCombinedType(sourceType, relType, targetType);
if (entityType != null) {
logger.debug("Class for assembled combined {}", entityType.getName());
return entityType;
}
// first try: type property
if (relationship.hasProperty(type)) {
Object obj = relationship.getProperty(type);
if (obj != null) {
Class relationClass = StructrApp.getConfiguration().getRelationshipEntityClass(obj.toString());
if (relationClass != null) {
StructrApp.getConfiguration().setRelationClassForCombinedType(sourceType, relType, targetType, relationClass);
return relationClass;
}
}
}
// fallback to old type
final String combinedTypeName = "combinedType";
if (relationship.hasProperty(combinedTypeName)) {
Object obj = relationship.getProperty(combinedTypeName);
if (obj != null) {
Class classForCombinedType = getClassForCombinedType(obj.toString());
if (classForCombinedType != null) {
return classForCombinedType;
}
}
}
// logger.warn("No instantiable class for relationship found for {} {} {}, returning generic relationship class.", new Object[] { sourceType, relType, targetType });
return getGenericRelationshipType();
}
private Class getClassForCombinedType(final String combinedType) {
final String[] parts = StringUtils.split(combinedType, COMBINED_RELATIONSHIP_KEY_SEP);
final String sourceType = parts[0];
final String relType = parts[1];
final String targetType = parts[2];
return getClassForCombinedType(sourceType, relType, targetType);
}
private Class getClassForCombinedType(final String sourceType, final String relType, final String targetType) {
return StructrApp.getConfiguration().getRelationClassForCombinedType(sourceType, relType, targetType);
}
}