net.sf.ehcache.CacheQuery Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of ehcache Show documentation
Show all versions of ehcache Show documentation
Ehcache is an open source, standards-based cache used to boost performance,
offload the database and simplify scalability. Ehcache is robust, proven and full-featured and
this has made it the most widely-used Java-based cache.
/**
* Copyright Terracotta, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.sf.ehcache;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import net.sf.ehcache.search.Attribute;
import net.sf.ehcache.search.Direction;
import net.sf.ehcache.search.ExecutionHints;
import net.sf.ehcache.search.Query;
import net.sf.ehcache.search.Results;
import net.sf.ehcache.search.SearchException;
import net.sf.ehcache.search.aggregator.Aggregator;
import net.sf.ehcache.search.aggregator.AggregatorException;
import net.sf.ehcache.search.aggregator.AggregatorInstance;
import net.sf.ehcache.search.expression.AlwaysMatch;
import net.sf.ehcache.search.expression.Criteria;
import net.sf.ehcache.store.StoreQuery;
/**
* Query builder implementation. Instances are bound to a specific cache
*
* @author teck
*/
class CacheQuery implements Query, StoreQuery {
private volatile boolean frozen;
private volatile boolean includeKeys;
private volatile boolean includeValues;
private volatile int maxResults = -1;
private String[] targets;
private final List orderings = Collections.synchronizedList(new ArrayList());
private final Set> includedAttributes = Collections.synchronizedSet(new HashSet>());
private final List criteria = Collections.synchronizedList(new ArrayList());
private final List aggregators = Collections.synchronizedList(new ArrayList());
private final Set> groupByAttributes = Collections.synchronizedSet(new HashSet>());
private final Cache cache;
private volatile ExecutionHints hints;
/**
* Create a new builder instance
*
* @param cache
*/
public CacheQuery(Cache cache) {
this.cache = cache;
}
/**
* {@inheritDoc}
*/
public Query includeKeys() {
checkFrozen();
this.includeKeys = true;
return this;
}
/**
* {@inheritDoc}
*/
public Query includeValues() {
checkFrozen();
this.includeValues = true;
return this;
}
/**
* {@inheritDoc}
*/
public Query includeAttribute(Attribute... attributes) {
checkFrozen();
if (attributes == null) {
throw new NullPointerException();
}
for (Attribute attribute : attributes) {
if (attribute == null) {
throw new NullPointerException("null attribute");
}
this.includedAttributes.add(attribute);
}
return this;
}
/**
* {@inheritDoc}
*/
public Query includeAggregator(Aggregator... aggregators) throws SearchException, AggregatorException {
checkFrozen();
if (aggregators == null) {
throw new NullPointerException();
}
for (Aggregator aggregator : aggregators) {
if (aggregator == null) {
throw new NullPointerException("null aggregator");
}
this.aggregators.add(aggregator);
}
return this;
}
/**
* {@inheritDoc}
*/
public Query addOrderBy(Attribute attribute, Direction direction) {
checkFrozen();
this.orderings.add(new OrderingImpl(attribute, direction));
return this;
}
/**
* {@inheritDoc}
*/
public Query addGroupBy(Attribute... attributes) {
checkFrozen();
if (attributes == null) {
throw new NullPointerException();
}
for (Attribute attribute : attributes) {
if (attribute == null) {
throw new NullPointerException("null attribute");
}
groupByAttributes.add(attribute);
}
return this;
}
/**
* {@inheritDoc}
*/
public Query maxResults(int maxResults) {
checkFrozen();
this.maxResults = maxResults;
return this;
}
/**
* {@inheritDoc}
*/
public Query addCriteria(Criteria criteria) {
checkFrozen();
if (criteria == null) {
throw new NullPointerException("null criteria");
}
this.criteria.add(criteria);
return this;
}
/**
* {@inheritDoc}
*/
public Results execute() throws SearchException {
return cache.executeQuery(snapshot());
}
/**
* {@inheritDoc}
*/
public Results execute(ExecutionHints params) throws SearchException {
this.hints = params;
return cache.executeQuery(snapshot());
}
/**
* {@inheritDoc}
*/
public Query end() {
frozen = true;
return this;
}
/**
* {@inheritDoc}
*/
public List getOrdering() {
assertFrozen();
return Collections.unmodifiableList(orderings);
}
/**
* {@inheritDoc}
*/
public Criteria getCriteria() {
assertFrozen();
return getEffectiveCriteriaCopy();
}
/**
* {@inheritDoc}
*/
public boolean requestsKeys() {
assertFrozen();
return includeKeys;
}
/**
* {@inheritDoc}
*/
public boolean requestsValues() {
assertFrozen();
return includeValues;
}
/**
* {@inheritDoc}
*/
public Cache getCache() {
assertFrozen();
return cache;
}
/**
* {@inheritDoc}
*/
public Set> requestedAttributes() {
assertFrozen();
return Collections.unmodifiableSet(this.includedAttributes);
}
/**
* {@inheritDoc}
*/
public Set> groupByAttributes() {
assertFrozen();
return Collections.unmodifiableSet(this.groupByAttributes);
}
/**
* {@inheritDoc}
*/
public int maxResults() {
assertFrozen();
return maxResults;
}
/**
* {@inheritDoc}
*/
@Override
public ExecutionHints getExecutionHints() {
assertFrozen();
return hints;
}
/**
* {@inheritDoc}
*/
public List getAggregators() {
return Collections.unmodifiableList(this.aggregators);
}
/**
* {@inheritDoc}
*/
public List> getAggregatorInstances() {
assertFrozen();
return Collections.unmodifiableList(createAggregatorInstances(aggregators));
}
private static List> createAggregatorInstances(List aggregators) {
List> rv = new ArrayList>(aggregators.size());
for (Aggregator aggregator : aggregators) {
rv.add(aggregator.createInstance());
}
return rv;
}
private Criteria getEffectiveCriteriaCopy() {
Criteria result = new AlwaysMatch();
for (Criteria c : criteria) {
result = result.and(c);
}
return result;
}
private void assertFrozen() {
if (!frozen) {
throw new AssertionError("not frozen");
}
}
private StoreQuery snapshot() {
if (frozen) {
return this;
}
return new StoreQueryImpl();
}
private void checkFrozen() {
if (frozen) {
throw new SearchException("Query is frozen and cannot be mutated");
}
}
/**
* {@inheritDoc}
*/
public String[] getTargets() {
return this.targets;
}
/**
* {@inheritDoc}
*/
@Override
public void targets(final String[] targets) {
this.targets = targets;
}
/**
* StoreQuery implementation (essentially a snapshot of this (non-frozen) query builder
*/
private class StoreQueryImpl implements StoreQuery {
private final Criteria copiedCriteria = CacheQuery.this.getEffectiveCriteriaCopy();
private final boolean copiedIncludeKeys = includeKeys;
private final boolean copiedIncludeValues = includeValues;
private final Set> copiedAttributes = Collections.unmodifiableSet(new HashSet>(includedAttributes));
private final int copiedMaxResults = maxResults;
private final List copiedOrdering = Collections.unmodifiableList(new ArrayList(orderings));
private final List copiedAggregators = Collections.unmodifiableList(aggregators);
private final List> copiedAggregatorInstances = Collections.unmodifiableList(createAggregatorInstances(aggregators));
private final Set> copiedGroupByAttributes = Collections.unmodifiableSet(new HashSet>(groupByAttributes));
private final ExecutionHints execHints = hints;
public Criteria getCriteria() {
return copiedCriteria;
}
public boolean requestsKeys() {
return copiedIncludeKeys;
}
public boolean requestsValues() {
return copiedIncludeValues;
}
public Cache getCache() {
return cache;
}
public Set> requestedAttributes() {
return copiedAttributes;
}
public Set> groupByAttributes() {
return copiedGroupByAttributes;
}
public int maxResults() {
return copiedMaxResults;
}
public List getOrdering() {
return copiedOrdering;
}
public List getAggregators() {
return copiedAggregators;
}
public List> getAggregatorInstances() {
return copiedAggregatorInstances;
}
public String[] getTargets() {
return targets;
}
/**
* {@inheritDoc}
*/
public void targets(String[] targets) {
CacheQuery.this.targets = targets;
}
public ExecutionHints getExecutionHints() {
return execHints;
}
}
/**
* An attribute/direction pair
*/
private static class OrderingImpl implements Ordering {
private final Attribute attribute;
private final Direction direction;
public OrderingImpl(Attribute attribute, Direction direction) {
if ((attribute == null) || (direction == null)) {
throw new NullPointerException();
}
this.attribute = attribute;
this.direction = direction;
}
public Attribute getAttribute() {
return attribute;
}
public Direction getDirection() {
return direction;
}
}
}