GQLFragmentReference.java

package net.morimekta.providence.graphql.gql;

import net.morimekta.providence.descriptor.PMessageDescriptor;

import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import javax.annotation.concurrent.Immutable;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * A reference to a fragment.
 *
 * {@inheritDoc}
 */
@Immutable
public class GQLFragmentReference implements GQLFragment {
    private final String name;
    private final PMessageDescriptor<?> parentDescriptor;
    private final Map<String, GQLFragmentDefinition> fragmentMap;

    /**
     * A fragment reference. Since the fragment may not be defined yet, this
     * is just given a map to fragments-to-be.
     *
     * @param name Name of defined fragment to be referred to.
     * @param parentDescriptor Descriptor to the containing message type.
     * @param fragmentMap Map of registered fragments, may not be filled yet.
     */
    public GQLFragmentReference(@Nonnull String name,
                                @Nonnull PMessageDescriptor<?> parentDescriptor,
                                @Nonnull Map<String, GQLFragmentDefinition> fragmentMap) {
        this.name = name;
        this.parentDescriptor = parentDescriptor;
        this.fragmentMap = fragmentMap;
    }

    @Nonnull
    public String getName() {
        return name;
    }

    @Nullable
    public GQLFragmentDefinition getDefinition() {
        return fragmentMap.get(name);
    }

    @Nonnull
    public PMessageDescriptor<?> getParentDescriptor() {
        return parentDescriptor;
    }

    @Nonnull
    @Override
    public PMessageDescriptor<?> getTypeCondition() {
        if (!fragmentMap.containsKey(name)) {
            throw new IllegalStateException("No named fragment " + name + " to reference");
        }
        return fragmentMap.get(name).getTypeCondition();
    }

    @Nonnull
    @Override
    public List<GQLSelection> getSelectionSet() {
        if (!fragmentMap.containsKey(name)) {
            throw new IllegalStateException("No named fragment " + name + " to reference");
        }
        return fragmentMap.get(name).getSelectionSet();
    }

    @Override
    public String toString() {
        return "..." + name;
    }

    @Override
    public int hashCode() {
        return Objects.hash(getClass(), name);
    }

    @Override
    public boolean equals(Object o) {
        if (o == this) return true;
        if (!(o instanceof GQLFragmentReference)) return false;
        GQLFragmentReference other = (GQLFragmentReference) o;
        return Objects.equals(name, other.name);
    }
}