Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package graphql.schema;

import com.google.common.collect.ImmutableMap;
import graphql.PublicApi;

import java.util.Comparator;
Expand All @@ -18,9 +19,45 @@
@PublicApi
public class DefaultGraphqlTypeComparatorRegistry implements GraphqlTypeComparatorRegistry {

public static final Comparator<GraphQLSchemaElement> DEFAULT_COMPARATOR;
static {
DEFAULT_COMPARATOR = Comparator.comparing(element -> {
// This sensible order was taken from the original SchemaPrinter code. It ordered the types in this manner
private static final ImmutableMap<Class<? extends GraphQLSchemaElement>, Integer> SENSIBLE_ORDER =
ImmutableMap.<Class<? extends GraphQLSchemaElement>, Integer>builder()
.put(GraphQLDirective.class, 1)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This doesn't specify unfortunately how "schema { query: Foo ..}" element will be printed.

.put(GraphQLInterfaceType.class, 2)
.put(GraphQLUnionType.class, 3)
.put(GraphQLObjectType.class, 4)
.put(GraphQLEnumType.class, 5)
.put(GraphQLScalarType.class, 6)
.put(GraphQLInputObjectType.class, 7)
.build();

/**
* This orders the schema into a sensible grouped order
* @return a comparator that allows for sensible grouped order
*/
public static Comparator<GraphQLSchemaElement> sensibleGroupedOrder() {
return (o1, o2) -> {
o1 = unwrapElement(o1);
o2 = unwrapElement(o2);
int i1 = SENSIBLE_ORDER.getOrDefault(o1.getClass(), 0);
int i2 = SENSIBLE_ORDER.getOrDefault(o2.getClass(), 0);
int rc = i1 - i2;
if (rc == 0) {
rc = compareByName(o1, o2);
}
return rc;
};
}

private static GraphQLSchemaElement unwrapElement(GraphQLSchemaElement element) {
if (element instanceof GraphQLType) {
element = unwrapAll((GraphQLType) element);
}
return element;
}

private static int compareByName(GraphQLSchemaElement o1, GraphQLSchemaElement o2) {
return Comparator.comparing(element -> {
if (element instanceof GraphQLType) {
element = unwrapAll((GraphQLType) element);
}
Expand All @@ -29,9 +66,11 @@ public class DefaultGraphqlTypeComparatorRegistry implements GraphqlTypeComparat
} else {
return Objects.toString(element);
}
});
}).compare(o1, o2);
}

public static final Comparator<GraphQLSchemaElement> DEFAULT_COMPARATOR = sensibleGroupedOrder();

private Map<GraphqlTypeComparatorEnvironment, Comparator<?>> registry = new HashMap<>();

private DefaultGraphqlTypeComparatorRegistry() {
Expand Down Expand Up @@ -72,7 +111,7 @@ public static Builder newComparators() {

public static class Builder {

private Map<GraphqlTypeComparatorEnvironment, Comparator<?>> registry = new HashMap<>();
private final Map<GraphqlTypeComparatorEnvironment, Comparator<?>> registry = new HashMap<>();

/**
* Registers a {@code Comparator} with an environment to control its permitted scope of operation.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package graphql.schema;

import graphql.Assert;
import graphql.PublicApi;

import java.util.Objects;
Expand All @@ -10,7 +9,7 @@
* Defines the scope to control where the registered {@code Comparator} can be applied.
* <p>
* {@code elementType}s can be ordered within its {@code parentType} to restrict the {@code Comparator}s scope of operation.
* Otherwise supplying only the {@code elementType} results in the {@code Comparator} being reused across all matching {@code GraphQLType}s regardless of parent.
* Otherwise, supplying only the {@code elementType} results in the {@code Comparator} being reused across all matching {@code GraphQLType}s regardless of parent.
*/
@PublicApi
public class GraphqlTypeComparatorEnvironment {
Expand All @@ -20,7 +19,6 @@ public class GraphqlTypeComparatorEnvironment {
private Class<? extends GraphQLSchemaElement> elementType;

private GraphqlTypeComparatorEnvironment(Class<? extends GraphQLSchemaElement> parentType, Class<? extends GraphQLSchemaElement> elementType) {
Assert.assertNotNull(elementType, () -> "elementType can't be null");
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This needs to be relaxed because now we can have a GraphqlTypeComparatorEnvironment where there is only a parent type and not element type.

This was probably wrong in the oder code but because we never sorted the top level types we never noticed this.

this.parentType = parentType;
this.elementType = elementType;
}
Expand All @@ -33,7 +31,7 @@ public Class<? extends GraphQLSchemaElement> getParentType() {
}

/**
* @return The valid element type.
* @return The valid element type or {@code null} if not supplied.
*/
public Class<? extends GraphQLSchemaElement> getElementType() {
return elementType;
Expand Down
Loading