Skip to content

Commit ee4e67c

Browse files
committed
This makes the ENF code public
1 parent 4aedac7 commit ee4e67c

6 files changed

Lines changed: 292 additions & 58 deletions

‎src/main/java/graphql/normalized/ExecutableNormalizedField.java‎

Lines changed: 131 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import graphql.Assert;
66
import graphql.Internal;
77
import graphql.Mutable;
8+
import graphql.PublicApi;
89
import graphql.collect.ImmutableKit;
910
import graphql.introspection.Introspection;
1011
import graphql.language.Argument;
@@ -38,9 +39,13 @@
3839
import static java.util.stream.Collectors.toSet;
3940

4041
/**
41-
* Intentionally Mutable
42+
* An {@link ExecutableNormalizedField} represents a field in an executable graphql operation. Its models what
43+
* could be executed during a given operation.
44+
* <p>
45+
* This class is intentionally mutable for performance reasons since building immutable parent child
46+
* objects is too expensive.
4247
*/
43-
@Internal
48+
@PublicApi
4449
@Mutable
4550
public class ExecutableNormalizedField {
4651
private final String alias;
@@ -164,7 +169,7 @@ public boolean isConditional(@NotNull GraphQLSchema schema) {
164169
}
165170
}
166171

167-
/**
172+
/*
168173
*__typename is the only field in a union type that CAN be NOT conditional
169174
*/
170175
List<GraphQLFieldDefinition> fieldDefinitions = parent.getFieldDefinitions(schema);
@@ -175,7 +180,7 @@ public boolean isConditional(@NotNull GraphQLSchema schema) {
175180
}
176181
}
177182

178-
/**
183+
/*
179184
* This means there is no Union or Interface which could serve as unconditional parent
180185
*/
181186
if (objectTypeNames.size() > 1) {
@@ -232,39 +237,58 @@ private static GraphQLFieldDefinition resolveIntrospectionField(GraphQLSchema sc
232237
return null;
233238
}
234239

240+
@Internal
235241
public void addObjectTypeNames(Collection<String> objectTypeNames) {
236242
this.objectTypeNames.addAll(objectTypeNames);
237243
}
238244

245+
@Internal
239246
public void setObjectTypeNames(Collection<String> objectTypeNames) {
240247
this.objectTypeNames.clear();
241248
this.objectTypeNames.addAll(objectTypeNames);
242249
}
243250

251+
@Internal
244252
public void addChild(ExecutableNormalizedField executableNormalizedField) {
245253
this.children.add(executableNormalizedField);
246254
}
247255

256+
@Internal
248257
public void clearChildren() {
249258
this.children.clear();
250259
}
251260

252261
/**
253-
* All merged fields have the same name.
262+
* All merged fields have the same name so this is the name of the {@link ExecutableNormalizedField}.
254263
* <p>
255-
* WARNING: This is not always the key in the execution result, because of possible aliases. See {@link #getResultKey()}
264+
* WARNING: This is not always the key in the execution result, because of possible field aliases.
265+
*
266+
* @return the name of this {@link ExecutableNormalizedField}
256267
*
257-
* @return the name of of the merged fields.
268+
* @see #getResultKey()
269+
* @see #getAlias()
258270
*/
259271
public String getName() {
260272
return getFieldName();
261273
}
262274

263275
/**
264-
* Returns the key of this MergedFieldWithType for the overall result.
265-
* This is either an alias or the FieldWTC name.
276+
* @return the same value as {@link #getName()}
277+
*
278+
* @see #getResultKey()
279+
* @see #getAlias()
280+
*/
281+
public String getFieldName() {
282+
return fieldName;
283+
}
284+
285+
/**
286+
* Returns the result key of this {@link ExecutableNormalizedField} within the overall result.
287+
* This is either a field alias or the value of {@link #getName()}
288+
*
289+
* @return the result key for this {@link ExecutableNormalizedField}.
266290
*
267-
* @return the key for this MergedFieldWithType.
291+
* @see #getName()
268292
*/
269293
public String getResultKey() {
270294
if (alias != null) {
@@ -273,56 +297,80 @@ public String getResultKey() {
273297
return getName();
274298
}
275299

300+
/**
301+
* @return the field alias used or null if there is none
302+
*
303+
* @see #getResultKey()
304+
* @see #getName()
305+
*/
276306
public String getAlias() {
277307
return alias;
278308
}
279309

310+
/**
311+
* @return a list of the {@link Argument}s on the field
312+
*/
280313
public ImmutableList<Argument> getAstArguments() {
281314
return astArguments;
282315
}
283316

317+
/**
318+
* Returns an argument value as a {@link NormalizedInputValue} which contains its type name and its current value
319+
*
320+
* @param name the name of the argument
321+
*
322+
* @return an argument value
323+
*/
284324
public NormalizedInputValue getNormalizedArgument(String name) {
285325
return normalizedArguments.get(name);
286326
}
287327

328+
/**
329+
* @return a map of all the arguments in {@link NormalizedInputValue} form
330+
*/
288331
public ImmutableMap<String, NormalizedInputValue> getNormalizedArguments() {
289332
return normalizedArguments;
290333
}
291334

335+
/**
336+
* @return a map of the resolved argument values
337+
*/
292338
public LinkedHashMap<String, Object> getResolvedArguments() {
293339
return resolvedArguments;
294340
}
295341

296342

297-
public static Builder newNormalizedField() {
298-
return new Builder();
299-
}
300-
301-
302-
public String getFieldName() {
303-
return fieldName;
304-
}
305-
306-
307-
public ExecutableNormalizedField transform(Consumer<Builder> builderConsumer) {
308-
Builder builder = new Builder(this);
309-
builderConsumer.accept(builder);
310-
return builder.build();
311-
}
312-
313-
314343
/**
315-
* @return Warning: returns a Mutable Set. No defensive copy is made for performance reasons.
344+
* A {@link ExecutableNormalizedField} can sometimes (for non-concrete types like interfaces and unions)
345+
* have more than one object type it could be when executed. There is no way to know what it will be until
346+
* the field is executed over data and the type is resolved via a {@link graphql.schema.TypeResolver}.
347+
* <p>
348+
* This method returns all the possible types a field can be which is one or more {@link GraphQLObjectType}
349+
* names.
350+
* <p>
351+
* Warning: This returns a Mutable Set. No defensive copy is made for performance reasons.
352+
*
353+
* @return a set of the possible type names this field could be.
316354
*/
317355
public Set<String> getObjectTypeNames() {
318356
return objectTypeNames;
319357
}
320358

359+
360+
/**
361+
* This returns the first entry in {@link #getObjectTypeNames()}. Sometimes you know a field cant be more than one
362+
* type and this method is a shortcut one to help you.
363+
*
364+
* @return the first entry from
365+
*/
321366
public String getSingleObjectTypeName() {
322367
return objectTypeNames.iterator().next();
323368
}
324369

325370

371+
/**
372+
* @return a helper method show field details
373+
*/
326374
public String printDetails() {
327375
StringBuilder result = new StringBuilder();
328376
if (getAlias() != null) {
@@ -331,6 +379,9 @@ public String printDetails() {
331379
return result + objectTypeNamesToString() + "." + fieldName;
332380
}
333381

382+
/**
383+
* @return a helper method to show the object types names as a string
384+
*/
334385
public String objectTypeNamesToString() {
335386
if (objectTypeNames.size() == 1) {
336387
return objectTypeNames.iterator().next();
@@ -339,6 +390,12 @@ public String objectTypeNamesToString() {
339390
}
340391
}
341392

393+
/**
394+
* This returns the list of the result keys (see {@link #getResultKey()} that lead from this field upwards to
395+
* its parent field
396+
*
397+
* @return a list of the result keys from this {@link ExecutableNormalizedField} to the top of the operation via parent fields
398+
*/
342399
public List<String> getListOfResultKeys() {
343400
LinkedList<String> list = new LinkedList<>();
344401
ExecutableNormalizedField current = this;
@@ -349,10 +406,20 @@ public List<String> getListOfResultKeys() {
349406
return list;
350407
}
351408

409+
/**
410+
* @return the children of the {@link ExecutableNormalizedField}
411+
*/
352412
public List<ExecutableNormalizedField> getChildren() {
353413
return children;
354414
}
355415

416+
/**
417+
* Returns the list of child fields that would have the same result key
418+
*
419+
* @param resultKey the result key to check
420+
*
421+
* @return a list of all direct {@link ExecutableNormalizedField} children with the specified result key
422+
*/
356423
public List<ExecutableNormalizedField> getChildrenWithSameResultKey(String resultKey) {
357424
return FpKit.filterList(children, child -> child.getResultKey().equals(resultKey));
358425
}
@@ -380,14 +447,24 @@ public List<ExecutableNormalizedField> getChildren(String objectTypeName) {
380447
.collect(toList());
381448
}
382449

450+
/**
451+
* the level of the {@link ExecutableNormalizedField} in the operation hierarchy with top level fields
452+
* starting at 1
453+
*
454+
* @return the level of the {@link ExecutableNormalizedField} in the operation hierarchy
455+
*/
383456
public int getLevel() {
384457
return level;
385458
}
386459

460+
/**
461+
* @return the parent of this {@link ExecutableNormalizedField} or null if it's a top level field
462+
*/
387463
public ExecutableNormalizedField getParent() {
388464
return parent;
389465
}
390466

467+
@Internal
391468
public void replaceParent(ExecutableNormalizedField newParent) {
392469
this.parent = newParent;
393470
}
@@ -404,6 +481,11 @@ public String toString() {
404481
}
405482

406483

484+
/**
485+
* Traverse from this {@link ExecutableNormalizedField} down into itself and all of its children
486+
*
487+
* @param consumer the callback for each {@link ExecutableNormalizedField} in the hierarchy.
488+
*/
407489
public void traverseSubTree(Consumer<ExecutableNormalizedField> consumer) {
408490
this.getChildren().forEach(child -> {
409491
traverseImpl(child, consumer, 1, Integer.MAX_VALUE);
@@ -423,6 +505,27 @@ private void traverseImpl(ExecutableNormalizedField root,
423505
});
424506
}
425507

508+
/**
509+
* @return a {@link Builder} of {@link ExecutableNormalizedField}s
510+
*/
511+
public static Builder newNormalizedField() {
512+
return new Builder();
513+
}
514+
515+
516+
/**
517+
* Allows this {@link ExecutableNormalizedField} to be transformed via a {@link Builder} consumer callback
518+
*
519+
* @param builderConsumer the consumer given a builder
520+
*
521+
* @return a new transformed {@link ExecutableNormalizedField}
522+
*/
523+
public ExecutableNormalizedField transform(Consumer<Builder> builderConsumer) {
524+
Builder builder = new Builder(this);
525+
builderConsumer.accept(builder);
526+
return builder.build();
527+
}
528+
426529
public static class Builder {
427530
private LinkedHashSet<String> objectTypeNames = new LinkedHashSet<>();
428531
private String fieldName;

0 commit comments

Comments
 (0)