📄 parser.java
字号:
/* * Copyright 2001-2004 The Apache Software Foundation. * * Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. *//* * $Id: Parser.java,v 1.2.4.1 2005/09/13 12:14:32 pvedula Exp $ */package com.sun.org.apache.xalan.internal.xsltc.compiler;import java.io.File;import java.io.IOException;import java.io.StringReader;import java.util.Dictionary;import java.util.Enumeration;import java.util.Hashtable;import java.util.Properties;import java.util.Stack;import java.util.StringTokenizer;import java.util.Vector;import com.sun.java_cup.internal.runtime.Symbol;import javax.xml.XMLConstants;import javax.xml.parsers.ParserConfigurationException;import javax.xml.parsers.SAXParser;import javax.xml.parsers.SAXParserFactory;import com.sun.org.apache.xalan.internal.xsltc.compiler.util.ErrorMsg;import com.sun.org.apache.xalan.internal.xsltc.compiler.util.MethodType;import com.sun.org.apache.xalan.internal.xsltc.compiler.util.Type;import com.sun.org.apache.xalan.internal.xsltc.compiler.util.TypeCheckError;import com.sun.org.apache.xalan.internal.xsltc.runtime.AttributeList;import org.xml.sax.Attributes;import org.xml.sax.ContentHandler;import org.xml.sax.InputSource;import org.xml.sax.Locator;import org.xml.sax.SAXException;import org.xml.sax.SAXParseException;import org.xml.sax.XMLReader;/** * @author Jacek Ambroziak * @author Santiago Pericas-Geertsen * @author G. Todd Miller * @author Morten Jorgensen * @author Erwin Bolwidt <ejb@klomp.org> */public class Parser implements Constants, ContentHandler { private static final String XSL = "xsl"; // standard prefix private static final String TRANSLET = "translet"; // extension prefix private Locator _locator = null; private XSLTC _xsltc; // Reference to the compiler object. private XPathParser _xpathParser; // Reference to the XPath parser. private Vector _errors; // Contains all compilation errors private Vector _warnings; // Contains all compilation errors private Hashtable _instructionClasses; // Maps instructions to classes private Hashtable _instructionAttrs;; // reqd and opt attrs private Hashtable _qNames; private Hashtable _namespaces; private QName _useAttributeSets; private QName _excludeResultPrefixes; private QName _extensionElementPrefixes; private Hashtable _variableScope; private Stylesheet _currentStylesheet; private SymbolTable _symbolTable; // Maps QNames to syntax-tree nodes private Output _output; private Template _template; // Reference to the template being parsed. private boolean _rootNamespaceDef; // Used for validity check private SyntaxTreeNode _root; private String _target; private int _currentImportPrecedence; public Parser(XSLTC xsltc) { _xsltc = xsltc; } public void init() { _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"); } public void setOutput(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; } } public Output getOutput() { return _output; } public Properties getOutputProperties() { return getTopLevelStylesheet().getOutputProperties(); } public void addVariable(Variable var) { addVariableOrParam(var); } public void addParameter(Param param) { addVariableOrParam(param); } private void addVariableOrParam(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 void removeVariable(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 VariableBase lookupVariable(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 void setXSLTC(XSLTC xsltc) { _xsltc = xsltc; } public XSLTC getXSLTC() { return _xsltc; } public int getCurrentImportPrecedence() { return _currentImportPrecedence; } public int getNextImportPrecedence() { return ++_currentImportPrecedence; } public void setCurrentStylesheet(Stylesheet stylesheet) { _currentStylesheet = stylesheet; } public Stylesheet getCurrentStylesheet() { return _currentStylesheet; } public Stylesheet getTopLevelStylesheet() { return _xsltc.getStylesheet(); } public QName getQNameSafe(final 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); } } public QName getQName(final String stringRep) { return getQName(stringRep, true, false); } public QName getQNameIgnoreDefaultNs(final String stringRep) { return getQName(stringRep, true, true); } public QName getQName(final String stringRep, boolean reportError) { return getQName(stringRep, reportError, false); } private QName getQName(final 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 QName getQName(String namespace, String prefix, 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 QName getQName(String scope, String name) { return getQName(scope + name); } public QName getQName(QName scope, QName name) { return getQName(scope.toString() + name.toString()); } public QName getUseAttributeSets() { return _useAttributeSets; } public QName getExtensionElementPrefixes() { return _extensionElementPrefixes; } public QName getExcludeResultPrefixes() { return _excludeResultPrefixes; } /** * Create an instance of the <code>Stylesheet</code> class, * and then parse, typecheck and compile the instance. * Must be called after <code>parse()</code>. */ public Stylesheet makeStylesheet(SyntaxTreeNode element) throws CompilerException { 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()); } } /** * Instanciates a SAX2 parser and generate the AST from the input. */ public void createAST(Stylesheet stylesheet) { 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)); } } /** * 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 */ public SyntaxTreeNode parse(XMLReader reader, InputSource input) { 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; } /** * 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 */ public SyntaxTreeNode parse(InputSource input) { 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));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -