GQLIntrospection.java
package net.morimekta.providence.graphql.gql;
import net.morimekta.providence.PMessage;
import net.morimekta.providence.descriptor.PDescriptor;
import net.morimekta.providence.descriptor.PField;
import net.morimekta.providence.descriptor.PPrimitive;
import net.morimekta.providence.descriptor.PStructDescriptor;
import net.morimekta.providence.graphql.introspection.Schema;
import net.morimekta.providence.graphql.introspection.Type;
import net.morimekta.providence.graphql.introspection.TypeArguments;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import javax.annotation.concurrent.Immutable;
import java.util.List;
import static net.morimekta.providence.graphql.gql.GQLUtil.toArgumentString;
/**
* A introspection is very much like a 'normal' field, but
* has special meaning to graphql. Note that <b>all</b> field
* names that start with <code>__</code> are reserved for
* introspection.
*
* {@inheritDoc}
*/
@Immutable
public class GQLIntrospection implements GQLSelection {
private final List<GQLSelection> selectionSet;
private final PMessage arguments;
private final Field field;
private final String alias;
/**
* Introspeciton fields supported by providence-graphql.
*/
public enum Field {
__type(TypeArguments.kDescriptor, Type.kDescriptor),
__typename(null, PPrimitive.STRING),
__schema(null, Schema.kDescriptor),
;
public final PStructDescriptor<?> arguments;
public final PDescriptor response;
Field(PStructDescriptor<?> arguments, PDescriptor response) {
this.arguments = arguments;
this.response = response;
}
}
/**
* Find introspection field by name.
*
* @param name The name of field to find.
* @return The introspection field, or null if not found.
*/
public static Field findFieldByName(String name) {
for (Field field : Field.values()) {
if (field.name().equals(name)) {
return field;
}
}
return null;
}
/**
* @param field Name of introspection field.
* @param alias Introspection alias. Only possible / allowed
* on root type introspection.
* @param arguments Arguments for general introspection.
* @param selectionSet The introspection selection set.
*/
public GQLIntrospection(@Nonnull Field field,
@Nullable String alias,
@Nullable PMessage<?> arguments,
@Nullable List<GQLSelection> selectionSet) {
this.field = field;
this.alias = alias;
this.arguments = arguments;
this.selectionSet = selectionSet;
}
@Nullable
public PMessage getArguments() {
return arguments;
}
@Nullable
public String getAlias() {
return alias;
}
@Nonnull
public Field getField() {
return field;
}
@Override
public List<GQLSelection> getSelectionSet() {
return selectionSet;
}
@Override
public String toString() {
StringBuilder builder = new StringBuilder();
if (alias != null) {
builder.append(alias).append(": ");
}
builder.append(field.name());
if (arguments != null) {
builder.append("(");
boolean first = true;
for (PField pf : arguments.descriptor().getFields()) {
if (arguments.has(pf.getId())) {
if (!first) {
builder.append(", ");
} else {
first = false;
}
builder.append(pf.getName())
.append(": ")
.append(toArgumentString(arguments.get(pf.getId())));
}
}
builder.append(")");
}
if (selectionSet != null && selectionSet.size() > 0) {
if (arguments != null) {
builder.append(" ");
}
builder.append("{");
boolean first = true;
for (GQLSelection field : selectionSet) {
if (!first) {
builder.append(", ");
} else {
first = false;
}
builder.append(field.toString());
}
builder.append("}");
}
return builder.toString();
}
}