Main Page | Packages | Class Hierarchy | Class List | File List | Class Members

Interpreter.java

Go to the documentation of this file.
00001 //$Id: Interpreter_8java-source.html 336 2010-01-12 20:03:17Z linus $
00002 //Copyright (c) 2003, Mikael Albertsson, Mattias Danielsson, Per Engström, 
00003 //Fredrik Gröndahl, Martin Gyllensten, Anna Kent, Anders Olsson, 
00004 //Mattias Sidebäck.
00005 //All rights reserved.
00006 //
00007 //Redistribution and use in source and binary forms, with or without 
00008 //modification, are permitted provided that the following conditions are met:
00009 //
00010 //* Redistributions of source code must retain the above copyright notice, 
00011 //  this list of conditions and the following disclaimer.
00012 // 
00013 //* Redistributions in binary form must reproduce the above copyright 
00014 //  notice, this list of conditions and the following disclaimer in the 
00015 //  documentation and/or other materials provided with the distribution.
00016 //
00017 //* Neither the name of the University of Linköping nor the names of its 
00018 //  contributors may be used to endorse or promote products derived from 
00019 //  this software without specific prior written permission. 
00020 //
00021 //THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
00022 //AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
00023 //IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 
00024 //ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 
00025 //LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 
00026 //CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
00027 //SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
00028 //INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
00029 //CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
00030 //ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
00031 //THE POSSIBILITY OF SUCH DAMAGE.
00032 
00033 
00034 package org.argoprint.engine.interpreters;
00035 
00036 import java.util.Vector;
00037 import org.w3c.dom.*;
00038 import org.argoprint.ArgoPrintDataSource;
00039 import org.argoprint.engine.*;
00040 
00041 /**
00042  * Superclass for the interpreters. This abstract class implements the chain 
00043  * of responsibility design pattern. All argoprint specific elements are 
00044  * handled by classes extending this class. 
00045  */
00046 abstract public class Interpreter{
00047     /**
00048      * The namespace prefix identifying the elements that shall be processed.
00049      */
00050     protected static final String PREFIX = "ap";
00051     private String _tagName;
00052     private Interpreter _nextHandler;
00053     /**
00054      * A reference to the first handler in the chain of responsibility, 
00055      * for recursion.
00056      */
00057     protected Interpreter _firstHandler;
00058     /**
00059      * A reference to the data source to use.
00060      */
00061     protected ArgoPrintDataSource _dataSource;
00062     
00063     public Interpreter() {
00064     }
00065     
00066     /**
00067      * @param tagName The name of the tag that this Interpreter can process.
00068      * @param dataSource The ArgoPrintDataSource that this Interpreter should
00069      * fetch data from.
00070      */
00071     public Interpreter(String tagName, ArgoPrintDataSource dataSource) {
00072         _tagName = tagName;
00073         _dataSource = dataSource;
00074         _nextHandler = null;
00075         _firstHandler = null;
00076     }
00077     
00078     /**
00079      * Specifies the next Interpreter in the chain of responsibility.
00080      * 
00081      * @param nextHandler The next Interpreter.
00082      */
00083     public void setNextHandler(Interpreter nextHandler) {
00084         _nextHandler = nextHandler;
00085     }
00086     
00087     /**
00088      * Specifies the first Interpreter in the chain of responsibility.
00089      * 
00090      * @param firstHandler The first Interpreter.
00091      */
00092     public void setFirstHandler(Interpreter firstHandler) {
00093     _firstHandler = firstHandler;
00094     }
00095     
00096     /**
00097      * Processes the Node or sends it to the next Interpreter.
00098      *  
00099      * @param tagNode The Node to handle.
00100      * @param env The environment in which the Node is to be processed.
00101      */
00102     public void handleTag(Node tagNode, Environment env)
00103     throws Exception {
00104     if (canHandle(tagNode))
00105         processTag(tagNode, env);
00106     else
00107         if (_nextHandler == null)
00108         throw new Exception("The last Interpreter in the chain could not handle the Node.");
00109         else
00110         _nextHandler.handleTag(tagNode, env);   
00111     }
00112 
00113     /**
00114      * Processes a tag.
00115      * 
00116      * @param tagNode The tag to process.
00117      * @param env The environment in which to process it.
00118      */
00119     protected abstract void processTag(Node tagNode, Environment env) throws Exception;
00120 
00121     /**
00122      * Checks if this Interpreter can handle this Node.
00123      * 
00124      * @param tagNode The Node to check.
00125      */
00126     protected boolean canHandle(Node tagNode){
00127     if (tagNode.getNodeType() == Node.ELEMENT_NODE && tagNode.getLocalName().equals(_tagName) && tagNode.getPrefix().equals(PREFIX)) {
00128         return true;
00129     }
00130     else {
00131         return false;
00132     }
00133     }
00134     
00135     /**
00136      * Uses the attributes what and iterator to call the data source and 
00137      * return the value.
00138      * 
00139      * @param callAttr The name of the attribute containing the call.
00140      * @param attributes A NamedNodeMap of map of attributes that must contain 
00141      * at least the attribute what.
00142      * @param env The Environment in which to process the call.
00143      * @return The Object as returned from the data source.
00144      * @throws Exception
00145      */
00146     protected Object callDataSource(String callAttr, NamedNodeMap attributes, Environment env) 
00147     throws Exception {
00148     Node callAttrNode = attributes.getNamedItem(callAttr);
00149     if (callAttrNode == null)
00150         throw new BadTemplateException(_tagName + " tag contains no " + callAttr +" attribute.");
00151     Object returnValue;
00152     Node iteratorAttribute = attributes.getNamedItem("iterator");
00153     if (iteratorAttribute == null)
00154         returnValue = _dataSource.caller(callAttrNode.getNodeValue());
00155     else {
00156         if (!env.existsIterator(iteratorAttribute.getNodeValue()))
00157         throw new BadTemplateException("Value of iterator in " + _tagName + 
00158                            " tag does not correspond to a valid iterator. "
00159                            + iteratorAttribute.getNodeValue());
00160         
00161         ArgoPrintIterator iterator = env.getIterator(iteratorAttribute.getNodeValue());
00162         returnValue = _dataSource.caller(callAttrNode.getNodeValue(), iterator.currentObject());
00163     }
00164     return returnValue;
00165     }
00166         
00167     /**
00168      * Checks if Node has a certain name.
00169      * 
00170      * @param node The node to check
00171      * @param prefix The namespace prefix
00172      * @param localName The local name
00173      * @return
00174      */
00175     protected boolean isNodeNamed(Node node, String prefix, String localName) {
00176     if ((node.getLocalName() == null) || node.getPrefix() == null)
00177         return false;
00178     else
00179         return (node.getLocalName().equals(localName) && node.getPrefix().equals(prefix));
00180     }
00181     
00182     /**
00183      * Constructs a Vector from a NodeList.
00184      * 
00185      * @param nodeList The NodeList
00186      * @return A vector with the same ordering as the NodeList.
00187      */
00188     protected Vector getVector(NodeList nodeList) { 
00189     int numNodes = nodeList.getLength();
00190     Vector vector = new Vector(numNodes);
00191     for (int i = 0; i < numNodes; i++){
00192         vector.add(i, nodeList.item(i));
00193     }
00194     return vector;
00195     }
00196     
00197     /**
00198      * Recurses on every Node in the Vector.
00199      * 
00200      * @param nodes A vector containing Nodes.
00201      * @param env
00202      * @throws Exception
00203      */
00204     protected void recurse(Vector nodes, Environment env) throws Exception {
00205     for (int i = 0; i < nodes.size(); i++) {
00206         _firstHandler.handleTag((Node)nodes.get(i), env);
00207     }
00208     }
00209 }

Generated on Tue Dec 2 22:50:56 2003 for ArgoPrint by doxygen 1.3.4