org.openanzo.glitter.query.SubqueryController.java Source code

Java tutorial

Introduction

Here is the source code for org.openanzo.glitter.query.SubqueryController.java

Source

/*******************************************************************************
 * Copyright (c) 2009 Cambridge Semantics Incorporated.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     Cambridge Semantics Incorporated
 *******************************************************************************/
package org.openanzo.glitter.query;

import java.util.EnumSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import org.apache.commons.collections15.BidiMap;
import org.apache.commons.collections15.bidimap.TreeBidiMap;
import org.openanzo.glitter.Engine;
import org.openanzo.glitter.dataset.QueryDataset;
import org.openanzo.glitter.syntax.concrete.ParseException;
import org.openanzo.rdf.URI;
import org.openanzo.rdf.Variable;

/**
 * A SubqueryController specializes {@link QueryController} to be used for capturing the details of a subquery. Subqueries are more limited versions of full
 * queries - they can only be initialized from existing queries and copy things like base URI, prefix map, and dataset information from their parent.
 * 
 * @author lee <lee@cambridgesemantics.com>
 * 
 */
public class SubqueryController extends QueryController {
    private QueryController parent;

    /**
     * @param parent
     */
    public SubqueryController(QueryController parent) {
        this.parent = parent;
    }

    @Override
    public void setEngine(Engine engine) {
        if (engine == null || !engine.equals(getEngine()))
            throw new UnsupportedOperationException(
                    "Subqueries cannot have a different engine from the parent query.");
    }

    @Override
    public Engine getEngine() {
        return this.parent.getEngine();
    }

    @Override
    public QueryDataset getQueryDataset() {
        return parent.getQueryDataset();
    }

    @Override
    public void setQueryDataset(QueryDataset queryDataset) {
        throw new UnsupportedOperationException("Subqueries cannot set the query Dataset.");
    }

    @Override
    public void setBaseUri(URI u) {
        throw new UnsupportedOperationException(
                "Subqueries cannot have a different base URI from the parent query.");
    }

    @Override
    public URI getBaseUri() {
        return this.parent.getBaseUri();
    }

    @Override
    public void mapPrefix(String prefix, URI uri) {
        throw new UnsupportedOperationException(
                "Subqueries cannot have a different set of prefixes from the parent query.");
    }

    @Override
    public URI resolveQName(String prefix, String localPart) throws ParseException {
        return this.parent.resolveQName(prefix, localPart);
    }

    @Override
    public SolutionGenerator getSolutionGenerator() {
        return this.parent.getSolutionGenerator();
    }

    @Override
    public void setSolutionGenerator(SolutionGenerator solutionGenerator) {
        throw new UnsupportedOperationException(
                "Subqueries cannot have a different solution generator from the parent query.");
    }

    @Override
    public void prettyPrint(StringBuilder buffer) {
        buffer.append("Query(");

        int limit = this.getLimit();
        if (limit > -1)
            buffer.append("LIMIT(" + limit + "), ");

        int offset = this.getOffset();
        if (offset > -1)
            buffer.append("OFFSET(" + offset + "), ");

        List<OrderingCondition> orderingConditions = this.getOrderingConditions();
        if (orderingConditions.size() > 0) {
            buffer.append("OrderBy(");
            int i = 0;
            for (OrderingCondition condition : orderingConditions) {
                condition.getCondition().prettyPrint(buffer);
                if (++i < orderingConditions.size())
                    buffer.append(", ");
            }
            buffer.append("), ");
        }

        this.getQueryResultForm().prettyPrint(buffer);
        buffer.append(", GraphPattern(");
        queryPattern.prettyPrint(buffer);
        buffer.append(")");

        buffer.append(")");
    }

    /**
     * Pretty print query string
     * 
     * @param printFlags
     *            print flags
     * @param startIndentLevel
     * @return pretty print version of query
     */
    @SuppressWarnings("all")
    public String prettyPrintQueryString(EnumSet<QueryStringPrintOptions> printFlags, int startIndentLevel) {
        StringBuilder s = new StringBuilder();
        prettyPrintQueryStringPart(printFlags, startIndentLevel, s);
        return s.toString();
    }

    /**
     * Pretty print query string
     * 
     * @param printFlags
     *            print flags
     * @param startIndentLevel
     * @return pretty print version of query
     */
    @SuppressWarnings("all")
    public void prettyPrintQueryStringPart(EnumSet<QueryStringPrintOptions> printFlags, int startIndentLevel,
            StringBuilder s) {
        QueryResultForm queryResultForm = this.getQueryResultForm();

        final BidiMap<String, String> prefix2uri = new TreeBidiMap<String, String>();
        Map<String, String> uri2prefix = prefix2uri.inverseBidiMap();
        for (Entry<String, URI> e : this.parent.prefixMap.entrySet())
            prefix2uri.put(e.getKey(), e.getValue().toString());
        this.resultForm.prettyPrintQueryPart(printFlags, startIndentLevel, uri2prefix, s);
        printSeparator(printFlags, startIndentLevel, s);
        s.append("WHERE {");
        printSeparator(printFlags, startIndentLevel + 1, s);
        this.queryPattern.prettyPrintQueryPart(printFlags, startIndentLevel + 1, uri2prefix, s);
        printSeparator(printFlags, startIndentLevel, s);
        s.append("}");

        if (queryResultForm instanceof Projection) {
            Projection projection = (Projection) queryResultForm;
            if (!projection.getGroupByVariables().isEmpty()) {
                printSeparator(printFlags, startIndentLevel, s);
                projection.prettyPrintGroupByQueryPart(printFlags, startIndentLevel, uri2prefix, s);
            }
        }

        if (this.ordering.size() > 0) {
            printSeparator(printFlags, 0, s);
            s.append("ORDER BY ");
            for (int i = 0; i < this.ordering.size(); i++) {
                OrderingCondition c = this.ordering.get(i);
                if (i != 0)
                    s.append(' ');
                c.prettyPrintQueryPart(printFlags, startIndentLevel, uri2prefix, s);
            }
            printSeparator(printFlags, startIndentLevel, s);
        }

        if (this.limit > -1) {
            printSeparator(printFlags, startIndentLevel, s);
            s.append("LIMIT ");
            s.append(this.limit);
        }
        if (this.offset > -1) {
            printSeparator(printFlags, startIndentLevel, s);
            s.append("OFFSET ");
            s.append(this.offset);
        }
    }

    @Override
    public String getQueryString(boolean includeFromClauses) {
        QueryResultForm queryResultForm = this.getQueryResultForm();

        StringBuilder s = new StringBuilder(this.resultForm.toString());

        s.append(" WHERE { ");
        s.append(this.queryPattern);
        s.append(" }");
        if (this.ordering.size() > 0) {
            s.append(" ORDER BY");
            for (OrderingCondition c : this.ordering)
                s.append(" " + c.getCondition());
        }

        if (queryResultForm instanceof Projection) {
            Projection projection = (Projection) queryResultForm;
            List<Variable> vars = projection.getGroupByVariables();
            if (vars != null && !vars.isEmpty()) {
                s.append(" GROUP BY");
                for (Variable v : vars)
                    s.append(" " + v);
            }
        }

        if (this.limit > -1)
            s.append(" LIMIT " + this.limit);
        if (this.offset > -1)
            s.append(" OFFSET " + this.offset);
        return s.toString();
    }

}