/*
* The contents of this file are subject to the Mozilla Public License
* Version 1.1 (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.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
* the License for the specific language governing rights and limitations
* under the License.
*
* The Original Code is the Kowari Metadata Store.
*
* The Initial Developer of the Original Code is Plugged In Software Pty
* Ltd (http://www.pisoftware.com, mailto:info@pisoftware.com). Portions
* created by Plugged In Software Pty Ltd are Copyright (C) 2001,2002
* Plugged In Software Pty Ltd. All Rights Reserved.
*
* Contributor(s): N/A.
*
* [NOTE: The text of this Exhibit A may differ slightly from the text
* of the notices in the Source Code files of the Original Code. You
* should use the text of this Exhibit A rather than the text found in the
* Original Code Source Code for Your Modifications.]
*
*/
package org.mulgara.itql;
// Java 2 standard packages
import java.net.*;
import java.util.*;
// Third party packages
import org.apache.log4j.Logger;
// Automatically generated packages (SableCC)
import org.mulgara.itql.node.AAndModelTerm;
import org.mulgara.itql.node.AExpressionModelFactor;
import org.mulgara.itql.node.AOrModelExpression;
import org.mulgara.itql.node.AFactorModelTerm;
import org.mulgara.itql.node.AResourceModelFactor;
import org.mulgara.itql.node.ATermModelExpression;
import org.mulgara.itql.node.PModelExpression;
import org.mulgara.itql.node.PModelFactor;
import org.mulgara.itql.node.PModelTerm;
import org.mulgara.query.GraphExpression;
import org.mulgara.query.GraphIntersection;
import org.mulgara.query.GraphResource;
import org.mulgara.query.GraphUnion;
import org.mulgara.query.QueryException;
import org.mulgara.util.ServerURIHandler;
import org.mulgara.util.URIUtil;
/**
* Builds model expressions using input from the iTQL command interpreter.
*
* @created 2001-09-11
*
* @author Tom Adams
*
* @version $Revision: 1.9 $
*
* @modified $Date: 2005/04/04 11:30:11 $ by $Author: tomadams $
*
* @maintenanceAuthor $Author: tomadams $
*
* @copyright ©2001-2004
* <a href="http://www.pisoftware.com/">Plugged In Software Pty Ltd</a>
*
* @licence <a href="{@docRoot}/../../LICENCE">Mozilla Public License v1.1</a>
*/
public class GraphExpressionBuilder {
//
// Constants
//
/**
* the category to log to
*/
private final static Logger logger =
Logger.getLogger(GraphExpressionBuilder.class.getName());
//
// Public API (methods overridden from ExpressionBuilder)
//
/**
* Builds a {@link org.mulgara.query.GraphExpression} object from a {@link
* org.mulgara.itql.node.PModelExpression}, using an <code>aliasMap</code>
* to resolve aliases.
*
* TODO: aliasMap is currently ignored!
*
* @param aliasMap the map from targets to aliases
* @param expression a model expression from the parser
* @return RETURNED VALUE TO DO
* @throws QueryException if <code>rawModelExpression</code> does not
* represent a valid query
* @throws URISyntaxException if the <code>rawModelExpression</code> contains
* a resource whose text violates <a
* href="http://www.isi.edu/in-notes/rfc2396.txt">RFC?2396</a>
*/
public static GraphExpression build(Map<String,URI> aliasMap,
PModelExpression expression) throws QueryException, URISyntaxException {
// validate aliasMap parameter
if (aliasMap == null) {
throw new IllegalArgumentException("Null \"aliasMap\" parameter");
}
// end if
// validate expression parameter
if (expression == null) {
throw new IllegalArgumentException("Null \"expression\" parameter");
}
// end if
// logger that we're building a model expression
if (logger.isDebugEnabled()) {
logger.debug("Building model expression from " + expression);
}
// build the model expression from the parser input
GraphExpression graphExpression = buildModelExpression(expression, aliasMap);
// logger that we've building successfully built a model expression
if (logger.isDebugEnabled()) {
logger.debug("Successfully built model expression from " + expression);
}
// return the model expression
return graphExpression;
}
// build()
//
// Internal methods
//
/**
* Recursively builds a {@link org.mulgara.query.GraphExpression} from a
* {@link org.mulgara.itql.node.PModelExpression}.
*
* @param rawModelExpression a raw model expression from the parser
* @return a {@link org.mulgara.query.GraphExpression} suitable for use in
* creating a {@link org.mulgara.query.Query}
* @throws QueryException if <code>rawModelExpression</code> does not
* represent a valid query
* @throws URISyntaxException if the <code>rawModelExpression</code> contains
* a resource whose text violates <a
* href="http://www.isi.edu/in-notes/rfc2396.txt">RFC?2396</a>
*/
private static GraphExpression buildModelExpression(
PModelExpression rawModelExpression, Map<String,URI> aliasMap)
throws QueryException, URISyntaxException {
// validate the rawModelExpression parameter
if (rawModelExpression == null) {
throw new IllegalArgumentException("Null \"rawModelExpression\" " +
"parameter");
}
// end if
// logger that we're building a model expression
if (logger.isDebugEnabled()) {
logger.debug("Building model expression from " + rawModelExpression);
}
// create a new model expression that we can return
GraphExpression graphExpression = null;
// drill down to find its constituents
if (rawModelExpression instanceof AOrModelExpression) {
// logger that we've found a OR model expression
if (logger.isDebugEnabled()) {
logger.debug("Found OR model expression " + rawModelExpression);
}
// get the OR model expression
PModelExpression orModelExpression =
((AOrModelExpression) rawModelExpression).getModelExpression();
// get the model term
PModelTerm modelTerm =
((AOrModelExpression) rawModelExpression).getModelTerm();
// logger that we've found the operands of the union
if (logger.isDebugEnabled()) {
logger.debug("Recursing with model expression " + orModelExpression +
" & model term " + modelTerm);
}
// get the LHS and RHS operands of the union
GraphExpression lhs = buildModelExpression(orModelExpression, aliasMap);
GraphExpression rhs = buildModelExpression(modelTerm, aliasMap);
// logger that we've resolved the operands
if (logger.isDebugEnabled()) {
logger.debug("Resolved LHS union operand " + lhs);
logger.debug("Resolved RHS union operand " + rhs);
}
// apply the union
graphExpression = new GraphUnion(lhs, rhs);
} else if (rawModelExpression instanceof ATermModelExpression) {
// logger that we've got a term model expression
if (logger.isDebugEnabled()) {
logger.debug("Found term model expression " + rawModelExpression);
}
// get the model term
PModelTerm modelTerm = ((ATermModelExpression)rawModelExpression).getModelTerm();
// logger that we're about to resolve the term into an expression
if (logger.isDebugEnabled()) {
logger.debug("Recursing with model term " + modelTerm);
}
// drill down into the model term
graphExpression = buildModelExpression(modelTerm, aliasMap);
}
// end if
// we should not be returning null
if (graphExpression == null) {
throw new QueryException("Unable to parse ITQL model expression " +
"into a valid model expression");
}
// end if
// logger that we've created a model expression
if (logger.isDebugEnabled()) {
logger.debug("Created model expression " + graphExpression);
}
// return the built up expression
return graphExpression;
}
// buildModelExpression()
/**
* Recursively builds a {@link org.mulgara.query.GraphExpression} from a
* {@link org.mulgara.itql.node.PModelTerm}.
*
* @param rawModelTerm a raw model term from the parser
* @return a {@link org.mulgara.query.GraphExpression} suitable for use in
* creating a {@link org.mulgara.query.Query}
* @throws QueryException if <code>rawModelExpression</code> does not
* represent a valid query
* @throws URISyntaxException if the <code>rawModelExpression</code> contains
* a resource whose text violates <a
* href="http://www.isi.edu/in-notes/rfc2396.txt">RFC?2396</a>
*/
private static GraphExpression buildModelExpression(
PModelTerm rawModelTerm, Map<String,URI> aliasMap
) throws QueryException, URISyntaxException {
// validate the rawModelTerm parameter
if (rawModelTerm == null) {
throw new IllegalArgumentException("Null \"rawModelTerm\" " +
"parameter");
}
// end if
// logger that we're building a model expression
if (logger.isDebugEnabled()) {
logger.debug("Building model expression from " + rawModelTerm);
}
// create a new model expression that we can return
GraphExpression graphExpression = null;
// drill down into the model term
if (rawModelTerm instanceof AFactorModelTerm) {
// logger that we've got a factor model term
if (logger.isDebugEnabled()) {
logger.debug("Found factor contraint term " + rawModelTerm);
}
// get the model factor
PModelFactor modelFactor = ((AFactorModelTerm) rawModelTerm).getModelFactor();
// logger that we're recursing with a model part
if (logger.isDebugEnabled()) {
logger.debug("Recursing with model part " + modelFactor);
}
// drill down into the model part
graphExpression = buildModelExpression(modelFactor, aliasMap);
} else if (rawModelTerm instanceof AAndModelTerm) {
// logger that we've got a AND model term
if (logger.isDebugEnabled()) {
logger.debug("Found AND contraint term " + rawModelTerm);
}
// get the model term
PModelTerm modelTerm = ((AAndModelTerm)rawModelTerm).getModelTerm();
// get the model part
PModelFactor modelFactor = ((AAndModelTerm)rawModelTerm).getModelFactor();
// logger that we've found the operands of the union
if (logger.isDebugEnabled()) {
logger.debug("Recursing with model term " + modelTerm +
" & model factor " + modelFactor);
}
// get the LHS and RHS operands of the intersection
GraphExpression lhs = buildModelExpression(modelTerm, aliasMap);
GraphExpression rhs = buildModelExpression(modelFactor, aliasMap);
// logger that we've resolved the operands
if (logger.isDebugEnabled()) {
logger.debug("Resolved LHS intersection operand " + lhs);
logger.debug("Resolved RHS intersection operand " + rhs);
}
// apply the intersection
graphExpression = new GraphIntersection(lhs, rhs);
}
// end if
// we should not be returning null
if (graphExpression == null) {
throw new QueryException("Unable to parse ITQL model term into a valid model expression");
}
// end if
// logger that we've created a model expression
if (logger.isDebugEnabled()) {
logger.debug("Created model expression " + graphExpression);
}
// return the built up expression
return graphExpression;
}
// buildModelExpression()
// buildModelExpression()
/**
* Recursively builds a {@link org.mulgara.query.GraphExpression} from a
* {@link org.mulgara.itql.node.PModelFactor}.
*
* @param rawModelFactor a raw model factor from the parser
* @return a {@link org.mulgara.query.GraphExpression} suitable for use in
* creating a {@link org.mulgara.query.Query}
* @throws QueryException if <code>rawModelExpression</code> does not
* represent a valid query
* @throws URISyntaxException if the <code>rawModelExpression</code> contains
* a resource whose text violates <a
* href="http://www.isi.edu/in-notes/rfc2396.txt">RFC?2396</a>
*/
private static GraphExpression buildModelExpression(
PModelFactor rawModelFactor, Map<String,URI> aliasMap
) throws QueryException, URISyntaxException {
// validate the rawModelFactor parameter
if (rawModelFactor == null) {
throw new IllegalArgumentException("Null \"rawModelFactor\" parameter");
}
// end if
// logger that we're building a model expression
if (logger.isDebugEnabled()) {
logger.debug("Building model expression from " + rawModelFactor);
}
// create a new model expression that we can return
GraphExpression graphExpression = null;
// drill down into the model term
if (rawModelFactor instanceof AResourceModelFactor) {
// logger that we've got a model model factor
if (logger.isDebugEnabled()) {
logger.debug("Found resource model factor " + rawModelFactor);
}
// get the resource
String resource = ((AResourceModelFactor)rawModelFactor).getResource().getText();
// logger that we've found a resource
if (logger.isDebugEnabled()) {
logger.debug("Found resource " + resource);
}
// this resource is what we're looking for
URI modelURI = URIUtil.convertToURI(resource, aliasMap);
graphExpression = new GraphResource(ServerURIHandler.removePort(modelURI));
} else if (rawModelFactor instanceof AExpressionModelFactor) {
// logger that we've got an expression model factor
if (logger.isDebugEnabled()) {
logger.debug("Found factor expression model factor " + rawModelFactor);
}
// get the model expression
PModelExpression embeddedModelExpression = ((AExpressionModelFactor)rawModelFactor).getModelExpression();
// logger that we're recursing with a model expression
if (logger.isDebugEnabled()) {
logger.debug("Recursing with model factor " + graphExpression);
}
// build the model expression
graphExpression = buildModelExpression(embeddedModelExpression, aliasMap);
}
// end if
// we should not be returning null
if (graphExpression == null) {
throw new QueryException("Unable to parse ITQL model factor " +
"into a valid model expression");
}
// end if
// logger that we've created a model expression
if (logger.isDebugEnabled()) {
logger.debug("Created model expression " + graphExpression);
}
// return the built up expression
return graphExpression;
}
// buildModelExpression()
}
// GraphExpressionBuilder