/* 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 compile.scomp.detailed; | |
import compile.scomp.common.CompileCommon; | |
import org.apache.xmlbeans.*; | |
import org.apache.xmlbeans.impl.xb.xsdschema.SchemaDocument; | |
import org.junit.Test; | |
import javax.xml.namespace.QName; | |
import java.io.File; | |
import java.util.ArrayList; | |
import java.util.Iterator; | |
import static org.junit.Assert.*; | |
public class DetailedCompTests { | |
/** | |
* This test requires laxDoc.xsd to be compiled and | |
* on the classpath ahead of time, otherwise documentation | |
* element processing would not occur | |
* @throws Exception | |
*/ | |
@Test | |
public void testLaxDocProcessing() throws Exception { | |
QName q = new QName("urn:lax.Doc.Compilation", "ItemRequest"); | |
ArrayList err = new ArrayList(); | |
XmlOptions xm_opt = new XmlOptions().setErrorListener(err); | |
xm_opt.setSavePrettyPrint(); | |
XmlObject xObj = XmlObject.Factory.parse( | |
new File(CompileCommon.fileLocation+"/detailed/laxDoc.xsd")); | |
XmlObject[] schemas = new XmlObject[]{xObj}; | |
// ensure exception is thrown when | |
// xmloptions flag is not set | |
boolean valDocEx = false; | |
try{ | |
SchemaTypeSystem sts = XmlBeans.compileXmlBeans(null, null, | |
schemas, null, XmlBeans.getBuiltinTypeSystem(), null, xm_opt); | |
assertNotNull("STS was null", sts); | |
}catch(XmlException xmlEx){ | |
valDocEx = true; | |
System.err.println("Expected Error: "+xmlEx.getMessage()); | |
} catch(Exception e){ | |
throw e; | |
} | |
//check exception was thrown | |
if(!valDocEx) | |
throw new Exception("Documentation processing " + | |
"should have thrown and error"); | |
// validate error code | |
valDocEx = false; | |
for (Iterator iterator = err.iterator(); iterator.hasNext();) { | |
XmlError xErr = (XmlError)iterator.next(); | |
//System.out.println("ERROR: '"+ xErr+"'"); | |
//any one of these are possible | |
if(xErr.getErrorCode().compareTo("cvc-complex-type.4") == 0 || | |
xErr.getErrorCode().compareTo("cvc-complex-type.2.3") == 0 || | |
xErr.getErrorCode().compareTo("cvc-complex-type.2.4c") == 0) | |
valDocEx = true; | |
} | |
if (!valDocEx) | |
throw new Exception("Expected Error code did not validate"); | |
//reset errors | |
err.clear(); | |
//ensure no exception when error | |
xm_opt = xm_opt.setCompileNoValidation(); | |
try { | |
SchemaTypeSystem sts = XmlBeans.compileXmlBeans(null, null, | |
schemas, null, XmlBeans.getBuiltinTypeSystem(), null, | |
xm_opt); | |
if(!err.isEmpty()) | |
throw new Exception("Error listener should be empty"); | |
for (Iterator iterator = err.iterator(); iterator.hasNext();) { | |
System.out.println(iterator.next()); | |
} | |
SchemaGlobalElement sge = sts.findElement(q); | |
System.out.println("QName: " + sge.getName()); | |
System.out.println("Type: " + sge.getType()); | |
} catch (Exception e) { | |
throw e; | |
} | |
} | |
private static final String schema_begin = "<xs:schema xmlns:xs=\"http://www.w3.org/2001/XMLSchema\">\n"; | |
private static final String root_decl = "<xs:element name=\"root\">\n <xs:complexType>\n"; | |
private static final String att_decl = " <xs:attribute name=\"att\" type=\"simpleNotType\"/>\n"; | |
private static final String root_end = " </xs:complexType>\n</xs:element>\n"; | |
private static final String schema_end = "</xs:schema>\n"; | |
private static final String notation1 = " <xs:attribute name=\"att\" type=\"xs:NOTATION\"/>\n"; | |
private static final String notation2 = "<xs:simpleType name=\"simpleNotType\">\n" + | |
" <xs:restriction base=\"xs:NOTATION\">\n" + | |
" <xs:pattern value=\"ns:.*\"/>\n" + | |
" </xs:restriction>\n</xs:simpleType>\n"; | |
private static final String notation3 = " <xs:sequence>\n " + | |
"<xs:element name=\"elem\" type=\"xs:ID\"/>\n" + | |
" </xs:sequence>\n"; | |
private static final String notation4 = " targetNamespace=\"scomp.detailed.CompilationTests\" " + | |
"xmlns=\"scomp.detailed.CompilationTests\">\n"; | |
private static final String simpleTypeDef= "<xs:simpleType name=\"simpleNotType\">\n" + | |
" <xs:restriction base=\"enumDef\">\n"; | |
private static final String notation6 = " <xs:pattern value=\"ns:.*\"/>\n"; | |
private static final String notation5 = " <xs:length value=\"6\"/>\n"; | |
private static final String enumDef = " </xs:restriction>\n</xs:simpleType>\n" + | |
"<xs:simpleType name=\"enumDef\">\n" + | |
" <xs:restriction base=\"xs:NOTATION\" xmlns:ns=\"namespace.notation\">\n" + | |
" <xs:enumeration value=\"ns:app1\"/>\n" + | |
" <xs:enumeration value=\"ns:app2\"/>\n" + | |
" </xs:restriction>\n</xs:simpleType>\n"; | |
private static final String doc_begin = "<root xmlns:ns=\"namespace.notation\" " + | |
"xmlns:app=\"namespace.notation\" att=\""; | |
private static final String doc_end = "\"/>"; | |
private static final String notation7 = "ns1:app1"; | |
private static final String notation8 = "ns:app"; | |
private static final String notation9 = "app:app1"; | |
private static final String notation10 = "ns:app1"; | |
/** | |
* This tests usage of the xs:NOTATION type | |
*/ | |
@Test | |
public void testNotation() throws Exception | |
{ | |
String schema; | |
String xml; | |
SchemaTypeSystem typeSystem; | |
XmlObject[] parsedSchema = new XmlObject[1]; | |
XmlObject parsedDoc; | |
XmlOptions opts = new XmlOptions(); | |
ArrayList errors = new ArrayList(); | |
opts.setErrorListener(errors); | |
opts.put("COMPILE_PARTIAL_TYPESYSTEM"); | |
// 1. Negative test - Error if xs:NOTATION used directly | |
schema = schema_begin + root_decl + notation1 + root_end + schema_end; | |
// System.out.println(schema); | |
parsedSchema[0] = SchemaDocument.Factory.parse(schema); | |
errors.clear(); | |
XmlBeans.compileXsd(parsedSchema, null, opts); | |
assertTrue("Expected error: NOTATION type cannot be used directly", errors.size() == 1); | |
assertEquals("Expected error: NOTATION type cannot be used directly", | |
XmlErrorCodes.ATTR_NOTATION_TYPE_FORBIDDEN, ((XmlError)errors.get(0)).getErrorCode()); | |
assertEquals(XmlError.SEVERITY_ERROR, ((XmlError)errors.get(0)).getSeverity()); | |
// 2. Negative test - Error if xs:NOTATION restricted without enumeration | |
schema = schema_begin + root_decl + att_decl + root_end + notation2 + schema_end; | |
// System.out.println(schema); | |
parsedSchema[0] = SchemaDocument.Factory.parse(schema); | |
errors.clear(); | |
XmlBeans.compileXsd(parsedSchema, null, opts); | |
assertTrue("Expected error: restriction of NOTATION must use enumeration facet", errors.size() == 1); | |
assertEquals("Expected error: restriction of NOTATION must use enumeration facet", | |
XmlErrorCodes.DATATYPE_ENUM_NOTATION, ((XmlError)errors.get(0)).getErrorCode()); | |
assertEquals(XmlError.SEVERITY_ERROR, ((XmlError)errors.get(0)).getSeverity()); | |
// 3. Warning if xs:NOTATION used as type of an element | |
final String correctTypes = simpleTypeDef + notation6 + enumDef; | |
schema = schema_begin + root_decl + notation3 + root_end + correctTypes + schema_end; | |
// System.out.println(schema); | |
parsedSchema[0] = SchemaDocument.Factory.parse(schema); | |
errors.clear(); | |
XmlBeans.compileXsd(parsedSchema, null, opts); | |
assertTrue("Expected warning: NOTATION-derived type should not be used on elements", errors.size() == 1); | |
assertEquals("Expected warning: NOTATION-derived type should not be used on elements", | |
XmlErrorCodes.ELEM_COMPATIBILITY_TYPE, ((XmlError)errors.get(0)).getErrorCode()); | |
assertEquals(XmlError.SEVERITY_WARNING, ((XmlError)errors.get(0)).getSeverity()); | |
// 4. Warning if xs:NOTATION is used in a Schema with target namespace | |
schema = schema_begin.substring(0, schema_begin.length() - 2) + notation4 + root_decl + | |
att_decl + root_end + correctTypes + schema_end; | |
// System.out.println(schema); | |
parsedSchema[0] = SchemaDocument.Factory.parse(schema); | |
errors.clear(); | |
XmlBeans.compileXsd(parsedSchema, null, opts); | |
assertTrue("Expected warning: NOTATION-derived type should not be used in a Schema with target namespace", errors.size() == 1); | |
assertEquals("Expected warning: NOTATION-derived type should not be used in a Schema with target namespace", | |
XmlErrorCodes.ATTR_COMPATIBILITY_TARGETNS, ((XmlError)errors.get(0)).getErrorCode()); | |
assertEquals(XmlError.SEVERITY_WARNING, ((XmlError)errors.get(0)).getSeverity()); | |
// 5. Warning - Deprecation of minLength, maxLength and length facets | |
schema = schema_begin + root_decl + att_decl + root_end + simpleTypeDef + notation5 + | |
enumDef + schema_end; | |
// System.out.println(schema); | |
parsedSchema[0] = SchemaDocument.Factory.parse(schema); | |
errors.clear(); | |
XmlBeans.compileXsd(parsedSchema, null, opts); | |
assertTrue("Expected warning: length facet cannot be used on a type derived from NOTATION", errors.size() == 1); | |
assertEquals("Expected warning: length facet cannot be used on a type derived from NOTATION", | |
XmlErrorCodes.FACETS_DEPRECATED_NOTATION, ((XmlError)errors.get(0)).getErrorCode()); | |
assertEquals(XmlError.SEVERITY_WARNING, ((XmlError)errors.get(0)).getSeverity()); | |
// 6. Positive test - Test restriction via enumeration, then same as 2 | |
schema = schema_begin + root_decl + att_decl + root_end + correctTypes + schema_end; | |
// System.out.println(schema); | |
parsedSchema[0] = SchemaDocument.Factory.parse(schema); | |
errors.clear(); | |
typeSystem = XmlBeans.compileXsd(parsedSchema, null, opts); | |
assertTrue("Expected no errors or warnings", errors.size() == 0); | |
SchemaType docType = typeSystem.findDocumentType(new QName("", "root")); | |
SchemaType type = docType.getElementProperty(new QName("", "root")).getType(). | |
getAttributeProperty(new QName("", "att")).getType(); | |
assertEquals(type.getPrimitiveType().getBuiltinTypeCode(), SchemaType.BTC_NOTATION); | |
SchemaTypeLoader loader = XmlBeans.typeLoaderUnion(new SchemaTypeLoader[] {typeSystem, | |
XmlBeans.getBuiltinTypeSystem()}); | |
// 7. Validation negative - Test error if QName has bad prefix | |
xml = doc_begin + notation7 + doc_end; | |
parsedDoc = loader.parse(xml, null, opts); | |
assertEquals("Did not find the root element in the Schema", docType, parsedDoc.schemaType()); | |
errors.clear(); | |
parsedDoc.validate(opts); | |
// Both "prefix not found" and "pattern doesn't match" errors | |
assertTrue("Expected validation errors", errors.size() == 2); | |
// Unfortunately, can't get the error code because it is logged via an intermediate exception | |
assertTrue("Expected prefix not found error", ((XmlError) errors.get(0)).getMessage(). | |
indexOf("Invalid QName") >= 0); | |
assertEquals(XmlError.SEVERITY_ERROR, ((XmlError) errors.get(0)).getSeverity()); | |
// System.out.println(xml); | |
// 8. Validation negative - Test error if QName has correct prefix but not in enumeration | |
xml = doc_begin + notation8 + doc_end; | |
parsedDoc = loader.parse(xml, null, opts); | |
assertEquals("Did not find the root element in the Schema", docType, parsedDoc.schemaType()); | |
errors.clear(); | |
parsedDoc.validate(opts); | |
assertTrue("Expected validation errors", errors.size() == 1); | |
assertEquals("Expected prefix not found error", XmlErrorCodes.DATATYPE_ENUM_VALID, | |
((XmlError) errors.get(0)).getErrorCode()); | |
assertEquals(XmlError.SEVERITY_ERROR, ((XmlError) errors.get(0)).getSeverity()); | |
// System.out.println(xml); | |
// 9. Validation negative - Test error if QName doesn't match the extra facet | |
xml = doc_begin + notation9 + doc_end; | |
parsedDoc = loader.parse(xml, null, opts); | |
assertEquals("Did not find the root element in the Schema", docType, parsedDoc.schemaType()); | |
errors.clear(); | |
parsedDoc.validate(opts); | |
assertTrue("Expected validation errors", errors.size() == 1); | |
assertEquals("Expected prefix not found error", XmlErrorCodes.DATATYPE_VALID$PATTERN_VALID, | |
((XmlError) errors.get(0)).getErrorCode()); | |
assertEquals(XmlError.SEVERITY_ERROR, ((XmlError) errors.get(0)).getSeverity()); | |
// System.out.println(xml); | |
// 10. Validation positive - Test that validation can be performed correctly | |
xml = doc_begin + notation10 + doc_end; | |
parsedDoc = loader.parse(xml, null, opts); | |
assertEquals("Did not find the root element in the Schema", docType, parsedDoc.schemaType()); | |
errors.clear(); | |
parsedDoc.validate(opts); | |
assertTrue("Expected no validation errors", errors.size() == 0); | |
// System.out.println(xml); | |
} | |
} |