diff options
| author | Chris Burdess <dog@bluezoo.org> | 2006-03-03 19:19:01 +0000 |
|---|---|---|
| committer | Chris Burdess <dog@bluezoo.org> | 2006-03-03 19:19:01 +0000 |
| commit | 66b4973184946b9bcdef8229159b4a341797ac6d (patch) | |
| tree | 0b98437927be178233056628f991c00a7a9e8895 /gnu/xml/validation/xmlschema/XMLSchemaValidatorHandler.java | |
| parent | 0c5acec995103361200f805acf839f09c7456183 (diff) | |
| download | classpath-66b4973184946b9bcdef8229159b4a341797ac6d.tar.gz | |
2006-03-03 Chris Burdess <dog@gnu.org>
* gnu/xml/validation/relaxng/AnyNameNameClass.java,
gnu/xml/validation/relaxng/AttributePattern.java,
gnu/xml/validation/relaxng/ChoiceNameClass.java,
gnu/xml/validation/relaxng/ChoicePattern.java,
gnu/xml/validation/relaxng/DataPattern.java,
gnu/xml/validation/relaxng/Define.java,
gnu/xml/validation/relaxng/ElementPattern.java,
gnu/xml/validation/relaxng/EmptyPattern.java,
gnu/xml/validation/relaxng/FullSyntaxBuilder.java,
gnu/xml/validation/relaxng/Grammar.java,
gnu/xml/validation/relaxng/GrammarException.java,
gnu/xml/validation/relaxng/GrammarValidator.java,
gnu/xml/validation/relaxng/GroupPattern.java,
gnu/xml/validation/relaxng/InterleavePattern.java,
gnu/xml/validation/relaxng/ListPattern.java,
gnu/xml/validation/relaxng/NSNameNameClass.java,
gnu/xml/validation/relaxng/NameClass.java,
gnu/xml/validation/relaxng/NameNameClass.java,
gnu/xml/validation/relaxng/NotAllowedPattern.java,
gnu/xml/validation/relaxng/OneOrMorePattern.java,
gnu/xml/validation/relaxng/Param.java,
gnu/xml/validation/relaxng/Pattern.java,
gnu/xml/validation/relaxng/RELAXNGSchemaFactory.java,
gnu/xml/validation/relaxng/RefPattern.java,
gnu/xml/validation/relaxng/TextPattern.java,
gnu/xml/validation/relaxng/ValuePattern.java: New RELAX NG grammar
builder and data model.
* gnu/xml/validation/xmlschema/AnyAttribute.java,
gnu/xml/validation/xmlschema/AttributeDeclaration.java,
gnu/xml/validation/xmlschema/AttributeUse.java,
gnu/xml/validation/xmlschema/ComplexType.java,
gnu/xml/validation/xmlschema/ElementDeclaration.java,
gnu/xml/validation/xmlschema/Particle.java,
gnu/xml/validation/xmlschema/ValidationException.java,
gnu/xml/validation/xmlschema/XMLSchema.java,
gnu/xml/validation/xmlschema/XMLSchemaAttributeTypeInfo.java,
gnu/xml/validation/xmlschema/XMLSchemaBuilder.java,
gnu/xml/validation/xmlschema/XMLSchemaElementTypeInfo.java,
gnu/xml/validation/xmlschema/XMLSchemaSchemaFactory.java,
gnu/xml/validation/xmlschema/XMLSchemaTypeInfo.java,
gnu/xml/validation/xmlschema/XMLSchemaTypeInfoProvider.java,
gnu/xml/validation/xmlschema/XMLSchemaValidator.java,
gnu/xml/validation/xmlschema/XMLSchemaValidatorHandler.java: New
W3C XML Schema builder and schema components.
* javax/xml/validation/SchemaFactory.java: Recognise RELAX NG and W3C
XML Schema namespace URIs.
Diffstat (limited to 'gnu/xml/validation/xmlschema/XMLSchemaValidatorHandler.java')
| -rw-r--r-- | gnu/xml/validation/xmlschema/XMLSchemaValidatorHandler.java | 394 |
1 files changed, 394 insertions, 0 deletions
diff --git a/gnu/xml/validation/xmlschema/XMLSchemaValidatorHandler.java b/gnu/xml/validation/xmlschema/XMLSchemaValidatorHandler.java new file mode 100644 index 000000000..9e6d8e9a9 --- /dev/null +++ b/gnu/xml/validation/xmlschema/XMLSchemaValidatorHandler.java @@ -0,0 +1,394 @@ +/* XMLSchemaValidatorHandler.java -- + Copyright (C) 2006 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package gnu.xml.validation.xmlschema; + +import java.util.ArrayList; +import java.util.LinkedList; +import javax.xml.XMLConstants; +import javax.xml.namespace.QName; +import javax.xml.validation.TypeInfoProvider; +import javax.xml.validation.ValidatorHandler; +import org.relaxng.datatype.DatatypeException; +import org.relaxng.datatype.DatatypeLibrary; +import org.relaxng.datatype.helpers.DatatypeLibraryLoader; +import org.w3c.dom.TypeInfo; +import org.w3c.dom.ls.LSResourceResolver; +import org.xml.sax.Attributes; +import org.xml.sax.ContentHandler; +import org.xml.sax.ErrorHandler; +import org.xml.sax.Locator; +import org.xml.sax.SAXException; +import org.xml.sax.ext.Attributes2Impl; +import org.xml.sax.helpers.NamespaceSupport; +import gnu.xml.validation.datatype.SimpleType; +import gnu.xml.validation.datatype.Type; + +/** + * Streaming validator. + * + * @author <a href='mailto:dog@gnu.org'>Chris Burdess</a> + */ +final class XMLSchemaValidatorHandler + extends ValidatorHandler +{ + + final XMLSchema schema; + final TypeInfoProvider typeInfoProvider; + final NamespaceSupport namespaceSupport; + final DatatypeLibrary typeLibrary; + Locator loc; + ContentHandler contentHandler; + ErrorHandler errorHandler; + LSResourceResolver resourceResolver; + final LinkedList context; // element context + final ArrayList attributes; // attribute context; + + XMLSchemaValidatorHandler(XMLSchema schema) + { + this.schema = schema; + typeInfoProvider = new XMLSchemaTypeInfoProvider(this); + namespaceSupport = new NamespaceSupport(); + context = new LinkedList(); + attributes = new ArrayList(); + final String ns = XMLConstants.W3C_XML_SCHEMA_NS_URI; + typeLibrary = new DatatypeLibraryLoader().createDatatypeLibrary(ns); + } + + public ContentHandler getContentHandler() + { + return contentHandler; + } + + public void setContentHandler(ContentHandler contentHandler) + { + this.contentHandler = contentHandler; + } + + public ErrorHandler getErrorHandler() + { + return errorHandler; + } + + public void setErrorHandler(ErrorHandler errorHandler) + { + this.errorHandler = errorHandler; + } + + public LSResourceResolver getResourceResolver() + { + return resourceResolver; + } + + public void setResourceResolver(LSResourceResolver resourceResolver) + { + this.resourceResolver = resourceResolver; + } + + public TypeInfoProvider getTypeInfoProvider() + { + return typeInfoProvider; + } + + TypeInfo getElementTypeInfo() + { + return (XMLSchemaElementTypeInfo) context.getFirst(); + } + + TypeInfo getAttributeTypeInfo(int index) + { + return (XMLSchemaAttributeTypeInfo) attributes.get(index); + } + + boolean isIdAttribute(int index) + { + XMLSchemaAttributeTypeInfo typeInfo = + (XMLSchemaAttributeTypeInfo) attributes.get(index); + return typeInfo.id; + } + + boolean isSpecified(int index) + { + XMLSchemaAttributeTypeInfo typeInfo = + (XMLSchemaAttributeTypeInfo) attributes.get(index); + return typeInfo.specified; + } + + public void setDocumentLocator(Locator locator) + { + loc = locator; + if (contentHandler != null) + { + contentHandler.setDocumentLocator(locator); + } + } + + public void startDocument() + throws SAXException + { + namespaceSupport.reset(); + context.clear(); + attributes.clear(); + if (contentHandler != null) + { + contentHandler.startDocument(); + } + } + + public void endDocument() + throws SAXException + { + if (contentHandler != null) + { + contentHandler.endDocument(); + } + } + + public void startPrefixMapping(String prefix, String uri) + throws SAXException + { + namespaceSupport.declarePrefix(prefix, uri); + if (contentHandler != null) + { + contentHandler.startPrefixMapping(prefix, uri); + } + } + + public void endPrefixMapping(String prefix) + throws SAXException + { + if (contentHandler != null) + { + contentHandler.endPrefixMapping(prefix); + } + } + + public void startElement(String uri, String localName, String qName, + Attributes atts) + throws SAXException + { + namespaceSupport.pushContext(); + QName name = new QName(uri, localName); + ElementDeclaration decl = + (ElementDeclaration) schema.elementDeclarations.get(name); + // Validation Rule: Element Locally Valid (Element) + String xsiType = + atts.getValue(XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI, "type"); + xsiType = xsiType.trim(); // normalise + String xsiNil = + atts.getValue(XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI, "nil"); + Type type = decl.datatype; + if (xsiType.length() > 0) + { + try + { + Type specifiedType = resolveType(xsiType); + // TODO 4.3 + type = specifiedType; + } + catch (DatatypeException e) // 4.1, 4.2 + { + ValidationException e2 = + new ValidationException("Can't resolve type " + xsiType, + loc); + e2.initCause(e); + throw e2; + } + } + XMLSchemaElementTypeInfo typeInfo = + new XMLSchemaElementTypeInfo(schema, decl, type); + if (decl == null) // 1 + { + throw new ValidationException("No declaration for " + name, loc); + } + if (decl.isAbstract) // 2 + { + throw new ValidationException("Declaration for " + name + + " is abstract", loc); + } + if (xsiNil.length() > 0) + { + if (!decl.nillable) // 3.1 + { + throw new ValidationException("Declaration for " + name + + " is nillable but xsi:nil present", + loc); + } + else if ("true".equals(xsiNil)) // 3.2 + { + typeInfo.nil = true; + if (decl.type == XMLSchema.CONSTRAINT_FIXED) // 3.2.2 + { + throw new ValidationException("Declaration for " + name + + " is fixed but xsi:nil is true", + loc); + } + } + } + // TODO 5, 6, 7 + + // parent + if (!context.isEmpty()) + { + XMLSchemaElementTypeInfo parent = + (XMLSchemaElementTypeInfo) context.getFirst(); + if (parent.nil) // Element Locally Valid (Element) 3.2.1 + { + throw new ValidationException("Parent of " + qName + + " is declared xsi:nil", loc); + } + // TODO + } + context.addFirst(typeInfo); + // attributes + int len = atts.getLength(); + Attributes2Impl atts2 = new Attributes2Impl(); + int count = 0; + for (int i = 0; i < len; i++) + { + String attUri = atts.getURI(i); + String attLocalName = atts.getLocalName(i); + String attQName = atts.getQName(i); + String attValue = atts.getValue(i); + + if (XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI.equals(attUri)) + { + continue; // ? + } + + QName attName = new QName(attUri, attLocalName); + AttributeDeclaration attDecl = + (AttributeDeclaration) schema.attributeDeclarations.get(attName); + boolean declared = (attDecl != null); + + String attType = (attDecl != null) ? + attDecl.datatype.toString() : "CDATA"; + XMLSchemaAttributeTypeInfo attTypeInfo = + new XMLSchemaAttributeTypeInfo(schema, attDecl, true); + attributes.add(attTypeInfo); + + atts2.addAttribute(attUri, attLocalName, attQName, attType, attValue); + atts2.setDeclared(count, declared); + atts2.setSpecified(count, true); + count++; + } + // add defaulted attributes to atts2 + // TODO + // atts2.setSpecified(count, false); + if (contentHandler != null) + { + contentHandler.startElement(uri, localName, qName, atts2); + } + } + + public void endElement(String uri, String localName, String qName) + throws SAXException + { + // TODO check all required have been seen + context.removeFirst(); + attributes.clear(); + namespaceSupport.popContext(); + if (contentHandler != null) + { + contentHandler.endElement(uri, localName, qName); + } + } + + public void characters(char[] ch, int start, int length) + throws SAXException + { + XMLSchemaElementTypeInfo parent = + (XMLSchemaElementTypeInfo) context.getFirst(); + if (parent.nil) // Element Locally Valid (Element) 3.2.1 + { + throw new ValidationException(parent.decl.name.toString() + + " is declared xsi:nil", + loc); + } + // TODO + if (contentHandler != null) + { + contentHandler.characters(ch, start, length); + } + } + + public void ignorableWhitespace(char[] ch, int start, int length) + throws SAXException + { + if (contentHandler != null) + { + contentHandler.ignorableWhitespace(ch, start, length); + } + } + + public void processingInstruction(String target, String data) + throws SAXException + { + if (contentHandler != null) + { + contentHandler.processingInstruction(target, data); + } + } + + public void skippedEntity(String name) + throws SAXException + { + if (contentHandler != null) + { + contentHandler.skippedEntity(name); + } + } + + Type resolveType(String value) + throws DatatypeException + { + QName name = QName.valueOf(value); + String prefix = name.getPrefix(); + String localName = name.getLocalPart(); + if (prefix != null && prefix.length() > 0) + { + String uri = namespaceSupport.getURI(prefix); + if (!XMLConstants.W3C_XML_SCHEMA_NS_URI.equals(uri)) + return null; + } + if ("anyType".equals(localName)) + return Type.ANY_TYPE; + return (SimpleType) typeLibrary.createDatatype(localName); + } + +} + |
