Index: api2/src/java/javax/jdo/spi/JDOImplHelper.java =================================================================== --- api2/src/java/javax/jdo/spi/JDOImplHelper.java (revision 546169) +++ api2/src/java/javax/jdo/spi/JDOImplHelper.java (working copy) @@ -22,6 +22,8 @@ package javax.jdo.spi; +import org.xml.sax.ErrorHandler; + import java.lang.reflect.Constructor; import java.text.DateFormat; @@ -45,6 +47,7 @@ import javax.jdo.JDOFatalInternalException; import javax.jdo.JDOFatalUserException; import javax.jdo.JDOUserException; +import javax.xml.parsers.DocumentBuilderFactory; /** This class is a helper class for JDO implementations. It contains methods * to register metadata for persistence-capable classes and to perform common @@ -104,6 +107,16 @@ */ private static DateFormat dateFormat; + /** + * The DocumentBuilderFactory used during jdoconfig.xml parsing. + */ + private static DocumentBuilderFactory documentBuilderFactory; + + /** + * The ErrorHandler used during jdoconfig.xml parsing. + */ + private static ErrorHandler errorHandler; + /** Register the default DateFormat instance. */ static { @@ -530,6 +543,37 @@ } } + /** + * Register a DocumentBuilderFactory instance for use in parsing the + * resource(s) META-INF/jdoconfig.xml. The default is governed by the + * semantics of DocumentBuilderFactory.newInstance(). + * + * @param factory the DocumentBuilderFactory instance to use + */ + public synchronized void registerDocumentBuilderFactory( + DocumentBuilderFactory factory) { + documentBuilderFactory = factory; + } + + public static DocumentBuilderFactory getRegisteredDocumentBuilderFactory() { + return documentBuilderFactory; + } + + /** + * Register an ErrorHandler instance for use in parsing the + * resource(s) META-INF/jdoconfig.xml. The default is an ErrorHandler + * that throws on error or fatalError and ignores warnings. + * + * @param handler the ErrorHandler instance to use + */ + public synchronized void registerErrorHandler(ErrorHandler handler) { + errorHandler = handler; + } + + public static ErrorHandler getRegisteredErrorHandler() { + return errorHandler; + } + /** Check that the parameter instance is of a class that is authorized for * JDOPermission("setStateManager"). This method is called by the * replaceStateManager method in persistence-capable classes. Index: api2/src/java/javax/jdo/JDOHelper.java =================================================================== --- api2/src/java/javax/jdo/JDOHelper.java (revision 546169) +++ api2/src/java/javax/jdo/JDOHelper.java (working copy) @@ -1018,14 +1018,11 @@ ArrayList processedResources = new ArrayList(); // get ready to parse XML - DocumentBuilderFactory factory = null; - // TODO: ensure DBF is initialized properly - factory = DocumentBuilderFactory.newInstance(); - factory.setIgnoringComments(true); - factory.setNamespaceAware(true); - factory.setValidating(false); - factory.setIgnoringElementContentWhitespace(true); - factory.setExpandEntityReferences(true); + DocumentBuilderFactory factory = + implHelper.getRegisteredDocumentBuilderFactory(); + if (factory == null) { + factory = getDefaultDocumentBuilderFactory(); + } do { URL currentConfigURL = (URL) resources.nextElement(); @@ -1077,6 +1074,36 @@ } + protected static DocumentBuilderFactory getDefaultDocumentBuilderFactory() { + DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); + factory.setIgnoringComments(true); + factory.setNamespaceAware(true); + factory.setValidating(false); + factory.setIgnoringElementContentWhitespace(true); + factory.setExpandEntityReferences(true); + + return factory; + } + + protected static ErrorHandler getDefaultErrorHandler() { + return new ErrorHandler() { + public void error(SAXParseException exception) + throws SAXException { + throw exception; + } + + public void fatalError(SAXParseException exception) + throws SAXException { + throw exception; + } + + public void warning(SAXParseException exception) + throws SAXException { + // gulp: ignore warnings + } + }; + } + /** * Convenience method for retrieving the JPA persistence unit by the given * name. This method is equivalent to Index: api2-legacy/src/java/javax/jdo/spi/JDOImplHelper.java =================================================================== --- api2-legacy/src/java/javax/jdo/spi/JDOImplHelper.java (revision 546169) +++ api2-legacy/src/java/javax/jdo/spi/JDOImplHelper.java (working copy) @@ -22,6 +22,8 @@ package javax.jdo.spi; +import org.xml.sax.ErrorHandler; + import java.lang.reflect.Constructor; import java.text.DateFormat; @@ -45,6 +47,7 @@ import javax.jdo.JDOFatalInternalException; import javax.jdo.JDOFatalUserException; import javax.jdo.JDOUserException; +import javax.xml.parsers.DocumentBuilderFactory; /** This class is a helper class for JDO implementations. It contains methods * to register metadata for persistence-capable classes and to perform common @@ -104,6 +107,16 @@ */ private static DateFormat dateFormat; + /** + * The DocumentBuilderFactory used during jdoconfig.xml parsing. + */ + private static DocumentBuilderFactory documentBuilderFactory; + + /** + * The ErrorHandler used during jdoconfig.xml parsing. + */ + private static ErrorHandler errorHandler; + /** Register the default DateFormat instance. */ static { @@ -530,6 +543,37 @@ } } + /** + * Register a DocumentBuilderFactory instance for use in parsing the + * resource(s) META-INF/jdoconfig.xml. The default is governed by the + * semantics of DocumentBuilderFactory.newInstance(). + * + * @param factory the DocumentBuilderFactory instance to use + */ + public synchronized void registerDocumentBuilderFactory( + DocumentBuilderFactory factory) { + documentBuilderFactory = factory; + } + + public static DocumentBuilderFactory getRegisteredDocumentBuilderFactory() { + return documentBuilderFactory; + } + + /** + * Register an ErrorHandler instance for use in parsing the + * resource(s) META-INF/jdoconfig.xml. The default is an ErrorHandler + * that throws on error or fatalError and ignores warnings. + * + * @param handler the ErrorHandler instance to use + */ + public synchronized void registerErrorHandler(ErrorHandler handler) { + errorHandler = handler; + } + + public static ErrorHandler getRegisteredErrorHandler() { + return errorHandler; + } + /** Check that the parameter instance is of a class that is authorized for * JDOPermission("setStateManager"). This method is called by the * replaceStateManager method in persistence-capable classes. Index: api2-legacy/src/java/javax/jdo/JDOHelper.java =================================================================== --- api2-legacy/src/java/javax/jdo/JDOHelper.java (revision 546169) +++ api2-legacy/src/java/javax/jdo/JDOHelper.java (working copy) @@ -1018,14 +1018,11 @@ ArrayList processedResources = new ArrayList(); // get ready to parse XML - DocumentBuilderFactory factory = null; - // TODO: ensure DBF is initialized properly - factory = DocumentBuilderFactory.newInstance(); - factory.setIgnoringComments(true); - factory.setNamespaceAware(true); - factory.setValidating(false); - factory.setIgnoringElementContentWhitespace(true); - factory.setExpandEntityReferences(true); + DocumentBuilderFactory factory = + implHelper.getRegisteredDocumentBuilderFactory(); + if (factory == null) { + factory = getDefaultDocumentBuilderFactory(); + } do { URL currentConfigURL = (URL) resources.nextElement(); @@ -1077,6 +1074,36 @@ } + protected static DocumentBuilderFactory getDefaultDocumentBuilderFactory() { + DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); + factory.setIgnoringComments(true); + factory.setNamespaceAware(true); + factory.setValidating(false); + factory.setIgnoringElementContentWhitespace(true); + factory.setExpandEntityReferences(true); + + return factory; + } + + protected static ErrorHandler getDefaultErrorHandler() { + return new ErrorHandler() { + public void error(SAXParseException exception) + throws SAXException { + throw exception; + } + + public void fatalError(SAXParseException exception) + throws SAXException { + throw exception; + } + + public void warning(SAXParseException exception) + throws SAXException { + // gulp: ignore warnings + } + }; + } + /** * Convenience method for retrieving the JPA persistence unit by the given * name. This method is equivalent to