/** | |
* Copyright 2006 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 tests.w3c; | |
import java.io.ByteArrayInputStream; | |
import java.io.ByteArrayOutputStream; | |
import java.io.File; | |
import java.io.FileReader; | |
import java.io.InputStreamReader; | |
import java.lang.reflect.InvocationTargetException; | |
import java.util.ListIterator; | |
import org.apache.ws.commons.schema.XmlSchema; | |
import org.apache.ws.commons.schema.XmlSchemaCollection; | |
import org.custommonkey.xmlunit.DetailedDiff; | |
import org.custommonkey.xmlunit.Diff; | |
import org.custommonkey.xmlunit.Difference; | |
import org.custommonkey.xmlunit.DifferenceConstants; | |
import org.custommonkey.xmlunit.IgnoreTextAndAttributeValuesDifferenceListener; | |
import org.custommonkey.xmlunit.XMLTestCase; | |
import org.w3c.dom.Element; | |
/** | |
* Class to test a single schema by roundtripping it using XMLUnit | |
* cmd line parms: arg0 - valid|invalid arg1 - path to xsd file | |
* | |
*/ | |
public class TestRoundTripXSD extends XMLTestCase { | |
private static boolean debug; | |
static { | |
String debugString = System.getProperty("debug"); | |
debug = (debugString == null) ? false : debugString.equals("true"); | |
} | |
private File fileToTest = null; | |
private boolean valid = false; | |
public final static void main(String[] args) { | |
junit.textui.TestRunner.run(new TestRoundTripXSD(new File(args[1]), | |
args[0].equals("valid"))); | |
} | |
public TestRoundTripXSD() { | |
this(new File(System.getProperty("W3CTestLocation")), | |
System.getProperty("W3CTestValidity").equals("valid")); | |
} | |
public TestRoundTripXSD(File f, boolean valid) { | |
super(basename(f)); | |
this.fileToTest = f; | |
this.valid = valid; | |
} | |
private static String basename(File f) { | |
String path = f.getPath(); | |
int i = path.lastIndexOf(System.getProperty("file.separator")); | |
String retval = path.substring(i+1); | |
return retval; | |
} | |
protected void runTest() throws Throwable { | |
try { | |
testRoundTrip(); | |
} | |
catch (InvocationTargetException e) { | |
e.fillInStackTrace(); | |
throw e.getTargetException(); | |
} | |
catch (IllegalAccessException e) { | |
e.fillInStackTrace(); | |
throw e; | |
} | |
} | |
public void testRoundTrip() throws Exception { | |
XmlSchema schema = null; | |
DetailedDiff detaileddiffs = null; | |
try { | |
if (debug) { | |
System.out.println("fileToTest=" + this.fileToTest); | |
System.out.println("valid=" + this.valid); | |
} | |
schema = loadSchema(fileToTest); | |
// TODO: if we get here and the input was meant to be invalid perhaps | |
// should fail. Depends on whether XmlSchema is doing validation. For | |
// now we're ignoring invalid tests. | |
ByteArrayOutputStream baos = new ByteArrayOutputStream(); | |
schema.write(baos); | |
Diff diff = new Diff(new FileReader(fileToTest), | |
new InputStreamReader(new ByteArrayInputStream(baos | |
.toByteArray()))); | |
detaileddiffs = new DetailedDiff(diff); | |
detaileddiffs.overrideDifferenceListener(new SchemaAttrDiff()); | |
boolean result = detaileddiffs.similar(); | |
if (!result && debug) printFailureDetail(schema, detaileddiffs); | |
assertTrue("Serialized out schema not similar to original", result); | |
} catch (Exception e) { | |
if (this.valid) { | |
if (debug) printFailureDetail(schema, detaileddiffs); | |
throw new Exception(this.fileToTest.getPath(), e); | |
} | |
} | |
} | |
public XmlSchema loadSchema(File f) throws Exception { | |
XmlSchemaCollection col = new XmlSchemaCollection(); | |
col.setBaseUri(f.getPath()); | |
XmlSchema xmlSchema = col.read(new FileReader(f), null); | |
return xmlSchema; | |
} | |
static class SchemaAttrDiff extends | |
IgnoreTextAndAttributeValuesDifferenceListener { | |
public int differenceFound(Difference difference) { | |
if (difference.getId() == DifferenceConstants.ELEMENT_NUM_ATTRIBUTES | |
.getId()) { | |
// control and test have to be elements | |
// check if they are schema elements .. they only | |
// seem to have the added attributeFormDefault and | |
// elementFormDefault attributes | |
// so shldnt have more than 2 attributes difference | |
Element actualEl = (Element) difference.getControlNodeDetail() | |
.getNode(); | |
if (actualEl.getLocalName().equals("schema")) { | |
int expectedAttrs = Integer.parseInt(difference | |
.getControlNodeDetail().getValue()); | |
int actualAttrs = Integer.parseInt(difference | |
.getTestNodeDetail().getValue()); | |
if (Math.abs(actualAttrs - expectedAttrs) <= 2) { | |
return RETURN_IGNORE_DIFFERENCE_NODES_SIMILAR; | |
} | |
} | |
} else if (difference.getId() == DifferenceConstants.ATTR_NAME_NOT_FOUND_ID) { | |
// sometimes the serializer throws in a few extra attributes... | |
Element actualEl = (Element) difference.getControlNodeDetail() | |
.getNode(); | |
if (actualEl.getLocalName().equals("schema")) { | |
return RETURN_IGNORE_DIFFERENCE_NODES_SIMILAR; | |
} | |
} | |
return super.differenceFound(difference); | |
} | |
} | |
private void printFailureDetail(XmlSchema schema, DetailedDiff detaileddiffs) { | |
System.err.println(super.getName() + " failure detail"); | |
System.err.println("-----"); | |
schema.write(System.err); | |
if (detaileddiffs != null) { | |
ListIterator li = detaileddiffs.getAllDifferences().listIterator(); | |
while (li.hasNext()) { | |
System.err.println(li.next()); | |
} | |
} | |
} | |
} |