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) ||
|