1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/share/jaxws_classes/com/sun/xml/internal/ws/api/streaming/XMLStreamReaderFactory.java Wed Apr 27 01:27:09 2016 +0800 1.3 @@ -0,0 +1,619 @@ 1.4 +/* 1.5 + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. 1.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 1.7 + * 1.8 + * This code is free software; you can redistribute it and/or modify it 1.9 + * under the terms of the GNU General Public License version 2 only, as 1.10 + * published by the Free Software Foundation. Oracle designates this 1.11 + * particular file as subject to the "Classpath" exception as provided 1.12 + * by Oracle in the LICENSE file that accompanied this code. 1.13 + * 1.14 + * This code is distributed in the hope that it will be useful, but WITHOUT 1.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1.17 + * version 2 for more details (a copy is included in the LICENSE file that 1.18 + * accompanied this code). 1.19 + * 1.20 + * You should have received a copy of the GNU General Public License version 1.21 + * 2 along with this work; if not, write to the Free Software Foundation, 1.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 1.23 + * 1.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 1.25 + * or visit www.oracle.com if you need additional information or have any 1.26 + * questions. 1.27 + */ 1.28 + 1.29 +package com.sun.xml.internal.ws.api.streaming; 1.30 + 1.31 +import com.sun.istack.internal.NotNull; 1.32 +import com.sun.istack.internal.Nullable; 1.33 +import com.sun.xml.internal.ws.streaming.XMLReaderException; 1.34 +import com.sun.xml.internal.ws.util.xml.XmlUtil; 1.35 +import org.xml.sax.InputSource; 1.36 + 1.37 +import javax.xml.stream.XMLInputFactory; 1.38 +import javax.xml.stream.XMLStreamException; 1.39 +import javax.xml.stream.XMLStreamReader; 1.40 +import java.io.IOException; 1.41 +import java.io.InputStream; 1.42 +import java.io.InputStreamReader; 1.43 +import java.io.Reader; 1.44 +import java.io.StringReader; 1.45 +import java.io.UnsupportedEncodingException; 1.46 +import java.lang.reflect.InvocationTargetException; 1.47 +import java.lang.reflect.Method; 1.48 +import java.net.URL; 1.49 +import java.security.AccessController; 1.50 +import java.util.logging.Level; 1.51 +import java.util.logging.Logger; 1.52 + 1.53 +import com.sun.xml.internal.ws.resources.StreamingMessages; 1.54 + 1.55 +/** 1.56 + * Factory for {@link XMLStreamReader}. 1.57 + * 1.58 + * <p> 1.59 + * This wraps {@link XMLInputFactory} and allows us to reuse {@link XMLStreamReader} instances 1.60 + * when appropriate. 1.61 + * 1.62 + * @author Kohsuke Kawaguchi 1.63 + */ 1.64 +@SuppressWarnings("StaticNonFinalUsedInInitialization") 1.65 +public abstract class XMLStreamReaderFactory { 1.66 + 1.67 + private static final Logger LOGGER = Logger.getLogger(XMLStreamReaderFactory.class.getName()); 1.68 + 1.69 + private static final String CLASS_NAME_OF_WSTXINPUTFACTORY = "com.ctc.wstx.stax.WstxInputFactory"; 1.70 + 1.71 + /** 1.72 + * Singleton instance. 1.73 + */ 1.74 + private static volatile ContextClassloaderLocal<XMLStreamReaderFactory> streamReader = 1.75 + new ContextClassloaderLocal<XMLStreamReaderFactory>() { 1.76 + 1.77 + @Override 1.78 + protected XMLStreamReaderFactory initialValue() { 1.79 + 1.80 + XMLInputFactory xif = getXMLInputFactory(); 1.81 + XMLStreamReaderFactory f=null; 1.82 + 1.83 + // this system property can be used to disable the pooling altogether, 1.84 + // in case someone hits an issue with pooling in the production system. 1.85 + if(!getProperty(XMLStreamReaderFactory.class.getName()+".noPool")) { 1.86 + f = Zephyr.newInstance(xif); 1.87 + } 1.88 + 1.89 + if(f==null) { 1.90 + // is this Woodstox? 1.91 + if (xif.getClass().getName().equals(CLASS_NAME_OF_WSTXINPUTFACTORY)) { 1.92 + f = new Woodstox(xif); 1.93 + } 1.94 + } 1.95 + 1.96 + if (f==null) { 1.97 + f = new Default(); 1.98 + } 1.99 + 1.100 + if (LOGGER.isLoggable(Level.FINE)) { 1.101 + LOGGER.log(Level.FINE, "XMLStreamReaderFactory instance is = {0}", f); 1.102 + } 1.103 + return f; 1.104 + } 1.105 + }; 1.106 + 1.107 + private static XMLInputFactory getXMLInputFactory() { 1.108 + XMLInputFactory xif = null; 1.109 + if (getProperty(XMLStreamReaderFactory.class.getName()+".woodstox")) { 1.110 + try { 1.111 + xif = (XMLInputFactory)Class.forName("com.ctc.wstx.stax.WstxInputFactory").newInstance(); 1.112 + } catch (Exception e) { 1.113 + if (LOGGER.isLoggable(Level.WARNING)) { 1.114 + LOGGER.log(Level.WARNING, StreamingMessages.WOODSTOX_CANT_LOAD(CLASS_NAME_OF_WSTXINPUTFACTORY), e); 1.115 + } 1.116 + } 1.117 + } 1.118 + if (xif == null) { 1.119 + xif = XmlUtil.newXMLInputFactory(true); 1.120 + } 1.121 + xif.setProperty(XMLInputFactory.IS_NAMESPACE_AWARE, true); 1.122 + xif.setProperty(XMLInputFactory.SUPPORT_DTD, false); 1.123 + xif.setProperty(XMLInputFactory.IS_COALESCING, true); 1.124 + 1.125 + return xif; 1.126 + } 1.127 + 1.128 + /** 1.129 + * Overrides the singleton {@link XMLStreamReaderFactory} instance that 1.130 + * the JAX-WS RI uses. 1.131 + */ 1.132 + public static void set(XMLStreamReaderFactory f) { 1.133 + if(f==null) { 1.134 + throw new IllegalArgumentException(); 1.135 + } 1.136 + streamReader.set(f); 1.137 + } 1.138 + 1.139 + public static XMLStreamReaderFactory get() { 1.140 + return streamReader.get(); 1.141 + } 1.142 + 1.143 + public static XMLStreamReader create(InputSource source, boolean rejectDTDs) { 1.144 + try { 1.145 + // Char stream available? 1.146 + if (source.getCharacterStream() != null) { 1.147 + return get().doCreate(source.getSystemId(), source.getCharacterStream(), rejectDTDs); 1.148 + } 1.149 + 1.150 + // Byte stream available? 1.151 + if (source.getByteStream() != null) { 1.152 + return get().doCreate(source.getSystemId(), source.getByteStream(), rejectDTDs); 1.153 + } 1.154 + 1.155 + // Otherwise, open URI 1.156 + return get().doCreate(source.getSystemId(), new URL(source.getSystemId()).openStream(),rejectDTDs); 1.157 + } catch (IOException e) { 1.158 + throw new XMLReaderException("stax.cantCreate",e); 1.159 + } 1.160 + } 1.161 + 1.162 + public static XMLStreamReader create(@Nullable String systemId, InputStream in, boolean rejectDTDs) { 1.163 + return get().doCreate(systemId,in,rejectDTDs); 1.164 + } 1.165 + 1.166 + public static XMLStreamReader create(@Nullable String systemId, InputStream in, @Nullable String encoding, boolean rejectDTDs) { 1.167 + return (encoding == null) 1.168 + ? create(systemId, in, rejectDTDs) 1.169 + : get().doCreate(systemId,in,encoding,rejectDTDs); 1.170 + } 1.171 + 1.172 + public static XMLStreamReader create(@Nullable String systemId, Reader reader, boolean rejectDTDs) { 1.173 + return get().doCreate(systemId,reader,rejectDTDs); 1.174 + } 1.175 + 1.176 + /** 1.177 + * Should be invoked when the code finished using an {@link XMLStreamReader}. 1.178 + * 1.179 + * <p> 1.180 + * If the recycled instance implements {@link RecycleAware}, 1.181 + * {@link RecycleAware#onRecycled()} will be invoked to let the instance 1.182 + * know that it's being recycled. 1.183 + * 1.184 + * <p> 1.185 + * It is not a hard requirement to call this method on every {@link XMLStreamReader} 1.186 + * instance. Not doing so just reduces the performance by throwing away 1.187 + * possibly reusable instances. So the caller should always consider the effort 1.188 + * it takes to recycle vs the possible performance gain by doing so. 1.189 + * 1.190 + * <p> 1.191 + * This method may be invoked by multiple threads concurrently. 1.192 + * 1.193 + * @param r 1.194 + * The {@link XMLStreamReader} instance that the caller finished using. 1.195 + * This could be any {@link XMLStreamReader} implementation, not just 1.196 + * the ones that were created from this factory. So the implementation 1.197 + * of this class needs to be aware of that. 1.198 + */ 1.199 + public static void recycle(XMLStreamReader r) { 1.200 + get().doRecycle(r); 1.201 + if (r instanceof RecycleAware) { 1.202 + ((RecycleAware)r).onRecycled(); 1.203 + } 1.204 + } 1.205 + 1.206 + // implementations 1.207 + 1.208 + public abstract XMLStreamReader doCreate(String systemId, InputStream in, boolean rejectDTDs); 1.209 + 1.210 + private XMLStreamReader doCreate(String systemId, InputStream in, @NotNull String encoding, boolean rejectDTDs) { 1.211 + Reader reader; 1.212 + try { 1.213 + reader = new InputStreamReader(in, encoding); 1.214 + } catch(UnsupportedEncodingException ue) { 1.215 + throw new XMLReaderException("stax.cantCreate", ue); 1.216 + } 1.217 + return doCreate(systemId, reader, rejectDTDs); 1.218 + } 1.219 + 1.220 + public abstract XMLStreamReader doCreate(String systemId, Reader reader, boolean rejectDTDs); 1.221 + 1.222 + public abstract void doRecycle(XMLStreamReader r); 1.223 + 1.224 + /** 1.225 + * Interface that can be implemented by {@link XMLStreamReader} to 1.226 + * be notified when it's recycled. 1.227 + * 1.228 + * <p> 1.229 + * This provides a filtering {@link XMLStreamReader} an opportunity to 1.230 + * recycle its inner {@link XMLStreamReader}. 1.231 + */ 1.232 + public interface RecycleAware { 1.233 + void onRecycled(); 1.234 + } 1.235 + 1.236 + /** 1.237 + * {@link XMLStreamReaderFactory} implementation for SJSXP/JAXP RI. 1.238 + */ 1.239 + private static final class Zephyr extends XMLStreamReaderFactory { 1.240 + private final XMLInputFactory xif; 1.241 + 1.242 + private final ThreadLocal<XMLStreamReader> pool = new ThreadLocal<XMLStreamReader>(); 1.243 + 1.244 + /** 1.245 + * Sun StAX impl <code>XMLReaderImpl.setInputSource()</code> method via reflection. 1.246 + */ 1.247 + private final Method setInputSourceMethod; 1.248 + 1.249 + /** 1.250 + * Sun StAX impl <code>XMLReaderImpl.reset()</code> method via reflection. 1.251 + */ 1.252 + private final Method resetMethod; 1.253 + 1.254 + /** 1.255 + * The Sun StAX impl's {@link XMLStreamReader} implementation clas. 1.256 + */ 1.257 + private final Class zephyrClass; 1.258 + 1.259 + /** 1.260 + * Creates {@link Zephyr} instance if the given {@link XMLInputFactory} is the one 1.261 + * from Zephyr. 1.262 + */ 1.263 + public static @Nullable 1.264 + XMLStreamReaderFactory newInstance(XMLInputFactory xif) { 1.265 + // check if this is from Zephyr 1.266 + try { 1.267 + Class<?> clazz = xif.createXMLStreamReader(new StringReader("<foo/>")).getClass(); 1.268 + // JDK has different XMLStreamReader impl class. Even if we check for that, 1.269 + // it doesn't have setInputSource(InputSource). Let it use Default 1.270 + if(!(clazz.getName().startsWith("com.sun.xml.internal.stream.")) ) 1.271 + return null; // nope 1.272 + return new Zephyr(xif,clazz); 1.273 + } catch (NoSuchMethodException e) { 1.274 + return null; // this factory is not for zephyr 1.275 + } catch (XMLStreamException e) { 1.276 + return null; // impossible to fail to parse <foo/>, but anyway 1.277 + } 1.278 + } 1.279 + 1.280 + public Zephyr(XMLInputFactory xif, Class clazz) throws NoSuchMethodException { 1.281 + zephyrClass = clazz; 1.282 + setInputSourceMethod = clazz.getMethod("setInputSource", InputSource.class); 1.283 + resetMethod = clazz.getMethod("reset"); 1.284 + 1.285 + try { 1.286 + // Turn OFF internal factory caching in Zephyr. 1.287 + // Santiago told me that this makes it thread-safe. 1.288 + xif.setProperty("reuse-instance", false); 1.289 + } catch (IllegalArgumentException e) { 1.290 + // falls through 1.291 + } 1.292 + this.xif = xif; 1.293 + } 1.294 + 1.295 + /** 1.296 + * Fetchs an instance from the pool if available, otherwise null. 1.297 + */ 1.298 + private @Nullable XMLStreamReader fetch() { 1.299 + XMLStreamReader sr = pool.get(); 1.300 + if(sr==null) return null; 1.301 + pool.set(null); 1.302 + return sr; 1.303 + } 1.304 + 1.305 + @Override 1.306 + public void doRecycle(XMLStreamReader r) { 1.307 + if(zephyrClass.isInstance(r)) 1.308 + pool.set(r); 1.309 + } 1.310 + 1.311 + @Override 1.312 + public XMLStreamReader doCreate(String systemId, InputStream in, boolean rejectDTDs) { 1.313 + try { 1.314 + XMLStreamReader xsr = fetch(); 1.315 + if(xsr==null) 1.316 + return xif.createXMLStreamReader(systemId,in); 1.317 + 1.318 + // try re-using this instance. 1.319 + InputSource is = new InputSource(systemId); 1.320 + is.setByteStream(in); 1.321 + reuse(xsr,is); 1.322 + return xsr; 1.323 + } catch (IllegalAccessException e) { 1.324 + throw new XMLReaderException("stax.cantCreate",e); 1.325 + } catch (InvocationTargetException e) { 1.326 + throw new XMLReaderException("stax.cantCreate",e); 1.327 + } catch (XMLStreamException e) { 1.328 + throw new XMLReaderException("stax.cantCreate",e); 1.329 + } 1.330 + } 1.331 + 1.332 + @Override 1.333 + public XMLStreamReader doCreate(String systemId, Reader in, boolean rejectDTDs) { 1.334 + try { 1.335 + XMLStreamReader xsr = fetch(); 1.336 + if(xsr==null) 1.337 + return xif.createXMLStreamReader(systemId,in); 1.338 + 1.339 + // try re-using this instance. 1.340 + InputSource is = new InputSource(systemId); 1.341 + is.setCharacterStream(in); 1.342 + reuse(xsr,is); 1.343 + return xsr; 1.344 + } catch (IllegalAccessException e) { 1.345 + throw new XMLReaderException("stax.cantCreate",e); 1.346 + } catch (InvocationTargetException e) { 1.347 + Throwable cause = e.getCause(); 1.348 + if (cause == null) { 1.349 + cause = e; 1.350 + } 1.351 + throw new XMLReaderException("stax.cantCreate", cause); 1.352 + } catch (XMLStreamException e) { 1.353 + throw new XMLReaderException("stax.cantCreate",e); 1.354 + } 1.355 + } 1.356 + 1.357 + private void reuse(XMLStreamReader xsr, InputSource in) throws IllegalAccessException, InvocationTargetException { 1.358 + resetMethod.invoke(xsr); 1.359 + setInputSourceMethod.invoke(xsr,in); 1.360 + } 1.361 + } 1.362 + 1.363 + /** 1.364 + * Default {@link XMLStreamReaderFactory} implementation 1.365 + * that can work with any {@link XMLInputFactory}. 1.366 + * 1.367 + * <p> 1.368 + * {@link XMLInputFactory} is not required to be thread-safe, but 1.369 + * if the create method on this implementation is synchronized, 1.370 + * it may run into (see <a href="https://jax-ws.dev.java.net/issues/show_bug.cgi?id=555"> 1.371 + * race condition</a>). Hence, using a XMLInputFactory per thread. 1.372 + */ 1.373 + public static final class Default extends XMLStreamReaderFactory { 1.374 + 1.375 + private final ThreadLocal<XMLInputFactory> xif = new ThreadLocal<XMLInputFactory>() { 1.376 + @Override 1.377 + public XMLInputFactory initialValue() { 1.378 + return getXMLInputFactory(); 1.379 + } 1.380 + }; 1.381 + 1.382 + @Override 1.383 + public XMLStreamReader doCreate(String systemId, InputStream in, boolean rejectDTDs) { 1.384 + try { 1.385 + return xif.get().createXMLStreamReader(systemId,in); 1.386 + } catch (XMLStreamException e) { 1.387 + throw new XMLReaderException("stax.cantCreate",e); 1.388 + } 1.389 + } 1.390 + 1.391 + @Override 1.392 + public XMLStreamReader doCreate(String systemId, Reader in, boolean rejectDTDs) { 1.393 + try { 1.394 + return xif.get().createXMLStreamReader(systemId,in); 1.395 + } catch (XMLStreamException e) { 1.396 + throw new XMLReaderException("stax.cantCreate",e); 1.397 + } 1.398 + } 1.399 + 1.400 + @Override 1.401 + public void doRecycle(XMLStreamReader r) { 1.402 + // there's no way to recycle with the default StAX API. 1.403 + } 1.404 + 1.405 + } 1.406 + 1.407 + /** 1.408 + * Similar to {@link Default} but doesn't do any synchronization. 1.409 + * 1.410 + * <p> 1.411 + * This is useful when you know your {@link XMLInputFactory} is thread-safe by itself. 1.412 + */ 1.413 + public static class NoLock extends XMLStreamReaderFactory { 1.414 + private final XMLInputFactory xif; 1.415 + 1.416 + public NoLock(XMLInputFactory xif) { 1.417 + this.xif = xif; 1.418 + } 1.419 + 1.420 + @Override 1.421 + public XMLStreamReader doCreate(String systemId, InputStream in, boolean rejectDTDs) { 1.422 + try { 1.423 + return xif.createXMLStreamReader(systemId,in); 1.424 + } catch (XMLStreamException e) { 1.425 + throw new XMLReaderException("stax.cantCreate",e); 1.426 + } 1.427 + } 1.428 + 1.429 + @Override 1.430 + public XMLStreamReader doCreate(String systemId, Reader in, boolean rejectDTDs) { 1.431 + try { 1.432 + return xif.createXMLStreamReader(systemId,in); 1.433 + } catch (XMLStreamException e) { 1.434 + throw new XMLReaderException("stax.cantCreate",e); 1.435 + } 1.436 + } 1.437 + 1.438 + @Override 1.439 + public void doRecycle(XMLStreamReader r) { 1.440 + // there's no way to recycle with the default StAX API. 1.441 + } 1.442 + } 1.443 + 1.444 + /** 1.445 + * Handles Woodstox's XIF, but sets properties to do the string interning, sets various limits, ... 1.446 + * Woodstox {@link XMLInputFactory} is thread safe. 1.447 + */ 1.448 + public static final class Woodstox extends NoLock { 1.449 + 1.450 + public final static String PROPERTY_MAX_ATTRIBUTES_PER_ELEMENT = "xml.ws.maximum.AttributesPerElement"; 1.451 + public final static String PROPERTY_MAX_ATTRIBUTE_SIZE = "xml.ws.maximum.AttributeSize"; 1.452 + public final static String PROPERTY_MAX_CHILDREN_PER_ELEMENT = "xml.ws.maximum.ChildrenPerElement"; 1.453 + public final static String PROPERTY_MAX_ELEMENT_COUNT = "xml.ws.maximum.ElementCount"; 1.454 + public final static String PROPERTY_MAX_ELEMENT_DEPTH = "xml.ws.maximum.ElementDepth"; 1.455 + public final static String PROPERTY_MAX_CHARACTERS = "xml.ws.maximum.Characters"; 1.456 + 1.457 + private static final int DEFAULT_MAX_ATTRIBUTES_PER_ELEMENT = 500; 1.458 + private static final int DEFAULT_MAX_ATTRIBUTE_SIZE = 65536 * 8; 1.459 + private static final int DEFAULT_MAX_CHILDREN_PER_ELEMENT = Integer.MAX_VALUE; 1.460 + private static final int DEFAULT_MAX_ELEMENT_DEPTH = 500; 1.461 + private static final long DEFAULT_MAX_ELEMENT_COUNT = Integer.MAX_VALUE; 1.462 + private static final long DEFAULT_MAX_CHARACTERS = Long.MAX_VALUE; 1.463 + 1.464 + /* Woodstox default setting: 1.465 + int mMaxAttributesPerElement = 1000; 1.466 + int mMaxAttributeSize = 65536 * 8; 1.467 + int mMaxChildrenPerElement = Integer.MAX_VALUE; 1.468 + int mMaxElementDepth = 1000; 1.469 + long mMaxElementCount = Long.MAX_VALUE; 1.470 + long mMaxCharacters = Long.MAX_VALUE; 1.471 + */ 1.472 + 1.473 + private int maxAttributesPerElement = DEFAULT_MAX_ATTRIBUTES_PER_ELEMENT; 1.474 + private int maxAttributeSize = DEFAULT_MAX_ATTRIBUTE_SIZE; 1.475 + private int maxChildrenPerElement = DEFAULT_MAX_CHILDREN_PER_ELEMENT; 1.476 + private int maxElementDepth = DEFAULT_MAX_ELEMENT_DEPTH; 1.477 + private long maxElementCount = DEFAULT_MAX_ELEMENT_COUNT; 1.478 + private long maxCharacters = DEFAULT_MAX_CHARACTERS; 1.479 + 1.480 + // Note: this is a copy from com.ctc.wstx.api.WstxInputProperties, to be removed in the future 1.481 + private static final java.lang.String P_MAX_ATTRIBUTES_PER_ELEMENT = "com.ctc.wstx.maxAttributesPerElement"; 1.482 + private static final java.lang.String P_MAX_ATTRIBUTE_SIZE = "com.ctc.wstx.maxAttributeSize"; 1.483 + private static final java.lang.String P_MAX_CHILDREN_PER_ELEMENT = "com.ctc.wstx.maxChildrenPerElement"; 1.484 + private static final java.lang.String P_MAX_ELEMENT_COUNT = "com.ctc.wstx.maxElementCount"; 1.485 + private static final java.lang.String P_MAX_ELEMENT_DEPTH = "com.ctc.wstx.maxElementDepth"; 1.486 + private static final java.lang.String P_MAX_CHARACTERS = "com.ctc.wstx.maxCharacters"; 1.487 + private static final java.lang.String P_INTERN_NSURIS = "org.codehaus.stax2.internNsUris"; 1.488 + 1.489 + public Woodstox(XMLInputFactory xif) { 1.490 + super(xif); 1.491 + 1.492 + if (xif.isPropertySupported(P_INTERN_NSURIS)) { 1.493 + xif.setProperty(P_INTERN_NSURIS, true); 1.494 + if (LOGGER.isLoggable(Level.FINE)) { 1.495 + LOGGER.log(Level.FINE, P_INTERN_NSURIS + " is {0}", true); 1.496 + } 1.497 + } 1.498 + 1.499 + if (xif.isPropertySupported(P_MAX_ATTRIBUTES_PER_ELEMENT)) { 1.500 + maxAttributesPerElement = Integer.valueOf(buildIntegerValue( 1.501 + PROPERTY_MAX_ATTRIBUTES_PER_ELEMENT, DEFAULT_MAX_ATTRIBUTES_PER_ELEMENT) 1.502 + ); 1.503 + xif.setProperty(P_MAX_ATTRIBUTES_PER_ELEMENT, maxAttributesPerElement); 1.504 + if (LOGGER.isLoggable(Level.FINE)) { 1.505 + LOGGER.log(Level.FINE, P_MAX_ATTRIBUTES_PER_ELEMENT + " is {0}", maxAttributesPerElement); 1.506 + } 1.507 + } 1.508 + 1.509 + if (xif.isPropertySupported(P_MAX_ATTRIBUTE_SIZE)) { 1.510 + maxAttributeSize = Integer.valueOf(buildIntegerValue( 1.511 + PROPERTY_MAX_ATTRIBUTE_SIZE, DEFAULT_MAX_ATTRIBUTE_SIZE) 1.512 + ); 1.513 + xif.setProperty(P_MAX_ATTRIBUTE_SIZE, maxAttributeSize); 1.514 + if (LOGGER.isLoggable(Level.FINE)) { 1.515 + LOGGER.log(Level.FINE, P_MAX_ATTRIBUTE_SIZE + " is {0}", maxAttributeSize); 1.516 + } 1.517 + } 1.518 + 1.519 + if (xif.isPropertySupported(P_MAX_CHILDREN_PER_ELEMENT)) { 1.520 + maxChildrenPerElement = Integer.valueOf(buildIntegerValue( 1.521 + PROPERTY_MAX_CHILDREN_PER_ELEMENT, DEFAULT_MAX_CHILDREN_PER_ELEMENT) 1.522 + ); 1.523 + xif.setProperty(P_MAX_CHILDREN_PER_ELEMENT, maxChildrenPerElement); 1.524 + if (LOGGER.isLoggable(Level.FINE)) { 1.525 + LOGGER.log(Level.FINE, P_MAX_CHILDREN_PER_ELEMENT + " is {0}", maxChildrenPerElement); 1.526 + } 1.527 + } 1.528 + 1.529 + if (xif.isPropertySupported(P_MAX_ELEMENT_DEPTH)) { 1.530 + maxElementDepth = Integer.valueOf(buildIntegerValue( 1.531 + PROPERTY_MAX_ELEMENT_DEPTH, DEFAULT_MAX_ELEMENT_DEPTH) 1.532 + ); 1.533 + xif.setProperty(P_MAX_ELEMENT_DEPTH, maxElementDepth); 1.534 + if (LOGGER.isLoggable(Level.FINE)) { 1.535 + LOGGER.log(Level.FINE, P_MAX_ELEMENT_DEPTH + " is {0}", maxElementDepth); 1.536 + } 1.537 + } 1.538 + 1.539 + if (xif.isPropertySupported(P_MAX_ELEMENT_COUNT)) { 1.540 + maxElementCount = Long.valueOf(buildLongValue( 1.541 + PROPERTY_MAX_ELEMENT_COUNT, DEFAULT_MAX_ELEMENT_COUNT) 1.542 + ); 1.543 + xif.setProperty(P_MAX_ELEMENT_COUNT, maxElementCount); 1.544 + if (LOGGER.isLoggable(Level.FINE)) { 1.545 + LOGGER.log(Level.FINE, P_MAX_ELEMENT_COUNT + " is {0}", maxElementCount); 1.546 + } 1.547 + } 1.548 + 1.549 + if (xif.isPropertySupported(P_MAX_CHARACTERS)) { 1.550 + maxCharacters = Long.valueOf(buildLongValue( 1.551 + PROPERTY_MAX_CHARACTERS, DEFAULT_MAX_CHARACTERS) 1.552 + ); 1.553 + xif.setProperty(P_MAX_CHARACTERS, maxCharacters); 1.554 + if (LOGGER.isLoggable(Level.FINE)) { 1.555 + LOGGER.log(Level.FINE, P_MAX_CHARACTERS + " is {0}", maxCharacters); 1.556 + } 1.557 + } 1.558 + } 1.559 + 1.560 + @Override 1.561 + public XMLStreamReader doCreate(String systemId, InputStream in, boolean rejectDTDs) { 1.562 + return super.doCreate(systemId, in, rejectDTDs); 1.563 + } 1.564 + 1.565 + @Override 1.566 + public XMLStreamReader doCreate(String systemId, Reader in, boolean rejectDTDs) { 1.567 + return super.doCreate(systemId, in, rejectDTDs); 1.568 + } 1.569 + } 1.570 + 1.571 + private static int buildIntegerValue(String propertyName, int defaultValue) { 1.572 + String propVal = System.getProperty(propertyName); 1.573 + if (propVal != null && propVal.length() > 0) { 1.574 + try { 1.575 + Integer value = Integer.parseInt(propVal); 1.576 + if (value > 0) { 1.577 + // return with the value in System property 1.578 + return value; 1.579 + } 1.580 + } catch (NumberFormatException nfe) { 1.581 + if (LOGGER.isLoggable(Level.WARNING)) { 1.582 + LOGGER.log(Level.WARNING, StreamingMessages.INVALID_PROPERTY_VALUE_INTEGER(propertyName, propVal, Integer.toString(defaultValue)), nfe); 1.583 + } 1.584 + } 1.585 + } 1.586 + // return with the default value 1.587 + return defaultValue; 1.588 + } 1.589 + 1.590 + private static long buildLongValue(String propertyName, long defaultValue) { 1.591 + String propVal = System.getProperty(propertyName); 1.592 + if (propVal != null && propVal.length() > 0) { 1.593 + try { 1.594 + long value = Long.parseLong(propVal); 1.595 + if (value > 0L) { 1.596 + // return with the value in System property 1.597 + return value; 1.598 + } 1.599 + } catch (NumberFormatException nfe) { 1.600 + // defult will be returned 1.601 + if (LOGGER.isLoggable(Level.WARNING)) { 1.602 + LOGGER.log(Level.WARNING, StreamingMessages.INVALID_PROPERTY_VALUE_LONG(propertyName, propVal, Long.toString(defaultValue)), nfe); 1.603 + } 1.604 + } 1.605 + } 1.606 + // return with the default value 1.607 + return defaultValue; 1.608 + } 1.609 + 1.610 + private static Boolean getProperty(final String prop) { 1.611 + return AccessController.doPrivileged( 1.612 + new java.security.PrivilegedAction<Boolean>() { 1.613 + @Override 1.614 + public Boolean run() { 1.615 + String value = System.getProperty(prop); 1.616 + return value != null ? Boolean.valueOf(value) : Boolean.FALSE; 1.617 + } 1.618 + } 1.619 + ); 1.620 + } 1.621 + 1.622 +}