package com.mysema.rdfbean.model; import java.util.ArrayList; import java.util.List; import java.util.Map; import com.mysema.commons.lang.CloseableIterator; import com.mysema.query.BooleanBuilder; import com.mysema.query.DefaultQueryMetadata; import com.mysema.query.QueryFlag; import com.mysema.query.QueryFlag.Position; import com.mysema.query.QueryMetadata; import com.mysema.query.support.QueryBase; import com.mysema.query.support.QueryMixin; import com.mysema.query.types.ConstantImpl; import com.mysema.query.types.Expression; import com.mysema.query.types.Predicate; /** * @author tiwe * */ public class RDFQueryImpl extends QueryBase<RDFQueryImpl> implements RDFQuery { private final RDFConnection connection; private List<Block> blocks = new ArrayList<Block>(); private BooleanBuilder filters = new BooleanBuilder(); public RDFQueryImpl(RDFConnection connection) { super(new QueryMixin<RDFQueryImpl>(new DefaultQueryMetadata().noValidate())); queryMixin.setSelf(this); this.connection = connection; } @Override public RDFQuery addFlag(Position position, String flag) { return queryMixin.addFlag(new QueryFlag(position, flag)); } @Override public RDFQuery from(UID... graphs) { for (UID uid : graphs) { queryMixin.from(new ConstantImpl<UID>(UID.class, uid)); } return this; } @Override public boolean ask() { return createBooleanQuery().getBoolean(); } @Override public CloseableIterator<Map<String, NODE>> selectDistinct(Expression<?>... exprs) { return distinct().select(exprs); } @Override public CloseableIterator<Map<String, NODE>> select(Expression<?>... exprs) { return createTupleQuery(exprs).getTuples(); } @Override public CloseableIterator<Map<String, NODE>> selectDistinctAll() { return distinct().selectAll(); } @Override public CloseableIterator<Map<String, NODE>> selectAll() { return createTupleQuery().getTuples(); } public Map<String, NODE> selectSingle(Expression<?>... exprs) { CloseableIterator<Map<String, NODE>> it = select(exprs); try { if (it.hasNext()) { return it.next(); } else { return null; } } finally { it.close(); } } @Override public CloseableIterator<STMT> construct(Block... exprs) { return createGraphQuery(exprs).getTriples(); } @Override public BooleanQuery createBooleanQuery() { aggregateFilters(); return connection.createQuery(QueryLanguage.BOOLEAN, queryMixin.getMetadata()); } @Override public TupleQuery createTupleQuery(Expression<?>... exprs) { aggregateFilters(); queryMixin.addProjection(exprs); return connection.createQuery(QueryLanguage.TUPLE, queryMixin.getMetadata()); } @Override public GraphQuery createGraphQuery(Block... exprs) { aggregateFilters(); queryMixin.addProjection(exprs); return connection.createQuery(QueryLanguage.GRAPH, queryMixin.getMetadata()); } protected void aggregateFilters() { if (!blocks.isEmpty()) { if (filters.getValue() == null) { super.where(new GroupBlock(blocks)); } else { super.where(new GroupBlock(blocks, filters.getValue())); } } blocks = new ArrayList<Block>(); filters = new BooleanBuilder(); } @Override public RDFQueryImpl where(Predicate o) { if (o instanceof Block) { blocks.add((Block) o); } else { filters.and(o); } return this; } @Override public RDFQueryImpl where(Predicate... o) { for (Predicate predicate : o) { where(predicate); } return this; } public QueryMetadata getMetadata() { return queryMixin.getMetadata(); } @Override public String toString() { QueryMetadata metadata = queryMixin.getMetadata().clone(); if (!blocks.isEmpty()) { if (filters.getValue() == null) { metadata.addWhere(new GroupBlock(blocks)); } else { metadata.addWhere(new GroupBlock(blocks, filters.getValue())); } } SPARQLVisitor visitor = new SPARQLVisitor(); visitor.setInlineAll(true); visitor.visit(metadata, QueryLanguage.TUPLE); return visitor.toString(); } }