FileDocCategorySizeDatePackage
Parser.javaAPI DocJava SE 6 API45982Tue Jun 10 00:22:28 BST 2008com.sun.org.apache.xalan.internal.xsltc.compiler

Parser

public class Parser extends Object implements Constants, ContentHandler
author
Jacek Ambroziak
author
Santiago Pericas-Geertsen
author
G. Todd Miller
author
Morten Jorgensen
author
Erwin Bolwidt

Fields Summary
private static final String
XSL
private static final String
TRANSLET
private Locator
_locator
private XSLTC
_xsltc
private XPathParser
_xpathParser
private Vector
_errors
private Vector
_warnings
private Hashtable
_instructionClasses
private Hashtable
_instructionAttrs
private Hashtable
_qNames
private Hashtable
_namespaces
private QName
_useAttributeSets
private QName
_excludeResultPrefixes
private QName
_extensionElementPrefixes
private Hashtable
_variableScope
private Stylesheet
_currentStylesheet
private SymbolTable
_symbolTable
private Output
_output
private Template
_template
private boolean
_rootNamespaceDef
private SyntaxTreeNode
_root
private String
_target
private int
_currentImportPrecedence
private String
_PImedia
private String
_PItitle
private String
_PIcharset
private int
_templateIndex
private boolean
versionIsOne
Creates a new node in the abstract syntax tree. This node can be o) a supported XSLT 1.0 element o) an unsupported XSLT element (post 1.0) o) a supported XSLT extension o) an unsupported XSLT extension o) a literal result element (not an XSLT element and not an extension) Unsupported elements do not directly generate an error. We have to wait until we have received all child elements of an unsupported element to see if any elements exist.
private Stack
_parentStack
SAX2 ContentHandler INTERFACE
private Hashtable
_prefixMapping
Constructors Summary
public Parser(XSLTC xsltc)


       
	_xsltc = xsltc;
    
Methods Summary
public voidaddParameter(com.sun.org.apache.xalan.internal.xsltc.compiler.Param param)

	addVariableOrParam(param);
    
public voidaddVariable(com.sun.org.apache.xalan.internal.xsltc.compiler.Variable var)

	addVariableOrParam(var);
    
private voidaddVariableOrParam(com.sun.org.apache.xalan.internal.xsltc.compiler.VariableBase var)

	Object existing = _variableScope.get(var.getName());
	if (existing != null) {
	    if (existing instanceof Stack) {
		Stack stack = (Stack)existing;
		stack.push(var);
	    }
	    else if (existing instanceof VariableBase) {
		Stack stack = new Stack();
		stack.push(existing);
		stack.push(var);
		_variableScope.put(var.getName(), stack);
	    }
	}
	else {
	    _variableScope.put(var.getName(), var);
	}
    
public voidcharacters(char[] ch, int start, int length)
SAX2: Receive notification of character data.

	String string = new String(ch, start, length);
	SyntaxTreeNode parent = (SyntaxTreeNode)_parentStack.peek();

	if (string.length() == 0) return;

	// If this text occurs within an <xsl:text> element we append it
	// as-is to the existing text element
	if (parent instanceof Text) {
	    ((Text)parent).setText(string);
	    return;
	}

	// Ignore text nodes that occur directly under <xsl:stylesheet>
	if (parent instanceof Stylesheet) return;

	SyntaxTreeNode bro = parent.lastChild();
	if ((bro != null) && (bro instanceof Text)) {
	    Text text = (Text)bro;
	    if (!text.isTextElement()) {
		if ((length > 1) || ( ((int)ch[0]) < 0x100)) {
		    text.setText(string);
		    return;
		}
	    }
	}

	// Add it as a regular text node otherwise
	parent.addElement(new Text(string));
    
private voidcheckForSuperfluousAttributes(com.sun.org.apache.xalan.internal.xsltc.compiler.SyntaxTreeNode node, org.xml.sax.Attributes attrs)
checks the list of attributes against a list of allowed attributes for a particular element node.

	QName qname = node.getQName();
	boolean isStylesheet = (node instanceof Stylesheet); 
        String[] legal = (String[]) _instructionAttrs.get(qname);
	if (versionIsOne && legal != null) {
	    int j;
	    final int n = attrs.getLength();

	    for (int i = 0; i < n; i++) {
	        final String attrQName = attrs.getQName(i);

	        if (isStylesheet && attrQName.equals("version")) {
	            versionIsOne = attrs.getValue(i).equals("1.0");
	        }

		// Ignore if special or if it has a prefix
	        if (attrQName.startsWith("xml") ||
		    attrQName.indexOf(':") > 0) continue;

	        for (j = 0; j < legal.length; j++) {
	            if (attrQName.equalsIgnoreCase(legal[j])) {
		        break;
		    }	
	        }
	        if (j == legal.length) {
	            final ErrorMsg err = 
		        new ErrorMsg(ErrorMsg.ILLEGAL_ATTRIBUTE_ERR, 
				attrQName, node);
		    // Workaround for the TCK failure ErrorListener.errorTests.error001..
	            err.setWarningError(true);
		    reportError(WARNING, err);
	        }
	    }
        }	
    
public voidcreateAST(com.sun.org.apache.xalan.internal.xsltc.compiler.Stylesheet stylesheet)
Instanciates a SAX2 parser and generate the AST from the input.

	try {
	    if (stylesheet != null) {
		stylesheet.parseContents(this);
		final int precedence = stylesheet.getImportPrecedence();
		final Enumeration elements = stylesheet.elements();
		while (elements.hasMoreElements()) {
		    Object child = elements.nextElement();
		    if (child instanceof Text) {
			final int l = getLineNumber();
			ErrorMsg err =
			    new ErrorMsg(ErrorMsg.ILLEGAL_TEXT_NODE_ERR,l,null);
			reportError(ERROR, err);
		    }
		}
		if (!errorsFound()) {
		    stylesheet.typeCheck(_symbolTable);
		}
	    }
	}
	catch (TypeCheckError e) {
	    reportError(ERROR, new ErrorMsg(e));
	}
    
public booleanelementSupported(java.lang.String namespace, java.lang.String localName)

	return(_instructionClasses.get(getQName(namespace, XSL, localName)) != null);
    
public voidendDocument()
SAX2: Receive notification of the end of a document.

 
public voidendElement(java.lang.String uri, java.lang.String localname, java.lang.String qname)
SAX2: Receive notification of the end of an element.

	_parentStack.pop();
    
public voidendPrefixMapping(java.lang.String prefix)
SAX2: End the scope of a prefix-URI Namespace mapping. This has to be passed on to the symbol table!

 
public booleanerrorsFound()
Returns true if there were any errors during compilation

	return _errors.size() > 0;
    
private com.sun.org.apache.xalan.internal.xsltc.compiler.SyntaxTreeNodefindStylesheet(com.sun.org.apache.xalan.internal.xsltc.compiler.SyntaxTreeNode root, java.lang.String href)
Find a Stylesheet element with a specific ID attribute value. This method is used to find a Stylesheet node that is referred in a processing instruction.


	if (root == null) return null;

	if (root instanceof Stylesheet) {
	    String id = root.getAttribute("id");
	    if (id.equals(href)) return root;
	}
	Vector children = root.getContents();
	if (children != null) {
	    final int count = children.size();
	    for (int i = 0; i < count; i++) {
		SyntaxTreeNode child = (SyntaxTreeNode)children.elementAt(i);
		SyntaxTreeNode node = findStylesheet(child, href);
		if (node != null) return node;
	    }
	}
	return null;	
    
public booleanfunctionSupported(java.lang.String fname)

	return(_symbolTable.lookupPrimop(fname) != null);
    
public intgetCurrentImportPrecedence()

	return _currentImportPrecedence;
    
public com.sun.org.apache.xalan.internal.xsltc.compiler.StylesheetgetCurrentStylesheet()

	return _currentStylesheet;
    
public com.sun.org.apache.xalan.internal.xsltc.compiler.SyntaxTreeNodegetDocumentRoot()

	return _root;
    
public java.util.VectorgetErrors()

	return _errors;
    
public com.sun.org.apache.xalan.internal.xsltc.compiler.QNamegetExcludeResultPrefixes()

	return _excludeResultPrefixes;
    
public com.sun.org.apache.xalan.internal.xsltc.compiler.QNamegetExtensionElementPrefixes()

	return _extensionElementPrefixes;
    
private intgetLineNumber()
Get the line number, or zero if there is no _locator.

    	int line = 0;
    	if (_locator != null)
    		line = _locator.getLineNumber();
    	return line;
    
public intgetNextImportPrecedence()

	return ++_currentImportPrecedence;
    
public com.sun.org.apache.xalan.internal.xsltc.compiler.OutputgetOutput()

	return _output;
    
public java.util.PropertiesgetOutputProperties()

	return getTopLevelStylesheet().getOutputProperties();
    
public com.sun.org.apache.xalan.internal.xsltc.compiler.QNamegetQName(java.lang.String stringRep)

	return getQName(stringRep, true, false);    
    
public com.sun.org.apache.xalan.internal.xsltc.compiler.QNamegetQName(java.lang.String stringRep, boolean reportError)

	return getQName(stringRep, reportError, false);
    
private com.sun.org.apache.xalan.internal.xsltc.compiler.QNamegetQName(java.lang.String stringRep, boolean reportError, boolean ignoreDefaultNs)

	// parse and retrieve namespace
	final int colon = stringRep.lastIndexOf(':");
	if (colon != -1) {
	    final String prefix = stringRep.substring(0, colon);
	    final String localname = stringRep.substring(colon + 1);
	    String namespace = null;
	    
	    // Get the namespace uri from the symbol table
	    if (prefix.equals(XMLNS_PREFIX) == false) {
		namespace = _symbolTable.lookupNamespace(prefix);
		if (namespace == null && reportError) {
		    final int line = getLineNumber();
		    ErrorMsg err = new ErrorMsg(ErrorMsg.NAMESPACE_UNDEF_ERR,
						line, prefix);
		    reportError(ERROR, err);
		}
	    }
	    return getQName(namespace, prefix, localname);
	}
	else {
	    if (stringRep.equals(XMLNS_PREFIX)) {
		ignoreDefaultNs = true;
	    }
	    final String defURI = ignoreDefaultNs ? null 
				  : _symbolTable.lookupNamespace(EMPTYSTRING);
	    return getQName(defURI, null, stringRep);
	}
    
public com.sun.org.apache.xalan.internal.xsltc.compiler.QNamegetQName(java.lang.String namespace, java.lang.String prefix, java.lang.String localname)

	if (namespace == null || namespace.equals(EMPTYSTRING)) {
	    QName name = (QName)_qNames.get(localname);
	    if (name == null) {
		name = new QName(null, prefix, localname);
		_qNames.put(localname, name);
	    }
	    return name;
	}
	else {
	    Dictionary space = (Dictionary)_namespaces.get(namespace);
	    if (space == null) {
		final QName name = new QName(namespace, prefix, localname);
		_namespaces.put(namespace, space = new Hashtable());
		space.put(localname, name);
		return name;
	    }
	    else {
		QName name = (QName)space.get(localname);
		if (name == null) {
		    name = new QName(namespace, prefix, localname);
		    space.put(localname, name);
		}
		return name;
	    }
	}
    
public com.sun.org.apache.xalan.internal.xsltc.compiler.QNamegetQName(java.lang.String scope, java.lang.String name)

	return getQName(scope + name);
    
public com.sun.org.apache.xalan.internal.xsltc.compiler.QNamegetQName(com.sun.org.apache.xalan.internal.xsltc.compiler.QName scope, com.sun.org.apache.xalan.internal.xsltc.compiler.QName name)

	return getQName(scope.toString() + name.toString());
    
public com.sun.org.apache.xalan.internal.xsltc.compiler.QNamegetQNameIgnoreDefaultNs(java.lang.String stringRep)

	return getQName(stringRep, true, true);
    
public com.sun.org.apache.xalan.internal.xsltc.compiler.QNamegetQNameSafe(java.lang.String stringRep)

	// parse and retrieve namespace
	final int colon = stringRep.lastIndexOf(':");
	if (colon != -1) {
	    final String prefix = stringRep.substring(0, colon);
	    final String localname = stringRep.substring(colon + 1);
	    String namespace = null;
	    
	    // Get the namespace uri from the symbol table
	    if (prefix.equals(XMLNS_PREFIX) == false) {
		namespace = _symbolTable.lookupNamespace(prefix);
		if (namespace == null) namespace = EMPTYSTRING;
	    }
	    return getQName(namespace, prefix, localname);
	}
	else {
	    final String uri = stringRep.equals(XMLNS_PREFIX) ? null
		: _symbolTable.lookupNamespace(EMPTYSTRING);
	    return getQName(uri, null, stringRep);
	}
    
private com.sun.org.apache.xalan.internal.xsltc.compiler.SyntaxTreeNodegetStylesheet(com.sun.org.apache.xalan.internal.xsltc.compiler.SyntaxTreeNode root)
Extracts the DOM for the stylesheet. In the case of an embedded stylesheet, it extracts the DOM subtree corresponding to the embedded stylesheet that has an 'id' attribute whose value is the same as the value declared in the processing instruction (P.I.). In the xml-stylesheet P.I. the value is labeled as the 'href' data of the P.I. The extracted DOM representing the stylesheet is returned as an Element object.


	// Assume that this is a pure XSL stylesheet if there is not
	// <?xml-stylesheet ....?> processing instruction
	if (_target == null) {
	    if (!_rootNamespaceDef) {
		ErrorMsg msg = new ErrorMsg(ErrorMsg.MISSING_XSLT_URI_ERR);
		throw new CompilerException(msg.toString());
	    }
	    return(root);
	}

	// Find the xsl:stylesheet or xsl:transform with this reference
	if (_target.charAt(0) == '#") {
	    SyntaxTreeNode element = findStylesheet(root, _target.substring(1));
	    if (element == null) {
		ErrorMsg msg = new ErrorMsg(ErrorMsg.MISSING_XSLT_TARGET_ERR,
					    _target, root);
		throw new CompilerException(msg.toString());
	    }
	    return(element);
	}
	else {
	    return(loadExternalStylesheet(_target));
	}
    
public com.sun.org.apache.xalan.internal.xsltc.compiler.SymbolTablegetSymbolTable()

	return _symbolTable;
    
public com.sun.org.apache.xalan.internal.xsltc.compiler.TemplategetTemplate()

	return _template;
    
public intgetTemplateIndex()


       
	return(_templateIndex++);
    
private java.lang.StringgetTokenValue(java.lang.String token)

	final int start = token.indexOf('"");
	final int stop = token.lastIndexOf('"");
	return token.substring(start+1, stop);
    
public com.sun.org.apache.xalan.internal.xsltc.compiler.StylesheetgetTopLevelStylesheet()

	return _xsltc.getStylesheet();
    
public com.sun.org.apache.xalan.internal.xsltc.compiler.QNamegetUseAttributeSets()

	return _useAttributeSets;
    
public java.util.VectorgetWarnings()

	return _warnings;
    
public com.sun.org.apache.xalan.internal.xsltc.compiler.XSLTCgetXSLTC()

	return _xsltc;
    
public voidignorableWhitespace(char[] ch, int start, int length)
IGNORED - all ignorable whitespace is ignored

 
public voidinit()

	_qNames              = new Hashtable(512);
	_namespaces          = new Hashtable();
	_instructionClasses  = new Hashtable();
	_instructionAttrs    = new Hashtable();
	_variableScope       = new Hashtable();
	_template            = null;
	_errors              = new Vector();
	_warnings            = new Vector();
	_symbolTable         = new SymbolTable();
	_xpathParser         = new XPathParser(this);
	_currentStylesheet   = null;
        _output              = null;
        _root                = null;
        _rootNamespaceDef    = false;
	_currentImportPrecedence = 1;
	
	initStdClasses();
	initInstructionAttrs();
	initExtClasses();
	initSymbolTable();
	
	_useAttributeSets =
	    getQName(XSLT_URI, XSL, "use-attribute-sets");
	_excludeResultPrefixes =
	    getQName(XSLT_URI, XSL, "exclude-result-prefixes");
	_extensionElementPrefixes =
	    getQName(XSLT_URI, XSL, "extension-element-prefixes");
    
private voidinitAttrTable(java.lang.String elementName, java.lang.String[] attrs)

	_instructionAttrs.put(getQName(XSLT_URI, XSL, elementName),
				attrs);
    
private voidinitExtClass(java.lang.String elementName, java.lang.String className)

	_instructionClasses.put(getQName(TRANSLET_URI, TRANSLET, elementName),
				COMPILER_PACKAGE + '." + className);
    
private voidinitExtClass(java.lang.String namespace, java.lang.String elementName, java.lang.String className)

        _instructionClasses.put(getQName(namespace, TRANSLET, elementName),
                                COMPILER_PACKAGE + '." + className);
    
private voidinitExtClasses()

	initExtClass("output", "TransletOutput");
        initExtClass(REDIRECT_URI, "write", "TransletOutput");
    
private voidinitInstructionAttrs()

	initAttrTable("template", 
	    new String[] {"match", "name", "priority", "mode"});
	initAttrTable("stylesheet", 
	    new String[] {"id", "version", "extension-element-prefixes",
		"exclude-result-prefixes"});
	initAttrTable("transform",
	    new String[] {"id", "version", "extension-element-prefixes",
		"exclude-result-prefixes"});
	initAttrTable("text", new String[] {"disable-output-escaping"}); 
	initAttrTable("if", new String[] {"test"}); 
	initAttrTable("choose", new String[] {}); 
	initAttrTable("when", new String[] {"test"}); 
	initAttrTable("otherwise", new String[] {}); 
	initAttrTable("for-each", new String[] {"select"}); 
	initAttrTable("message", new String[] {"terminate"}); 
	initAttrTable("number", 
	    new String[] {"level", "count", "from", "value", "format", "lang",
		"letter-value", "grouping-separator", "grouping-size"});
		initAttrTable("comment", new String[] {}); 
	initAttrTable("copy", new String[] {"use-attribute-sets"}); 
	initAttrTable("copy-of", new String[] {"select"}); 
	initAttrTable("param", new String[] {"name", "select"}); 
	initAttrTable("with-param", new String[] {"name", "select"}); 
	initAttrTable("variable", new String[] {"name", "select"}); 
	initAttrTable("output", 
	    new String[] {"method", "version", "encoding", 
		"omit-xml-declaration", "standalone", "doctype-public",
		"doctype-system", "cdata-section-elements", "indent",
		"media-type"}); 
	initAttrTable("sort", 
	   new String[] {"select", "order", "case-order", "lang", "data-type"});
	initAttrTable("key", new String[] {"name", "match", "use"}); 
	initAttrTable("fallback", new String[] {}); 
	initAttrTable("attribute", new String[] {"name", "namespace"}); 
	initAttrTable("attribute-set", 
	    new String[] {"name", "use-attribute-sets"}); 
	initAttrTable("value-of", 
	    new String[] {"select", "disable-output-escaping"}); 
	initAttrTable("element", 
	    new String[] {"name", "namespace", "use-attribute-sets"}); 
	initAttrTable("call-template", new String[] {"name"}); 
	initAttrTable("apply-templates", new String[] {"select", "mode"}); 
	initAttrTable("apply-imports", new String[] {}); 
	initAttrTable("decimal-format", 
	    new String[] {"name", "decimal-separator", "grouping-separator",
		"infinity", "minus-sign", "NaN", "percent", "per-mille",
		"zero-digit", "digit", "pattern-separator"}); 
	initAttrTable("import", new String[] {"href"}); 
	initAttrTable("include", new String[] {"href"}); 
	initAttrTable("strip-space", new String[] {"elements"}); 
	initAttrTable("preserve-space", new String[] {"elements"}); 
	initAttrTable("processing-instruction", new String[] {"name"}); 
	initAttrTable("namespace-alias", 
	   new String[] {"stylesheet-prefix", "result-prefix"}); 
    
private voidinitStdClass(java.lang.String elementName, java.lang.String className)

	_instructionClasses.put(getQName(XSLT_URI, XSL, elementName),
				COMPILER_PACKAGE + '." + className);
    
private voidinitStdClasses()
Initialize the _instructionClasses Hashtable, which maps XSL element names to Java classes in this package.

	initStdClass("template", "Template");
	initStdClass("stylesheet", "Stylesheet");
	initStdClass("transform", "Stylesheet");
	initStdClass("text", "Text");
	initStdClass("if", "If");
	initStdClass("choose", "Choose");
	initStdClass("when", "When");
	initStdClass("otherwise", "Otherwise");
	initStdClass("for-each", "ForEach");
	initStdClass("message", "Message");
	initStdClass("number", "Number");
	initStdClass("comment", "Comment");
	initStdClass("copy", "Copy");
	initStdClass("copy-of", "CopyOf");
	initStdClass("param", "Param");
	initStdClass("with-param", "WithParam");
	initStdClass("variable", "Variable");
	initStdClass("output", "Output");
	initStdClass("sort", "Sort");
	initStdClass("key", "Key");
	initStdClass("fallback", "Fallback");
	initStdClass("attribute", "XslAttribute");
	initStdClass("attribute-set", "AttributeSet");
	initStdClass("value-of", "ValueOf");
	initStdClass("element", "XslElement");
	initStdClass("call-template", "CallTemplate");
	initStdClass("apply-templates", "ApplyTemplates");
	initStdClass("apply-imports", "ApplyImports");
	initStdClass("decimal-format", "DecimalFormatting");
	initStdClass("import", "Import");
	initStdClass("include", "Include");
	initStdClass("strip-space", "Whitespace");
	initStdClass("preserve-space", "Whitespace");
	initStdClass("processing-instruction", "ProcessingInstruction");
	initStdClass("namespace-alias", "NamespaceAlias");
    
private voidinitSymbolTable()
Add primops and base functions to the symbol table.

	MethodType I_V  = new MethodType(Type.Int, Type.Void);
	MethodType I_R  = new MethodType(Type.Int, Type.Real);
	MethodType I_S  = new MethodType(Type.Int, Type.String);
	MethodType I_D  = new MethodType(Type.Int, Type.NodeSet);
	MethodType R_I  = new MethodType(Type.Real, Type.Int);
	MethodType R_V  = new MethodType(Type.Real, Type.Void);
	MethodType R_R  = new MethodType(Type.Real, Type.Real);
	MethodType R_D  = new MethodType(Type.Real, Type.NodeSet);
	MethodType R_O  = new MethodType(Type.Real, Type.Reference);
	MethodType I_I  = new MethodType(Type.Int, Type.Int);
 	MethodType D_O  = new MethodType(Type.NodeSet, Type.Reference);
	MethodType D_V  = new MethodType(Type.NodeSet, Type.Void);
	MethodType D_S  = new MethodType(Type.NodeSet, Type.String);
	MethodType D_D  = new MethodType(Type.NodeSet, Type.NodeSet);
	MethodType A_V  = new MethodType(Type.Node, Type.Void);
	MethodType S_V  = new MethodType(Type.String, Type.Void);
	MethodType S_S  = new MethodType(Type.String, Type.String);
	MethodType S_A  = new MethodType(Type.String, Type.Node);
	MethodType S_D  = new MethodType(Type.String, Type.NodeSet);
	MethodType S_O  = new MethodType(Type.String, Type.Reference);
	MethodType B_O  = new MethodType(Type.Boolean, Type.Reference);
	MethodType B_V  = new MethodType(Type.Boolean, Type.Void);
	MethodType B_B  = new MethodType(Type.Boolean, Type.Boolean);
	MethodType B_S  = new MethodType(Type.Boolean, Type.String);
	MethodType D_X  = new MethodType(Type.NodeSet, Type.Object);
	MethodType R_RR = new MethodType(Type.Real, Type.Real, Type.Real);
	MethodType I_II = new MethodType(Type.Int, Type.Int, Type.Int);
	MethodType B_RR = new MethodType(Type.Boolean, Type.Real, Type.Real);
	MethodType B_II = new MethodType(Type.Boolean, Type.Int, Type.Int);
	MethodType S_SS = new MethodType(Type.String, Type.String, Type.String);
	MethodType S_DS = new MethodType(Type.String, Type.Real, Type.String);
	MethodType S_SR = new MethodType(Type.String, Type.String, Type.Real);
	MethodType O_SO = new MethodType(Type.Reference, Type.String, Type.Reference);

	MethodType D_SS =
	    new MethodType(Type.NodeSet, Type.String, Type.String);
	MethodType D_SD = 
	    new MethodType(Type.NodeSet, Type.String, Type.NodeSet);
	MethodType B_BB =
	    new MethodType(Type.Boolean, Type.Boolean, Type.Boolean);
	MethodType B_SS =
	    new MethodType(Type.Boolean, Type.String, Type.String);
	MethodType S_SD =
	    new MethodType(Type.String, Type.String, Type.NodeSet);
	MethodType S_DSS =
	    new MethodType(Type.String, Type.Real, Type.String, Type.String);
	MethodType S_SRR =
	    new MethodType(Type.String, Type.String, Type.Real, Type.Real);
	MethodType S_SSS =
	    new MethodType(Type.String, Type.String, Type.String, Type.String);

	/*
	 * Standard functions: implemented but not in this table concat().
	 * When adding a new function make sure to uncomment
	 * the corresponding line in <tt>FunctionAvailableCall</tt>.
	 */

	// The following functions are inlined

	_symbolTable.addPrimop("current", A_V);
	_symbolTable.addPrimop("last", I_V);
	_symbolTable.addPrimop("position", I_V);
	_symbolTable.addPrimop("true", B_V);
	_symbolTable.addPrimop("false", B_V);
	_symbolTable.addPrimop("not", B_B);
	_symbolTable.addPrimop("name", S_V);
	_symbolTable.addPrimop("name", S_A);
	_symbolTable.addPrimop("generate-id", S_V);
	_symbolTable.addPrimop("generate-id", S_A);
	_symbolTable.addPrimop("ceiling", R_R);
	_symbolTable.addPrimop("floor", R_R);
	_symbolTable.addPrimop("round", R_R);
	_symbolTable.addPrimop("contains", B_SS);
	_symbolTable.addPrimop("number", R_O);
	_symbolTable.addPrimop("number", R_V);
	_symbolTable.addPrimop("boolean", B_O);
	_symbolTable.addPrimop("string", S_O);
	_symbolTable.addPrimop("string", S_V);
	_symbolTable.addPrimop("translate", S_SSS);
	_symbolTable.addPrimop("string-length", I_V);
	_symbolTable.addPrimop("string-length", I_S);
	_symbolTable.addPrimop("starts-with", B_SS);
	_symbolTable.addPrimop("format-number", S_DS);
	_symbolTable.addPrimop("format-number", S_DSS);
	_symbolTable.addPrimop("unparsed-entity-uri", S_S);
	_symbolTable.addPrimop("key", D_SS);
	_symbolTable.addPrimop("key", D_SD);
	_symbolTable.addPrimop("id", D_S);
	_symbolTable.addPrimop("id", D_D);
	_symbolTable.addPrimop("namespace-uri", S_V);
	_symbolTable.addPrimop("function-available", B_S);
	_symbolTable.addPrimop("element-available", B_S);
	_symbolTable.addPrimop("document", D_S);
	_symbolTable.addPrimop("document", D_V);

	// The following functions are implemented in the basis library
	_symbolTable.addPrimop("count", I_D);
	_symbolTable.addPrimop("sum", R_D);
	_symbolTable.addPrimop("local-name", S_V);
	_symbolTable.addPrimop("local-name", S_D);
	_symbolTable.addPrimop("namespace-uri", S_V);
	_symbolTable.addPrimop("namespace-uri", S_D);
	_symbolTable.addPrimop("substring", S_SR);
	_symbolTable.addPrimop("substring", S_SRR);
	_symbolTable.addPrimop("substring-after", S_SS);
	_symbolTable.addPrimop("substring-before", S_SS);
	_symbolTable.addPrimop("normalize-space", S_V);
	_symbolTable.addPrimop("normalize-space", S_S);
	_symbolTable.addPrimop("system-property", S_S);

	// Extensions
        _symbolTable.addPrimop("nodeset", D_O);
        _symbolTable.addPrimop("objectType", S_O);
        _symbolTable.addPrimop("cast", O_SO);

	// Operators +, -, *, /, % defined on real types.
	_symbolTable.addPrimop("+", R_RR);	
	_symbolTable.addPrimop("-", R_RR);	
	_symbolTable.addPrimop("*", R_RR);	
	_symbolTable.addPrimop("/", R_RR);	
	_symbolTable.addPrimop("%", R_RR);	

	// Operators +, -, * defined on integer types.
	// Operators / and % are not  defined on integers (may cause exception)
	_symbolTable.addPrimop("+", I_II);	
	_symbolTable.addPrimop("-", I_II);	
	_symbolTable.addPrimop("*", I_II);	

	 // Operators <, <= >, >= defined on real types.
	_symbolTable.addPrimop("<",  B_RR);	
	_symbolTable.addPrimop("<=", B_RR);	
	_symbolTable.addPrimop(">",  B_RR);	
	_symbolTable.addPrimop(">=", B_RR);	

	// Operators <, <= >, >= defined on int types.
	_symbolTable.addPrimop("<",  B_II);	
	_symbolTable.addPrimop("<=", B_II);	
	_symbolTable.addPrimop(">",  B_II);	
	_symbolTable.addPrimop(">=", B_II);	

	// Operators <, <= >, >= defined on boolean types.
	_symbolTable.addPrimop("<",  B_BB);	
	_symbolTable.addPrimop("<=", B_BB);	
	_symbolTable.addPrimop(">",  B_BB);	
	_symbolTable.addPrimop(">=", B_BB);	

	// Operators 'and' and 'or'.
	_symbolTable.addPrimop("or", B_BB);	
	_symbolTable.addPrimop("and", B_BB);	

	// Unary minus.
	_symbolTable.addPrimop("u-", R_R);	
	_symbolTable.addPrimop("u-", I_I);	
    
private com.sun.org.apache.xalan.internal.xsltc.compiler.SyntaxTreeNodeloadExternalStylesheet(java.lang.String location)
For embedded stylesheets: Load an external file with stylesheet


	InputSource source;

	// Check if the location is URL or a local file
	if ((new File(location)).exists())
	    source = new InputSource("file:"+location);
	else
	    source = new InputSource(location);

	SyntaxTreeNode external = (SyntaxTreeNode)parse(source);
	return(external);
    
public com.sun.org.apache.xalan.internal.xsltc.compiler.VariableBaselookupVariable(com.sun.org.apache.xalan.internal.xsltc.compiler.QName name)

	Object existing = _variableScope.get(name);
	if (existing instanceof VariableBase) {
	    return((VariableBase)existing);
	}
	else if (existing instanceof Stack) {
	    Stack stack = (Stack)existing;
	    return((VariableBase)stack.peek());
	}
	return(null);
    
public com.sun.org.apache.xalan.internal.xsltc.compiler.SyntaxTreeNodemakeInstance(java.lang.String uri, java.lang.String prefix, java.lang.String local, org.xml.sax.Attributes attributes)


          
	   
    
	SyntaxTreeNode node = null;
	QName  qname = getQName(uri, prefix, local);
	String className = (String)_instructionClasses.get(qname);

	if (className != null) {
	    try {
		final Class clazz = ObjectFactory.findProviderClass(
                    className, ObjectFactory.findClassLoader(), true);
		node = (SyntaxTreeNode)clazz.newInstance();
		node.setQName(qname);
		node.setParser(this);
		if (_locator != null) {
		    node.setLineNumber(getLineNumber());
		}
		if (node instanceof Stylesheet) {
		    _xsltc.setStylesheet((Stylesheet)node);
		}
		checkForSuperfluousAttributes(node, attributes);
	    }
	    catch (ClassNotFoundException e) {
		ErrorMsg err = new ErrorMsg(ErrorMsg.CLASS_NOT_FOUND_ERR, node);
		reportError(ERROR, err);
	    }
	    catch (Exception e) {
		ErrorMsg err = new ErrorMsg(ErrorMsg.INTERNAL_ERR,
					    e.getMessage(), node);
		reportError(FATAL, err);
	    }
	}
	else {
	    if (uri != null) {
		// Check if the element belongs in our namespace
		if (uri.equals(XSLT_URI)) {
		    node = new UnsupportedElement(uri, prefix, local, false);
		    UnsupportedElement element = (UnsupportedElement)node;
		    ErrorMsg msg = new ErrorMsg(ErrorMsg.UNSUPPORTED_XSL_ERR,
						getLineNumber(),local);
		    element.setErrorMessage(msg);
		    if (versionIsOne) {
		    	reportError(UNSUPPORTED,msg);
 		    }
		}
		// Check if this is an XSLTC extension element
		else if (uri.equals(TRANSLET_URI)) {
		    node = new UnsupportedElement(uri, prefix, local, true);
		    UnsupportedElement element = (UnsupportedElement)node;
		    ErrorMsg msg = new ErrorMsg(ErrorMsg.UNSUPPORTED_EXT_ERR,
						getLineNumber(),local);
		    element.setErrorMessage(msg);
		}
		// Check if this is an extension of some other XSLT processor
		else {
		    Stylesheet sheet = _xsltc.getStylesheet();
		    if ((sheet != null) && (sheet.isExtension(uri))) {
			if (sheet != (SyntaxTreeNode)_parentStack.peek()) {
			    node = new UnsupportedElement(uri, prefix, local, true);
			    UnsupportedElement elem = (UnsupportedElement)node;
			    ErrorMsg msg =
				new ErrorMsg(ErrorMsg.UNSUPPORTED_EXT_ERR,
					     getLineNumber(),
					     prefix+":"+local);
			    elem.setErrorMessage(msg);
			}
		    }
		}
	    }
	    if (node == null) {
                node = new LiteralElement();
                node.setLineNumber(getLineNumber());
            }
	}
	if ((node != null) && (node instanceof LiteralElement)) {
	    ((LiteralElement)node).setQName(qname);
	}
	return(node);
    
public com.sun.org.apache.xalan.internal.xsltc.compiler.StylesheetmakeStylesheet(com.sun.org.apache.xalan.internal.xsltc.compiler.SyntaxTreeNode element)
Create an instance of the Stylesheet class, and then parse, typecheck and compile the instance. Must be called after parse().

	try {
	    Stylesheet stylesheet;

	    if (element instanceof Stylesheet) {
		stylesheet = (Stylesheet)element;
	    }
	    else {
		stylesheet = new Stylesheet();
		stylesheet.setSimplified();
		stylesheet.addElement(element);
		stylesheet.setAttributes((AttributeList) element.getAttributes());

		// Map the default NS if not already defined
		if (element.lookupNamespace(EMPTYSTRING) == null) {
		    element.addPrefixMapping(EMPTYSTRING, EMPTYSTRING);
		}
	    }
	    stylesheet.setParser(this);
	    return stylesheet;
	}
	catch (ClassCastException e) {
	    ErrorMsg err = new ErrorMsg(ErrorMsg.NOT_STYLESHEET_ERR, element);
	    throw new CompilerException(err.toString());
	}
    
public com.sun.org.apache.xalan.internal.xsltc.compiler.SyntaxTreeNodeparse(org.xml.sax.XMLReader reader, org.xml.sax.InputSource input)
Parses a stylesheet and builds the internal abstract syntax tree

param
reader A SAX2 SAXReader (parser)
param
input A SAX2 InputSource can be passed to a SAX reader
return
The root of the abstract syntax tree

	try {
	    // Parse the input document and build the abstract syntax tree
	    reader.setContentHandler(this);
	    reader.parse(input);
	    // Find the start of the stylesheet within the tree
	    return (SyntaxTreeNode)getStylesheet(_root);	
	}
	catch (IOException e) {
	    if (_xsltc.debug()) e.printStackTrace();
	    reportError(ERROR,new ErrorMsg(e));
	}
	catch (SAXException e) {
	    Throwable ex = e.getException();
	    if (_xsltc.debug()) {
		e.printStackTrace();
		if (ex != null) ex.printStackTrace();
	    }
	    reportError(ERROR, new ErrorMsg(e));
	}
	catch (CompilerException e) {
	    if (_xsltc.debug()) e.printStackTrace();
	    reportError(ERROR, new ErrorMsg(e));
	}
	catch (Exception e) {
	    if (_xsltc.debug()) e.printStackTrace();
	    reportError(ERROR, new ErrorMsg(e));
	}
	return null;
    
public com.sun.org.apache.xalan.internal.xsltc.compiler.SyntaxTreeNodeparse(org.xml.sax.InputSource input)
Parses a stylesheet and builds the internal abstract syntax tree

param
input A SAX2 InputSource can be passed to a SAX reader
return
The root of the abstract syntax tree

	try {
	    // Create a SAX parser and get the XMLReader object it uses
	    final SAXParserFactory factory = SAXParserFactory.newInstance();
	    
	    if (_xsltc.isSecureProcessing()) {
	        try {
	            factory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
	        }
	        catch (SAXException e) {}
	    }
	    
	    try {
		factory.setFeature(Constants.NAMESPACE_FEATURE,true);
	    }
	    catch (Exception e) {
		factory.setNamespaceAware(true);
	    }
	    final SAXParser parser = factory.newSAXParser();
	    final XMLReader reader = parser.getXMLReader();
	    return(parse(reader, input));
	}
	catch (ParserConfigurationException e) {
	    ErrorMsg err = new ErrorMsg(ErrorMsg.SAX_PARSER_CONFIG_ERR);
	    reportError(ERROR, err);
	}
	catch (SAXParseException e){
	    reportError(ERROR, new ErrorMsg(e.getMessage(),e.getLineNumber()));
	}
	catch (SAXException e) {
	    reportError(ERROR, new ErrorMsg(e.getMessage()));
	}
	return null;
    
public com.sun.org.apache.xalan.internal.xsltc.compiler.ExpressionparseExpression(com.sun.org.apache.xalan.internal.xsltc.compiler.SyntaxTreeNode parent, java.lang.String exp)
Parse an XPath expression:

param
parent - XSL element where the expression occured
param
exp - textual representation of the expression

	return (Expression)parseTopLevel(parent, "<EXPRESSION>"+exp, null);
    
public com.sun.org.apache.xalan.internal.xsltc.compiler.ExpressionparseExpression(com.sun.org.apache.xalan.internal.xsltc.compiler.SyntaxTreeNode parent, java.lang.String attr, java.lang.String def)
Parse an XPath expression:

param
parent - XSL element where the expression occured
param
attr - name of this element's attribute to get expression from
param
def - default expression (if the attribute was not found)

	// Get the textual representation of the expression (if any)
        String exp = parent.getAttribute(attr);
	// Use the default expression if none was found
        if ((exp.length() == 0) && (def != null)) exp = def;
	// Invoke the XPath parser
        return (Expression)parseTopLevel(parent, "<EXPRESSION>"+exp, exp);
    
public com.sun.org.apache.xalan.internal.xsltc.compiler.PatternparsePattern(com.sun.org.apache.xalan.internal.xsltc.compiler.SyntaxTreeNode parent, java.lang.String pattern)
Parse an XPath pattern:

param
parent - XSL element where the pattern occured
param
pattern - textual representation of the pattern

	return (Pattern)parseTopLevel(parent, "<PATTERN>"+pattern, pattern);
    
public com.sun.org.apache.xalan.internal.xsltc.compiler.PatternparsePattern(com.sun.org.apache.xalan.internal.xsltc.compiler.SyntaxTreeNode parent, java.lang.String attr, java.lang.String def)
Parse an XPath pattern:

param
parent - XSL element where the pattern occured
param
attr - name of this element's attribute to get pattern from
param
def - default pattern (if the attribute was not found)

	// Get the textual representation of the pattern (if any)
        String pattern = parent.getAttribute(attr);
	// Use the default pattern if none was found
	if ((pattern.length() == 0) && (def != null)) pattern = def;
	// Invoke the XPath parser
        return (Pattern)parseTopLevel(parent, "<PATTERN>"+pattern, pattern);
    
private com.sun.org.apache.xalan.internal.xsltc.compiler.SyntaxTreeNodeparseTopLevel(com.sun.org.apache.xalan.internal.xsltc.compiler.SyntaxTreeNode parent, java.lang.String text, java.lang.String expression)
Parse an XPath expression or pattern using the generated XPathParser The method will return a Dummy node if the XPath parser fails.

	int line = getLineNumber();

	try {
	    _xpathParser.setScanner(new XPathLexer(new StringReader(text)));
	    Symbol result = _xpathParser.parse(expression, line);
	    if (result != null) {
		final SyntaxTreeNode node = (SyntaxTreeNode)result.value;
		if (node != null) {
		    node.setParser(this);
		    node.setParent(parent);
		    node.setLineNumber(line);
// System.out.println("e = " + text + " " + node);
		    return node;
		}
	    } 
	    reportError(ERROR, new ErrorMsg(ErrorMsg.XPATH_PARSER_ERR,
					    expression, parent));
	}
	catch (Exception e) {
	    if (_xsltc.debug()) e.printStackTrace();
	    reportError(ERROR, new ErrorMsg(ErrorMsg.XPATH_PARSER_ERR,
					    expression, parent));
	}

	// Return a dummy pattern (which is an expression)
	SyntaxTreeNode.Dummy.setParser(this);
        return SyntaxTreeNode.Dummy; 
    
public voidprintErrors()
Prints all compile-time errors

	final int size = _errors.size();
	if (size > 0) {
	    System.err.println(new ErrorMsg(ErrorMsg.COMPILER_ERROR_KEY));
	    for (int i = 0; i < size; i++) {
		System.err.println("  " + _errors.elementAt(i));
	    }
	}
    
public voidprintWarnings()
Prints all compile-time warnings

	final int size = _warnings.size();
	if (size > 0) {
	    System.err.println(new ErrorMsg(ErrorMsg.COMPILER_WARNING_KEY));
	    for (int i = 0; i < size; i++) {
		System.err.println("  " + _warnings.elementAt(i));
	    }
	}
    
public voidprocessingInstruction(java.lang.String name, java.lang.String value)
SAX2: Receive notification of a processing instruction. These require special handling for stylesheet PIs.

	// We only handle the <?xml-stylesheet ...?> PI
	if ((_target == null) && (name.equals("xml-stylesheet"))) {

	    String href = null;    // URI of stylesheet found
	    String media = null;   // Media of stylesheet found
	    String title = null;   // Title of stylesheet found
	    String charset = null; // Charset of stylesheet found

	    // Get the attributes from the processing instruction
	    StringTokenizer tokens = new StringTokenizer(value);
	    while (tokens.hasMoreElements()) {
		String token = (String)tokens.nextElement();
		if (token.startsWith("href"))
		    href = getTokenValue(token);
		else if (token.startsWith("media"))
		    media = getTokenValue(token);
		else if (token.startsWith("title"))
		    title = getTokenValue(token);
		else if (token.startsWith("charset"))
		    charset = getTokenValue(token);
	    }

	    // Set the target to this PI's href if the parameters are
	    // null or match the corresponding attributes of this PI.
	    if ( ((_PImedia == null) || (_PImedia.equals(media))) &&
		 ((_PItitle == null) || (_PImedia.equals(title))) &&
		 ((_PIcharset == null) || (_PImedia.equals(charset))) ) {
		_target = href;
	    }
	}
    
public voidremoveVariable(com.sun.org.apache.xalan.internal.xsltc.compiler.QName name)

	Object existing = _variableScope.get(name);
	if (existing instanceof Stack) {
	    Stack stack = (Stack)existing;
	    if (!stack.isEmpty()) stack.pop();
	    if (!stack.isEmpty()) return;
	}
	_variableScope.remove(name);
    
public voidreportError(int category, com.sun.org.apache.xalan.internal.xsltc.compiler.util.ErrorMsg error)
Common error/warning message handler

	switch (category) {
	case Constants.INTERNAL:
	    // Unexpected internal errors, such as null-ptr exceptions, etc.
	    // Immediately terminates compilation, no translet produced
	    _errors.addElement(error);
	    break;
	case Constants.UNSUPPORTED:
	    // XSLT elements that are not implemented and unsupported ext.
	    // Immediately terminates compilation, no translet produced
	    _errors.addElement(error);
	    break;
	case Constants.FATAL:
	    // Fatal error in the stylesheet input (parsing or content)
	    // Immediately terminates compilation, no translet produced
	    _errors.addElement(error);
	    break;
	case Constants.ERROR:
	    // Other error in the stylesheet input (parsing or content)
	    // Does not terminate compilation, no translet produced
	    _errors.addElement(error);
	    break;
	case Constants.WARNING:
	    // Other error in the stylesheet input (content errors only)
	    // Does not terminate compilation, a translet is produced
	    _warnings.addElement(error);
	    break;
	}
    
public voidsetCurrentStylesheet(com.sun.org.apache.xalan.internal.xsltc.compiler.Stylesheet stylesheet)

	_currentStylesheet = stylesheet;
    
public voidsetDocumentLocator(org.xml.sax.Locator locator)
Store the document locator to later retrieve line numbers of all elements from the stylesheet

	_locator = locator;
    
public voidsetOutput(com.sun.org.apache.xalan.internal.xsltc.compiler.Output output)

	if (_output != null) {
	    if (_output.getImportPrecedence() <= output.getImportPrecedence()) {
		String cdata = _output.getCdata();
                output.mergeOutput(_output);
		_output.disable();
		_output = output;
	    }
	    else {
		output.disable();
	    }
	}
	else {
	    _output = output;
	}
    
protected voidsetPIParameters(java.lang.String media, java.lang.String title, java.lang.String charset)
Set the parameters to use to locate the correct processing instruction in the case where the input document is an XML document with one or more references to a stylesheet.

param
media The media attribute to be matched. May be null, in which case the prefered templates will be used (i.e. alternate = no).
param
title The value of the title attribute to match. May be null.
param
charset The value of the charset attribute to match. May be null.


                                                                                           
            
	_PImedia = media;
	_PItitle = title;
	_PIcharset = charset;
    
public voidsetTemplate(com.sun.org.apache.xalan.internal.xsltc.compiler.Template template)

	_template = template;
    
public voidsetXSLTC(com.sun.org.apache.xalan.internal.xsltc.compiler.XSLTC xsltc)

	_xsltc = xsltc;
    
public voidskippedEntity(java.lang.String name)
IGNORED - we do not have to do anything with skipped entities

 
public voidstartDocument()
SAX2: Receive notification of the beginning of a document.


                  
       
	_root = null;
	_target = null;
	_prefixMapping = null;
	_parentStack = new Stack();
    
public voidstartElement(java.lang.String uri, java.lang.String localname, java.lang.String qname, org.xml.sax.Attributes attributes)
SAX2: Receive notification of the beginning of an element. The parser may re-use the attribute list that we're passed so we clone the attributes in our own Attributes implementation

	final int col = qname.lastIndexOf(':");
	final String prefix = (col == -1) ? null : qname.substring(0, col);

	SyntaxTreeNode element = makeInstance(uri, prefix, 
					localname, attributes);
	if (element == null) {
	    ErrorMsg err = new ErrorMsg(ErrorMsg.ELEMENT_PARSE_ERR,
					prefix+':"+localname);
	    throw new SAXException(err.toString());
	}

	// If this is the root element of the XML document we need to make sure
	// that it contains a definition of the XSL namespace URI
	if (_root == null) {
	    if ((_prefixMapping == null) ||
		(_prefixMapping.containsValue(Constants.XSLT_URI) == false))
		_rootNamespaceDef = false;
	    else
		_rootNamespaceDef = true;
	    _root = element;
	}
	else {
	    SyntaxTreeNode parent = (SyntaxTreeNode)_parentStack.peek();
	    parent.addElement(element);
	    element.setParent(parent);
	}
	element.setAttributes(new AttributeList(attributes));
	element.setPrefixMapping(_prefixMapping);
	
	if (element instanceof Stylesheet) {
	    // Extension elements and excluded elements have to be
	    // handled at this point in order to correctly generate
	    // Fallback elements from <xsl:fallback>s.
	    getSymbolTable().setCurrentNode(element);
	    ((Stylesheet)element).excludeExtensionPrefixes(this);
	}

	_prefixMapping = null;
	_parentStack.push(element);
    
public voidstartPrefixMapping(java.lang.String prefix, java.lang.String uri)
SAX2: Begin the scope of a prefix-URI Namespace mapping. This has to be passed on to the symbol table!

	if (_prefixMapping == null) {
	    _prefixMapping = new Hashtable();
	}
	_prefixMapping.put(prefix, uri);