< prev index next >

src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/trax/TransformerImpl.java

Print this page
rev 1063 : 8172974: [JAXP] XALAN: Wrong result when transforming namespace unaware StAX Input
   1 /*
   2  * Copyright (c) 2007, 2016, Oracle and/or its affiliates. All rights reserved.
   3  */
   4 /*
   5  * Licensed to the Apache Software Foundation (ASF) under one or more
   6  * contributor license agreements.  See the NOTICE file distributed with
   7  * this work for additional information regarding copyright ownership.
   8  * The ASF licenses this file to You under the Apache License, Version 2.0
   9  * (the "License"); you may not use this file except in compliance with
  10  * the License.  You may obtain a copy of the License at
  11  *
  12  *     http://www.apache.org/licenses/LICENSE-2.0
  13  *
  14  * Unless required by applicable law or agreed to in writing, software
  15  * distributed under the License is distributed on an "AS IS" BASIS,
  16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  17  * See the License for the specific language governing permissions and
  18  * limitations under the License.
  19  */
  20 
  21 package com.sun.org.apache.xalan.internal.xsltc.trax;
  22 


  78 import javax.xml.transform.sax.SAXResult;
  79 import javax.xml.transform.sax.SAXSource;
  80 import javax.xml.transform.stax.StAXResult;
  81 import javax.xml.transform.stax.StAXSource;
  82 import javax.xml.transform.stream.StreamResult;
  83 import javax.xml.transform.stream.StreamSource;
  84 import jdk.xml.internal.JdkXmlFeatures;
  85 import jdk.xml.internal.JdkXmlUtils;
  86 import org.xml.sax.ContentHandler;
  87 import org.xml.sax.InputSource;
  88 import org.xml.sax.SAXException;
  89 import org.xml.sax.XMLReader;
  90 import org.xml.sax.ext.LexicalHandler;
  91 
  92 /**
  93  * @author Morten Jorgensen
  94  * @author G. Todd Miller
  95  * @author Santiago Pericas-Geertsen
  96  */
  97 public final class TransformerImpl extends Transformer
  98     implements DOMCache, ErrorListener
  99 {
 100 
 101     private final static String LEXICAL_HANDLER_PROPERTY =
 102         "http://xml.org/sax/properties/lexical-handler";
 103     private static final String NAMESPACE_FEATURE =
 104         "http://xml.org/sax/features/namespaces";
 105 
 106     /**
 107      * Namespace prefixes feature for {@link XMLReader}.
 108      */
 109     private static final String NAMESPACE_PREFIXES_FEATURE =
 110         "http://xml.org/sax/features/namespace-prefixes";
 111 
 112     /**
 113      * A reference to the translet or null if the identity transform.
 114      */
 115     private AbstractTranslet _translet = null;
 116 
 117     /**
 118      * The output method of this transformation.
 119      */
 120     private String _method = null;
 121 
 122     /**
 123      * The output encoding of this transformation.
 124      */


 143      * Output properties of this transformer instance.
 144      */
 145     private Properties _properties, _propertiesClone;
 146 
 147     /**
 148      * A reference to an output handler factory.
 149      */
 150     private TransletOutputHandlerFactory _tohFactory = null;
 151 
 152     /**
 153      * A reference to a internal DOM representation of the input.
 154      */
 155     private DOM _dom = null;
 156 
 157     /**
 158      * Number of indent spaces to add when indentation is on.
 159      */
 160     private int _indentNumber = -1;
 161 
 162     /**
 163      * A reference to the transformer factory that this templates
 164      * object belongs to.
 165      */
 166     private TransformerFactoryImpl _tfactory = null;
 167 
 168     /**
 169      * A reference to the output stream, if we create one in our code.
 170      */
 171     private OutputStream _ostream = null;
 172 
 173     /**
 174      * A reference to the XSLTCDTMManager which is used to build the DOM/DTM
 175      * for this transformer.
 176      */
 177     private XSLTCDTMManager _dtmManager = null;
 178 
 179     /**
 180      * A reference to an object that creates and caches XMLReader objects.
 181      */
 182     private XMLReaderManager _readerManager;
 183 
 184     /**
 185      * A flag indicating whether we use incremental building of the DTM.
 186      */
 187     //private boolean _isIncremental = false;
 188 
 189     /**
 190      * A flag indicating whether this transformer implements the identity
 191      * transform.
 192      */
 193     private boolean _isIdentity = false;
 194 
 195     /**
 196      * State of the secure processing feature.
 197      */
 198     private boolean _isSecureProcessing = false;
 199 
 200     /**
 201      * Indicates whether implementation parts should use
 202      *   service loader (or similar).
 203      * Note the default value (false) is the safe option..
 204      */
 205     private boolean _useServicesMechanism;

 206     /**
 207      * protocols allowed for external references set by the stylesheet processing instruction, Import and Include element.
 208      */
 209     private String _accessExternalStylesheet = XalanConstants.EXTERNAL_ACCESS_DEFAULT;
 210      /**
 211      * protocols allowed for external DTD references in source file and/or stylesheet.
 212      */
 213     private String _accessExternalDTD = XalanConstants.EXTERNAL_ACCESS_DEFAULT;
 214 
 215     private XMLSecurityManager _securityManager;

 216     /**
 217      * A map to store parameters for the identity transform. These
 218      * are not needed during the transformation, but we must keep track of
 219      * them to be fully complaint with the JAXP API.
 220      */
 221     private Map<String, Object> _parameters = null;
 222 
 223     // Catalog features
 224     CatalogFeatures _catalogFeatures;
 225     CatalogResolver _catalogUriResolver;
 226 
 227     // Catalog is enabled by default
 228     boolean _useCatalog = true;
 229 
 230     int _cdataChunkSize = JdkXmlUtils.CDATA_CHUNK_SIZE_DEFAULT;
 231 
 232     /**
 233      * This class wraps an ErrorListener into a MessageHandler in order to
 234      * capture messages reported via xsl:message.
 235      */
 236     static class MessageHandler
 237            extends com.sun.org.apache.xalan.internal.xsltc.runtime.MessageHandler
 238     {
 239         private ErrorListener _errorListener;
 240 
 241         public MessageHandler(ErrorListener errorListener) {
 242             _errorListener = errorListener;
 243         }
 244 
 245         @Override
 246         public void displayMessage(String msg) {
 247             if(_errorListener == null) {
 248                 System.err.println(msg);
 249             }
 250             else {
 251                 try {
 252                     _errorListener.warning(new TransformerException(msg));
 253                 }
 254                 catch (TransformerException e) {
 255                     // ignored
 256                 }
 257             }
 258         }
 259     }
 260 
 261     protected TransformerImpl(Properties outputProperties, int indentNumber,
 262         TransformerFactoryImpl tfactory)
 263     {
 264         this(null, outputProperties, indentNumber, tfactory);
 265         _isIdentity = true;
 266         // _properties.put(OutputKeys.METHOD, "xml");
 267     }
 268 
 269     protected TransformerImpl(Translet translet, Properties outputProperties,
 270         int indentNumber, TransformerFactoryImpl tfactory)
 271     {
 272         _translet = (AbstractTranslet) translet;
 273         _properties = createOutputProperties(outputProperties);
 274         _propertiesClone = (Properties) _properties.clone();
 275         _indentNumber = indentNumber;
 276         _tfactory = tfactory;
 277         _useServicesMechanism = _tfactory.useServicesMechnism();
 278         _accessExternalStylesheet = (String)_tfactory.getAttribute(XMLConstants.ACCESS_EXTERNAL_STYLESHEET);
 279         _accessExternalDTD = (String)_tfactory.getAttribute(XMLConstants.ACCESS_EXTERNAL_DTD);
 280         _securityManager = (XMLSecurityManager)_tfactory.getAttribute(XalanConstants.SECURITY_MANAGER);
 281         _readerManager = XMLReaderManager.getInstance(_useServicesMechanism);
 282         _readerManager.setProperty(XMLConstants.ACCESS_EXTERNAL_DTD, _accessExternalDTD);
 283         _readerManager.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, _isSecureProcessing);
 284         _readerManager.setProperty(XalanConstants.SECURITY_MANAGER, _securityManager);
 285         _cdataChunkSize = JdkXmlUtils.getValue(_tfactory.getAttribute(JdkXmlUtils.CDATA_CHUNK_SIZE),
 286                 JdkXmlUtils.CDATA_CHUNK_SIZE_DEFAULT);
 287         _readerManager.setProperty(JdkXmlUtils.CDATA_CHUNK_SIZE, _cdataChunkSize);
 288 
 289         _useCatalog = _tfactory.getFeature(XMLConstants.USE_CATALOG);
 290         if (_useCatalog) {
 291             _catalogFeatures = (CatalogFeatures)_tfactory.getAttribute(JdkXmlFeatures.CATALOG_FEATURES);
 292             String catalogFiles = _catalogFeatures.get(CatalogFeatures.Feature.DEFER);
 293             if (catalogFiles != null) {
 294                 _readerManager.setFeature(XMLConstants.USE_CATALOG, _useCatalog);
 295                 _readerManager.setProperty(JdkXmlFeatures.CATALOG_FEATURES, _catalogFeatures);
 296             }
 297         }
 298         //_isIncremental = tfactory._incremental;
 299     }
 300 
 301     /**
 302      * Return the state of the secure processing feature.
 303      */
 304     public boolean isSecureProcessing() {
 305         return _isSecureProcessing;
 306     }
 307 
 308     /**
 309      * Set the state of the secure processing feature.
 310      */
 311     public void setSecureProcessing(boolean flag) {
 312         _isSecureProcessing = flag;
 313         _readerManager.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, _isSecureProcessing);
 314     }
 315     /**
 316      * Return the state of the services mechanism feature.
 317      */
 318     public boolean useServicesMechnism() {


 579                          _tfactory.createNewDTMManagerInstance();
 580                      _dtmManager.setServicesMechnism(_useServicesMechanism);
 581                  }
 582                  dom = (DOM)_dtmManager.getDTM(source, false, wsfilter, true,
 583                                               false, false, 0, hasIdCall);
 584             } else if (_dom != null) {
 585                  dom = _dom;
 586                  _dom = null;  // use only once, so reset to 'null'
 587             } else {
 588                  return null;
 589             }
 590 
 591             if (!_isIdentity) {
 592                 // Give the translet the opportunity to make a prepass of
 593                 // the document, in case it can extract useful information early
 594                 _translet.prepassDocument(dom);
 595             }
 596 
 597             return dom;
 598 
 599         }
 600         catch (Exception e) {
 601             if (_errorListener != null) {
 602                 postErrorToListener(e.getMessage());
 603             }
 604             throw new TransformerException(e);
 605         }
 606     }
 607 
 608     /**
 609      * Returns the {@link com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl}
 610      * object that create this <code>Transformer</code>.
 611      */
 612     protected TransformerFactoryImpl getTransformerFactory() {
 613         return _tfactory;
 614     }
 615 
 616     /**
 617      * Returns the {@link com.sun.org.apache.xalan.internal.xsltc.runtime.output.TransletOutputHandlerFactory}
 618      * object that create the <code>TransletOutputHandler</code>.
 619      */
 620     protected TransletOutputHandlerFactory getTransletOutputHandlerFactory() {


 836         _errorListener = listener;
 837 
 838         // Register a message handler to report xsl:messages
 839     if (_translet != null)
 840         _translet.setMessageHandler(new MessageHandler(_errorListener));
 841     }
 842 
 843     /**
 844      * Inform TrAX error listener of an error
 845      */
 846     private void postErrorToListener(String message) {
 847         try {
 848             _errorListener.error(new TransformerException(message));
 849         }
 850         catch (TransformerException e) {
 851             // ignored - transformation cannot be continued
 852         }
 853     }
 854 
 855     /**
 856      * Inform TrAX error listener of a warning
 857      */
 858     private void postWarningToListener(String message) {
 859         try {
 860             _errorListener.warning(new TransformerException(message));
 861         }
 862         catch (TransformerException e) {
 863             // ignored - transformation cannot be continued
 864         }
 865     }
 866 
 867     /**
 868      * Implements JAXP's Transformer.getOutputProperties().
 869      * Returns a copy of the output properties for the transformation. This is
 870      * a set of layered properties. The first layer contains properties set by
 871      * calls to setOutputProperty() and setOutputProperties() on this class,
 872      * and the output settings defined in the stylesheet's <xsl:output>
 873      * element makes up the second level, while the default XSLT output
 874      * settings are returned on the third level.
 875      *
 876      * @return Properties in effect for this Transformer
 877      */
 878     @Override
 879     public Properties getOutputProperties() {
 880         return (Properties) _properties.clone();
 881     }
 882 
 883     /**
 884      * Implements JAXP's Transformer.getOutputProperty().
 885      * Get an output property that is in effect for the transformation. The
 886      * property specified may be a property that was set with setOutputProperty,
 887      * or it may be a property specified in the stylesheet.


 897             ErrorMsg err = new ErrorMsg(ErrorMsg.JAXP_UNKNOWN_PROP_ERR, name);
 898             throw new IllegalArgumentException(err.toString());
 899         }
 900         return _properties.getProperty(name);
 901     }
 902 
 903     /**
 904      * Implements JAXP's Transformer.setOutputProperties().
 905      * Set the output properties for the transformation. These properties
 906      * will override properties set in the Templates with xsl:output.
 907      * Unrecognised properties will be quitely ignored.
 908      *
 909      * @param properties The properties to use for the Transformer
 910      * @throws IllegalArgumentException Never, errors are ignored
 911      */
 912     @Override
 913     public void setOutputProperties(Properties properties)
 914         throws IllegalArgumentException
 915     {
 916         if (properties != null) {
 917             final Enumeration names = properties.propertyNames();
 918 
 919             while (names.hasMoreElements()) {
 920                 final String name = (String) names.nextElement();
 921 
 922                 // Ignore lower layer properties
 923                 if (isDefaultProperty(name, properties)) continue;
 924 
 925                 if (validOutputProperty(name)) {
 926                     _properties.setProperty(name, properties.getProperty(name));
 927                 }
 928                 else {
 929                     ErrorMsg err = new ErrorMsg(ErrorMsg.JAXP_UNKNOWN_PROP_ERR, name);
 930                     throw new IllegalArgumentException(err.toString());
 931                 }
 932             }
 933         }
 934         else {
 935             _properties = _propertiesClone;
 936         }
 937     }


 950     public void setOutputProperty(String name, String value)
 951         throws IllegalArgumentException
 952     {
 953         if (!validOutputProperty(name)) {
 954             ErrorMsg err = new ErrorMsg(ErrorMsg.JAXP_UNKNOWN_PROP_ERR, name);
 955             throw new IllegalArgumentException(err.toString());
 956         }
 957         _properties.setProperty(name, value);
 958     }
 959 
 960     /**
 961      * Internal method to pass any properties to the translet prior to
 962      * initiating the transformation
 963      */
 964     private void transferOutputProperties(AbstractTranslet translet)
 965     {
 966         // Return right now if no properties are set
 967         if (_properties == null) return;
 968 
 969         // Get a list of all the defined properties
 970         Enumeration names = _properties.propertyNames();
 971         while (names.hasMoreElements()) {
 972             // Note the use of get() instead of getProperty()
 973             String name  = (String) names.nextElement();
 974             String value = (String) _properties.get(name);
 975 
 976             // Ignore default properties
 977             if (value == null) continue;
 978 
 979             // Pass property value to translet - override previous setting
 980             if (name.equals(OutputKeys.ENCODING)) {
 981                 translet._encoding = value;
 982             }
 983             else if (name.equals(OutputKeys.METHOD)) {
 984                 translet._method = value;
 985             }
 986             else if (name.equals(OutputKeys.DOCTYPE_PUBLIC)) {
 987                 translet._doctypePublic = value;
 988             }
 989             else if (name.equals(OutputKeys.DOCTYPE_SYSTEM)) {
 990                 translet._doctypeSystem = value;


1029                  if (value != null && value.equals("yes")) {
1030                      translet._isStandalone = true;
1031                  }
1032             }
1033         }
1034     }
1035 
1036     /**
1037      * This method is used to pass any properties to the output handler
1038      * when running the identity transform.
1039      */
1040     public void transferOutputProperties(SerializationHandler handler)
1041     {
1042         // Return right now if no properties are set
1043         if (_properties == null) return;
1044 
1045         String doctypePublic = null;
1046         String doctypeSystem = null;
1047 
1048         // Get a list of all the defined properties
1049         Enumeration names = _properties.propertyNames();
1050         while (names.hasMoreElements()) {
1051             // Note the use of get() instead of getProperty()
1052             String name  = (String) names.nextElement();
1053             String value = (String) _properties.get(name);
1054 
1055             // Ignore default properties
1056             if (value == null) continue;
1057 
1058             // Pass property value to translet - override previous setting
1059             if (name.equals(OutputKeys.DOCTYPE_PUBLIC)) {
1060                 doctypePublic = value;
1061             }
1062             else if (name.equals(OutputKeys.DOCTYPE_SYSTEM)) {
1063                 doctypeSystem = value;
1064             }
1065             else if (name.equals(OutputKeys.MEDIA_TYPE)) {
1066                 handler.setMediaType(value);
1067             }
1068             else if (name.equals(OutputKeys.STANDALONE)) {
1069                 handler.setStandalone(value);


1130 
1131         // Call setDoctype() if needed
1132         if (doctypePublic != null || doctypeSystem != null) {
1133             handler.setDoctype(doctypeSystem, doctypePublic);
1134         }
1135     }
1136 
1137     /**
1138      * Internal method to create the initial set of properties. There
1139      * are two layers of properties: the default layer and the base layer.
1140      * The latter contains properties defined in the stylesheet or by
1141      * the user using this API.
1142      */
1143     private Properties createOutputProperties(Properties outputProperties) {
1144         final Properties defaults = new Properties();
1145         setDefaults(defaults, "xml");
1146 
1147         // Copy propeties set in stylesheet to base
1148         final Properties base = new Properties(defaults);
1149         if (outputProperties != null) {
1150             final Enumeration names = outputProperties.propertyNames();
1151             while (names.hasMoreElements()) {
1152                 final String name = (String) names.nextElement();
1153                 base.setProperty(name, outputProperties.getProperty(name));
1154             }
1155         }
1156         else {
1157             base.setProperty(OutputKeys.ENCODING, _translet._encoding);
1158             if (_translet._method != null)
1159                 base.setProperty(OutputKeys.METHOD, _translet._method);
1160         }
1161 
1162         // Update defaults based on output method
1163         final String method = base.getProperty(OutputKeys.METHOD);
1164         if (method != null) {
1165             if (method.equals("html")) {
1166                 setDefaults(defaults,"html");
1167             }
1168             else if (method.equals("text")) {
1169                 setDefaults(defaults,"text");
1170             }
1171         }
1172 
1173         return base;
1174     }
1175 
1176         /**
1177          * Internal method to get the default properties from the
1178          * serializer factory and set them on the property object.
1179          * @param props a java.util.Property object on which the properties are set.
1180          * @param method The output method type, one of "xml", "text", "html" ...
1181          */
1182         private void setDefaults(Properties props, String method)
1183         {
1184                 final Properties method_props =
1185                         OutputPropertiesFactory.getDefaultMethodProperties(method);
1186                 {
1187                         final Enumeration names = method_props.propertyNames();
1188                         while (names.hasMoreElements())
1189                         {
1190                                 final String name = (String)names.nextElement();
1191                                 props.setProperty(name, method_props.getProperty(name));
1192                         }
1193                 }
1194         }
1195     /**
1196      * Verifies if a given output property name is a property defined in
1197      * the JAXP 1.1 / TrAX spec
1198      */
1199     private boolean validOutputProperty(String name) {
1200         return (name.equals(OutputKeys.ENCODING) ||
1201                 name.equals(OutputKeys.METHOD) ||
1202                 name.equals(OutputKeys.INDENT) ||
1203                 name.equals(OutputKeys.DOCTYPE_PUBLIC) ||
1204                 name.equals(OutputKeys.DOCTYPE_SYSTEM) ||
1205                 name.equals(OutputKeys.CDATA_SECTION_ELEMENTS) ||
1206                 name.equals(OutputKeys.MEDIA_TYPE) ||
1207                 name.equals(OutputKeys.OMIT_XML_DECLARATION)   ||


   1 /*
   2  * Copyright (c) 2007, 2017, Oracle and/or its affiliates. All rights reserved.
   3  */
   4 /*
   5  * Licensed to the Apache Software Foundation (ASF) under one or more
   6  * contributor license agreements.  See the NOTICE file distributed with
   7  * this work for additional information regarding copyright ownership.
   8  * The ASF licenses this file to You under the Apache License, Version 2.0
   9  * (the "License"); you may not use this file except in compliance with
  10  * the License.  You may obtain a copy of the License at
  11  *
  12  *     http://www.apache.org/licenses/LICENSE-2.0
  13  *
  14  * Unless required by applicable law or agreed to in writing, software
  15  * distributed under the License is distributed on an "AS IS" BASIS,
  16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  17  * See the License for the specific language governing permissions and
  18  * limitations under the License.
  19  */
  20 
  21 package com.sun.org.apache.xalan.internal.xsltc.trax;
  22 


  78 import javax.xml.transform.sax.SAXResult;
  79 import javax.xml.transform.sax.SAXSource;
  80 import javax.xml.transform.stax.StAXResult;
  81 import javax.xml.transform.stax.StAXSource;
  82 import javax.xml.transform.stream.StreamResult;
  83 import javax.xml.transform.stream.StreamSource;
  84 import jdk.xml.internal.JdkXmlFeatures;
  85 import jdk.xml.internal.JdkXmlUtils;
  86 import org.xml.sax.ContentHandler;
  87 import org.xml.sax.InputSource;
  88 import org.xml.sax.SAXException;
  89 import org.xml.sax.XMLReader;
  90 import org.xml.sax.ext.LexicalHandler;
  91 
  92 /**
  93  * @author Morten Jorgensen
  94  * @author G. Todd Miller
  95  * @author Santiago Pericas-Geertsen
  96  */
  97 public final class TransformerImpl extends Transformer
  98     implements DOMCache, ErrorListener {

  99 
 100     private final static String LEXICAL_HANDLER_PROPERTY =
 101         "http://xml.org/sax/properties/lexical-handler";


 102 
 103     /**
 104      * Namespace prefixes feature for {@link XMLReader}.
 105      */
 106     private static final String NAMESPACE_PREFIXES_FEATURE =
 107         "http://xml.org/sax/features/namespace-prefixes";
 108 
 109     /**
 110      * A reference to the translet or null if the identity transform.
 111      */
 112     private AbstractTranslet _translet = null;
 113 
 114     /**
 115      * The output method of this transformation.
 116      */
 117     private String _method = null;
 118 
 119     /**
 120      * The output encoding of this transformation.
 121      */


 140      * Output properties of this transformer instance.
 141      */
 142     private Properties _properties, _propertiesClone;
 143 
 144     /**
 145      * A reference to an output handler factory.
 146      */
 147     private TransletOutputHandlerFactory _tohFactory = null;
 148 
 149     /**
 150      * A reference to a internal DOM representation of the input.
 151      */
 152     private DOM _dom = null;
 153 
 154     /**
 155      * Number of indent spaces to add when indentation is on.
 156      */
 157     private int _indentNumber = -1;
 158 
 159     /**
 160      * A reference to the transformer factory that this transformer
 161      * object belongs to.
 162      */
 163     private TransformerFactoryImpl _tfactory = null;
 164 
 165     /**
 166      * A reference to the output stream, if we create one in our code.
 167      */
 168     private OutputStream _ostream = null;
 169 
 170     /**
 171      * A reference to the XSLTCDTMManager which is used to build the DOM/DTM
 172      * for this transformer.
 173      */
 174     private XSLTCDTMManager _dtmManager = null;
 175 
 176     /**
 177      * A reference to an object that creates and caches XMLReader objects.
 178      */
 179     private XMLReaderManager _readerManager;
 180 
 181     /**





 182      * A flag indicating whether this transformer implements the identity
 183      * transform.
 184      */
 185     private boolean _isIdentity = false;
 186 
 187     /**
 188      * State of the secure processing feature.
 189      */
 190     private boolean _isSecureProcessing = false;
 191 
 192     /**
 193      * Indicates whether implementation parts should use
 194      *   service loader (or similar).
 195      * Note the default value (false) is the safe option.
 196      */
 197     private boolean _useServicesMechanism;
 198 
 199     /**




 200      * protocols allowed for external DTD references in source file and/or stylesheet.
 201      */
 202     private String _accessExternalDTD = XalanConstants.EXTERNAL_ACCESS_DEFAULT;
 203 
 204     private XMLSecurityManager _securityManager;
 205 
 206     /**
 207      * A map to store parameters for the identity transform. These
 208      * are not needed during the transformation, but we must keep track of
 209      * them to be fully complaint with the JAXP API.
 210      */
 211     private Map<String, Object> _parameters = null;
 212 
 213     // Catalog features
 214     CatalogFeatures _catalogFeatures;
 215     CatalogResolver _catalogUriResolver;
 216 
 217     // Catalog is enabled by default
 218     boolean _useCatalog = true;
 219 
 220     int _cdataChunkSize = JdkXmlUtils.CDATA_CHUNK_SIZE_DEFAULT;
 221 
 222     /**
 223      * This class wraps an ErrorListener into a MessageHandler in order to
 224      * capture messages reported via xsl:message.
 225      */
 226     static class MessageHandler
 227            extends com.sun.org.apache.xalan.internal.xsltc.runtime.MessageHandler
 228     {
 229         private ErrorListener _errorListener;
 230 
 231         public MessageHandler(ErrorListener errorListener) {
 232             _errorListener = errorListener;
 233         }
 234 
 235         @Override
 236         public void displayMessage(String msg) {
 237             if(_errorListener == null) {
 238                 System.err.println(msg);
 239             } else {

 240                 try {
 241                     _errorListener.warning(new TransformerException(msg));
 242                 }
 243                 catch (TransformerException e) {
 244                     // ignored
 245                 }
 246             }
 247         }
 248     }
 249 
 250     protected TransformerImpl(Properties outputProperties, int indentNumber,
 251         TransformerFactoryImpl tfactory)
 252     {
 253         this(null, outputProperties, indentNumber, tfactory);
 254         _isIdentity = true;

 255     }
 256 
 257     protected TransformerImpl(Translet translet, Properties outputProperties,
 258         int indentNumber, TransformerFactoryImpl tfactory)
 259     {
 260         _translet = (AbstractTranslet) translet;
 261         _properties = createOutputProperties(outputProperties);
 262         _propertiesClone = (Properties) _properties.clone();
 263         _indentNumber = indentNumber;
 264         _tfactory = tfactory;
 265         _useServicesMechanism = _tfactory.useServicesMechnism();

 266         _accessExternalDTD = (String)_tfactory.getAttribute(XMLConstants.ACCESS_EXTERNAL_DTD);
 267         _securityManager = (XMLSecurityManager)_tfactory.getAttribute(XalanConstants.SECURITY_MANAGER);
 268         _readerManager = XMLReaderManager.getInstance(_useServicesMechanism);
 269         _readerManager.setProperty(XMLConstants.ACCESS_EXTERNAL_DTD, _accessExternalDTD);
 270         _readerManager.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, _isSecureProcessing);
 271         _readerManager.setProperty(XalanConstants.SECURITY_MANAGER, _securityManager);
 272         _cdataChunkSize = JdkXmlUtils.getValue(_tfactory.getAttribute(JdkXmlUtils.CDATA_CHUNK_SIZE),
 273                 JdkXmlUtils.CDATA_CHUNK_SIZE_DEFAULT);
 274         _readerManager.setProperty(JdkXmlUtils.CDATA_CHUNK_SIZE, _cdataChunkSize);
 275 
 276         _useCatalog = _tfactory.getFeature(XMLConstants.USE_CATALOG);
 277         if (_useCatalog) {
 278             _catalogFeatures = (CatalogFeatures)_tfactory.getAttribute(JdkXmlFeatures.CATALOG_FEATURES);
 279             String catalogFiles = _catalogFeatures.get(CatalogFeatures.Feature.DEFER);
 280             if (catalogFiles != null) {
 281                 _readerManager.setFeature(XMLConstants.USE_CATALOG, _useCatalog);
 282                 _readerManager.setProperty(JdkXmlFeatures.CATALOG_FEATURES, _catalogFeatures);
 283             }
 284         }

 285     }
 286 
 287     /**
 288      * Return the state of the secure processing feature.
 289      */
 290     public boolean isSecureProcessing() {
 291         return _isSecureProcessing;
 292     }
 293 
 294     /**
 295      * Set the state of the secure processing feature.
 296      */
 297     public void setSecureProcessing(boolean flag) {
 298         _isSecureProcessing = flag;
 299         _readerManager.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, _isSecureProcessing);
 300     }
 301     /**
 302      * Return the state of the services mechanism feature.
 303      */
 304     public boolean useServicesMechnism() {


 565                          _tfactory.createNewDTMManagerInstance();
 566                      _dtmManager.setServicesMechnism(_useServicesMechanism);
 567                  }
 568                  dom = (DOM)_dtmManager.getDTM(source, false, wsfilter, true,
 569                                               false, false, 0, hasIdCall);
 570             } else if (_dom != null) {
 571                  dom = _dom;
 572                  _dom = null;  // use only once, so reset to 'null'
 573             } else {
 574                  return null;
 575             }
 576 
 577             if (!_isIdentity) {
 578                 // Give the translet the opportunity to make a prepass of
 579                 // the document, in case it can extract useful information early
 580                 _translet.prepassDocument(dom);
 581             }
 582 
 583             return dom;
 584 
 585         } catch (Exception e) {

 586             if (_errorListener != null) {
 587                 postErrorToListener(e.getMessage());
 588             }
 589             throw new TransformerException(e);
 590         }
 591     }
 592 
 593     /**
 594      * Returns the {@link com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl}
 595      * object that create this <code>Transformer</code>.
 596      */
 597     protected TransformerFactoryImpl getTransformerFactory() {
 598         return _tfactory;
 599     }
 600 
 601     /**
 602      * Returns the {@link com.sun.org.apache.xalan.internal.xsltc.runtime.output.TransletOutputHandlerFactory}
 603      * object that create the <code>TransletOutputHandler</code>.
 604      */
 605     protected TransletOutputHandlerFactory getTransletOutputHandlerFactory() {


 821         _errorListener = listener;
 822 
 823         // Register a message handler to report xsl:messages
 824     if (_translet != null)
 825         _translet.setMessageHandler(new MessageHandler(_errorListener));
 826     }
 827 
 828     /**
 829      * Inform TrAX error listener of an error
 830      */
 831     private void postErrorToListener(String message) {
 832         try {
 833             _errorListener.error(new TransformerException(message));
 834         }
 835         catch (TransformerException e) {
 836             // ignored - transformation cannot be continued
 837         }
 838     }
 839 
 840     /**












 841      * Implements JAXP's Transformer.getOutputProperties().
 842      * Returns a copy of the output properties for the transformation. This is
 843      * a set of layered properties. The first layer contains properties set by
 844      * calls to setOutputProperty() and setOutputProperties() on this class,
 845      * and the output settings defined in the stylesheet's <xsl:output>
 846      * element makes up the second level, while the default XSLT output
 847      * settings are returned on the third level.
 848      *
 849      * @return Properties in effect for this Transformer
 850      */
 851     @Override
 852     public Properties getOutputProperties() {
 853         return (Properties) _properties.clone();
 854     }
 855 
 856     /**
 857      * Implements JAXP's Transformer.getOutputProperty().
 858      * Get an output property that is in effect for the transformation. The
 859      * property specified may be a property that was set with setOutputProperty,
 860      * or it may be a property specified in the stylesheet.


 870             ErrorMsg err = new ErrorMsg(ErrorMsg.JAXP_UNKNOWN_PROP_ERR, name);
 871             throw new IllegalArgumentException(err.toString());
 872         }
 873         return _properties.getProperty(name);
 874     }
 875 
 876     /**
 877      * Implements JAXP's Transformer.setOutputProperties().
 878      * Set the output properties for the transformation. These properties
 879      * will override properties set in the Templates with xsl:output.
 880      * Unrecognised properties will be quitely ignored.
 881      *
 882      * @param properties The properties to use for the Transformer
 883      * @throws IllegalArgumentException Never, errors are ignored
 884      */
 885     @Override
 886     public void setOutputProperties(Properties properties)
 887         throws IllegalArgumentException
 888     {
 889         if (properties != null) {
 890             final Enumeration<?> names = properties.propertyNames();
 891 
 892             while (names.hasMoreElements()) {
 893                 final String name = (String) names.nextElement();
 894 
 895                 // Ignore lower layer properties
 896                 if (isDefaultProperty(name, properties)) continue;
 897 
 898                 if (validOutputProperty(name)) {
 899                     _properties.setProperty(name, properties.getProperty(name));
 900                 }
 901                 else {
 902                     ErrorMsg err = new ErrorMsg(ErrorMsg.JAXP_UNKNOWN_PROP_ERR, name);
 903                     throw new IllegalArgumentException(err.toString());
 904                 }
 905             }
 906         }
 907         else {
 908             _properties = _propertiesClone;
 909         }
 910     }


 923     public void setOutputProperty(String name, String value)
 924         throws IllegalArgumentException
 925     {
 926         if (!validOutputProperty(name)) {
 927             ErrorMsg err = new ErrorMsg(ErrorMsg.JAXP_UNKNOWN_PROP_ERR, name);
 928             throw new IllegalArgumentException(err.toString());
 929         }
 930         _properties.setProperty(name, value);
 931     }
 932 
 933     /**
 934      * Internal method to pass any properties to the translet prior to
 935      * initiating the transformation
 936      */
 937     private void transferOutputProperties(AbstractTranslet translet)
 938     {
 939         // Return right now if no properties are set
 940         if (_properties == null) return;
 941 
 942         // Get a list of all the defined properties
 943         Enumeration<?> names = _properties.propertyNames();
 944         while (names.hasMoreElements()) {
 945             // Note the use of get() instead of getProperty()
 946             String name  = (String) names.nextElement();
 947             String value = (String) _properties.get(name);
 948 
 949             // Ignore default properties
 950             if (value == null) continue;
 951 
 952             // Pass property value to translet - override previous setting
 953             if (name.equals(OutputKeys.ENCODING)) {
 954                 translet._encoding = value;
 955             }
 956             else if (name.equals(OutputKeys.METHOD)) {
 957                 translet._method = value;
 958             }
 959             else if (name.equals(OutputKeys.DOCTYPE_PUBLIC)) {
 960                 translet._doctypePublic = value;
 961             }
 962             else if (name.equals(OutputKeys.DOCTYPE_SYSTEM)) {
 963                 translet._doctypeSystem = value;


1002                  if (value != null && value.equals("yes")) {
1003                      translet._isStandalone = true;
1004                  }
1005             }
1006         }
1007     }
1008 
1009     /**
1010      * This method is used to pass any properties to the output handler
1011      * when running the identity transform.
1012      */
1013     public void transferOutputProperties(SerializationHandler handler)
1014     {
1015         // Return right now if no properties are set
1016         if (_properties == null) return;
1017 
1018         String doctypePublic = null;
1019         String doctypeSystem = null;
1020 
1021         // Get a list of all the defined properties
1022         Enumeration<?> names = _properties.propertyNames();
1023         while (names.hasMoreElements()) {
1024             // Note the use of get() instead of getProperty()
1025             String name  = (String) names.nextElement();
1026             String value = (String) _properties.get(name);
1027 
1028             // Ignore default properties
1029             if (value == null) continue;
1030 
1031             // Pass property value to translet - override previous setting
1032             if (name.equals(OutputKeys.DOCTYPE_PUBLIC)) {
1033                 doctypePublic = value;
1034             }
1035             else if (name.equals(OutputKeys.DOCTYPE_SYSTEM)) {
1036                 doctypeSystem = value;
1037             }
1038             else if (name.equals(OutputKeys.MEDIA_TYPE)) {
1039                 handler.setMediaType(value);
1040             }
1041             else if (name.equals(OutputKeys.STANDALONE)) {
1042                 handler.setStandalone(value);


1103 
1104         // Call setDoctype() if needed
1105         if (doctypePublic != null || doctypeSystem != null) {
1106             handler.setDoctype(doctypeSystem, doctypePublic);
1107         }
1108     }
1109 
1110     /**
1111      * Internal method to create the initial set of properties. There
1112      * are two layers of properties: the default layer and the base layer.
1113      * The latter contains properties defined in the stylesheet or by
1114      * the user using this API.
1115      */
1116     private Properties createOutputProperties(Properties outputProperties) {
1117         final Properties defaults = new Properties();
1118         setDefaults(defaults, "xml");
1119 
1120         // Copy propeties set in stylesheet to base
1121         final Properties base = new Properties(defaults);
1122         if (outputProperties != null) {
1123             final Enumeration<?> names = outputProperties.propertyNames();
1124             while (names.hasMoreElements()) {
1125                 final String name = (String) names.nextElement();
1126                 base.setProperty(name, outputProperties.getProperty(name));
1127             }
1128         }
1129         else {
1130             base.setProperty(OutputKeys.ENCODING, _translet._encoding);
1131             if (_translet._method != null)
1132                 base.setProperty(OutputKeys.METHOD, _translet._method);
1133         }
1134 
1135         // Update defaults based on output method
1136         final String method = base.getProperty(OutputKeys.METHOD);
1137         if (method != null) {
1138             if (method.equals("html")) {
1139                 setDefaults(defaults,"html");
1140             }
1141             else if (method.equals("text")) {
1142                 setDefaults(defaults,"text");
1143             }
1144         }
1145 
1146         return base;
1147     }
1148 
1149         /**
1150          * Internal method to get the default properties from the
1151          * serializer factory and set them on the property object.
1152          * @param props a java.util.Property object on which the properties are set.
1153          * @param method The output method type, one of "xml", "text", "html" ...
1154          */
1155         private void setDefaults(Properties props, String method)
1156         {
1157                 final Properties method_props =
1158                         OutputPropertiesFactory.getDefaultMethodProperties(method);
1159                 {
1160                         final Enumeration<?> names = method_props.propertyNames();
1161                         while (names.hasMoreElements())
1162                         {
1163                                 final String name = (String)names.nextElement();
1164                                 props.setProperty(name, method_props.getProperty(name));
1165                         }
1166                 }
1167         }
1168     /**
1169      * Verifies if a given output property name is a property defined in
1170      * the JAXP 1.1 / TrAX spec
1171      */
1172     private boolean validOutputProperty(String name) {
1173         return (name.equals(OutputKeys.ENCODING) ||
1174                 name.equals(OutputKeys.METHOD) ||
1175                 name.equals(OutputKeys.INDENT) ||
1176                 name.equals(OutputKeys.DOCTYPE_PUBLIC) ||
1177                 name.equals(OutputKeys.DOCTYPE_SYSTEM) ||
1178                 name.equals(OutputKeys.CDATA_SECTION_ELEMENTS) ||
1179                 name.equals(OutputKeys.MEDIA_TYPE) ||
1180                 name.equals(OutputKeys.OMIT_XML_DECLARATION)   ||


< prev index next >