Package com.mysema.query.collections

Source Code of com.mysema.query.collections.AbstractCollQuery

/*
* Copyright 2011, Mysema Ltd
*
* 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 com.mysema.query.collections;

import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.mysema.commons.lang.CloseableIterator;
import com.mysema.commons.lang.IteratorAdapter;
import com.mysema.query.JoinType;
import com.mysema.query.QueryException;
import com.mysema.query.QueryMetadata;
import com.mysema.query.SearchResults;
import com.mysema.query.SimpleQuery;
import com.mysema.query.Tuple;
import com.mysema.query.support.ProjectableQuery;
import com.mysema.query.types.*;

/**
* AbstractCollQuery provides a base class for Collection query implementations.
* Extend it like this
*
* <pre>
* public class MyType extends AbstractColQuery&lt;MyType&gt;{
*   ...
* }
* </pre>
*
* @see CollQuery
*
* @author tiwe
*/
public abstract class AbstractCollQuery<Q extends AbstractCollQuery<Q>> extends ProjectableQuery<Q> implements SimpleQuery<Q> {

    private final Map<Expression<?>, Iterable<?>> iterables = new HashMap<Expression<?>, Iterable<?>>();

    private final QueryEngine queryEngine;

    @SuppressWarnings("unchecked")
    public AbstractCollQuery(QueryMetadata metadata, QueryEngine queryEngine) {
        super(new CollQueryMixin<Q>(metadata));
        this.queryMixin.setSelf((Q) this);
        this.queryEngine = queryEngine;
    }

    @Override
    public long count() {
        try {
            return queryEngine.count(getMetadata(), iterables);
        } catch (Exception e) {
            throw new QueryException(e.getMessage(), e);
        } finally {
            reset();
        }
    }

    @Override
    public boolean exists() {
        try {
            return queryEngine.exists(getMetadata(), iterables);
        } catch (Exception e) {
            throw new QueryException(e.getMessage(), e);
        } finally {
            reset();
        }
    }

    private <D> Expression<D> createAlias(Path<? extends Collection<D>> target, Path<D> alias) {
        return OperationImpl.create(alias.getType(), Ops.ALIAS, target, alias);
    }

    private <D> Expression<D> createAlias(MapExpression<?,D> target, Path<D> alias) {
        return OperationImpl.create(alias.getType(), Ops.ALIAS, target, alias);
    }

    /**
     * Add a query source
     *
     * @param <A>
     * @param entity Path for the source
     * @param col content of the source
     * @return
     */
    public <A> Q from(Path<A> entity, Iterable<? extends A> col) {
        iterables.put(entity, col);
        getMetadata().addJoin(JoinType.DEFAULT, entity);
        return (Q)this;
    }

    /**
     * Bind the given collection to an already existing query source
     *
     * @param <A>
     * @param entity Path for the source
     * @param col content of the source
     * @return
     */
    public <A> Q bind(Path<A> entity, Iterable<? extends A> col) {
        iterables.put(entity, col);
        return (Q)this;
    }

    @Override
    public Q groupBy(Expression<?> e) {
        throw new UnsupportedOperationException();
    }

    @Override
    public Q groupBy(Expression<?>... o) {
        throw new UnsupportedOperationException();
    }

    @Override
    public Q having(Predicate e) {
        throw new UnsupportedOperationException();
    }

    @Override
    public Q having(Predicate... e) {
        throw new UnsupportedOperationException();
    }


    public abstract QueryMetadata getMetadata();

    protected QueryEngine getQueryEngine() {
        return queryEngine;
    }

    /**
     * Define an inner join from the Collection typed path to the alias
     *
     * @param <P>
     * @param target
     * @param alias
     * @return
     */
    public <P> Q innerJoin(Path<? extends Collection<P>> target, Path<P> alias) {
        getMetadata().addJoin(JoinType.INNERJOIN, createAlias(target, alias));
        return (Q)this;
    }

    /**
     * Define an inner join from the Map typed path to the alias
     *
     * @param <P>
     * @param target
     * @param alias
     * @return
     */
    public <P> Q innerJoin(MapExpression<?,P> target, Path<P> alias) {
        getMetadata().addJoin(JoinType.INNERJOIN, createAlias(target, alias));
        return (Q)this;
    }

    /**
     * Define a left join from the Collection typed path to the alias
     *
     * @param <P>
     * @param target
     * @param alias
     * @return
     */
    public <P> Q leftJoin(Path<? extends Collection<P>> target, Path<P> alias) {
        getMetadata().addJoin(JoinType.LEFTJOIN, createAlias(target, alias));
        return (Q)this;
    }

    /**
     * Define a left join from the Map typed path to the alias
     *
     * @param <P>
     * @param target
     * @param alias
     * @return
     */
    public <P> Q leftJoin(MapExpression<?,P> target, Path<P> alias) {
        getMetadata().addJoin(JoinType.LEFTJOIN, createAlias(target, alias));
        return (Q)this;
    }

    @Override
    public CloseableIterator<Tuple> iterate(Expression<?>... args) {
        return iterate(queryMixin.createProjection(args));
    }

    @Override
    public <RT> CloseableIterator<RT> iterate(Expression<RT> projection) {
        try {
            projection = queryMixin.addProjection(projection);
            return new IteratorAdapter<RT>(queryEngine.list(getMetadata(), iterables, projection).iterator());
        } finally {
            reset();
        }
    }

    @Override
    public List<Tuple> list(Expression<?>... args) {
        return list(queryMixin.createProjection(args));
    }

    @Override
    public <RT> List<RT> list(Expression<RT> projection) {
        try {
            projection = queryMixin.addProjection(projection);
            return queryEngine.list(getMetadata(), iterables, projection);
        } finally {
            reset();
        }
    }

    @Override
    public SearchResults<Tuple> listResults(Expression<?>... args) {
        return listResults(queryMixin.createProjection(args));
    }

    @Override
    public <RT> SearchResults<RT> listResults(Expression<RT> projection) {
        projection = queryMixin.addProjection(projection);
        long count = queryEngine.count(getMetadata(), iterables);
        if (count > 0l) {
            List<RT> list = queryEngine.list(getMetadata(), iterables, projection);
            reset();
            return new SearchResults<RT>(list, getMetadata().getModifiers(), count);
        } else {
            reset();
            return SearchResults.<RT>emptyResults();
        }

    }

    @Override
    public Tuple uniqueResult(Expression<?>... args) {
        return uniqueResult(queryMixin.createProjection(args));
    }

    @Override
    public <RT> RT uniqueResult(Expression<RT> expr) {
        queryMixin.setUnique(true);
        if (queryMixin.getMetadata().getModifiers().getLimit() == null) {
            limit(2l);
        }
        return uniqueResult(iterate(expr));
    }

    private void reset() {
        getMetadata().reset();
    }

}
TOP

Related Classes of com.mysema.query.collections.AbstractCollQuery

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.