Search in sources :

Example 1 with SCHEMA_ELEMENT_ADAPTER

use of graphql.schema.GraphQLSchemaElementAdapter.SCHEMA_ELEMENT_ADAPTER in project graphql-java by graphql-java.

the class SchemaTransformer method traverseAndTransform.

private boolean traverseAndTransform(DummyRoot dummyRoot, Map<String, GraphQLNamedType> changedTypes, Map<String, GraphQLTypeReference> typeReferences, GraphQLTypeVisitor visitor, GraphQLCodeRegistry.Builder codeRegistry) {
    List<NodeZipper<GraphQLSchemaElement>> zippers = new LinkedList<>();
    Map<GraphQLSchemaElement, NodeZipper<GraphQLSchemaElement>> zipperByNodeAfterTraversing = new LinkedHashMap<>();
    Map<GraphQLSchemaElement, NodeZipper<GraphQLSchemaElement>> zipperByOriginalNode = new LinkedHashMap<>();
    Map<NodeZipper<GraphQLSchemaElement>, List<List<Breadcrumb<GraphQLSchemaElement>>>> breadcrumbsByZipper = new LinkedHashMap<>();
    Map<GraphQLSchemaElement, List<GraphQLSchemaElement>> reverseDependencies = new LinkedHashMap<>();
    Map<String, List<GraphQLSchemaElement>> typeRefReverseDependencies = new LinkedHashMap<>();
    TraverserVisitor<GraphQLSchemaElement> nodeTraverserVisitor = new TraverserVisitor<GraphQLSchemaElement>() {

        @Override
        public TraversalControl enter(TraverserContext<GraphQLSchemaElement> context) {
            GraphQLSchemaElement currentSchemaElement = context.thisNode();
            if (currentSchemaElement == dummyRoot) {
                return TraversalControl.CONTINUE;
            }
            if (currentSchemaElement instanceof GraphQLTypeReference) {
                GraphQLTypeReference typeRef = (GraphQLTypeReference) currentSchemaElement;
                typeReferences.put(typeRef.getName(), typeRef);
            }
            NodeZipper<GraphQLSchemaElement> nodeZipper = new NodeZipper<>(currentSchemaElement, context.getBreadcrumbs(), SCHEMA_ELEMENT_ADAPTER);
            context.setVar(NodeZipper.class, nodeZipper);
            context.setVar(NodeAdapter.class, SCHEMA_ELEMENT_ADAPTER);
            int zippersBefore = zippers.size();
            TraversalControl result = currentSchemaElement.accept(context, visitor);
            // detection if the node was changed
            if (zippersBefore + 1 == zippers.size()) {
                nodeZipper = zippers.get(zippers.size() - 1);
                if (context.originalThisNode() instanceof GraphQLNamedType && context.isChanged()) {
                    GraphQLNamedType originalNamedType = (GraphQLNamedType) context.originalThisNode();
                    GraphQLNamedType changedNamedType = (GraphQLNamedType) context.thisNode();
                    if (!originalNamedType.getName().equals(changedNamedType.getName())) {
                        changedTypes.put(originalNamedType.getName(), changedNamedType);
                    }
                }
            }
            zipperByOriginalNode.put(context.originalThisNode(), nodeZipper);
            if (context.isDeleted()) {
                zipperByNodeAfterTraversing.put(context.originalThisNode(), nodeZipper);
            } else {
                zipperByNodeAfterTraversing.put(context.thisNode(), nodeZipper);
            }
            breadcrumbsByZipper.put(nodeZipper, new ArrayList<>());
            breadcrumbsByZipper.get(nodeZipper).add(context.getBreadcrumbs());
            if (nodeZipper.getModificationType() != NodeZipper.ModificationType.DELETE) {
                reverseDependencies.computeIfAbsent(context.thisNode(), ign -> new ArrayList<>()).add(context.getParentNode());
                if (context.originalThisNode() instanceof GraphQLTypeReference) {
                    String typeName = ((GraphQLTypeReference) context.originalThisNode()).getName();
                    typeRefReverseDependencies.computeIfAbsent(typeName, ign -> new ArrayList<>()).add(context.getParentNode());
                }
            }
            return result;
        }

        @Override
        public TraversalControl leave(TraverserContext<GraphQLSchemaElement> context) {
            return TraversalControl.CONTINUE;
        }

        @Override
        public TraversalControl backRef(TraverserContext<GraphQLSchemaElement> context) {
            NodeZipper<GraphQLSchemaElement> zipper = zipperByOriginalNode.get(context.thisNode());
            breadcrumbsByZipper.get(zipper).add(context.getBreadcrumbs());
            if (zipper.getModificationType() == DELETE) {
                return CONTINUE;
            }
            visitor.visitBackRef(context);
            List<GraphQLSchemaElement> reverseDependenciesForCurNode = reverseDependencies.get(zipper.getCurNode());
            assertNotNull(reverseDependenciesForCurNode);
            reverseDependenciesForCurNode.add(context.getParentNode());
            return TraversalControl.CONTINUE;
        }
    };
    Traverser<GraphQLSchemaElement> traverser = Traverser.depthFirstWithNamedChildren(SCHEMA_ELEMENT_ADAPTER::getNamedChildren, zippers, null);
    if (codeRegistry != null) {
        traverser.rootVar(GraphQLCodeRegistry.Builder.class, codeRegistry);
    }
    traverser.traverse(dummyRoot, nodeTraverserVisitor);
    List<List<GraphQLSchemaElement>> stronglyConnectedTopologicallySorted = getStronglyConnectedComponentsTopologicallySorted(reverseDependencies, typeRefReverseDependencies);
    return zipUpToDummyRoot(zippers, stronglyConnectedTopologicallySorted, breadcrumbsByZipper, zipperByNodeAfterTraversing);
}
Also used : TraversalControl(graphql.util.TraversalControl) Traverser(graphql.util.Traverser) SCHEMA_ELEMENT_ADAPTER(graphql.schema.GraphQLSchemaElementAdapter.SCHEMA_ELEMENT_ADAPTER) HashMap(java.util.HashMap) Multimap(com.google.common.collect.Multimap) NodeLocation(graphql.util.NodeLocation) StronglyConnectedComponentsTopologicallySorted.getStronglyConnectedComponentsTopologicallySorted(graphql.schema.impl.StronglyConnectedComponentsTopologicallySorted.getStronglyConnectedComponentsTopologicallySorted) TraverserContext(graphql.util.TraverserContext) ArrayList(java.util.ArrayList) LinkedHashMap(java.util.LinkedHashMap) Breadcrumb(graphql.util.Breadcrumb) Assert.assertShouldNeverHappen(graphql.Assert.assertShouldNeverHappen) NodeAdapter(graphql.util.NodeAdapter) Map(java.util.Map) SchemaElementChildrenContainer.newSchemaElementChildrenContainer(graphql.schema.SchemaElementChildrenContainer.newSchemaElementChildrenContainer) LinkedList(java.util.LinkedList) LinkedHashMultimap(com.google.common.collect.LinkedHashMultimap) LinkedHashSet(java.util.LinkedHashSet) REPLACE(graphql.util.NodeZipper.ModificationType.REPLACE) TraverserVisitor(graphql.util.TraverserVisitor) Iterator(java.util.Iterator) CONTINUE(graphql.util.TraversalControl.CONTINUE) Collection(java.util.Collection) Set(java.util.Set) DELETE(graphql.util.NodeZipper.ModificationType.DELETE) String.format(java.lang.String.format) Consumer(java.util.function.Consumer) NodeZipper(graphql.util.NodeZipper) List(java.util.List) PublicApi(graphql.PublicApi) Assert.assertNotNull(graphql.Assert.assertNotNull) Assert.assertNotEmpty(graphql.Assert.assertNotEmpty) Collections(java.util.Collections) ArrayList(java.util.ArrayList) TraverserContext(graphql.util.TraverserContext) LinkedHashMap(java.util.LinkedHashMap) TraverserVisitor(graphql.util.TraverserVisitor) TraversalControl(graphql.util.TraversalControl) ArrayList(java.util.ArrayList) LinkedList(java.util.LinkedList) List(java.util.List) SCHEMA_ELEMENT_ADAPTER(graphql.schema.GraphQLSchemaElementAdapter.SCHEMA_ELEMENT_ADAPTER) Breadcrumb(graphql.util.Breadcrumb) LinkedList(java.util.LinkedList) NodeZipper(graphql.util.NodeZipper)

Aggregations

LinkedHashMultimap (com.google.common.collect.LinkedHashMultimap)1 Multimap (com.google.common.collect.Multimap)1 Assert.assertNotEmpty (graphql.Assert.assertNotEmpty)1 Assert.assertNotNull (graphql.Assert.assertNotNull)1 Assert.assertShouldNeverHappen (graphql.Assert.assertShouldNeverHappen)1 PublicApi (graphql.PublicApi)1 SCHEMA_ELEMENT_ADAPTER (graphql.schema.GraphQLSchemaElementAdapter.SCHEMA_ELEMENT_ADAPTER)1 SchemaElementChildrenContainer.newSchemaElementChildrenContainer (graphql.schema.SchemaElementChildrenContainer.newSchemaElementChildrenContainer)1 StronglyConnectedComponentsTopologicallySorted.getStronglyConnectedComponentsTopologicallySorted (graphql.schema.impl.StronglyConnectedComponentsTopologicallySorted.getStronglyConnectedComponentsTopologicallySorted)1 Breadcrumb (graphql.util.Breadcrumb)1 NodeAdapter (graphql.util.NodeAdapter)1 NodeLocation (graphql.util.NodeLocation)1 NodeZipper (graphql.util.NodeZipper)1 DELETE (graphql.util.NodeZipper.ModificationType.DELETE)1 REPLACE (graphql.util.NodeZipper.ModificationType.REPLACE)1 TraversalControl (graphql.util.TraversalControl)1 CONTINUE (graphql.util.TraversalControl.CONTINUE)1 Traverser (graphql.util.Traverser)1 TraverserContext (graphql.util.TraverserContext)1 TraverserVisitor (graphql.util.TraverserVisitor)1