org.immutables.criteria.expression.ImmutableQuery Maven / Gradle / Ivy
package org.immutables.criteria.expression;
import com.google.common.collect.ImmutableList;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.OptionalLong;
import javax.annotation.Nullable;
import javax.annotation.ParametersAreNonnullByDefault;
import javax.annotation.concurrent.Immutable;
import javax.annotation.concurrent.NotThreadSafe;
import org.immutables.value.Generated;
/**
* Immutable implementation of {@link Query}.
*
* Use the builder to create immutable instances:
* {@code ImmutableQuery.builder()}.
* Use the static factory method to create immutable instances:
* {@code ImmutableQuery.of()}.
*/
@Generated(from = "Query", generator = "Immutables")
@SuppressWarnings({"all"})
@ParametersAreNonnullByDefault
@javax.annotation.Generated("org.immutables.processor.ProxyProcessor")
@Immutable
final class ImmutableQuery extends Query {
private final Class> entityClass;
private final @Nullable Expression filter;
private final @Nullable Long limit;
private final @Nullable Long offset;
private final ImmutableList projections;
private final ImmutableList collations;
private final ImmutableList groupBy;
private ImmutableQuery(Class> entityClass) {
this.entityClass = Objects.requireNonNull(entityClass, "entityClass");
this.filter = null;
this.limit = null;
this.offset = null;
this.projections = ImmutableList.of();
this.collations = ImmutableList.of();
this.groupBy = ImmutableList.of();
}
private ImmutableQuery(
Class> entityClass,
@Nullable Expression filter,
@Nullable Long limit,
@Nullable Long offset,
ImmutableList projections,
ImmutableList collations,
ImmutableList groupBy) {
this.entityClass = entityClass;
this.filter = filter;
this.limit = limit;
this.offset = offset;
this.projections = projections;
this.collations = collations;
this.groupBy = groupBy;
}
/**
* @return The value of the {@code entityClass} attribute
*/
@Override
public Class> entityClass() {
return entityClass;
}
/**
* @return The value of the {@code filter} attribute
*/
@Override
public Optional filter() {
return Optional.ofNullable(filter);
}
/**
* @return The value of the {@code limit} attribute
*/
@Override
public OptionalLong limit() {
return limit != null
? OptionalLong.of(limit)
: OptionalLong.empty();
}
/**
* @return The value of the {@code offset} attribute
*/
@Override
public OptionalLong offset() {
return offset != null
? OptionalLong.of(offset)
: OptionalLong.empty();
}
/**
* @return The value of the {@code projections} attribute
*/
@Override
public ImmutableList projections() {
return projections;
}
/**
* @return The value of the {@code collations} attribute
*/
@Override
public ImmutableList collations() {
return collations;
}
/**
* @return The value of the {@code groupBy} attribute
*/
@Override
public ImmutableList groupBy() {
return groupBy;
}
/**
* Copy the current immutable object by setting a value for the {@link Query#entityClass() entityClass} attribute.
* A shallow reference equality check is used to prevent copying of the same value by returning {@code this}.
* @param value A new value for entityClass
* @return A modified copy of the {@code this} object
*/
public final ImmutableQuery withEntityClass(Class> value) {
if (this.entityClass == value) return this;
Class> newValue = Objects.requireNonNull(value, "entityClass");
return new ImmutableQuery(newValue, this.filter, this.limit, this.offset, this.projections, this.collations, this.groupBy);
}
/**
* Copy the current immutable object by setting a present value for the optional {@link Query#filter() filter} attribute.
* @param value The value for filter
* @return A modified copy of {@code this} object
*/
public final ImmutableQuery withFilter(Expression value) {
@Nullable Expression newValue = Objects.requireNonNull(value, "filter");
if (this.filter == newValue) return this;
return new ImmutableQuery(
this.entityClass,
newValue,
this.limit,
this.offset,
this.projections,
this.collations,
this.groupBy);
}
/**
* Copy the current immutable object by setting an optional value for the {@link Query#filter() filter} attribute.
* A shallow reference equality check is used on unboxed optional value to prevent copying of the same value by returning {@code this}.
* @param optional A value for filter
* @return A modified copy of {@code this} object
*/
@SuppressWarnings("unchecked") // safe covariant cast
public final ImmutableQuery withFilter(Optional extends Expression> optional) {
@Nullable Expression value = optional.orElse(null);
if (this.filter == value) return this;
return new ImmutableQuery(
this.entityClass,
value,
this.limit,
this.offset,
this.projections,
this.collations,
this.groupBy);
}
/**
* Copy the current immutable object by setting a present value for the optional {@link Query#limit() limit} attribute.
* @param value The value for limit
* @return A modified copy of {@code this} object
*/
public final ImmutableQuery withLimit(long value) {
@Nullable Long newValue = value;
if (Objects.equals(this.limit, newValue)) return this;
return new ImmutableQuery(
this.entityClass,
this.filter,
newValue,
this.offset,
this.projections,
this.collations,
this.groupBy);
}
/**
* Copy the current immutable object by setting an optional value for the {@link Query#limit() limit} attribute.
* An equality check is used on inner nullable value to prevent copying of the same value by returning {@code this}.
* @param optional A value for limit
* @return A modified copy of {@code this} object
*/
public final ImmutableQuery withLimit(OptionalLong optional) {
@Nullable Long value = optional.isPresent() ? optional.getAsLong() : null;
if (Objects.equals(this.limit, value)) return this;
return new ImmutableQuery(
this.entityClass,
this.filter,
value,
this.offset,
this.projections,
this.collations,
this.groupBy);
}
/**
* Copy the current immutable object by setting a present value for the optional {@link Query#offset() offset} attribute.
* @param value The value for offset
* @return A modified copy of {@code this} object
*/
public final ImmutableQuery withOffset(long value) {
@Nullable Long newValue = value;
if (Objects.equals(this.offset, newValue)) return this;
return new ImmutableQuery(
this.entityClass,
this.filter,
this.limit,
newValue,
this.projections,
this.collations,
this.groupBy);
}
/**
* Copy the current immutable object by setting an optional value for the {@link Query#offset() offset} attribute.
* An equality check is used on inner nullable value to prevent copying of the same value by returning {@code this}.
* @param optional A value for offset
* @return A modified copy of {@code this} object
*/
public final ImmutableQuery withOffset(OptionalLong optional) {
@Nullable Long value = optional.isPresent() ? optional.getAsLong() : null;
if (Objects.equals(this.offset, value)) return this;
return new ImmutableQuery(
this.entityClass,
this.filter,
this.limit,
value,
this.projections,
this.collations,
this.groupBy);
}
/**
* Copy the current immutable object with elements that replace the content of {@link Query#projections() projections}.
* @param elements The elements to set
* @return A modified copy of {@code this} object
*/
public final ImmutableQuery withProjections(Expression... elements) {
ImmutableList newValue = ImmutableList.copyOf(elements);
return new ImmutableQuery(this.entityClass, this.filter, this.limit, this.offset, newValue, this.collations, this.groupBy);
}
/**
* Copy the current immutable object with elements that replace the content of {@link Query#projections() projections}.
* A shallow reference equality check is used to prevent copying of the same value by returning {@code this}.
* @param elements An iterable of projections elements to set
* @return A modified copy of {@code this} object
*/
public final ImmutableQuery withProjections(Iterable extends Expression> elements) {
if (this.projections == elements) return this;
ImmutableList newValue = ImmutableList.copyOf(elements);
return new ImmutableQuery(this.entityClass, this.filter, this.limit, this.offset, newValue, this.collations, this.groupBy);
}
/**
* Copy the current immutable object with elements that replace the content of {@link Query#collations() collations}.
* @param elements The elements to set
* @return A modified copy of {@code this} object
*/
public final ImmutableQuery withCollations(Collation... elements) {
ImmutableList newValue = ImmutableList.copyOf(elements);
return new ImmutableQuery(
this.entityClass,
this.filter,
this.limit,
this.offset,
this.projections,
newValue,
this.groupBy);
}
/**
* Copy the current immutable object with elements that replace the content of {@link Query#collations() collations}.
* A shallow reference equality check is used to prevent copying of the same value by returning {@code this}.
* @param elements An iterable of collations elements to set
* @return A modified copy of {@code this} object
*/
public final ImmutableQuery withCollations(Iterable extends Collation> elements) {
if (this.collations == elements) return this;
ImmutableList newValue = ImmutableList.copyOf(elements);
return new ImmutableQuery(
this.entityClass,
this.filter,
this.limit,
this.offset,
this.projections,
newValue,
this.groupBy);
}
/**
* Copy the current immutable object with elements that replace the content of {@link Query#groupBy() groupBy}.
* @param elements The elements to set
* @return A modified copy of {@code this} object
*/
public final ImmutableQuery withGroupBy(Expression... elements) {
ImmutableList newValue = ImmutableList.copyOf(elements);
return new ImmutableQuery(
this.entityClass,
this.filter,
this.limit,
this.offset,
this.projections,
this.collations,
newValue);
}
/**
* Copy the current immutable object with elements that replace the content of {@link Query#groupBy() groupBy}.
* A shallow reference equality check is used to prevent copying of the same value by returning {@code this}.
* @param elements An iterable of groupBy elements to set
* @return A modified copy of {@code this} object
*/
public final ImmutableQuery withGroupBy(Iterable extends Expression> elements) {
if (this.groupBy == elements) return this;
ImmutableList newValue = ImmutableList.copyOf(elements);
return new ImmutableQuery(
this.entityClass,
this.filter,
this.limit,
this.offset,
this.projections,
this.collations,
newValue);
}
/**
* This instance is equal to all instances of {@code ImmutableQuery} that have equal attribute values.
* @return {@code true} if {@code this} is equal to {@code another} instance
*/
@Override
public boolean equals(@Nullable Object another) {
if (this == another) return true;
return another instanceof ImmutableQuery
&& equalTo((ImmutableQuery) another);
}
private boolean equalTo(ImmutableQuery another) {
return entityClass.equals(another.entityClass)
&& Objects.equals(filter, another.filter)
&& Objects.equals(limit, another.limit)
&& Objects.equals(offset, another.offset)
&& projections.equals(another.projections)
&& collations.equals(another.collations)
&& groupBy.equals(another.groupBy);
}
/**
* Computes a hash code from attributes: {@code entityClass}, {@code filter}, {@code limit}, {@code offset}, {@code projections}, {@code collations}, {@code groupBy}.
* @return hashCode value
*/
@Override
public int hashCode() {
int h = 5381;
h += (h << 5) + entityClass.hashCode();
h += (h << 5) + Objects.hashCode(filter);
h += (h << 5) + Objects.hashCode(limit);
h += (h << 5) + Objects.hashCode(offset);
h += (h << 5) + projections.hashCode();
h += (h << 5) + collations.hashCode();
h += (h << 5) + groupBy.hashCode();
return h;
}
/**
* Construct a new immutable {@code Query} instance.
* @param entityClass The value for the {@code entityClass} attribute
* @return An immutable Query instance
*/
public static ImmutableQuery of(Class> entityClass) {
return new ImmutableQuery(entityClass);
}
/**
* Creates an immutable copy of a {@link Query} value.
* Uses accessors to get values to initialize the new immutable instance.
* If an instance is already immutable, it is returned as is.
* @param instance The instance to copy
* @return A copied immutable Query instance
*/
public static ImmutableQuery copyOf(Query instance) {
if (instance instanceof ImmutableQuery) {
return (ImmutableQuery) instance;
}
return ImmutableQuery.builder()
.from(instance)
.build();
}
/**
* Creates a builder for {@link ImmutableQuery ImmutableQuery}.
*
* ImmutableQuery.builder()
* .entityClass(Class<?>) // required {@link Query#entityClass() entityClass}
* .filter(org.immutables.criteria.expression.Expression) // optional {@link Query#filter() filter}
* .limit(long) // optional {@link Query#limit() limit}
* .offset(long) // optional {@link Query#offset() offset}
* .addProjections|addAllProjections(org.immutables.criteria.expression.Expression) // {@link Query#projections() projections} elements
* .addCollations|addAllCollations(org.immutables.criteria.expression.Collation) // {@link Query#collations() collations} elements
* .addGroupBy|addAllGroupBy(org.immutables.criteria.expression.Expression) // {@link Query#groupBy() groupBy} elements
* .build();
*
* @return A new ImmutableQuery builder
*/
public static ImmutableQuery.Builder builder() {
return new ImmutableQuery.Builder();
}
/**
* Builds instances of type {@link ImmutableQuery ImmutableQuery}.
* Initialize attributes and then invoke the {@link #build()} method to create an
* immutable instance.
* {@code Builder} is not thread-safe and generally should not be stored in a field or collection,
* but instead used immediately to create instances.
*/
@Generated(from = "Query", generator = "Immutables")
@NotThreadSafe
public static final class Builder {
private static final long INIT_BIT_ENTITY_CLASS = 0x1L;
private long initBits = 0x1L;
private @Nullable Class> entityClass;
private @Nullable Expression filter;
private @Nullable Long limit;
private @Nullable Long offset;
private ImmutableList.Builder projections = ImmutableList.builder();
private ImmutableList.Builder collations = ImmutableList.builder();
private ImmutableList.Builder groupBy = ImmutableList.builder();
private Builder() {
}
/**
* Fill a builder with attribute values from the provided {@code Query} instance.
* Regular attribute values will be replaced with those from the given instance.
* Absent optional values will not replace present values.
* Collection elements and entries will be added, not replaced.
* @param instance The instance from which to copy values
* @return {@code this} builder for use in a chained invocation
*/
public final Builder from(Query instance) {
Objects.requireNonNull(instance, "instance");
entityClass(instance.entityClass());
Optional filterOptional = instance.filter();
if (filterOptional.isPresent()) {
filter(filterOptional);
}
OptionalLong limitOptional = instance.limit();
if (limitOptional.isPresent()) {
limit(limitOptional);
}
OptionalLong offsetOptional = instance.offset();
if (offsetOptional.isPresent()) {
offset(offsetOptional);
}
addAllProjections(instance.projections());
addAllCollations(instance.collations());
addAllGroupBy(instance.groupBy());
return this;
}
/**
* Initializes the value for the {@link Query#entityClass() entityClass} attribute.
* @param entityClass The value for entityClass
* @return {@code this} builder for use in a chained invocation
*/
public final Builder entityClass(Class> entityClass) {
this.entityClass = Objects.requireNonNull(entityClass, "entityClass");
initBits &= ~INIT_BIT_ENTITY_CLASS;
return this;
}
/**
* Initializes the optional value {@link Query#filter() filter} to filter.
* @param filter The value for filter
* @return {@code this} builder for chained invocation
*/
public final Builder filter(Expression filter) {
this.filter = Objects.requireNonNull(filter, "filter");
return this;
}
/**
* Initializes the optional value {@link Query#filter() filter} to filter.
* @param filter The value for filter
* @return {@code this} builder for use in a chained invocation
*/
public final Builder filter(Optional extends Expression> filter) {
this.filter = filter.orElse(null);
return this;
}
/**
* Initializes the optional value {@link Query#limit() limit} to limit.
* @param limit The value for limit
* @return {@code this} builder for chained invocation
*/
public final Builder limit(long limit) {
this.limit = limit;
return this;
}
/**
* Initializes the optional value {@link Query#limit() limit} to limit.
* @param limit The value for limit
* @return {@code this} builder for use in a chained invocation
*/
public final Builder limit(OptionalLong limit) {
this.limit = limit.isPresent() ? limit.getAsLong() : null;
return this;
}
/**
* Initializes the optional value {@link Query#offset() offset} to offset.
* @param offset The value for offset
* @return {@code this} builder for chained invocation
*/
public final Builder offset(long offset) {
this.offset = offset;
return this;
}
/**
* Initializes the optional value {@link Query#offset() offset} to offset.
* @param offset The value for offset
* @return {@code this} builder for use in a chained invocation
*/
public final Builder offset(OptionalLong offset) {
this.offset = offset.isPresent() ? offset.getAsLong() : null;
return this;
}
/**
* Adds one element to {@link Query#projections() projections} list.
* @param element A projections element
* @return {@code this} builder for use in a chained invocation
*/
public final Builder addProjections(Expression element) {
this.projections.add(element);
return this;
}
/**
* Adds elements to {@link Query#projections() projections} list.
* @param elements An array of projections elements
* @return {@code this} builder for use in a chained invocation
*/
public final Builder addProjections(Expression... elements) {
this.projections.add(elements);
return this;
}
/**
* Sets or replaces all elements for {@link Query#projections() projections} list.
* @param elements An iterable of projections elements
* @return {@code this} builder for use in a chained invocation
*/
public final Builder projections(Iterable extends Expression> elements) {
this.projections = ImmutableList.builder();
return addAllProjections(elements);
}
/**
* Adds elements to {@link Query#projections() projections} list.
* @param elements An iterable of projections elements
* @return {@code this} builder for use in a chained invocation
*/
public final Builder addAllProjections(Iterable extends Expression> elements) {
this.projections.addAll(elements);
return this;
}
/**
* Adds one element to {@link Query#collations() collations} list.
* @param element A collations element
* @return {@code this} builder for use in a chained invocation
*/
public final Builder addCollations(Collation element) {
this.collations.add(element);
return this;
}
/**
* Adds elements to {@link Query#collations() collations} list.
* @param elements An array of collations elements
* @return {@code this} builder for use in a chained invocation
*/
public final Builder addCollations(Collation... elements) {
this.collations.add(elements);
return this;
}
/**
* Sets or replaces all elements for {@link Query#collations() collations} list.
* @param elements An iterable of collations elements
* @return {@code this} builder for use in a chained invocation
*/
public final Builder collations(Iterable extends Collation> elements) {
this.collations = ImmutableList.builder();
return addAllCollations(elements);
}
/**
* Adds elements to {@link Query#collations() collations} list.
* @param elements An iterable of collations elements
* @return {@code this} builder for use in a chained invocation
*/
public final Builder addAllCollations(Iterable extends Collation> elements) {
this.collations.addAll(elements);
return this;
}
/**
* Adds one element to {@link Query#groupBy() groupBy} list.
* @param element A groupBy element
* @return {@code this} builder for use in a chained invocation
*/
public final Builder addGroupBy(Expression element) {
this.groupBy.add(element);
return this;
}
/**
* Adds elements to {@link Query#groupBy() groupBy} list.
* @param elements An array of groupBy elements
* @return {@code this} builder for use in a chained invocation
*/
public final Builder addGroupBy(Expression... elements) {
this.groupBy.add(elements);
return this;
}
/**
* Sets or replaces all elements for {@link Query#groupBy() groupBy} list.
* @param elements An iterable of groupBy elements
* @return {@code this} builder for use in a chained invocation
*/
public final Builder groupBy(Iterable extends Expression> elements) {
this.groupBy = ImmutableList.builder();
return addAllGroupBy(elements);
}
/**
* Adds elements to {@link Query#groupBy() groupBy} list.
* @param elements An iterable of groupBy elements
* @return {@code this} builder for use in a chained invocation
*/
public final Builder addAllGroupBy(Iterable extends Expression> elements) {
this.groupBy.addAll(elements);
return this;
}
/**
* Builds a new {@link ImmutableQuery ImmutableQuery}.
* @return An immutable instance of Query
* @throws java.lang.IllegalStateException if any required attributes are missing
*/
public ImmutableQuery build() {
if (initBits != 0) {
throw new IllegalStateException(formatRequiredAttributesMessage());
}
return new ImmutableQuery(entityClass, filter, limit, offset, projections.build(), collations.build(), groupBy.build());
}
private String formatRequiredAttributesMessage() {
List attributes = new ArrayList<>();
if ((initBits & INIT_BIT_ENTITY_CLASS) != 0) attributes.add("entityClass");
return "Cannot build Query, some of required attributes are not set " + attributes;
}
}
}