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

net.morimekta.providence.graphql.gql.GQLSelection Maven / Gradle / Ivy

There is a newer version: 2.7.0
Show newest version
package net.morimekta.providence.graphql.gql;

import net.morimekta.providence.descriptor.PField;
import net.morimekta.util.collect.UnmodifiableList;

import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.ArrayList;
import java.util.List;

/**
 * When defining a graphql each point in a selection set is called a
 * 'selection'. A selection may be a field or a fragment, each having
 * a distinct definition and uses.
 *
 * Most selections can be recursive, i.e. containing a selection set
 * of it's own. The selection set is ordered, therefore it is returned
 * as a list, not a set.
 */
public interface GQLSelection {
    /**
     * @return List if selections contained within this selection.
     */
    @Nullable
    List getSelectionSet();

    /**
     * Check if any of the given fields are in the selection.
     * It will only look the the current struct, but check in all contained
     * and referenced fragments. If only one field is given, this method
     * will return true if and only if {@link #getSelection(PField)} returns
     * a non-empty list.
     *
     * @param fields Fields to check selection for.
     * @return True only if the current selection set contains ony
     *         of the provided fields.
     */
    default boolean hasSelection(@Nonnull PField... fields) {
        // Everything requested.
        if (getSelectionSet() == null) return true;
        if (fields.length == 0) return false;

        for (GQLSelection sel : getSelectionSet()) {
            if (sel instanceof GQLField) {
                GQLField sf = (GQLField) sel;
                for (PField field : fields) {
                    if (sf.getField() == field) {
                        return true;
                    }
                }
            } else if (sel instanceof GQLFragment) {
                GQLFragment fragment = (GQLFragment) sel;
                if (fragment.hasSelection(fields)) {
                    return true;
                }
            }
        }
        return false;
    }

    /**
     * Get all selection entries related to the given field. It will
     * only look at the current struct, but look at all levels of
     * fragments.
     *
     * The result will contain one entry for each time the field is
     * requested, so if multiple fragments requests the same field, this
     * will return one entry per reference. If it contains more than one,
     * the query should only have one such without alias, and all
     * others should use unique aliases, but is not required.
     *
     * This method will return a non-empty list if and only if
     * {@link #hasSelection(PField[])} called with the same field returns
     * true.
     *
     * @param field The field to get selection for.
     * @return List of selection related to the field.
     */
    @Nonnull
    default List getSelection(@Nonnull PField field) {
        if (getSelectionSet() == null) return UnmodifiableList.listOf();

        List selection = new ArrayList<>();
        for (GQLSelection sel : getSelectionSet()) {
            if (sel instanceof GQLField) {
                GQLField sf = (GQLField) sel;
                if (field.equals(sf.getField())) {
                    selection.add(sf);
                }
            } else if (sel instanceof GQLFragment) {
                GQLFragment fragment = (GQLFragment) sel;
                selection.addAll(fragment.getSelection(field));
            }
        }

        return UnmodifiableList.copyOf(selection);
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy