You are viewing a plain text version of this content. The canonical link for it is here.
Posted to jdo-commits@db.apache.org by mb...@apache.org on 2006/03/06 23:02:53 UTC
svn commit: r383687 - in /db/jdo/trunk/api20: maven.xml project.properties
project.xml test/java/javax/jdo/schema/XMLTest.java
test/java/javax/jdo/util/AbstractTest.java
test/java/javax/jdo/util/XMLTestUtil.java test/schema/Positive99-xsd.jdoquery
Author: mbo
Date: Mon Mar 6 14:02:51 2006
New Revision: 383687
URL: http://svn.apache.org/viewcvs?rev=383687&view=rev
Log:
JDO-319: Enhance api20 XMLTest so that users can check their own .jdo .orm, and .jdoquery files
Added:
db/jdo/trunk/api20/test/java/javax/jdo/util/XMLTestUtil.java
Modified:
db/jdo/trunk/api20/maven.xml
db/jdo/trunk/api20/project.properties
db/jdo/trunk/api20/project.xml
db/jdo/trunk/api20/test/java/javax/jdo/schema/XMLTest.java
db/jdo/trunk/api20/test/java/javax/jdo/util/AbstractTest.java
db/jdo/trunk/api20/test/schema/Positive99-xsd.jdoquery
Modified: db/jdo/trunk/api20/maven.xml
URL: http://svn.apache.org/viewcvs/db/jdo/trunk/api20/maven.xml?rev=383687&r1=383686&r2=383687&view=diff
==============================================================================
--- db/jdo/trunk/api20/maven.xml (original)
+++ db/jdo/trunk/api20/maven.xml Mon Mar 6 14:02:51 2006
@@ -45,4 +45,27 @@
</delete>
</goal>
+ <!-- ======== -->
+ <!-- XML test -->
+ <!-- ======== -->
+
+ <!-- Run XML parser on JDO metadata files (suffix .jdo, .orm or .jdoquery). -->
+ <!-- The tool uses the following system properties: -->
+ <!-- javax.jdo.metadata: a comma separated list of JDO metadata files or directories. -->
+ <!-- javax.jdo.recursive: recursively serach directories. -->
+ <goal name="xmltest" prereqs="test:compile">
+ <java classname="javax.jdo.util.XMLTestUtil" fork="true">
+ <classpath>
+ <pathelement location="${xmlapis.jarfile}"/>
+ <pathelement location="${xerces.jarfile}"/>
+ <pathelement location="${maven.build.dir}/classes"/>
+ <pathelement location="${maven.build.dir}/test-classes"/>
+ </classpath>
+ <sysproperty key="javax.jdo.metadata" value="${javax.jdo.metadata}"/>
+ <sysproperty key="javax.jdo.recursive" value="${javax.jdo.recursive}"/>
+ <sysproperty key="javax.xml.parsers.DocumentBuilderFactory"
+ value="${javax.xml.parsers.DocumentBuilderFactory}"/>
+ </java>
+ </goal>
+
</project>
Modified: db/jdo/trunk/api20/project.properties
URL: http://svn.apache.org/viewcvs/db/jdo/trunk/api20/project.properties?rev=383687&r1=383686&r2=383687&view=diff
==============================================================================
--- db/jdo/trunk/api20/project.properties (original)
+++ db/jdo/trunk/api20/project.properties Mon Mar 6 14:02:51 2006
@@ -16,5 +16,9 @@
maven.junit.sysproperties = javax.xml.parsers.DocumentBuilderFactory basedir
javax.xml.parsers.DocumentBuilderFactory=org.apache.xerces.jaxp.DocumentBuilderFactoryImpl
+xmlapis.jarfile = ${pom.getDependencyPath('xml-apis:xml-apis')}
+xerces.jarfile = ${pom.getDependencyPath('xerces:xerces')}
+junit.jarfile = ${pom.getDependencyPath('junit:junit')}
+
# Manifest seed file
maven.jar.manifest = ${basedir}/../JDO20.MF
Modified: db/jdo/trunk/api20/project.xml
URL: http://svn.apache.org/viewcvs/db/jdo/trunk/api20/project.xml?rev=383687&r1=383686&r2=383687&view=diff
==============================================================================
--- db/jdo/trunk/api20/project.xml (original)
+++ db/jdo/trunk/api20/project.xml Mon Mar 6 14:02:51 2006
@@ -42,13 +42,18 @@
</dependency>
<dependency>
<groupId>xerces</groupId>
- <artifactId>xercesImpl</artifactId>
- <version>2.7.1</version>
+ <artifactId>xerces</artifactId>
+ <version>2.4.0</version>
</dependency>
<dependency>
- <groupId>xerces</groupId>
- <artifactId>xmlParserAPIs</artifactId>
- <version>2.6.2</version>
+ <groupId>xml-apis</groupId>
+ <artifactId>xml-apis</artifactId>
+ <version>1.0.b2</version>
+ </dependency>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>3.8.1</version>
</dependency>
</dependencies>
<!-- =================== -->
Modified: db/jdo/trunk/api20/test/java/javax/jdo/schema/XMLTest.java
URL: http://svn.apache.org/viewcvs/db/jdo/trunk/api20/test/java/javax/jdo/schema/XMLTest.java?rev=383687&r1=383686&r2=383687&view=diff
==============================================================================
--- db/jdo/trunk/api20/test/java/javax/jdo/schema/XMLTest.java (original)
+++ db/jdo/trunk/api20/test/java/javax/jdo/schema/XMLTest.java Mon Mar 6 14:02:51 2006
@@ -16,23 +16,17 @@
package javax.jdo.schema;
-import java.io.BufferedReader;
import java.io.File;
-import java.io.FileReader;
-import java.io.InputStream;
-import java.io.InputStreamReader;
import java.io.IOException;
import java.io.FilenameFilter;
-import java.security.AccessController;
-import java.security.PrivilegedAction;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.Map;
+import java.util.Arrays;
+import java.util.List;
import javax.jdo.JDOFatalException;
import javax.jdo.util.AbstractTest;
import javax.jdo.util.BatchTestRunner;
+import javax.jdo.util.XMLTestUtil;
import javax.xml.parsers.*;
import org.w3c.dom.Document;
@@ -48,29 +42,8 @@
/** */
protected static String BASEDIR = System.getProperty("basedir", ".");
- /** "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-schemaLocation";
-
- /** jdo namespace */
- protected static final String JDO_XSD_NS =
- "http://java.sun.com/xml/ns/jdo/jdo";
-
- /** orm namespace */
- protected static final String ORM_XSD_NS =
- "http://java.sun.com/xml/ns/jdo/orm";
-
- /** jdoquery namespace */
- protected static final String JDOQL_XSD_NS =
- "http://java.sun.com/xml/ns/jdo/jdoquery";
+ /** File prefix */
+ protected static final String FILE_PREFIX = BASEDIR + "/test/schema/";
/** */
protected static final File JDO_XSD_FILE =
@@ -81,39 +54,29 @@
new File(BASEDIR + "/target/classes/javax/jdo/orm.xsd");
/** */
- protected static final File JDOQL_XSD_FILE =
+ protected static final File JDOQUERY_XSD_FILE =
new File(BASEDIR + "/target/classes/javax/jdo/jdoquery.xsd");
- /** File prefix */
- protected static final String FILE_PREFIX = BASEDIR + "/test/schema/";
-
- /** Entity resolver */
- protected static final EntityResolver resolver = new JDOEntityResolver();
-
- /** Error handler */
- protected static final Handler handler = new Handler();
-
/** .xsd files */
- protected static final File[] XSD_FILES = {
- JDO_XSD_FILE, ORM_XSD_FILE, JDOQL_XSD_FILE
- };
+ protected static final File[] XSD_FILES =
+ new File[] {JDO_XSD_FILE, ORM_XSD_FILE, JDOQUERY_XSD_FILE};
/** 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[] positiveXSDJDOQL = getFiles("Positive", "-xsd.jdoquery");
- protected static File[] negativeXSDJDOQL = getFiles("Negative", "-xsd.jdoquery");
-
+ 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[] positiveDTDJDOQL = getFiles("Positive", "-dtd.jdoquery");
- protected static File[] negativeDTDJDOQL = getFiles("Negative", "-dtd.jdoquery");
-
+ 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 () {
@@ -131,284 +94,35 @@
}
/** Test XSD files jdo.xsd, orm.xsd, and jdoquery.xsd. */
- public void testXSD() throws SAXException, IOException {
- DocumentBuilder builder = null;
- DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
- factory.setNamespaceAware(true);
- builder = getParser(factory);
- checkXML(builder, XSD_FILES, true);
- String messages = retrieveMessages();
- if (messages != null) {
- fail(messages);
- }
+ public void testXSD() {
+ XMLTestUtil util = new XMLTestUtil();
+ appendMessage(util.checkXMLNonValidating(XSD_FILES));
+ failOnError();
}
/** Test XSD based .jdo, .orm and .jdoquery files. */
public void testXSDBased() {
- // create XSD parser
- DocumentBuilder builder = null;
- builder = createBuilder(JDO_XSD_NS + " " + JDO_XSD_FILE.toURI().toString());
- checkXML(builder, positiveXSDJDO, true);
- checkXML(builder, negativeXSDJDO, false);
- builder = createBuilder(ORM_XSD_NS + " " + ORM_XSD_FILE.toURI().toString());
- checkXML(builder, positiveXSDORM, true);
- checkXML(builder, negativeXSDORM, false);
- builder = createBuilder(JDOQL_XSD_NS + " " + JDOQL_XSD_FILE.toURI().toString());
- checkXML(builder, positiveXSDJDOQL, true);
- checkXML(builder, negativeXSDJDOQL, false);
- String messages = retrieveMessages();
- if (messages != null) {
- fail(messages);
- }
+ XMLTestUtil util = new XMLTestUtil();
+ appendMessage(util.checkXML(positiveXSDJDO, true));
+ appendMessage(util.checkXML(negativeXSDJDO, false));
+ appendMessage(util.checkXML(positiveXSDORM, true));
+ appendMessage(util.checkXML(negativeXSDORM, false));
+ appendMessage(util.checkXML(positiveXSDJDOQUERY, true));
+ appendMessage(util.checkXML(negativeXSDJDOQUERY, false));
+ failOnError();
}
/** Test DTD based .jdo, .orm and .jdoquery files. */
public void testDTDBased() {
- // create DTD parser
- DocumentBuilder builder = createBuilder();
- checkXML(builder, positiveDTDJDO, true);
- checkXML(builder, negativeDTDJDO, false);
- checkXML(builder, positiveDTDORM, true);
- checkXML(builder, negativeDTDORM, false);
- checkXML(builder, positiveDTDJDOQL, true);
- checkXML(builder, negativeDTDJDOQL, false);
- String messages = retrieveMessages();
- if (messages != null) {
- fail(messages);
- }
- }
-
- /** Create XSD builder.
- */
- private DocumentBuilder createBuilder(String location) {
- DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
- factory.setValidating(true);
- factory.setNamespaceAware(true);
- factory.setAttribute(SCHEMA_LANGUAGE_PROP, XSD_TYPE);
- factory.setAttribute(SCHEMA_LOCATION_PROP, location);
- return getParser(factory);
+ XMLTestUtil util = new XMLTestUtil();
+ appendMessage(util.checkXML(positiveDTDJDO, true));
+ appendMessage(util.checkXML(negativeDTDJDO, false));
+ appendMessage(util.checkXML(positiveDTDORM, true));
+ appendMessage(util.checkXML(negativeDTDORM, false));
+ appendMessage(util.checkXML(positiveDTDJDOQUERY, true));
+ appendMessage(util.checkXML(negativeDTDJDOQUERY, false));
+ failOnError();
}
- /** Create DTD builder.
- */
- private DocumentBuilder createBuilder() {
- DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
- factory.setValidating(true);
- factory.setNamespaceAware(true);
- return getParser(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);
- }
- }
-
- /** Parse the specified files using the specified builder. The valid
- * parameter determines whether the specified files are valid JDO metadata
- * files. The method does not throw an exception on an error, instead it
- * appends any error message to the global message handler.
- */
- private void checkXML(DocumentBuilder builder, File[] files, boolean valid) {
- for (int i = 0; i < files.length; i++) {
- File file = files[i];
- handler.init(file);
- try {
- builder.parse(file);
- } catch (SAXParseException ex) {
- handler.error(ex);
- } catch (Exception ex) {
- throw new JDOFatalException("Fatal error processing " +
- file.getName(), ex);
- }
- String messages = handler.getMessages();
- if (valid && (messages != null)) {
- appendMessage(messages);
- } else if (!valid && (messages == null)) {
- appendMessage(file.getName() + " is not valid, " +
- "but the parser did not catch the error.");
- }
- }
- }
-
- /** ErrorHandler implementation. */
- private static class Handler implements ErrorHandler {
-
- private File fileUnderTest;
- private String[] lines;
- private StringBuffer messages;
-
- public void error(SAXParseException ex) {
- append("Handler.error: ", ex);
- }
-
- public void fatalError(SAXParseException ex) {
- append("Handler.fatalError: ", ex);
- }
-
- public void warning(SAXParseException ex) {
- append("Handler.warning: ", ex);
- }
-
- public void init(File file) {
- this.fileUnderTest = file;
- this.messages = new StringBuffer();
- this.lines = null;
- }
-
- public String getMessages() {
- return (messages.length() == 0) ? null : messages.toString();
- }
-
- private void append(String prefix, SAXParseException ex) {
- int lineNumber = ex.getLineNumber();
- int columnNumber = ex.getColumnNumber();
- messages.append("------------------------").append(NL);
- messages.append(prefix).append(fileUnderTest.getName());
- messages.append(" [line=").append(lineNumber);
- messages.append(", col=").append(columnNumber).append("]: ");
- messages.append(ex.getMessage()).append(NL);
- messages.append(getErrorLocation(lineNumber, columnNumber));
- }
-
- private String[] getLines() {
- if (lines == null) {
- try {
- BufferedReader bufferedReader =
- new BufferedReader(new FileReader(fileUnderTest));
- ArrayList tmp = new ArrayList();
- while (bufferedReader.ready()) {
- tmp.add(bufferedReader.readLine());
- }
- lines = (String[])tmp.toArray(new String[tmp.size()]);
- } catch (IOException ex) {
- throw new JDOFatalException("getLines: caught IOException", ex);
- }
- }
- return lines;
- }
-
- /** Return the error location for the file under test.
- */
- private String getErrorLocation(int lineNumber, int columnNumber) {
- String[] lines = getLines();
- int length = lines.length;
- if (lineNumber > length) {
- return "Line number " + lineNumber +
- " exceeds the number of lines in the file (" +
- lines.length + ")";
- } else if (lineNumber < 1) {
- return "Line number " + lineNumber +
- " does not allow retriving the error location.";
- }
- StringBuffer buf = new StringBuffer();
- if (lineNumber > 2) {
- buf.append(lines[lineNumber-3]);
- buf.append(NL);
- buf.append(lines[lineNumber-2]);
- buf.append(NL);
- }
- buf.append(lines[lineNumber-1]);
- buf.append(NL);
- for (int i = 1; i < columnNumber; ++i) {
- buf.append(' ');
- }
- buf.append("^\n");
- if (lineNumber + 1 < length) {
- buf.append(lines[lineNumber]);
- buf.append(NL);
- buf.append(lines[lineNumber+1]);
- buf.append(NL);
- }
- return buf.toString();
- }
- }
-
- /** Implementation of EntityResolver interface to check the jdo.dtd location
- **/
- private static class JDOEntityResolver
- implements EntityResolver {
-
- private static final String RECOGNIZED_JDO_PUBLIC_ID =
- "-//Sun Microsystems, Inc.//DTD Java Data Objects Metadata 2.0//EN";
- private static final String RECOGNIZED_JDO_SYSTEM_ID =
- "file:/javax/jdo/jdo.dtd";
- private static final String RECOGNIZED_JDO_SYSTEM_ID2 =
- "http://java.sun.com/dtd/jdo_2_0.dtd";
- private static final String RECOGNIZED_ORM_PUBLIC_ID =
- "-//Sun Microsystems, Inc.//DTD Java Data Objects Mapping Metadata 2.0//EN";
- private static final String RECOGNIZED_ORM_SYSTEM_ID =
- "file:/javax/jdo/orm.dtd";
- private static final String RECOGNIZED_ORM_SYSTEM_ID2 =
- "http://java.sun.com/dtd/orm_2_0.dtd";
- private static final String RECOGNIZED_JDOQUERY_PUBLIC_ID =
- "-//Sun Microsystems, Inc.//DTD Java Data Objects Query Metadata 2.0//EN";
- private static final String RECOGNIZED_JDOQUERY_SYSTEM_ID =
- "file:/javax/jdo/jdoquery.dtd";
- private static final String RECOGNIZED_JDOQUERY_SYSTEM_ID2 =
- "http://java.sun.com/dtd/jdoquery_2_0.dtd";
- private static final String JDO_DTD_FILENAME =
- "javax/jdo/jdo.dtd";
- private static final String ORM_DTD_FILENAME =
- "javax/jdo/orm.dtd";
- private static final String JDOQUERY_DTD_FILENAME =
- "javax/jdo/jdoquery.dtd";
-
- static Map publicIds = new HashMap();
- static Map systemIds = new HashMap();
- static {
- publicIds.put(RECOGNIZED_JDO_PUBLIC_ID, JDO_DTD_FILENAME);
- publicIds.put(RECOGNIZED_ORM_PUBLIC_ID, ORM_DTD_FILENAME);
- publicIds.put(RECOGNIZED_JDOQUERY_PUBLIC_ID, JDOQUERY_DTD_FILENAME);
- systemIds.put(RECOGNIZED_JDO_SYSTEM_ID, JDO_DTD_FILENAME);
- systemIds.put(RECOGNIZED_ORM_SYSTEM_ID, ORM_DTD_FILENAME);
- systemIds.put(RECOGNIZED_JDOQUERY_SYSTEM_ID, JDOQUERY_DTD_FILENAME);
- systemIds.put(RECOGNIZED_JDO_SYSTEM_ID2, JDO_DTD_FILENAME);
- systemIds.put(RECOGNIZED_ORM_SYSTEM_ID2, ORM_DTD_FILENAME);
- systemIds.put(RECOGNIZED_JDOQUERY_SYSTEM_ID2, JDOQUERY_DTD_FILENAME);
- }
- public InputSource resolveEntity(String publicId, final String systemId)
- throws SAXException, IOException
- {
- // check for recognized ids
- String filename = (String)publicIds.get(publicId);
- if (filename == null) {
- filename = (String)systemIds.get(systemId);
- }
- final String finalName = filename;
- if (finalName == null) {
- return null;
- } else {
- // 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(finalName);
- }
- }
- );
- if (stream == null) {
- // TDB: error handling + I18N
- throw new JDOFatalException("Cannot load " +
- finalName +
- ", 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 + ".");
- }
- return new InputSource(new InputStreamReader(stream));
- }
- }
- }
}
Modified: db/jdo/trunk/api20/test/java/javax/jdo/util/AbstractTest.java
URL: http://svn.apache.org/viewcvs/db/jdo/trunk/api20/test/java/javax/jdo/util/AbstractTest.java?rev=383687&r1=383686&r2=383687&view=diff
==============================================================================
--- db/jdo/trunk/api20/test/java/javax/jdo/util/AbstractTest.java (original)
+++ db/jdo/trunk/api20/test/java/javax/jdo/util/AbstractTest.java Mon Mar 6 14:02:51 2006
@@ -55,11 +55,13 @@
/** Appends to error messages.
*/
protected static synchronized void appendMessage(String message) {
- if (messages == null) {
- messages = new StringBuffer();
+ if (message != null) {
+ if (messages == null) {
+ messages = new StringBuffer();
+ }
+ messages.append(message);
+ messages.append(NL);
}
- messages.append(message);
- messages.append(NL);
}
/**
@@ -75,5 +77,14 @@
return msg;
}
+ /**
+ * Fail the test if there are any error messages.
+ */
+ protected void failOnError() {
+ String errors = retrieveMessages();
+ if (errors != null) {
+ fail (errors);
+ }
+ }
}
Added: db/jdo/trunk/api20/test/java/javax/jdo/util/XMLTestUtil.java
URL: http://svn.apache.org/viewcvs/db/jdo/trunk/api20/test/java/javax/jdo/util/XMLTestUtil.java?rev=383687&view=auto
==============================================================================
--- db/jdo/trunk/api20/test/java/javax/jdo/util/XMLTestUtil.java (added)
+++ db/jdo/trunk/api20/test/java/javax/jdo/util/XMLTestUtil.java Mon Mar 6 14:02:51 2006
@@ -0,0 +1,561 @@
+/*
+ * 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.
+ */
+
+package javax.jdo.util;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileReader;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.IOException;
+import java.io.FileFilter;
+import java.io.FilenameFilter;
+
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.Arrays;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.StringTokenizer;
+
+import javax.jdo.JDOFatalException;
+
+import javax.xml.parsers.*;
+import org.w3c.dom.Document;
+import org.xml.sax.*;
+import org.xml.sax.helpers.*;
+
+/**
+ * Tests schema files.
+ * <p>
+ */
+public class XMLTestUtil {
+
+ /** */
+ protected static String BASEDIR = System.getProperty("basedir", ".");
+
+ /** "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-schemaLocation";
+
+ /** jdo namespace */
+ protected static final String JDO_XSD_NS =
+ "http://java.sun.com/xml/ns/jdo/jdo";
+
+ /** orm namespace */
+ protected static final String ORM_XSD_NS =
+ "http://java.sun.com/xml/ns/jdo/orm";
+
+ /** jdoquery namespace */
+ protected static final String JDOQUERY_XSD_NS =
+ "http://java.sun.com/xml/ns/jdo/jdoquery";
+
+ /** jdo xsd file */
+ protected static final File JDO_XSD_FILE =
+ new File(BASEDIR + "/target/classes/javax/jdo/jdo.xsd");
+
+ /** orm xsd file */
+ protected static final File ORM_XSD_FILE =
+ new File(BASEDIR + "/target/classes/javax/jdo/orm.xsd");
+
+ /** jdoquery xsd file */
+ protected static final File JDOQUERY_XSD_FILE =
+ new File(BASEDIR + "/target/classes/javax/jdo/jdoquery.xsd");
+
+ /** Entity resolver */
+ protected static final EntityResolver resolver = new JDOEntityResolver();
+
+ /** Error handler */
+ protected static final Handler handler = new Handler();
+
+ /** Name of the metadata property, a comma separated list of JDO metadata
+ * file or directories containing such files. */
+ protected static String METADATA_PROP = "javax.jdo.metadata";
+
+ /** Name of the recursive property, allowing recursive search of metadata
+ * files. */
+ protected static String RECURSIVE_PROP = "javax.jdo.recursive";
+
+ /** Separator character for the metadata property. */
+ protected static final String DELIM = ",;";
+
+ /** Newline. */
+ protected static final String NL = System.getProperty("line.separator");
+
+ /** XSD builder for jdo namespace. */
+ private final DocumentBuilder jdoXsdBuilder =
+ createBuilder(JDO_XSD_NS + " " + JDO_XSD_FILE.toURI().toString());
+
+ /** XSD builder for orm namespace. */
+ private final DocumentBuilder ormXsdBuilder =
+ createBuilder(ORM_XSD_NS + " " + ORM_XSD_FILE.toURI().toString());
+
+ /** XSD builder for jdoquery namespace. */
+ private final DocumentBuilder jdoqueryXsdBuilder =
+ createBuilder(JDOQUERY_XSD_NS + " " + JDOQUERY_XSD_FILE.toURI().toString());
+
+ /** DTD builder. */
+ private final DocumentBuilder dtdBuilder = createBuilder(true);
+
+ /** Non validating builder. */
+ private final DocumentBuilder nonValidatingBuilder = createBuilder(false);
+
+ /** Create XSD builder. */
+ private DocumentBuilder createBuilder(String location) {
+ DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+ factory.setValidating(true);
+ factory.setNamespaceAware(true);
+ factory.setAttribute(SCHEMA_LANGUAGE_PROP, XSD_TYPE);
+ factory.setAttribute(SCHEMA_LOCATION_PROP, location);
+ return getParser(factory);
+ }
+
+ /** Create builder. */
+ private DocumentBuilder createBuilder(boolean validating) {
+ DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+ factory.setValidating(validating);
+ factory.setNamespaceAware(true);
+ return getParser(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);
+ }
+ }
+
+ /** Parse the specified files. The valid parameter determines whether the
+ * specified files are valid JDO metadata files. The method does not throw
+ * an exception on an error, instead it instead it returns the error
+ * message(s) as string.
+ */
+ public String checkXML(File[] files, boolean valid) {
+ StringBuffer messages = new StringBuffer();
+ for (int i = 0; i < files.length; i++) {
+ String msg = checkXML(files[i], valid);
+ if (msg != null) {
+ messages.append(msg);
+ }
+ }
+ return (messages.length() == 0) ? null : messages.toString();
+ }
+
+ /** Parse the specified files using a non validating parser. The method
+ * does not throw an exception on an error, instead it instead it returns
+ * the error message(s) as string.
+ */
+ public String checkXMLNonValidating(File[] files) {
+ StringBuffer messages = new StringBuffer();
+ for (int i = 0; i < files.length; i++) {
+ String msg = checkXML(nonValidatingBuilder, files[i], true);
+ if (msg != null) {
+ messages.append(msg);
+ }
+ }
+ return (messages.length() == 0) ? null : messages.toString();
+ }
+
+ /** Parse the specified file. The method checks whether it is a XSD or
+ * DTD base file and parses the file using a builder according to the file
+ * name suffix. The valid parameter determines whether the specified files
+ * are valid JDO metadata files. The method does not throw an exception on
+ * an error, instead it returns the error message(s) as string.
+ */
+ private String checkXML(File file, boolean valid) {
+ String messages = null;
+ String fileName = file.getName();
+ try {
+ if (isDTDBased(file)) {
+ messages = checkXML(dtdBuilder, file, valid);
+ } else if (fileName.endsWith(".jdo")) {
+ messages = checkXML(jdoXsdBuilder, file, valid);
+ } else if (fileName.endsWith(".orm")) {
+ messages = checkXML(ormXsdBuilder, file, valid);
+ } else if (fileName.endsWith(".jdoquery")) {
+ messages = checkXML(jdoqueryXsdBuilder, file, valid);
+ }
+ } catch (SAXException ex) {
+ messages = ex.getMessage();
+ }
+ return messages;
+ }
+
+ /** Parse the specified file using the specified builder. The valid
+ * parameter determines whether the specified files are valid JDO metadata
+ * files. The method does not throw an exception on an error, instead it
+ * returns the error message(s) as string.
+ */
+ private String checkXML(DocumentBuilder builder, File file, boolean valid) {
+ String messages = null;
+ handler.init(file);
+ try {
+ builder.parse(file);
+ } catch (SAXParseException ex) {
+ handler.error(ex);
+ } catch (Exception ex) {
+ messages = "Fatal error processing " + file.getName() + ": " + ex;
+ }
+ if (messages == null) {
+ messages = handler.getMessages();
+ }
+ if (!valid) {
+ if (messages != null) {
+ // expected error for negative test
+ messages = null;
+ } else {
+ messages = file.getName() + " is not valid, " +
+ "but the parser did not catch the error.";
+ }
+ }
+ return messages;
+ }
+
+ /** Checks whether the specifeid file is DTD or XSD based. The method
+ * throws a SAXException if the file has syntax errors. */
+ private boolean isDTDBased(File file) throws SAXException {
+ handler.init(file);
+ try {
+ Document document = nonValidatingBuilder.parse(file);
+ return document.getDoctype() != null;
+ } catch (SAXParseException ex) {
+ handler.error(ex);
+ throw new SAXException(handler.getMessages());
+ } catch (Exception ex) {
+ throw new SAXException(
+ "Fatal error processing " + file.getName() + ": " + ex);
+ }
+ }
+
+ /** ErrorHandler implementation. */
+ private static class Handler implements ErrorHandler {
+
+ private File fileUnderTest;
+ private String[] lines;
+ private StringBuffer messages;
+
+ public void error(SAXParseException ex) {
+ append("Handler.error: ", ex);
+ }
+
+ public void fatalError(SAXParseException ex) {
+ append("Handler.fatalError: ", ex);
+ }
+
+ public void warning(SAXParseException ex) {
+ append("Handler.warning: ", ex);
+ }
+
+ public void init(File file) {
+ this.fileUnderTest = file;
+ this.messages = new StringBuffer();
+ this.lines = null;
+ }
+
+ public String getMessages() {
+ return (messages.length() == 0) ? null : messages.toString();
+ }
+
+ private void append(String prefix, SAXParseException ex) {
+ int lineNumber = ex.getLineNumber();
+ int columnNumber = ex.getColumnNumber();
+ messages.append("------------------------").append(NL);
+ messages.append(prefix).append(fileUnderTest.getName());
+ messages.append(" [line=").append(lineNumber);
+ messages.append(", col=").append(columnNumber).append("]: ");
+ messages.append(ex.getMessage()).append(NL);
+ messages.append(getErrorLocation(lineNumber, columnNumber));
+ }
+
+ private String[] getLines() {
+ if (lines == null) {
+ try {
+ BufferedReader bufferedReader =
+ new BufferedReader(new FileReader(fileUnderTest));
+ ArrayList tmp = new ArrayList();
+ while (bufferedReader.ready()) {
+ tmp.add(bufferedReader.readLine());
+ }
+ lines = (String[])tmp.toArray(new String[tmp.size()]);
+ } catch (IOException ex) {
+ throw new JDOFatalException("getLines: caught IOException", ex);
+ }
+ }
+ return lines;
+ }
+
+ /** Return the error location for the file under test.
+ */
+ private String getErrorLocation(int lineNumber, int columnNumber) {
+ String[] lines = getLines();
+ int length = lines.length;
+ if (lineNumber > length) {
+ return "Line number " + lineNumber +
+ " exceeds the number of lines in the file (" +
+ lines.length + ")";
+ } else if (lineNumber < 1) {
+ return "Line number " + lineNumber +
+ " does not allow retriving the error location.";
+ }
+ StringBuffer buf = new StringBuffer();
+ if (lineNumber > 2) {
+ buf.append(lines[lineNumber-3]);
+ buf.append(NL);
+ buf.append(lines[lineNumber-2]);
+ buf.append(NL);
+ }
+ buf.append(lines[lineNumber-1]);
+ buf.append(NL);
+ for (int i = 1; i < columnNumber; ++i) {
+ buf.append(' ');
+ }
+ buf.append("^\n");
+ if (lineNumber + 1 < length) {
+ buf.append(lines[lineNumber]);
+ buf.append(NL);
+ buf.append(lines[lineNumber+1]);
+ buf.append(NL);
+ }
+ return buf.toString();
+ }
+ }
+
+ /** Implementation of EntityResolver interface to check the jdo.dtd location
+ **/
+ private static class JDOEntityResolver
+ implements EntityResolver {
+
+ private static final String RECOGNIZED_JDO_PUBLIC_ID =
+ "-//Sun Microsystems, Inc.//DTD Java Data Objects Metadata 2.0//EN";
+ private static final String RECOGNIZED_JDO_SYSTEM_ID =
+ "file:/javax/jdo/jdo.dtd";
+ private static final String RECOGNIZED_JDO_SYSTEM_ID2 =
+ "http://java.sun.com/dtd/jdo_2_0.dtd";
+ private static final String RECOGNIZED_ORM_PUBLIC_ID =
+ "-//Sun Microsystems, Inc.//DTD Java Data Objects Mapping Metadata 2.0//EN";
+ private static final String RECOGNIZED_ORM_SYSTEM_ID =
+ "file:/javax/jdo/orm.dtd";
+ private static final String RECOGNIZED_ORM_SYSTEM_ID2 =
+ "http://java.sun.com/dtd/orm_2_0.dtd";
+ private static final String RECOGNIZED_JDOQUERY_PUBLIC_ID =
+ "-//Sun Microsystems, Inc.//DTD Java Data Objects Query Metadata 2.0//EN";
+ private static final String RECOGNIZED_JDOQUERY_SYSTEM_ID =
+ "file:/javax/jdo/jdoquery.dtd";
+ private static final String RECOGNIZED_JDOQUERY_SYSTEM_ID2 =
+ "http://java.sun.com/dtd/jdoquery_2_0.dtd";
+ private static final String JDO_DTD_FILENAME =
+ "javax/jdo/jdo.dtd";
+ private static final String ORM_DTD_FILENAME =
+ "javax/jdo/orm.dtd";
+ private static final String JDOQUERY_DTD_FILENAME =
+ "javax/jdo/jdoquery.dtd";
+
+ static Map publicIds = new HashMap();
+ static Map systemIds = new HashMap();
+ static {
+ publicIds.put(RECOGNIZED_JDO_PUBLIC_ID, JDO_DTD_FILENAME);
+ publicIds.put(RECOGNIZED_ORM_PUBLIC_ID, ORM_DTD_FILENAME);
+ publicIds.put(RECOGNIZED_JDOQUERY_PUBLIC_ID, JDOQUERY_DTD_FILENAME);
+ systemIds.put(RECOGNIZED_JDO_SYSTEM_ID, JDO_DTD_FILENAME);
+ systemIds.put(RECOGNIZED_ORM_SYSTEM_ID, ORM_DTD_FILENAME);
+ systemIds.put(RECOGNIZED_JDOQUERY_SYSTEM_ID, JDOQUERY_DTD_FILENAME);
+ systemIds.put(RECOGNIZED_JDO_SYSTEM_ID2, JDO_DTD_FILENAME);
+ systemIds.put(RECOGNIZED_ORM_SYSTEM_ID2, ORM_DTD_FILENAME);
+ systemIds.put(RECOGNIZED_JDOQUERY_SYSTEM_ID2, JDOQUERY_DTD_FILENAME);
+ }
+ public InputSource resolveEntity(String publicId, final String systemId)
+ throws SAXException, IOException
+ {
+ // check for recognized ids
+ String filename = (String)publicIds.get(publicId);
+ if (filename == null) {
+ filename = (String)systemIds.get(systemId);
+ }
+ final String finalName = filename;
+ if (finalName == null) {
+ return null;
+ } else {
+ // 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(finalName);
+ }
+ }
+ );
+ if (stream == null) {
+ throw new JDOFatalException("Cannot load " + finalName +
+ ", 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 + ".");
+ }
+ return new InputSource(new InputStreamReader(stream));
+ }
+ }
+ }
+
+ /** Helper class to find all test JDO metadata files. */
+ public static class XMLFinder {
+
+ private List metadataFiles = new ArrayList();
+ private final boolean recursive;
+
+ /** Constructor. */
+ public XMLFinder(String[] fileNames, boolean recursive) {
+ this.recursive = recursive;
+ if (fileNames == null) return;
+ for (int i = 0; i < fileNames.length; i++) {
+ appendTestFiles(fileNames[i]);
+ }
+ }
+
+ /** Returns array of files of matching file names. */
+ private File[] getFiles(File dir, final String suffix) {
+ FilenameFilter filter = new FilenameFilter() {
+ public boolean accept(File file, String name) {
+ return name.endsWith(suffix);
+ }
+ };
+ return dir.listFiles(filter);
+ }
+
+ /** */
+ private File[] getDirectories(File dir) {
+ FileFilter filter = new FileFilter() {
+ public boolean accept(File pathname) {
+ return pathname.isDirectory();
+ }
+ };
+ return dir.listFiles(filter);
+ }
+
+ /** */
+ private void appendTestFiles(String fileName) {
+ File file = new File(fileName);
+ if (file.isDirectory()) {
+ processDirectory(file);
+ } else if (fileName.endsWith(".jdo") ||
+ fileName.endsWith(".orm") ||
+ fileName.endsWith(".jdoquery")) {
+ metadataFiles.add(new File(fileName));
+ }
+ }
+
+ /** Adds all files with suffix .jdo, .orm and .jdoquery to the list of
+ * metadata files. Recursively process subdirectories if recursive
+ * flag is set. */
+ private void processDirectory(File dir) {
+ metadataFiles.addAll(Arrays.asList(getFiles(dir, ".jdo")));
+ metadataFiles.addAll(Arrays.asList(getFiles(dir, ".orm")));
+ metadataFiles.addAll(Arrays.asList(getFiles(dir, ".jdoquery")));
+ if (recursive) {
+ File[] subdirs = getDirectories(dir);
+ for (int i = 0; i < subdirs.length; i++) {
+ processDirectory(subdirs[i]);
+ }
+ }
+ }
+
+ /** Returns an array of test files with suffix .jdo, .orm or .jdoquery. */
+ public File[] getMetadataFiles() {
+ return (File[])metadataFiles.toArray(new File[metadataFiles.size()]);
+ }
+
+ }
+
+ /** */
+ private static String[] checkMetadataSystemProperty() {
+ String[] ret = null;
+ String metadata = System.getProperty(METADATA_PROP);
+ if ((metadata != null) && (metadata.length() > 0)) {
+ List entries = new ArrayList();
+ StringTokenizer st = new StringTokenizer(metadata, DELIM);
+ while (st.hasMoreTokens()) {
+ entries.add(st.nextToken());
+ }
+ ret = (String[])entries.toArray(new String[entries.size()]);
+ }
+ return ret;
+ }
+
+ /**
+ * Command line tool to test JDO metadata files.
+ * Usage: XMLTestUtil [-r] <file or directory>+
+ */
+ public static void main(String args[]) {
+ String[] fromProp = checkMetadataSystemProperty();
+ boolean recursive = Boolean.getBoolean(RECURSIVE_PROP);
+
+ // handle command line args
+ String[] fileNames = null;
+ if ((args.length > 0) && ("-r".equals(args[0]))) {
+ recursive = true;
+ fileNames = new String[args.length - 1];
+ System.arraycopy(args, 1, fileNames, 0, args.length - 1);
+ } else {
+ fileNames = args;
+ }
+
+ // check args
+ if ((fileNames.length == 0) && (fromProp == null)) {
+ System.err.println(
+ "No commandline arguments and system property metadata not defined; " +
+ "nothing to be tested.\nUsage: XMLTestUtil [-r] <directories>\n" +
+ "\tAll .jdo, .orm, and .jdoquery files in the directory (recursively) will be tested.");
+ } else if ((fileNames.length == 0) && (fromProp != null)) {
+ // use metadata system property
+ fileNames = fromProp;
+ } else if ((fileNames.length != 0) && (fromProp != null)) {
+ System.err.println(
+ "Commandline arguments specified and system property metadata defined; " +
+ "ignoring system property metadata.");
+ }
+
+ // run the test
+ XMLTestUtil xmlTest = new XMLTestUtil();
+ File[] files = new XMLFinder(fileNames, recursive).getMetadataFiles();
+ for (int i = 0; i < files.length; i++) {
+ File file = files[i];
+ System.out.print("Checking " + file.getPath() + ": ");
+ String messages = xmlTest.checkXML(file, true);
+ messages = (messages == null) ? "OK" : NL + messages;
+ System.out.println(messages);
+ }
+ }
+}
+
Modified: db/jdo/trunk/api20/test/schema/Positive99-xsd.jdoquery
URL: http://svn.apache.org/viewcvs/db/jdo/trunk/api20/test/schema/Positive99-xsd.jdoquery?rev=383687&r1=383686&r2=383687&view=diff
==============================================================================
--- db/jdo/trunk/api20/test/schema/Positive99-xsd.jdoquery (original)
+++ db/jdo/trunk/api20/test/schema/Positive99-xsd.jdoquery Mon Mar 6 14:02:51 2006
@@ -1,5 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE jdoquery SYSTEM "file:/javax/jdo/jdoquery.dtd">
<jdoquery xmlns="http://java.sun.com/xml/ns/jdo/jdoquery"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/jdo/jdoquery