/* * 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.URISyntaxException; import java.util.ArrayList; import java.util.List; // Third party packages import org.apache.log4j.Logger; // Automatically generated packages (SableCC) import org.mulgara.itql.analysis.AnalysisAdapter; import org.mulgara.itql.node.*; // Locally written packages import org.mulgara.query.*; import org.mulgara.query.rdf.URIReferenceImpl; /** * A implementation of SableCC's Adapter which creates list of variables * depending on the type of object given (visitor pattern). Tied heavily to * the ItqlInterpreter. * * @created 2004-06-18 * * @author Andrew Newman * * @company <a href="mailto:info@PIsoftware.com">Plugged In Software</a> * * @copyright ©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 VariableBuilder extends AnalysisAdapter { /** The logger */ private final static Logger logger = Logger.getLogger(VariableBuilder.class.getName()); /** Variable name generator for anonymous columns */ private VariableFactory variableFactory; /** URI Syntax Exception - not null if exception occurred since last get. */ private URISyntaxException uriException = null; /** Query Exception - not null if exception occurred since last get. */ private QueryException queryException = null; /** * The list of variables - these are mixed object types: * ConstantValue, Variable, Count, SubQuery */ private List<SelectElement> variableList; /** The TQL interpreter */ private SableCCInterpreter interpreter; /** * Create a new builder. Requires methods on the interpreter in order to * function correctly. * @param newInterpreter the interpreter to use. */ public VariableBuilder(SableCCInterpreter newInterpreter, VariableFactory newVariableFactory) { variableList = new ArrayList<SelectElement>(); interpreter = newInterpreter; variableFactory = newVariableFactory; } /** * Converts a literal element to a constant and adds it to the variable list. * This method is called back from SableCC. * @param element the literal element to add to the variable list. */ public void caseALiteralElement(ALiteralElement element) { variableList.add(new ConstantValue( variableFactory.newVariable(), interpreter.toLiteralImpl(((ALiteralElement)element).getLiteral()) )); } /** * Converts a resource element to a constant and adds it to the variable list. * This method is called back from SableCC. * @param element the resource element to add to the variable list. */ public void caseAResourceElement(AResourceElement element) { // add a new resource to the list variableList.add(new ConstantValue( variableFactory.newVariable(), new URIReferenceImpl(interpreter.toURI(((AResourceElement) element).getResource())) )); } /** * Gets the string values of a variable element and adds it to the variable list. * This method is called back from SableCC. * @param element the variable element to add to the variable list. */ public void caseAVariableElement(AVariableElement element) { // get the name of this variable String variableName = ((AVariable)((AVariableElement)element).getVariable()).getIdentifier().getText(); if (logger.isDebugEnabled()) logger.debug("Found variable $" + variableName); // add a new variable to the list variableList.add(new Variable(variableName)); if (logger.isDebugEnabled()) logger.debug("Variable list: " + variableList); } /** * Handle an aggregate element. At the moment it handles both count and * sub-queries. Any further aggregates will be instantiated here. * Will set URIException or QueryException if an exception occurs. * This method is called back from SableCC. * @param element the aggregate element to add to the variable list. */ public void caseAAggregateElement(AAggregateElement element) { try { AAggregateElement aggregateElement = (AAggregateElement)element; // build the elements of the aggregate Variable aggregateVariable = variableFactory.newVariable(); Query aggregateQuery = interpreter.buildQuery(aggregateElement.getQuery()); // create the correct aggregate type - count or subquery PAggregate aggregate = aggregateElement.getAggregate(); if (aggregate instanceof ACountAggregate) { variableList.add(new Count(aggregateVariable, aggregateQuery)); } else if (aggregate instanceof ASubqueryAggregate) { variableList.add(new Subquery(aggregateVariable, aggregateQuery)); } else { throw new Error("Unsupported aggregate type: " + aggregate.getClass()); } } catch (QueryException qe) { queryException = qe; } catch (URISyntaxException use) { uriException = use; } } /** * Returns the latest variable list or throws an exception if there * was an error creating it. Once called the variable list is cleared * and exceptions are nulled. * @return A list of: Variable, ConstantValue, Count, Subquery. * @throws QueryException if the variable does not is invalid * @throws URISyntaxException if the variable contains a resource whose * text violates <a href="http://www.isi.edu/in-notes/rfc2396.txt">RFC?2396</a> */ public List<SelectElement> getVariableList() throws QueryException, URISyntaxException { try { List<SelectElement> tmpVariableList = new ArrayList<SelectElement>(variableList); if (uriException != null) throw uriException; else if (queryException != null) throw queryException; else return tmpVariableList; } finally { uriException = null; queryException = null; variableList.clear(); } } }