26
26
import org .springframework .data .repository .query .ReturnedType ;
27
27
28
28
import java .beans .PropertyDescriptor ;
29
- import java .util .ArrayList ;
30
29
import java .util .Collection ;
31
30
import java .util .Collections ;
31
+ import java .util .HashMap ;
32
32
import java .util .HashSet ;
33
- import java .util .List ;
33
+ import java .util .Map ;
34
34
35
35
/**
36
36
* This class is responsible for creating a List of {@link PropertyPath} entries that contains all reachable
39
39
@ API (status = API .Status .INTERNAL , since = "6.1.3" )
40
40
public final class PropertyFilterSupport {
41
41
42
- public static List <PropertyPath > getInputProperties (ResultProcessor resultProcessor , ProjectionFactory factory ,
43
- Neo4jMappingContext mappingContext ) {
42
+ public static Map <PropertyPath , Boolean > getInputProperties (ResultProcessor resultProcessor , ProjectionFactory factory ,
43
+ Neo4jMappingContext mappingContext ) {
44
44
45
45
ReturnedType returnedType = resultProcessor .getReturnedType ();
46
- List <PropertyPath > filteredProperties = new ArrayList <>();
46
+ Map <PropertyPath , Boolean > filteredProperties = new HashMap <>();
47
47
48
48
boolean isProjecting = returnedType .isProjecting ();
49
49
boolean isClosedProjection = factory .getProjectionInformation (returnedType .getReturnedType ()).isClosed ();
50
50
51
51
if (!isProjecting || !isClosedProjection ) {
52
- return Collections .emptyList ();
52
+ return Collections .emptyMap ();
53
53
}
54
54
55
55
for (String inputProperty : returnedType .getInputProperties ()) {
@@ -60,21 +60,21 @@ public static List<PropertyPath> getInputProperties(ResultProcessor resultProces
60
60
return filteredProperties ;
61
61
}
62
62
63
- static List <PropertyPath > addPropertiesFrom (Class <?> domainType , Class <?> returnType ,
63
+ static Map <PropertyPath , Boolean > addPropertiesFrom (Class <?> domainType , Class <?> returnType ,
64
64
ProjectionFactory projectionFactory ,
65
65
Neo4jMappingContext neo4jMappingContext ) {
66
66
67
67
ProjectionInformation projectionInformation = projectionFactory .getProjectionInformation (returnType );
68
- List <PropertyPath > propertyPaths = new ArrayList <>();
68
+ Map <PropertyPath , Boolean > propertyPaths = new HashMap <>();
69
69
for (PropertyDescriptor inputProperty : projectionInformation .getInputProperties ()) {
70
70
addPropertiesFrom (domainType , returnType , projectionFactory , propertyPaths , inputProperty .getName (), neo4jMappingContext );
71
71
}
72
72
return propertyPaths ;
73
73
}
74
74
75
75
private static void addPropertiesFrom (Class <?> domainType , Class <?> returnedType , ProjectionFactory factory ,
76
- Collection <PropertyPath > filteredProperties , String inputProperty ,
77
- Neo4jMappingContext mappingContext ) {
76
+ Map <PropertyPath , Boolean > filteredProperties , String inputProperty ,
77
+ Neo4jMappingContext mappingContext ) {
78
78
79
79
ProjectionInformation projectionInformation = factory .getProjectionInformation (returnedType );
80
80
PropertyPath propertyPath ;
@@ -93,33 +93,33 @@ private static void addPropertiesFrom(Class<?> domainType, Class<?> returnedType
93
93
// 2. Something that looks like an entity needs to get processed as such
94
94
// 3. Embedded projection
95
95
if (mappingContext .getConversionService ().isSimpleType (propertyType )) {
96
- filteredProperties .add (propertyPath );
96
+ filteredProperties .put (propertyPath , false );
97
97
} else if (mappingContext .hasPersistentEntityFor (propertyType )) {
98
- // avoid recursion / cycles
99
- if (propertyType .equals (domainType )) {
100
- return ;
101
- }
102
-
103
98
addPropertiesFromEntity (filteredProperties , propertyPath , propertyType , mappingContext , new HashSet <>());
104
99
} else {
105
100
ProjectionInformation nestedProjectionInformation = factory .getProjectionInformation (propertyType );
106
- filteredProperties .add (propertyPath );
107
101
// Closed projection should get handled as above (recursion)
108
102
if (nestedProjectionInformation .isClosed ()) {
103
+ filteredProperties .put (propertyPath , false );
109
104
for (PropertyDescriptor nestedInputProperty : nestedProjectionInformation .getInputProperties ()) {
110
105
PropertyPath nestedPropertyPath = propertyPath .nested (nestedInputProperty .getName ());
111
- filteredProperties .add (nestedPropertyPath );
106
+ if (propertyPath .hasNext () && (domainType .equals (propertyPath .getLeafProperty ().getOwningType ().getType ())
107
+ || returnedType .equals (propertyPath .getLeafProperty ().getOwningType ().getType ()))) {
108
+ break ;
109
+ }
110
+
112
111
addPropertiesFrom (domainType , returnedType , factory , filteredProperties ,
113
112
nestedPropertyPath .toDotPath (), mappingContext );
114
113
}
115
114
} else {
116
115
// an open projection at this place needs to get replaced with the matching (real) entity
116
+ filteredProperties .put (propertyPath , true );
117
117
processEntity (domainType , filteredProperties , inputProperty , mappingContext );
118
118
}
119
119
}
120
120
}
121
121
122
- private static void processEntity (Class <?> domainType , Collection <PropertyPath > filteredProperties ,
122
+ private static void processEntity (Class <?> domainType , Map <PropertyPath , Boolean > filteredProperties ,
123
123
String inputProperty , Neo4jMappingContext mappingContext ) {
124
124
125
125
Neo4jPersistentEntity <?> persistentEntity = mappingContext .getPersistentEntity (domainType );
@@ -131,59 +131,27 @@ private static void processEntity(Class<?> domainType, Collection<PropertyPath>
131
131
addPropertiesFromEntity (filteredProperties , propertyPath , propertyEntityType , mappingContext , new HashSet <>());
132
132
}
133
133
134
- private static void addPropertiesFromEntity (Collection <PropertyPath > filteredProperties , PropertyPath propertyPath ,
134
+ private static void addPropertiesFromEntity (Map <PropertyPath , Boolean > filteredProperties , PropertyPath propertyPath ,
135
135
Class <?> propertyType , Neo4jMappingContext mappingContext ,
136
136
Collection <Neo4jPersistentEntity <?>> processedEntities ) {
137
137
138
+ if (!mappingContext .hasPersistentEntityFor (propertyType )) {
139
+ throw new RuntimeException ("hmmmm" );
140
+ }
141
+
138
142
Neo4jPersistentEntity <?> persistentEntityFromProperty = mappingContext .getPersistentEntity (propertyType );
139
143
// break the recursion / cycles
140
144
if (hasProcessedEntity (persistentEntityFromProperty , processedEntities )) {
141
145
return ;
142
146
}
143
- processedEntities .add (persistentEntityFromProperty );
144
147
145
- // save base/root entity/projection type to avoid recursion later
146
- Class <?> pathRootType = propertyPath .getOwningType ().getType ();
147
- if (mappingContext .hasPersistentEntityFor (pathRootType )) {
148
- processedEntities .add (mappingContext .getPersistentEntity (pathRootType ));
149
- }
148
+ filteredProperties .put (propertyPath , true );
150
149
151
- takeAllPropertiesFromEntity (filteredProperties , propertyPath , mappingContext , persistentEntityFromProperty , processedEntities );
152
150
}
153
151
154
152
private static boolean hasProcessedEntity (Neo4jPersistentEntity <?> persistentEntityFromProperty ,
155
153
Collection <Neo4jPersistentEntity <?>> processedEntities ) {
156
154
157
155
return processedEntities .contains (persistentEntityFromProperty );
158
156
}
159
-
160
- private static void takeAllPropertiesFromEntity (Collection <PropertyPath > filteredProperties ,
161
- PropertyPath propertyPath , Neo4jMappingContext mappingContext ,
162
- Neo4jPersistentEntity <?> persistentEntityFromProperty ,
163
- Collection <Neo4jPersistentEntity <?>> processedEntities ) {
164
-
165
- filteredProperties .add (propertyPath );
166
-
167
- persistentEntityFromProperty .doWithAll (neo4jPersistentProperty -> {
168
- addPropertiesFromEntity (filteredProperties , propertyPath .nested (neo4jPersistentProperty .getFieldName ()), mappingContext , processedEntities );
169
- });
170
- }
171
-
172
- private static void addPropertiesFromEntity (Collection <PropertyPath > filteredProperties , PropertyPath propertyPath ,
173
- Neo4jMappingContext mappingContext ,
174
- Collection <Neo4jPersistentEntity <?>> processedEntities ) {
175
-
176
- // break the recursion / cycles
177
- if (filteredProperties .contains (propertyPath )) {
178
- return ;
179
- }
180
- Class <?> propertyType = propertyPath .getLeafType ();
181
- // simple types can get added directly to the list.
182
- if (mappingContext .getConversionService ().isSimpleType (propertyType )) {
183
- filteredProperties .add (propertyPath );
184
- // Other types are handled also as entities because there cannot be any nested projection within a real entity.
185
- } else if (mappingContext .hasPersistentEntityFor (propertyType )) {
186
- addPropertiesFromEntity (filteredProperties , propertyPath , propertyType , mappingContext , processedEntities );
187
- }
188
- }
189
157
}
0 commit comments