use XmlOptions for parser properties instead of system properties

git-svn-id: https://svn.apache.org/repos/asf/xmlbeans/trunk@1838345 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/CHANGES.txt b/CHANGES.txt
index 31e40a3..11ea138 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -1,3 +1,8 @@
+Changes in V3.0.1 since V3.0.0
+
+* XMLBEANS-518: add support to XmlOptions to allow control over the XML parser settings that affect DTD loading
+and entity expansion
+
 Changes in V3.0.0 since V2.6.0
 
 * XMLBEANS-517: use safe XML parsers
diff --git a/src/common/org/apache/xmlbeans/impl/common/DocumentHelper.java b/src/common/org/apache/xmlbeans/impl/common/DocumentHelper.java
index 5b96667..fde0a84 100644
--- a/src/common/org/apache/xmlbeans/impl/common/DocumentHelper.java
+++ b/src/common/org/apache/xmlbeans/impl/common/DocumentHelper.java
@@ -25,6 +25,7 @@
 import javax.xml.parsers.ParserConfigurationException;
 import javax.xml.stream.events.Namespace;
 
+import org.apache.xmlbeans.XmlOptionsBean;
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
 import org.xml.sax.ErrorHandler;
@@ -77,12 +78,13 @@
     /**
      * Creates a new document builder, with sensible defaults
      *
+     * @param xmlOptions
      * @throws IllegalStateException If creating the DocumentBuilder fails, e.g.
      *  due to {@link ParserConfigurationException}.
      */
-    public static synchronized DocumentBuilder newDocumentBuilder() {
+    public static synchronized DocumentBuilder newDocumentBuilder(XmlOptionsBean xmlOptions) {
         try {
-            DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
+            DocumentBuilder documentBuilder = documentBuilderFactory(xmlOptions).newDocumentBuilder();
             documentBuilder.setEntityResolver(SAXHelper.IGNORING_ENTITY_RESOLVER);
             documentBuilder.setErrorHandler(new DocHelperErrorHandler());
             return documentBuilder;
@@ -91,14 +93,15 @@
         }
     }
 
-    private static final DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
-    static {
+    private static final DocumentBuilderFactory documentBuilderFactory(XmlOptionsBean options) {
+        DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
         documentBuilderFactory.setNamespaceAware(true);
         documentBuilderFactory.setValidating(false);
         trySetFeature(documentBuilderFactory, XMLConstants.FEATURE_SECURE_PROCESSING, true);
-        trySetFeature(documentBuilderFactory, XMLBeansConstants.FEATURE_LOAD_DTD_GRAMMAR, XMLBeansConstants.isLoadDtdGrammar());
-        trySetFeature(documentBuilderFactory, XMLBeansConstants.FEATURE_LOAD_EXTERNAL_DTD, XMLBeansConstants.isLoadExternalDtd());
-        trySetXercesSecurityManager(documentBuilderFactory);
+        trySetFeature(documentBuilderFactory, XMLBeansConstants.FEATURE_LOAD_DTD_GRAMMAR, options.isLoadDTDGrammar());
+        trySetFeature(documentBuilderFactory, XMLBeansConstants.FEATURE_LOAD_EXTERNAL_DTD, options.isLoadExternalDTD());
+        trySetXercesSecurityManager(documentBuilderFactory, options);
+        return documentBuilderFactory;
     }
 
     private static void trySetFeature(DocumentBuilderFactory dbf, String feature, boolean enabled) {
@@ -111,7 +114,7 @@
         }
     }
     
-    private static void trySetXercesSecurityManager(DocumentBuilderFactory dbf) {
+    private static void trySetXercesSecurityManager(DocumentBuilderFactory dbf, XmlOptionsBean options) {
         // Try built-in JVM one first, standalone if not
         for (String securityManagerClassName : new String[]{
                 //"com.sun.org.apache.xerces.internal.util.SecurityManager",
@@ -120,8 +123,8 @@
             try {
                 Object mgr = Class.forName(securityManagerClassName).newInstance();
                 Method setLimit = mgr.getClass().getMethod("setEntityExpansionLimit", Integer.TYPE);
-                setLimit.invoke(mgr, XMLBeansConstants.getEntityExpansionLimit());
-                dbf.setAttribute(XMLBeansConstants.XML_PROPERTY_SECURITY_MANAGER, mgr);
+                setLimit.invoke(mgr, options.getEntityExpansionLimit());
+                dbf.setAttribute(XMLBeansConstants.SECURITY_MANAGER, mgr);
                 // Stop once one can be setup without error
                 return;
             } catch (ClassNotFoundException e) {
@@ -132,7 +135,7 @@
         }
 
         // separate old version of Xerces not found => use the builtin way of setting the property
-        dbf.setAttribute(XMLBeansConstants.XML_PROPERTY_ENTITY_EXPANSION_LIMIT, XMLBeansConstants.getEntityExpansionLimit());
+        dbf.setAttribute(XMLBeansConstants.ENTITY_EXPANSION_LIMIT, options.getEntityExpansionLimit());
     }
 
     /**
@@ -141,8 +144,8 @@
      * @param inp Stream to read the XML data from
      * @return the parsed Document 
      */
-    public static Document readDocument(InputStream inp) throws IOException, SAXException {
-        return newDocumentBuilder().parse(inp);
+    public static Document readDocument(XmlOptionsBean xmlOptions, InputStream inp) throws IOException, SAXException {
+        return newDocumentBuilder(xmlOptions).parse(inp);
     }
 
     /**
@@ -151,12 +154,12 @@
      * @param inp sax source to read the XML data from
      * @return the parsed Document 
      */
-    public static Document readDocument(InputSource inp) throws IOException, SAXException {
-        return newDocumentBuilder().parse(inp);
+    public static Document readDocument(XmlOptionsBean xmlOptions, InputSource inp) throws IOException, SAXException {
+        return newDocumentBuilder(xmlOptions).parse(inp);
     }
 
     // must only be used to create empty documents, do not use it for parsing!
-    private static final DocumentBuilder documentBuilderSingleton = newDocumentBuilder();
+    private static final DocumentBuilder documentBuilderSingleton = newDocumentBuilder(new XmlOptionsBean());
 
     /**
      * Creates a new DOM Document
diff --git a/src/common/org/apache/xmlbeans/impl/common/LoadSaveUtils.java b/src/common/org/apache/xmlbeans/impl/common/LoadSaveUtils.java
index a80deff..d3f580b 100644
--- a/src/common/org/apache/xmlbeans/impl/common/LoadSaveUtils.java
+++ b/src/common/org/apache/xmlbeans/impl/common/LoadSaveUtils.java
@@ -39,7 +39,7 @@
     public static Document xmlText2GenericDom(InputStream is, Document emptyDoc)
             throws SAXException, ParserConfigurationException, IOException
     {
-        SAXParser parser = SAXHelper.saxFactory.newSAXParser();
+        SAXParser parser = SAXHelper.saxFactory().newSAXParser();
 
         Sax2Dom handler = new Sax2Dom(emptyDoc);
 
diff --git a/src/common/org/apache/xmlbeans/impl/common/SAXHelper.java b/src/common/org/apache/xmlbeans/impl/common/SAXHelper.java
index 5194331..e3040c9 100644
--- a/src/common/org/apache/xmlbeans/impl/common/SAXHelper.java
+++ b/src/common/org/apache/xmlbeans/impl/common/SAXHelper.java
@@ -24,6 +24,7 @@
 import javax.xml.parsers.ParserConfigurationException;
 import javax.xml.parsers.SAXParserFactory;
 
+import org.apache.xmlbeans.XmlOptionsBean;
 import org.xml.sax.EntityResolver;
 import org.xml.sax.InputSource;
 import org.xml.sax.SAXException;
@@ -41,30 +42,34 @@
     /**
      * Creates a new SAX XMLReader, with sensible defaults
      */
-    public static synchronized XMLReader newXMLReader() throws SAXException, ParserConfigurationException {
-        XMLReader xmlReader = saxFactory.newSAXParser().getXMLReader();
+    public static XMLReader newXMLReader(XmlOptionsBean options) throws SAXException, ParserConfigurationException {
+        XMLReader xmlReader = saxFactory(options).newSAXParser().getXMLReader();
         xmlReader.setEntityResolver(IGNORING_ENTITY_RESOLVER);
         trySetSAXFeature(xmlReader, XMLConstants.FEATURE_SECURE_PROCESSING);
-        trySetXercesSecurityManager(xmlReader);
+        trySetXercesSecurityManager(xmlReader, options);
         return xmlReader;
     }
     
-    static final EntityResolver IGNORING_ENTITY_RESOLVER = new EntityResolver() {
+    public static final EntityResolver IGNORING_ENTITY_RESOLVER = new EntityResolver() {
         @Override
         public InputSource resolveEntity(String publicId, String systemId)
                 throws SAXException, IOException {
             return new InputSource(new StringReader(""));
         }
     };
-    
-    static final SAXParserFactory saxFactory;
-    static {
-        saxFactory = SAXParserFactory.newInstance();
+
+    static SAXParserFactory saxFactory() {
+        return saxFactory(new XmlOptionsBean());
+    }
+
+    static SAXParserFactory saxFactory(XmlOptionsBean options) {
+        SAXParserFactory saxFactory = SAXParserFactory.newInstance();
         saxFactory.setValidating(false);
         saxFactory.setNamespaceAware(true);
         trySetSAXFeature(saxFactory, XMLConstants.FEATURE_SECURE_PROCESSING, true);
-        trySetSAXFeature(saxFactory, XMLBeansConstants.FEATURE_LOAD_DTD_GRAMMAR, XMLBeansConstants.isLoadDtdGrammar());
-        trySetSAXFeature(saxFactory, XMLBeansConstants.FEATURE_LOAD_EXTERNAL_DTD, XMLBeansConstants.isLoadExternalDtd());
+        trySetSAXFeature(saxFactory, XMLBeansConstants.FEATURE_LOAD_DTD_GRAMMAR, options.isLoadDTDGrammar());
+        trySetSAXFeature(saxFactory, XMLBeansConstants.FEATURE_LOAD_EXTERNAL_DTD, options.isLoadExternalDTD());
+        return saxFactory;
     }
 
     private static void trySetSAXFeature(SAXParserFactory spf, String feature, boolean flag) {
@@ -87,7 +92,7 @@
         }
     }
     
-    private static void trySetXercesSecurityManager(XMLReader xmlReader) {
+    private static void trySetXercesSecurityManager(XMLReader xmlReader, XmlOptionsBean options) {
         // Try built-in JVM one first, standalone if not
         for (String securityManagerClassName : new String[] {
                 //"com.sun.org.apache.xerces.internal.util.SecurityManager",
@@ -96,8 +101,8 @@
             try {
                 Object mgr = Class.forName(securityManagerClassName).newInstance();
                 Method setLimit = mgr.getClass().getMethod("setEntityExpansionLimit", Integer.TYPE);
-                setLimit.invoke(mgr, XMLBeansConstants.getEntityExpansionLimit());
-                xmlReader.setProperty(XMLBeansConstants.XML_PROPERTY_SECURITY_MANAGER, mgr);
+                setLimit.invoke(mgr, options.getEntityExpansionLimit());
+                xmlReader.setProperty(XMLBeansConstants.SECURITY_MANAGER, mgr);
                 // Stop once one can be setup without error
                 return;
             } catch (Throwable e) {     // NOSONAR - also catch things like NoClassDefError here
@@ -111,7 +116,7 @@
 
         // separate old version of Xerces not found => use the builtin way of setting the property
         try {
-            xmlReader.setProperty(XMLBeansConstants.XML_PROPERTY_ENTITY_EXPANSION_LIMIT, XMLBeansConstants.getEntityExpansionLimit());
+            xmlReader.setProperty(XMLBeansConstants.ENTITY_EXPANSION_LIMIT, options.getEntityExpansionLimit());
         } catch (SAXException e) {     // NOSONAR - also catch things like NoClassDefError here
             // throttle the log somewhat as it can spam the log otherwise
             if(System.currentTimeMillis() > lastLog + TimeUnit.MINUTES.toMillis(5)) {
diff --git a/src/common/org/apache/xmlbeans/impl/common/StaxHelper.java b/src/common/org/apache/xmlbeans/impl/common/StaxHelper.java
index fa29e2d..6b25293 100644
--- a/src/common/org/apache/xmlbeans/impl/common/StaxHelper.java
+++ b/src/common/org/apache/xmlbeans/impl/common/StaxHelper.java
@@ -19,6 +19,7 @@
 import javax.xml.stream.XMLInputFactory;
 import javax.xml.stream.XMLOutputFactory;
 
+import org.apache.xmlbeans.XmlOptionsBean;
 
 /**
  * Provides handy methods for working with StAX parsers and readers
@@ -31,19 +32,19 @@
     /**
      * Creates a new StAX XMLInputFactory, with sensible defaults
      */
-    public static XMLInputFactory newXMLInputFactory() {
+    public static XMLInputFactory newXMLInputFactory(XmlOptionsBean options) {
         XMLInputFactory factory = XMLInputFactory.newFactory();
         trySetProperty(factory, XMLInputFactory.IS_NAMESPACE_AWARE, true);
         trySetProperty(factory, XMLInputFactory.IS_VALIDATING, false);
-        trySetProperty(factory, XMLInputFactory.SUPPORT_DTD, XMLBeansConstants.isLoadDtdGrammar());
-        trySetProperty(factory, XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES, XMLBeansConstants.isLoadExternalDtd());
+        trySetProperty(factory, XMLInputFactory.SUPPORT_DTD, options.isLoadDTDGrammar());
+        trySetProperty(factory, XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES, options.isLoadExternalDTD());
         return factory;
     }
 
     /**
      * Creates a new StAX XMLOutputFactory, with sensible defaults
      */
-    public static XMLOutputFactory newXMLOutputFactory() {
+    public static XMLOutputFactory newXMLOutputFactory(XmlOptionsBean options) {
         XMLOutputFactory factory = XMLOutputFactory.newFactory();
         trySetProperty(factory, XMLOutputFactory.IS_REPAIRING_NAMESPACES, true);
         return factory;
@@ -52,7 +53,7 @@
     /**
      * Creates a new StAX XMLEventFactory, with sensible defaults
      */
-    public static XMLEventFactory newXMLEventFactory() {
+    public static XMLEventFactory newXMLEventFactory(XmlOptionsBean options) {
         return XMLEventFactory.newFactory();
     }
             
diff --git a/src/common/org/apache/xmlbeans/impl/common/XMLBeansConstants.java b/src/common/org/apache/xmlbeans/impl/common/XMLBeansConstants.java
index 5eaacbb..5326ad1 100644
--- a/src/common/org/apache/xmlbeans/impl/common/XMLBeansConstants.java
+++ b/src/common/org/apache/xmlbeans/impl/common/XMLBeansConstants.java
@@ -15,23 +15,11 @@
 
 package org.apache.xmlbeans.impl.common;
 
+import org.apache.xmlbeans.XmlOptions;
+
 public class XMLBeansConstants {
-    public static final String PROPERTY_ENTITY_EXPANSION_LIMIT = "xmlbeans.entity.expansion.limit";
-    public static final String PROPERTY_LOAD_DTD_GRAMMAR = "xmlbeans.load.dtd.grammar";
-    public static final String PROPERTY_LOAD_EXTERNAL_DTD = "xmlbeans.load.external.dtd";
-    public static final int DEFAULT_ENTITY_EXPANSION_LIMIT = 2048;
-    public static final String XML_PROPERTY_ENTITY_EXPANSION_LIMIT = "http://www.oracle.com/xml/jaxp/properties/entityExpansionLimit";
-    public static final String XML_PROPERTY_SECURITY_MANAGER = "http://apache.org/xml/properties/security-manager";
+    public static final String ENTITY_EXPANSION_LIMIT = "http://www.oracle.com/xml/jaxp/properties/entityExpansionLimit";
+    public static final String SECURITY_MANAGER = "http://apache.org/xml/properties/security-manager";
     public static final String FEATURE_LOAD_DTD_GRAMMAR = "http://apache.org/xml/features/nonvalidating/load-dtd-grammar";
     public static final String FEATURE_LOAD_EXTERNAL_DTD = "http://apache.org/xml/features/nonvalidating/load-external-dtd";
-
-    public static int getEntityExpansionLimit() {
-        return Integer.getInteger(PROPERTY_ENTITY_EXPANSION_LIMIT, DEFAULT_ENTITY_EXPANSION_LIMIT);
-    }
-    public static boolean isLoadDtdGrammar() {
-        return Boolean.getBoolean(PROPERTY_LOAD_DTD_GRAMMAR);
-    }
-    public static boolean isLoadExternalDtd() {
-        return Boolean.getBoolean(PROPERTY_LOAD_EXTERNAL_DTD);
-    }
 }
diff --git a/src/store/org/apache/xmlbeans/impl/store/Locale.java b/src/store/org/apache/xmlbeans/impl/store/Locale.java
index 359f63f..7e559c6 100755
--- a/src/store/org/apache/xmlbeans/impl/store/Locale.java
+++ b/src/store/org/apache/xmlbeans/impl/store/Locale.java
@@ -82,6 +82,7 @@
 import org.apache.xmlbeans.XmlException;
 import org.apache.xmlbeans.XmlObject;
 import org.apache.xmlbeans.XmlOptions;
+import org.apache.xmlbeans.XmlOptionsBean;
 import org.apache.xmlbeans.XmlSaxHandler;
 import org.apache.xmlbeans.SchemaType;
 import org.apache.xmlbeans.SchemaTypeLoader;
@@ -3051,7 +3052,7 @@
 
         if (xr == null) {
             try {
-                xr = SAXHelper.newXMLReader();
+                xr = SAXHelper.newXMLReader(new XmlOptionsBean(options));
             } catch(Exception e) {
                 throw new XmlException("Problem creating XMLReader", e);
             } 
diff --git a/src/xmlcomp/org/apache/xmlbeans/impl/tool/StreamInstanceValidator.java b/src/xmlcomp/org/apache/xmlbeans/impl/tool/StreamInstanceValidator.java
index 28d9731..f9a8367 100644
--- a/src/xmlcomp/org/apache/xmlbeans/impl/tool/StreamInstanceValidator.java
+++ b/src/xmlcomp/org/apache/xmlbeans/impl/tool/StreamInstanceValidator.java
@@ -20,6 +20,7 @@
 import org.apache.xmlbeans.XmlException;
 import org.apache.xmlbeans.XmlObject;
 import org.apache.xmlbeans.XmlOptions;
+import org.apache.xmlbeans.XmlOptionsBean;
 import org.apache.xmlbeans.XmlError;
 import org.apache.xmlbeans.impl.common.StaxHelper;
 import org.apache.xmlbeans.impl.validator.ValidatingXMLStreamReader;
@@ -40,8 +41,6 @@
 
 public class StreamInstanceValidator
 {
-    private static final XMLInputFactory XML_INPUT_FACTORY = StaxHelper.newXMLInputFactory();
-
     public static void printUsage()
     {
         System.out.println("Validates the specified instance against the specified schema.");
@@ -174,9 +173,11 @@
             errors.clear();
 
             try {
+                final XMLInputFactory xmlInputFactory = StaxHelper.newXMLInputFactory(new XmlOptionsBean(options));
+
                 final FileInputStream fis = new FileInputStream(file);
                 final XMLStreamReader rdr =
-                    XML_INPUT_FACTORY.createXMLStreamReader(path, fis);
+                        xmlInputFactory.createXMLStreamReader(path, fis);
 
                 //advance to first start element.
                 while(!rdr.isStartElement()) {
diff --git a/src/xmlpublic/org/apache/xmlbeans/XmlOptions.java b/src/xmlpublic/org/apache/xmlbeans/XmlOptions.java
index 6af8ceb..7b57fc3 100644
--- a/src/xmlpublic/org/apache/xmlbeans/XmlOptions.java
+++ b/src/xmlpublic/org/apache/xmlbeans/XmlOptions.java
@@ -613,7 +613,7 @@
     }
 
     /**
-     * By default, XmlBeans uses an internal Piccolo parser,
+     * By default, XmlBeans creates a JAXP parser,
      * other parsers can be used by providing an XMLReader.
      * For using the default JDK's SAX parser use:
      * xmlOptions.setLoadUseXMLReader( SAXParserFactory.newInstance().newSAXParser().getXMLReader() );
@@ -858,7 +858,7 @@
      */
     public XmlOptions setCopyUseNewSynchronizationDomain (boolean useNewSyncDomain)
     {
-        return set(COPY_USE_NEW_SYNC_DOMAIN, useNewSyncDomain ? Boolean.TRUE : Boolean.FALSE );
+        return set(COPY_USE_NEW_SYNC_DOMAIN, useNewSyncDomain);
     }
 
     /**
@@ -872,6 +872,41 @@
         return set(LOAD_ENTITY_BYTES_LIMIT,entityBytesLimit);
     }
 
+    /**
+     * Sets the maximum number of entity expansions allowed during parsing.
+     * The default value is 2048.
+     * @param entityExpansionLimit
+     * @return this
+     */
+    public XmlOptions setEntityExpansionLimit (int entityExpansionLimit)
+    {
+        return set(ENTITY_EXPANSION_LIMIT, entityExpansionLimit);
+    }
+
+    /**
+     * Controls whether DTD grammar is loaded during parsing.
+     * The default value is false.
+     *
+     * @param loadDTDGrammar
+     * @return this
+     */
+    public XmlOptions setLoadDTDGrammar (boolean loadDTDGrammar)
+    {
+        return set(LOAD_DTD_GRAMMAR, loadDTDGrammar);
+    }
+
+    /**
+     * Controls whether external DTDs are loaded during parsing.
+     * The default value is false.
+     *
+     * @param loadExternalDTD
+     * @return this
+     */
+    public XmlOptions setLoadExternalDTD (boolean loadExternalDTD)
+    {
+        return set(LOAD_EXTERNAL_DTD, loadExternalDTD);
+    }
+
     public static final String GENERATE_JAVA_14 = "1.4";
     public static final String GENERATE_JAVA_15 = "1.5";
 
@@ -996,6 +1031,14 @@
     public static final String COPY_USE_NEW_SYNC_DOMAIN        = "COPY_USE_NEW_LOCALE";
     /** @exclude */
     public static final String LOAD_ENTITY_BYTES_LIMIT         = "LOAD_ENTITY_BYTES_LIMIT";
+    /** @exclude */
+    public static final String ENTITY_EXPANSION_LIMIT          = "ENTITY_EXPANSION_LIMIT";
+    /** @exclude */
+    public static final String LOAD_DTD_GRAMMAR                = "LOAD_DTD_GRAMMAR";
+    /** @exclude */
+    public static final String LOAD_EXTERNAL_DTD               = "LOAD_EXTERNAL_DTD";
+
+    public static final int DEFAULT_ENTITY_EXPANSION_LIMIT = 2048;
 
     private static final XmlOptions EMPTY_OPTIONS;
     static {
diff --git a/src/xmlpublic/org/apache/xmlbeans/XmlOptionsBean.java b/src/xmlpublic/org/apache/xmlbeans/XmlOptionsBean.java
index 6a4642c..f414439 100644
--- a/src/xmlpublic/org/apache/xmlbeans/XmlOptionsBean.java
+++ b/src/xmlpublic/org/apache/xmlbeans/XmlOptionsBean.java
@@ -442,4 +442,22 @@
     {

         return (String) get( GENERATE_JAVA_VERSION );

     }

+

+    public int getEntityExpansionLimit()

+    {

+        Integer limit = (Integer) get( ENTITY_EXPANSION_LIMIT );

+        return limit == null ? DEFAULT_ENTITY_EXPANSION_LIMIT : limit;

+    }

+

+    public boolean isLoadDTDGrammar()

+    {

+        Boolean flag = (Boolean) get( LOAD_DTD_GRAMMAR );

+        return flag == null ? false : flag;

+    }

+

+    public boolean isLoadExternalDTD()

+    {

+        Boolean flag = (Boolean) get( LOAD_EXTERNAL_DTD );

+        return flag == null ? false : flag;

+    }

 }

diff --git a/test/src/dom/checkin/ParserTest.java b/test/src/dom/checkin/ParserTest.java
index c3a3e9d..9e82a08 100755
--- a/test/src/dom/checkin/ParserTest.java
+++ b/test/src/dom/checkin/ParserTest.java
@@ -16,11 +16,16 @@
 
 package dom.checkin;
 
+import java.io.ByteArrayInputStream;
+import javax.xml.XMLConstants;
 import javax.xml.stream.XMLInputFactory;
 
 import junit.framework.*;
 
+import org.apache.xmlbeans.XmlOptionsBean;
 import org.apache.xmlbeans.impl.common.*;
+import org.xml.sax.InputSource;
+import org.xml.sax.XMLReader;
 
 /**
  * Tests for XML Parser settings
@@ -28,29 +33,26 @@
 
 public class ParserTest extends TestCase {
 
-    public void testXMLBeansConstantsDefaults() {
-        assertEquals(2048, XMLBeansConstants.getEntityExpansionLimit());
-        assertFalse(XMLBeansConstants.isLoadDtdGrammar());
-        assertFalse(XMLBeansConstants.isLoadExternalDtd());
+    public void testXmlOptionsDefaults() {
+        XmlOptionsBean options = new XmlOptionsBean();
+        assertEquals(2048, options.getEntityExpansionLimit());
+        assertFalse(options.isLoadDTDGrammar());
+        assertFalse(options.isLoadExternalDTD());
     }
 
     public void testXMLBeansConstantsOverrides() {
-        try {
-            System.setProperty(XMLBeansConstants.PROPERTY_ENTITY_EXPANSION_LIMIT, "1");
-            System.setProperty(XMLBeansConstants.PROPERTY_LOAD_DTD_GRAMMAR, "true");
-            System.setProperty(XMLBeansConstants.PROPERTY_LOAD_EXTERNAL_DTD, "true");
-            assertEquals(1, XMLBeansConstants.getEntityExpansionLimit());
-            assertTrue(XMLBeansConstants.isLoadDtdGrammar());
-            assertTrue(XMLBeansConstants.isLoadExternalDtd());
-        } finally {
-            System.clearProperty(XMLBeansConstants.PROPERTY_ENTITY_EXPANSION_LIMIT);
-            System.clearProperty(XMLBeansConstants.PROPERTY_LOAD_DTD_GRAMMAR);
-            System.clearProperty(XMLBeansConstants.PROPERTY_LOAD_EXTERNAL_DTD);
-        }
+        XmlOptionsBean options = new XmlOptionsBean();
+        options.setEntityExpansionLimit(1);
+        options.setLoadDTDGrammar(true);
+        options.setLoadExternalDTD(true);
+        assertEquals(1, options.getEntityExpansionLimit());
+        assertTrue(options.isLoadDTDGrammar());
+        assertTrue(options.isLoadExternalDTD());
     }
 
     public void testXmlInputFactoryPropertyDefaults() {
-        XMLInputFactory factory = StaxHelper.newXMLInputFactory();
+        XmlOptionsBean options = new XmlOptionsBean();
+        XMLInputFactory factory = StaxHelper.newXMLInputFactory(options);
         assertEquals(true, factory.getProperty(XMLInputFactory.IS_NAMESPACE_AWARE));
         assertEquals(false, factory.getProperty(XMLInputFactory.IS_VALIDATING));
         assertEquals(false, factory.getProperty(XMLInputFactory.SUPPORT_DTD));
@@ -58,15 +60,39 @@
     }
 
     public void testXmlInputFactoryPropertyOverrides() {
-        try {
-            System.setProperty(XMLBeansConstants.PROPERTY_LOAD_DTD_GRAMMAR, "true");
-            System.setProperty(XMLBeansConstants.PROPERTY_LOAD_EXTERNAL_DTD, "true");
-            XMLInputFactory factory = StaxHelper.newXMLInputFactory();
-            assertEquals(true, factory.getProperty(XMLInputFactory.SUPPORT_DTD));
-            assertEquals(true, factory.getProperty(XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES));
-        } finally {
-            System.clearProperty(XMLBeansConstants.PROPERTY_LOAD_DTD_GRAMMAR);
-            System.clearProperty(XMLBeansConstants.PROPERTY_LOAD_EXTERNAL_DTD);
-        }
+        XmlOptionsBean options = new XmlOptionsBean();
+        options.setEntityExpansionLimit(1);
+        options.setLoadDTDGrammar(true);
+        options.setLoadExternalDTD(true);
+        XMLInputFactory factory = StaxHelper.newXMLInputFactory(options);
+        assertEquals(true, factory.getProperty(XMLInputFactory.SUPPORT_DTD));
+        assertEquals(true, factory.getProperty(XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES));
+    }
+
+    public void testXMLReader() throws Exception {
+        XmlOptionsBean options = new XmlOptionsBean();
+        XMLReader reader = SAXHelper.newXMLReader(options);
+        assertNotSame(reader, SAXHelper.newXMLReader(options));
+        assertFalse(reader.getFeature(XMLBeansConstants.FEATURE_LOAD_DTD_GRAMMAR));
+        assertFalse(reader.getFeature(XMLBeansConstants.FEATURE_LOAD_EXTERNAL_DTD));
+        assertEquals(SAXHelper.IGNORING_ENTITY_RESOLVER, reader.getEntityResolver());
+        assertNotNull(reader.getProperty(XMLBeansConstants.SECURITY_MANAGER));
+
+        reader.parse(new InputSource(new ByteArrayInputStream("<xml></xml>".getBytes("UTF-8"))));
+    }
+
+    public void testXMLReaderOverrides() throws Exception {
+        XmlOptionsBean options = new XmlOptionsBean();
+        options.setEntityExpansionLimit(1);
+        options.setLoadDTDGrammar(true);
+        options.setLoadExternalDTD(true);
+        XMLReader reader = SAXHelper.newXMLReader(options);
+        assertNotSame(reader, SAXHelper.newXMLReader(options));
+        assertTrue(reader.getFeature(XMLBeansConstants.FEATURE_LOAD_DTD_GRAMMAR));
+        assertTrue(reader.getFeature(XMLBeansConstants.FEATURE_LOAD_EXTERNAL_DTD));
+        assertEquals(SAXHelper.IGNORING_ENTITY_RESOLVER, reader.getEntityResolver());
+        assertNotNull(reader.getProperty(XMLBeansConstants.SECURITY_MANAGER));
+
+        reader.parse(new InputSource(new ByteArrayInputStream("<xml></xml>".getBytes("UTF-8"))));
     }
 }
diff --git a/test/src/misc/common/ParsersBase.java b/test/src/misc/common/ParsersBase.java
index e24d8f7..96bd523 100644
--- a/test/src/misc/common/ParsersBase.java
+++ b/test/src/misc/common/ParsersBase.java
@@ -40,16 +40,10 @@
     // System Property                               Parser                        Value

     // ----------------------------------------------------------------------------------------------------------

     // javax.xml.parsers.DocumentBuilderFactory     Xerces              org.apache.xerces.jaxp.DocumentBuilderFactoryImpl

-    //                                              Crimson             org.apache.crimson.jaxp.DocumentBuilderFactoryImpl

-    //                                              Piccolo             NA

     //

     // org.xml.sax.driver                           Xerces              org.apache.xerces.parsers.SAXParser

-    //                                              Crimson             org.apache.crimson.parser.XmlReaderImpl

-    //                                              Piccolo (Xbeans)    org.apache.xmlbeans.impl.piccolo.xml.Piccolo

     //

     // javax.xml.parsers.SAXParserFactory           Xerces              org.apache.xerces.jaxp.SAXParserFactoryImpl

-    //                                              Crimson             org.apache.crimson.jaxp.SAXParserFactoryImpl

-    //                                              Piccolo (XBeans)    org.apache.xmlbeans.impl.piccolo.xml.JAXPSAXParserFactory

     // ----------------------------------------------------------------------------------------------------------

 

 

diff --git a/test/src/misc/detailed/CharEncodingTest.java b/test/src/misc/detailed/CharEncodingTest.java
index c25209e..048e6d4 100644
--- a/test/src/misc/detailed/CharEncodingTest.java
+++ b/test/src/misc/detailed/CharEncodingTest.java
@@ -33,38 +33,16 @@
         String I18N_test_string1 = "<i18n xmlns:\u00c1\u00c1\u00c1=\"\u00c1\u00c1\u00c1\" type=\"\u00c1\u00c1\u00c1:t\"/>";

         String I18N_test_string2 = "<i18n xmlns:\u30af\u30af\u30af=\"\u30af\u30af\u30af\" type=\"\u30af\u30af\u30af:t\"/>";

 

-        // Test all 3 parsers with string 1, this is a valid string and should pass

-        parseXmlWithSAXAPI(I18N_test_string1,

-                "Crimson",

-                "org.apache.crimson.parser.XmlReaderImpl",

-                "org.apache.crimson.jaxp.SAXParserFactoryImpl");

-

         parseXmlWithSAXAPI(I18N_test_string1,

                 "Xerces",

                 "org.apache.xerces.parsers.SAXParser",

                 "org.apache.xerces.jaxp.SAXParserFactoryImpl");

 

-        parseXmlWithSAXAPI(I18N_test_string1,

-                "Piccolo",

-                "org.apache.xmlbeans.impl.piccolo.xml.Piccolo",

-                "org.apache.xmlbeans.impl.piccolo.xml.JAXPSAXParserFactory");

-

-        // Now test all 3 parsers with string 2, this is a valid string and should pass but piccolo fails

-        parseXmlWithSAXAPI(I18N_test_string2,

-                "Crimson",

-                "org.apache.crimson.parser.XmlReaderImpl",

-                "org.apache.crimson.jaxp.SAXParserFactoryImpl");

-

         parseXmlWithSAXAPI(I18N_test_string2,

                 "Xerces",

                 "org.apache.xerces.parsers.SAXParser",

                 "org.apache.xerces.jaxp.SAXParserFactoryImpl");

 

-        parseXmlWithSAXAPI(I18N_test_string2,

-                "Piccolo",

-                "org.apache.xmlbeans.impl.piccolo.xml.Piccolo",

-                "org.apache.xmlbeans.impl.piccolo.xml.JAXPSAXParserFactory");

-

     }

 

     // Piccolo has an issue with handling external identifiers when the value is PUBLIC

@@ -83,17 +61,6 @@
                 "org.apache.xerces.parsers.SAXParser",

                 "org.apache.xerces.jaxp.SAXParserFactoryImpl");

 

-        parseXmlWithSAXAPI(netPubEntity,

-                "Piccolo",

-                "org.apache.xmlbeans.impl.piccolo.xml.Piccolo",

-                "org.apache.xmlbeans.impl.piccolo.xml.JAXPSAXParserFactory");

-

-        parseXmlWithSAXAPI(netPubEntity,

-                "Crimson",

-                "org.apache.crimson.parser.XmlReaderImpl",

-                "org.apache.crimson.jaxp.SAXParserFactoryImpl");

-

-

         // parse same string using scomp

         XmlOptions options = new XmlOptions();

         List errors = new ArrayList();