com.apollographql.federation.graphqljava.directives.LinkImportsRenamingVisitor Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of federation-graphql-java-support Show documentation
Show all versions of federation-graphql-java-support Show documentation
GraphQL Java server support for Apollo Federation
The newest version!
package com.apollographql.federation.graphqljava.directives;
import static graphql.util.TreeTransformerUtil.changeNode;
import com.apollographql.federation.graphqljava.exceptions.UnsupportedRenameException;
import graphql.language.DirectiveDefinition;
import graphql.language.EnumTypeDefinition;
import graphql.language.NamedNode;
import graphql.language.Node;
import graphql.language.NodeVisitorStub;
import graphql.language.ScalarTypeDefinition;
import graphql.language.TypeName;
import graphql.util.TraversalControl;
import graphql.util.TraverserContext;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
/**
* GraphQL schema node visitor that supports renaming imported elements specified in the @link
*
directive.
*/
class LinkImportsRenamingVisitor extends NodeVisitorStub {
private static final Set BUILT_IN_SCALARS =
new HashSet<>(Arrays.asList("String", "Boolean", "Int", "Float", "ID"));
private final Map fed2Imports;
public LinkImportsRenamingVisitor(Map fed2Imports) {
this.fed2Imports = fed2Imports;
}
@Override
protected TraversalControl visitNode(Node node, TraverserContext context) {
if (node instanceof NamedNode) {
Node newNode = null;
if (node instanceof TypeName) {
String newName = newName(((NamedNode>) node).getName(), fed2Imports, false);
newNode = ((TypeName) node).transform(builder -> builder.name(newName));
} else if (node instanceof ScalarTypeDefinition) {
String newName = newName(((NamedNode>) node).getName(), fed2Imports, false);
newNode = ((ScalarTypeDefinition) node).transform(builder -> builder.name(newName));
} else if (node instanceof DirectiveDefinition) {
String newName = newName(((NamedNode>) node).getName(), fed2Imports, true);
newNode = ((DirectiveDefinition) node).transform(builder -> builder.name(newName));
} else if (node instanceof EnumTypeDefinition) {
String newName = newName(((NamedNode>) node).getName(), fed2Imports, true);
newNode = ((EnumTypeDefinition) node).transform(builder -> builder.name(newName));
}
if (newNode != null) {
return changeNode(context, newNode);
}
}
return super.visitNode(node, context);
}
private String newName(String name, Map fed2Imports, boolean isDirective) {
String key;
if (isDirective) {
key = "@" + name;
} else {
key = name;
}
if (BUILT_IN_SCALARS.contains(key)) {
// Do not rename builtin types
return name;
}
if (fed2Imports.containsKey(key)) {
String newName = fed2Imports.get(key);
if (("@tag".equals(key) || "@inaccessible".equals(key)) && !newName.equals(key)) {
throw new UnsupportedRenameException(key);
}
if (isDirective) {
return newName.substring(1);
} else {
return newName;
}
} else {
if (name.equals("inaccessible") || name.equals("tag")) {
return name;
} else if (name.equals("Import") || name.equals("Purpose")) {
return "link__" + name;
} else {
// apply default namespace
return "federation__" + name;
}
}
}
}