| /* Copyright 2004 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 tools.inst2xsd.common; |
| |
| import common.Common; |
| import org.apache.xmlbeans.*; |
| import org.apache.xmlbeans.impl.inst2xsd.Inst2Xsd; |
| import org.apache.xmlbeans.impl.inst2xsd.Inst2XsdOptions; |
| import org.apache.xmlbeans.impl.xb.xsdschema.SchemaDocument; |
| import tools.xml.XmlComparator; |
| |
| import java.util.ArrayList; |
| import java.util.Collection; |
| |
| import static org.junit.Assert.assertNotNull; |
| |
| public class Inst2XsdTestBase extends Common { |
| |
| public static tools.inst2xsd.common.Inst2XsdCommon common; |
| private static boolean _verbose = true; |
| |
| private static String caseroot = XBEAN_CASE_ROOT; |
| //location of files under "cases folder" |
| private static String miscDir = caseroot + P + "tools"; |
| private static String inst2xsdDir = miscDir + P + "inst2xsd" + P; |
| protected static String OPTION_CASES_DIR = inst2xsdDir + P + "options" + P; |
| protected static String SCHEMA_CASES_DIR = inst2xsdDir + P + "schema" + P; |
| protected static final String BASEXML = OPTION_CASES_DIR + "base.xml"; |
| protected static final String EXPBASEXML = OPTION_CASES_DIR + "base0.xsd"; |
| |
| |
| protected XmlObject getTypeXml(String val) throws Exception { |
| return XmlObject.Factory.parse(setTypeVal(val)); |
| } |
| |
| private String setTypeVal(String val) { |
| String base_start = "<a xmlns=\"typeTests\">"; |
| String base_end = "</a>"; |
| return base_start + val + base_end; |
| } |
| |
| protected XmlObject getAttrTypeXml(String val) throws Exception { |
| return XmlObject.Factory.parse(setAttrVal(val)); |
| } |
| |
| private String setAttrVal(String val) { |
| String attr_base_end = "\" />"; |
| String attr_base_start = "<a xmlns=\"attrTests\" a=\""; |
| return attr_base_start + val + attr_base_end; |
| } |
| |
| //attribute testing methods |
| |
| private String getAttrTypeXmlVenetian(String type) { |
| return "<schema attributeFormDefault=\"unqualified\" elementFormDefault=\"qualified\" " + |
| "targetNamespace=\"attrTests\" xmlns=\"http://www.w3.org/2001/XMLSchema\">" + |
| "<element name=\"a\" type=\"att:aType\" xmlns:att=\"attrTests\"/>" + |
| "<complexType name=\"aType\">" + |
| "<simpleContent>" + |
| "<extension base=\"xs:string\" xmlns:xs=\"http://www.w3.org/2001/XMLSchema\">" + |
| "<attribute type=\"xs:" + type + "\" name=\"a\"/>" + |
| "</extension>" + |
| "</simpleContent></complexType></schema>"; |
| } |
| |
| private String getAttrTypeXmlRDandSS(String type) { |
| return "<schema attributeFormDefault=\"unqualified\" elementFormDefault=\"qualified\" " + |
| "targetNamespace=\"attrTests\" xmlns=\"http://www.w3.org/2001/XMLSchema\">" + |
| "<element name=\"a\">" + |
| "<complexType>" + |
| "<simpleContent>" + |
| "<extension base=\"xs:string\" xmlns:xs=\"http://www.w3.org/2001/XMLSchema\">" + |
| "<attribute type=\"xs:" + type + "\" name=\"a\"/>" + |
| "</extension>" + |
| "</simpleContent>" + |
| "</complexType></element></schema>"; |
| } |
| |
| protected void runAttrTypeChecking(XmlObject act, String expType) throws Exception { |
| |
| log("=== Venetian options ==="); |
| runAttrTypeChecking(act, expType, Inst2XsdCommon.getVenetianOptions()); |
| log("=== Russian options ==="); |
| runAttrTypeChecking(act, expType, Inst2XsdCommon.getRussianOptions()); |
| log("=== Salami options ==="); |
| runAttrTypeChecking(act, expType, Inst2XsdCommon.getSalamiOptions()); |
| log("=== Default options ==="); |
| runAttrTypeChecking(act, expType, Inst2XsdCommon.getDefaultInstOptions()); |
| } |
| |
| private void runAttrTypeChecking(XmlObject act, String expType, Inst2XsdOptions opt) throws Exception { |
| SchemaDocument[] venetian = (SchemaDocument[]) runInst2Xsd(act, opt); |
| checkLength(venetian, 1); |
| |
| if (opt.getDesign() == Inst2XsdOptions.DESIGN_RUSSIAN_DOLL || |
| opt.getDesign() == Inst2XsdOptions.DESIGN_SALAMI_SLICE) |
| compare(venetian[0], XmlObject.Factory.parse(getAttrTypeXmlRDandSS(expType))); |
| else if (opt.getDesign() == Inst2XsdOptions.DESIGN_VENETIAN_BLIND) |
| compare(venetian[0], XmlObject.Factory.parse(getAttrTypeXmlVenetian(expType))); |
| else |
| throw new Exception("Design style was not found"); |
| |
| checkInstance(venetian, new XmlObject[]{act}); |
| |
| } |
| |
| //element value test methods |
| protected void runTypeChecking(XmlObject act, String expType) throws Exception { |
| log("=== Venetian options ==="); |
| runTypeChecking(act, expType, Inst2XsdCommon.getVenetianOptions()); |
| log("=== Russian options ==="); |
| runTypeChecking(act, expType, Inst2XsdCommon.getRussianOptions()); |
| log("=== Salami options ==="); |
| runTypeChecking(act, expType, Inst2XsdCommon.getSalamiOptions()); |
| log("=== Default options ==="); |
| runTypeChecking(act, expType, Inst2XsdCommon.getDefaultInstOptions()); |
| } |
| |
| |
| private void runTypeChecking(XmlObject act, String expType, Inst2XsdOptions opt) throws Exception { |
| SchemaDocument[] venetian = (SchemaDocument[]) runInst2Xsd(act, opt); |
| checkLength(venetian, 1); |
| log("actual: " + act); |
| log("expType: " + expType); |
| checkInstance(venetian, new XmlObject[]{act}); |
| compare(venetian[0], XmlObject.Factory.parse(getExpTypeXml(expType))); |
| } |
| |
| private String getExpTypeXml(String type) { |
| return "<xs:schema attributeFormDefault=\"unqualified\" " + |
| "elementFormDefault=\"qualified\" targetNamespace=\"typeTests\"" + |
| " xmlns:xs=\"http://www.w3.org/2001/XMLSchema\" >" + |
| "<xs:element name=\"a\" type=\"xs:" + type + "\"" + |
| " xmlns:xs=\"http://www.w3.org/2001/XMLSchema\" />" + |
| "</xs:schema>"; |
| } |
| |
| //type coercion/LCD test methods |
| protected void runLCDTypeCheckTest(String val1, String val2, String expType) throws Exception { |
| log("=== Venetian options ==="); |
| runLCDTypeChecking(val1, val2, expType, Inst2XsdCommon.getVenetianOptions()); |
| log("=== Russian options ==="); |
| runLCDTypeChecking(val1, val2, expType, Inst2XsdCommon.getRussianOptions()); |
| log("=== Salami options ==="); |
| runLCDTypeChecking(val1, val2, expType, Inst2XsdCommon.getSalamiOptions()); |
| log("=== Default options ==="); |
| runLCDTypeChecking(val1, val2, expType, Inst2XsdCommon.getDefaultInstOptions()); |
| } |
| |
| private void runLCDTypeChecking(String val1, String val2, String expType, Inst2XsdOptions opt) throws Exception { |
| XmlObject act = getTypeCoerceXml(val1, val2); |
| SchemaDocument[] venetian = (SchemaDocument[]) runInst2Xsd(act, opt); |
| checkLength(venetian, 1); |
| log("instance: " + act); |
| log("expType: " + expType); |
| checkInstance(venetian, new XmlObject[]{act}); |
| |
| if (opt.getDesign() == Inst2XsdOptions.DESIGN_VENETIAN_BLIND) |
| compare(venetian[0], getExpLCDXml_vb(expType)); |
| else if (opt.getDesign() == Inst2XsdOptions.DESIGN_SALAMI_SLICE) |
| compare(venetian[0], getExpLCDXml_ss(expType)); |
| else if (opt.getDesign() == Inst2XsdOptions.DESIGN_RUSSIAN_DOLL) |
| compare(venetian[0], getExpLCDXml_rd(expType)); |
| else |
| compare(venetian[0], getExpLCDXml_vb(expType)); |
| } |
| |
| private String getTypeCoerceXmlString(String val1, String val2) { |
| return "<a xmlns=\"typeCoercion\">" + |
| " <b c=\"" + val1 + "\">" + val1 + "</b>" + |
| " <b c=\"" + val2 + "\">" + val2 + "</b>" + |
| "</a>"; |
| } |
| |
| private XmlObject getTypeCoerceXml(String val1, String val2) throws XmlException { |
| return XmlObject.Factory.parse(getTypeCoerceXmlString(val1, val2)); |
| } |
| |
| |
| private XmlObject getExpLCDXml_vb(String type) throws XmlException { |
| return XmlObject.Factory.parse("<xs:schema attributeFormDefault=\"unqualified\" elementFormDefault=\"qualified\" targetNamespace=\"typeCoercion\" xmlns:xs=\"http://www.w3.org/2001/XMLSchema\">\n" + |
| " <xs:element name=\"a\" type=\"typ:aType\" xmlns:typ=\"typeCoercion\"/>\n" + |
| " <xs:complexType name=\"aType\">\n" + |
| " <xs:sequence>\n" + |
| " <xs:element type=\"typ:bType\" name=\"b\" maxOccurs=\"unbounded\" minOccurs=\"0\" xmlns:typ=\"typeCoercion\"/>\n" + |
| " </xs:sequence>\n" + |
| " </xs:complexType>\n" + |
| " <xs:complexType name=\"bType\">\n" + |
| " <xs:simpleContent>\n" + |
| " <xs:extension base=\"xs:" + type + "\" xmlns:xs=\"http://www.w3.org/2001/XMLSchema\">\n" + |
| " <xs:attribute type=\"xs:" + type + "\" name=\"c\" use=\"optional\"/>\n" + |
| " </xs:extension>\n" + |
| " </xs:simpleContent>\n" + |
| " </xs:complexType>\n" + |
| "</xs:schema>"); |
| } |
| |
| private XmlObject getExpLCDXml_ss(String type) throws XmlException { |
| return XmlObject.Factory.parse("<xs:schema attributeFormDefault=\"unqualified\" elementFormDefault=\"qualified\" targetNamespace=\"typeCoercion\" xmlns:xs=\"http://www.w3.org/2001/XMLSchema\">\n" + |
| " <xs:element name=\"b\">\n" + |
| " <xs:complexType>\n" + |
| " <xs:simpleContent>\n" + |
| " <xs:extension base=\"xs:" + type + "\" xmlns:xs=\"http://www.w3.org/2001/XMLSchema\">\n" + |
| " <xs:attribute type=\"xs:" + type + "\" name=\"c\" use=\"optional\"/>\n" + |
| " </xs:extension>\n" + |
| " </xs:simpleContent>\n" + |
| " </xs:complexType>\n" + |
| " </xs:element>\n" + |
| " <xs:element name=\"a\">\n" + |
| " <xs:complexType>\n" + |
| " <xs:sequence>\n" + |
| " <xs:element ref=\"typ:b\" maxOccurs=\"unbounded\" minOccurs=\"0\" xmlns:typ=\"typeCoercion\"/>\n" + |
| " </xs:sequence>\n" + |
| " </xs:complexType>\n" + |
| " </xs:element>\n" + |
| "</xs:schema>"); |
| } |
| |
| private XmlObject getExpLCDXml_rd(String type) throws XmlException { |
| return XmlObject.Factory.parse("<xs:schema attributeFormDefault=\"unqualified\" elementFormDefault=\"qualified\" targetNamespace=\"typeCoercion\" xmlns:xs=\"http://www.w3.org/2001/XMLSchema\">\n" + |
| " <xs:element name=\"a\">\n" + |
| " <xs:complexType>\n" + |
| " <xs:sequence>\n" + |
| " <xs:element name=\"b\" maxOccurs=\"unbounded\" minOccurs=\"0\">\n" + |
| " <xs:complexType>\n" + |
| " <xs:simpleContent>\n" + |
| " <xs:extension base=\"xs:" + type + "\" xmlns:xs=\"http://www.w3.org/2001/XMLSchema\">\n" + |
| " <xs:attribute type=\"xs:" + type + "\" name=\"c\" use=\"optional\"/>\n" + |
| " </xs:extension>\n" + |
| " </xs:simpleContent>\n" + |
| " </xs:complexType>\n" + |
| " </xs:element>\n" + |
| " </xs:sequence>\n" + |
| " </xs:complexType>\n" + |
| " </xs:element>\n" + |
| "</xs:schema>"); |
| } |
| |
| |
| protected static XmlObject[] runInst2Xsd(XmlObject inst, Inst2XsdOptions options) { |
| return Inst2Xsd.inst2xsd(new XmlObject[]{inst}, options); |
| } |
| |
| protected static XmlObject[] runInst2Xsd(XmlObject[] inst, Inst2XsdOptions options) { |
| return Inst2Xsd.inst2xsd(inst, options); |
| } |
| |
| |
| protected static SchemaDocument[] getSchemaDoc(XmlObject[] inst) throws XmlException { |
| SchemaDocument[] docs = new SchemaDocument[inst.length]; |
| for (int i = 0; i < docs.length; i++) { |
| docs[i] = SchemaDocument.Factory.parse(inst[i].xmlText()); |
| } |
| return docs; |
| |
| } |
| |
| protected static void runSchemaBuild(XmlObject inst, Inst2XsdOptions opts, XmlObject exp) throws Exception { |
| XmlObject[] genSchema = runInst2Xsd(inst, opts); |
| log(genSchema); |
| checkInstanceToAll(genSchema, inst, exp); |
| checkLength(genSchema, 1); |
| compare(genSchema[0], exp); |
| |
| } |
| |
| protected static void runSchemaBuild(XmlObject inst, Inst2XsdOptions opts, XmlObject[] exp) throws XmlException { |
| XmlObject[] genSchema = runInst2Xsd(inst, opts); |
| log(genSchema); |
| checkInstanceToAll(genSchema, new XmlObject[]{inst}, exp); |
| checkLength(genSchema, exp.length); |
| compare(genSchema, exp); |
| |
| } |
| |
| //TODO: Make this error narrowed |
| protected static void checkLength(Object[] obj, int val) throws XmlException { |
| log("Length = " + obj.length + " exp: " + val); |
| |
| if (obj.length < val) { |
| throw new XmlException("Actual was smaller than expected"); |
| } else if (obj.length > val) { |
| throw new XmlException("Actual was larger than expected"); |
| } |
| } |
| |
| |
| public static void compare(XmlObject[] act, XmlObject[] exp) throws XmlException { |
| checkLength(act, exp.length); |
| //Arrays.sort(act); |
| //Arrays.sort(exp); |
| //if (Arrays.equals(act, exp)){ |
| // return; |
| //}else{ |
| for (int i = 0; i < act.length; i++) { |
| compare(act[i], exp[i]); |
| } |
| |
| } |
| |
| public static void compare(XmlObject act, XmlObject exp) throws XmlException { |
| XmlComparator.Diagnostic diag = XmlComparator.lenientlyCompareTwoXmlStrings(act.xmlText(Inst2XsdCommon.getXmlOptions()), |
| exp.xmlText(Inst2XsdCommon.getXmlOptions())); |
| if (diag.hasMessage()) { |
| log("Expected: \n" + exp.xmlText(Inst2XsdCommon.getXmlOptions())); |
| log("Actual: \n" + act.xmlText(Inst2XsdCommon.getXmlOptions())); |
| throw new XmlException("Xml Comparison Failed:\n" + diag.toString()); |
| } |
| } |
| |
| public static void log(XmlObject[] doc) { |
| if (_verbose) { |
| for (int i = 0; i < doc.length; i++) { |
| log("Schema[" + i + "] - " + doc[i].xmlText(Inst2XsdCommon.getXmlOptions())); |
| } |
| } |
| } |
| |
| public static void log(String msg) { |
| if (_verbose) |
| System.out.println(msg); |
| } |
| |
| public static void log(XmlObject obj) { |
| if (_verbose) |
| System.out.println(obj.xmlText(Inst2XsdCommon.getXmlOptions())); |
| } |
| |
| |
| private static void checkInstanceToAll(XmlObject[] actSchemaDoc, XmlObject inst, |
| XmlObject expSchemas) throws Exception { |
| checkInstanceToAll(getSchemaDoc(actSchemaDoc), new XmlObject[]{inst}, getSchemaDoc(new XmlObject[]{expSchemas})); |
| } |
| |
| private static void checkInstanceToAll(XmlObject[] actSchemaDoc, XmlObject[] inst, |
| XmlObject[] expSchemas) throws XmlException { |
| checkInstanceToAll(getSchemaDoc(actSchemaDoc), inst, getSchemaDoc(expSchemas)); |
| } |
| |
| private static void checkInstanceToAll(SchemaDocument[] actSchemaDoc, XmlObject[] inst, |
| SchemaDocument[] expSchemas) throws XmlException { |
| log("-= Comparing Actual to instance=-"); |
| if (checkInstance(actSchemaDoc, inst)) |
| log("-= Instance validated actual =-"); |
| |
| log("-= Comparing Expected to instance=-"); |
| if (checkInstance(expSchemas, inst)) |
| log("-= Instance validated Expected =-"); |
| |
| } |
| |
| private static boolean checkInstance(SchemaDocument[] sDocs, XmlObject[] inst) throws XmlException { |
| if (validateInstances(sDocs, inst)) { |
| return true; |
| } else { |
| throw new XmlException("Instance Failed to validate"); |
| } |
| } |
| |
| /** |
| * Copied from inst2Xsd as option may be removed |
| */ |
| private static boolean validateInstances(SchemaDocument[] sDocs, XmlObject[] instances) { |
| |
| SchemaTypeLoader sLoader; |
| Collection compErrors = new ArrayList(); |
| XmlOptions schemaOptions = new XmlOptions(); |
| schemaOptions.setErrorListener(compErrors); |
| try { |
| sLoader = XmlBeans.loadXsd(sDocs, schemaOptions); |
| } catch (Exception e) { |
| if (compErrors.isEmpty() || !(e instanceof XmlException)) { |
| e.printStackTrace(System.out); |
| } |
| System.out.println("Schema invalid"); |
| for (Object compError : compErrors) System.out.println(compError); |
| return false; |
| } |
| |
| boolean result = true; |
| |
| for (int i = 0; i < instances.length; i++) { |
| String instance = instances[i].toString(); |
| |
| XmlObject xobj; |
| |
| try { |
| assertNotNull(sLoader); |
| xobj = sLoader.parse(instance, null, new XmlOptions().setLoadLineNumbers()); |
| } catch (XmlException e) { |
| System.out.println("Error:\n" + instance + " not loadable: " + e); |
| e.printStackTrace(System.out); |
| result = false; |
| continue; |
| } |
| |
| Collection errors = new ArrayList(); |
| |
| if (xobj.schemaType() == XmlObject.type) { |
| System.out.println(instance + " NOT valid. "); |
| System.out.println(" Document type not found."); |
| result = false; |
| } else if (xobj.validate(new XmlOptions().setErrorListener(errors))) |
| System.out.println("Instance[" + i + "] valid."); |
| else { |
| System.out.println("Instance[" + i + "] NOT valid."); |
| for (Object error : errors) { |
| System.out.println(" " + error); |
| } |
| result = false; |
| } |
| } |
| |
| return result; |
| } |
| |
| } |