All Downloads are FREE. Search and download functionalities are using the official Maven repository.

graphql.validation.RulesVisitor Maven / Gradle / Ivy

The newest version!
package graphql.validation;


import graphql.language.*;

import java.util.*;

public class RulesVisitor implements QueryLanguageVisitor {

    private final List rules = new ArrayList<>();
    private ValidationContext validationContext;
    private boolean subVisitor;
    private List rulesVisitingFragmentSpreads = new ArrayList<>();
    private Map> rulesToSkipByUntilNode = new IdentityHashMap<>();
    private Set rulesToSkip = new LinkedHashSet<>();

    public RulesVisitor(ValidationContext validationContext, List rules) {
        this(validationContext, rules, false);
    }

    public RulesVisitor(ValidationContext validationContext, List rules, boolean subVisitor) {
        this.validationContext = validationContext;
        this.subVisitor = subVisitor;
        this.rules.addAll(rules);
        this.subVisitor = subVisitor;
        findRulesVisitingFragmentSpreads();
    }

    private void findRulesVisitingFragmentSpreads() {
        for (AbstractRule rule : rules) {
            if (rule.isVisitFragmentSpreads()) {
                rulesVisitingFragmentSpreads.add(rule);
            }
        }
    }

    @Override
    public void enter(Node node, List ancestors) {
//        System.out.println("enter: " + node);
        validationContext.getTraversalContext().enter(node, ancestors);
        Set tmpRulesSet = new LinkedHashSet<>(this.rules);
        tmpRulesSet.removeAll(rulesToSkip);
        List rulesToConsider = new ArrayList<>(tmpRulesSet);
        if (node instanceof Argument) {
            checkArgument((Argument) node, rulesToConsider);
        } else if (node instanceof TypeName) {
            checkTypeName((TypeName) node, rulesToConsider);
        } else if (node instanceof VariableDefinition) {
            checkVariableDefinition((VariableDefinition) node, rulesToConsider);
        } else if (node instanceof Field) {
            checkField((Field) node, rulesToConsider);
        } else if (node instanceof InlineFragment) {
            checkInlineFragment((InlineFragment) node, rulesToConsider);
        } else if (node instanceof Directive) {
            checkDirective((Directive) node, ancestors, rulesToConsider);
        } else if (node instanceof FragmentSpread) {
            checkFragmentSpread((FragmentSpread) node, rulesToConsider, ancestors);
        } else if (node instanceof FragmentDefinition) {
            checkFragmentDefinition((FragmentDefinition) node, rulesToConsider);
        } else if (node instanceof OperationDefinition) {
            checkOperationDefinition((OperationDefinition) node, rulesToConsider);
        } else if (node instanceof VariableReference) {
            checkVariable((VariableReference) node, rulesToConsider);
        } else if (node instanceof SelectionSet) {
            checkSelectionSet((SelectionSet) node, rulesToConsider);
        }

    }


    private void checkArgument(Argument node, List rules) {
        for (AbstractRule rule : rules) {
            rule.checkArgument(node);
        }
    }

    private void checkTypeName(TypeName node, List rules) {
        for (AbstractRule rule : rules) {
            rule.checkTypeName(node);
        }
    }


    private void checkVariableDefinition(VariableDefinition variableDefinition, List rules) {
        for (AbstractRule rule : rules) {
            rule.checkVariableDefinition(variableDefinition);
        }
    }

    private void checkField(Field field, List rules) {
        for (AbstractRule rule : rules) {
            rule.checkField(field);
        }
    }

    private void checkInlineFragment(InlineFragment inlineFragment, List rules) {
        for (AbstractRule rule : rules) {
            rule.checkInlineFragment(inlineFragment);
        }
    }

    private void checkDirective(Directive directive, List ancestors, List rules) {
        for (AbstractRule rule : rules) {
            rule.checkDirective(directive, ancestors);
        }
    }

    private void checkFragmentSpread(FragmentSpread fragmentSpread, List rules, List ancestors) {
        for (AbstractRule rule : rules) {
            rule.checkFragmentSpread(fragmentSpread);
        }
        List rulesVisitingFragmentSpreads = getRulesVisitingFragmentSpreads(rules);
        if (rulesVisitingFragmentSpreads.size() > 0) {
            FragmentDefinition fragment = validationContext.getFragment(fragmentSpread.getName());
            if (fragment != null && !ancestors.contains(fragment)) {
                new LanguageTraversal(ancestors).traverse(fragment, new RulesVisitor(validationContext, rulesVisitingFragmentSpreads, true));
            }
        }
    }

    private List getRulesVisitingFragmentSpreads(List rules) {
        List result = new ArrayList<>();
        for (AbstractRule rule : rules) {
            if (rule.isVisitFragmentSpreads()) result.add(rule);
        }
        return result;
    }


    private void checkFragmentDefinition(FragmentDefinition fragmentDefinition, List rules) {
        if (!subVisitor) {
            rulesToSkipByUntilNode.put(fragmentDefinition, new ArrayList<>(rulesVisitingFragmentSpreads));
            rulesToSkip.addAll(rulesVisitingFragmentSpreads);
        }


        for (AbstractRule rule : rules) {
            if (!subVisitor && (rule.isVisitFragmentSpreads())) continue;
            rule.checkFragmentDefinition(fragmentDefinition);
        }

    }

    private void checkOperationDefinition(OperationDefinition operationDefinition, List rules) {
        for (AbstractRule rule : rules) {
            rule.checkOperationDefinition(operationDefinition);
        }
    }

    private void checkSelectionSet(SelectionSet selectionSet, List rules) {
        for (AbstractRule rule : rules) {
            rule.checkSelectionSet(selectionSet);
        }
    }

    private void checkVariable(VariableReference variableReference, List rules) {
        for (AbstractRule rule : rules) {
            rule.checkVariable(variableReference);
        }
    }


    @Override
    public void leave(Node node, List ancestors) {
        validationContext.getTraversalContext().leave(node, ancestors);

        if (node instanceof Document) {
            documentFinished((Document) node);
        } else if (node instanceof OperationDefinition) {
            leaveOperationDefinition((OperationDefinition) node);
        } else if (node instanceof SelectionSet) {
            leaveSelectionSet((SelectionSet) node);
        }

        if (rulesToSkipByUntilNode.containsKey(node)) {
            rulesToSkip.removeAll(rulesToSkipByUntilNode.get(node));
            rulesToSkipByUntilNode.remove(node);
        }


    }

    private void leaveSelectionSet(SelectionSet selectionSet) {
        for (AbstractRule rule : rules) {
            rule.leaveSelectionSet(selectionSet);
        }
    }

    private void leaveOperationDefinition(OperationDefinition operationDefinition) {
        for (AbstractRule rule : rules) {
            rule.leaveOperationDefinition(operationDefinition);
        }
    }

    private void documentFinished(Document document) {
        for (AbstractRule rule : rules) {
            rule.documentFinished(document);
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy