1 /* 2 * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package com.sun.xml.internal.ws.api.streaming; 27 28 import com.sun.istack.internal.NotNull; 29 import com.sun.istack.internal.Nullable; 30 import com.sun.xml.internal.ws.streaming.XMLReaderException; 31 import com.sun.xml.internal.ws.util.MrJarUtil; 32 import com.sun.xml.internal.ws.util.xml.XmlUtil; 33 import org.xml.sax.InputSource; 34 35 import javax.xml.stream.XMLInputFactory; 36 import javax.xml.stream.XMLStreamException; 37 import javax.xml.stream.XMLStreamReader; 38 import java.io.IOException; 39 import java.io.InputStream; 40 import java.io.InputStreamReader; 41 import java.io.Reader; 42 import java.io.StringReader; 43 import java.io.UnsupportedEncodingException; 44 import java.lang.reflect.InvocationTargetException; 45 import java.lang.reflect.Method; 46 import java.net.URL; 47 import java.security.AccessController; 48 import java.util.logging.Level; 49 import java.util.logging.Logger; 50 51 import com.sun.xml.internal.ws.resources.StreamingMessages; 52 53 /** 54 * Factory for {@link XMLStreamReader}. 55 * 56 * <p> 57 * This wraps {@link XMLInputFactory} and allows us to reuse {@link XMLStreamReader} instances 58 * when appropriate. 59 * 60 * @author Kohsuke Kawaguchi 61 */ 62 @SuppressWarnings("StaticNonFinalUsedInInitialization") 63 public abstract class XMLStreamReaderFactory { 64 65 private static final Logger LOGGER = Logger.getLogger(XMLStreamReaderFactory.class.getName()); 66 67 private static final String CLASS_NAME_OF_WSTXINPUTFACTORY = "com.ctc.wstx.stax.WstxInputFactory"; 68 69 /** 70 * Singleton instance. 71 */ 72 private static volatile ContextClassloaderLocal<XMLStreamReaderFactory> streamReader = 73 new ContextClassloaderLocal<XMLStreamReaderFactory>() { 74 75 @Override 76 protected XMLStreamReaderFactory initialValue() { 77 78 XMLInputFactory xif = getXMLInputFactory(); 79 XMLStreamReaderFactory f=null; 80 81 // this system property can be used to disable the pooling altogether, 82 // in case someone hits an issue with pooling in the production system. 83 if(!MrJarUtil.getNoPoolProperty(XMLStreamReaderFactory.class.getName())) { 84 f = Zephyr.newInstance(xif); 85 } 86 87 if(f==null) { 88 // is this Woodstox? 89 if (xif.getClass().getName().equals(CLASS_NAME_OF_WSTXINPUTFACTORY)) { 90 f = new Woodstox(xif); 91 } 92 } 93 94 if (f==null) { 95 f = new Default(); 96 } 97 98 if (LOGGER.isLoggable(Level.FINE)) { 99 LOGGER.log(Level.FINE, "XMLStreamReaderFactory instance is = {0}", f); 100 } 101 return f; 102 } 103 }; 104 105 private static XMLInputFactory getXMLInputFactory() { 106 XMLInputFactory xif = null; 107 if (getProperty(XMLStreamReaderFactory.class.getName()+".woodstox")) { 108 try { 109 xif = (XMLInputFactory)Class.forName("com.ctc.wstx.stax.WstxInputFactory").newInstance(); 110 } catch (Exception e) { 111 if (LOGGER.isLoggable(Level.WARNING)) { 112 LOGGER.log(Level.WARNING, StreamingMessages.WOODSTOX_CANT_LOAD(CLASS_NAME_OF_WSTXINPUTFACTORY), e); 113 } 114 } 115 } 116 if (xif == null) { 117 xif = XmlUtil.newXMLInputFactory(true); 118 } 119 xif.setProperty(XMLInputFactory.IS_NAMESPACE_AWARE, true); 120 xif.setProperty(XMLInputFactory.SUPPORT_DTD, false); 121 xif.setProperty(XMLInputFactory.IS_COALESCING, true); 122 123 return xif; 124 } 125 126 /** 127 * Overrides the singleton {@link XMLStreamReaderFactory} instance that 128 * the JAX-WS RI uses. 129 */ 130 public static void set(XMLStreamReaderFactory f) { 131 if(f==null) { 132 throw new IllegalArgumentException(); 133 } 134 streamReader.set(f); 135 } 136 137 public static XMLStreamReaderFactory get() { 138 return streamReader.get(); 139 } 140 141 public static XMLStreamReader create(InputSource source, boolean rejectDTDs) { 142 try { 143 // Char stream available? 144 if (source.getCharacterStream() != null) { 145 return get().doCreate(source.getSystemId(), source.getCharacterStream(), rejectDTDs); 146 } 147 148 // Byte stream available? 149 if (source.getByteStream() != null) { 150 return get().doCreate(source.getSystemId(), source.getByteStream(), rejectDTDs); 151 } 152 153 // Otherwise, open URI 154 return get().doCreate(source.getSystemId(), new URL(source.getSystemId()).openStream(),rejectDTDs); 155 } catch (IOException e) { 156 throw new XMLReaderException("stax.cantCreate",e); 157 } 158 } 159 160 public static XMLStreamReader create(@Nullable String systemId, InputStream in, boolean rejectDTDs) { 161 return get().doCreate(systemId,in,rejectDTDs); 162 } 163 164 public static XMLStreamReader create(@Nullable String systemId, InputStream in, @Nullable String encoding, boolean rejectDTDs) { 165 return (encoding == null) 166 ? create(systemId, in, rejectDTDs) 167 : get().doCreate(systemId,in,encoding,rejectDTDs); 168 } 169 170 public static XMLStreamReader create(@Nullable String systemId, Reader reader, boolean rejectDTDs) { 171 return get().doCreate(systemId,reader,rejectDTDs); 172 } 173 174 /** 175 * Should be invoked when the code finished using an {@link XMLStreamReader}. 176 * 177 * <p> 178 * If the recycled instance implements {@link RecycleAware}, 179 * {@link RecycleAware#onRecycled()} will be invoked to let the instance 180 * know that it's being recycled. 181 * 182 * <p> 183 * It is not a hard requirement to call this method on every {@link XMLStreamReader} 184 * instance. Not doing so just reduces the performance by throwing away 185 * possibly reusable instances. So the caller should always consider the effort 186 * it takes to recycle vs the possible performance gain by doing so. 187 * 188 * <p> 189 * This method may be invoked by multiple threads concurrently. 190 * 191 * @param r 192 * The {@link XMLStreamReader} instance that the caller finished using. 193 * This could be any {@link XMLStreamReader} implementation, not just 194 * the ones that were created from this factory. So the implementation 195 * of this class needs to be aware of that. 196 */ 197 public static void recycle(XMLStreamReader r) { 198 /* the XMLStreamReaderFactory recycle becomes expenisve in the threadLocal get operation. 199 get().doRecycle(r); 200 if (r instanceof RecycleAware) { 201 ((RecycleAware)r).onRecycled(); 202 }*/ 203 } 204 205 // implementations 206 207 public abstract XMLStreamReader doCreate(String systemId, InputStream in, boolean rejectDTDs); 208 209 private XMLStreamReader doCreate(String systemId, InputStream in, @NotNull String encoding, boolean rejectDTDs) { 210 Reader reader; 211 try { 212 reader = new InputStreamReader(in, encoding); 213 } catch(UnsupportedEncodingException ue) { 214 throw new XMLReaderException("stax.cantCreate", ue); 215 } 216 return doCreate(systemId, reader, rejectDTDs); 217 } 218 219 public abstract XMLStreamReader doCreate(String systemId, Reader reader, boolean rejectDTDs); 220 221 public abstract void doRecycle(XMLStreamReader r); 222 223 /** 224 * Interface that can be implemented by {@link XMLStreamReader} to 225 * be notified when it's recycled. 226 * 227 * <p> 228 * This provides a filtering {@link XMLStreamReader} an opportunity to 229 * recycle its inner {@link XMLStreamReader}. 230 */ 231 public interface RecycleAware { 232 void onRecycled(); 233 } 234 235 /** 236 * {@link XMLStreamReaderFactory} implementation for SJSXP/JAXP RI. 237 */ 238 private static final class Zephyr extends XMLStreamReaderFactory { 239 private final XMLInputFactory xif; 240 241 private final ThreadLocal<XMLStreamReader> pool = new ThreadLocal<XMLStreamReader>(); 242 243 /** 244 * Sun StAX impl <code>XMLReaderImpl.setInputSource()</code> method via reflection. 245 */ 246 private final Method setInputSourceMethod; 247 248 /** 249 * Sun StAX impl <code>XMLReaderImpl.reset()</code> method via reflection. 250 */ 251 private final Method resetMethod; 252 253 /** 254 * The Sun StAX impl's {@link XMLStreamReader} implementation clas. 255 */ 256 private final Class zephyrClass; 257 258 /** 259 * Creates {@link Zephyr} instance if the given {@link XMLInputFactory} is the one 260 * from Zephyr. 261 */ 262 public static @Nullable 263 XMLStreamReaderFactory newInstance(XMLInputFactory xif) { 264 // check if this is from Zephyr 265 try { 266 Class<?> clazz = xif.createXMLStreamReader(new StringReader("<foo/>")).getClass(); 267 // JDK has different XMLStreamReader impl class. Even if we check for that, 268 // it doesn't have setInputSource(InputSource). Let it use Default 269 if(!(clazz.getName().startsWith("com.sun.xml.internal.stream.")) ) 270 return null; // nope 271 return new Zephyr(xif,clazz); 272 } catch (NoSuchMethodException e) { 273 return null; // this factory is not for zephyr 274 } catch (XMLStreamException e) { 275 return null; // impossible to fail to parse <foo/>, but anyway 276 } 277 } 278 279 public Zephyr(XMLInputFactory xif, Class clazz) throws NoSuchMethodException { 280 zephyrClass = clazz; 281 setInputSourceMethod = clazz.getMethod("setInputSource", InputSource.class); 282 resetMethod = clazz.getMethod("reset"); 283 284 try { 285 // Turn OFF internal factory caching in Zephyr. 286 // Santiago told me that this makes it thread-safe. 287 xif.setProperty("reuse-instance", false); 288 } catch (IllegalArgumentException e) { 289 // falls through 290 } 291 this.xif = xif; 292 } 293 294 /** 295 * Fetchs an instance from the pool if available, otherwise null. 296 */ 297 private @Nullable XMLStreamReader fetch() { 298 XMLStreamReader sr = pool.get(); 299 if(sr==null) return null; 300 pool.set(null); 301 return sr; 302 } 303 304 @Override 305 public void doRecycle(XMLStreamReader r) { 306 if(zephyrClass.isInstance(r)) 307 pool.set(r); 308 } 309 310 @Override 311 public XMLStreamReader doCreate(String systemId, InputStream in, boolean rejectDTDs) { 312 try { 313 XMLStreamReader xsr = fetch(); 314 if(xsr==null) 315 return xif.createXMLStreamReader(systemId,in); 316 317 // try re-using this instance. 318 InputSource is = new InputSource(systemId); 319 is.setByteStream(in); 320 reuse(xsr,is); 321 return xsr; 322 } catch (IllegalAccessException e) { 323 throw new XMLReaderException("stax.cantCreate",e); 324 } catch (InvocationTargetException e) { 325 throw new XMLReaderException("stax.cantCreate",e); 326 } catch (XMLStreamException e) { 327 throw new XMLReaderException("stax.cantCreate",e); 328 } 329 } 330 331 @Override 332 public XMLStreamReader doCreate(String systemId, Reader in, boolean rejectDTDs) { 333 try { 334 XMLStreamReader xsr = fetch(); 335 if(xsr==null) 336 return xif.createXMLStreamReader(systemId,in); 337 338 // try re-using this instance. 339 InputSource is = new InputSource(systemId); 340 is.setCharacterStream(in); 341 reuse(xsr,is); 342 return xsr; 343 } catch (IllegalAccessException e) { 344 throw new XMLReaderException("stax.cantCreate",e); 345 } catch (InvocationTargetException e) { 346 Throwable cause = e.getCause(); 347 if (cause == null) { 348 cause = e; 349 } 350 throw new XMLReaderException("stax.cantCreate", cause); 351 } catch (XMLStreamException e) { 352 throw new XMLReaderException("stax.cantCreate",e); 353 } 354 } 355 356 private void reuse(XMLStreamReader xsr, InputSource in) throws IllegalAccessException, InvocationTargetException { 357 resetMethod.invoke(xsr); 358 setInputSourceMethod.invoke(xsr,in); 359 } 360 } 361 362 /** 363 * Default {@link XMLStreamReaderFactory} implementation 364 * that can work with any {@link XMLInputFactory}. 365 * 366 * <p> 367 * {@link XMLInputFactory} is not required to be thread-safe, but 368 * if the create method on this implementation is synchronized, 369 * it may run into (see <a href="https://jax-ws.dev.java.net/issues/show_bug.cgi?id=555"> 370 * race condition</a>). Hence, using a XMLInputFactory per thread. 371 */ 372 public static final class Default extends XMLStreamReaderFactory { 373 374 private final ThreadLocal<XMLInputFactory> xif = new ThreadLocal<XMLInputFactory>() { 375 @Override 376 public XMLInputFactory initialValue() { 377 return getXMLInputFactory(); 378 } 379 }; 380 381 @Override 382 public XMLStreamReader doCreate(String systemId, InputStream in, boolean rejectDTDs) { 383 try { 384 return xif.get().createXMLStreamReader(systemId,in); 385 } catch (XMLStreamException e) { 386 throw new XMLReaderException("stax.cantCreate",e); 387 } 388 } 389 390 @Override 391 public XMLStreamReader doCreate(String systemId, Reader in, boolean rejectDTDs) { 392 try { 393 return xif.get().createXMLStreamReader(systemId,in); 394 } catch (XMLStreamException e) { 395 throw new XMLReaderException("stax.cantCreate",e); 396 } 397 } 398 399 @Override 400 public void doRecycle(XMLStreamReader r) { 401 // there's no way to recycle with the default StAX API. 402 } 403 404 } 405 406 /** 407 * Similar to {@link Default} but doesn't do any synchronization. 408 * 409 * <p> 410 * This is useful when you know your {@link XMLInputFactory} is thread-safe by itself. 411 */ 412 public static class NoLock extends XMLStreamReaderFactory { 413 private final XMLInputFactory xif; 414 415 public NoLock(XMLInputFactory xif) { 416 this.xif = xif; 417 } 418 419 @Override 420 public XMLStreamReader doCreate(String systemId, InputStream in, boolean rejectDTDs) { 421 try { 422 return xif.createXMLStreamReader(systemId,in); 423 } catch (XMLStreamException e) { 424 throw new XMLReaderException("stax.cantCreate",e); 425 } 426 } 427 428 @Override 429 public XMLStreamReader doCreate(String systemId, Reader in, boolean rejectDTDs) { 430 try { 431 return xif.createXMLStreamReader(systemId,in); 432 } catch (XMLStreamException e) { 433 throw new XMLReaderException("stax.cantCreate",e); 434 } 435 } 436 437 @Override 438 public void doRecycle(XMLStreamReader r) { 439 // there's no way to recycle with the default StAX API. 440 } 441 } 442 443 /** 444 * Handles Woodstox's XIF, but sets properties to do the string interning, sets various limits, ... 445 * Woodstox {@link XMLInputFactory} is thread safe. 446 */ 447 public static final class Woodstox extends NoLock { 448 449 public final static String PROPERTY_MAX_ATTRIBUTES_PER_ELEMENT = "xml.ws.maximum.AttributesPerElement"; 450 public final static String PROPERTY_MAX_ATTRIBUTE_SIZE = "xml.ws.maximum.AttributeSize"; 451 public final static String PROPERTY_MAX_CHILDREN_PER_ELEMENT = "xml.ws.maximum.ChildrenPerElement"; 452 public final static String PROPERTY_MAX_ELEMENT_COUNT = "xml.ws.maximum.ElementCount"; 453 public final static String PROPERTY_MAX_ELEMENT_DEPTH = "xml.ws.maximum.ElementDepth"; 454 public final static String PROPERTY_MAX_CHARACTERS = "xml.ws.maximum.Characters"; 455 456 private static final int DEFAULT_MAX_ATTRIBUTES_PER_ELEMENT = 500; 457 private static final int DEFAULT_MAX_ATTRIBUTE_SIZE = 65536 * 8; 458 private static final int DEFAULT_MAX_CHILDREN_PER_ELEMENT = Integer.MAX_VALUE; 459 private static final int DEFAULT_MAX_ELEMENT_DEPTH = 500; 460 private static final long DEFAULT_MAX_ELEMENT_COUNT = Integer.MAX_VALUE; 461 private static final long DEFAULT_MAX_CHARACTERS = Long.MAX_VALUE; 462 463 /* Woodstox default setting: 464 int mMaxAttributesPerElement = 1000; 465 int mMaxAttributeSize = 65536 * 8; 466 int mMaxChildrenPerElement = Integer.MAX_VALUE; 467 int mMaxElementDepth = 1000; 468 long mMaxElementCount = Long.MAX_VALUE; 469 long mMaxCharacters = Long.MAX_VALUE; 470 */ 471 472 private int maxAttributesPerElement = DEFAULT_MAX_ATTRIBUTES_PER_ELEMENT; 473 private int maxAttributeSize = DEFAULT_MAX_ATTRIBUTE_SIZE; 474 private int maxChildrenPerElement = DEFAULT_MAX_CHILDREN_PER_ELEMENT; 475 private int maxElementDepth = DEFAULT_MAX_ELEMENT_DEPTH; 476 private long maxElementCount = DEFAULT_MAX_ELEMENT_COUNT; 477 private long maxCharacters = DEFAULT_MAX_CHARACTERS; 478 479 // Note: this is a copy from com.ctc.wstx.api.WstxInputProperties, to be removed in the future 480 private static final java.lang.String P_MAX_ATTRIBUTES_PER_ELEMENT = "com.ctc.wstx.maxAttributesPerElement"; 481 private static final java.lang.String P_MAX_ATTRIBUTE_SIZE = "com.ctc.wstx.maxAttributeSize"; 482 private static final java.lang.String P_MAX_CHILDREN_PER_ELEMENT = "com.ctc.wstx.maxChildrenPerElement"; 483 private static final java.lang.String P_MAX_ELEMENT_COUNT = "com.ctc.wstx.maxElementCount"; 484 private static final java.lang.String P_MAX_ELEMENT_DEPTH = "com.ctc.wstx.maxElementDepth"; 485 private static final java.lang.String P_MAX_CHARACTERS = "com.ctc.wstx.maxCharacters"; 486 private static final java.lang.String P_INTERN_NSURIS = "org.codehaus.stax2.internNsUris"; 487 private static final java.lang.String P_RETURN_NULL_FOR_DEFAULT_NAMESPACE = "com.ctc.wstx.returnNullForDefaultNamespace"; 488 489 public Woodstox(XMLInputFactory xif) { 490 super(xif); 491 492 if (xif.isPropertySupported(P_INTERN_NSURIS)) { 493 xif.setProperty(P_INTERN_NSURIS, true); 494 if (LOGGER.isLoggable(Level.FINE)) { 495 LOGGER.log(Level.FINE, P_INTERN_NSURIS + " is {0}", true); 496 } 497 } 498 499 if (xif.isPropertySupported(P_MAX_ATTRIBUTES_PER_ELEMENT)) { 500 maxAttributesPerElement = Integer.valueOf(buildIntegerValue( 501 PROPERTY_MAX_ATTRIBUTES_PER_ELEMENT, DEFAULT_MAX_ATTRIBUTES_PER_ELEMENT) 502 ); 503 xif.setProperty(P_MAX_ATTRIBUTES_PER_ELEMENT, maxAttributesPerElement); 504 if (LOGGER.isLoggable(Level.FINE)) { 505 LOGGER.log(Level.FINE, P_MAX_ATTRIBUTES_PER_ELEMENT + " is {0}", maxAttributesPerElement); 506 } 507 } 508 509 if (xif.isPropertySupported(P_MAX_ATTRIBUTE_SIZE)) { 510 maxAttributeSize = Integer.valueOf(buildIntegerValue( 511 PROPERTY_MAX_ATTRIBUTE_SIZE, DEFAULT_MAX_ATTRIBUTE_SIZE) 512 ); 513 xif.setProperty(P_MAX_ATTRIBUTE_SIZE, maxAttributeSize); 514 if (LOGGER.isLoggable(Level.FINE)) { 515 LOGGER.log(Level.FINE, P_MAX_ATTRIBUTE_SIZE + " is {0}", maxAttributeSize); 516 } 517 } 518 519 if (xif.isPropertySupported(P_MAX_CHILDREN_PER_ELEMENT)) { 520 maxChildrenPerElement = Integer.valueOf(buildIntegerValue( 521 PROPERTY_MAX_CHILDREN_PER_ELEMENT, DEFAULT_MAX_CHILDREN_PER_ELEMENT) 522 ); 523 xif.setProperty(P_MAX_CHILDREN_PER_ELEMENT, maxChildrenPerElement); 524 if (LOGGER.isLoggable(Level.FINE)) { 525 LOGGER.log(Level.FINE, P_MAX_CHILDREN_PER_ELEMENT + " is {0}", maxChildrenPerElement); 526 } 527 } 528 529 if (xif.isPropertySupported(P_MAX_ELEMENT_DEPTH)) { 530 maxElementDepth = Integer.valueOf(buildIntegerValue( 531 PROPERTY_MAX_ELEMENT_DEPTH, DEFAULT_MAX_ELEMENT_DEPTH) 532 ); 533 xif.setProperty(P_MAX_ELEMENT_DEPTH, maxElementDepth); 534 if (LOGGER.isLoggable(Level.FINE)) { 535 LOGGER.log(Level.FINE, P_MAX_ELEMENT_DEPTH + " is {0}", maxElementDepth); 536 } 537 } 538 539 if (xif.isPropertySupported(P_MAX_ELEMENT_COUNT)) { 540 maxElementCount = Long.valueOf(buildLongValue( 541 PROPERTY_MAX_ELEMENT_COUNT, DEFAULT_MAX_ELEMENT_COUNT) 542 ); 543 xif.setProperty(P_MAX_ELEMENT_COUNT, maxElementCount); 544 if (LOGGER.isLoggable(Level.FINE)) { 545 LOGGER.log(Level.FINE, P_MAX_ELEMENT_COUNT + " is {0}", maxElementCount); 546 } 547 } 548 549 if (xif.isPropertySupported(P_MAX_CHARACTERS)) { 550 maxCharacters = Long.valueOf(buildLongValue( 551 PROPERTY_MAX_CHARACTERS, DEFAULT_MAX_CHARACTERS) 552 ); 553 xif.setProperty(P_MAX_CHARACTERS, maxCharacters); 554 if (LOGGER.isLoggable(Level.FINE)) { 555 LOGGER.log(Level.FINE, P_MAX_CHARACTERS + " is {0}", maxCharacters); 556 } 557 } 558 //Using try/catch instead of isPropertySupported because Woodstox 559 //isPropertySupported is not always reliable 560 try { 561 //this is needed to make sure Woodstox behavior is spec compliant for 562 //calls to XMLStreamReader.getNamespacePrefix 563 xif.setProperty(P_RETURN_NULL_FOR_DEFAULT_NAMESPACE, Boolean.TRUE); 564 if (LOGGER.isLoggable(Level.FINE)) { 565 LOGGER.log(Level.FINE, P_RETURN_NULL_FOR_DEFAULT_NAMESPACE + " is {0}", xif.getProperty(P_RETURN_NULL_FOR_DEFAULT_NAMESPACE)); 566 } 567 } catch (Throwable t) { 568 //ignore - this should not happen Woodstox 4.1.2 or later (maybe older version of Woodstox). 569 LOGGER.log(Level.WARNING, "Expected property not found in Woodstox input factory: '{0}'", P_RETURN_NULL_FOR_DEFAULT_NAMESPACE); 570 } 571 } 572 573 @Override 574 public XMLStreamReader doCreate(String systemId, InputStream in, boolean rejectDTDs) { 575 return super.doCreate(systemId, in, rejectDTDs); 576 } 577 578 @Override 579 public XMLStreamReader doCreate(String systemId, Reader in, boolean rejectDTDs) { 580 return super.doCreate(systemId, in, rejectDTDs); 581 } 582 } 583 584 private static int buildIntegerValue(String propertyName, int defaultValue) { 585 String propVal = System.getProperty(propertyName); 586 if (propVal != null && propVal.length() > 0) { 587 try { 588 Integer value = Integer.parseInt(propVal); 589 if (value > 0) { 590 // return with the value in System property 591 return value; 592 } 593 } catch (NumberFormatException nfe) { 594 if (LOGGER.isLoggable(Level.WARNING)) { 595 LOGGER.log(Level.WARNING, StreamingMessages.INVALID_PROPERTY_VALUE_INTEGER(propertyName, propVal, Integer.toString(defaultValue)), nfe); 596 } 597 } 598 } 599 // return with the default value 600 return defaultValue; 601 } 602 603 private static long buildLongValue(String propertyName, long defaultValue) { 604 String propVal = System.getProperty(propertyName); 605 if (propVal != null && propVal.length() > 0) { 606 try { 607 long value = Long.parseLong(propVal); 608 if (value > 0L) { 609 // return with the value in System property 610 return value; 611 } 612 } catch (NumberFormatException nfe) { 613 // defult will be returned 614 if (LOGGER.isLoggable(Level.WARNING)) { 615 LOGGER.log(Level.WARNING, StreamingMessages.INVALID_PROPERTY_VALUE_LONG(propertyName, propVal, Long.toString(defaultValue)), nfe); 616 } 617 } 618 } 619 // return with the default value 620 return defaultValue; 621 } 622 623 private static Boolean getProperty(final String prop) { 624 return AccessController.doPrivileged( 625 new java.security.PrivilegedAction<Boolean>() { 626 @Override 627 public Boolean run() { 628 String value = System.getProperty(prop); 629 return value != null ? Boolean.valueOf(value) : Boolean.FALSE; 630 } 631 } 632 ); 633 } 634 635 }