📄 xsltc.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: XSLTC.java,v 1.2.4.1 2005/09/05 09:51:38 pvedula Exp $ */package com.sun.org.apache.xalan.internal.xsltc.compiler;import java.io.BufferedOutputStream;import java.io.ByteArrayOutputStream;import java.io.File;import java.io.FileOutputStream;import java.io.IOException;import java.io.InputStream;import java.net.URL;import java.util.Date;import java.util.Enumeration;import java.util.Hashtable;import java.util.Map;import java.util.Properties;import java.util.Vector;import java.util.jar.JarEntry;import java.util.jar.JarOutputStream;import java.util.jar.Manifest;import com.sun.org.apache.bcel.internal.classfile.JavaClass;import com.sun.org.apache.xalan.internal.xsltc.compiler.util.ErrorMsg;import com.sun.org.apache.xalan.internal.xsltc.compiler.util.Util;import com.sun.org.apache.xml.internal.dtm.DTM;import org.xml.sax.InputSource;import org.xml.sax.XMLReader;/** * @author Jacek Ambroziak * @author Santiago Pericas-Geertsen * @author G. Todd Miller * @author Morten Jorgensen * @author John Howard (johnh@schemasoft.com) */public final class XSLTC { // A reference to the main stylesheet parser object. private Parser _parser; // A reference to an external XMLReader (SAX parser) passed to us private XMLReader _reader = null; // A reference to an external SourceLoader (for use with include/import) private SourceLoader _loader = null; // A reference to the stylesheet being compiled. private Stylesheet _stylesheet; // Counters used by various classes to generate unique names. // private int _variableSerial = 1; private int _modeSerial = 1; private int _stylesheetSerial = 1; private int _stepPatternSerial = 1; private int _helperClassSerial = 0; private int _attributeSetSerial = 0; private int[] _numberFieldIndexes; // Name index tables private int _nextGType; // Next available element type private Vector _namesIndex; // Index of all registered QNames private Hashtable _elements; // Hashtable of all registered elements private Hashtable _attributes; // Hashtable of all registered attributes // Namespace index tables private int _nextNSType; // Next available namespace type private Vector _namespaceIndex; // Index of all registered namespaces private Hashtable _namespaces; // Hashtable of all registered namespaces private Hashtable _namespacePrefixes;// Hashtable of all registered namespace prefixes // All literal text in the stylesheet private Vector m_characterData; // These define the various methods for outputting the translet public static final int FILE_OUTPUT = 0; public static final int JAR_OUTPUT = 1; public static final int BYTEARRAY_OUTPUT = 2; public static final int CLASSLOADER_OUTPUT = 3; public static final int BYTEARRAY_AND_FILE_OUTPUT = 4; public static final int BYTEARRAY_AND_JAR_OUTPUT = 5; // Compiler options (passed from command line or XSLTC client) private boolean _debug = false; // -x private String _jarFileName = null; // -j <jar-file-name> private String _className = null; // -o <class-name> private String _packageName = null; // -p <package-name> private File _destDir = null; // -d <directory-name> private int _outputType = FILE_OUTPUT; // by default private Vector _classes; private Vector _bcelClasses; private boolean _callsNodeset = false; private boolean _multiDocument = false; private boolean _hasIdCall = false; /** * Set to true if template inlining is requested. Template * inlining used to be the default, but we have found that * Hotspots does a better job with shorter methods, so the * default is *not* to inline now. */ private boolean _templateInlining = false; /** * State of the secure processing feature. */ private boolean _isSecureProcessing = false; /** * XSLTC compiler constructor */ public XSLTC() { _parser = new Parser(this); } /** * Set the state of the secure processing feature. */ public void setSecureProcessing(boolean flag) { _isSecureProcessing = flag; } /** * Return the state of the secure processing feature. */ public boolean isSecureProcessing() { return _isSecureProcessing; } /** * Only for user by the internal TrAX implementation. */ public Parser getParser() { return _parser; } /** * Only for user by the internal TrAX implementation. */ public void setOutputType(int type) { _outputType = type; } /** * Only for user by the internal TrAX implementation. */ public Properties getOutputProperties() { return _parser.getOutputProperties(); } /** * Initializes the compiler to compile a new stylesheet */ public void init() { reset(); _reader = null; _classes = new Vector(); _bcelClasses = new Vector(); } /** * Initializes the compiler to produce a new translet */ private void reset() { _nextGType = DTM.NTYPES; _elements = new Hashtable(); _attributes = new Hashtable(); _namespaces = new Hashtable(); _namespaces.put("",new Integer(_nextNSType)); _namesIndex = new Vector(128); _namespaceIndex = new Vector(32); _namespacePrefixes = new Hashtable(); _stylesheet = null; _parser.init(); //_variableSerial = 1; _modeSerial = 1; _stylesheetSerial = 1; _stepPatternSerial = 1; _helperClassSerial = 0; _attributeSetSerial = 0; _multiDocument = false; _hasIdCall = false; _numberFieldIndexes = new int[] { -1, // LEVEL_SINGLE -1, // LEVEL_MULTIPLE -1 // LEVEL_ANY }; } /** * Defines an external SourceLoader to provide the compiler with documents * referenced in xsl:include/import * @param loader The SourceLoader to use for include/import */ public void setSourceLoader(SourceLoader loader) { _loader = loader; } /** * Set a flag indicating if templates are to be inlined or not. The * default is to do inlining, but this causes problems when the * stylesheets have a large number of templates (e.g. branch targets * exceeding 64K or a length of a method exceeding 64K). */ public void setTemplateInlining(boolean templateInlining) { _templateInlining = templateInlining; } /** * Set the parameters to use to locate the correct <?xml-stylesheet ...?> * processing instruction in the case where the input document to the * compiler (and parser) is an XML document. * @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. */ public void setPIParameters(String media, String title, String charset) { _parser.setPIParameters(media, title, charset); } /** * Compiles an XSL stylesheet pointed to by a URL * @param url An URL containing the input XSL stylesheet */ public boolean compile(URL url) { try { // Open input stream from URL and wrap inside InputSource final InputStream stream = url.openStream(); final InputSource input = new InputSource(stream); input.setSystemId(url.toString()); return compile(input, _className); } catch (IOException e) { _parser.reportError(Constants.FATAL, new ErrorMsg(e)); return false; } } /** * Compiles an XSL stylesheet pointed to by a URL * @param url An URL containing the input XSL stylesheet * @param name The name to assign to the translet class */ public boolean compile(URL url, String name) { try { // Open input stream from URL and wrap inside InputSource final InputStream stream = url.openStream(); final InputSource input = new InputSource(stream); input.setSystemId(url.toString()); return compile(input, name); } catch (IOException e) { _parser.reportError(Constants.FATAL, new ErrorMsg(e)); return false; } } /** * Compiles an XSL stylesheet passed in through an InputStream * @param stream An InputStream that will pass in the stylesheet contents * @param name The name of the translet class to generate * @return 'true' if the compilation was successful */ public boolean compile(InputStream stream, String name) { final InputSource input = new InputSource(stream); input.setSystemId(name); // We have nothing else!!! return compile(input, name); } /** * Compiles an XSL stylesheet passed in through an InputStream * @param input An InputSource that will pass in the stylesheet contents * @param name The name of the translet class to generate - can be null * @return 'true' if the compilation was successful */ public boolean compile(InputSource input, String name) { try { // Reset globals in case we're called by compile(Vector v); reset(); // The systemId may not be set, so we'll have to check the URL String systemId = null; if (input != null) { systemId = input.getSystemId(); } // Set the translet class name if not already set if (_className == null) { if (name != null) { setClassName(name); } else if (systemId != null && !systemId.equals("")) { setClassName(Util.baseName(systemId)); } // Ensure we have a non-empty class name at this point if (_className == null || _className.length() == 0) { setClassName("GregorSamsa"); // default translet name } } // Get the root node of the abstract syntax tree SyntaxTreeNode element = null; if (_reader == null) { element = _parser.parse(input); } else { element = _parser.parse(_reader, input); } // Compile the translet - this is where the work is done! if ((!_parser.errorsFound()) && (element != null)) { // Create a Stylesheet element from the root node _stylesheet = _parser.makeStylesheet(element); _stylesheet.setSourceLoader(_loader); _stylesheet.setSystemId(systemId); _stylesheet.setParentStylesheet(null); _stylesheet.setTemplateInlining(_templateInlining); _parser.setCurrentStylesheet(_stylesheet); // Create AST under the Stylesheet element (parse & type-check) _parser.createAST(_stylesheet); } // Generate the bytecodes and output the translet class(es) if ((!_parser.errorsFound()) && (_stylesheet != null)) { _stylesheet.setCallsNodeset(_callsNodeset); _stylesheet.setMultiDocument(_multiDocument); _stylesheet.setHasIdCall(_hasIdCall); // Class synchronization is needed for BCEL synchronized (getClass()) { _stylesheet.translate(); } } } catch (Exception e) { /*if (_debug)*/ e.printStackTrace(); _parser.reportError(Constants.FATAL, new ErrorMsg(e)); } catch (Error e) { if (_debug) e.printStackTrace(); _parser.reportError(Constants.FATAL, new ErrorMsg(e)); } finally { _reader = null; // reset this here to be sure it is not re-used } return !_parser.errorsFound(); } /** * Compiles a set of stylesheets pointed to by a Vector of URLs * @param stylesheets A Vector containing URLs pointing to the stylesheets * @return 'true' if the compilation was successful */ public boolean compile(Vector stylesheets) { // Get the number of stylesheets (ie. URLs) in the vector final int count = stylesheets.size(); // Return straight away if the vector is empty if (count == 0) return true; // Special handling needed if the URL count is one, becuase the // _className global must not be reset if it was set explicitly if (count == 1) { final Object url = stylesheets.firstElement(); if (url instanceof URL) return compile((URL)url); else return false; } else { // Traverse all elements in the vector and compile final Enumeration urls = stylesheets.elements(); while (urls.hasMoreElements()) { _className = null; // reset, so that new name will be computed final Object url = urls.nextElement(); if (url instanceof URL) { if (!compile((URL)url)) return false; } } } return true; } /** * Returns an array of bytecode arrays generated by a compilation. * @return JVM bytecodes that represent translet class definition */ public byte[][] getBytecodes() { final int count = _classes.size(); final byte[][] result = new byte[count][1]; for (int i = 0; i < count; i++) result[i] = (byte[])_classes.elementAt(i); return result; } /** * Compiles a stylesheet pointed to by a URL. The result is put in a * set of byte arrays. One byte array for each generated class. * @param name The name of the translet class to generate * @param input An InputSource that will pass in the stylesheet contents * @param outputType The output type * @return JVM bytecodes that represent translet class definition */ public byte[][] compile(String name, InputSource input, int outputType) { _outputType = outputType; if (compile(input, name)) return getBytecodes(); else return null; } /** * Compiles a stylesheet pointed to by a URL. The result is put in a * set of byte arrays. One byte array for each generated class. * @param name The name of the translet class to generate * @param input An InputSource that will pass in the stylesheet contents * @return JVM bytecodes that represent translet class definition */ public byte[][] compile(String name, InputSource input) { return compile(name, input, BYTEARRAY_OUTPUT); } /** * Set the XMLReader to use for parsing the next input stylesheet * @param reader XMLReader (SAX2 parser) to use
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -