1 /* 2 * Copyright (c) 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.xml.internal.serializer; 22 23 import com.sun.org.apache.xml.internal.serializer.utils.MsgKey; 24 import com.sun.org.apache.xml.internal.serializer.utils.Utils; 25 import com.sun.org.apache.xml.internal.serializer.utils.WrappedRuntimeException; 26 import java.io.BufferedInputStream; 27 import java.io.IOException; 28 import java.io.InputStream; 29 import java.security.AccessController; 30 import java.security.PrivilegedAction; 31 import java.util.Enumeration; 32 import java.util.Properties; 33 import javax.xml.transform.OutputKeys; 34 import jdk.xml.internal.SecuritySupport; 35 36 /** 37 * This class is a factory to generate a set of default properties 38 * of key/value pairs that are used to create a serializer through the 39 * factory {@link SerializerFactory SerilizerFactory}. 40 * The properties generated by this factory 41 * may be modified to non-default values before the SerializerFactory is used to 42 * create a Serializer. 43 * <p> 44 * The given output types supported are "xml", "text", and "html". 45 * These type strings can be obtained from the 46 * {@link Method Method} class in this package. 47 * <p> 48 * Other constants defined in this class are the non-standard property keys 49 * that can be used to set non-standard property values on a java.util.Properties object 50 * that is used to create or configure a serializer. Here are the non-standard keys: 51 * <ul> 52 * <li> <b>S_KEY_INDENT_AMOUNT </b> - 53 * The non-standard property key to use to set the indentation amount. 54 * The "indent" key needs to have a value of "yes", and this 55 * properties value is a the number of whitespaces to indent by per 56 * indentation level. 57 * 58 * <li> <b>S_KEY_CONTENT_HANDLER </b> - 59 * This non-standard property key is used to set the name of the fully qualified 60 * Java class that implements the ContentHandler interface. 61 * The output of the serializer will be SAX events sent to this an 62 * object of this class. 63 * 64 * <li> <b>S_KEY_ENTITIES </b> - 65 * This non-standard property key is used to specify the name of the property file 66 * that specifies character to entity reference mappings. A line in such a 67 * file is has the name of the entity and the numeric (base 10) value 68 * of the corresponding character, like this one: <br> quot=34 <br> 69 * 70 * <li> <b>S_USE_URL_ESCAPING </b> - 71 * This non-standard property key is used to set a value of "yes" if the href values for HTML serialization should 72 * use %xx escaping. 73 * 74 * <li> <b>S_OMIT_META_TAG </b> - 75 * This non-standard property key is used to set a value of "yes" if the META tag should be omitted where it would 76 * otherwise be supplied. 77 * </ul> 78 * 79 * @see SerializerFactory 80 * @see Method 81 * @see Serializer 82 * @LastModified: Oct 2017 83 */ 84 public final class OutputPropertiesFactory 85 { 86 /** S_BUILTIN_EXTENSIONS_URL is a mnemonic for the XML Namespace 87 *(http://xml.apache.org/xalan) predefined to signify Xalan's 88 * built-in XSLT Extensions. When used in stylesheets, this is often 89 * bound to the "xalan:" prefix. 90 */ 91 private static final String 92 S_BUILTIN_EXTENSIONS_URL = "http://xml.apache.org/xalan"; 93 94 /** 95 * The old built-in extension url. It is still supported for 96 * backward compatibility. 97 */ 98 private static final String 99 S_BUILTIN_OLD_EXTENSIONS_URL = "http://xml.apache.org/xslt"; 100 101 //************************************************************ 102 //* PUBLIC CONSTANTS 130 S_BUILTIN_EXTENSIONS_UNIVERSAL + "line-separator"; 131 132 /** This non-standard property key is used to set the name of the fully qualified 133 * Java class that implements the ContentHandler interface. 134 * Fully qualified name of class with a default constructor that 135 * implements the ContentHandler interface, where the result tree events 136 * will be sent to. 137 */ 138 139 public static final String S_KEY_CONTENT_HANDLER = 140 S_BUILTIN_EXTENSIONS_UNIVERSAL + "content-handler"; 141 142 /** 143 * This non-standard property key is used to specify the name of the property file 144 * that specifies character to entity reference mappings. 145 */ 146 public static final String S_KEY_ENTITIES = 147 S_BUILTIN_EXTENSIONS_UNIVERSAL + "entities"; 148 149 /** 150 * This non-standard property key is used to set a value of "yes" if the href values for HTML serialization should 151 * use %xx escaping. */ 152 public static final String S_USE_URL_ESCAPING = 153 S_BUILTIN_EXTENSIONS_UNIVERSAL + "use-url-escaping"; 154 155 /** 156 * This non-standard property key is used to set a value of "yes" if the META tag should be omitted where it would 157 * otherwise be supplied. 158 */ 159 public static final String S_OMIT_META_TAG = 160 S_BUILTIN_EXTENSIONS_UNIVERSAL + "omit-meta-tag"; 161 162 /** 163 * The old built-in extension namespace, this is not a public API. 164 */ 165 public static final String S_BUILTIN_OLD_EXTENSIONS_UNIVERSAL = 166 "{" + S_BUILTIN_OLD_EXTENSIONS_URL + "}"; 167 168 /** 169 * This is not a public API, it is only public because it is used 170 * by outside of this package, 171 * it is the length of the old built-in extension namespace. 172 */ 173 public static final int S_BUILTIN_OLD_EXTENSIONS_UNIVERSAL_LEN = 174 S_BUILTIN_OLD_EXTENSIONS_UNIVERSAL.length(); 175 176 /** 177 * This non-standard, Oracle-impl only property key is used as if OutputKeys.STANDALONE is specified but 178 * without writing it out in the declaration; It can be used to reverse the change by Xalan patch 1495. 179 * Since Xalan patch 1495 can cause incompatible behavior, this property is add for application to neutralize 180 * the effect of Xalan patch 1495 181 */ 182 /** 183 * <p>Is Standalone</p> 184 * 185 * <ul> 186 * <li> 187 * <code>yes</code> to indicate the output is intended to be used as standalone 188 * </li> 189 * <li> 190 * <code>no</code> has no effect. 191 * </li> 192 * </ul> 193 */ 194 public static final String ORACLE_IS_STANDALONE = "http://www.oracle.com/xml/is-standalone"; 195 196 //************************************************************ 197 //* PRIVATE CONSTANTS 198 //************************************************************ 199 200 private static final String S_XSLT_PREFIX = "xslt.output."; 201 private static final int S_XSLT_PREFIX_LEN = S_XSLT_PREFIX.length(); 202 private static final String S_XALAN_PREFIX = "org.apache.xslt."; 203 private static final int S_XALAN_PREFIX_LEN = S_XALAN_PREFIX.length(); 204 205 /** Synchronization object for lazy initialization of the above tables. */ 206 private static final Object m_synch_object = new Object(); 207 208 /** the directory in which the various method property files are located */ 209 private static final String PROP_DIR = "com/sun/org/apache/xml/internal/serializer/"; 210 /** property file for default XML properties */ 211 private static final String PROP_FILE_XML = "output_xml.properties"; 212 /** property file for default TEXT properties */ 213 private static final String PROP_FILE_TEXT = "output_text.properties"; 214 /** property file for default HTML properties */ 215 private static final String PROP_FILE_HTML = "output_html.properties"; 216 /** property file for default UNKNOWN (Either XML or HTML, to be determined later) properties */ 217 private static final String PROP_FILE_UNKNOWN = "output_unknown.properties"; 218 219 //************************************************************ 220 //* PRIVATE STATIC FIELDS 221 //************************************************************ 222 223 /** The default properties of all output files. */ 224 private static Properties m_xml_properties = null; 225 226 /** The default properties when method="html". */ 227 private static Properties m_html_properties = null; 228 229 /** The default properties when method="text". */ 230 private static Properties m_text_properties = null; 231 232 /** The properties when method="" for the "unknown" wrapper */ 233 private static Properties m_unknown_properties = null; 234 235 private static final Class<?> 236 ACCESS_CONTROLLER_CLASS = findAccessControllerClass(); 237 238 private static Class<?> findAccessControllerClass() { 239 try 240 { 241 // This Class was introduced in JDK 1.2. With the re-architecture of 242 // security mechanism ( starting in JDK 1.2 ), we have option of 243 // giving privileges to certain part of code using doPrivileged block. 244 // In JDK1.1.X applications won't be having security manager and if 245 // there is security manager ( in applets ), code need to be signed 246 // and trusted for having access to resources. 247 248 return Class.forName("java.security.AccessController"); 249 } 250 catch (Exception e) 251 { 252 //User may be using older JDK ( JDK <1.2 ). Allow him/her to use it. 253 // But don't try to use doPrivileged 254 } 255 256 return null; 257 } 258 259 /** 260 * Creates an empty OutputProperties with the property key/value defaults specified by 261 * a property file. The method argument is used to construct a string of 262 * the form output_[method].properties (for instance, output_html.properties). 263 * The output_xml.properties file is always used as the base. 264 * 265 * <p>Anything other than 'text', 'xml', and 'html', will 266 * use the output_xml.properties file.</p> 267 * 268 * @param method non-null reference to method name. 269 * 270 * @return Properties object that holds the defaults for the given method. 271 */ 272 static public final Properties getDefaultMethodProperties(String method) 273 { 274 String fileName = null; 275 Properties defaultProperties = null; 276 // According to this article : Double-check locking does not work 277 // http://www.javaworld.com/javaworld/jw-02-2001/jw-0209-toolbox.html 278 try 279 { 280 synchronized (m_synch_object) 281 { 282 if (null == m_xml_properties) // double check 283 { 284 fileName = PROP_FILE_XML; 285 m_xml_properties = loadPropertiesFile(fileName, null); 286 } 287 } 288 289 if (method.equals(Method.XML)) 290 { 291 defaultProperties = m_xml_properties; 292 } 293 else if (method.equals(Method.HTML)) 294 { 295 if (null == m_html_properties) // double check 296 { 297 fileName = PROP_FILE_HTML; 298 m_html_properties = 299 loadPropertiesFile(fileName, m_xml_properties); 300 } 301 302 defaultProperties = m_html_properties; 303 } 304 else if (method.equals(Method.TEXT)) 305 { 306 if (null == m_text_properties) // double check 307 { 308 fileName = PROP_FILE_TEXT; 309 m_text_properties = 310 loadPropertiesFile(fileName, m_xml_properties); 311 if (null 312 == m_text_properties.getProperty(OutputKeys.ENCODING)) 313 { 314 String mimeEncoding = Encodings.getMimeEncoding(null); 315 m_text_properties.put( 316 OutputKeys.ENCODING, 317 mimeEncoding); 318 } 319 } 320 321 defaultProperties = m_text_properties; 322 } 323 else if (method.equals(com.sun.org.apache.xml.internal.serializer.Method.UNKNOWN)) 324 { 325 if (null == m_unknown_properties) // double check 326 { 327 fileName = PROP_FILE_UNKNOWN; 328 m_unknown_properties = 329 loadPropertiesFile(fileName, m_xml_properties); 330 } 331 332 defaultProperties = m_unknown_properties; 333 } 334 else 335 { 336 // TODO: Calculate res file from name. 337 defaultProperties = m_xml_properties; 338 } 339 } 340 catch (IOException ioe) 341 { 342 throw new WrappedRuntimeException( 343 Utils.messages.createMessage( 344 MsgKey.ER_COULD_NOT_LOAD_METHOD_PROPERTY, 345 new Object[] { fileName, method }), 346 ioe); 347 } 348 // wrap these cached defaultProperties in a new Property object just so 349 // that the caller of this method can't modify the default values 350 return new Properties(defaultProperties); 351 } 352 353 /** 354 * Load the properties file from a resource stream. If a 355 * key name such as "org.apache.xslt.xxx", fix up the start of 356 * string to be a curly namespace. If a key name starts with 357 * "xslt.output.xxx", clip off "xslt.output.". If a key name *or* a 358 * key value is discovered, check for \u003a in the text, and 359 * fix it up to be ":", since earlier versions of the JDK do not 360 * handle the escape sequence (at least in key names). 361 * 362 * @param resourceName non-null reference to resource name. 363 * @param defaults Default properties, which may be null. 364 */ 365 static private Properties loadPropertiesFile( 366 final String resourceName, 367 Properties defaults) 368 throws IOException 369 { 370 371 // This static method should eventually be moved to a thread-specific class 372 // so that we can cache the ContextClassLoader and bottleneck all properties file 373 // loading throughout Xalan. 374 375 Properties props = new Properties(defaults); 376 377 InputStream is = null; 378 BufferedInputStream bis = null; 379 380 try 381 { 382 if (ACCESS_CONTROLLER_CLASS != null) 383 { 384 is = AccessController.doPrivileged(new PrivilegedAction<InputStream>() { 385 public InputStream run() 386 { 387 return OutputPropertiesFactory.class 388 .getResourceAsStream(resourceName); 389 } 390 }); 391 } 392 else 393 { 394 // User may be using older JDK ( JDK < 1.2 ) 395 is = OutputPropertiesFactory.class 396 .getResourceAsStream(resourceName); 397 } 398 399 bis = new BufferedInputStream(is); 400 props.load(bis); 401 } 402 catch (IOException ioe) 403 { 404 if (defaults == null) 405 { 406 throw ioe; 407 } 408 else 409 { 410 throw new WrappedRuntimeException( 411 Utils.messages.createMessage( 412 MsgKey.ER_COULD_NOT_LOAD_RESOURCE, 413 new Object[] { resourceName }), 414 ioe); 415 //"Could not load '"+resourceName+"' (check CLASSPATH), now using just the defaults ", ioe); 416 } 417 } 418 catch (SecurityException se) 419 { 420 // Repeat IOException handling for sandbox/applet case -sc 421 if (defaults == null) 422 { 423 throw se; 424 } 425 else 426 { 427 throw new WrappedRuntimeException( 428 Utils.messages.createMessage( 429 MsgKey.ER_COULD_NOT_LOAD_RESOURCE, 430 new Object[] { resourceName }), 431 se); 432 //"Could not load '"+resourceName+"' (check CLASSPATH, applet security), now using just the defaults ", se); 433 } 434 } 435 finally 436 { 437 if (bis != null) 438 { 439 bis.close(); 440 } 441 if (is != null) 442 { 443 is.close(); 444 } 445 } 446 447 // Note that we're working at the HashTable level here, 448 // and not at the Properties level! This is important 449 // because we don't want to modify the default properties. 450 // NB: If fixupPropertyString ends up changing the property 451 // name or value, we need to remove the old key and re-add 452 // with the new key and value. However, then our Enumeration 453 // could lose its place in the HashTable. So, we first 454 // clone the HashTable and enumerate over that since the 455 // clone will not change. When we migrate to Collections, 456 // this code should be revisited and cleaned up to use 457 // an Iterator which may (or may not) alleviate the need for 458 // the clone. Many thanks to Padraig O'hIceadha 459 // <padraig@gradient.ie> for finding this problem. Bugzilla 2000. 460 461 Enumeration<Object> keys = ((Properties) props.clone()).keys(); 462 while (keys.hasMoreElements()) 463 { 464 String key = (String) keys.nextElement(); 465 // Now check if the given key was specified as a 466 // System property. If so, the system property 467 // overides the default value in the propery file. 468 String value = null; 469 try 470 { 471 value = SecuritySupport.getSystemProperty(key); 472 } 473 catch (SecurityException se) 474 { 475 // No-op for sandbox/applet case, leave null -sc 476 } 477 if (value == null) 478 value = (String) props.get(key); 479 480 String newKey = fixupPropertyString(key, true); 481 String newValue = null; 482 try 483 { 484 newValue = SecuritySupport.getSystemProperty(newKey); 485 } 486 catch (SecurityException se) 487 { 488 // No-op for sandbox/applet case, leave null -sc 489 } 490 if (newValue == null) 491 newValue = fixupPropertyString(value, false); 492 else 493 newValue = fixupPropertyString(newValue, false); 494 495 if (key != newKey || value != newValue) 496 { 497 props.remove(key); 498 props.put(newKey, newValue); 499 } 500 501 } 502 503 return props; 504 } 505 506 /** 507 * Fix up a string in an output properties file according to 508 * the rules of {@link #loadPropertiesFile}. 509 * 510 * @param s non-null reference to string that may need to be fixed up. 511 * @return A new string if fixup occured, otherwise the s argument. 512 */ 513 static private String fixupPropertyString(String s, boolean doClipping) 514 { 515 int index; 516 if (doClipping && s.startsWith(S_XSLT_PREFIX)) 517 { 518 s = s.substring(S_XSLT_PREFIX_LEN); 519 } 520 if (s.startsWith(S_XALAN_PREFIX)) 521 { 522 s = 523 S_BUILTIN_EXTENSIONS_UNIVERSAL 524 + s.substring(S_XALAN_PREFIX_LEN); 525 } 526 if ((index = s.indexOf("\\u003a")) > 0) 527 { 528 String temp = s.substring(index + 6); 529 s = s.substring(0, index) + ":" + temp; 530 531 } 532 return s; 533 } 534 535 } | 1 /* 2 * Copyright (c) 2017, 2019, 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.xml.internal.serializer; 22 23 import java.util.Properties; 24 import javax.xml.transform.OutputKeys; 25 import jdk.xml.internal.SecuritySupport; 26 27 /** 28 * This class is a factory to generate a set of default properties 29 * of key/value pairs that are used to create a serializer through the 30 * factory {@link SerializerFactory SerilizerFactory}. 31 * The properties generated by this factory 32 * may be modified to non-default values before the SerializerFactory is used to 33 * create a Serializer. 34 * <p> 35 * The given output types supported are "xml", "text", and "html". 36 * These type strings can be obtained from the 37 * {@link Method Method} class in this package. 38 * <p> 39 * Other constants defined in this class are the non-standard property keys 40 * that can be used to set non-standard property values on a java.util.Properties object 41 * that is used to create or configure a serializer. Here are the non-standard keys: 42 * <ul> 43 * <li> <b>S_KEY_INDENT_AMOUNT </b> - 44 * The non-standard property key to use to set the indentation amount. 45 * The "indent" key needs to have a value of "yes", and this 46 * properties value is a the number of whitespaces to indent by per 47 * indentation level. 48 * 49 * <li> <b>S_KEY_CONTENT_HANDLER </b> - 50 * This non-standard property key is used to set the name of the fully qualified 51 * Java class that implements the ContentHandler interface. 52 * The output of the serializer will be SAX events sent to this an 53 * object of this class. 54 * 55 * <li> <b>S_KEY_ENTITIES </b> - 56 * This non-standard property key is used to specify the name of the property file 57 * that specifies character to entity reference mappings. A line in such a 58 * file is has the name of the entity and the numeric (base 10) value 59 * of the corresponding character, like this one: <br> quot=34 <br> 60 * 61 * <li> <b>S_USE_URL_ESCAPING </b> - 62 * This non-standard property key is used to set a value of "yes" if the href values 63 * for HTML serialization should use %xx escaping. 64 * 65 * <li> <b>S_OMIT_META_TAG </b> - 66 * This non-standard property key is used to set a value of "yes" if the META tag 67 * should be omitted where it would otherwise be supplied. 68 * </ul> 69 * 70 * @see SerializerFactory 71 * @see Method 72 * @see Serializer 73 * @LastModified: Feb 2019 74 */ 75 public final class OutputPropertiesFactory 76 { 77 /** S_BUILTIN_EXTENSIONS_URL is a mnemonic for the XML Namespace 78 *(http://xml.apache.org/xalan) predefined to signify Xalan's 79 * built-in XSLT Extensions. When used in stylesheets, this is often 80 * bound to the "xalan:" prefix. 81 */ 82 private static final String 83 S_BUILTIN_EXTENSIONS_URL = "http://xml.apache.org/xalan"; 84 85 /** 86 * The old built-in extension url. It is still supported for 87 * backward compatibility. 88 */ 89 private static final String 90 S_BUILTIN_OLD_EXTENSIONS_URL = "http://xml.apache.org/xslt"; 91 92 //************************************************************ 93 //* PUBLIC CONSTANTS 121 S_BUILTIN_EXTENSIONS_UNIVERSAL + "line-separator"; 122 123 /** This non-standard property key is used to set the name of the fully qualified 124 * Java class that implements the ContentHandler interface. 125 * Fully qualified name of class with a default constructor that 126 * implements the ContentHandler interface, where the result tree events 127 * will be sent to. 128 */ 129 130 public static final String S_KEY_CONTENT_HANDLER = 131 S_BUILTIN_EXTENSIONS_UNIVERSAL + "content-handler"; 132 133 /** 134 * This non-standard property key is used to specify the name of the property file 135 * that specifies character to entity reference mappings. 136 */ 137 public static final String S_KEY_ENTITIES = 138 S_BUILTIN_EXTENSIONS_UNIVERSAL + "entities"; 139 140 /** 141 * This non-standard property key is used to set a value of "yes" if the href 142 * values for HTML serialization should use %xx escaping. 143 */ 144 public static final String S_USE_URL_ESCAPING = 145 S_BUILTIN_EXTENSIONS_UNIVERSAL + "use-url-escaping"; 146 147 /** 148 * This non-standard property key is used to set a value of "yes" if the META 149 * tag should be omitted where it would otherwise be supplied. 150 */ 151 public static final String S_OMIT_META_TAG = 152 S_BUILTIN_EXTENSIONS_UNIVERSAL + "omit-meta-tag"; 153 154 /** 155 * The old built-in extension namespace, this is not a public API. 156 */ 157 public static final String S_BUILTIN_OLD_EXTENSIONS_UNIVERSAL = 158 "{" + S_BUILTIN_OLD_EXTENSIONS_URL + "}"; 159 160 /** 161 * This is not a public API, it is only public because it is used 162 * by outside of this package, 163 * it is the length of the old built-in extension namespace. 164 */ 165 public static final int S_BUILTIN_OLD_EXTENSIONS_UNIVERSAL_LEN = 166 S_BUILTIN_OLD_EXTENSIONS_UNIVERSAL.length(); 167 168 /** 169 * This non-standard, Oracle-impl only property key is used as if 170 * OutputKeys.STANDALONE is specified but without writing it out in the declaration; 171 * It can be used to reverse the change by Xalan patch 1495. 172 * Since Xalan patch 1495 can cause incompatible behavior, this property is 173 * added for application to neutralize the effect of Xalan patch 1495 174 */ 175 /** 176 * <p>Is Standalone</p> 177 * 178 * <ul> 179 * <li> 180 * <code>yes</code> to indicate the output is intended to be used as standalone 181 * </li> 182 * <li> 183 * <code>no</code> has no effect. 184 * </li> 185 * </ul> 186 */ 187 public static final String ORACLE_IS_STANDALONE = "http://www.oracle.com/xml/is-standalone"; 188 189 //************************************************************ 190 //* PRIVATE CONSTANTS 191 //************************************************************ 192 193 /* 194 * XSLT properties do not need namespace qualification. 195 * 196 * Xalan-specific output properties can be overridden in the stylesheet 197 * assigning a xalan namespace. For example: 198 * <xsl:stylesheet version="1.0" 199 * xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 200 * xmlns:xalan="http://xml.apache.org/xalan"> 201 * <xsl:output method="html" encoding="UTF-8" 202 * xalan:content-handler="MyContentHandler"/> 203 * ... 204 */ 205 private static final String[] PROP_XML = { 206 "method", 207 "version", 208 "encoding", 209 "indent", 210 "omit-xml-declaration", 211 "standalone", 212 "media-type", 213 "{http://xml.apache.org/xalan}indent-amount", 214 "{http://xml.apache.org/xalan}content-handler", 215 "{http://xml.apache.org/xalan}entities" 216 }; 217 218 private static final String[] PROP_XML_VALUE = { 219 "xml", 220 "1.0", 221 "UTF-8", 222 "no", 223 "no", 224 "no", 225 "text/xml", 226 "0", 227 "com.sun.org.apache.xml.internal.serializer.ToXMLStream", 228 "com/sun/org/apache/xml/internal/serializer/XMLEntities" 229 }; 230 231 private static final String[] PROP_HTML = { 232 "method", 233 "indent", 234 "media", 235 "version", 236 "{http://xml.apache.org/xalan}indent-amount", 237 "{http://xml.apache.org/xalan}content-handler", 238 "{http://xml.apache.org/xalan}entities", 239 "{http://xml.apache.org/xalan}use-url-escaping", 240 "{http://xml.apache.org/xalan}omit-meta-tag" 241 }; 242 243 private static final String[] PROP_HTML_VALUE = { 244 "html", 245 "yes", 246 "text/html", 247 "4.0", 248 "4", 249 "com.sun.org.apache.xml.internal.serializer.ToHTMLStream", 250 "com/sun/org/apache/xml/internal/serializer/HTMLEntities", 251 "yes", 252 "no" 253 }; 254 255 private static final String[] PROP_TEXT = { 256 "method", 257 "media-type", 258 "{http://xml.apache.org/xalan}content-handler" 259 }; 260 261 private static final String[] PROP_TEXT_VALUE = { 262 "text", 263 "text/plain", 264 "com.sun.org.apache.xml.internal.serializer.ToTextStream" 265 }; 266 267 private static final String[] PROP_UNKNOWN = { 268 "method", 269 "version", 270 "encoding", 271 "indent", 272 "omit-xml-declaration", 273 "standalone", 274 "media-type", 275 "{http://xml.apache.org/xalan}indent-amount", 276 "{http://xml.apache.org/xalan}content-handler" 277 }; 278 279 private static final String[] PROP_UNKNOWN_VALUE = { 280 "xml", 281 "1.0", 282 "UTF-8", 283 "no", 284 "no", 285 "no", 286 "text/xml", 287 "0", 288 "com.sun.org.apache.xml.internal.serializer.ToUnknownStream", 289 }; 290 291 //************************************************************ 292 //* PRIVATE STATIC FIELDS 293 //************************************************************ 294 295 /** The default properties for all other than html and text. */ 296 private static Properties m_xml_properties = null; 297 298 /** The default properties when method="html". */ 299 private static Properties m_html_properties = null; 300 301 /** The default properties when method="text". */ 302 private static Properties m_text_properties = null; 303 304 /** The properties when method="" for the "unknown" wrapper */ 305 private static Properties m_unknown_properties = null; 306 307 /** 308 * Returns a Properties based on the specified method. The default is xml. 309 * 310 * @param method non-null reference to method name. 311 * 312 * @return Properties object that holds the defaults for the given method. 313 */ 314 static public final Properties getDefaultMethodProperties(String method) 315 { 316 Properties defaultProperties = null; 317 318 if (null == m_xml_properties) { 319 m_xml_properties = initProperties(PROP_XML, PROP_XML_VALUE, null); 320 } 321 322 323 switch (method) { 324 case Method.XML: 325 defaultProperties = m_xml_properties; 326 break; 327 case Method.HTML: 328 if (null == m_html_properties) { 329 m_html_properties = initProperties( 330 PROP_HTML, PROP_HTML_VALUE, m_xml_properties); 331 } 332 defaultProperties = m_html_properties; 333 break; 334 case Method.TEXT: 335 if (null == m_text_properties) { 336 m_text_properties = initProperties( 337 PROP_TEXT, PROP_TEXT_VALUE, m_xml_properties); 338 339 if (null == m_text_properties.getProperty(OutputKeys.ENCODING)) 340 { 341 String mimeEncoding = Encodings.getMimeEncoding(null); 342 m_text_properties.put(OutputKeys.ENCODING, mimeEncoding); 343 } 344 } 345 defaultProperties = m_text_properties; 346 break; 347 case com.sun.org.apache.xml.internal.serializer.Method.UNKNOWN: 348 if (null == m_unknown_properties) { 349 m_unknown_properties = initProperties( 350 PROP_UNKNOWN, PROP_UNKNOWN_VALUE, m_xml_properties); 351 } 352 defaultProperties = m_unknown_properties; 353 break; 354 default: 355 defaultProperties = m_xml_properties; 356 break; 357 } 358 359 // wrap these cached defaultProperties in a new Property object just so 360 // that the caller of this method can't modify the default values 361 return new Properties(defaultProperties); 362 } 363 364 /** 365 * Initiates the properties 366 * 367 * @param keys an array of keys 368 * @param values values corresponding to the keys 369 * @param defaults Default properties, which may be null. 370 */ 371 static private Properties initProperties(String[] keys, String[] values, Properties defaults) 372 { 373 Properties props = new Properties(defaults); 374 375 for (int i = 0; i < keys.length; i++) { 376 // check System Property. This is kept as is for binary compatibility 377 String sys = SecuritySupport.getSystemProperty(keys[i]); 378 props.put(keys[i], (sys == null) ? values[i] : sys); 379 } 380 381 return props; 382 } 383 } |