21
21
import java .util .Iterator ;
22
22
import java .util .List ;
23
23
import java .util .function .Function ;
24
- import java .util .stream .Collectors ;
25
24
26
25
import graphql .schema .DataFetchingFieldSelectionSet ;
27
26
import graphql .schema .SelectedField ;
28
27
29
28
import org .springframework .data .mapping .PropertyPath ;
30
29
import org .springframework .data .util .TypeInformation ;
30
+ import org .springframework .util .CollectionUtils ;
31
31
32
32
/**
33
33
* Utility to compute {@link PropertyPath property paths} from
@@ -46,90 +46,60 @@ class PropertySelection {
46
46
47
47
private final List <PropertyPath > propertyPaths ;
48
48
49
+
49
50
private PropertySelection (List <PropertyPath > propertyPaths ) {
50
51
this .propertyPaths = propertyPaths ;
51
52
}
52
53
54
+
55
+ /**
56
+ * @return the property paths as list.
57
+ */
58
+ public List <String > toList () {
59
+ return this .propertyPaths .stream ().map (PropertyPath ::toDotPath ).toList ();
60
+ }
61
+
62
+
53
63
/**
54
64
* Create a property selection for the given {@link TypeInformation type} and
55
65
* {@link DataFetchingFieldSelectionSet}.
56
66
*
57
- * @param typeInformation the type to inspect
67
+ * @param typeInfo the type to inspect
58
68
* @param selectionSet the field selection to apply
59
69
* @return a property selection holding all selectable property paths.
60
70
*/
61
- public static PropertySelection create (TypeInformation <?> typeInformation ,
62
- DataFetchingFieldSelectionSet selectionSet ) {
63
- return create (typeInformation , new DataFetchingFieldSelection (selectionSet ));
71
+ public static PropertySelection create (TypeInformation <?> typeInfo , DataFetchingFieldSelectionSet selectionSet ) {
72
+ FieldSelection selection = new DataFetchingFieldSelection (selectionSet );
73
+ List <PropertyPath > paths = getPropertyPaths (typeInfo , selection , path -> PropertyPath .from (path , typeInfo ));
74
+ return new PropertySelection (paths );
64
75
}
65
76
66
- private static PropertySelection create (TypeInformation <?> typeInformation , FieldSelection selection ) {
67
- List <PropertyPath > propertyPaths = collectPropertyPaths (typeInformation ,
68
- selection ,
69
- path -> PropertyPath .from (path , typeInformation ));
70
- return new PropertySelection (propertyPaths );
71
- }
77
+ private static List <PropertyPath > getPropertyPaths (
78
+ TypeInformation <?> typeInfo , FieldSelection selection , Function <String , PropertyPath > pathFactory ) {
72
79
73
- private static List <PropertyPath > collectPropertyPaths (TypeInformation <?> typeInformation ,
74
- FieldSelection selection , Function <String , PropertyPath > propertyPathFactory ) {
75
- List <PropertyPath > propertyPaths = new ArrayList <>();
80
+ List <PropertyPath > result = new ArrayList <>();
76
81
77
82
for (SelectedField selectedField : selection ) {
78
-
79
83
String propertyName = selectedField .getName ();
80
- TypeInformation <?> property = typeInformation .getProperty (propertyName );
81
-
82
- if (property == null ) {
84
+ TypeInformation <?> propertyTypeInfo = typeInfo .getProperty (propertyName );
85
+ if (propertyTypeInfo == null ) {
83
86
continue ;
84
87
}
85
88
86
- PropertyPath propertyPath = propertyPathFactory .apply (propertyName );
87
- FieldSelection nestedSelection = selection .select (selectedField );
88
-
89
- List <PropertyPath > pathsToAdd = Collections .singletonList (propertyPath );
90
-
91
- if (!nestedSelection .isEmpty () && property .getActualType () != null ) {
92
- List <PropertyPath > nestedPaths = collectPropertyPaths (property .getRequiredActualType (),
93
- nestedSelection , propertyPath ::nested );
89
+ PropertyPath propertyPath = pathFactory .apply (propertyName );
94
90
95
- if (!nestedPaths .isEmpty ()) {
96
- pathsToAdd = nestedPaths ;
97
- }
91
+ List <PropertyPath > nestedPaths = null ;
92
+ FieldSelection nestedSelection = selection .select (selectedField );
93
+ if (!nestedSelection .isEmpty () && propertyTypeInfo .getActualType () != null ) {
94
+ TypeInformation <?> actualType = propertyTypeInfo .getRequiredActualType ();
95
+ nestedPaths = getPropertyPaths (actualType , nestedSelection , propertyPath ::nested );
98
96
}
99
97
100
- propertyPaths .addAll (pathsToAdd );
101
- }
102
-
103
- return propertyPaths ;
104
- }
105
-
106
- /**
107
- * @return the property paths as list.
108
- */
109
- public List <String > toList () {
110
- return this .propertyPaths .stream ().map (PropertyPath ::toDotPath ).collect (Collectors .toList ());
111
- }
112
-
113
-
114
- enum EmptyFieldSelection implements FieldSelection {
115
-
116
- INSTANCE ;
117
-
118
- @ Override
119
- public boolean isEmpty () {
120
- return true ;
121
- }
122
-
123
- @ Override
124
- public FieldSelection select (SelectedField field ) {
125
- return INSTANCE ;
126
- }
127
-
128
- @ Override
129
- public Iterator <SelectedField > iterator () {
130
- return Collections .emptyIterator ();
98
+ result .addAll (CollectionUtils .isEmpty (nestedPaths ) ?
99
+ Collections .singletonList (propertyPath ) : nestedPaths );
131
100
}
132
101
102
+ return result ;
133
103
}
134
104
135
105
@@ -155,7 +125,7 @@ interface FieldSelection extends Iterable<SelectedField> {
155
125
}
156
126
157
127
158
- static class DataFetchingFieldSelection implements FieldSelection {
128
+ private static class DataFetchingFieldSelection implements FieldSelection {
159
129
160
130
private final List <SelectedField > selectedFields ;
161
131
@@ -166,8 +136,7 @@ static class DataFetchingFieldSelection implements FieldSelection {
166
136
this .allFields = selectionSet .getFields ();
167
137
}
168
138
169
- private DataFetchingFieldSelection (List <SelectedField > selectedFields ,
170
- List <SelectedField > allFields ) {
139
+ private DataFetchingFieldSelection (List <SelectedField > selectedFields , List <SelectedField > allFields ) {
171
140
this .selectedFields = selectedFields ;
172
141
this .allFields = allFields ;
173
142
}
@@ -179,16 +148,18 @@ public boolean isEmpty() {
179
148
180
149
@ Override
181
150
public FieldSelection select (SelectedField field ) {
182
- List <SelectedField > selectedFields = new ArrayList <>() ;
151
+ List <SelectedField > selectedFields = null ;
183
152
184
- for (SelectedField selectedField : allFields ) {
153
+ for (SelectedField selectedField : this . allFields ) {
185
154
if (field .equals (selectedField .getParentField ())) {
155
+ selectedFields = (selectedFields != null ? selectedFields : new ArrayList <>());
186
156
selectedFields .add (selectedField );
187
157
}
188
158
}
189
159
190
- return (selectedFields .isEmpty () ? EmptyFieldSelection .INSTANCE
191
- : new DataFetchingFieldSelection (selectedFields , allFields ));
160
+ return (selectedFields != null ?
161
+ new DataFetchingFieldSelection (selectedFields , this .allFields ) :
162
+ EmptyFieldSelection .INSTANCE );
192
163
}
193
164
194
165
@ Override
@@ -198,4 +169,26 @@ public Iterator<SelectedField> iterator() {
198
169
199
170
}
200
171
172
+
173
+ enum EmptyFieldSelection implements FieldSelection {
174
+
175
+ INSTANCE ;
176
+
177
+ @ Override
178
+ public boolean isEmpty () {
179
+ return true ;
180
+ }
181
+
182
+ @ Override
183
+ public FieldSelection select (SelectedField field ) {
184
+ return INSTANCE ;
185
+ }
186
+
187
+ @ Override
188
+ public Iterator <SelectedField > iterator () {
189
+ return Collections .emptyIterator ();
190
+ }
191
+
192
+ }
193
+
201
194
}
0 commit comments