| 1 | 
         14 | 
         jlechner | 
         /* Stylesheet.java --
  | 
      
      
         | 2 | 
          | 
          | 
            Copyright (C) 2004 Free Software Foundation, Inc.
  | 
      
      
         | 3 | 
          | 
          | 
          
  | 
      
      
         | 4 | 
          | 
          | 
         This file is part of GNU Classpath.
  | 
      
      
         | 5 | 
          | 
          | 
          
  | 
      
      
         | 6 | 
          | 
          | 
         GNU Classpath is free software; you can redistribute it and/or modify
  | 
      
      
         | 7 | 
          | 
          | 
         it under the terms of the GNU General Public License as published by
  | 
      
      
         | 8 | 
          | 
          | 
         the Free Software Foundation; either version 2, or (at your option)
  | 
      
      
         | 9 | 
          | 
          | 
         any later version.
  | 
      
      
         | 10 | 
          | 
          | 
          
  | 
      
      
         | 11 | 
          | 
          | 
         GNU Classpath is distributed in the hope that it will be useful, but
  | 
      
      
         | 12 | 
          | 
          | 
         WITHOUT ANY WARRANTY; without even the implied warranty of
  | 
      
      
         | 13 | 
          | 
          | 
         MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  | 
      
      
         | 14 | 
          | 
          | 
         General Public License for more details.
  | 
      
      
         | 15 | 
          | 
          | 
          
  | 
      
      
         | 16 | 
          | 
          | 
         You should have received a copy of the GNU General Public License
  | 
      
      
         | 17 | 
          | 
          | 
         along with GNU Classpath; see the file COPYING.  If not, write to the
  | 
      
      
         | 18 | 
          | 
          | 
         Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
  | 
      
      
         | 19 | 
          | 
          | 
         02110-1301 USA.
  | 
      
      
         | 20 | 
          | 
          | 
          
  | 
      
      
         | 21 | 
          | 
          | 
         Linking this library statically or dynamically with other modules is
  | 
      
      
         | 22 | 
          | 
          | 
         making a combined work based on this library.  Thus, the terms and
  | 
      
      
         | 23 | 
          | 
          | 
         conditions of the GNU General Public License cover the whole
  | 
      
      
         | 24 | 
          | 
          | 
         combination.
  | 
      
      
         | 25 | 
          | 
          | 
          
  | 
      
      
         | 26 | 
          | 
          | 
         As a special exception, the copyright holders of this library give you
  | 
      
      
         | 27 | 
          | 
          | 
         permission to link this library with independent modules to produce an
  | 
      
      
         | 28 | 
          | 
          | 
         executable, regardless of the license terms of these independent
  | 
      
      
         | 29 | 
          | 
          | 
         modules, and to copy and distribute the resulting executable under
  | 
      
      
         | 30 | 
          | 
          | 
         terms of your choice, provided that you also meet, for each linked
  | 
      
      
         | 31 | 
          | 
          | 
         independent module, the terms and conditions of the license of that
  | 
      
      
         | 32 | 
          | 
          | 
         module.  An independent module is a module which is not derived from
  | 
      
      
         | 33 | 
          | 
          | 
         or based on this library.  If you modify this library, you may extend
  | 
      
      
         | 34 | 
          | 
          | 
         this exception to your version of the library, but you are not
  | 
      
      
         | 35 | 
          | 
          | 
         obligated to do so.  If you do not wish to do so, delete this
  | 
      
      
         | 36 | 
          | 
          | 
         exception statement from your version. */
  | 
      
      
         | 37 | 
          | 
          | 
          
  | 
      
      
         | 38 | 
          | 
          | 
         package gnu.xml.transform;
  | 
      
      
         | 39 | 
          | 
          | 
          
  | 
      
      
         | 40 | 
          | 
          | 
         import java.text.DecimalFormat;
  | 
      
      
         | 41 | 
          | 
          | 
         import java.text.DecimalFormatSymbols;
  | 
      
      
         | 42 | 
          | 
          | 
         import java.util.ArrayList;
  | 
      
      
         | 43 | 
          | 
          | 
         import java.util.Collection;
  | 
      
      
         | 44 | 
          | 
          | 
         import java.util.Collections;
  | 
      
      
         | 45 | 
          | 
          | 
         import java.util.HashSet;
  | 
      
      
         | 46 | 
          | 
          | 
         import java.util.Iterator;
  | 
      
      
         | 47 | 
          | 
          | 
         import java.util.LinkedHashMap;
  | 
      
      
         | 48 | 
          | 
          | 
         import java.util.LinkedHashSet;
  | 
      
      
         | 49 | 
          | 
          | 
         import java.util.LinkedList;
  | 
      
      
         | 50 | 
          | 
          | 
         import java.util.List;
  | 
      
      
         | 51 | 
          | 
          | 
         import java.util.Map;
  | 
      
      
         | 52 | 
          | 
          | 
         import java.util.Set;
  | 
      
      
         | 53 | 
          | 
          | 
         import java.util.StringTokenizer;
  | 
      
      
         | 54 | 
          | 
          | 
         import java.util.TreeSet;
  | 
      
      
         | 55 | 
          | 
          | 
         import javax.xml.XMLConstants;
  | 
      
      
         | 56 | 
          | 
          | 
         import javax.xml.namespace.NamespaceContext;
  | 
      
      
         | 57 | 
          | 
          | 
         import javax.xml.namespace.QName;
  | 
      
      
         | 58 | 
          | 
          | 
         import javax.xml.transform.Source;
  | 
      
      
         | 59 | 
          | 
          | 
         import javax.xml.transform.TransformerConfigurationException;
  | 
      
      
         | 60 | 
          | 
          | 
         import javax.xml.transform.TransformerException;
  | 
      
      
         | 61 | 
          | 
          | 
         import javax.xml.xpath.XPathFunction;
  | 
      
      
         | 62 | 
          | 
          | 
         import javax.xml.xpath.XPathFunctionResolver;
  | 
      
      
         | 63 | 
          | 
          | 
         import javax.xml.xpath.XPathExpressionException;
  | 
      
      
         | 64 | 
          | 
          | 
         import org.w3c.dom.Attr;
  | 
      
      
         | 65 | 
          | 
          | 
         import org.w3c.dom.Document;
  | 
      
      
         | 66 | 
          | 
          | 
         import org.w3c.dom.DOMException;
  | 
      
      
         | 67 | 
          | 
          | 
         import org.w3c.dom.Element;
  | 
      
      
         | 68 | 
          | 
          | 
         import org.w3c.dom.NamedNodeMap;
  | 
      
      
         | 69 | 
          | 
          | 
         import org.w3c.dom.Node;
  | 
      
      
         | 70 | 
          | 
          | 
         import org.w3c.dom.Text;
  | 
      
      
         | 71 | 
          | 
          | 
         import org.w3c.dom.UserDataHandler;
  | 
      
      
         | 72 | 
          | 
          | 
         import gnu.xml.xpath.Expr;
  | 
      
      
         | 73 | 
          | 
          | 
         import gnu.xml.xpath.NameTest;
  | 
      
      
         | 74 | 
          | 
          | 
         import gnu.xml.xpath.NodeTypeTest;
  | 
      
      
         | 75 | 
          | 
          | 
         import gnu.xml.xpath.Pattern;
  | 
      
      
         | 76 | 
          | 
          | 
         import gnu.xml.xpath.Selector;
  | 
      
      
         | 77 | 
          | 
          | 
         import gnu.xml.xpath.Root;
  | 
      
      
         | 78 | 
          | 
          | 
         import gnu.xml.xpath.Test;
  | 
      
      
         | 79 | 
          | 
          | 
         import gnu.xml.xpath.XPathImpl;
  | 
      
      
         | 80 | 
          | 
          | 
          
  | 
      
      
         | 81 | 
          | 
          | 
         /**
  | 
      
      
         | 82 | 
          | 
          | 
          * An XSL stylesheet.
  | 
      
      
         | 83 | 
          | 
          | 
          *
  | 
      
      
         | 84 | 
          | 
          | 
          * @author <a href='mailto:dog@gnu.org'>Chris Burdess</a>
  | 
      
      
         | 85 | 
          | 
          | 
          */
  | 
      
      
         | 86 | 
          | 
          | 
         class Stylesheet
  | 
      
      
         | 87 | 
          | 
          | 
           implements NamespaceContext, XPathFunctionResolver, UserDataHandler, Cloneable
  | 
      
      
         | 88 | 
          | 
          | 
         {
  | 
      
      
         | 89 | 
          | 
          | 
          
  | 
      
      
         | 90 | 
          | 
          | 
           static final String XSL_NS = "http://www.w3.org/1999/XSL/Transform";
  | 
      
      
         | 91 | 
          | 
          | 
          
  | 
      
      
         | 92 | 
          | 
          | 
           static final int OUTPUT_XML = 0;
  | 
      
      
         | 93 | 
          | 
          | 
           static final int OUTPUT_HTML = 1;
  | 
      
      
         | 94 | 
          | 
          | 
           static final int OUTPUT_TEXT = 2;
  | 
      
      
         | 95 | 
          | 
          | 
          
  | 
      
      
         | 96 | 
          | 
          | 
           final TransformerFactoryImpl factory;
  | 
      
      
         | 97 | 
          | 
          | 
           TransformerImpl transformer;
  | 
      
      
         | 98 | 
          | 
          | 
           Stylesheet parent;
  | 
      
      
         | 99 | 
          | 
          | 
           final XPathImpl xpath;
  | 
      
      
         | 100 | 
          | 
          | 
           final String systemId;
  | 
      
      
         | 101 | 
          | 
          | 
           final int precedence;
  | 
      
      
         | 102 | 
          | 
          | 
          
  | 
      
      
         | 103 | 
          | 
          | 
           final boolean debug;
  | 
      
      
         | 104 | 
          | 
          | 
          
  | 
      
      
         | 105 | 
          | 
          | 
           /**
  | 
      
      
         | 106 | 
          | 
          | 
            * Version of XSLT.
  | 
      
      
         | 107 | 
          | 
          | 
            */
  | 
      
      
         | 108 | 
          | 
          | 
           String version;
  | 
      
      
         | 109 | 
          | 
          | 
          
  | 
      
      
         | 110 | 
          | 
          | 
           Collection extensionElementPrefixes;
  | 
      
      
         | 111 | 
          | 
          | 
           Collection excludeResultPrefixes;
  | 
      
      
         | 112 | 
          | 
          | 
          
  | 
      
      
         | 113 | 
          | 
          | 
           /**
  | 
      
      
         | 114 | 
          | 
          | 
            * Set of element names for which we should strip whitespace.
  | 
      
      
         | 115 | 
          | 
          | 
            */
  | 
      
      
         | 116 | 
          | 
          | 
           Set stripSpace;
  | 
      
      
         | 117 | 
          | 
          | 
          
  | 
      
      
         | 118 | 
          | 
          | 
           /**
  | 
      
      
         | 119 | 
          | 
          | 
            * Set of element names for which we should preserve whitespace.
  | 
      
      
         | 120 | 
          | 
          | 
            */
  | 
      
      
         | 121 | 
          | 
          | 
           Set preserveSpace;
  | 
      
      
         | 122 | 
          | 
          | 
          
  | 
      
      
         | 123 | 
          | 
          | 
           /**
  | 
      
      
         | 124 | 
          | 
          | 
            * Output options.
  | 
      
      
         | 125 | 
          | 
          | 
            */
  | 
      
      
         | 126 | 
          | 
          | 
           Node output;
  | 
      
      
         | 127 | 
          | 
          | 
           int outputMethod;
  | 
      
      
         | 128 | 
          | 
          | 
           String outputVersion;
  | 
      
      
         | 129 | 
          | 
          | 
           String outputEncoding;
  | 
      
      
         | 130 | 
          | 
          | 
           boolean outputOmitXmlDeclaration;
  | 
      
      
         | 131 | 
          | 
          | 
           boolean outputStandalone;
  | 
      
      
         | 132 | 
          | 
          | 
           String outputPublicId;
  | 
      
      
         | 133 | 
          | 
          | 
           String outputSystemId;
  | 
      
      
         | 134 | 
          | 
          | 
           Collection outputCdataSectionElements;
  | 
      
      
         | 135 | 
          | 
          | 
           boolean outputIndent;
  | 
      
      
         | 136 | 
          | 
          | 
           String outputMediaType;
  | 
      
      
         | 137 | 
          | 
          | 
          
  | 
      
      
         | 138 | 
          | 
          | 
           /**
  | 
      
      
         | 139 | 
          | 
          | 
            * Keys.
  | 
      
      
         | 140 | 
          | 
          | 
            */
  | 
      
      
         | 141 | 
          | 
          | 
           Collection keys;
  | 
      
      
         | 142 | 
          | 
          | 
          
  | 
      
      
         | 143 | 
          | 
          | 
           /**
  | 
      
      
         | 144 | 
          | 
          | 
            * Decimal formats.
  | 
      
      
         | 145 | 
          | 
          | 
            */
  | 
      
      
         | 146 | 
          | 
          | 
           Map decimalFormats;
  | 
      
      
         | 147 | 
          | 
          | 
          
  | 
      
      
         | 148 | 
          | 
          | 
           /**
  | 
      
      
         | 149 | 
          | 
          | 
            * Namespace aliases.
  | 
      
      
         | 150 | 
          | 
          | 
            */
  | 
      
      
         | 151 | 
          | 
          | 
           Map namespaceAliases;
  | 
      
      
         | 152 | 
          | 
          | 
          
  | 
      
      
         | 153 | 
          | 
          | 
           /**
  | 
      
      
         | 154 | 
          | 
          | 
            * Attribute-sets.
  | 
      
      
         | 155 | 
          | 
          | 
            */
  | 
      
      
         | 156 | 
          | 
          | 
           List attributeSets;
  | 
      
      
         | 157 | 
          | 
          | 
          
  | 
      
      
         | 158 | 
          | 
          | 
           /**
  | 
      
      
         | 159 | 
          | 
          | 
            * Variables.
  | 
      
      
         | 160 | 
          | 
          | 
            */
  | 
      
      
         | 161 | 
          | 
          | 
           List variables;
  | 
      
      
         | 162 | 
          | 
          | 
          
  | 
      
      
         | 163 | 
          | 
          | 
           /**
  | 
      
      
         | 164 | 
          | 
          | 
            * Variable and parameter bindings.
  | 
      
      
         | 165 | 
          | 
          | 
            */
  | 
      
      
         | 166 | 
          | 
          | 
           Bindings bindings;
  | 
      
      
         | 167 | 
          | 
          | 
          
  | 
      
      
         | 168 | 
          | 
          | 
           /**
  | 
      
      
         | 169 | 
          | 
          | 
            * Templates.
  | 
      
      
         | 170 | 
          | 
          | 
            */
  | 
      
      
         | 171 | 
          | 
          | 
           LinkedList templates;
  | 
      
      
         | 172 | 
          | 
          | 
          
  | 
      
      
         | 173 | 
          | 
          | 
           TemplateNode builtInNodeTemplate;
  | 
      
      
         | 174 | 
          | 
          | 
           TemplateNode builtInTextTemplate;
  | 
      
      
         | 175 | 
          | 
          | 
          
  | 
      
      
         | 176 | 
          | 
          | 
           /**
  | 
      
      
         | 177 | 
          | 
          | 
            * Holds the current node while parsing.
  | 
      
      
         | 178 | 
          | 
          | 
            * Necessary to associate the document function with its declaring node,
  | 
      
      
         | 179 | 
          | 
          | 
            * to resolve namespaces, and to maintain the current node for the
  | 
      
      
         | 180 | 
          | 
          | 
            * current() function.
  | 
      
      
         | 181 | 
          | 
          | 
            */
  | 
      
      
         | 182 | 
          | 
          | 
           Node current;
  | 
      
      
         | 183 | 
          | 
          | 
          
  | 
      
      
         | 184 | 
          | 
          | 
           /**
  | 
      
      
         | 185 | 
          | 
          | 
            * Set by a terminating message.
  | 
      
      
         | 186 | 
          | 
          | 
            */
  | 
      
      
         | 187 | 
          | 
          | 
           transient boolean terminated;
  | 
      
      
         | 188 | 
          | 
          | 
          
  | 
      
      
         | 189 | 
          | 
          | 
           /**
  | 
      
      
         | 190 | 
          | 
          | 
            * Current template in force.
  | 
      
      
         | 191 | 
          | 
          | 
            */
  | 
      
      
         | 192 | 
          | 
          | 
           transient Template currentTemplate;
  | 
      
      
         | 193 | 
          | 
          | 
          
  | 
      
      
         | 194 | 
          | 
          | 
           Stylesheet(TransformerFactoryImpl factory,
  | 
      
      
         | 195 | 
          | 
          | 
                      Stylesheet parent,
  | 
      
      
         | 196 | 
          | 
          | 
                      Document doc,
  | 
      
      
         | 197 | 
          | 
          | 
                      String systemId,
  | 
      
      
         | 198 | 
          | 
          | 
                      int precedence)
  | 
      
      
         | 199 | 
          | 
          | 
             throws TransformerConfigurationException
  | 
      
      
         | 200 | 
          | 
          | 
           {
  | 
      
      
         | 201 | 
          | 
          | 
             this.factory = factory;
  | 
      
      
         | 202 | 
          | 
          | 
             this.systemId = systemId;
  | 
      
      
         | 203 | 
          | 
          | 
             this.precedence = precedence;
  | 
      
      
         | 204 | 
          | 
          | 
             this.parent = parent;
  | 
      
      
         | 205 | 
          | 
          | 
             extensionElementPrefixes = new HashSet();
  | 
      
      
         | 206 | 
          | 
          | 
             excludeResultPrefixes = new HashSet();
  | 
      
      
         | 207 | 
          | 
          | 
             stripSpace = new LinkedHashSet();
  | 
      
      
         | 208 | 
          | 
          | 
             preserveSpace = new LinkedHashSet();
  | 
      
      
         | 209 | 
          | 
          | 
             outputCdataSectionElements = new LinkedHashSet();
  | 
      
      
         | 210 | 
          | 
          | 
             xpath = (XPathImpl) factory.xpathFactory.newXPath();
  | 
      
      
         | 211 | 
          | 
          | 
             if (parent == null)
  | 
      
      
         | 212 | 
          | 
          | 
               {
  | 
      
      
         | 213 | 
          | 
          | 
                 bindings = new Bindings(this);
  | 
      
      
         | 214 | 
          | 
          | 
                 attributeSets = new LinkedList();
  | 
      
      
         | 215 | 
          | 
          | 
                 variables = new LinkedList();
  | 
      
      
         | 216 | 
          | 
          | 
                 namespaceAliases = new LinkedHashMap();
  | 
      
      
         | 217 | 
          | 
          | 
                 templates = new LinkedList();
  | 
      
      
         | 218 | 
          | 
          | 
                 keys = new LinkedList();
  | 
      
      
         | 219 | 
          | 
          | 
                 decimalFormats = new LinkedHashMap();
  | 
      
      
         | 220 | 
          | 
          | 
                 initDefaultDecimalFormat();
  | 
      
      
         | 221 | 
          | 
          | 
                 xpath.setNamespaceContext(this);
  | 
      
      
         | 222 | 
          | 
          | 
                 xpath.setXPathFunctionResolver(this);
  | 
      
      
         | 223 | 
          | 
          | 
               }
  | 
      
      
         | 224 | 
          | 
          | 
             else
  | 
      
      
         | 225 | 
          | 
          | 
               {
  | 
      
      
         | 226 | 
          | 
          | 
                 /* Test for import circularity */
  | 
      
      
         | 227 | 
          | 
          | 
                 for (Stylesheet ctx = this; ctx.parent != null; ctx = ctx.parent)
  | 
      
      
         | 228 | 
          | 
          | 
                   {
  | 
      
      
         | 229 | 
          | 
          | 
                     if (systemId != null && systemId.equals(ctx.parent.systemId))
  | 
      
      
         | 230 | 
          | 
          | 
                       {
  | 
      
      
         | 231 | 
          | 
          | 
                         String msg = "circularity importing " + systemId;
  | 
      
      
         | 232 | 
          | 
          | 
                         throw new TransformerConfigurationException(msg);
  | 
      
      
         | 233 | 
          | 
          | 
                       }
  | 
      
      
         | 234 | 
          | 
          | 
                   }
  | 
      
      
         | 235 | 
          | 
          | 
                 /* OK */
  | 
      
      
         | 236 | 
          | 
          | 
                 Stylesheet root = getRootStylesheet();
  | 
      
      
         | 237 | 
          | 
          | 
                 bindings = root.bindings;
  | 
      
      
         | 238 | 
          | 
          | 
                 attributeSets = root.attributeSets;
  | 
      
      
         | 239 | 
          | 
          | 
                 variables = root.variables;
  | 
      
      
         | 240 | 
          | 
          | 
                 namespaceAliases = root.namespaceAliases;
  | 
      
      
         | 241 | 
          | 
          | 
                 templates = root.templates;
  | 
      
      
         | 242 | 
          | 
          | 
                 keys = root.keys;
  | 
      
      
         | 243 | 
          | 
          | 
                 decimalFormats = root.decimalFormats;
  | 
      
      
         | 244 | 
          | 
          | 
                 xpath.setNamespaceContext(root);
  | 
      
      
         | 245 | 
          | 
          | 
                 xpath.setXPathFunctionResolver(root);
  | 
      
      
         | 246 | 
          | 
          | 
               }
  | 
      
      
         | 247 | 
          | 
          | 
             xpath.setXPathVariableResolver(bindings);
  | 
      
      
         | 248 | 
          | 
          | 
          
  | 
      
      
         | 249 | 
          | 
          | 
             Test anyNode = new NodeTypeTest((short) 0);
  | 
      
      
         | 250 | 
          | 
          | 
             List tests = Collections.singletonList(anyNode);
  | 
      
      
         | 251 | 
          | 
          | 
             builtInNodeTemplate =
  | 
      
      
         | 252 | 
          | 
          | 
               new ApplyTemplatesNode(new Selector(Selector.CHILD, tests),
  | 
      
      
         | 253 | 
          | 
          | 
                                      null, null, null, true);
  | 
      
      
         | 254 | 
          | 
          | 
             builtInTextTemplate =
  | 
      
      
         | 255 | 
          | 
          | 
               new ValueOfNode(new Selector(Selector.SELF, tests),
  | 
      
      
         | 256 | 
          | 
          | 
                               false);
  | 
      
      
         | 257 | 
          | 
          | 
          
  | 
      
      
         | 258 | 
          | 
          | 
             parse(doc.getDocumentElement(), true);
  | 
      
      
         | 259 | 
          | 
          | 
             current = doc; // Alow namespace resolution during processing
  | 
      
      
         | 260 | 
          | 
          | 
          
  | 
      
      
         | 261 | 
          | 
          | 
             debug = ("yes".equals(System.getProperty("xsl.debug")));
  | 
      
      
         | 262 | 
          | 
          | 
          
  | 
      
      
         | 263 | 
          | 
          | 
             if (debug)
  | 
      
      
         | 264 | 
          | 
          | 
               {
  | 
      
      
         | 265 | 
          | 
          | 
                 System.err.println("Stylesheet: " + doc.getDocumentURI());
  | 
      
      
         | 266 | 
          | 
          | 
                 for (Iterator i = templates.iterator(); i.hasNext(); )
  | 
      
      
         | 267 | 
          | 
          | 
                   {
  | 
      
      
         | 268 | 
          | 
          | 
                     Template t = (Template) i.next();
  | 
      
      
         | 269 | 
          | 
          | 
                     t.list(System.err);
  | 
      
      
         | 270 | 
          | 
          | 
                     System.err.println("--------------------");
  | 
      
      
         | 271 | 
          | 
          | 
                   }
  | 
      
      
         | 272 | 
          | 
          | 
               }
  | 
      
      
         | 273 | 
          | 
          | 
           }
  | 
      
      
         | 274 | 
          | 
          | 
          
  | 
      
      
         | 275 | 
          | 
          | 
           Stylesheet getRootStylesheet()
  | 
      
      
         | 276 | 
          | 
          | 
           {
  | 
      
      
         | 277 | 
          | 
          | 
             Stylesheet stylesheet = this;
  | 
      
      
         | 278 | 
          | 
          | 
             while (stylesheet.parent != null)
  | 
      
      
         | 279 | 
          | 
          | 
               {
  | 
      
      
         | 280 | 
          | 
          | 
                 stylesheet = stylesheet.parent;
  | 
      
      
         | 281 | 
          | 
          | 
               }
  | 
      
      
         | 282 | 
          | 
          | 
             return stylesheet;
  | 
      
      
         | 283 | 
          | 
          | 
           }
  | 
      
      
         | 284 | 
          | 
          | 
          
  | 
      
      
         | 285 | 
          | 
          | 
           void initDefaultDecimalFormat()
  | 
      
      
         | 286 | 
          | 
          | 
           {
  | 
      
      
         | 287 | 
          | 
          | 
             DecimalFormat defaultDecimalFormat = new DecimalFormat();
  | 
      
      
         | 288 | 
          | 
          | 
             DecimalFormatSymbols symbols = new DecimalFormatSymbols();
  | 
      
      
         | 289 | 
          | 
          | 
             symbols.setDecimalSeparator('.');
  | 
      
      
         | 290 | 
          | 
          | 
             symbols.setGroupingSeparator(',');
  | 
      
      
         | 291 | 
          | 
          | 
             symbols.setPercent('%');
  | 
      
      
         | 292 | 
          | 
          | 
             symbols.setPerMill('\u2030');
  | 
      
      
         | 293 | 
          | 
          | 
             symbols.setZeroDigit('0');
  | 
      
      
         | 294 | 
          | 
          | 
             symbols.setDigit('#');
  | 
      
      
         | 295 | 
          | 
          | 
             symbols.setPatternSeparator(';');
  | 
      
      
         | 296 | 
          | 
          | 
             symbols.setInfinity("Infinity");
  | 
      
      
         | 297 | 
          | 
          | 
             symbols.setNaN("NaN");
  | 
      
      
         | 298 | 
          | 
          | 
             symbols.setMinusSign('-');
  | 
      
      
         | 299 | 
          | 
          | 
             defaultDecimalFormat.setDecimalFormatSymbols(symbols);
  | 
      
      
         | 300 | 
          | 
          | 
             decimalFormats.put(null, defaultDecimalFormat);
  | 
      
      
         | 301 | 
          | 
          | 
           }
  | 
      
      
         | 302 | 
          | 
          | 
          
  | 
      
      
         | 303 | 
          | 
          | 
           // -- Cloneable --
  | 
      
      
         | 304 | 
          | 
          | 
          
  | 
      
      
         | 305 | 
          | 
          | 
           public Object clone()
  | 
      
      
         | 306 | 
          | 
          | 
           {
  | 
      
      
         | 307 | 
          | 
          | 
             try
  | 
      
      
         | 308 | 
          | 
          | 
               {
  | 
      
      
         | 309 | 
          | 
          | 
                 Stylesheet clone = (Stylesheet) super.clone();
  | 
      
      
         | 310 | 
          | 
          | 
                 clone.bindings = (Bindings) bindings.clone();
  | 
      
      
         | 311 | 
          | 
          | 
          
  | 
      
      
         | 312 | 
          | 
          | 
                 LinkedList templates2 = new LinkedList();
  | 
      
      
         | 313 | 
          | 
          | 
                 for (Iterator i = templates.iterator(); i.hasNext(); )
  | 
      
      
         | 314 | 
          | 
          | 
                   {
  | 
      
      
         | 315 | 
          | 
          | 
                     Template t = (Template) i.next();
  | 
      
      
         | 316 | 
          | 
          | 
                     templates2.add(t.clone(clone));
  | 
      
      
         | 317 | 
          | 
          | 
                   }
  | 
      
      
         | 318 | 
          | 
          | 
                 clone.templates = templates2;
  | 
      
      
         | 319 | 
          | 
          | 
          
  | 
      
      
         | 320 | 
          | 
          | 
                 LinkedList attributeSets2 = new LinkedList();
  | 
      
      
         | 321 | 
          | 
          | 
                 for (Iterator i = attributeSets.iterator(); i.hasNext(); )
  | 
      
      
         | 322 | 
          | 
          | 
                   {
  | 
      
      
         | 323 | 
          | 
          | 
                     AttributeSet as = (AttributeSet) i.next();
  | 
      
      
         | 324 | 
          | 
          | 
                     attributeSets2.add(as.clone(clone));
  | 
      
      
         | 325 | 
          | 
          | 
                   }
  | 
      
      
         | 326 | 
          | 
          | 
                 clone.attributeSets = attributeSets2;
  | 
      
      
         | 327 | 
          | 
          | 
          
  | 
      
      
         | 328 | 
          | 
          | 
                 LinkedList variables2 = new LinkedList();
  | 
      
      
         | 329 | 
          | 
          | 
                 for (Iterator i = variables.iterator(); i.hasNext(); )
  | 
      
      
         | 330 | 
          | 
          | 
                   {
  | 
      
      
         | 331 | 
          | 
          | 
                     ParameterNode var = (ParameterNode) i.next();
  | 
      
      
         | 332 | 
          | 
          | 
                     variables2.add(var.clone(clone));
  | 
      
      
         | 333 | 
          | 
          | 
                   }
  | 
      
      
         | 334 | 
          | 
          | 
                 clone.variables = variables2;
  | 
      
      
         | 335 | 
          | 
          | 
          
  | 
      
      
         | 336 | 
          | 
          | 
                 LinkedList keys2 = new LinkedList();
  | 
      
      
         | 337 | 
          | 
          | 
                 for (Iterator i = keys.iterator(); i.hasNext(); )
  | 
      
      
         | 338 | 
          | 
          | 
                   {
  | 
      
      
         | 339 | 
          | 
          | 
                     Key k = (Key) i.next();
  | 
      
      
         | 340 | 
          | 
          | 
                     keys2.add(k.clone(clone));
  | 
      
      
         | 341 | 
          | 
          | 
                   }
  | 
      
      
         | 342 | 
          | 
          | 
                 clone.keys = keys2;
  | 
      
      
         | 343 | 
          | 
          | 
          
  | 
      
      
         | 344 | 
          | 
          | 
                 return clone;
  | 
      
      
         | 345 | 
          | 
          | 
               }
  | 
      
      
         | 346 | 
          | 
          | 
             catch (CloneNotSupportedException e)
  | 
      
      
         | 347 | 
          | 
          | 
               {
  | 
      
      
         | 348 | 
          | 
          | 
                 throw new Error(e.getMessage());
  | 
      
      
         | 349 | 
          | 
          | 
               }
  | 
      
      
         | 350 | 
          | 
          | 
           }
  | 
      
      
         | 351 | 
          | 
          | 
          
  | 
      
      
         | 352 | 
          | 
          | 
           // -- Variable evaluation --
  | 
      
      
         | 353 | 
          | 
          | 
          
  | 
      
      
         | 354 | 
          | 
          | 
           void initTopLevelVariables(Node context)
  | 
      
      
         | 355 | 
          | 
          | 
             throws TransformerException
  | 
      
      
         | 356 | 
          | 
          | 
           {
  | 
      
      
         | 357 | 
          | 
          | 
             current = context;
  | 
      
      
         | 358 | 
          | 
          | 
             // Sort the variables into order
  | 
      
      
         | 359 | 
          | 
          | 
             // See XSLT 11.4: "If the template or expression specifying the value of
  | 
      
      
         | 360 | 
          | 
          | 
             // a global variable x references a global variable y, then the value
  | 
      
      
         | 361 | 
          | 
          | 
             // for y must be computed before the value of x."
  | 
      
      
         | 362 | 
          | 
          | 
             List topLevel = new ArrayList(variables);
  | 
      
      
         | 363 | 
          | 
          | 
             Collections.sort(topLevel);
  | 
      
      
         | 364 | 
          | 
          | 
             for (Iterator i = topLevel.iterator(); i.hasNext(); )
  | 
      
      
         | 365 | 
          | 
          | 
               {
  | 
      
      
         | 366 | 
          | 
          | 
                 ParameterNode var = (ParameterNode) i.next();
  | 
      
      
         | 367 | 
          | 
          | 
                 bindings.set(var.name,
  | 
      
      
         | 368 | 
          | 
          | 
                              var.getValue(this, null, context, 1, 1),
  | 
      
      
         | 369 | 
          | 
          | 
                              var.type);
  | 
      
      
         | 370 | 
          | 
          | 
               }
  | 
      
      
         | 371 | 
          | 
          | 
             current = null;
  | 
      
      
         | 372 | 
          | 
          | 
           }
  | 
      
      
         | 373 | 
          | 
          | 
          
  | 
      
      
         | 374 | 
          | 
          | 
           // -- NamespaceContext --
  | 
      
      
         | 375 | 
          | 
          | 
          
  | 
      
      
         | 376 | 
          | 
          | 
           public String getNamespaceURI(String prefix)
  | 
      
      
         | 377 | 
          | 
          | 
           {
  | 
      
      
         | 378 | 
          | 
          | 
             return (current == null) ? null : current.lookupNamespaceURI(prefix);
  | 
      
      
         | 379 | 
          | 
          | 
           }
  | 
      
      
         | 380 | 
          | 
          | 
          
  | 
      
      
         | 381 | 
          | 
          | 
           public String getPrefix(String namespaceURI)
  | 
      
      
         | 382 | 
          | 
          | 
           {
  | 
      
      
         | 383 | 
          | 
          | 
             return (current == null) ? null : current.lookupPrefix(namespaceURI);
  | 
      
      
         | 384 | 
          | 
          | 
           }
  | 
      
      
         | 385 | 
          | 
          | 
          
  | 
      
      
         | 386 | 
          | 
          | 
           public Iterator getPrefixes(String namespaceURI)
  | 
      
      
         | 387 | 
          | 
          | 
           {
  | 
      
      
         | 388 | 
          | 
          | 
             // TODO
  | 
      
      
         | 389 | 
          | 
          | 
             return Collections.singleton(getPrefix(namespaceURI)).iterator();
  | 
      
      
         | 390 | 
          | 
          | 
           }
  | 
      
      
         | 391 | 
          | 
          | 
          
  | 
      
      
         | 392 | 
          | 
          | 
           final QName getQName(String name)
  | 
      
      
         | 393 | 
          | 
          | 
           {
  | 
      
      
         | 394 | 
          | 
          | 
             String localName = name, uri = null, prefix = null;
  | 
      
      
         | 395 | 
          | 
          | 
             int ci = name.indexOf(':');
  | 
      
      
         | 396 | 
          | 
          | 
             if (ci != -1)
  | 
      
      
         | 397 | 
          | 
          | 
               {
  | 
      
      
         | 398 | 
          | 
          | 
                 prefix = name.substring(0, ci);
  | 
      
      
         | 399 | 
          | 
          | 
                 localName = name.substring(ci + 1);
  | 
      
      
         | 400 | 
          | 
          | 
                 uri = getNamespaceURI(prefix);
  | 
      
      
         | 401 | 
          | 
          | 
               }
  | 
      
      
         | 402 | 
          | 
          | 
             return new QName(uri, localName, prefix);
  | 
      
      
         | 403 | 
          | 
          | 
           }
  | 
      
      
         | 404 | 
          | 
          | 
          
  | 
      
      
         | 405 | 
          | 
          | 
           // -- Template selection --
  | 
      
      
         | 406 | 
          | 
          | 
          
  | 
      
      
         | 407 | 
          | 
          | 
           TemplateNode getTemplate(QName mode, Node context, boolean applyImports)
  | 
      
      
         | 408 | 
          | 
          | 
             throws TransformerException
  | 
      
      
         | 409 | 
          | 
          | 
           {
  | 
      
      
         | 410 | 
          | 
          | 
             if (debug)
  | 
      
      
         | 411 | 
          | 
          | 
               {
  | 
      
      
         | 412 | 
          | 
          | 
                 System.err.println("getTemplate: mode="+mode+" context="+context);
  | 
      
      
         | 413 | 
          | 
          | 
               }
  | 
      
      
         | 414 | 
          | 
          | 
             Set candidates = new TreeSet();
  | 
      
      
         | 415 | 
          | 
          | 
             for (Iterator j = templates.iterator(); j.hasNext(); )
  | 
      
      
         | 416 | 
          | 
          | 
               {
  | 
      
      
         | 417 | 
          | 
          | 
                 Template t = (Template) j.next();
  | 
      
      
         | 418 | 
          | 
          | 
                 boolean isMatch = t.matches(mode, context);
  | 
      
      
         | 419 | 
          | 
          | 
                 if (applyImports)
  | 
      
      
         | 420 | 
          | 
          | 
                   {
  | 
      
      
         | 421 | 
          | 
          | 
                     if (currentTemplate == null)
  | 
      
      
         | 422 | 
          | 
          | 
                       {
  | 
      
      
         | 423 | 
          | 
          | 
                         String msg = "current template may not be null " +
  | 
      
      
         | 424 | 
          | 
          | 
                           "during apply-imports";
  | 
      
      
         | 425 | 
          | 
          | 
                         throw new TransformerException(msg);
  | 
      
      
         | 426 | 
          | 
          | 
                       }
  | 
      
      
         | 427 | 
          | 
          | 
                     if (!currentTemplate.imports(t))
  | 
      
      
         | 428 | 
          | 
          | 
                       {
  | 
      
      
         | 429 | 
          | 
          | 
                         isMatch = false;
  | 
      
      
         | 430 | 
          | 
          | 
                       }
  | 
      
      
         | 431 | 
          | 
          | 
                   }
  | 
      
      
         | 432 | 
          | 
          | 
                 //System.err.println("\t"+context+" "+t+"="+isMatch);
  | 
      
      
         | 433 | 
          | 
          | 
                 if (isMatch)
  | 
      
      
         | 434 | 
          | 
          | 
                   {
  | 
      
      
         | 435 | 
          | 
          | 
                     candidates.add(t);
  | 
      
      
         | 436 | 
          | 
          | 
                   }
  | 
      
      
         | 437 | 
          | 
          | 
               }
  | 
      
      
         | 438 | 
          | 
          | 
             //System.err.println("\tcandidates="+candidates);
  | 
      
      
         | 439 | 
          | 
          | 
             if (candidates.isEmpty())
  | 
      
      
         | 440 | 
          | 
          | 
               {
  | 
      
      
         | 441 | 
          | 
          | 
                 // Apply built-in template
  | 
      
      
         | 442 | 
          | 
          | 
                 // Current template is unchanged
  | 
      
      
         | 443 | 
          | 
          | 
                 if (debug)
  | 
      
      
         | 444 | 
          | 
          | 
                   {
  | 
      
      
         | 445 | 
          | 
          | 
                     System.err.println("\tbuiltInTemplate context="+context);
  | 
      
      
         | 446 | 
          | 
          | 
                   }
  | 
      
      
         | 447 | 
          | 
          | 
                 switch (context.getNodeType())
  | 
      
      
         | 448 | 
          | 
          | 
                   {
  | 
      
      
         | 449 | 
          | 
          | 
                   case Node.ELEMENT_NODE:
  | 
      
      
         | 450 | 
          | 
          | 
                   case Node.DOCUMENT_NODE:
  | 
      
      
         | 451 | 
          | 
          | 
                   case Node.DOCUMENT_FRAGMENT_NODE:
  | 
      
      
         | 452 | 
          | 
          | 
                   case Node.PROCESSING_INSTRUCTION_NODE:
  | 
      
      
         | 453 | 
          | 
          | 
                   case Node.COMMENT_NODE:
  | 
      
      
         | 454 | 
          | 
          | 
                     return builtInNodeTemplate;
  | 
      
      
         | 455 | 
          | 
          | 
                   case Node.TEXT_NODE:
  | 
      
      
         | 456 | 
          | 
          | 
                   case Node.ATTRIBUTE_NODE:
  | 
      
      
         | 457 | 
          | 
          | 
                     return builtInTextTemplate;
  | 
      
      
         | 458 | 
          | 
          | 
                   default:
  | 
      
      
         | 459 | 
          | 
          | 
                     return null;
  | 
      
      
         | 460 | 
          | 
          | 
                   }
  | 
      
      
         | 461 | 
          | 
          | 
               }
  | 
      
      
         | 462 | 
          | 
          | 
             else
  | 
      
      
         | 463 | 
          | 
          | 
               {
  | 
      
      
         | 464 | 
          | 
          | 
                 Template t = (Template) candidates.iterator().next();
  | 
      
      
         | 465 | 
          | 
          | 
                 // Set current template
  | 
      
      
         | 466 | 
          | 
          | 
                 currentTemplate = t;
  | 
      
      
         | 467 | 
          | 
          | 
                 if (debug)
  | 
      
      
         | 468 | 
          | 
          | 
                   {
  | 
      
      
         | 469 | 
          | 
          | 
                     System.err.println("\ttemplate="+t+" context="+context);
  | 
      
      
         | 470 | 
          | 
          | 
                   }
  | 
      
      
         | 471 | 
          | 
          | 
                 return t.node;
  | 
      
      
         | 472 | 
          | 
          | 
               }
  | 
      
      
         | 473 | 
          | 
          | 
           }
  | 
      
      
         | 474 | 
          | 
          | 
          
  | 
      
      
         | 475 | 
          | 
          | 
           TemplateNode getTemplate(QName mode, QName name)
  | 
      
      
         | 476 | 
          | 
          | 
             throws TransformerException
  | 
      
      
         | 477 | 
          | 
          | 
           {
  | 
      
      
         | 478 | 
          | 
          | 
             //System.err.println("getTemplate: mode="+mode+" name="+name);
  | 
      
      
         | 479 | 
          | 
          | 
             Set candidates = new TreeSet();
  | 
      
      
         | 480 | 
          | 
          | 
             for (Iterator j = templates.iterator(); j.hasNext(); )
  | 
      
      
         | 481 | 
          | 
          | 
               {
  | 
      
      
         | 482 | 
          | 
          | 
                 Template t = (Template) j.next();
  | 
      
      
         | 483 | 
          | 
          | 
                 boolean isMatch = t.matches(name);
  | 
      
      
         | 484 | 
          | 
          | 
                 //System.err.println("\t"+name+" "+t+"="+isMatch);
  | 
      
      
         | 485 | 
          | 
          | 
                 if (isMatch)
  | 
      
      
         | 486 | 
          | 
          | 
                   {
  | 
      
      
         | 487 | 
          | 
          | 
                     candidates.add(t);
  | 
      
      
         | 488 | 
          | 
          | 
                   }
  | 
      
      
         | 489 | 
          | 
          | 
               }
  | 
      
      
         | 490 | 
          | 
          | 
             if (candidates.isEmpty())
  | 
      
      
         | 491 | 
          | 
          | 
               {
  | 
      
      
         | 492 | 
          | 
          | 
                 return null;
  | 
      
      
         | 493 | 
          | 
          | 
                 //throw new TransformerException("template '" + name + "' not found");
  | 
      
      
         | 494 | 
          | 
          | 
               }
  | 
      
      
         | 495 | 
          | 
          | 
             Template t = (Template) candidates.iterator().next();
  | 
      
      
         | 496 | 
          | 
          | 
             //System.err.println("\ttemplate="+t+" context="+context);
  | 
      
      
         | 497 | 
          | 
          | 
             return t.node;
  | 
      
      
         | 498 | 
          | 
          | 
           }
  | 
      
      
         | 499 | 
          | 
          | 
          
  | 
      
      
         | 500 | 
          | 
          | 
           /**
  | 
      
      
         | 501 | 
          | 
          | 
            * template
  | 
      
      
         | 502 | 
          | 
          | 
            */
  | 
      
      
         | 503 | 
          | 
          | 
           final Template parseTemplate(Node node, NamedNodeMap attrs)
  | 
      
      
         | 504 | 
          | 
          | 
             throws TransformerConfigurationException, XPathExpressionException
  | 
      
      
         | 505 | 
          | 
          | 
           {
  | 
      
      
         | 506 | 
          | 
          | 
             String n = getAttribute(attrs, "name");
  | 
      
      
         | 507 | 
          | 
          | 
             QName name = (n == null) ? null : getQName(n);
  | 
      
      
         | 508 | 
          | 
          | 
             String m = getAttribute(attrs, "match");
  | 
      
      
         | 509 | 
          | 
          | 
             Pattern match = null;
  | 
      
      
         | 510 | 
          | 
          | 
             if (m != null)
  | 
      
      
         | 511 | 
          | 
          | 
               {
  | 
      
      
         | 512 | 
          | 
          | 
                 try
  | 
      
      
         | 513 | 
          | 
          | 
                   {
  | 
      
      
         | 514 | 
          | 
          | 
                     match = (Pattern) xpath.compile(m);
  | 
      
      
         | 515 | 
          | 
          | 
                   }
  | 
      
      
         | 516 | 
          | 
          | 
                 catch (ClassCastException e)
  | 
      
      
         | 517 | 
          | 
          | 
                   {
  | 
      
      
         | 518 | 
          | 
          | 
                     String msg = "illegal pattern: " + m;
  | 
      
      
         | 519 | 
          | 
          | 
                     throw new TransformerConfigurationException(msg);
  | 
      
      
         | 520 | 
          | 
          | 
                   }
  | 
      
      
         | 521 | 
          | 
          | 
               }
  | 
      
      
         | 522 | 
          | 
          | 
             String p = getAttribute(attrs, "priority");
  | 
      
      
         | 523 | 
          | 
          | 
             String mm = getAttribute(attrs, "mode");
  | 
      
      
         | 524 | 
          | 
          | 
             QName mode = (mm == null) ? null : getQName(mm);
  | 
      
      
         | 525 | 
          | 
          | 
             double priority = (p == null) ? Template.DEFAULT_PRIORITY :
  | 
      
      
         | 526 | 
          | 
          | 
               Double.parseDouble(p);
  | 
      
      
         | 527 | 
          | 
          | 
             Node children = node.getFirstChild();
  | 
      
      
         | 528 | 
          | 
          | 
             return new Template(this, name, match, parse(children),
  | 
      
      
         | 529 | 
          | 
          | 
                                 precedence, priority, mode);
  | 
      
      
         | 530 | 
          | 
          | 
           }
  | 
      
      
         | 531 | 
          | 
          | 
          
  | 
      
      
         | 532 | 
          | 
          | 
           /**
  | 
      
      
         | 533 | 
          | 
          | 
            * output
  | 
      
      
         | 534 | 
          | 
          | 
            */
  | 
      
      
         | 535 | 
          | 
          | 
           final void parseOutput(Node node, NamedNodeMap attrs)
  | 
      
      
         | 536 | 
          | 
          | 
             throws TransformerConfigurationException
  | 
      
      
         | 537 | 
          | 
          | 
           {
  | 
      
      
         | 538 | 
          | 
          | 
             output = node;
  | 
      
      
         | 539 | 
          | 
          | 
             String method = getAttribute(attrs, "method");
  | 
      
      
         | 540 | 
          | 
          | 
             if ("xml".equals(method) || method == null)
  | 
      
      
         | 541 | 
          | 
          | 
               {
  | 
      
      
         | 542 | 
          | 
          | 
                 outputMethod = OUTPUT_XML;
  | 
      
      
         | 543 | 
          | 
          | 
               }
  | 
      
      
         | 544 | 
          | 
          | 
             else if ("html".equals(method))
  | 
      
      
         | 545 | 
          | 
          | 
               {
  | 
      
      
         | 546 | 
          | 
          | 
                 outputMethod = OUTPUT_HTML;
  | 
      
      
         | 547 | 
          | 
          | 
               }
  | 
      
      
         | 548 | 
          | 
          | 
             else if ("text".equals(method))
  | 
      
      
         | 549 | 
          | 
          | 
               {
  | 
      
      
         | 550 | 
          | 
          | 
                 outputMethod = OUTPUT_TEXT;
  | 
      
      
         | 551 | 
          | 
          | 
               }
  | 
      
      
         | 552 | 
          | 
          | 
             else
  | 
      
      
         | 553 | 
          | 
          | 
               {
  | 
      
      
         | 554 | 
          | 
          | 
                 String msg = "unsupported output method: " + method;
  | 
      
      
         | 555 | 
          | 
          | 
                 DOMSourceLocator l = new DOMSourceLocator(node);
  | 
      
      
         | 556 | 
          | 
          | 
                 throw new TransformerConfigurationException(msg, l);
  | 
      
      
         | 557 | 
          | 
          | 
               }
  | 
      
      
         | 558 | 
          | 
          | 
             outputPublicId = getAttribute(attrs, "public-id");
  | 
      
      
         | 559 | 
          | 
          | 
             outputSystemId = getAttribute(attrs, "system-id");
  | 
      
      
         | 560 | 
          | 
          | 
             outputEncoding = getAttribute(attrs, "encoding");
  | 
      
      
         | 561 | 
          | 
          | 
             String indent = getAttribute(attrs, "indent");
  | 
      
      
         | 562 | 
          | 
          | 
             if (indent != null)
  | 
      
      
         | 563 | 
          | 
          | 
               {
  | 
      
      
         | 564 | 
          | 
          | 
                 outputIndent = "yes".equals(indent);
  | 
      
      
         | 565 | 
          | 
          | 
               }
  | 
      
      
         | 566 | 
          | 
          | 
             outputVersion = getAttribute(attrs, "version");
  | 
      
      
         | 567 | 
          | 
          | 
             String omitXmlDecl = getAttribute(attrs, "omit-xml-declaration");
  | 
      
      
         | 568 | 
          | 
          | 
             if (omitXmlDecl != null)
  | 
      
      
         | 569 | 
          | 
          | 
               {
  | 
      
      
         | 570 | 
          | 
          | 
                 outputOmitXmlDeclaration = "yes".equals(omitXmlDecl);
  | 
      
      
         | 571 | 
          | 
          | 
               }
  | 
      
      
         | 572 | 
          | 
          | 
             String standalone = getAttribute(attrs, "standalone");
  | 
      
      
         | 573 | 
          | 
          | 
             if (standalone != null)
  | 
      
      
         | 574 | 
          | 
          | 
               {
  | 
      
      
         | 575 | 
          | 
          | 
                 outputStandalone = "yes".equals(standalone);
  | 
      
      
         | 576 | 
          | 
          | 
               }
  | 
      
      
         | 577 | 
          | 
          | 
             outputMediaType = getAttribute(attrs, "media-type");
  | 
      
      
         | 578 | 
          | 
          | 
             String cdataSectionElements =
  | 
      
      
         | 579 | 
          | 
          | 
               getAttribute(attrs, "cdata-section-elements");
  | 
      
      
         | 580 | 
          | 
          | 
             if (cdataSectionElements != null)
  | 
      
      
         | 581 | 
          | 
          | 
               {
  | 
      
      
         | 582 | 
          | 
          | 
                 StringTokenizer st = new StringTokenizer(cdataSectionElements, " ");
  | 
      
      
         | 583 | 
          | 
          | 
                 while (st.hasMoreTokens())
  | 
      
      
         | 584 | 
          | 
          | 
                   {
  | 
      
      
         | 585 | 
          | 
          | 
                     outputCdataSectionElements.add(st.nextToken());
  | 
      
      
         | 586 | 
          | 
          | 
                   }
  | 
      
      
         | 587 | 
          | 
          | 
               }
  | 
      
      
         | 588 | 
          | 
          | 
           }
  | 
      
      
         | 589 | 
          | 
          | 
          
  | 
      
      
         | 590 | 
          | 
          | 
           /**
  | 
      
      
         | 591 | 
          | 
          | 
            * key
  | 
      
      
         | 592 | 
          | 
          | 
            */
  | 
      
      
         | 593 | 
          | 
          | 
           final void parseKey(Node node, NamedNodeMap attrs)
  | 
      
      
         | 594 | 
          | 
          | 
             throws TransformerConfigurationException, XPathExpressionException
  | 
      
      
         | 595 | 
          | 
          | 
           {
  | 
      
      
         | 596 | 
          | 
          | 
             String n = getRequiredAttribute(attrs, "name", node);
  | 
      
      
         | 597 | 
          | 
          | 
             String m = getRequiredAttribute(attrs, "match", node);
  | 
      
      
         | 598 | 
          | 
          | 
             String u = getRequiredAttribute(attrs, "use", node);
  | 
      
      
         | 599 | 
          | 
          | 
             QName name = getQName(n);
  | 
      
      
         | 600 | 
          | 
          | 
             Expr use = (Expr) xpath.compile(u);
  | 
      
      
         | 601 | 
          | 
          | 
             try
  | 
      
      
         | 602 | 
          | 
          | 
               {
  | 
      
      
         | 603 | 
          | 
          | 
                 Pattern match = (Pattern) xpath.compile(m);
  | 
      
      
         | 604 | 
          | 
          | 
                 Key key = new Key(name, match, use);
  | 
      
      
         | 605 | 
          | 
          | 
                 keys.add(key);
  | 
      
      
         | 606 | 
          | 
          | 
               }
  | 
      
      
         | 607 | 
          | 
          | 
             catch (ClassCastException e)
  | 
      
      
         | 608 | 
          | 
          | 
               {
  | 
      
      
         | 609 | 
          | 
          | 
                 throw new TransformerConfigurationException("invalid pattern: " + m);
  | 
      
      
         | 610 | 
          | 
          | 
               }
  | 
      
      
         | 611 | 
          | 
          | 
           }
  | 
      
      
         | 612 | 
          | 
          | 
          
  | 
      
      
         | 613 | 
          | 
          | 
           /**
  | 
      
      
         | 614 | 
          | 
          | 
            * decimal-format
  | 
      
      
         | 615 | 
          | 
          | 
            */
  | 
      
      
         | 616 | 
          | 
          | 
           final void parseDecimalFormat(Node node, NamedNodeMap attrs)
  | 
      
      
         | 617 | 
          | 
          | 
             throws TransformerConfigurationException
  | 
      
      
         | 618 | 
          | 
          | 
           {
  | 
      
      
         | 619 | 
          | 
          | 
             String dfName = getAttribute(attrs, "name");
  | 
      
      
         | 620 | 
          | 
          | 
             DecimalFormat df = new DecimalFormat();
  | 
      
      
         | 621 | 
          | 
          | 
             DecimalFormatSymbols symbols = new DecimalFormatSymbols();
  | 
      
      
         | 622 | 
          | 
          | 
             symbols.setDecimalSeparator(parseDFChar(attrs, "decimal-separator", '.'));
  | 
      
      
         | 623 | 
          | 
          | 
             symbols.setGroupingSeparator(parseDFChar(attrs, "grouping-separator", ','));
  | 
      
      
         | 624 | 
          | 
          | 
             symbols.setInfinity(parseDFString(attrs, "infinity", "Infinity"));
  | 
      
      
         | 625 | 
          | 
          | 
             symbols.setMinusSign(parseDFChar(attrs, "minus-sign", '-'));
  | 
      
      
         | 626 | 
          | 
          | 
             symbols.setNaN(parseDFString(attrs, "NaN", "NaN"));
  | 
      
      
         | 627 | 
          | 
          | 
             symbols.setPercent(parseDFChar(attrs, "percent", '%'));
  | 
      
      
         | 628 | 
          | 
          | 
             symbols.setPerMill(parseDFChar(attrs, "per-mille", '\u2030'));
  | 
      
      
         | 629 | 
          | 
          | 
             symbols.setZeroDigit(parseDFChar(attrs, "zero-digit", '0'));
  | 
      
      
         | 630 | 
          | 
          | 
             symbols.setDigit(parseDFChar(attrs, "digit", '#'));
  | 
      
      
         | 631 | 
          | 
          | 
             symbols.setPatternSeparator(parseDFChar(attrs, "pattern-separator", ';'));
  | 
      
      
         | 632 | 
          | 
          | 
             df.setDecimalFormatSymbols(symbols);
  | 
      
      
         | 633 | 
          | 
          | 
             decimalFormats.put(dfName, df);
  | 
      
      
         | 634 | 
          | 
          | 
           }
  | 
      
      
         | 635 | 
          | 
          | 
          
  | 
      
      
         | 636 | 
          | 
          | 
           private final char parseDFChar(NamedNodeMap attrs, String name, char def)
  | 
      
      
         | 637 | 
          | 
          | 
             throws TransformerConfigurationException
  | 
      
      
         | 638 | 
          | 
          | 
           {
  | 
      
      
         | 639 | 
          | 
          | 
             Node attr = attrs.getNamedItem(name);
  | 
      
      
         | 640 | 
          | 
          | 
             try
  | 
      
      
         | 641 | 
          | 
          | 
               {
  | 
      
      
         | 642 | 
          | 
          | 
                 return (attr == null) ? def : attr.getNodeValue().charAt(0);
  | 
      
      
         | 643 | 
          | 
          | 
               }
  | 
      
      
         | 644 | 
          | 
          | 
             catch (StringIndexOutOfBoundsException e)
  | 
      
      
         | 645 | 
          | 
          | 
               {
  | 
      
      
         | 646 | 
          | 
          | 
                 throw new TransformerConfigurationException("empty attribute '" +
  | 
      
      
         | 647 | 
          | 
          | 
                                                             name +
  | 
      
      
         | 648 | 
          | 
          | 
                                                             "' in decimal-format", e);
  | 
      
      
         | 649 | 
          | 
          | 
               }
  | 
      
      
         | 650 | 
          | 
          | 
           }
  | 
      
      
         | 651 | 
          | 
          | 
          
  | 
      
      
         | 652 | 
          | 
          | 
           private final String parseDFString(NamedNodeMap attrs, String name,
  | 
      
      
         | 653 | 
          | 
          | 
                                              String def)
  | 
      
      
         | 654 | 
          | 
          | 
           {
  | 
      
      
         | 655 | 
          | 
          | 
             Node attr = attrs.getNamedItem(name);
  | 
      
      
         | 656 | 
          | 
          | 
             return (attr == null) ? def : attr.getNodeValue();
  | 
      
      
         | 657 | 
          | 
          | 
           }
  | 
      
      
         | 658 | 
          | 
          | 
          
  | 
      
      
         | 659 | 
          | 
          | 
           /**
  | 
      
      
         | 660 | 
          | 
          | 
            * namespace-alias
  | 
      
      
         | 661 | 
          | 
          | 
            */
  | 
      
      
         | 662 | 
          | 
          | 
           final void parseNamespaceAlias(Node node, NamedNodeMap attrs)
  | 
      
      
         | 663 | 
          | 
          | 
             throws TransformerConfigurationException
  | 
      
      
         | 664 | 
          | 
          | 
           {
  | 
      
      
         | 665 | 
          | 
          | 
             String sp = getRequiredAttribute(attrs, "stylesheet-prefix", node);
  | 
      
      
         | 666 | 
          | 
          | 
             String rp = getRequiredAttribute(attrs, "result-prefix", node);
  | 
      
      
         | 667 | 
          | 
          | 
             namespaceAliases.put(sp, rp);
  | 
      
      
         | 668 | 
          | 
          | 
           }
  | 
      
      
         | 669 | 
          | 
          | 
          
  | 
      
      
         | 670 | 
          | 
          | 
           /**
  | 
      
      
         | 671 | 
          | 
          | 
            * attribute-set
  | 
      
      
         | 672 | 
          | 
          | 
            */
  | 
      
      
         | 673 | 
          | 
          | 
           final void parseAttributeSet(Node node, NamedNodeMap attrs)
  | 
      
      
         | 674 | 
          | 
          | 
             throws TransformerConfigurationException, XPathExpressionException
  | 
      
      
         | 675 | 
          | 
          | 
           {
  | 
      
      
         | 676 | 
          | 
          | 
             TemplateNode children = parse(node.getFirstChild());
  | 
      
      
         | 677 | 
          | 
          | 
             String name = getRequiredAttribute(attrs, "name", node);
  | 
      
      
         | 678 | 
          | 
          | 
             String uas = getAttribute(attrs, "use-attribute-sets");
  | 
      
      
         | 679 | 
          | 
          | 
             attributeSets.add(new AttributeSet(children, name, uas));
  | 
      
      
         | 680 | 
          | 
          | 
           }
  | 
      
      
         | 681 | 
          | 
          | 
          
  | 
      
      
         | 682 | 
          | 
          | 
           /**
  | 
      
      
         | 683 | 
          | 
          | 
            * Parse top-level elements.
  | 
      
      
         | 684 | 
          | 
          | 
            */
  | 
      
      
         | 685 | 
          | 
          | 
           void parse(Node node, boolean root)
  | 
      
      
         | 686 | 
          | 
          | 
             throws TransformerConfigurationException
  | 
      
      
         | 687 | 
          | 
          | 
           {
  | 
      
      
         | 688 | 
          | 
          | 
             while (node != null)
  | 
      
      
         | 689 | 
          | 
          | 
               {
  | 
      
      
         | 690 | 
          | 
          | 
                 current = node;
  | 
      
      
         | 691 | 
          | 
          | 
                 doParse(node, root);
  | 
      
      
         | 692 | 
          | 
          | 
                 node = node.getNextSibling();
  | 
      
      
         | 693 | 
          | 
          | 
               }
  | 
      
      
         | 694 | 
          | 
          | 
           }
  | 
      
      
         | 695 | 
          | 
          | 
          
  | 
      
      
         | 696 | 
          | 
          | 
           void doParse(Node node, boolean root)
  | 
      
      
         | 697 | 
          | 
          | 
             throws TransformerConfigurationException
  | 
      
      
         | 698 | 
          | 
          | 
           {
  | 
      
      
         | 699 | 
          | 
          | 
             try
  | 
      
      
         | 700 | 
          | 
          | 
               {
  | 
      
      
         | 701 | 
          | 
          | 
                 String namespaceUri = node.getNamespaceURI();
  | 
      
      
         | 702 | 
          | 
          | 
                 if (XSL_NS.equals(namespaceUri) &&
  | 
      
      
         | 703 | 
          | 
          | 
                     node.getNodeType() == Node.ELEMENT_NODE)
  | 
      
      
         | 704 | 
          | 
          | 
                   {
  | 
      
      
         | 705 | 
          | 
          | 
                     String name = node.getLocalName();
  | 
      
      
         | 706 | 
          | 
          | 
                     NamedNodeMap attrs = node.getAttributes();
  | 
      
      
         | 707 | 
          | 
          | 
                     if ("stylesheet".equals(name))
  | 
      
      
         | 708 | 
          | 
          | 
                       {
  | 
      
      
         | 709 | 
          | 
          | 
                         version = getAttribute(attrs, "version");
  | 
      
      
         | 710 | 
          | 
          | 
                         String eep = getAttribute(attrs, "extension-element-prefixes");
  | 
      
      
         | 711 | 
          | 
          | 
                         if (eep != null)
  | 
      
      
         | 712 | 
          | 
          | 
                           {
  | 
      
      
         | 713 | 
          | 
          | 
                             StringTokenizer st = new StringTokenizer(eep);
  | 
      
      
         | 714 | 
          | 
          | 
                             while (st.hasMoreTokens())
  | 
      
      
         | 715 | 
          | 
          | 
                               {
  | 
      
      
         | 716 | 
          | 
          | 
                                 extensionElementPrefixes.add(st.nextToken());
  | 
      
      
         | 717 | 
          | 
          | 
                               }
  | 
      
      
         | 718 | 
          | 
          | 
                           }
  | 
      
      
         | 719 | 
          | 
          | 
                         String erp = getAttribute(attrs, "exclude-result-prefixes");
  | 
      
      
         | 720 | 
          | 
          | 
                         if (erp != null)
  | 
      
      
         | 721 | 
          | 
          | 
                           {
  | 
      
      
         | 722 | 
          | 
          | 
                             StringTokenizer st = new StringTokenizer(erp);
  | 
      
      
         | 723 | 
          | 
          | 
                             while (st.hasMoreTokens())
  | 
      
      
         | 724 | 
          | 
          | 
                               {
  | 
      
      
         | 725 | 
          | 
          | 
                                 excludeResultPrefixes.add(st.nextToken());
  | 
      
      
         | 726 | 
          | 
          | 
                               }
  | 
      
      
         | 727 | 
          | 
          | 
                           }
  | 
      
      
         | 728 | 
          | 
          | 
                         parse(node.getFirstChild(), false);
  | 
      
      
         | 729 | 
          | 
          | 
                       }
  | 
      
      
         | 730 | 
          | 
          | 
                     else if ("template".equals(name))
  | 
      
      
         | 731 | 
          | 
          | 
                       {
  | 
      
      
         | 732 | 
          | 
          | 
                         templates.add(parseTemplate(node, attrs));
  | 
      
      
         | 733 | 
          | 
          | 
                       }
  | 
      
      
         | 734 | 
          | 
          | 
                     else if ("param".equals(name) ||
  | 
      
      
         | 735 | 
          | 
          | 
                              "variable".equals(name))
  | 
      
      
         | 736 | 
          | 
          | 
                       {
  | 
      
      
         | 737 | 
          | 
          | 
                         int type = "variable".equals(name) ?
  | 
      
      
         | 738 | 
          | 
          | 
                           Bindings.VARIABLE : Bindings.PARAM;
  | 
      
      
         | 739 | 
          | 
          | 
                         TemplateNode content = parse(node.getFirstChild());
  | 
      
      
         | 740 | 
          | 
          | 
                         QName paramName =
  | 
      
      
         | 741 | 
          | 
          | 
                           getQName(getRequiredAttribute(attrs, "name", node));
  | 
      
      
         | 742 | 
          | 
          | 
                         String select = getAttribute(attrs, "select");
  | 
      
      
         | 743 | 
          | 
          | 
                         ParameterNode param;
  | 
      
      
         | 744 | 
          | 
          | 
                         if (select != null && select.length() > 0)
  | 
      
      
         | 745 | 
          | 
          | 
                           {
  | 
      
      
         | 746 | 
          | 
          | 
                             if (content != null)
  | 
      
      
         | 747 | 
          | 
          | 
                               {
  | 
      
      
         | 748 | 
          | 
          | 
                                 String msg = "parameter '" + paramName +
  | 
      
      
         | 749 | 
          | 
          | 
                                   "' has both select and content";
  | 
      
      
         | 750 | 
          | 
          | 
                                 DOMSourceLocator l = new DOMSourceLocator(node);
  | 
      
      
         | 751 | 
          | 
          | 
                                 throw new TransformerConfigurationException(msg, l);
  | 
      
      
         | 752 | 
          | 
          | 
                               }
  | 
      
      
         | 753 | 
          | 
          | 
                             Expr expr = (Expr) xpath.compile(select);
  | 
      
      
         | 754 | 
          | 
          | 
                             param = new ParameterNode(paramName, expr, type);
  | 
      
      
         | 755 | 
          | 
          | 
                           }
  | 
      
      
         | 756 | 
          | 
          | 
                         else
  | 
      
      
         | 757 | 
          | 
          | 
                           {
  | 
      
      
         | 758 | 
          | 
          | 
                             param = new ParameterNode(paramName, null, type);
  | 
      
      
         | 759 | 
          | 
          | 
                             param.children = content;
  | 
      
      
         | 760 | 
          | 
          | 
                           }
  | 
      
      
         | 761 | 
          | 
          | 
                         variables.add(param);
  | 
      
      
         | 762 | 
          | 
          | 
                       }
  | 
      
      
         | 763 | 
          | 
          | 
                     else if ("include".equals(name) || "import".equals(name))
  | 
      
      
         | 764 | 
          | 
          | 
                       {
  | 
      
      
         | 765 | 
          | 
          | 
                         int delta = "import".equals(name) ? -1 : 0;
  | 
      
      
         | 766 | 
          | 
          | 
                         String href = getRequiredAttribute(attrs, "href", node);
  | 
      
      
         | 767 | 
          | 
          | 
                         Source source;
  | 
      
      
         | 768 | 
          | 
          | 
                         synchronized (factory.resolver)
  | 
      
      
         | 769 | 
          | 
          | 
                           {
  | 
      
      
         | 770 | 
          | 
          | 
                             if (transformer != null)
  | 
      
      
         | 771 | 
          | 
          | 
                               {
  | 
      
      
         | 772 | 
          | 
          | 
                                 factory.resolver
  | 
      
      
         | 773 | 
          | 
          | 
                                   .setUserResolver(transformer.getURIResolver());
  | 
      
      
         | 774 | 
          | 
          | 
                                 factory.resolver
  | 
      
      
         | 775 | 
          | 
          | 
                                   .setUserListener(transformer.getErrorListener());
  | 
      
      
         | 776 | 
          | 
          | 
                               }
  | 
      
      
         | 777 | 
          | 
          | 
                             source = factory.resolver.resolve(systemId, href);
  | 
      
      
         | 778 | 
          | 
          | 
                           }
  | 
      
      
         | 779 | 
          | 
          | 
                         factory.newStylesheet(source, precedence + delta, this);
  | 
      
      
         | 780 | 
          | 
          | 
                       }
  | 
      
      
         | 781 | 
          | 
          | 
                     else if ("output".equals(name))
  | 
      
      
         | 782 | 
          | 
          | 
                       {
  | 
      
      
         | 783 | 
          | 
          | 
                         parseOutput(node, attrs);
  | 
      
      
         | 784 | 
          | 
          | 
                       }
  | 
      
      
         | 785 | 
          | 
          | 
                     else if ("preserve-space".equals(name))
  | 
      
      
         | 786 | 
          | 
          | 
                       {
  | 
      
      
         | 787 | 
          | 
          | 
                         String elements =
  | 
      
      
         | 788 | 
          | 
          | 
                           getRequiredAttribute(attrs, "elements", node);
  | 
      
      
         | 789 | 
          | 
          | 
                         StringTokenizer st = new StringTokenizer(elements,
  | 
      
      
         | 790 | 
          | 
          | 
                                                                  " \t\n\r");
  | 
      
      
         | 791 | 
          | 
          | 
                         while (st.hasMoreTokens())
  | 
      
      
         | 792 | 
          | 
          | 
                           {
  | 
      
      
         | 793 | 
          | 
          | 
                             preserveSpace.add(parseNameTest(st.nextToken()));
  | 
      
      
         | 794 | 
          | 
          | 
                           }
  | 
      
      
         | 795 | 
          | 
          | 
                       }
  | 
      
      
         | 796 | 
          | 
          | 
                     else if ("strip-space".equals(name))
  | 
      
      
         | 797 | 
          | 
          | 
                       {
  | 
      
      
         | 798 | 
          | 
          | 
                         String elements =
  | 
      
      
         | 799 | 
          | 
          | 
                           getRequiredAttribute(attrs, "elements", node);
  | 
      
      
         | 800 | 
          | 
          | 
                         StringTokenizer st = new StringTokenizer(elements,
  | 
      
      
         | 801 | 
          | 
          | 
                                                                  " \t\n\r");
  | 
      
      
         | 802 | 
          | 
          | 
                         while (st.hasMoreTokens())
  | 
      
      
         | 803 | 
          | 
          | 
                           {
  | 
      
      
         | 804 | 
          | 
          | 
                             stripSpace.add(parseNameTest(st.nextToken()));
  | 
      
      
         | 805 | 
          | 
          | 
                           }
  | 
      
      
         | 806 | 
          | 
          | 
                       }
  | 
      
      
         | 807 | 
          | 
          | 
                     else if ("key".equals(name))
  | 
      
      
         | 808 | 
          | 
          | 
                       {
  | 
      
      
         | 809 | 
          | 
          | 
                         parseKey(node, attrs);
  | 
      
      
         | 810 | 
          | 
          | 
                       }
  | 
      
      
         | 811 | 
          | 
          | 
                     else if ("decimal-format".equals(name))
  | 
      
      
         | 812 | 
          | 
          | 
                       {
  | 
      
      
         | 813 | 
          | 
          | 
                         parseDecimalFormat(node, attrs);
  | 
      
      
         | 814 | 
          | 
          | 
                       }
  | 
      
      
         | 815 | 
          | 
          | 
                     else if ("namespace-alias".equals(name))
  | 
      
      
         | 816 | 
          | 
          | 
                       {
  | 
      
      
         | 817 | 
          | 
          | 
                         parseNamespaceAlias(node, attrs);
  | 
      
      
         | 818 | 
          | 
          | 
                       }
  | 
      
      
         | 819 | 
          | 
          | 
                     else if ("attribute-set".equals(name))
  | 
      
      
         | 820 | 
          | 
          | 
                       {
  | 
      
      
         | 821 | 
          | 
          | 
                         parseAttributeSet(node, attrs);
  | 
      
      
         | 822 | 
          | 
          | 
                       }
  | 
      
      
         | 823 | 
          | 
          | 
                   }
  | 
      
      
         | 824 | 
          | 
          | 
                 else if (root)
  | 
      
      
         | 825 | 
          | 
          | 
                   {
  | 
      
      
         | 826 | 
          | 
          | 
                     // Literal document element
  | 
      
      
         | 827 | 
          | 
          | 
                     Attr versionNode =
  | 
      
      
         | 828 | 
          | 
          | 
                       ((Element)node).getAttributeNodeNS(XSL_NS, "version");
  | 
      
      
         | 829 | 
          | 
          | 
                     if (versionNode == null)
  | 
      
      
         | 830 | 
          | 
          | 
                       {
  | 
      
      
         | 831 | 
          | 
          | 
                         String msg = "no xsl:version attribute on literal result node";
  | 
      
      
         | 832 | 
          | 
          | 
                         DOMSourceLocator l = new DOMSourceLocator(node);
  | 
      
      
         | 833 | 
          | 
          | 
                         throw new TransformerConfigurationException(msg, l);
  | 
      
      
         | 834 | 
          | 
          | 
                       }
  | 
      
      
         | 835 | 
          | 
          | 
                     version = versionNode.getValue();
  | 
      
      
         | 836 | 
          | 
          | 
                     Node rootClone = node.cloneNode(true);
  | 
      
      
         | 837 | 
          | 
          | 
                     NamedNodeMap attrs = rootClone.getAttributes();
  | 
      
      
         | 838 | 
          | 
          | 
                     attrs.removeNamedItemNS(XSL_NS, "version");
  | 
      
      
         | 839 | 
          | 
          | 
                     templates.add(new Template(this, null, new Root(),
  | 
      
      
         | 840 | 
          | 
          | 
                                                parse(rootClone),
  | 
      
      
         | 841 | 
          | 
          | 
                                                precedence,
  | 
      
      
         | 842 | 
          | 
          | 
                                                Template.DEFAULT_PRIORITY,
  | 
      
      
         | 843 | 
          | 
          | 
                                                null));
  | 
      
      
         | 844 | 
          | 
          | 
                   }
  | 
      
      
         | 845 | 
          | 
          | 
                 else
  | 
      
      
         | 846 | 
          | 
          | 
                   {
  | 
      
      
         | 847 | 
          | 
          | 
                     // Skip unknown elements, text, comments, etc
  | 
      
      
         | 848 | 
          | 
          | 
                   }
  | 
      
      
         | 849 | 
          | 
          | 
               }
  | 
      
      
         | 850 | 
          | 
          | 
             catch (TransformerException e)
  | 
      
      
         | 851 | 
          | 
          | 
               {
  | 
      
      
         | 852 | 
          | 
          | 
                 DOMSourceLocator l = new DOMSourceLocator(node);
  | 
      
      
         | 853 | 
          | 
          | 
                 throw new TransformerConfigurationException(e.getMessage(), l, e);
  | 
      
      
         | 854 | 
          | 
          | 
               }
  | 
      
      
         | 855 | 
          | 
          | 
             catch (DOMException e)
  | 
      
      
         | 856 | 
          | 
          | 
               {
  | 
      
      
         | 857 | 
          | 
          | 
                 DOMSourceLocator l = new DOMSourceLocator(node);
  | 
      
      
         | 858 | 
          | 
          | 
                 throw new TransformerConfigurationException(e.getMessage(), l, e);
  | 
      
      
         | 859 | 
          | 
          | 
               }
  | 
      
      
         | 860 | 
          | 
          | 
             catch (XPathExpressionException e)
  | 
      
      
         | 861 | 
          | 
          | 
               {
  | 
      
      
         | 862 | 
          | 
          | 
                 DOMSourceLocator l = new DOMSourceLocator(node);
  | 
      
      
         | 863 | 
          | 
          | 
                 throw new TransformerConfigurationException(e.getMessage(), l, e);
  | 
      
      
         | 864 | 
          | 
          | 
               }
  | 
      
      
         | 865 | 
          | 
          | 
           }
  | 
      
      
         | 866 | 
          | 
          | 
          
  | 
      
      
         | 867 | 
          | 
          | 
           final NameTest parseNameTest(String token)
  | 
      
      
         | 868 | 
          | 
          | 
           {
  | 
      
      
         | 869 | 
          | 
          | 
             if ("*".equals(token))
  | 
      
      
         | 870 | 
          | 
          | 
               {
  | 
      
      
         | 871 | 
          | 
          | 
                 return new NameTest(null, true, true);
  | 
      
      
         | 872 | 
          | 
          | 
               }
  | 
      
      
         | 873 | 
          | 
          | 
             else if (token.endsWith(":*"))
  | 
      
      
         | 874 | 
          | 
          | 
               {
  | 
      
      
         | 875 | 
          | 
          | 
                 QName qName = getQName(token.substring(0, token.length() - 2));
  | 
      
      
         | 876 | 
          | 
          | 
                 return new NameTest(qName, true, false);
  | 
      
      
         | 877 | 
          | 
          | 
               }
  | 
      
      
         | 878 | 
          | 
          | 
             else
  | 
      
      
         | 879 | 
          | 
          | 
               {
  | 
      
      
         | 880 | 
          | 
          | 
                 QName qName = getQName(token);
  | 
      
      
         | 881 | 
          | 
          | 
                 return new NameTest(qName, false, false);
  | 
      
      
         | 882 | 
          | 
          | 
               }
  | 
      
      
         | 883 | 
          | 
          | 
           }
  | 
      
      
         | 884 | 
          | 
          | 
          
  | 
      
      
         | 885 | 
          | 
          | 
           final TemplateNode parseAttributeValueTemplate(String value, Node source)
  | 
      
      
         | 886 | 
          | 
          | 
             throws TransformerConfigurationException, XPathExpressionException
  | 
      
      
         | 887 | 
          | 
          | 
           {
  | 
      
      
         | 888 | 
          | 
          | 
             current = source;
  | 
      
      
         | 889 | 
          | 
          | 
             // Tokenize
  | 
      
      
         | 890 | 
          | 
          | 
             int len = value.length();
  | 
      
      
         | 891 | 
          | 
          | 
             int off = 0;
  | 
      
      
         | 892 | 
          | 
          | 
             List tokens = new ArrayList(); // text tokens
  | 
      
      
         | 893 | 
          | 
          | 
             List types = new ArrayList(); // literal or expression
  | 
      
      
         | 894 | 
          | 
          | 
             int depth = 0;
  | 
      
      
         | 895 | 
          | 
          | 
             for (int i = 0; i < len; i++)
  | 
      
      
         | 896 | 
          | 
          | 
               {
  | 
      
      
         | 897 | 
          | 
          | 
                 char c = value.charAt(i);
  | 
      
      
         | 898 | 
          | 
          | 
                 if (c == '{')
  | 
      
      
         | 899 | 
          | 
          | 
                   {
  | 
      
      
         | 900 | 
          | 
          | 
                     if (i < (len - 1) && value.charAt(i + 1) == '{')
  | 
      
      
         | 901 | 
          | 
          | 
                       {
  | 
      
      
         | 902 | 
          | 
          | 
                         tokens.add(value.substring(off, i + 1));
  | 
      
      
         | 903 | 
          | 
          | 
                         types.add(Boolean.FALSE);
  | 
      
      
         | 904 | 
          | 
          | 
                         i++;
  | 
      
      
         | 905 | 
          | 
          | 
                         off = i + 1;
  | 
      
      
         | 906 | 
          | 
          | 
                         continue;
  | 
      
      
         | 907 | 
          | 
          | 
                       }
  | 
      
      
         | 908 | 
          | 
          | 
                     if (depth == 0)
  | 
      
      
         | 909 | 
          | 
          | 
                       {
  | 
      
      
         | 910 | 
          | 
          | 
                         if (i - off > 0)
  | 
      
      
         | 911 | 
          | 
          | 
                           {
  | 
      
      
         | 912 | 
          | 
          | 
                             tokens.add(value.substring(off, i));
  | 
      
      
         | 913 | 
          | 
          | 
                             types.add(Boolean.FALSE);
  | 
      
      
         | 914 | 
          | 
          | 
                           }
  | 
      
      
         | 915 | 
          | 
          | 
                         off = i + 1;
  | 
      
      
         | 916 | 
          | 
          | 
                       }
  | 
      
      
         | 917 | 
          | 
          | 
                     depth++;
  | 
      
      
         | 918 | 
          | 
          | 
                   }
  | 
      
      
         | 919 | 
          | 
          | 
                 else if (c == '}')
  | 
      
      
         | 920 | 
          | 
          | 
                   {
  | 
      
      
         | 921 | 
          | 
          | 
                     if (i < (len - 1) && value.charAt(i + 1) == '}')
  | 
      
      
         | 922 | 
          | 
          | 
                       {
  | 
      
      
         | 923 | 
          | 
          | 
                         tokens.add(value.substring(off, i + 1));
  | 
      
      
         | 924 | 
          | 
          | 
                         types.add(Boolean.FALSE);
  | 
      
      
         | 925 | 
          | 
          | 
                         i++;
  | 
      
      
         | 926 | 
          | 
          | 
                         off = i + 1;
  | 
      
      
         | 927 | 
          | 
          | 
                         continue;
  | 
      
      
         | 928 | 
          | 
          | 
                       }
  | 
      
      
         | 929 | 
          | 
          | 
                     if (depth == 1)
  | 
      
      
         | 930 | 
          | 
          | 
                       {
  | 
      
      
         | 931 | 
          | 
          | 
                         if (i - off > 0)
  | 
      
      
         | 932 | 
          | 
          | 
                           {
  | 
      
      
         | 933 | 
          | 
          | 
                             tokens.add(value.substring(off, i));
  | 
      
      
         | 934 | 
          | 
          | 
                             types.add(Boolean.TRUE);
  | 
      
      
         | 935 | 
          | 
          | 
                           }
  | 
      
      
         | 936 | 
          | 
          | 
                         else
  | 
      
      
         | 937 | 
          | 
          | 
                           {
  | 
      
      
         | 938 | 
          | 
          | 
                             String msg = "attribute value template " +
  | 
      
      
         | 939 | 
          | 
          | 
                               "must contain expression: " + value;
  | 
      
      
         | 940 | 
          | 
          | 
                             DOMSourceLocator l = new DOMSourceLocator(source);
  | 
      
      
         | 941 | 
          | 
          | 
                             throw new TransformerConfigurationException(msg, l);
  | 
      
      
         | 942 | 
          | 
          | 
                           }
  | 
      
      
         | 943 | 
          | 
          | 
                         off = i + 1;
  | 
      
      
         | 944 | 
          | 
          | 
                       }
  | 
      
      
         | 945 | 
          | 
          | 
                     depth--;
  | 
      
      
         | 946 | 
          | 
          | 
                   }
  | 
      
      
         | 947 | 
          | 
          | 
               }
  | 
      
      
         | 948 | 
          | 
          | 
             if (depth > 0)
  | 
      
      
         | 949 | 
          | 
          | 
               {
  | 
      
      
         | 950 | 
          | 
          | 
                 String msg = "invalid attribute value template: " + value;
  | 
      
      
         | 951 | 
          | 
          | 
                 throw new TransformerConfigurationException(msg);
  | 
      
      
         | 952 | 
          | 
          | 
               }
  | 
      
      
         | 953 | 
          | 
          | 
             if (len - off > 0)
  | 
      
      
         | 954 | 
          | 
          | 
               {
  | 
      
      
         | 955 | 
          | 
          | 
                 // Trailing text
  | 
      
      
         | 956 | 
          | 
          | 
                 tokens.add(value.substring(off));
  | 
      
      
         | 957 | 
          | 
          | 
                 types.add(Boolean.FALSE);
  | 
      
      
         | 958 | 
          | 
          | 
               }
  | 
      
      
         | 959 | 
          | 
          | 
          
  | 
      
      
         | 960 | 
          | 
          | 
             // Construct template node tree
  | 
      
      
         | 961 | 
          | 
          | 
             TemplateNode ret = null;
  | 
      
      
         | 962 | 
          | 
          | 
             Document doc = source.getOwnerDocument();
  | 
      
      
         | 963 | 
          | 
          | 
             len = tokens.size();
  | 
      
      
         | 964 | 
          | 
          | 
             for (int i = len - 1; i >= 0; i--)
  | 
      
      
         | 965 | 
          | 
          | 
               {
  | 
      
      
         | 966 | 
          | 
          | 
                 String token = (String) tokens.get(i);
  | 
      
      
         | 967 | 
          | 
          | 
                 Boolean type = (Boolean) types.get(i);
  | 
      
      
         | 968 | 
          | 
          | 
                 if (type == Boolean.TRUE)
  | 
      
      
         | 969 | 
          | 
          | 
                   {
  | 
      
      
         | 970 | 
          | 
          | 
                     // Expression text
  | 
      
      
         | 971 | 
          | 
          | 
                     Expr select = (Expr) xpath.compile(token);
  | 
      
      
         | 972 | 
          | 
          | 
                     TemplateNode ret2 = new ValueOfNode(select, false);
  | 
      
      
         | 973 | 
          | 
          | 
                     ret2.next = ret;
  | 
      
      
         | 974 | 
          | 
          | 
                     ret = ret2;
  | 
      
      
         | 975 | 
          | 
          | 
                   }
  | 
      
      
         | 976 | 
          | 
          | 
                 else
  | 
      
      
         | 977 | 
          | 
          | 
                   {
  | 
      
      
         | 978 | 
          | 
          | 
                     // Verbatim text
  | 
      
      
         | 979 | 
          | 
          | 
                     TemplateNode ret2 = new LiteralNode(doc.createTextNode(token));
  | 
      
      
         | 980 | 
          | 
          | 
                     ret2.next = ret;
  | 
      
      
         | 981 | 
          | 
          | 
                     ret = ret2;
  | 
      
      
         | 982 | 
          | 
          | 
                   }
  | 
      
      
         | 983 | 
          | 
          | 
               }
  | 
      
      
         | 984 | 
          | 
          | 
             return ret;
  | 
      
      
         | 985 | 
          | 
          | 
           }
  | 
      
      
         | 986 | 
          | 
          | 
          
  | 
      
      
         | 987 | 
          | 
          | 
           boolean isPreserved(Text text)
  | 
      
      
         | 988 | 
          | 
          | 
             throws TransformerConfigurationException
  | 
      
      
         | 989 | 
          | 
          | 
           {
  | 
      
      
         | 990 | 
          | 
          | 
             // Check characters in text
  | 
      
      
         | 991 | 
          | 
          | 
             String value = text.getData();
  | 
      
      
         | 992 | 
          | 
          | 
             if (value != null)
  | 
      
      
         | 993 | 
          | 
          | 
               {
  | 
      
      
         | 994 | 
          | 
          | 
                 int len = value.length();
  | 
      
      
         | 995 | 
          | 
          | 
                 for (int i = 0; i < len; i++)
  | 
      
      
         | 996 | 
          | 
          | 
                   {
  | 
      
      
         | 997 | 
          | 
          | 
                     char c = value.charAt(i);
  | 
      
      
         | 998 | 
          | 
          | 
                     if (c != 0x20 && c != 0x09 && c != 0x0a && c != 0x0d)
  | 
      
      
         | 999 | 
          | 
          | 
                       {
  | 
      
      
         | 1000 | 
          | 
          | 
                         return true;
  | 
      
      
         | 1001 | 
          | 
          | 
                       }
  | 
      
      
         | 1002 | 
          | 
          | 
                   }
  | 
      
      
         | 1003 | 
          | 
          | 
               }
  | 
      
      
         | 1004 | 
          | 
          | 
             // Check parent node
  | 
      
      
         | 1005 | 
          | 
          | 
             Node ctx = text.getParentNode();
  | 
      
      
         | 1006 | 
          | 
          | 
             if (!preserveSpace.isEmpty())
  | 
      
      
         | 1007 | 
          | 
          | 
               {
  | 
      
      
         | 1008 | 
          | 
          | 
                 for (Iterator i = preserveSpace.iterator(); i.hasNext(); )
  | 
      
      
         | 1009 | 
          | 
          | 
                   {
  | 
      
      
         | 1010 | 
          | 
          | 
                     NameTest preserveTest = (NameTest) i.next();
  | 
      
      
         | 1011 | 
          | 
          | 
                     if (preserveTest.matches(ctx, 1, 1))
  | 
      
      
         | 1012 | 
          | 
          | 
                       {
  | 
      
      
         | 1013 | 
          | 
          | 
                         boolean override = false;
  | 
      
      
         | 1014 | 
          | 
          | 
                         if (!stripSpace.isEmpty())
  | 
      
      
         | 1015 | 
          | 
          | 
                           {
  | 
      
      
         | 1016 | 
          | 
          | 
                             for (Iterator j = stripSpace.iterator(); j.hasNext(); )
  | 
      
      
         | 1017 | 
          | 
          | 
                               {
  | 
      
      
         | 1018 | 
          | 
          | 
                                 NameTest stripTest = (NameTest) j.next();
  | 
      
      
         | 1019 | 
          | 
          | 
                                 if (stripTest.matches(ctx, 1, 1))
  | 
      
      
         | 1020 | 
          | 
          | 
                                   {
  | 
      
      
         | 1021 | 
          | 
          | 
                                     override = true;
  | 
      
      
         | 1022 | 
          | 
          | 
                                     break;
  | 
      
      
         | 1023 | 
          | 
          | 
                                   }
  | 
      
      
         | 1024 | 
          | 
          | 
                               }
  | 
      
      
         | 1025 | 
          | 
          | 
                           }
  | 
      
      
         | 1026 | 
          | 
          | 
                         if (!override)
  | 
      
      
         | 1027 | 
          | 
          | 
                           {
  | 
      
      
         | 1028 | 
          | 
          | 
                             return true;
  | 
      
      
         | 1029 | 
          | 
          | 
                           }
  | 
      
      
         | 1030 | 
          | 
          | 
                       }
  | 
      
      
         | 1031 | 
          | 
          | 
                   }
  | 
      
      
         | 1032 | 
          | 
          | 
               }
  | 
      
      
         | 1033 | 
          | 
          | 
             // Check whether any ancestor specified xml:space
  | 
      
      
         | 1034 | 
          | 
          | 
             while (ctx != null)
  | 
      
      
         | 1035 | 
          | 
          | 
               {
  | 
      
      
         | 1036 | 
          | 
          | 
                 if (ctx.getNodeType() == Node.ELEMENT_NODE)
  | 
      
      
         | 1037 | 
          | 
          | 
                   {
  | 
      
      
         | 1038 | 
          | 
          | 
                     Element element = (Element) ctx;
  | 
      
      
         | 1039 | 
          | 
          | 
                     String xmlSpace = element.getAttribute("xml:space");
  | 
      
      
         | 1040 | 
          | 
          | 
                     if ("default".equals(xmlSpace))
  | 
      
      
         | 1041 | 
          | 
          | 
                       {
  | 
      
      
         | 1042 | 
          | 
          | 
                         break;
  | 
      
      
         | 1043 | 
          | 
          | 
                       }
  | 
      
      
         | 1044 | 
          | 
          | 
                     else if ("preserve".equals(xmlSpace))
  | 
      
      
         | 1045 | 
          | 
          | 
                       {
  | 
      
      
         | 1046 | 
          | 
          | 
                         return true;
  | 
      
      
         | 1047 | 
          | 
          | 
                       }
  | 
      
      
         | 1048 | 
          | 
          | 
                     else if (xmlSpace.length() > 0)
  | 
      
      
         | 1049 | 
          | 
          | 
                       {
  | 
      
      
         | 1050 | 
          | 
          | 
                         String msg = "Illegal value for xml:space: " + xmlSpace;
  | 
      
      
         | 1051 | 
          | 
          | 
                         throw new TransformerConfigurationException(msg);
  | 
      
      
         | 1052 | 
          | 
          | 
                       }
  | 
      
      
         | 1053 | 
          | 
          | 
                     else if ("text".equals(ctx.getLocalName()) &&
  | 
      
      
         | 1054 | 
          | 
          | 
                              XSL_NS.equals(ctx.getNamespaceURI()))
  | 
      
      
         | 1055 | 
          | 
          | 
                       {
  | 
      
      
         | 1056 | 
          | 
          | 
                         // xsl:text implies xml:space='preserve'
  | 
      
      
         | 1057 | 
          | 
          | 
                         return true;
  | 
      
      
         | 1058 | 
          | 
          | 
                       }
  | 
      
      
         | 1059 | 
          | 
          | 
                   }
  | 
      
      
         | 1060 | 
          | 
          | 
                 ctx = ctx.getParentNode();
  | 
      
      
         | 1061 | 
          | 
          | 
               }
  | 
      
      
         | 1062 | 
          | 
          | 
             return false;
  | 
      
      
         | 1063 | 
          | 
          | 
           }
  | 
      
      
         | 1064 | 
          | 
          | 
          
  | 
      
      
         | 1065 | 
          | 
          | 
           public XPathFunction resolveFunction(QName name, int arity)
  | 
      
      
         | 1066 | 
          | 
          | 
           {
  | 
      
      
         | 1067 | 
          | 
          | 
             String uri = name.getNamespaceURI();
  | 
      
      
         | 1068 | 
          | 
          | 
             if (XSL_NS.equals(uri) || uri == null || uri.length() == 0)
  | 
      
      
         | 1069 | 
          | 
          | 
               {
  | 
      
      
         | 1070 | 
          | 
          | 
                 String localName = name.getLocalPart();
  | 
      
      
         | 1071 | 
          | 
          | 
                 if ("document".equals(localName) && (arity == 1 || arity == 2))
  | 
      
      
         | 1072 | 
          | 
          | 
                   {
  | 
      
      
         | 1073 | 
          | 
          | 
                     if (current == null)
  | 
      
      
         | 1074 | 
          | 
          | 
                       {
  | 
      
      
         | 1075 | 
          | 
          | 
                         throw new RuntimeException("current is null");
  | 
      
      
         | 1076 | 
          | 
          | 
                       }
  | 
      
      
         | 1077 | 
          | 
          | 
                     return new DocumentFunction(getRootStylesheet(), current);
  | 
      
      
         | 1078 | 
          | 
          | 
                   }
  | 
      
      
         | 1079 | 
          | 
          | 
                 else if ("key".equals(localName) && (arity == 2))
  | 
      
      
         | 1080 | 
          | 
          | 
                   {
  | 
      
      
         | 1081 | 
          | 
          | 
                     return new KeyFunction(getRootStylesheet());
  | 
      
      
         | 1082 | 
          | 
          | 
                   }
  | 
      
      
         | 1083 | 
          | 
          | 
                 else if ("format-number".equals(localName) &&
  | 
      
      
         | 1084 | 
          | 
          | 
                          (arity == 2 || arity == 3))
  | 
      
      
         | 1085 | 
          | 
          | 
                   {
  | 
      
      
         | 1086 | 
          | 
          | 
                     return new FormatNumberFunction(getRootStylesheet());
  | 
      
      
         | 1087 | 
          | 
          | 
                   }
  | 
      
      
         | 1088 | 
          | 
          | 
                 else if ("current".equals(localName) && (arity == 0))
  | 
      
      
         | 1089 | 
          | 
          | 
                   {
  | 
      
      
         | 1090 | 
          | 
          | 
                     return new CurrentFunction(getRootStylesheet());
  | 
      
      
         | 1091 | 
          | 
          | 
                   }
  | 
      
      
         | 1092 | 
          | 
          | 
                 else if ("unparsed-entity-uri".equals(localName) && (arity == 1))
  | 
      
      
         | 1093 | 
          | 
          | 
                   {
  | 
      
      
         | 1094 | 
          | 
          | 
                     return new UnparsedEntityUriFunction();
  | 
      
      
         | 1095 | 
          | 
          | 
                   }
  | 
      
      
         | 1096 | 
          | 
          | 
                 else if ("generate-id".equals(localName) &&
  | 
      
      
         | 1097 | 
          | 
          | 
                          (arity == 1 || arity == 0))
  | 
      
      
         | 1098 | 
          | 
          | 
                   {
  | 
      
      
         | 1099 | 
          | 
          | 
                     return new GenerateIdFunction();
  | 
      
      
         | 1100 | 
          | 
          | 
                   }
  | 
      
      
         | 1101 | 
          | 
          | 
                 else if ("system-property".equals(localName) && (arity == 1))
  | 
      
      
         | 1102 | 
          | 
          | 
                   {
  | 
      
      
         | 1103 | 
          | 
          | 
                     return new SystemPropertyFunction();
  | 
      
      
         | 1104 | 
          | 
          | 
                   }
  | 
      
      
         | 1105 | 
          | 
          | 
                 else if ("element-available".equals(localName) && (arity == 1))
  | 
      
      
         | 1106 | 
          | 
          | 
                   {
  | 
      
      
         | 1107 | 
          | 
          | 
                     return new ElementAvailableFunction(this);
  | 
      
      
         | 1108 | 
          | 
          | 
                   }
  | 
      
      
         | 1109 | 
          | 
          | 
                 else if ("function-available".equals(localName) && (arity == 1))
  | 
      
      
         | 1110 | 
          | 
          | 
                   {
  | 
      
      
         | 1111 | 
          | 
          | 
                     return new FunctionAvailableFunction(this);
  | 
      
      
         | 1112 | 
          | 
          | 
                   }
  | 
      
      
         | 1113 | 
          | 
          | 
               }
  | 
      
      
         | 1114 | 
          | 
          | 
             return null;
  | 
      
      
         | 1115 | 
          | 
          | 
           }
  | 
      
      
         | 1116 | 
          | 
          | 
          
  | 
      
      
         | 1117 | 
          | 
          | 
           // -- Parsing --
  | 
      
      
         | 1118 | 
          | 
          | 
          
  | 
      
      
         | 1119 | 
          | 
          | 
           /**
  | 
      
      
         | 1120 | 
          | 
          | 
            * apply-templates
  | 
      
      
         | 1121 | 
          | 
          | 
            */
  | 
      
      
         | 1122 | 
          | 
          | 
           final TemplateNode parseApplyTemplates(Node node)
  | 
      
      
         | 1123 | 
          | 
          | 
             throws TransformerConfigurationException, XPathExpressionException
  | 
      
      
         | 1124 | 
          | 
          | 
           {
  | 
      
      
         | 1125 | 
          | 
          | 
             NamedNodeMap attrs = node.getAttributes();
  | 
      
      
         | 1126 | 
          | 
          | 
             String m = getAttribute(attrs, "mode");
  | 
      
      
         | 1127 | 
          | 
          | 
             QName mode = (m == null) ? null : getQName(m);
  | 
      
      
         | 1128 | 
          | 
          | 
             String s = getAttribute(attrs, "select");
  | 
      
      
         | 1129 | 
          | 
          | 
             if (s == null)
  | 
      
      
         | 1130 | 
          | 
          | 
               {
  | 
      
      
         | 1131 | 
          | 
          | 
                 s = "child::node()";
  | 
      
      
         | 1132 | 
          | 
          | 
               }
  | 
      
      
         | 1133 | 
          | 
          | 
             Node children = node.getFirstChild();
  | 
      
      
         | 1134 | 
          | 
          | 
             List sortKeys = parseSortKeys(children);
  | 
      
      
         | 1135 | 
          | 
          | 
             List withParams = parseWithParams(children);
  | 
      
      
         | 1136 | 
          | 
          | 
             Expr select = (Expr) xpath.compile(s);
  | 
      
      
         | 1137 | 
          | 
          | 
             return new ApplyTemplatesNode(select, mode,
  | 
      
      
         | 1138 | 
          | 
          | 
                                           sortKeys, withParams, false);
  | 
      
      
         | 1139 | 
          | 
          | 
           }
  | 
      
      
         | 1140 | 
          | 
          | 
          
  | 
      
      
         | 1141 | 
          | 
          | 
           /**
  | 
      
      
         | 1142 | 
          | 
          | 
            * call-template
  | 
      
      
         | 1143 | 
          | 
          | 
            */
  | 
      
      
         | 1144 | 
          | 
          | 
           final TemplateNode parseCallTemplate(Node node)
  | 
      
      
         | 1145 | 
          | 
          | 
             throws TransformerConfigurationException, XPathExpressionException
  | 
      
      
         | 1146 | 
          | 
          | 
           {
  | 
      
      
         | 1147 | 
          | 
          | 
             NamedNodeMap attrs = node.getAttributes();
  | 
      
      
         | 1148 | 
          | 
          | 
             String n = getRequiredAttribute(attrs, "name", node);
  | 
      
      
         | 1149 | 
          | 
          | 
             QName name = getQName(n);
  | 
      
      
         | 1150 | 
          | 
          | 
             Node children = node.getFirstChild();
  | 
      
      
         | 1151 | 
          | 
          | 
             List withParams = parseWithParams(children);
  | 
      
      
         | 1152 | 
          | 
          | 
             return new CallTemplateNode(name, withParams);
  | 
      
      
         | 1153 | 
          | 
          | 
           }
  | 
      
      
         | 1154 | 
          | 
          | 
          
  | 
      
      
         | 1155 | 
          | 
          | 
           /**
  | 
      
      
         | 1156 | 
          | 
          | 
            * value-of
  | 
      
      
         | 1157 | 
          | 
          | 
            */
  | 
      
      
         | 1158 | 
          | 
          | 
           final TemplateNode parseValueOf(Node node)
  | 
      
      
         | 1159 | 
          | 
          | 
             throws TransformerConfigurationException, XPathExpressionException
  | 
      
      
         | 1160 | 
          | 
          | 
           {
  | 
      
      
         | 1161 | 
          | 
          | 
             NamedNodeMap attrs = node.getAttributes();
  | 
      
      
         | 1162 | 
          | 
          | 
             String s = getRequiredAttribute(attrs, "select", node);
  | 
      
      
         | 1163 | 
          | 
          | 
             String doe = getAttribute(attrs, "disable-output-escaping");
  | 
      
      
         | 1164 | 
          | 
          | 
             boolean d = "yes".equals(doe);
  | 
      
      
         | 1165 | 
          | 
          | 
             Expr select = (Expr) xpath.compile(s);
  | 
      
      
         | 1166 | 
          | 
          | 
             return new ValueOfNode(select, d);
  | 
      
      
         | 1167 | 
          | 
          | 
           }
  | 
      
      
         | 1168 | 
          | 
          | 
          
  | 
      
      
         | 1169 | 
          | 
          | 
           /**
  | 
      
      
         | 1170 | 
          | 
          | 
            * for-each
  | 
      
      
         | 1171 | 
          | 
          | 
            */
  | 
      
      
         | 1172 | 
          | 
          | 
           final TemplateNode parseForEach(Node node)
  | 
      
      
         | 1173 | 
          | 
          | 
             throws TransformerConfigurationException, XPathExpressionException
  | 
      
      
         | 1174 | 
          | 
          | 
           {
  | 
      
      
         | 1175 | 
          | 
          | 
             NamedNodeMap attrs = node.getAttributes();
  | 
      
      
         | 1176 | 
          | 
          | 
             String s = getRequiredAttribute(attrs, "select", node);
  | 
      
      
         | 1177 | 
          | 
          | 
             Node children = node.getFirstChild();
  | 
      
      
         | 1178 | 
          | 
          | 
             List sortKeys = parseSortKeys(children);
  | 
      
      
         | 1179 | 
          | 
          | 
             Expr select = (Expr) xpath.compile(s);
  | 
      
      
         | 1180 | 
          | 
          | 
             ForEachNode ret = new ForEachNode(select, sortKeys);
  | 
      
      
         | 1181 | 
          | 
          | 
             ret.children = parse(children);
  | 
      
      
         | 1182 | 
          | 
          | 
             return ret;
  | 
      
      
         | 1183 | 
          | 
          | 
           }
  | 
      
      
         | 1184 | 
          | 
          | 
          
  | 
      
      
         | 1185 | 
          | 
          | 
           /**
  | 
      
      
         | 1186 | 
          | 
          | 
            * if
  | 
      
      
         | 1187 | 
          | 
          | 
            */
  | 
      
      
         | 1188 | 
          | 
          | 
           final TemplateNode parseIf(Node node)
  | 
      
      
         | 1189 | 
          | 
          | 
             throws TransformerConfigurationException, XPathExpressionException
  | 
      
      
         | 1190 | 
          | 
          | 
           {
  | 
      
      
         | 1191 | 
          | 
          | 
             NamedNodeMap attrs = node.getAttributes();
  | 
      
      
         | 1192 | 
          | 
          | 
             String t = getRequiredAttribute(attrs, "test", node);
  | 
      
      
         | 1193 | 
          | 
          | 
             Expr test = (Expr) xpath.compile(t);
  | 
      
      
         | 1194 | 
          | 
          | 
             Node children = node.getFirstChild();
  | 
      
      
         | 1195 | 
          | 
          | 
             IfNode ret = new IfNode(test);
  | 
      
      
         | 1196 | 
          | 
          | 
             ret.children = parse(children);
  | 
      
      
         | 1197 | 
          | 
          | 
             return ret;
  | 
      
      
         | 1198 | 
          | 
          | 
           }
  | 
      
      
         | 1199 | 
          | 
          | 
          
  | 
      
      
         | 1200 | 
          | 
          | 
           /**
  | 
      
      
         | 1201 | 
          | 
          | 
            * when
  | 
      
      
         | 1202 | 
          | 
          | 
            */
  | 
      
      
         | 1203 | 
          | 
          | 
           final TemplateNode parseWhen(Node node)
  | 
      
      
         | 1204 | 
          | 
          | 
             throws TransformerConfigurationException, XPathExpressionException
  | 
      
      
         | 1205 | 
          | 
          | 
           {
  | 
      
      
         | 1206 | 
          | 
          | 
             NamedNodeMap attrs = node.getAttributes();
  | 
      
      
         | 1207 | 
          | 
          | 
             String t = getRequiredAttribute(attrs, "test", node);
  | 
      
      
         | 1208 | 
          | 
          | 
             Expr test = (Expr) xpath.compile(t);
  | 
      
      
         | 1209 | 
          | 
          | 
             Node children = node.getFirstChild();
  | 
      
      
         | 1210 | 
          | 
          | 
             WhenNode ret = new WhenNode(test);
  | 
      
      
         | 1211 | 
          | 
          | 
             ret.children = parse(children);
  | 
      
      
         | 1212 | 
          | 
          | 
             return ret;
  | 
      
      
         | 1213 | 
          | 
          | 
           }
  | 
      
      
         | 1214 | 
          | 
          | 
          
  | 
      
      
         | 1215 | 
          | 
          | 
           /**
  | 
      
      
         | 1216 | 
          | 
          | 
            * element
  | 
      
      
         | 1217 | 
          | 
          | 
            */
  | 
      
      
         | 1218 | 
          | 
          | 
           final TemplateNode parseElement(Node node)
  | 
      
      
         | 1219 | 
          | 
          | 
             throws TransformerConfigurationException, XPathExpressionException
  | 
      
      
         | 1220 | 
          | 
          | 
           {
  | 
      
      
         | 1221 | 
          | 
          | 
             NamedNodeMap attrs = node.getAttributes();
  | 
      
      
         | 1222 | 
          | 
          | 
             String name = getRequiredAttribute(attrs, "name", node);
  | 
      
      
         | 1223 | 
          | 
          | 
             String namespace = getAttribute(attrs, "namespace");
  | 
      
      
         | 1224 | 
          | 
          | 
             String uas = getAttribute(attrs, "use-attribute-sets");
  | 
      
      
         | 1225 | 
          | 
          | 
             TemplateNode n = parseAttributeValueTemplate(name, node);
  | 
      
      
         | 1226 | 
          | 
          | 
             TemplateNode ns = (namespace == null) ? null :
  | 
      
      
         | 1227 | 
          | 
          | 
               parseAttributeValueTemplate(namespace, node);
  | 
      
      
         | 1228 | 
          | 
          | 
             Node children = node.getFirstChild();
  | 
      
      
         | 1229 | 
          | 
          | 
             ElementNode ret = new ElementNode(n, ns, uas, node);
  | 
      
      
         | 1230 | 
          | 
          | 
             ret.children = parse(children);
  | 
      
      
         | 1231 | 
          | 
          | 
             return ret;
  | 
      
      
         | 1232 | 
          | 
          | 
           }
  | 
      
      
         | 1233 | 
          | 
          | 
          
  | 
      
      
         | 1234 | 
          | 
          | 
           /**
  | 
      
      
         | 1235 | 
          | 
          | 
            * attribute
  | 
      
      
         | 1236 | 
          | 
          | 
            */
  | 
      
      
         | 1237 | 
          | 
          | 
           final TemplateNode parseAttribute(Node node)
  | 
      
      
         | 1238 | 
          | 
          | 
             throws TransformerConfigurationException, XPathExpressionException
  | 
      
      
         | 1239 | 
          | 
          | 
           {
  | 
      
      
         | 1240 | 
          | 
          | 
             NamedNodeMap attrs = node.getAttributes();
  | 
      
      
         | 1241 | 
          | 
          | 
             String name = getRequiredAttribute(attrs, "name", node);
  | 
      
      
         | 1242 | 
          | 
          | 
             String namespace = getAttribute(attrs, "namespace");
  | 
      
      
         | 1243 | 
          | 
          | 
             TemplateNode n = parseAttributeValueTemplate(name, node);
  | 
      
      
         | 1244 | 
          | 
          | 
             TemplateNode ns = (namespace == null) ? null :
  | 
      
      
         | 1245 | 
          | 
          | 
               parseAttributeValueTemplate(namespace, node);
  | 
      
      
         | 1246 | 
          | 
          | 
             Node children = node.getFirstChild();
  | 
      
      
         | 1247 | 
          | 
          | 
             AttributeNode ret = new AttributeNode(n, ns, node);
  | 
      
      
         | 1248 | 
          | 
          | 
             ret.children = parse(children);
  | 
      
      
         | 1249 | 
          | 
          | 
             return ret;
  | 
      
      
         | 1250 | 
          | 
          | 
           }
  | 
      
      
         | 1251 | 
          | 
          | 
          
  | 
      
      
         | 1252 | 
          | 
          | 
           /**
  | 
      
      
         | 1253 | 
          | 
          | 
            * text
  | 
      
      
         | 1254 | 
          | 
          | 
            */
  | 
      
      
         | 1255 | 
          | 
          | 
           final TemplateNode parseText(Node node)
  | 
      
      
         | 1256 | 
          | 
          | 
             throws TransformerConfigurationException, XPathExpressionException
  | 
      
      
         | 1257 | 
          | 
          | 
           {
  | 
      
      
         | 1258 | 
          | 
          | 
             NamedNodeMap attrs = node.getAttributes();
  | 
      
      
         | 1259 | 
          | 
          | 
             String doe = getAttribute(attrs, "disable-output-escaping");
  | 
      
      
         | 1260 | 
          | 
          | 
             boolean d = "yes".equals(doe);
  | 
      
      
         | 1261 | 
          | 
          | 
             Node children = node.getFirstChild();
  | 
      
      
         | 1262 | 
          | 
          | 
             TextNode ret = new TextNode(d);
  | 
      
      
         | 1263 | 
          | 
          | 
             ret.children = parse(children);
  | 
      
      
         | 1264 | 
          | 
          | 
             return ret;
  | 
      
      
         | 1265 | 
          | 
          | 
           }
  | 
      
      
         | 1266 | 
          | 
          | 
          
  | 
      
      
         | 1267 | 
          | 
          | 
           /**
  | 
      
      
         | 1268 | 
          | 
          | 
            * copy
  | 
      
      
         | 1269 | 
          | 
          | 
            */
  | 
      
      
         | 1270 | 
          | 
          | 
           final TemplateNode parseCopy(Node node)
  | 
      
      
         | 1271 | 
          | 
          | 
             throws TransformerConfigurationException, XPathExpressionException
  | 
      
      
         | 1272 | 
          | 
          | 
           {
  | 
      
      
         | 1273 | 
          | 
          | 
             NamedNodeMap attrs = node.getAttributes();
  | 
      
      
         | 1274 | 
          | 
          | 
             String uas = getAttribute(attrs, "use-attribute-sets");
  | 
      
      
         | 1275 | 
          | 
          | 
             Node children = node.getFirstChild();
  | 
      
      
         | 1276 | 
          | 
          | 
             CopyNode ret = new CopyNode(uas);
  | 
      
      
         | 1277 | 
          | 
          | 
             ret.children = parse(children);
  | 
      
      
         | 1278 | 
          | 
          | 
             return ret;
  | 
      
      
         | 1279 | 
          | 
          | 
           }
  | 
      
      
         | 1280 | 
          | 
          | 
          
  | 
      
      
         | 1281 | 
          | 
          | 
           /**
  | 
      
      
         | 1282 | 
          | 
          | 
            * processing-instruction
  | 
      
      
         | 1283 | 
          | 
          | 
            */
  | 
      
      
         | 1284 | 
          | 
          | 
           final TemplateNode parseProcessingInstruction(Node node)
  | 
      
      
         | 1285 | 
          | 
          | 
             throws TransformerConfigurationException, XPathExpressionException
  | 
      
      
         | 1286 | 
          | 
          | 
           {
  | 
      
      
         | 1287 | 
          | 
          | 
             NamedNodeMap attrs = node.getAttributes();
  | 
      
      
         | 1288 | 
          | 
          | 
             String name = getRequiredAttribute(attrs, "name", node);
  | 
      
      
         | 1289 | 
          | 
          | 
             Node children = node.getFirstChild();
  | 
      
      
         | 1290 | 
          | 
          | 
             ProcessingInstructionNode ret = new ProcessingInstructionNode(name);
  | 
      
      
         | 1291 | 
          | 
          | 
             ret.children = parse(children);
  | 
      
      
         | 1292 | 
          | 
          | 
             return ret;
  | 
      
      
         | 1293 | 
          | 
          | 
           }
  | 
      
      
         | 1294 | 
          | 
          | 
          
  | 
      
      
         | 1295 | 
          | 
          | 
           /**
  | 
      
      
         | 1296 | 
          | 
          | 
            * number
  | 
      
      
         | 1297 | 
          | 
          | 
            */
  | 
      
      
         | 1298 | 
          | 
          | 
           final TemplateNode parseNumber(Node node)
  | 
      
      
         | 1299 | 
          | 
          | 
             throws TransformerConfigurationException, XPathExpressionException
  | 
      
      
         | 1300 | 
          | 
          | 
           {
  | 
      
      
         | 1301 | 
          | 
          | 
             NamedNodeMap attrs = node.getAttributes();
  | 
      
      
         | 1302 | 
          | 
          | 
             String v = getAttribute(attrs, "value");
  | 
      
      
         | 1303 | 
          | 
          | 
             String ff = getAttribute(attrs, "format");
  | 
      
      
         | 1304 | 
          | 
          | 
             if (ff == null)
  | 
      
      
         | 1305 | 
          | 
          | 
               {
  | 
      
      
         | 1306 | 
          | 
          | 
                 ff = "1";
  | 
      
      
         | 1307 | 
          | 
          | 
               }
  | 
      
      
         | 1308 | 
          | 
          | 
             TemplateNode format = parseAttributeValueTemplate(ff, node);
  | 
      
      
         | 1309 | 
          | 
          | 
             String lang = getAttribute(attrs, "lang");
  | 
      
      
         | 1310 | 
          | 
          | 
             String lv = getAttribute(attrs, "letter-value");
  | 
      
      
         | 1311 | 
          | 
          | 
             int letterValue = "traditional".equals(lv) ?
  | 
      
      
         | 1312 | 
          | 
          | 
               AbstractNumberNode.TRADITIONAL :
  | 
      
      
         | 1313 | 
          | 
          | 
               AbstractNumberNode.ALPHABETIC;
  | 
      
      
         | 1314 | 
          | 
          | 
             String gs = getAttribute(attrs, "grouping-separator");
  | 
      
      
         | 1315 | 
          | 
          | 
             String gz = getAttribute(attrs, "grouping-size");
  | 
      
      
         | 1316 | 
          | 
          | 
             int gz2 = (gz != null && gz.length() > 0) ?
  | 
      
      
         | 1317 | 
          | 
          | 
               Integer.parseInt(gz) : 1;
  | 
      
      
         | 1318 | 
          | 
          | 
             Node children = node.getFirstChild();
  | 
      
      
         | 1319 | 
          | 
          | 
             TemplateNode ret;
  | 
      
      
         | 1320 | 
          | 
          | 
             if (v != null && v.length() > 0)
  | 
      
      
         | 1321 | 
          | 
          | 
               {
  | 
      
      
         | 1322 | 
          | 
          | 
                 Expr value = (Expr) xpath.compile(v);
  | 
      
      
         | 1323 | 
          | 
          | 
                 ret = new NumberNode(value, format, lang,
  | 
      
      
         | 1324 | 
          | 
          | 
                                      letterValue, gs, gz2);
  | 
      
      
         | 1325 | 
          | 
          | 
               }
  | 
      
      
         | 1326 | 
          | 
          | 
             else
  | 
      
      
         | 1327 | 
          | 
          | 
               {
  | 
      
      
         | 1328 | 
          | 
          | 
                 String l = getAttribute(attrs, "level");
  | 
      
      
         | 1329 | 
          | 
          | 
                 int level =
  | 
      
      
         | 1330 | 
          | 
          | 
                   "multiple".equals(l) ? NodeNumberNode.MULTIPLE :
  | 
      
      
         | 1331 | 
          | 
          | 
                               "any".equals(l) ? NodeNumberNode.ANY :
  | 
      
      
         | 1332 | 
          | 
          | 
                               NodeNumberNode.SINGLE;
  | 
      
      
         | 1333 | 
          | 
          | 
                 String c = getAttribute(attrs, "count");
  | 
      
      
         | 1334 | 
          | 
          | 
                 String f = getAttribute(attrs, "from");
  | 
      
      
         | 1335 | 
          | 
          | 
                 Pattern count = null;
  | 
      
      
         | 1336 | 
          | 
          | 
                 Pattern from = null;
  | 
      
      
         | 1337 | 
          | 
          | 
                 if (c != null)
  | 
      
      
         | 1338 | 
          | 
          | 
                   {
  | 
      
      
         | 1339 | 
          | 
          | 
                     try
  | 
      
      
         | 1340 | 
          | 
          | 
                       {
  | 
      
      
         | 1341 | 
          | 
          | 
                         count = (Pattern) xpath.compile(c);
  | 
      
      
         | 1342 | 
          | 
          | 
                       }
  | 
      
      
         | 1343 | 
          | 
          | 
                     catch (ClassCastException e)
  | 
      
      
         | 1344 | 
          | 
          | 
                       {
  | 
      
      
         | 1345 | 
          | 
          | 
                         String msg = "invalid pattern: " + c;
  | 
      
      
         | 1346 | 
          | 
          | 
                         throw new TransformerConfigurationException(msg);
  | 
      
      
         | 1347 | 
          | 
          | 
                       }
  | 
      
      
         | 1348 | 
          | 
          | 
                   }
  | 
      
      
         | 1349 | 
          | 
          | 
                 if (f != null)
  | 
      
      
         | 1350 | 
          | 
          | 
                   {
  | 
      
      
         | 1351 | 
          | 
          | 
                     try
  | 
      
      
         | 1352 | 
          | 
          | 
                       {
  | 
      
      
         | 1353 | 
          | 
          | 
                         from = (Pattern) xpath.compile(f);
  | 
      
      
         | 1354 | 
          | 
          | 
                       }
  | 
      
      
         | 1355 | 
          | 
          | 
                     catch (ClassCastException e)
  | 
      
      
         | 1356 | 
          | 
          | 
                       {
  | 
      
      
         | 1357 | 
          | 
          | 
                         String msg = "invalid pattern: " + f;
  | 
      
      
         | 1358 | 
          | 
          | 
                         throw new TransformerConfigurationException(msg);
  | 
      
      
         | 1359 | 
          | 
          | 
                       }
  | 
      
      
         | 1360 | 
          | 
          | 
                   }
  | 
      
      
         | 1361 | 
          | 
          | 
                 ret = new NodeNumberNode(level, count, from,
  | 
      
      
         | 1362 | 
          | 
          | 
                                          format, lang,
  | 
      
      
         | 1363 | 
          | 
          | 
                                          letterValue, gs, gz2);
  | 
      
      
         | 1364 | 
          | 
          | 
               }
  | 
      
      
         | 1365 | 
          | 
          | 
             ret.children = parse(children);
  | 
      
      
         | 1366 | 
          | 
          | 
             return ret;
  | 
      
      
         | 1367 | 
          | 
          | 
           }
  | 
      
      
         | 1368 | 
          | 
          | 
          
  | 
      
      
         | 1369 | 
          | 
          | 
           /**
  | 
      
      
         | 1370 | 
          | 
          | 
            * copy-of
  | 
      
      
         | 1371 | 
          | 
          | 
            */
  | 
      
      
         | 1372 | 
          | 
          | 
           final TemplateNode parseCopyOf(Node node)
  | 
      
      
         | 1373 | 
          | 
          | 
             throws TransformerConfigurationException, XPathExpressionException
  | 
      
      
         | 1374 | 
          | 
          | 
           {
  | 
      
      
         | 1375 | 
          | 
          | 
             NamedNodeMap attrs = node.getAttributes();
  | 
      
      
         | 1376 | 
          | 
          | 
             String s = getRequiredAttribute(attrs, "select", node);
  | 
      
      
         | 1377 | 
          | 
          | 
             Expr select = (Expr) xpath.compile(s);
  | 
      
      
         | 1378 | 
          | 
          | 
             Node children = node.getFirstChild();
  | 
      
      
         | 1379 | 
          | 
          | 
             CopyOfNode ret = new CopyOfNode(select);
  | 
      
      
         | 1380 | 
          | 
          | 
             ret.children = parse(children);
  | 
      
      
         | 1381 | 
          | 
          | 
             return ret;
  | 
      
      
         | 1382 | 
          | 
          | 
           }
  | 
      
      
         | 1383 | 
          | 
          | 
          
  | 
      
      
         | 1384 | 
          | 
          | 
           /**
  | 
      
      
         | 1385 | 
          | 
          | 
            * message
  | 
      
      
         | 1386 | 
          | 
          | 
            */
  | 
      
      
         | 1387 | 
          | 
          | 
           final TemplateNode parseMessage(Node node)
  | 
      
      
         | 1388 | 
          | 
          | 
             throws TransformerConfigurationException, XPathExpressionException
  | 
      
      
         | 1389 | 
          | 
          | 
           {
  | 
      
      
         | 1390 | 
          | 
          | 
             NamedNodeMap attrs = node.getAttributes();
  | 
      
      
         | 1391 | 
          | 
          | 
             String t = getAttribute(attrs, "terminate");
  | 
      
      
         | 1392 | 
          | 
          | 
             boolean terminate = "yes".equals(t);
  | 
      
      
         | 1393 | 
          | 
          | 
             Node children = node.getFirstChild();
  | 
      
      
         | 1394 | 
          | 
          | 
             MessageNode ret = new MessageNode(terminate);
  | 
      
      
         | 1395 | 
          | 
          | 
             ret.children = parse(children);
  | 
      
      
         | 1396 | 
          | 
          | 
             return ret;
  | 
      
      
         | 1397 | 
          | 
          | 
           }
  | 
      
      
         | 1398 | 
          | 
          | 
          
  | 
      
      
         | 1399 | 
          | 
          | 
           /**
  | 
      
      
         | 1400 | 
          | 
          | 
            * Parse template-level elements.
  | 
      
      
         | 1401 | 
          | 
          | 
            */
  | 
      
      
         | 1402 | 
          | 
          | 
           final TemplateNode parse(Node node)
  | 
      
      
         | 1403 | 
          | 
          | 
             throws TransformerConfigurationException
  | 
      
      
         | 1404 | 
          | 
          | 
           {
  | 
      
      
         | 1405 | 
          | 
          | 
             TemplateNode first = null;
  | 
      
      
         | 1406 | 
          | 
          | 
             TemplateNode previous = null;
  | 
      
      
         | 1407 | 
          | 
          | 
             while (node != null)
  | 
      
      
         | 1408 | 
          | 
          | 
               {
  | 
      
      
         | 1409 | 
          | 
          | 
                 Node next = node.getNextSibling();
  | 
      
      
         | 1410 | 
          | 
          | 
                 TemplateNode tnode = doParse(node);
  | 
      
      
         | 1411 | 
          | 
          | 
                 if (tnode != null)
  | 
      
      
         | 1412 | 
          | 
          | 
                   {
  | 
      
      
         | 1413 | 
          | 
          | 
                     if (first == null)
  | 
      
      
         | 1414 | 
          | 
          | 
                       {
  | 
      
      
         | 1415 | 
          | 
          | 
                         first = tnode;
  | 
      
      
         | 1416 | 
          | 
          | 
                       }
  | 
      
      
         | 1417 | 
          | 
          | 
                     if (previous != null)
  | 
      
      
         | 1418 | 
          | 
          | 
                       {
  | 
      
      
         | 1419 | 
          | 
          | 
                         previous.next = tnode;
  | 
      
      
         | 1420 | 
          | 
          | 
                       }
  | 
      
      
         | 1421 | 
          | 
          | 
                     previous = tnode;
  | 
      
      
         | 1422 | 
          | 
          | 
                   }
  | 
      
      
         | 1423 | 
          | 
          | 
                 node = next;
  | 
      
      
         | 1424 | 
          | 
          | 
               }
  | 
      
      
         | 1425 | 
          | 
          | 
             return first;
  | 
      
      
         | 1426 | 
          | 
          | 
           }
  | 
      
      
         | 1427 | 
          | 
          | 
          
  | 
      
      
         | 1428 | 
          | 
          | 
           private final TemplateNode doParse(Node node)
  | 
      
      
         | 1429 | 
          | 
          | 
             throws TransformerConfigurationException
  | 
      
      
         | 1430 | 
          | 
          | 
           {
  | 
      
      
         | 1431 | 
          | 
          | 
             // Hack to associate the document function with its declaring node
  | 
      
      
         | 1432 | 
          | 
          | 
             current = node;
  | 
      
      
         | 1433 | 
          | 
          | 
             try
  | 
      
      
         | 1434 | 
          | 
          | 
               {
  | 
      
      
         | 1435 | 
          | 
          | 
                 String namespaceUri = node.getNamespaceURI();
  | 
      
      
         | 1436 | 
          | 
          | 
                 if (Stylesheet.XSL_NS.equals(namespaceUri) &&
  | 
      
      
         | 1437 | 
          | 
          | 
                     Node.ELEMENT_NODE == node.getNodeType())
  | 
      
      
         | 1438 | 
          | 
          | 
                   {
  | 
      
      
         | 1439 | 
          | 
          | 
                     String name = node.getLocalName();
  | 
      
      
         | 1440 | 
          | 
          | 
                     if ("apply-templates".equals(name))
  | 
      
      
         | 1441 | 
          | 
          | 
                       {
  | 
      
      
         | 1442 | 
          | 
          | 
                         return parseApplyTemplates(node);
  | 
      
      
         | 1443 | 
          | 
          | 
                       }
  | 
      
      
         | 1444 | 
          | 
          | 
                     else if ("call-template".equals(name))
  | 
      
      
         | 1445 | 
          | 
          | 
                       {
  | 
      
      
         | 1446 | 
          | 
          | 
                         return parseCallTemplate(node);
  | 
      
      
         | 1447 | 
          | 
          | 
                       }
  | 
      
      
         | 1448 | 
          | 
          | 
                     else if ("value-of".equals(name))
  | 
      
      
         | 1449 | 
          | 
          | 
                       {
  | 
      
      
         | 1450 | 
          | 
          | 
                         return parseValueOf(node);
  | 
      
      
         | 1451 | 
          | 
          | 
                       }
  | 
      
      
         | 1452 | 
          | 
          | 
                     else if ("for-each".equals(name))
  | 
      
      
         | 1453 | 
          | 
          | 
                       {
  | 
      
      
         | 1454 | 
          | 
          | 
                         return parseForEach(node);
  | 
      
      
         | 1455 | 
          | 
          | 
                       }
  | 
      
      
         | 1456 | 
          | 
          | 
                     else if ("if".equals(name))
  | 
      
      
         | 1457 | 
          | 
          | 
                       {
  | 
      
      
         | 1458 | 
          | 
          | 
                         return parseIf(node);
  | 
      
      
         | 1459 | 
          | 
          | 
                       }
  | 
      
      
         | 1460 | 
          | 
          | 
                     else if ("choose".equals(name))
  | 
      
      
         | 1461 | 
          | 
          | 
                       {
  | 
      
      
         | 1462 | 
          | 
          | 
                         Node children = node.getFirstChild();
  | 
      
      
         | 1463 | 
          | 
          | 
                         ChooseNode ret = new ChooseNode();
  | 
      
      
         | 1464 | 
          | 
          | 
                         ret.children = parse(children);
  | 
      
      
         | 1465 | 
          | 
          | 
                         return ret;
  | 
      
      
         | 1466 | 
          | 
          | 
                       }
  | 
      
      
         | 1467 | 
          | 
          | 
                     else if ("when".equals(name))
  | 
      
      
         | 1468 | 
          | 
          | 
                       {
  | 
      
      
         | 1469 | 
          | 
          | 
                         return parseWhen(node);
  | 
      
      
         | 1470 | 
          | 
          | 
                       }
  | 
      
      
         | 1471 | 
          | 
          | 
                     else if ("otherwise".equals(name))
  | 
      
      
         | 1472 | 
          | 
          | 
                       {
  | 
      
      
         | 1473 | 
          | 
          | 
                         Node children = node.getFirstChild();
  | 
      
      
         | 1474 | 
          | 
          | 
                         OtherwiseNode ret = new OtherwiseNode();
  | 
      
      
         | 1475 | 
          | 
          | 
                         ret.children = parse(children);
  | 
      
      
         | 1476 | 
          | 
          | 
                         return ret;
  | 
      
      
         | 1477 | 
          | 
          | 
                       }
  | 
      
      
         | 1478 | 
          | 
          | 
                     else if ("element".equals(name))
  | 
      
      
         | 1479 | 
          | 
          | 
                       {
  | 
      
      
         | 1480 | 
          | 
          | 
                         return parseElement(node);
  | 
      
      
         | 1481 | 
          | 
          | 
                       }
  | 
      
      
         | 1482 | 
          | 
          | 
                     else if ("attribute".equals(name))
  | 
      
      
         | 1483 | 
          | 
          | 
                       {
  | 
      
      
         | 1484 | 
          | 
          | 
                         return parseAttribute(node);
  | 
      
      
         | 1485 | 
          | 
          | 
                       }
  | 
      
      
         | 1486 | 
          | 
          | 
                     else if ("text".equals(name))
  | 
      
      
         | 1487 | 
          | 
          | 
                       {
  | 
      
      
         | 1488 | 
          | 
          | 
                         return parseText(node);
  | 
      
      
         | 1489 | 
          | 
          | 
                       }
  | 
      
      
         | 1490 | 
          | 
          | 
                     else if ("copy".equals(name))
  | 
      
      
         | 1491 | 
          | 
          | 
                       {
  | 
      
      
         | 1492 | 
          | 
          | 
                         return parseCopy(node);
  | 
      
      
         | 1493 | 
          | 
          | 
                       }
  | 
      
      
         | 1494 | 
          | 
          | 
                     else if ("processing-instruction".equals(name))
  | 
      
      
         | 1495 | 
          | 
          | 
                       {
  | 
      
      
         | 1496 | 
          | 
          | 
                         return parseProcessingInstruction(node);
  | 
      
      
         | 1497 | 
          | 
          | 
                       }
  | 
      
      
         | 1498 | 
          | 
          | 
                     else if ("comment".equals(name))
  | 
      
      
         | 1499 | 
          | 
          | 
                       {
  | 
      
      
         | 1500 | 
          | 
          | 
                         Node children = node.getFirstChild();
  | 
      
      
         | 1501 | 
          | 
          | 
                         CommentNode ret = new CommentNode();
  | 
      
      
         | 1502 | 
          | 
          | 
                         ret.children = parse(children);
  | 
      
      
         | 1503 | 
          | 
          | 
                         return ret;
  | 
      
      
         | 1504 | 
          | 
          | 
                       }
  | 
      
      
         | 1505 | 
          | 
          | 
                     else if ("number".equals(name))
  | 
      
      
         | 1506 | 
          | 
          | 
                       {
  | 
      
      
         | 1507 | 
          | 
          | 
                         return parseNumber(node);
  | 
      
      
         | 1508 | 
          | 
          | 
                       }
  | 
      
      
         | 1509 | 
          | 
          | 
                     else if ("param".equals(name) ||
  | 
      
      
         | 1510 | 
          | 
          | 
                              "variable".equals(name))
  | 
      
      
         | 1511 | 
          | 
          | 
                       {
  | 
      
      
         | 1512 | 
          | 
          | 
                         int type = "variable".equals(name) ?
  | 
      
      
         | 1513 | 
          | 
          | 
                           Bindings.VARIABLE : Bindings.PARAM;
  | 
      
      
         | 1514 | 
          | 
          | 
                         NamedNodeMap attrs = node.getAttributes();
  | 
      
      
         | 1515 | 
          | 
          | 
                         Node children = node.getFirstChild();
  | 
      
      
         | 1516 | 
          | 
          | 
                         TemplateNode content = parse(children);
  | 
      
      
         | 1517 | 
          | 
          | 
                         QName paramName =
  | 
      
      
         | 1518 | 
          | 
          | 
                           getQName(getRequiredAttribute(attrs, "name", node));
  | 
      
      
         | 1519 | 
          | 
          | 
                         String select = getAttribute(attrs, "select");
  | 
      
      
         | 1520 | 
          | 
          | 
                         ParameterNode ret;
  | 
      
      
         | 1521 | 
          | 
          | 
                         if (select != null)
  | 
      
      
         | 1522 | 
          | 
          | 
                           {
  | 
      
      
         | 1523 | 
          | 
          | 
                             if (content != null)
  | 
      
      
         | 1524 | 
          | 
          | 
                               {
  | 
      
      
         | 1525 | 
          | 
          | 
                                 String msg = "parameter '" + paramName +
  | 
      
      
         | 1526 | 
          | 
          | 
                                   "' has both select and content";
  | 
      
      
         | 1527 | 
          | 
          | 
                                 DOMSourceLocator l = new DOMSourceLocator(node);
  | 
      
      
         | 1528 | 
          | 
          | 
                                 throw new TransformerConfigurationException(msg, l);
  | 
      
      
         | 1529 | 
          | 
          | 
                               }
  | 
      
      
         | 1530 | 
          | 
          | 
                             Expr expr = (Expr) xpath.compile(select);
  | 
      
      
         | 1531 | 
          | 
          | 
                             ret = new ParameterNode(paramName, expr, type);
  | 
      
      
         | 1532 | 
          | 
          | 
                           }
  | 
      
      
         | 1533 | 
          | 
          | 
                         else
  | 
      
      
         | 1534 | 
          | 
          | 
                           {
  | 
      
      
         | 1535 | 
          | 
          | 
                             ret = new ParameterNode(paramName, null, type);
  | 
      
      
         | 1536 | 
          | 
          | 
                             ret.children = content;
  | 
      
      
         | 1537 | 
          | 
          | 
                           }
  | 
      
      
         | 1538 | 
          | 
          | 
                         return ret;
  | 
      
      
         | 1539 | 
          | 
          | 
                       }
  | 
      
      
         | 1540 | 
          | 
          | 
                     else if ("copy-of".equals(name))
  | 
      
      
         | 1541 | 
          | 
          | 
                       {
  | 
      
      
         | 1542 | 
          | 
          | 
                         return parseCopyOf(node);
  | 
      
      
         | 1543 | 
          | 
          | 
                       }
  | 
      
      
         | 1544 | 
          | 
          | 
                     else if ("message".equals(name))
  | 
      
      
         | 1545 | 
          | 
          | 
                       {
  | 
      
      
         | 1546 | 
          | 
          | 
                         return parseMessage(node);
  | 
      
      
         | 1547 | 
          | 
          | 
                       }
  | 
      
      
         | 1548 | 
          | 
          | 
                     else if ("apply-imports".equals(name))
  | 
      
      
         | 1549 | 
          | 
          | 
                       {
  | 
      
      
         | 1550 | 
          | 
          | 
                         Node children = node.getFirstChild();
  | 
      
      
         | 1551 | 
          | 
          | 
                         ApplyImportsNode ret = new ApplyImportsNode();
  | 
      
      
         | 1552 | 
          | 
          | 
                         ret.children = parse(children);
  | 
      
      
         | 1553 | 
          | 
          | 
                         return ret;
  | 
      
      
         | 1554 | 
          | 
          | 
                       }
  | 
      
      
         | 1555 | 
          | 
          | 
                     else
  | 
      
      
         | 1556 | 
          | 
          | 
                       {
  | 
      
      
         | 1557 | 
          | 
          | 
                         // xsl:fallback
  | 
      
      
         | 1558 | 
          | 
          | 
                         // Pass over any other XSLT nodes
  | 
      
      
         | 1559 | 
          | 
          | 
                         return null;
  | 
      
      
         | 1560 | 
          | 
          | 
                       }
  | 
      
      
         | 1561 | 
          | 
          | 
                   }
  | 
      
      
         | 1562 | 
          | 
          | 
                 String prefix = node.getPrefix();
  | 
      
      
         | 1563 | 
          | 
          | 
                 if (extensionElementPrefixes.contains(prefix))
  | 
      
      
         | 1564 | 
          | 
          | 
                   {
  | 
      
      
         | 1565 | 
          | 
          | 
                     // Pass over extension elements
  | 
      
      
         | 1566 | 
          | 
          | 
                     return null;
  | 
      
      
         | 1567 | 
          | 
          | 
                   }
  | 
      
      
         | 1568 | 
          | 
          | 
                 switch (node.getNodeType())
  | 
      
      
         | 1569 | 
          | 
          | 
                   {
  | 
      
      
         | 1570 | 
          | 
          | 
                   case Node.TEXT_NODE:
  | 
      
      
         | 1571 | 
          | 
          | 
                     // Determine whether to strip whitespace
  | 
      
      
         | 1572 | 
          | 
          | 
                     Text text = (Text) node;
  | 
      
      
         | 1573 | 
          | 
          | 
                     if (!isPreserved(text))
  | 
      
      
         | 1574 | 
          | 
          | 
                       {
  | 
      
      
         | 1575 | 
          | 
          | 
                         // Strip
  | 
      
      
         | 1576 | 
          | 
          | 
                         /*String data = text.getData().trim();
  | 
      
      
         | 1577 | 
          | 
          | 
                         if (data.length() > 0)
  | 
      
      
         | 1578 | 
          | 
          | 
                           {
  | 
      
      
         | 1579 | 
          | 
          | 
                             text.setData(data);
  | 
      
      
         | 1580 | 
          | 
          | 
                           } // else */
  | 
      
      
         | 1581 | 
          | 
          | 
                         text.getParentNode().removeChild(text);
  | 
      
      
         | 1582 | 
          | 
          | 
                         return null;
  | 
      
      
         | 1583 | 
          | 
          | 
                       }
  | 
      
      
         | 1584 | 
          | 
          | 
                     break;
  | 
      
      
         | 1585 | 
          | 
          | 
                   case Node.COMMENT_NODE:
  | 
      
      
         | 1586 | 
          | 
          | 
                     // Ignore comments
  | 
      
      
         | 1587 | 
          | 
          | 
                     return null;
  | 
      
      
         | 1588 | 
          | 
          | 
                   case Node.ELEMENT_NODE:
  | 
      
      
         | 1589 | 
          | 
          | 
                     // Check for attribute value templates and use-attribute-sets
  | 
      
      
         | 1590 | 
          | 
          | 
                     NamedNodeMap attrs = node.getAttributes();
  | 
      
      
         | 1591 | 
          | 
          | 
                     boolean convert = false;
  | 
      
      
         | 1592 | 
          | 
          | 
                     String useAttributeSets = null;
  | 
      
      
         | 1593 | 
          | 
          | 
                     int len = attrs.getLength();
  | 
      
      
         | 1594 | 
          | 
          | 
                     for (int i = 0; i < len; i++)
  | 
      
      
         | 1595 | 
          | 
          | 
                       {
  | 
      
      
         | 1596 | 
          | 
          | 
                         Node attr = attrs.item(i);
  | 
      
      
         | 1597 | 
          | 
          | 
                         String value = attr.getNodeValue();
  | 
      
      
         | 1598 | 
          | 
          | 
                         if (Stylesheet.XSL_NS.equals(attr.getNamespaceURI()) &&
  | 
      
      
         | 1599 | 
          | 
          | 
                             "use-attribute-sets".equals(attr.getLocalName()))
  | 
      
      
         | 1600 | 
          | 
          | 
                           {
  | 
      
      
         | 1601 | 
          | 
          | 
                             useAttributeSets = value;
  | 
      
      
         | 1602 | 
          | 
          | 
                             convert = true;
  | 
      
      
         | 1603 | 
          | 
          | 
                             break;
  | 
      
      
         | 1604 | 
          | 
          | 
                           }
  | 
      
      
         | 1605 | 
          | 
          | 
                         int start = value.indexOf('{');
  | 
      
      
         | 1606 | 
          | 
          | 
                         int end = value.indexOf('}');
  | 
      
      
         | 1607 | 
          | 
          | 
                         if (start != -1 || end != -1)
  | 
      
      
         | 1608 | 
          | 
          | 
                           {
  | 
      
      
         | 1609 | 
          | 
          | 
                             convert = true;
  | 
      
      
         | 1610 | 
          | 
          | 
                             break;
  | 
      
      
         | 1611 | 
          | 
          | 
                           }
  | 
      
      
         | 1612 | 
          | 
          | 
                       }
  | 
      
      
         | 1613 | 
          | 
          | 
                     if (convert)
  | 
      
      
         | 1614 | 
          | 
          | 
                       {
  | 
      
      
         | 1615 | 
          | 
          | 
                         // Create an element-producing template node instead
  | 
      
      
         | 1616 | 
          | 
          | 
                         // with appropriate attribute-producing child template nodes
  | 
      
      
         | 1617 | 
          | 
          | 
                         Node children = node.getFirstChild();
  | 
      
      
         | 1618 | 
          | 
          | 
                         TemplateNode child = parse(children);
  | 
      
      
         | 1619 | 
          | 
          | 
                         for (int i = 0; i < len; i++)
  | 
      
      
         | 1620 | 
          | 
          | 
                           {
  | 
      
      
         | 1621 | 
          | 
          | 
                             Node attr = attrs.item(i);
  | 
      
      
         | 1622 | 
          | 
          | 
                             String ans = attr.getNamespaceURI();
  | 
      
      
         | 1623 | 
          | 
          | 
                             String aname = attr.getNodeName();
  | 
      
      
         | 1624 | 
          | 
          | 
                             if (Stylesheet.XSL_NS.equals(ans) &&
  | 
      
      
         | 1625 | 
          | 
          | 
                                 "use-attribute-sets".equals(attr.getLocalName()))
  | 
      
      
         | 1626 | 
          | 
          | 
                               {
  | 
      
      
         | 1627 | 
          | 
          | 
                                 continue;
  | 
      
      
         | 1628 | 
          | 
          | 
                               }
  | 
      
      
         | 1629 | 
          | 
          | 
                             String value = attr.getNodeValue();
  | 
      
      
         | 1630 | 
          | 
          | 
                             TemplateNode grandchild =
  | 
      
      
         | 1631 | 
          | 
          | 
                               parseAttributeValueTemplate(value, node);
  | 
      
      
         | 1632 | 
          | 
          | 
                             TemplateNode n =
  | 
      
      
         | 1633 | 
          | 
          | 
                               parseAttributeValueTemplate(aname, node);
  | 
      
      
         | 1634 | 
          | 
          | 
                             TemplateNode ns = (ans == null) ? null :
  | 
      
      
         | 1635 | 
          | 
          | 
                               parseAttributeValueTemplate(ans, node);
  | 
      
      
         | 1636 | 
          | 
          | 
                             TemplateNode newChild = new AttributeNode(n, ns, attr);
  | 
      
      
         | 1637 | 
          | 
          | 
                             newChild.children = grandchild;
  | 
      
      
         | 1638 | 
          | 
          | 
                             newChild.next = child;
  | 
      
      
         | 1639 | 
          | 
          | 
                             child = newChild;
  | 
      
      
         | 1640 | 
          | 
          | 
                           }
  | 
      
      
         | 1641 | 
          | 
          | 
                         String ename = node.getNodeName();
  | 
      
      
         | 1642 | 
          | 
          | 
                         TemplateNode n = parseAttributeValueTemplate(ename, node);
  | 
      
      
         | 1643 | 
          | 
          | 
                         TemplateNode ns = (namespaceUri == null) ? null :
  | 
      
      
         | 1644 | 
          | 
          | 
                           parseAttributeValueTemplate(namespaceUri, node);
  | 
      
      
         | 1645 | 
          | 
          | 
                         ElementNode ret = new ElementNode(n, ns, useAttributeSets,
  | 
      
      
         | 1646 | 
          | 
          | 
                                                           node);
  | 
      
      
         | 1647 | 
          | 
          | 
                         ret.children = child;
  | 
      
      
         | 1648 | 
          | 
          | 
                         return ret;
  | 
      
      
         | 1649 | 
          | 
          | 
                       }
  | 
      
      
         | 1650 | 
          | 
          | 
                     // Otherwise fall through
  | 
      
      
         | 1651 | 
          | 
          | 
                     break;
  | 
      
      
         | 1652 | 
          | 
          | 
                   }
  | 
      
      
         | 1653 | 
          | 
          | 
               }
  | 
      
      
         | 1654 | 
          | 
          | 
             catch (XPathExpressionException e)
  | 
      
      
         | 1655 | 
          | 
          | 
               {
  | 
      
      
         | 1656 | 
          | 
          | 
                 DOMSourceLocator l = new DOMSourceLocator(node);
  | 
      
      
         | 1657 | 
          | 
          | 
                 throw new TransformerConfigurationException(e.getMessage(), l, e);
  | 
      
      
         | 1658 | 
          | 
          | 
               }
  | 
      
      
         | 1659 | 
          | 
          | 
             Node children = node.getFirstChild();
  | 
      
      
         | 1660 | 
          | 
          | 
             LiteralNode ret = new LiteralNode(node);
  | 
      
      
         | 1661 | 
          | 
          | 
             ret.children = parse(children);
  | 
      
      
         | 1662 | 
          | 
          | 
             return ret;
  | 
      
      
         | 1663 | 
          | 
          | 
           }
  | 
      
      
         | 1664 | 
          | 
          | 
          
  | 
      
      
         | 1665 | 
          | 
          | 
           final List parseSortKeys(Node node)
  | 
      
      
         | 1666 | 
          | 
          | 
             throws TransformerConfigurationException, XPathExpressionException
  | 
      
      
         | 1667 | 
          | 
          | 
           {
  | 
      
      
         | 1668 | 
          | 
          | 
             List ret = new LinkedList();
  | 
      
      
         | 1669 | 
          | 
          | 
             while (node != null)
  | 
      
      
         | 1670 | 
          | 
          | 
               {
  | 
      
      
         | 1671 | 
          | 
          | 
                 String namespaceUri = node.getNamespaceURI();
  | 
      
      
         | 1672 | 
          | 
          | 
                 if (Stylesheet.XSL_NS.equals(namespaceUri) &&
  | 
      
      
         | 1673 | 
          | 
          | 
                     Node.ELEMENT_NODE == node.getNodeType() &&
  | 
      
      
         | 1674 | 
          | 
          | 
                     "sort".equals(node.getLocalName()))
  | 
      
      
         | 1675 | 
          | 
          | 
                   {
  | 
      
      
         | 1676 | 
          | 
          | 
                     NamedNodeMap attrs = node.getAttributes();
  | 
      
      
         | 1677 | 
          | 
          | 
                     String s = getAttribute(attrs, "select");
  | 
      
      
         | 1678 | 
          | 
          | 
                     if (s == null)
  | 
      
      
         | 1679 | 
          | 
          | 
                       {
  | 
      
      
         | 1680 | 
          | 
          | 
                         s = ".";
  | 
      
      
         | 1681 | 
          | 
          | 
                       }
  | 
      
      
         | 1682 | 
          | 
          | 
                     Expr select = (Expr) xpath.compile(s);
  | 
      
      
         | 1683 | 
          | 
          | 
                     String l = getAttribute(attrs, "lang");
  | 
      
      
         | 1684 | 
          | 
          | 
                     TemplateNode lang = (l == null) ? null :
  | 
      
      
         | 1685 | 
          | 
          | 
                       parseAttributeValueTemplate(l, node);
  | 
      
      
         | 1686 | 
          | 
          | 
                     String dt = getAttribute(attrs, "data-type");
  | 
      
      
         | 1687 | 
          | 
          | 
                     TemplateNode dataType = (dt == null) ? null :
  | 
      
      
         | 1688 | 
          | 
          | 
                       parseAttributeValueTemplate(dt, node);
  | 
      
      
         | 1689 | 
          | 
          | 
                     String o = getAttribute(attrs, "order");
  | 
      
      
         | 1690 | 
          | 
          | 
                     TemplateNode order = (o == null) ? null :
  | 
      
      
         | 1691 | 
          | 
          | 
                       parseAttributeValueTemplate(o, node);
  | 
      
      
         | 1692 | 
          | 
          | 
                     String co = getAttribute(attrs, "case-order");
  | 
      
      
         | 1693 | 
          | 
          | 
                     TemplateNode caseOrder = (co == null) ? null :
  | 
      
      
         | 1694 | 
          | 
          | 
                       parseAttributeValueTemplate(co, node);
  | 
      
      
         | 1695 | 
          | 
          | 
                     ret.add(new SortKey(select, lang, dataType, order, caseOrder));
  | 
      
      
         | 1696 | 
          | 
          | 
                   }
  | 
      
      
         | 1697 | 
          | 
          | 
                 node = node.getNextSibling();
  | 
      
      
         | 1698 | 
          | 
          | 
               }
  | 
      
      
         | 1699 | 
          | 
          | 
             return ret.isEmpty() ? null : ret;
  | 
      
      
         | 1700 | 
          | 
          | 
           }
  | 
      
      
         | 1701 | 
          | 
          | 
          
  | 
      
      
         | 1702 | 
          | 
          | 
           final List parseWithParams(Node node)
  | 
      
      
         | 1703 | 
          | 
          | 
             throws TransformerConfigurationException, XPathExpressionException
  | 
      
      
         | 1704 | 
          | 
          | 
           {
  | 
      
      
         | 1705 | 
          | 
          | 
             List ret = new LinkedList();
  | 
      
      
         | 1706 | 
          | 
          | 
             while (node != null)
  | 
      
      
         | 1707 | 
          | 
          | 
               {
  | 
      
      
         | 1708 | 
          | 
          | 
                 String namespaceUri = node.getNamespaceURI();
  | 
      
      
         | 1709 | 
          | 
          | 
                 if (Stylesheet.XSL_NS.equals(namespaceUri) &&
  | 
      
      
         | 1710 | 
          | 
          | 
                     Node.ELEMENT_NODE == node.getNodeType() &&
  | 
      
      
         | 1711 | 
          | 
          | 
                     "with-param".equals(node.getLocalName()))
  | 
      
      
         | 1712 | 
          | 
          | 
                   {
  | 
      
      
         | 1713 | 
          | 
          | 
                     NamedNodeMap attrs = node.getAttributes();
  | 
      
      
         | 1714 | 
          | 
          | 
                     TemplateNode content = parse(node.getFirstChild());
  | 
      
      
         | 1715 | 
          | 
          | 
                     QName name =
  | 
      
      
         | 1716 | 
          | 
          | 
                       getQName(getRequiredAttribute(attrs, "name", node));
  | 
      
      
         | 1717 | 
          | 
          | 
                     String select = getAttribute(attrs, "select");
  | 
      
      
         | 1718 | 
          | 
          | 
                     if (select != null)
  | 
      
      
         | 1719 | 
          | 
          | 
                       {
  | 
      
      
         | 1720 | 
          | 
          | 
                         if (content != null)
  | 
      
      
         | 1721 | 
          | 
          | 
                           {
  | 
      
      
         | 1722 | 
          | 
          | 
                             String msg = "parameter '" + name +
  | 
      
      
         | 1723 | 
          | 
          | 
                               "' has both select and content";
  | 
      
      
         | 1724 | 
          | 
          | 
                             DOMSourceLocator l = new DOMSourceLocator(node);
  | 
      
      
         | 1725 | 
          | 
          | 
                             throw new TransformerConfigurationException(msg, l);
  | 
      
      
         | 1726 | 
          | 
          | 
                           }
  | 
      
      
         | 1727 | 
          | 
          | 
                         Expr expr = (Expr) xpath.compile(select);
  | 
      
      
         | 1728 | 
          | 
          | 
                         ret.add(new WithParam(name, expr));
  | 
      
      
         | 1729 | 
          | 
          | 
                       }
  | 
      
      
         | 1730 | 
          | 
          | 
                     else
  | 
      
      
         | 1731 | 
          | 
          | 
                       {
  | 
      
      
         | 1732 | 
          | 
          | 
                         ret.add(new WithParam(name, content));
  | 
      
      
         | 1733 | 
          | 
          | 
                       }
  | 
      
      
         | 1734 | 
          | 
          | 
                   }
  | 
      
      
         | 1735 | 
          | 
          | 
                 node = node.getNextSibling();
  | 
      
      
         | 1736 | 
          | 
          | 
               }
  | 
      
      
         | 1737 | 
          | 
          | 
             return ret.isEmpty() ? null : ret;
  | 
      
      
         | 1738 | 
          | 
          | 
           }
  | 
      
      
         | 1739 | 
          | 
          | 
          
  | 
      
      
         | 1740 | 
          | 
          | 
           /**
  | 
      
      
         | 1741 | 
          | 
          | 
            * Created element nodes have a copy of the namespace nodes in the
  | 
      
      
         | 1742 | 
          | 
          | 
            * stylesheet, except the XSLT namespace, extension namespaces, and
  | 
      
      
         | 1743 | 
          | 
          | 
            * exclude-result-prefixes.
  | 
      
      
         | 1744 | 
          | 
          | 
            */
  | 
      
      
         | 1745 | 
          | 
          | 
           final void addNamespaceNodes(Node source, Node target, Document doc,
  | 
      
      
         | 1746 | 
          | 
          | 
                                        Collection elementExcludeResultPrefixes)
  | 
      
      
         | 1747 | 
          | 
          | 
           {
  | 
      
      
         | 1748 | 
          | 
          | 
             NamedNodeMap attrs = source.getAttributes();
  | 
      
      
         | 1749 | 
          | 
          | 
             if (attrs != null)
  | 
      
      
         | 1750 | 
          | 
          | 
               {
  | 
      
      
         | 1751 | 
          | 
          | 
                 int len = attrs.getLength();
  | 
      
      
         | 1752 | 
          | 
          | 
                 for (int i = 0; i < len; i++)
  | 
      
      
         | 1753 | 
          | 
          | 
                   {
  | 
      
      
         | 1754 | 
          | 
          | 
                     Node attr = attrs.item(i);
  | 
      
      
         | 1755 | 
          | 
          | 
                     String uri = attr.getNamespaceURI();
  | 
      
      
         | 1756 | 
          | 
          | 
                     if (uri == XMLConstants.XMLNS_ATTRIBUTE_NS_URI)
  | 
      
      
         | 1757 | 
          | 
          | 
                       {
  | 
      
      
         | 1758 | 
          | 
          | 
                         String prefix = attr.getLocalName();
  | 
      
      
         | 1759 | 
          | 
          | 
                         if (XMLConstants.XMLNS_ATTRIBUTE.equals(prefix))
  | 
      
      
         | 1760 | 
          | 
          | 
                           {
  | 
      
      
         | 1761 | 
          | 
          | 
                             prefix = "#default";
  | 
      
      
         | 1762 | 
          | 
          | 
                           }
  | 
      
      
         | 1763 | 
          | 
          | 
                         String ns = attr.getNodeValue();
  | 
      
      
         | 1764 | 
          | 
          | 
                         // Should the namespace be excluded?
  | 
      
      
         | 1765 | 
          | 
          | 
                         if (XSL_NS.equals(ns) ||
  | 
      
      
         | 1766 | 
          | 
          | 
                             extensionElementPrefixes.contains(prefix) ||
  | 
      
      
         | 1767 | 
          | 
          | 
                             elementExcludeResultPrefixes.contains(prefix) ||
  | 
      
      
         | 1768 | 
          | 
          | 
                             excludeResultPrefixes.contains(prefix))
  | 
      
      
         | 1769 | 
          | 
          | 
                           {
  | 
      
      
         | 1770 | 
          | 
          | 
                             continue;
  | 
      
      
         | 1771 | 
          | 
          | 
                           }
  | 
      
      
         | 1772 | 
          | 
          | 
                         // Is the namespace already defined on the target?
  | 
      
      
         | 1773 | 
          | 
          | 
                         if (prefix == "#default")
  | 
      
      
         | 1774 | 
          | 
          | 
                           {
  | 
      
      
         | 1775 | 
          | 
          | 
                             prefix = null;
  | 
      
      
         | 1776 | 
          | 
          | 
                           }
  | 
      
      
         | 1777 | 
          | 
          | 
                         if (target.lookupNamespaceURI(prefix) != null)
  | 
      
      
         | 1778 | 
          | 
          | 
                           {
  | 
      
      
         | 1779 | 
          | 
          | 
                             continue;
  | 
      
      
         | 1780 | 
          | 
          | 
                           }
  | 
      
      
         | 1781 | 
          | 
          | 
                         attr = attr.cloneNode(true);
  | 
      
      
         | 1782 | 
          | 
          | 
                         attr = doc.adoptNode(attr);
  | 
      
      
         | 1783 | 
          | 
          | 
                         target.getAttributes().setNamedItemNS(attr);
  | 
      
      
         | 1784 | 
          | 
          | 
                       }
  | 
      
      
         | 1785 | 
          | 
          | 
                   }
  | 
      
      
         | 1786 | 
          | 
          | 
               }
  | 
      
      
         | 1787 | 
          | 
          | 
             Node parent = source.getParentNode();
  | 
      
      
         | 1788 | 
          | 
          | 
             if (parent != null)
  | 
      
      
         | 1789 | 
          | 
          | 
               {
  | 
      
      
         | 1790 | 
          | 
          | 
                 addNamespaceNodes(parent, target, doc, elementExcludeResultPrefixes);
  | 
      
      
         | 1791 | 
          | 
          | 
               }
  | 
      
      
         | 1792 | 
          | 
          | 
           }
  | 
      
      
         | 1793 | 
          | 
          | 
          
  | 
      
      
         | 1794 | 
          | 
          | 
           static final String getAttribute(NamedNodeMap attrs, String name)
  | 
      
      
         | 1795 | 
          | 
          | 
           {
  | 
      
      
         | 1796 | 
          | 
          | 
             Node attr = attrs.getNamedItem(name);
  | 
      
      
         | 1797 | 
          | 
          | 
             if (attr == null)
  | 
      
      
         | 1798 | 
          | 
          | 
               {
  | 
      
      
         | 1799 | 
          | 
          | 
                 return null;
  | 
      
      
         | 1800 | 
          | 
          | 
               }
  | 
      
      
         | 1801 | 
          | 
          | 
             String ret = attr.getNodeValue();
  | 
      
      
         | 1802 | 
          | 
          | 
             if (ret.length() == 0)
  | 
      
      
         | 1803 | 
          | 
          | 
               {
  | 
      
      
         | 1804 | 
          | 
          | 
                 return null;
  | 
      
      
         | 1805 | 
          | 
          | 
               }
  | 
      
      
         | 1806 | 
          | 
          | 
             return ret;
  | 
      
      
         | 1807 | 
          | 
          | 
           }
  | 
      
      
         | 1808 | 
          | 
          | 
          
  | 
      
      
         | 1809 | 
          | 
          | 
           static final String getRequiredAttribute(NamedNodeMap attrs, String name,
  | 
      
      
         | 1810 | 
          | 
          | 
                                                    Node source)
  | 
      
      
         | 1811 | 
          | 
          | 
             throws TransformerConfigurationException
  | 
      
      
         | 1812 | 
          | 
          | 
           {
  | 
      
      
         | 1813 | 
          | 
          | 
             String value = getAttribute(attrs, name);
  | 
      
      
         | 1814 | 
          | 
          | 
             if (value == null || value.length() == 0)
  | 
      
      
         | 1815 | 
          | 
          | 
               {
  | 
      
      
         | 1816 | 
          | 
          | 
                 String msg =
  | 
      
      
         | 1817 | 
          | 
          | 
                   name + " attribute is required on " + source.getNodeName();
  | 
      
      
         | 1818 | 
          | 
          | 
                 DOMSourceLocator l = new DOMSourceLocator(source);
  | 
      
      
         | 1819 | 
          | 
          | 
                 throw new TransformerConfigurationException(msg, l);
  | 
      
      
         | 1820 | 
          | 
          | 
               }
  | 
      
      
         | 1821 | 
          | 
          | 
             return value;
  | 
      
      
         | 1822 | 
          | 
          | 
           }
  | 
      
      
         | 1823 | 
          | 
          | 
          
  | 
      
      
         | 1824 | 
          | 
          | 
           // Handle user data changes when nodes are cloned etc
  | 
      
      
         | 1825 | 
          | 
          | 
          
  | 
      
      
         | 1826 | 
          | 
          | 
           public void handle(short op, String key, Object data, Node src, Node dst)
  | 
      
      
         | 1827 | 
          | 
          | 
           {
  | 
      
      
         | 1828 | 
          | 
          | 
             dst.setUserData(key, data, this);
  | 
      
      
         | 1829 | 
          | 
          | 
           }
  | 
      
      
         | 1830 | 
          | 
          | 
          
  | 
      
      
         | 1831 | 
          | 
          | 
         }
  | 
      
      
         | 1832 | 
          | 
          | 
          
  |