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

net.sf.ehcache.CacheQuery Maven / Gradle / Ivy

There is a newer version: 2.10.9.2
Show newest version
/**
 *  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;
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy