src/share/jaxws_classes/com/sun/xml/internal/ws/api/streaming/XMLStreamReaderFactory.java

Thu, 31 Aug 2017 15:18:52 +0800

author
aoqi
date
Thu, 31 Aug 2017 15:18:52 +0800
changeset 637
9c07ef4934dd
parent 515
6cd506508147
parent 0
373ffda63c9a
permissions
-rw-r--r--

merge

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

mercurial