Index: project.properties
===================================================================
--- project.properties (Revision 0)
+++ project.properties (Revision 0)
@@ -0,0 +1,18 @@
+#
+# Copyright 2006 The Apache Software Foundation.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+#maven.junit.fork = yes
+maven.junit.sysproperties = javax.xml.parsers.DocumentBuilderFactory
+javax.xml.parsers.DocumentBuilderFactory=org.apache.xerces.jaxp.DocumentBuilderFactoryImpl
Index: project.xml
===================================================================
--- project.xml (Revision 377229)
+++ project.xml (Arbeitskopie)
@@ -1,6 +1,6 @@
@@ -56,6 +66,16 @@
+ */ +public class XMLTest extends AbstractTest { + + /** "http://www.w3.org/2001/XMLSchema" */ + protected static final String XSD_TYPE = + "http://www.w3.org/2001/XMLSchema"; + + /** */ + protected static final String SCHEMA_LANGUAGE_PROP = + "http://java.sun.com/xml/jaxp/properties/schemaLanguage"; + + /** */ + protected static final String SCHEMA_LOCATION_PROP = + "http://apache.org/xml/properties/schema/external-noNamespaceSchemaLocation"; + + /** */ + protected static final String XSD_FILE_URI = + "file:target/classes/javax/jdo/jdo.xsd"; + + /** File prefix */ + protected static final String FILE_PREFIX = "test/schema/"; + + /** Entity resolver */ + protected static final EntityResolver resolver = new JDOEntityResolver(); + + /** Error handler */ + protected static final Handler handler = new Handler(); + + /** XSD metadata files. */ + protected static File[] positiveXSDJDO = getFiles("Positive", "-xsd.jdo"); + protected static File[] negativeXSDJDO = getFiles("Negative", "-xsd.jdo"); + protected static File[] positiveXSDORM = getFiles("Positive", "-xsd.orm"); + protected static File[] negativeXSDORM = getFiles("Negative", "-xsd.orm"); + protected static File[] positiveXSDJDOQUERY = getFiles("Positive", "-xsd.jdoquery"); + protected static File[] negativeXSDJDOQUERY = getFiles("Negative", "-xsd.jdoquery"); + + /** DTD metadata files. */ + protected static File[] positiveDTDJDO = getFiles("Positive", "-dtd.jdo"); + protected static File[] negativeDTDJDO = getFiles("Negative", "-dtd.jdo"); + protected static File[] positiveDTDORM = getFiles("Positive", "-dtd.orm"); + protected static File[] negativeDTDORM = getFiles("Negative", "-dtd.orm"); + protected static File[] positiveDTDJDOQUERY = getFiles("Positive", "-dtd.jdoquery"); + protected static File[] negativeDTDJDOQUERY = getFiles("Negative", "-dtd.jdoquery"); + + /** Returns array of files of matching file names. */ + protected static File[] getFiles(final String prefix, final String suffix) { + FilenameFilter filter = new FilenameFilter () { + public boolean accept(File file, String name) { + return (name.startsWith(prefix) && name.endsWith(suffix)); + } + }; + File dir = new File(FILE_PREFIX); + return dir.listFiles(filter); + } + + /** */ + public static void main(String args[]) { + BatchTestRunner.run(XMLTest.class); + } + + /** Test XSD. */ + public void testXSD() throws SAXException, IOException { + // create XSD parser + DocumentBuilderFactory factory = getParserFactory(); + factory.setAttribute(SCHEMA_LANGUAGE_PROP, XSD_TYPE); + factory.setAttribute(SCHEMA_LOCATION_PROP, XSD_FILE_URI); + DocumentBuilder builder = getParser(factory); + // check xsd based files + initMessages(); + checkXML(builder, positiveXSDJDO, true); + checkXML(builder, negativeXSDJDO, false); + checkXML(builder, positiveXSDORM, true); + checkXML(builder, negativeXSDORM, false); + checkXML(builder, positiveXSDJDOQUERY, true); + checkXML(builder, negativeXSDJDOQUERY, false); + if (hasMessages()) { + fail(getMessages()); + } + } + + /** Test DTD. */ + public void testDTD() throws SAXException, IOException { + // create DTD parser + DocumentBuilderFactory factory = getParserFactory(); + DocumentBuilder builder = getParser(factory); + // check dtd based files + initMessages(); + checkXML(builder, positiveDTDJDO, true); + checkXML(builder, negativeDTDJDO, false); + checkXML(builder, positiveDTDORM, true); + checkXML(builder, negativeDTDORM, false); + checkXML(builder, positiveDTDJDOQUERY, true); + checkXML(builder, negativeDTDJDOQUERY, false); + if (hasMessages()) { + fail(getMessages()); + } + } + + /** */ + private void checkXML(DocumentBuilder builder, File[] files, boolean valid) { + for (int i = 0; i < files.length; i++) { + try { + handler.init(files[i].getName()); + builder.parse(files[i]); + String messages = handler.getMessages(); + if (valid && (messages != null)) { + appendMessage(messages); + } else if (!valid && (messages == null)) { + appendMessage(files[i].getName() + " is not valid, " + + "but the parser did not catch the error."); + } + } catch (Exception ex) { + throw new JDOFatalException("Fatal error:", ex); + } + } + } + + /** Returns parser factory. */ + private DocumentBuilderFactory getParserFactory() { + DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); + factory.setValidating(true); + factory.setNamespaceAware(true); + return factory; + } + + /** Returns a parser obtained from specified factroy. */ + private DocumentBuilder getParser(DocumentBuilderFactory factory) { + try { + DocumentBuilder builder = factory.newDocumentBuilder(); + builder.setEntityResolver(resolver); + builder.setErrorHandler(handler); + return builder; + } catch (ParserConfigurationException ex) { + throw new JDOFatalException("Cannot create XML parser", ex); + } + } + + /** */ + private static class Handler implements ErrorHandler { + + private String filename; + private StringBuffer messages; + + public void error(SAXParseException ex) { + append(filename, ex); + } + + public void fatalError(SAXParseException ex) throws SAXException { + throw ex; + } + + public void warning(SAXParseException ex) { + append(filename, ex); + } + + public void init(String filename) { + this.filename = filename; + this.messages = new StringBuffer(); + } + + public String getMessages() { + return (messages.length() == 0) ? null : messages.toString(); + } + + private void append(String prefix, SAXParseException ex) { + if (messages.length() > 0) { + messages.append("\n"); + } + messages.append(prefix); + messages.append(" [" + ex.getPublicId() + ", " + ex.getSystemId() + "] "); + messages.append("[" + ex.getLineNumber() + ", " + ex.getColumnNumber() + "] "); + messages.append(ex.getMessage()); + } + } + + /** Implementation of EntityResolver interface to check the jdo.dtd location + **/ + private static class JDOEntityResolver + implements EntityResolver { + + private static final String RECOGNIZED_PUBLIC_ID = + "-//Sun Microsystems, Inc.//DTD Java Data Objects Metadata 2.0//EN"; + private static final String RECOGNIZED_SYSTEM_ID = + "file:/javax/jdo/jdo.dtd"; + + public InputSource resolveEntity(String publicId, final String systemId) + throws SAXException, IOException + { + // check for recognized ids + if (((publicId != null) && RECOGNIZED_PUBLIC_ID.equals(publicId)) || + ((publicId == null) && (systemId != null) && + RECOGNIZED_SYSTEM_ID.equals(systemId))) { + // Substitute the dtd with the one from javax.jdo.jdo.dtd, + // but only if the publicId is equal to RECOGNIZED_PUBLIC_ID + // or there is no publicID and the systemID is equal to + // RECOGNIZED_SYSTEM_ID. + InputStream stream = (InputStream) AccessController.doPrivileged ( + new PrivilegedAction () { + public Object run () { + return getClass().getClassLoader(). + getResourceAsStream("javax/jdo/jdo.dtd"); + } + } + ); + if (stream == null) { + // TDB: error handling + I18N + throw new RuntimeException("Cannot load javax/jdo/jdo.dtd, because the file does not exist in the jdo.jar file, or the JDOParser class is not granted permission to read this file. The metadata .xml file contained PUBLIC=" + publicId + " SYSTEM=" + systemId + "."); // NOI18N + } + return new InputSource(new InputStreamReader(stream)); + } + return null; + } + } +} Index: test/java/javax/jdo/util/AbstractTest.java =================================================================== --- test/java/javax/jdo/util/AbstractTest.java (Revision 377229) +++ test/java/javax/jdo/util/AbstractTest.java (Arbeitskopie) @@ -43,5 +43,38 @@ if (verbose) out.println(s); } + + /** Keep track of error messages. + */ + protected static StringBuffer messages; + + /** Initialize messages. + */ + protected static void initMessages() { + messages = new StringBuffer(); + } + + /** Append to error messages. + */ + protected static void appendMessage(String message) { + if (messages == null) { + initMessages(); + } else if (messages.length() > 0) { + messages.append("\n"); + } + messages.append(message); + } + + /** Return true if there are any messages stored. + */ + protected static boolean hasMessages() { + return (messages != null) && (messages.length() > 0); + } + + /** Return messages. + */ + protected static String getMessages() { + return (messages == null) ? null : messages.toString(); + } }