From: <bo...@us...> - 2009-06-02 14:22:16
|
Revision: 340 http://xmlunit.svn.sourceforge.net/xmlunit/?rev=340&view=rev Author: bodewig Date: 2009-06-02 13:32:19 +0000 (Tue, 02 Jun 2009) Log Message: ----------- implement validation for DTDs in Java Modified Paths: -------------- trunk/xmlunit/src/main/java-core/net/sf/xmlunit/validation/JAXPValidator.java trunk/xmlunit/src/main/java-core/net/sf/xmlunit/validation/Validator.java Added Paths: ----------- trunk/xmlunit/src/main/java-core/net/sf/xmlunit/validation/ParsingValidator.java trunk/xmlunit/src/main/java-core/net/sf/xmlunit/validation/ValidationHandler.java trunk/xmlunit/src/tests/java-core/net/sf/xmlunit/validation/ParsingValidatorTest.java trunk/xmlunit/src/tests/resources/Book.dtd trunk/xmlunit/src/tests/resources/BookWithDoctype.xml trunk/xmlunit/src/tests/resources/invalidBookWithDoctype.xml Modified: trunk/xmlunit/src/main/java-core/net/sf/xmlunit/validation/JAXPValidator.java =================================================================== --- trunk/xmlunit/src/main/java-core/net/sf/xmlunit/validation/JAXPValidator.java 2009-05-28 13:07:01 UTC (rev 339) +++ trunk/xmlunit/src/main/java-core/net/sf/xmlunit/validation/JAXPValidator.java 2009-06-02 13:32:19 UTC (rev 340) @@ -13,14 +13,10 @@ */ package net.sf.xmlunit.validation; -import java.util.Collections; -import java.util.LinkedList; -import java.util.List; import javax.xml.transform.Source; import javax.xml.validation.Schema; import javax.xml.validation.SchemaFactory; import net.sf.xmlunit.exceptions.XMLUnitException; -import org.xml.sax.ErrorHandler; import org.xml.sax.SAXException; import org.xml.sax.SAXParseException; @@ -86,42 +82,4 @@ return v.getResult(); } - - private static class ValidationHandler implements ErrorHandler { - private List<ValidationProblem> problems = - new LinkedList<ValidationProblem>(); - private boolean valid = true; - // fatal errors are re-thrown by the parser - private SAXParseException lastFatalError = null; - - public void error(SAXParseException e) { - if (e != lastFatalError) { - valid = false; - problems.add(ValidationProblem.fromException(e, - ValidationProblem - .ProblemType.ERROR) - ); - } - } - - public void fatalError(SAXParseException e) { - valid = false; - lastFatalError = e; - problems.add(ValidationProblem.fromException(e, - ValidationProblem - .ProblemType.ERROR)); - } - - public void warning(SAXParseException e) { - problems.add(ValidationProblem.fromException(e, - ValidationProblem - .ProblemType.WARNING)); - } - - private ValidationResult getResult() { - return new ValidationResult(valid, - Collections.unmodifiableList(problems) - ); - } - } } Added: trunk/xmlunit/src/main/java-core/net/sf/xmlunit/validation/ParsingValidator.java =================================================================== --- trunk/xmlunit/src/main/java-core/net/sf/xmlunit/validation/ParsingValidator.java (rev 0) +++ trunk/xmlunit/src/main/java-core/net/sf/xmlunit/validation/ParsingValidator.java 2009-06-02 13:32:19 UTC (rev 340) @@ -0,0 +1,152 @@ +/* + This file is licensed to You 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 net.sf.xmlunit.validation; + +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.parsers.SAXParser; +import javax.xml.parsers.SAXParserFactory; +import javax.xml.transform.Source; +import javax.xml.transform.sax.SAXSource; +import net.sf.xmlunit.exceptions.ConfigurationException; +import net.sf.xmlunit.exceptions.XMLUnitException; +import org.xml.sax.InputSource; +import org.xml.sax.SAXException; +import org.xml.sax.SAXNotRecognizedException; +import org.xml.sax.SAXNotSupportedException; +import org.xml.sax.SAXParseException; +import org.xml.sax.helpers.DefaultHandler; + +/** + * Validator implementation that uses "the old way" of validating an + * XML input by parsing the input. + * + * <p>Even though this implementation supports W3C Schema you + * shouldn't use it for that language but rather use + * JAXPValidator.</p> + */ +public class ParsingValidator extends Validator { + private final String language; + + public ParsingValidator(String language) { + if (!Languages.W3C_XML_SCHEMA_NS_URI.equals(language) + && !Languages.XML_DTD_NS_URI.equals(language)) { + throw new IllegalArgumentException("only DTD and W3C Schema" + + " validation are supported by" + + " ParsingValidator"); + } + this.language = language; + } + + @Override public ValidationResult validateSchema() { + throw new XMLUnitException("Schema validation is not supported by" + + " ParsinValidator"); + } + + @Override public ValidationResult validateInstance(Source s) { + try { + SAXParserFactory factory = SAXParserFactory.newInstance(); + factory.setNamespaceAware(true); + factory.setValidating(true); + SAXParser parser = factory.newSAXParser(); + if (Languages.W3C_XML_SCHEMA_NS_URI.equals(language)) { + parser.setProperty(Properties.SCHEMA_LANGUAGE, + Languages.W3C_XML_SCHEMA_NS_URI); + } + final Source[] source = getSchemaSources(); + Handler handler = new Handler(); + if (source.length != 0) { + if (Languages.W3C_XML_SCHEMA_NS_URI.equals(language)) { + InputSource[] schemaSource = new InputSource[source.length]; + for (int i = 0; i < source.length; i++) { + schemaSource[i] = toInputSource(source[i]); + } + parser.setProperty(Properties.SCHEMA_SOURCE, + schemaSource); + } else if (source.length == 1) { + handler.setSchemaSystemId(source[0].getSystemId()); + } + } + InputSource input = toInputSource(s); + try { + parser.parse(input, handler); + } catch (SAXException e) { + if (e instanceof SAXParseException) { + handler.error((SAXParseException) e); + } else { + throw new XMLUnitException(e); + } + } + return handler.getResult(); + } catch (ParserConfigurationException ex) { + throw new ConfigurationException(ex); + } catch (SAXNotRecognizedException ex) { + throw new ConfigurationException(ex); + } catch (SAXNotSupportedException ex) { + throw new ConfigurationException(ex); + } catch (SAXException ex) { + throw new XMLUnitException(ex); + } catch (java.io.IOException ex) { + throw new XMLUnitException(ex); + } + } + + // TODO factor out to a common class, will be needed by other parts as well + private static InputSource toInputSource(Source s) throws SAXException { + return SAXSource.sourceToInputSource(s); + } + + private static class Properties { + static final String SCHEMA_LANGUAGE = + "http://java.sun.com/xml/jaxp/properties/schemaLanguage"; + + static final String SCHEMA_SOURCE = + "http://java.sun.com/xml/jaxp/properties/schemaSource"; + } + + private class Handler extends DefaultHandler { + private final ValidationHandler v = new ValidationHandler(); + private String systemId; + + @Override public void error(SAXParseException e) { + v.error(e); + } + + @Override public void fatalError(SAXParseException e) { + v.fatalError(e); + } + + @Override public void warning(SAXParseException e) { + v.warning(e); + } + + private void setSchemaSystemId(String id) { + systemId = id; + } + + @Override public InputSource resolveEntity(String publicId, + String systemId) + throws java.io.IOException, SAXException { + if (this.systemId != null && + (getSchemaURI() == null || getSchemaURI().equals(publicId)) + ) { + return new InputSource(this.systemId); + } + return super.resolveEntity(publicId, systemId); + } + + ValidationResult getResult() { + return v.getResult(); + } + } +} Property changes on: trunk/xmlunit/src/main/java-core/net/sf/xmlunit/validation/ParsingValidator.java ___________________________________________________________________ Added: svn:eol-style + native Added: trunk/xmlunit/src/main/java-core/net/sf/xmlunit/validation/ValidationHandler.java =================================================================== --- trunk/xmlunit/src/main/java-core/net/sf/xmlunit/validation/ValidationHandler.java (rev 0) +++ trunk/xmlunit/src/main/java-core/net/sf/xmlunit/validation/ValidationHandler.java 2009-06-02 13:32:19 UTC (rev 340) @@ -0,0 +1,61 @@ +/* + This file is licensed to You 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 net.sf.xmlunit.validation; + +import java.util.Collections; +import java.util.LinkedList; +import java.util.List; +import org.xml.sax.ErrorHandler; +import org.xml.sax.SAXParseException; + +/** + * ErrorHandler collecting parser exceptions as ValidationProblems + */ +final class ValidationHandler implements ErrorHandler { + private List<ValidationProblem> problems = + new LinkedList<ValidationProblem>(); + private boolean valid = true; + // fatal errors are re-thrown by the parser + private SAXParseException lastFatalError = null; + + public void error(SAXParseException e) { + if (e != lastFatalError) { + valid = false; + problems.add(ValidationProblem.fromException(e, + ValidationProblem + .ProblemType.ERROR) + ); + } + } + + public void fatalError(SAXParseException e) { + valid = false; + lastFatalError = e; + problems.add(ValidationProblem.fromException(e, + ValidationProblem + .ProblemType.ERROR)); + } + + public void warning(SAXParseException e) { + problems.add(ValidationProblem.fromException(e, + ValidationProblem + .ProblemType.WARNING)); + } + + ValidationResult getResult() { + return new ValidationResult(valid, + Collections.unmodifiableList(problems) + ); + } +} Property changes on: trunk/xmlunit/src/main/java-core/net/sf/xmlunit/validation/ValidationHandler.java ___________________________________________________________________ Added: svn:eol-style + native Modified: trunk/xmlunit/src/main/java-core/net/sf/xmlunit/validation/Validator.java =================================================================== --- trunk/xmlunit/src/main/java-core/net/sf/xmlunit/validation/Validator.java 2009-05-28 13:07:01 UTC (rev 339) +++ trunk/xmlunit/src/main/java-core/net/sf/xmlunit/validation/Validator.java 2009-06-02 13:32:19 UTC (rev 340) @@ -78,6 +78,9 @@ * @see Languages */ public static Validator forLanguage(String language) { - return null; + if (!Languages.XML_DTD_NS_URI.equals(language)) { + return new JAXPValidator(language); + } + return new ParsingValidator(Languages.XML_DTD_NS_URI); } } \ No newline at end of file Added: trunk/xmlunit/src/tests/java-core/net/sf/xmlunit/validation/ParsingValidatorTest.java =================================================================== --- trunk/xmlunit/src/tests/java-core/net/sf/xmlunit/validation/ParsingValidatorTest.java (rev 0) +++ trunk/xmlunit/src/tests/java-core/net/sf/xmlunit/validation/ParsingValidatorTest.java 2009-06-02 13:32:19 UTC (rev 340) @@ -0,0 +1,58 @@ +/* + This file is licensed to You 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 net.sf.xmlunit.validation; + +import java.io.File; +import javax.xml.transform.stream.StreamSource; +import static org.junit.Assert.*; +import org.junit.Test; + +public class ParsingValidatorTest { + + @Test public void shouldSuccessfullyValidateSchemaInstance() { + ParsingValidator v = + new ParsingValidator(Languages.W3C_XML_SCHEMA_NS_URI); + v.setSchemaSource(new StreamSource(new File("src/tests/resources/Book.xsd"))); + ValidationResult r = v.validateInstance(new StreamSource(new File("src/tests/resources/BookXsdGenerated.xml"))); + assertTrue(r.isValid()); + assertFalse(r.getProblems().iterator().hasNext()); + } + + @Test public void shouldFailOnBrokenSchemaInstance() { + ParsingValidator v = + new ParsingValidator(Languages.W3C_XML_SCHEMA_NS_URI); + v.setSchemaSource(new StreamSource(new File("src/tests/resources/Book.xsd"))); + ValidationResult r = v.validateInstance(new StreamSource(new File("src/tests/resources/invalidBook.xml"))); + assertFalse(r.isValid()); + assertTrue(r.getProblems().iterator().hasNext()); + } + + @Test public void shouldSuccessfullyValidateDTDInstance() { + ParsingValidator v = + new ParsingValidator(Languages.XML_DTD_NS_URI); + v.setSchemaSource(new StreamSource(new File("src/tests/resources/Book.dtd"))); + ValidationResult r = v.validateInstance(new StreamSource(new File("src/tests/resources/BookWithDoctype.xml"))); + assertTrue(r.isValid()); + assertFalse(r.getProblems().iterator().hasNext()); + } + + @Test public void shouldFailOnBrokenDTDInstance() { + ParsingValidator v = + new ParsingValidator(Languages.XML_DTD_NS_URI); + v.setSchemaSource(new StreamSource(new File("src/tests/resources/Book.dtd"))); + ValidationResult r = v.validateInstance(new StreamSource(new File("src/tests/resources/invalidBookWithDoctype.xml"))); + assertFalse(r.isValid()); + assertTrue(r.getProblems().iterator().hasNext()); + } +} Property changes on: trunk/xmlunit/src/tests/java-core/net/sf/xmlunit/validation/ParsingValidatorTest.java ___________________________________________________________________ Added: svn:eol-style + native Added: trunk/xmlunit/src/tests/resources/Book.dtd =================================================================== --- trunk/xmlunit/src/tests/resources/Book.dtd (rev 0) +++ trunk/xmlunit/src/tests/resources/Book.dtd 2009-06-02 13:32:19 UTC (rev 340) @@ -0,0 +1,6 @@ +<!ELEMENT Book (Title, Author*, Date, ISBN, Publisher) > +<!ELEMENT Title (#PCDATA)> +<!ELEMENT Author (#PCDATA)> +<!ELEMENT Date (#PCDATA)> +<!ELEMENT ISBN (#PCDATA)> +<!ELEMENT Publisher (#PCDATA)> Property changes on: trunk/xmlunit/src/tests/resources/Book.dtd ___________________________________________________________________ Added: svn:eol-style + native Copied: trunk/xmlunit/src/tests/resources/BookWithDoctype.xml (from rev 339, trunk/xmlunit/src/tests/resources/BookXsdGeneratedNoSchema.xml) =================================================================== --- trunk/xmlunit/src/tests/resources/BookWithDoctype.xml (rev 0) +++ trunk/xmlunit/src/tests/resources/BookWithDoctype.xml 2009-06-02 13:32:19 UTC (rev 340) @@ -0,0 +1,10 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE Book PUBLIC "XMLUNIT/TEST/PUB" "http://example.org/nonsense"> +<Book> + <Title>Chicken Soup for the Soul</Title> + <Author>Jack Canfield</Author> + <Author>Mark Victor Hansen</Author> + <Date>1993</Date> + <ISBN>1-55874-262-X</ISBN> + <Publisher>Health Communications, Inc.</Publisher> +</Book> Property changes on: trunk/xmlunit/src/tests/resources/BookWithDoctype.xml ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision Added: svn:mergeinfo + Added: svn:eol-style + native Copied: trunk/xmlunit/src/tests/resources/invalidBookWithDoctype.xml (from rev 339, trunk/xmlunit/src/tests/resources/invalidBook.xml) =================================================================== --- trunk/xmlunit/src/tests/resources/invalidBookWithDoctype.xml (rev 0) +++ trunk/xmlunit/src/tests/resources/invalidBookWithDoctype.xml 2009-06-02 13:32:19 UTC (rev 340) @@ -0,0 +1,9 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE Book PUBLIC "XMLUNIT/TEST/PUB" "http://example.org/nonsense"> +<Book> + <Title>Chicken Soup for the Soul</Title> + <Author>Jack Canfield</Author> + <Author>Mark Victor Hansen</Author> + <Date>1993</Date> + <ISBN>1-55874-262-X</ISBN> +</Book> Property changes on: trunk/xmlunit/src/tests/resources/invalidBookWithDoctype.xml ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision Added: svn:mergeinfo + Added: svn:eol-style + native This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |