transformerimpl.java
来自「JAVA的一些源码 JAVA2 STANDARD EDITION DEVELO」· Java 代码 · 共 1,308 行 · 第 1/3 页
JAVA
1,308 行
/* * 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: TransformerImpl.java,v 1.1.2.1 2006/09/19 01:07:41 jeffsuttor Exp $ */package com.sun.org.apache.xalan.internal.xsltc.trax;import java.io.File;import java.io.FileOutputStream;import java.io.IOException;import java.io.InputStream;import java.io.OutputStream;import java.io.Reader;import java.io.Writer;import java.net.URI;import java.net.URL;import java.net.URLConnection;import java.net.UnknownServiceException;import java.util.Enumeration;import java.util.Properties;import java.util.StringTokenizer;import java.util.Vector;import java.lang.reflect.Constructor;import javax.xml.parsers.DocumentBuilder;import javax.xml.parsers.DocumentBuilderFactory;import javax.xml.parsers.ParserConfigurationException;import javax.xml.transform.ErrorListener;import javax.xml.transform.OutputKeys;import javax.xml.transform.Result;import javax.xml.transform.Source;import javax.xml.transform.Transformer;import javax.xml.transform.TransformerException;import javax.xml.transform.URIResolver;import javax.xml.transform.dom.DOMResult;import javax.xml.transform.dom.DOMSource;import javax.xml.transform.sax.SAXResult;import javax.xml.transform.sax.SAXSource;import javax.xml.transform.stream.StreamResult;import javax.xml.transform.stream.StreamSource;import com.sun.org.apache.xml.internal.utils.SystemIDResolver;import com.sun.org.apache.xalan.internal.xsltc.DOM;import com.sun.org.apache.xalan.internal.xsltc.DOMCache;import com.sun.org.apache.xalan.internal.xsltc.DOMEnhancedForDTM;import com.sun.org.apache.xalan.internal.xsltc.StripFilter;import com.sun.org.apache.xalan.internal.xsltc.Translet;import com.sun.org.apache.xalan.internal.xsltc.TransletException;import com.sun.org.apache.xml.internal.serializer.OutputPropertiesFactory;import com.sun.org.apache.xml.internal.serializer.SerializationHandler;import com.sun.org.apache.xalan.internal.xsltc.compiler.util.ErrorMsg;import com.sun.org.apache.xalan.internal.xsltc.dom.DOMWSFilter;import com.sun.org.apache.xalan.internal.xsltc.dom.SAXImpl;import com.sun.org.apache.xalan.internal.xsltc.dom.XSLTCDTMManager;import com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet;import com.sun.org.apache.xalan.internal.xsltc.runtime.Hashtable;import com.sun.org.apache.xalan.internal.xsltc.runtime.output.TransletOutputHandlerFactory;import com.sun.org.apache.xml.internal.dtm.DTMWSFilter;import com.sun.org.apache.xml.internal.utils.XMLReaderManager;import org.xml.sax.ContentHandler;import org.xml.sax.InputSource;import org.xml.sax.SAXException;import org.xml.sax.XMLReader;import org.xml.sax.ext.LexicalHandler;/** * @author Morten Jorgensen * @author G. Todd Miller * @author Santiago Pericas-Geertsen */public final class TransformerImpl extends Transformer implements DOMCache, ErrorListener{ private final static String EMPTY_STRING = ""; private final static String NO_STRING = "no"; private final static String YES_STRING = "yes"; private final static String XML_STRING = "xml"; private final static String LEXICAL_HANDLER_PROPERTY = "http://xml.org/sax/properties/lexical-handler"; private static final String NAMESPACE_FEATURE = "http://xml.org/sax/features/namespaces"; private static final String NAMESPACE_PREFIXES_FEATURE = "http://xml.org/sax/features/namespace-prefixes"; /** * A reference to the translet or null if the identity transform. */ private AbstractTranslet _translet = null; /** * The output method of this transformation. */ private String _method = null; /** * The output encoding of this transformation. */ private String _encoding = null; /** * The systemId set in input source. */ private String _sourceSystemId = null; /** * An error listener for runtime errors. */ private ErrorListener _errorListener = this; /** * A reference to a URI resolver for calls to document(). */ private URIResolver _uriResolver = null; /** * Output properties of this transformer instance. */ private Properties _properties, _propertiesClone; /** * A reference to an output handler factory. */ private TransletOutputHandlerFactory _tohFactory = null; /** * A reference to a internal DOM represenation of the input. */ private DOM _dom = null; /** * Number of indent spaces to add when indentation is on. */ private int _indentNumber; /** * A reference to the transformer factory that this templates * object belongs to. */ private TransformerFactoryImpl _tfactory = null; /** * A reference to the XSLTCDTMManager which is used to build the DOM/DTM * for this transformer. */ private XSLTCDTMManager _dtmManager = null; /** * A reference to an object that creates and caches XMLReader objects. */ private XMLReaderManager _readerManager = XMLReaderManager.getInstance(); /** * A flag indicating whether we use incremental building of the DTM. */ //private boolean _isIncremental = false; /** * A flag indicating whether this transformer implements the identity * transform. */ private boolean _isIdentity = false; /** * State of the secure processing feature. */ private boolean _isSecureProcessing = false; /** * A hashtable to store parameters for the identity transform. These * are not needed during the transformation, but we must keep track of * them to be fully complaint with the JAXP API. */ private Hashtable _parameters = null; /** * This class wraps an ErrorListener into a MessageHandler in order to * capture messages reported via xsl:message. */ static class MessageHandler extends com.sun.org.apache.xalan.internal.xsltc.runtime.MessageHandler { private ErrorListener _errorListener; public MessageHandler(ErrorListener errorListener) { _errorListener = errorListener; } public void displayMessage(String msg) { if(_errorListener == null) { System.err.println(msg); } else { try { _errorListener.warning(new TransformerException(msg)); } catch (TransformerException e) { // ignored } } } } protected TransformerImpl(Properties outputProperties, int indentNumber, TransformerFactoryImpl tfactory) { this(null, outputProperties, indentNumber, tfactory); _isIdentity = true; // _properties.put(OutputKeys.METHOD, "xml"); } protected TransformerImpl(Translet translet, Properties outputProperties, int indentNumber, TransformerFactoryImpl tfactory) { _translet = (AbstractTranslet) translet; _properties = createOutputProperties(outputProperties); _propertiesClone = (Properties) _properties.clone(); _indentNumber = indentNumber; _tfactory = tfactory; //_isIncremental = tfactory._incremental; } /** * Return the state of the secure processing feature. */ public boolean isSecureProcessing() { return _isSecureProcessing; } /** * Set the state of the secure processing feature. */ public void setSecureProcessing(boolean flag) { _isSecureProcessing = flag; } /** * Returns the translet wrapped inside this Transformer or * null if this is the identity transform. */ protected AbstractTranslet getTranslet() { return _translet; } public boolean isIdentity() { return _isIdentity; } /** * Implements JAXP's Transformer.transform() * * @param source Contains the input XML document * @param result Will contain the output from the transformation * @throws TransformerException */ public void transform(Source source, Result result) throws TransformerException { if (!_isIdentity) { if (_translet == null) { ErrorMsg err = new ErrorMsg(ErrorMsg.JAXP_NO_TRANSLET_ERR); throw new TransformerException(err.toString()); } // Pass output properties to the translet transferOutputProperties(_translet); } final SerializationHandler toHandler = getOutputHandler(result); if (toHandler == null) { ErrorMsg err = new ErrorMsg(ErrorMsg.JAXP_NO_HANDLER_ERR); throw new TransformerException(err.toString()); } if (_uriResolver != null && !_isIdentity) { _translet.setDOMCache(this); } // Pass output properties to handler if identity if (_isIdentity) { transferOutputProperties(toHandler); } transform(source, toHandler, _encoding); if (result instanceof DOMResult) { ((DOMResult)result).setNode(_tohFactory.getNode()); } } /** * Create an output handler for the transformation output based on * the type and contents of the TrAX Result object passed to the * transform() method. */ public SerializationHandler getOutputHandler(Result result) throws TransformerException { // Get output method using get() to ignore defaults _method = (String) _properties.get(OutputKeys.METHOD); // Get encoding using getProperty() to use defaults _encoding = (String) _properties.getProperty(OutputKeys.ENCODING); _tohFactory = TransletOutputHandlerFactory.newInstance(); _tohFactory.setEncoding(_encoding); if (_method != null) { _tohFactory.setOutputMethod(_method); } // Set indentation number in the factory if (_indentNumber >= 0) { _tohFactory.setIndentNumber(_indentNumber); } // Return the content handler for this Result object try { // Result object could be SAXResult, DOMResult, or StreamResult if (result instanceof SAXResult) { final SAXResult target = (SAXResult)result; final ContentHandler handler = target.getHandler(); _tohFactory.setHandler(handler); /** * Fix for bug 24414 * If the lexicalHandler is set then we need to get that * for obtaining the lexical information */ LexicalHandler lexicalHandler = target.getLexicalHandler(); if (lexicalHandler != null ) { _tohFactory.setLexicalHandler(lexicalHandler); } _tohFactory.setOutputType(TransletOutputHandlerFactory.SAX); return _tohFactory.getSerializationHandler(); } else if (result instanceof DOMResult) { _tohFactory.setNode(((DOMResult) result).getNode()); _tohFactory.setOutputType(TransletOutputHandlerFactory.DOM); return _tohFactory.getSerializationHandler(); } else if (result instanceof StreamResult) { // Get StreamResult final StreamResult target = (StreamResult) result; // StreamResult may have been created with a java.io.File, // java.io.Writer, java.io.OutputStream or just a String // systemId. _tohFactory.setOutputType(TransletOutputHandlerFactory.STREAM); // try to get a Writer from Result object final Writer writer = target.getWriter(); if (writer != null) { _tohFactory.setWriter(writer); return _tohFactory.getSerializationHandler(); } // or try to get an OutputStream from Result object final OutputStream ostream = target.getOutputStream(); if (ostream != null) { _tohFactory.setOutputStream(ostream); return _tohFactory.getSerializationHandler(); } // or try to get just a systemId string from Result object String systemId = result.getSystemId(); if (systemId == null) { ErrorMsg err = new ErrorMsg(ErrorMsg.JAXP_NO_RESULT_ERR); throw new TransformerException(err.toString()); } // System Id may be in one of several forms, (1) a uri // that starts with 'file:', (2) uri that starts with 'http:' // or (3) just a filename on the local system. URL url = null; if (systemId.startsWith("file:")) { // if StreamResult(File) or setSystemID(File) was used, // the systemId will be URI encoded as a result of File.toURI(), // it must be decoded for use by URL try{ Class clazz = ObjectFactory.findProviderClass("java.net.URI", ObjectFactory.findClassLoader(), true); Constructor construct = clazz.getConstructor(new Class[] {java.lang.String.class} ); URI uri = (URI) construct.newInstance(new Object[]{systemId}) ; systemId = "file:"; String host = uri.getHost(); // decoded String String path = uri.getPath(); //decoded String if (path == null) { path = ""; } // if host (URI authority) then file:// + host + path // else just path (may be absolute or relative) if (host != null) { systemId += "//" + host + path; } else { systemId += path; } } catch(ClassNotFoundException e){ // running on J2SE 1.3 which doesn't have URI Class so OK to ignore //ClassNotFoundException. } catch (Exception exception) { // URI exception which means nothing can be done so OK to ignore } url = new URL(systemId); _tohFactory.setOutputStream( new FileOutputStream(url.getFile())); return _tohFactory.getSerializationHandler(); } else if (systemId.startsWith("http:")) { url = new URL(systemId); final URLConnection connection = url.openConnection();
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?