redirect.java

来自「java jdk 1.4的源码」· Java 代码 · 共 474 行 · 第 1/2 页

JAVA
474
字号
/* * The Apache Software License, Version 1.1 * * * Copyright (c) 1999 The Apache Software Foundation.  All rights * reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in *    the documentation and/or other materials provided with the *    distribution. * * 3. The end-user documentation included with the redistribution, *    if any, must include the following acknowledgment: *       "This product includes software developed by the *        Apache Software Foundation (http://www.apache.org/)." *    Alternately, this acknowledgment may appear in the software itself, *    if and wherever such third-party acknowledgments normally appear. * * 4. The names "Xalan" and "Apache Software Foundation" must *    not be used to endorse or promote products derived from this *    software without prior written permission. For written *    permission, please contact apache@apache.org. * * 5. Products derived from this software may not be called "Apache", *    nor may "Apache" appear in their name, without prior written *    permission of the Apache Software Foundation. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation and was * originally based on software copyright (c) 1999, Lotus * Development Corporation., http://www.lotus.com.  For more * information on the Apache Software Foundation, please see * <http://www.apache.org/>. */package org.apache.xalan.lib;import java.util.*;import java.io.*;import java.net.URL;import org.xml.sax.ContentHandler;import org.apache.xalan.extensions.XSLProcessorContext;import org.apache.xalan.transformer.TransformerImpl;import org.apache.xalan.templates.StylesheetRoot;import org.apache.xalan.templates.ElemExtensionCall;import org.apache.xalan.templates.OutputProperties;import org.apache.xalan.res.XSLTErrorResources;import org.apache.xpath.objects.XObject;import org.apache.xpath.XPath;import javax.xml.transform.stream.StreamResult;import javax.xml.transform.Result;import javax.xml.transform.TransformerException;import org.w3c.dom.*;/** * Implements three extension elements to allow an XSLT transformation to * redirect its output to multiple output files. * * It is accessed by specifying a namespace URI as follows: * <pre> *    xmlns:redirect="http://xml.apache.org/xalan/redirect" * </pre> * * <p>You can either just use redirect:write, in which case the file will be * opened and immediately closed after the write, or you can bracket the * write calls by redirect:open and redirect:close, in which case the * file will be kept open for multiple writes until the close call is * encountered.  Calls can be nested.   * * <p>Calls can take a 'file' attribute * and/or a 'select' attribute in order to get the filename.  If a select * attribute is encountered, it will evaluate that expression for a string * that indicates the filename.  If the string evaluates to empty, it will * attempt to use the 'file' attribute as a default.  Filenames can be relative * or absolute.  If they are relative, the base directory will be the same as * the base directory for the output document.  This is obtained by calling * getOutputTarget() on the TransformerImpl.  You can set this base directory * by calling TransformerImpl.setOutputTarget() or it is automatically set * when using the two argument form of transform() or transformNode(). * * <p>Calls to redirect:write and redirect:open also take an optional  * attribute append="true|yes", which will attempt to simply append  * to an existing file instead of always opening a new file.  The  * default behavior of always overwriting the file still happens  * if you do not specify append. * <p><b>Note:</b> this may give unexpected results when using xml  * or html output methods, since this is <b>not</b> coordinated  * with the serializers - hence, you may get extra xml decls in  * the middle of your file after appending to it. * * <p>Example:</p> * <PRE> * &lt;?xml version="1.0"?> * &lt;xsl:stylesheet xmlns:xsl="http://www.w3.org/XSL/Transform/1.0" *                 xmlns:redirect="http://xml.apache.org/xalan/redirect" *                 extension-element-prefixes="redirect"> * *   &lt;xsl:template match="/"> *     &lt;out> *       default output. *     &lt;/out> *     &lt;redirect:open file="doc3.out"/> *     &lt;redirect:write file="doc3.out"> *       &lt;out> *         &lt;redirect:write file="doc1.out"> *           &lt;out> *             doc1 output. *             &lt;redirect:write file="doc3.out"> *               Some text to doc3 *             &lt;/redirect:write> *           &lt;/out> *         &lt;/redirect:write> *         &lt;redirect:write file="doc2.out"> *           &lt;out> *             doc2 output. *             &lt;redirect:write file="doc3.out"> *               Some more text to doc3 *               &lt;redirect:write select="doc/foo"> *                 text for doc4 *               &lt;/redirect:write> *             &lt;/redirect:write> *           &lt;/out> *         &lt;/redirect:write> *       &lt;/out> *     &lt;/redirect:write> *     &lt;redirect:close file="doc3.out"/> *   &lt;/xsl:template> * * &lt;/xsl:stylesheet> * </PRE> * * @author Scott Boag * @version 1.0 * @see <a href="../../../../../../extensions.html#ex-redirect" target="_top">Example with Redirect extension</a> */public class Redirect{  /**   * List of formatter listeners indexed by filename.   */  protected Hashtable m_formatterListeners = new Hashtable ();  /**   * List of output streams indexed by filename.   */  protected Hashtable m_outputStreams = new Hashtable ();  /**    * Default append mode for bare open calls.     * False for backwards compatibility (I think).    */  public static final boolean DEFAULT_APPEND_OPEN = false;  /**    * Default append mode for bare write calls.     * False for backwards compatibility.    */  public static final boolean DEFAULT_APPEND_WRITE = false;  /**   * Open the given file and put it in the XML, HTML, or Text formatter listener's table.   */  public void open(XSLProcessorContext context, ElemExtensionCall elem)    throws java.net.MalformedURLException,           java.io.FileNotFoundException,           java.io.IOException,           javax.xml.transform.TransformerException  {    String fileName = getFilename(context, elem);    Object flistener = m_formatterListeners.get(fileName);    if(null == flistener)    {      String mkdirsExpr         = elem.getAttribute ("mkdirs", context.getContextNode(),                                                   context.getTransformer());      boolean mkdirs = (mkdirsExpr != null)                       ? (mkdirsExpr.equals("true") || mkdirsExpr.equals("yes")) : true;      // Whether to append to existing files or not, <jpvdm@iafrica.com>      String appendExpr = elem.getAttribute("append", context.getContextNode(), context.getTransformer());	  boolean append = (appendExpr != null)                       ? (appendExpr.equals("true") || appendExpr.equals("yes")) : DEFAULT_APPEND_OPEN;      Object ignored = makeFormatterListener(context, elem, fileName, true, mkdirs, append);    }  }    /**   * Write the evalutation of the element children to the given file. Then close the file   * unless it was opened with the open extension element and is in the formatter listener's table.   */  public void write(XSLProcessorContext context, ElemExtensionCall elem)    throws java.net.MalformedURLException,           java.io.FileNotFoundException,           java.io.IOException,           javax.xml.transform.TransformerException  {    String fileName = getFilename(context, elem);    Object flObject = m_formatterListeners.get(fileName);    ContentHandler formatter;    boolean inTable = false;    if(null == flObject)    {      String mkdirsExpr         = ((ElemExtensionCall)elem).getAttribute ("mkdirs",                                                   context.getContextNode(),                                                   context.getTransformer());      boolean mkdirs = (mkdirsExpr != null)                       ? (mkdirsExpr.equals("true") || mkdirsExpr.equals("yes")) : true;      // Whether to append to existing files or not, <jpvdm@iafrica.com>      String appendExpr = elem.getAttribute("append", context.getContextNode(), context.getTransformer());

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?