You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@xerces.apache.org by mr...@apache.org on 2008/08/08 19:44:00 UTC
svn commit: r684022 -
/xerces/java/branches/xml-schema-1.1-dev/src/org/apache/xerces/impl/xs/traversers/StAXSchemaParser.java
Author: mrglavas
Date: Fri Aug 8 10:43:59 2008
New Revision: 684022
URL: http://svn.apache.org/viewvc?rev=684022&view=rev
Log:
JIRA Issue #1313:
http://issues.apache.org/jira/browse/XERCESJ-1313
Adding support for construction of a Schema DOM from a StAXSource.
Still need to hook this up to the XSDHandler.
Added:
xerces/java/branches/xml-schema-1.1-dev/src/org/apache/xerces/impl/xs/traversers/StAXSchemaParser.java (with props)
Added: xerces/java/branches/xml-schema-1.1-dev/src/org/apache/xerces/impl/xs/traversers/StAXSchemaParser.java
URL: http://svn.apache.org/viewvc/xerces/java/branches/xml-schema-1.1-dev/src/org/apache/xerces/impl/xs/traversers/StAXSchemaParser.java?rev=684022&view=auto
==============================================================================
--- xerces/java/branches/xml-schema-1.1-dev/src/org/apache/xerces/impl/xs/traversers/StAXSchemaParser.java (added)
+++ xerces/java/branches/xml-schema-1.1-dev/src/org/apache/xerces/impl/xs/traversers/StAXSchemaParser.java Fri Aug 8 10:43:59 2008
@@ -0,0 +1,409 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file 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 org.apache.xerces.impl.xs.traversers;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+
+import javax.xml.stream.XMLEventReader;
+import javax.xml.stream.XMLStreamConstants;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamReader;
+import javax.xml.stream.events.Attribute;
+import javax.xml.stream.events.EndElement;
+import javax.xml.stream.events.Namespace;
+import javax.xml.stream.events.ProcessingInstruction;
+import javax.xml.stream.events.StartElement;
+import javax.xml.stream.events.XMLEvent;
+
+import org.apache.xerces.impl.xs.opti.SchemaDOMParser;
+import org.apache.xerces.util.JAXPNamespaceContextWrapper;
+import org.apache.xerces.util.StAXLocationWrapper;
+import org.apache.xerces.util.SymbolTable;
+import org.apache.xerces.util.XMLAttributesImpl;
+import org.apache.xerces.util.XMLStringBuffer;
+import org.apache.xerces.util.XMLSymbols;
+import org.apache.xerces.xni.NamespaceContext;
+import org.apache.xerces.xni.QName;
+import org.apache.xerces.xni.XMLString;
+import org.apache.xerces.xni.XNIException;
+import org.w3c.dom.Document;
+
+/**
+ * <p>StAXSchemaParser reads StAX events, converts them into XNI events
+ * and passes them directly to the SchemaDOMParser.</p>
+ *
+ * @xerces.internal
+ *
+ * @version $Id$
+ */
+final class StAXSchemaParser {
+
+ /** Chunk size (1024). */
+ private static final int CHUNK_SIZE = (1 << 10);
+
+ /** Chunk mask (CHUNK_SIZE - 1). */
+ private static final int CHUNK_MASK = CHUNK_SIZE - 1;
+
+ /** Array for holding character data. **/
+ private final char [] fCharBuffer = new char[CHUNK_SIZE];
+
+ /** Symbol table **/
+ private SymbolTable fSymbolTable;
+
+ /** SchemaDOMParser, events will be delegated to SchemaDOMParser to pass */
+ private SchemaDOMParser fSchemaDOMParser;
+
+ /** XML Locator wrapper for SAX. **/
+ private final StAXLocationWrapper fLocationWrapper = new StAXLocationWrapper();
+
+ /** The namespace context of this document: stores namespaces in scope */
+ private final JAXPNamespaceContextWrapper fNamespaceContext = new JAXPNamespaceContextWrapper(fSymbolTable);
+
+ /** Fields for start element, end element and characters. */
+ private final QName fElementQName = new QName();
+ private final QName fAttributeQName = new QName();
+ private final XMLAttributesImpl fAttributes = new XMLAttributesImpl();
+ private final XMLString fTempString = new XMLString();
+ private final ArrayList fDeclaredPrefixes = new ArrayList();
+ private final XMLStringBuffer fStringBuffer = new XMLStringBuffer();
+ private int fDepth;
+
+ public void reset(SchemaDOMParser schemaDOMParser, SymbolTable symbolTable) {
+ fSchemaDOMParser = schemaDOMParser;
+ fSymbolTable = symbolTable;
+ fNamespaceContext.setSymbolTable(fSymbolTable);
+ }
+
+ public Document getDocument() {
+ return fSchemaDOMParser.getDocument();
+ }
+
+ public void parse(XMLEventReader input) throws XMLStreamException, XNIException {
+ XMLEvent currentEvent = input.peek();
+ if (currentEvent != null) {
+ int eventType = currentEvent.getEventType();
+ if (eventType != XMLStreamConstants.START_DOCUMENT &&
+ eventType != XMLStreamConstants.START_ELEMENT) {
+ throw new XMLStreamException();
+ }
+ fSchemaDOMParser.startDocument(fLocationWrapper, null, fNamespaceContext, null);
+ loop: while (input.hasNext()) {
+ currentEvent = input.nextEvent();
+ eventType = currentEvent.getEventType();
+ switch (eventType) {
+ case XMLStreamConstants.START_ELEMENT:
+ ++fDepth;
+ StartElement start = currentEvent.asStartElement();
+ fillQName(fElementQName, start.getName());
+ fLocationWrapper.setLocation(start.getLocation());
+ fNamespaceContext.setNamespaceContext(start.getNamespaceContext());
+ fillXMLAttributes(start);
+ fillDeclaredPrefixes(start);
+ addNamespaceDeclarations();
+ fSchemaDOMParser.startElement(fElementQName, fAttributes, null);
+ break;
+ case XMLStreamConstants.END_ELEMENT:
+ EndElement end = currentEvent.asEndElement();
+ fillQName(fElementQName, end.getName());
+ fillDeclaredPrefixes(end);
+ fLocationWrapper.setLocation(end.getLocation());
+ fSchemaDOMParser.endElement(fElementQName, null);
+ --fDepth;
+ if (fDepth <= 0) {
+ break loop;
+ }
+ break;
+ case XMLStreamConstants.CHARACTERS:
+ sendCharactersToSchemaParser(currentEvent.asCharacters().getData(), false);
+ break;
+ case XMLStreamConstants.SPACE:
+ sendCharactersToSchemaParser(currentEvent.asCharacters().getData(), true);
+ break;
+ case XMLStreamConstants.CDATA:
+ fSchemaDOMParser.startCDATA(null);
+ sendCharactersToSchemaParser(currentEvent.asCharacters().getData(), false);
+ fSchemaDOMParser.endCDATA(null);
+ break;
+ case XMLStreamConstants.PROCESSING_INSTRUCTION:
+ ProcessingInstruction pi = (ProcessingInstruction)currentEvent;
+ fillProcessingInstruction(pi.getData());
+ fSchemaDOMParser.processingInstruction(pi.getTarget(), fTempString, null);
+ break;
+ case XMLStreamConstants.DTD:
+ /* There shouldn't be a DTD in the schema */
+ break;
+ case XMLStreamConstants.ENTITY_REFERENCE:
+ /* Not needed for schemas */
+ break;
+ case XMLStreamConstants.COMMENT:
+ /* No point in sending comments */
+ break;
+ case XMLStreamConstants.START_DOCUMENT:
+ fDepth++;
+ /* We automatically call startDocument before the loop */
+ break;
+ case XMLStreamConstants.END_DOCUMENT:
+ /* We automatically call endDocument after the loop */
+ break;
+ }
+ }
+ fLocationWrapper.setLocation(null);
+ fNamespaceContext.setNamespaceContext(null);
+ fSchemaDOMParser.endDocument(null);
+ }
+ }
+
+ public void parse(XMLStreamReader input) throws XMLStreamException, XNIException {
+ if (input.hasNext()) {
+ int eventType = input.getEventType();
+ if (eventType != XMLStreamConstants.START_DOCUMENT &&
+ eventType != XMLStreamConstants.START_ELEMENT) {
+ throw new XMLStreamException();
+ }
+ fSchemaDOMParser.startDocument(fLocationWrapper, null, fNamespaceContext, null);
+ boolean first = true;
+ loop: while (input.hasNext()) {
+ if (!first) {
+ eventType = input.next();
+ }
+ else {
+ first = false;
+ }
+ switch (eventType) {
+ case XMLStreamConstants.START_ELEMENT:
+ ++fDepth;
+ fLocationWrapper.setLocation(input.getLocation());
+ fNamespaceContext.setNamespaceContext(input.getNamespaceContext());
+ fillQName(fElementQName, input.getNamespaceURI(),
+ input.getLocalName(), input.getPrefix());
+ fillXMLAttributes(input);
+ fillDeclaredPrefixes(input);
+ addNamespaceDeclarations();
+ fSchemaDOMParser.startElement(fElementQName, fAttributes, null);
+ break;
+ case XMLStreamConstants.END_ELEMENT:
+ fLocationWrapper.setLocation(input.getLocation());
+ fNamespaceContext.setNamespaceContext(input.getNamespaceContext());
+ fillQName(fElementQName, input.getNamespaceURI(),
+ input.getLocalName(), input.getPrefix());
+ fillDeclaredPrefixes(input);
+ fSchemaDOMParser.endElement(fElementQName, null);
+ --fDepth;
+ if (fDepth <= 0) {
+ break loop;
+ }
+ break;
+ case XMLStreamConstants.CHARACTERS:
+ fTempString.setValues(input.getTextCharacters(),
+ input.getTextStart(), input.getTextLength());
+ fSchemaDOMParser.characters(fTempString, null);
+ break;
+ case XMLStreamConstants.SPACE:
+ fTempString.setValues(input.getTextCharacters(),
+ input.getTextStart(), input.getTextLength());
+ fSchemaDOMParser.ignorableWhitespace(fTempString, null);
+ break;
+ case XMLStreamConstants.CDATA:
+ fSchemaDOMParser.startCDATA(null);
+ fTempString.setValues(input.getTextCharacters(),
+ input.getTextStart(), input.getTextLength());
+ fSchemaDOMParser.characters(fTempString, null);
+ fSchemaDOMParser.endCDATA(null);
+ break;
+ case XMLStreamConstants.PROCESSING_INSTRUCTION:
+ fillProcessingInstruction(input.getPIData());
+ fSchemaDOMParser.processingInstruction(input.getPITarget(), fTempString, null);
+ break;
+ case XMLStreamConstants.DTD:
+ /* There shouldn't be a DTD in the schema */
+ break;
+ case XMLStreamConstants.ENTITY_REFERENCE:
+ /* Not needed for schemas */
+ break;
+ case XMLStreamConstants.COMMENT:
+ /* No point in sending comments */
+ break;
+ case XMLStreamConstants.START_DOCUMENT:
+ ++fDepth;
+ /* We automatically call startDocument before the loop */
+ break;
+ case XMLStreamConstants.END_DOCUMENT:
+ /* We automatically call endDocument after the loop */
+ break;
+ }
+ }
+ fLocationWrapper.setLocation(null);
+ fNamespaceContext.setNamespaceContext(null);
+ fSchemaDOMParser.endDocument(null);
+ }
+ }
+
+ /** Send characters to the validator in CHUNK_SIZE character chunks. */
+ private void sendCharactersToSchemaParser(String str, boolean whitespace) {
+ if (str != null) {
+ final int length = str.length();
+ final int remainder = length & CHUNK_MASK;
+ if (remainder > 0) {
+ str.getChars(0, remainder, fCharBuffer, 0);
+ fTempString.setValues(fCharBuffer, 0, remainder);
+ if (whitespace) {
+ fSchemaDOMParser.ignorableWhitespace(fTempString, null);
+ }
+ else {
+ fSchemaDOMParser.characters(fTempString, null);
+ }
+ }
+ int i = remainder;
+ while (i < length) {
+ str.getChars(i, i += CHUNK_SIZE, fCharBuffer, 0);
+ fTempString.setValues(fCharBuffer, 0, CHUNK_SIZE);
+ if (whitespace) {
+ fSchemaDOMParser.ignorableWhitespace(fTempString, null);
+ }
+ else {
+ fSchemaDOMParser.characters(fTempString, null);
+ }
+ }
+ }
+ }
+
+ // processing instructions must be sent all in one chunk
+ private void fillProcessingInstruction(String data) {
+ final int dataLength = data.length();
+ char [] charBuffer = fCharBuffer;
+ if (charBuffer.length < dataLength) {
+ // toCharArray() creates a newly allocated array, so it's okay
+ // to keep a reference to it.
+ charBuffer = data.toCharArray();
+ }
+ else {
+ data.getChars(0, dataLength, charBuffer, 0);
+ }
+ fTempString.setValues(charBuffer, 0, dataLength);
+ }
+
+ private void fillXMLAttributes(StartElement event) {
+ fAttributes.removeAllAttributes();
+ final Iterator attrs = event.getAttributes();
+ while (attrs.hasNext()) {
+ Attribute attr = (Attribute) attrs.next();
+ fillQName(fAttributeQName, attr.getName());
+ String type = attr.getDTDType();
+ int idx = fAttributes.getLength();
+ fAttributes.addAttributeNS(fAttributeQName,
+ (type != null) ? type : XMLSymbols.fCDATASymbol, attr.getValue());
+ fAttributes.setSpecified(idx, attr.isSpecified());
+ }
+ }
+
+ private void fillXMLAttributes(XMLStreamReader input) {
+ fAttributes.removeAllAttributes();
+ final int len = input.getAttributeCount();
+ for (int i = 0; i < len; ++i) {
+ fillQName(fAttributeQName, input.getAttributeNamespace(i),
+ input.getAttributeLocalName(i), input.getAttributePrefix(i));
+ String type = input.getAttributeType(i);
+ fAttributes.addAttributeNS(fAttributeQName,
+ (type != null) ? type : XMLSymbols.fCDATASymbol, input.getAttributeValue(i));
+ fAttributes.setSpecified(i, input.isAttributeSpecified(i));
+ }
+ }
+
+ private void addNamespaceDeclarations() {
+ String prefix = null;
+ String localpart = null;
+ String rawname = null;
+ String nsPrefix = null;
+ String nsURI = null;
+
+ final Iterator iter = fDeclaredPrefixes.iterator();
+ while (iter.hasNext()) {
+ nsPrefix = (String) iter.next();
+ nsURI = fNamespaceContext.getURI(nsPrefix);
+ if (nsPrefix.length() > 0) {
+ prefix = XMLSymbols.PREFIX_XMLNS;
+ localpart = nsPrefix;
+ fStringBuffer.clear();
+ fStringBuffer.append(prefix);
+ fStringBuffer.append(':');
+ fStringBuffer.append(localpart);
+ rawname = fSymbolTable.addSymbol(fStringBuffer.ch, fStringBuffer.offset, fStringBuffer.length);
+ }
+ else {
+ prefix = XMLSymbols.EMPTY_STRING;
+ localpart = XMLSymbols.PREFIX_XMLNS;
+ rawname = XMLSymbols.PREFIX_XMLNS;
+ }
+ fAttributeQName.setValues(prefix, localpart, rawname, NamespaceContext.XMLNS_URI);
+ fAttributes.addAttribute(fAttributeQName, XMLSymbols.fCDATASymbol, nsURI);
+ }
+ }
+
+ /** Fills in the list of declared prefixes. */
+ private void fillDeclaredPrefixes(StartElement event) {
+ fillDeclaredPrefixes(event.getNamespaces());
+ }
+
+ /** Fills in the list of declared prefixes. */
+ private void fillDeclaredPrefixes(EndElement event) {
+ fillDeclaredPrefixes(event.getNamespaces());
+ }
+
+ /** Fills in the list of declared prefixes. */
+ private void fillDeclaredPrefixes(Iterator namespaces) {
+ fDeclaredPrefixes.clear();
+ while (namespaces.hasNext()) {
+ Namespace ns = (Namespace) namespaces.next();
+ String prefix = ns.getPrefix();
+ fDeclaredPrefixes.add(prefix != null ? prefix : "");
+ }
+ }
+
+ /** Fills in the list of declared prefixes. */
+ private void fillDeclaredPrefixes(XMLStreamReader reader) {
+ fDeclaredPrefixes.clear();
+ final int len = reader.getNamespaceCount();
+ for (int i = 0; i < len; ++i) {
+ String prefix = reader.getNamespacePrefix(i);
+ fDeclaredPrefixes.add(prefix != null ? prefix : "");
+ }
+ }
+
+ /** Fills in a QName object. */
+ private void fillQName(QName toFill, javax.xml.namespace.QName toCopy) {
+ fillQName(toFill, toCopy.getNamespaceURI(), toCopy.getLocalPart(), toCopy.getPrefix());
+ }
+
+ /** Fills in a QName object. */
+ final void fillQName(QName toFill, String uri, String localpart, String prefix) {
+ uri = (uri != null && uri.length() > 0) ? fSymbolTable.addSymbol(uri) : null;
+ localpart = (localpart != null) ? fSymbolTable.addSymbol(localpart) : XMLSymbols.EMPTY_STRING;
+ prefix = (prefix != null && prefix.length() > 0) ? fSymbolTable.addSymbol(prefix) : XMLSymbols.EMPTY_STRING;
+ String raw = localpart;
+ if (prefix != XMLSymbols.EMPTY_STRING) {
+ fStringBuffer.clear();
+ fStringBuffer.append(prefix);
+ fStringBuffer.append(':');
+ fStringBuffer.append(localpart);
+ raw = fSymbolTable.addSymbol(fStringBuffer.ch, fStringBuffer.offset, fStringBuffer.length);
+ }
+ toFill.setValues(prefix, localpart, raw, uri);
+ }
+
+} // StAXSchemaParser
Propchange: xerces/java/branches/xml-schema-1.1-dev/src/org/apache/xerces/impl/xs/traversers/StAXSchemaParser.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: xerces/java/branches/xml-schema-1.1-dev/src/org/apache/xerces/impl/xs/traversers/StAXSchemaParser.java
------------------------------------------------------------------------------
svn:keywords = Author Date Id Revision
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@xerces.apache.org
For additional commands, e-mail: commits-help@xerces.apache.org