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

io.sphere.sdk.queries.MetaModelQueryDslImpl Maven / Gradle / Ivy

There is a newer version: 1.0.0-M26
Show newest version
package io.sphere.sdk.queries;

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.type.TypeFactory;
import io.sphere.sdk.client.HttpRequestIntent;
import io.sphere.sdk.client.SphereRequestBase;
import io.sphere.sdk.expansion.ExpansionPath;
import io.sphere.sdk.expansion.ExpansionPathContainer;
import io.sphere.sdk.http.HttpMethod;
import io.sphere.sdk.http.HttpQueryParameter;
import io.sphere.sdk.http.HttpResponse;
import io.sphere.sdk.http.UrlQueryBuilder;
import io.sphere.sdk.utils.ListUtils;

import javax.annotation.Nullable;
import java.util.List;
import java.util.Optional;
import java.util.function.Function;

import static io.sphere.sdk.queries.QueryParameterKeys.*;
import static io.sphere.sdk.utils.ListUtils.listOf;
import static java.lang.String.format;
import static java.util.Collections.emptyList;
import static java.util.Collections.singletonList;
import static java.util.Objects.requireNonNull;

/**
 *
 * @param  type of the query result
 * @param  type of the class implementing this class
 * @param  type of the query model
 * @param  type of the expansion model
 */
public abstract class MetaModelQueryDslImpl, Q, E> extends SphereRequestBase implements MetaModelQueryDsl {

    final List> predicate;
    final List> sort;
    @Nullable
    final Boolean withTotal;
    @Nullable
    final Long limit;
    @Nullable
    final Long offset;
    final List> expansionPaths;
    final List additionalQueryParameters;
    final String endpoint;
    final Q queryModel;
    final E expansionModel;
    final Function> resultMapper;
    final Function, C> queryDslBuilderFunction;

    public MetaModelQueryDslImpl(final List> predicate, final List> sort, @Nullable final Boolean fetchTotal, @Nullable final Long limit,
                                 @Nullable final Long offset, final String endpoint,
                                 final Function> resultMapper,
                                 final List> expansionPaths, final List additionalQueryParameters,
                                 final Q queryModel, final E expansionModel, final Function, C> queryDslBuilderFunction) {
        Optional.ofNullable(offset).ifPresent(presentOffset -> {
            if (presentOffset < MIN_OFFSET || presentOffset > MAX_OFFSET) {
                throw new IllegalArgumentException(format("The offset parameter must be in the range of [%d..%d], but was %d.", MIN_OFFSET, MAX_OFFSET, presentOffset));
            }
        });
        this.queryDslBuilderFunction = requireNonNull(queryDslBuilderFunction);
        this.predicate = requireNonNull(predicate);
        this.sort = requireNonNull(sort);
        this.withTotal = fetchTotal;
        this.limit = limit;
        this.offset = offset;
        this.endpoint = requireNonNull(endpoint);
        this.resultMapper = requireNonNull(resultMapper);
        this.expansionPaths = requireNonNull(expansionPaths);
        this.additionalQueryParameters = requireNonNull(additionalQueryParameters);
        this.expansionModel = requireNonNull(expansionModel);
        this.queryModel = requireNonNull(queryModel);
    }

    //uses typeReference of whole result
    public MetaModelQueryDslImpl(final String endpoint, final TypeReference> pagedQueryResultTypeReference,
                                 final Q queryModel, final E expansionModel, final Function, C> queryDslBuilderFunction,
                                 final List additionalQueryParameters) {
        this(emptyList(), emptyList(), null, null, null, endpoint, httpResponse -> deserialize(httpResponse, pagedQueryResultTypeReference),
                emptyList(), additionalQueryParameters, queryModel, expansionModel, queryDslBuilderFunction);
    }

    //uses typeReference of the fetched objects
    public MetaModelQueryDslImpl(final String endpoint, final JavaType singleElementJavatype,
                                 final Q queryModel, final E expansionModel, final Function, C> queryDslBuilderFunction,
                                 final List additionalQueryParameters) {
        this(emptyList(), emptyList(), null, null, null, endpoint, httpResponse -> deserialize(httpResponse, resolveJavaType(singleElementJavatype)),
                emptyList(), additionalQueryParameters, queryModel, expansionModel, queryDslBuilderFunction);
    }

    //uses typeReference of the fetched objects
    public MetaModelQueryDslImpl(final String endpoint, final JavaType singleElementJavatype,
                                 final Q queryModel, final E expansionModel, final Function, C> queryDslBuilderFunction) {
        this(endpoint, singleElementJavatype, queryModel, expansionModel, queryDslBuilderFunction, emptyList());
    }

    //uses typeReference of whole result
    public MetaModelQueryDslImpl(final String endpoint, final TypeReference> pagedQueryResultTypeReference,
                                 final Q queryModel, final E expansionModel, final Function, C> queryDslBuilderFunction) {
        this(endpoint, pagedQueryResultTypeReference, queryModel, expansionModel, queryDslBuilderFunction, emptyList());
    }

    public MetaModelQueryDslImpl(final MetaModelQueryDslBuilder builder) {
        this(builder.predicate, builder.sort, builder.withTotal, builder.limit, builder.offset, builder.endpoint,
                builder.resultMapper, builder.expansionPaths, builder.additionalQueryParameters, builder.queryModel,
                builder.expansionModel, builder.queryDslBuilderFunction);
    }

    @Override
    public C withPredicates(final List> queryPredicates) {
        return copyBuilder().predicates(queryPredicates).build();
    }

    @Override
    public C withPredicates(final QueryPredicate queryPredicate) {
        return withPredicates(singletonList(requireNonNull(queryPredicate)));
    }

    @Override
    public C withPredicates(final Function> m) {
        return withPredicates(m.apply(queryModel));
    }

    @Override
    public C plusPredicates(final List> predicates) {
        return withPredicates(listOf(predicates(), predicates));
    }

    @Override
    public C plusPredicates(final QueryPredicate queryPredicate) {
        return plusPredicates(singletonList(requireNonNull(queryPredicate)));
    }

    @Override
    public C plusPredicates(final Function> m) {
        return plusPredicates(m.apply(queryModel));
    }

    @Override
    public C withSort(final List> sort) {
        return copyBuilder().sort(sort).build();
    }

    @Override
    public C withSort(final QuerySort sort) {
        return withSort(singletonList(sort));
    }

    @Override
    public C withSort(final Function> m) {
        return withSort(m.apply(queryModel));
    }

    @Override
    public C withSortMulti(final Function>> m) {
        return withSort(m.apply(queryModel));
    }

    @Override
    public C plusSort(final Function> m) {
        final QuerySort additionalSort = m.apply(queryModel);
        return plusSort(additionalSort);
    }

    @Override
    public C plusSort(final List> sort) {
        return withSort(ListUtils.listOf(sort(), sort));
    }

    @Override
    public C plusSort(final QuerySort sort) {
        return plusSort(singletonList(sort));
    }

    @Override
    public C withFetchTotal(final boolean fetchTotal) {
        return copyBuilder().fetchTotal(fetchTotal).build();
    }

    @Override
    public C withLimit(final Long limit) {
        return copyBuilder().limit(limit).build();
    }

    @Override
    public C withOffset(final Long offset) {
        return copyBuilder().offset(offset).build();
    }

    @Override
    public C withExpansionPaths(final List> expansionPaths) {
        return copyBuilder().expansionPaths(expansionPaths).build();
    }

    @Override
    public C withExpansionPaths(final ExpansionPath expansionPath) {
        return withExpansionPaths(singletonList(requireNonNull(expansionPath)));
    }

    @Override
    public C withExpansionPaths(final Function> m) {
        return withExpansionPaths(m.apply(expansionModel).expansionPaths());
    }

    @Override
    public C plusExpansionPaths(final List> expansionPaths) {
        return withExpansionPaths(listOf(expansionPaths(), expansionPaths));
    }

    @Override
    public C plusExpansionPaths(final ExpansionPath expansionPath) {
        return plusExpansionPaths(singletonList(requireNonNull(expansionPath)));
    }

    @Override
    public C plusExpansionPaths(final Function> m) {
        return plusExpansionPaths(m.apply(expansionModel).expansionPaths());
    }

    @Override
    public List> predicates() {
        return predicate;
    }

    @Override
    public List> sort() {
        return sort;
    }

    @Override
    @Nullable
    public Boolean fetchTotal() {
        return withTotal;
    }

    @Override
    @Nullable
    public Long limit() {
        return limit;
    }

    @Override
    @Nullable
    public Long offset() {
        return offset;
    }

    @Override
    public String endpoint() {
        return endpoint;
    }

    @Override
    public List> expansionPaths() {
        return expansionPaths;
    }

    protected List additionalQueryParameters() {
        return additionalQueryParameters;
    }

    protected MetaModelQueryDslBuilder copyBuilder() {
        return new MetaModelQueryDslBuilder<>(this);
    }

    @Override
    public final HttpRequestIntent httpRequestIntent() {
        final String additions = queryParametersToString(true);
        return HttpRequestIntent.of(HttpMethod.GET, endpoint + (additions.length() > 1 ? additions : ""));
    }

    @Override
    public PagedQueryResult deserialize(final HttpResponse httpResponse) {
        return resultMapper.apply(httpResponse);
    }

    private String queryParametersToString(final boolean urlEncoded) {
        final UrlQueryBuilder builder = UrlQueryBuilder.of();
        predicates().forEach(predicate -> builder.add(WHERE, predicate.toSphereQuery(), urlEncoded));
        sort().forEach(sort -> builder.add(SORT, sort.toSphereSort(), urlEncoded));
        Optional.ofNullable(limit()).ifPresent(limit -> builder.add(LIMIT, limit.toString(), urlEncoded));
        Optional.ofNullable(offset()).ifPresent(offset -> builder.add(OFFSET, offset.toString(), urlEncoded));
        Optional.ofNullable(fetchTotal()).ifPresent(withTotal -> builder.add(WITH_TOTAL, withTotal.toString(), urlEncoded));
        expansionPaths().forEach(path -> builder.add(EXPAND, path.toSphereExpand(), urlEncoded));
        additionalQueryParameters().forEach(parameter -> builder.add(parameter.getKey(), parameter.getValue(), urlEncoded));
        return builder.toStringWithOptionalQuestionMark();
    }

    @Override
    public final boolean equals(Object o) {
        return o != null && (o instanceof Query) && ((Query)o).httpRequestIntent().getPath().equals(httpRequestIntent().getPath());
    }

    @Override
    public final int hashCode() {
        return httpRequestIntent().getPath().hashCode();
    }

    @Override
    public String toString() {
        final String readablePath = endpoint + queryParametersToString(false);

        return this.getClass().getSimpleName() +"{" +
                "predicate=" + predicate +
                ", sort=" + sort +
                ", expand=" + expansionPaths +
                ", additionalQueryParameters=" + additionalQueryParameters +
                ", limit=" + limit +
                ", offset=" + offset +
                ", endpoint='" + endpoint + '\'' +
                ", resultMapper=" + resultMapper +
                ", readablePath=" + readablePath +
                ", request=" + httpRequestIntent() +
                ", withTotal=" + withTotal +
                '}';
    }

    Q getQueryModel() {
        return queryModel;
    }

    E getExpansionModel() {
        return expansionModel;
    }

    Function> getResultMapper() {
        return resultMapper;
    }

    private static  JavaType resolveJavaType(final TypeReference typeReference) {
        final TypeFactory typeFactory = TypeFactory.defaultInstance();
        final JavaType typeParameterJavaType = typeFactory.constructType(typeReference);
        return resolveJavaType(typeParameterJavaType);
    }

    private static  JavaType resolveJavaType(final JavaType javaType) {
        final TypeFactory typeFactory = TypeFactory.defaultInstance();
        final JavaType resultJavaType = typeFactory.constructParametrizedType(PagedQueryResult.class, PagedQueryResult.class, javaType);
        return resultJavaType;
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy