|
Hi, Frank.
Here's a patch on top of your check-in of the StAX
support for SDO under JIRA 118. Two fixes are included:
1) Implementation of XMLStreamHelper.save(...) and
saveObject()
2) Correct the positioning for the XMLStreamReader
returned from XMLStreamHelper.createXMLStreamReader(XMLDocument)
Please review and apply.
Thanks,
Raymond
|
Index: impl/src/main/java/org/apache/tuscany/sdo/helper/XMLStreamHelperImpl.java
===================================================================
--- impl/src/main/java/org/apache/tuscany/sdo/helper/XMLStreamHelperImpl.java
(revision 411287)
+++ impl/src/main/java/org/apache/tuscany/sdo/helper/XMLStreamHelperImpl.java
(working copy)
@@ -22,6 +22,8 @@
import javax.xml.stream.XMLStreamWriter;
import org.apache.tuscany.sdo.util.resource.DataObjectXMLStreamReader;
+import org.apache.tuscany.sdo.util.resource.XMLDocumentStreamReader;
+import org.apache.tuscany.sdo.util.resource.XMLStreamSerializer;
import org.eclipse.emf.ecore.resource.Resource;
import commonj.sdo.DataObject;
@@ -51,12 +53,16 @@
public void save(XMLDocument document, XMLStreamWriter writer) throws
XMLStreamException
{
- throw new UnsupportedOperationException();
+ XMLStreamReader reader = createXMLStreamReader(document);
+ new XMLStreamSerializer().serialize(reader, writer);
}
public XMLStreamReader createXMLStreamReader(XMLDocument document) throws
XMLStreamException
{
- throw new UnsupportedOperationException();
+ XMLStreamReader reader = new
DataObjectXMLStreamReader(document.getRootObject(),
document.getRootElementURI(), document.getRootElementName(), typeHelper);
+ // Wrap the reader so that its position will be START_ELEMENT
+ return new XMLDocumentStreamReader(reader);
+
}
public DataObject loadObject(XMLStreamReader reader) throws
XMLStreamException, IllegalStateException
@@ -69,7 +75,8 @@
public void saveObject(DataObject sdo, XMLStreamWriter writer) throws
XMLStreamException
{
- throw new UnsupportedOperationException();
+ XMLStreamReader reader = createXMLStreamReader(sdo);
+ new XMLStreamSerializer().serialize(reader, writer);
}
public XMLStreamReader createXMLStreamReader(DataObject dataObject)
Index:
impl/src/main/java/org/apache/tuscany/sdo/util/resource/XMLDocumentStreamReader.java
===================================================================
---
impl/src/main/java/org/apache/tuscany/sdo/util/resource/XMLDocumentStreamReader.java
(revision 0)
+++
impl/src/main/java/org/apache/tuscany/sdo/util/resource/XMLDocumentStreamReader.java
(revision 0)
@@ -0,0 +1,424 @@
+/**
+ *
+ */
+package org.apache.tuscany.sdo.util.resource;
+
+import javax.xml.namespace.NamespaceContext;
+import javax.xml.namespace.QName;
+import javax.xml.stream.Location;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamReader;
+
+public class XMLDocumentStreamReader implements XMLStreamReader {
+ private static final int STATE_SWITCHED = 0;
+ private static final int STATE_INIT = 1;
+ private static final int STATE_SWITCH_AT_NEXT = 2;
+ private static final int STATE_COMPLETE_AT_NEXT = 3;
+ private static final int STATE_COMPLETED = 4;
+ private XMLStreamReader realReader = null;
+ private int state = STATE_INIT;
+ private int prevState = state;
+
+
+ public XMLDocumentStreamReader(XMLStreamReader realReader) {
+ if (realReader == null) {
+ throw new UnsupportedOperationException("Reader cannot be null");
+ }
+
+ this.realReader = realReader;
+ }
+
+ public void close() throws XMLStreamException {
+ if (prevState != STATE_INIT) {
+ realReader.close();
+ } else {
+ throw new XMLStreamException();
+ }
+ }
+
+ public int next() throws XMLStreamException {
+ prevState = state;
+ int returnEvent = -1;
+
+ switch (state) {
+ case STATE_INIT:
+ if (realReader.getEventType() == START_DOCUMENT) {
+ state = STATE_SWITCHED;
+ returnEvent = realReader.getEventType();
+ } else {
+ state = STATE_SWITCH_AT_NEXT;
+ returnEvent = START_DOCUMENT;
+ }
+ break;
+ case STATE_SWITCHED:
+ returnEvent = realReader.next();
+ if (returnEvent == END_DOCUMENT) {
+ state = STATE_COMPLETED;
+ } else if (!realReader.hasNext()) {
+ state = STATE_COMPLETE_AT_NEXT;
+ }
+ break;
+ case STATE_SWITCH_AT_NEXT:
+ state = STATE_SWITCHED;
+ returnEvent = realReader.getEventType();
+ break;
+ case STATE_COMPLETE_AT_NEXT:
+ state = STATE_COMPLETED;
+ returnEvent = END_DOCUMENT;
+ break;
+ case STATE_COMPLETED:
+ //oops - no way we can go beyond this
+ throw new XMLStreamException("end reached!");
+ default:
+ throw new UnsupportedOperationException();
+ }
+
+ return returnEvent;
+ }
+
+ public int nextTag() throws XMLStreamException {
+ if (prevState != STATE_INIT) {
+ return realReader.nextTag();
+ } else {
+ throw new XMLStreamException();
+ }
+ }
+
+ public void require(int i, String s, String s1) throws XMLStreamException {
+ if (prevState != STATE_INIT) {
+ realReader.require(i, s, s1);
+ }
+ }
+
+ public boolean standaloneSet() {
+ if (prevState != STATE_INIT) {
+ return realReader.standaloneSet();
+ } else {
+ return false;
+ }
+ }
+
+ public int getAttributeCount() {
+ if (prevState != STATE_INIT) {
+ return realReader.getAttributeCount();
+ } else {
+ return 0;
+ }
+ }
+
+ public String getAttributeLocalName(int i) {
+ if (prevState != STATE_INIT) {
+ return realReader.getAttributeLocalName(i);
+ } else {
+ return null;
+ }
+ }
+
+ public QName getAttributeName(int i) {
+ if (prevState != STATE_INIT) {
+ return realReader.getAttributeName(i);
+ } else {
+ return null;
+ }
+ }
+
+ public String getAttributeNamespace(int i) {
+ if (prevState != STATE_INIT) {
+ return realReader.getAttributeNamespace(i);
+ } else {
+ return null;
+ }
+ }
+
+ public String getAttributePrefix(int i) {
+ if (prevState != STATE_INIT) {
+ return realReader.getAttributePrefix(i);
+ } else {
+ return null;
+ }
+ }
+
+ public String getAttributeType(int i) {
+ if (prevState != STATE_INIT) {
+ return realReader.getAttributeType(i);
+ } else {
+ return null;
+ }
+ }
+
+ public String getAttributeValue(int i) {
+ if (prevState != STATE_INIT) {
+ return realReader.getAttributeValue(i);
+ } else {
+ return null;
+ }
+ }
+
+ public String getAttributeValue(String s, String s1) {
+ if (prevState != STATE_INIT) {
+ return realReader.getAttributeValue(s, s1);
+ } else {
+ return null;
+ }
+ }
+
+ public String getCharacterEncodingScheme() {
+ if (prevState != STATE_INIT) {
+ return realReader.getCharacterEncodingScheme();
+ } else {
+ return null;
+ }
+ }
+
+ public String getElementText() throws XMLStreamException {
+ if (prevState != STATE_INIT) {
+ return realReader.getElementText();
+ } else {
+ throw new XMLStreamException();
+ }
+ }
+
+ public String getEncoding() {
+ if (prevState != STATE_INIT) {
+ return realReader.getEncoding();
+ } else {
+ return null;
+ }
+ }
+
+ public int getEventType() {
+ if (prevState == STATE_INIT) {
+ return START_DOCUMENT;
+ } else {
+ return realReader.getEventType();
+ }
+ }
+
+ public String getLocalName() {
+ if (prevState != STATE_INIT) {
+ return realReader.getLocalName();
+ } else {
+ return null;
+ }
+ }
+
+ public Location getLocation() {
+ if (prevState != STATE_INIT) {
+ return realReader.getLocation();
+ } else {
+ return null;
+ }
+ }
+
+ public QName getName() {
+ if (prevState != STATE_INIT) {
+ return realReader.getName();
+ } else {
+ return null;
+ }
+ }
+
+ public NamespaceContext getNamespaceContext() {
+ if (prevState != STATE_INIT) {
+ return realReader.getNamespaceContext();
+ } else {
+ return null;
+ }
+ }
+
+ public int getNamespaceCount() {
+ if (prevState != STATE_INIT) {
+ return realReader.getNamespaceCount();
+ } else {
+ return 0;
+ }
+ }
+
+ public String getNamespacePrefix(int i) {
+ if (prevState != STATE_INIT) {
+ return realReader.getNamespacePrefix(i);
+ } else {
+ return null;
+ }
+ }
+
+ public String getNamespaceURI() {
+ if (prevState != STATE_INIT) {
+ return realReader.getNamespaceURI();
+ } else {
+ return null;
+ }
+ }
+
+ public String getNamespaceURI(int i) {
+ if (prevState != STATE_INIT) {
+ return realReader.getNamespaceURI(i);
+ } else {
+ return null;
+ }
+ }
+
+ public String getNamespaceURI(String s) {
+ if (prevState != STATE_INIT) {
+ return realReader.getNamespaceURI(s);
+ } else {
+ return null;
+ }
+ }
+
+ public String getPIData() {
+ if (prevState != STATE_INIT) {
+ return realReader.getPIData();
+ } else {
+ return null;
+ }
+ }
+
+ public String getPITarget() {
+ if (prevState != STATE_INIT) {
+ return realReader.getPITarget();
+ } else {
+ return null;
+ }
+ }
+
+ public String getPrefix() {
+ if (prevState != STATE_INIT) {
+ return realReader.getPrefix();
+ } else {
+ return null;
+ }
+ }
+
+ public Object getProperty(String s) throws IllegalArgumentException {
+ if (prevState != STATE_INIT) {
+ return realReader.getProperty(s);
+ } else {
+ throw new IllegalArgumentException();
+ }
+ }
+
+ public String getText() {
+ if (prevState != STATE_INIT) {
+ return realReader.getText();
+ } else {
+ return null;
+ }
+ }
+
+ public char[] getTextCharacters() {
+ if (prevState != STATE_INIT) {
+ return realReader.getTextCharacters();
+ } else {
+ return new char[0];
+ }
+ }
+
+ public int getTextCharacters(int i, char[] chars, int i1, int i2) throws
XMLStreamException {
+ if (prevState != STATE_INIT) {
+ return realReader.getTextCharacters(i, chars, i1, i2);
+ } else {
+ return 0;
+ }
+ }
+
+ public int getTextLength() {
+ if (prevState != STATE_INIT) {
+ return realReader.getTextStart();
+ } else {
+ return 0;
+ }
+ }
+
+ public int getTextStart() {
+ if (prevState != STATE_INIT) {
+ return realReader.getTextStart();
+ } else {
+ return 0;
+ }
+ }
+
+ public String getVersion() {
+ if (prevState != STATE_INIT) {
+ return realReader.getVersion();
+ } else {
+ return null;
+ }
+ }
+
+ public boolean hasName() {
+ if (prevState != STATE_INIT) {
+ return realReader.hasName();
+ } else {
+ return false;
+ }
+ }
+
+ public boolean hasNext() throws XMLStreamException {
+ if (state == STATE_COMPLETE_AT_NEXT) {
+ return true;
+ } else if (state == STATE_COMPLETED) {
+ return false;
+ } else if (prevState != STATE_INIT) {
+ return realReader.hasNext();
+ } else {
+ return true;
+ }
+ }
+
+ public boolean hasText() {
+ if (prevState != STATE_INIT) {
+ return realReader.hasText();
+ } else {
+ return false;
+ }
+ }
+
+ public boolean isAttributeSpecified(int i) {
+ if (prevState != STATE_INIT) {
+ return realReader.isAttributeSpecified(i);
+ } else {
+ return false;
+ }
+ }
+
+ public boolean isCharacters() {
+ if (prevState != STATE_INIT) {
+ return realReader.isCharacters();
+ } else {
+ return false;
+ }
+ }
+
+ public boolean isEndElement() {
+ if (prevState != STATE_INIT) {
+ return realReader.isEndElement();
+ } else {
+ return false;
+ }
+ }
+
+ public boolean isStandalone() {
+ if (prevState != STATE_INIT) {
+ return realReader.isStandalone();
+ } else {
+ return false;
+ }
+ }
+
+ public boolean isStartElement() {
+ if (prevState != STATE_INIT) {
+ return realReader.isStartElement();
+ } else {
+ return false;
+ }
+ }
+
+ public boolean isWhiteSpace() {
+ if (prevState != STATE_INIT) {
+ return realReader.isWhiteSpace();
+ } else {
+ return false;
+ }
+ }
+}
\ No newline at end of file
Property changes on:
impl\src\main\java\org\apache\tuscany\sdo\util\resource\XMLDocumentStreamReader.java
___________________________________________________________________
Name: svn:keywords
+ Rev,Date
Name: svn:eol-style
+ native
Index:
impl/src/main/java/org/apache/tuscany/sdo/util/resource/XMLStreamSerializer.java
===================================================================
---
impl/src/main/java/org/apache/tuscany/sdo/util/resource/XMLStreamSerializer.java
(revision 0)
+++
impl/src/main/java/org/apache/tuscany/sdo/util/resource/XMLStreamSerializer.java
(revision 0)
@@ -0,0 +1,258 @@
+/*
+ * Copyright 2004,2005 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 org.apache.tuscany.sdo.util.resource;
+
+import javax.xml.namespace.NamespaceContext;
+import javax.xml.stream.XMLStreamConstants;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamReader;
+import javax.xml.stream.XMLStreamWriter;
+
+/**
+ * The XMLStreamSerializer pulls events from the XMLStreamReader and dumps
into the XMLStreamWriter
+ */
+public class XMLStreamSerializer implements XMLStreamConstants {
+
+ private static int namespaceSuffix = 0;
+
+ public static final String NAMESPACE_PREFIX = "ns";
+
+ /*
+ * The behavior of the serializer is such that it returns when it
encounters the starting element for the second time. The depth variable tracks
+ * the depth of the serilizer and tells it when to return. Note that it is
assumed that this serialization starts on an Element.
+ */
+
+ /**
+ * Field depth
+ */
+ private int depth = 0;
+
+ /**
+ * Method serialize.
+ *
+ * @param node
+ * @param writer
+ * @throws XMLStreamException
+ */
+ public void serialize(XMLStreamReader node, XMLStreamWriter writer) throws
XMLStreamException {
+ serializeNode(node, writer);
+ }
+
+ /**
+ * Method serializeNode.
+ *
+ * @param reader
+ * @param writer
+ * @throws XMLStreamException
+ */
+ protected void serializeNode(XMLStreamReader reader, XMLStreamWriter
writer) throws XMLStreamException {
+ // TODO We get the StAXWriter at this point and uses it hereafter
assuming that this is the only entry point to this class.
+ // If there can be other classes calling methodes of this we might
need to change methode signatures to OMOutputer
+ while (reader.hasNext()) {
+ int event = reader.next();
+ if (event == START_ELEMENT) {
+ serializeElement(reader, writer);
+ depth++;
+ } else if (event == ATTRIBUTE) {
+ serializeAttributes(reader, writer);
+ } else if (event == CHARACTERS) {
+ serializeText(reader, writer);
+ } else if (event == COMMENT) {
+ serializeComment(reader, writer);
+ } else if (event == CDATA) {
+ serializeCData(reader, writer);
+ } else if (event == END_ELEMENT) {
+ serializeEndElement(writer);
+ depth--;
+ } else if (event == START_DOCUMENT) {
+ depth++; // if a start document is found then increment the
depth
+ } else if (event == END_DOCUMENT) {
+ if (depth != 0)
+ depth--; // for the end document - reduce the depth
+ try {
+ serializeEndElement(writer);
+ } catch (Exception e) {
+ // TODO: log exceptions
+ }
+ }
+ if (depth == 0) {
+ break;
+ }
+ }
+ }
+
+ /**
+ * @param reader
+ * @param writer
+ * @throws XMLStreamException
+ */
+ protected void serializeElement(XMLStreamReader reader, XMLStreamWriter
writer) throws XMLStreamException {
+ String prefix = reader.getPrefix();
+ String nameSpaceName = reader.getNamespaceURI();
+ if (nameSpaceName != null) {
+ String writer_prefix = writer.getPrefix(nameSpaceName);
+ if (writer_prefix != null) {
+ writer.writeStartElement(nameSpaceName, reader.getLocalName());
+ } else {
+ if (prefix != null) {
+ writer.writeStartElement(prefix, reader.getLocalName(),
nameSpaceName);
+ writer.writeNamespace(prefix, nameSpaceName);
+ writer.setPrefix(prefix, nameSpaceName);
+ } else {
+ writer.writeStartElement(nameSpaceName,
reader.getLocalName());
+ writer.writeDefaultNamespace(nameSpaceName);
+ writer.setDefaultNamespace(nameSpaceName);
+ }
+ }
+ } else {
+ writer.writeStartElement(reader.getLocalName());
+ }
+
+ // add the namespaces
+ int count = reader.getNamespaceCount();
+ String namespacePrefix;
+ for (int i = 0; i < count; i++) {
+ namespacePrefix = reader.getNamespacePrefix(i);
+ if (namespacePrefix != null && namespacePrefix.length() == 0)
+ continue;
+
+ serializeNamespace(namespacePrefix, reader.getNamespaceURI(i),
writer);
+ }
+
+ // add attributes
+ serializeAttributes(reader, writer);
+
+ }
+
+ /**
+ * Method serializeEndElement.
+ *
+ * @param writer
+ * @throws XMLStreamException
+ */
+ protected void serializeEndElement(XMLStreamWriter writer) throws
XMLStreamException {
+ writer.writeEndElement();
+ }
+
+ /**
+ * @param reader
+ * @param writer
+ * @throws XMLStreamException
+ */
+ protected void serializeText(XMLStreamReader reader, XMLStreamWriter
writer) throws XMLStreamException {
+ writer.writeCharacters(reader.getText());
+ }
+
+ /**
+ * Method serializeCData.
+ *
+ * @param reader
+ * @param writer
+ * @throws XMLStreamException
+ */
+ protected void serializeCData(XMLStreamReader reader, XMLStreamWriter
writer) throws XMLStreamException {
+ writer.writeCData(reader.getText());
+ }
+
+ /**
+ * Method serializeComment.
+ *
+ * @param reader
+ * @param writer
+ * @throws XMLStreamException
+ */
+ protected void serializeComment(XMLStreamReader reader, XMLStreamWriter
writer) throws XMLStreamException {
+ writer.writeComment(reader.getText());
+ }
+
+ /**
+ * @param reader
+ * @param writer
+ * @throws XMLStreamException
+ */
+ protected void serializeAttributes(XMLStreamReader reader, XMLStreamWriter
writer) throws XMLStreamException {
+ int count = reader.getAttributeCount();
+ String prefix = null;
+ String namespaceName = null;
+ String writerPrefix = null;
+ for (int i = 0; i < count; i++) {
+ prefix = reader.getAttributePrefix(i);
+ namespaceName = reader.getAttributeNamespace(i);
+ if (namespaceName != null)
+ writerPrefix =
writer.getNamespaceContext().getPrefix(namespaceName);
+
+ if (!"".equals(namespaceName)) {
+ // prefix has already being declared but this particular
attrib has a
+ // no prefix attached. So use the prefix provided by the writer
+ if (writerPrefix != null && (prefix == null ||
prefix.equals(""))) {
+ writer.writeAttribute(writerPrefix, namespaceName,
reader.getAttributeLocalName(i), reader.getAttributeValue(i));
+
+ // writer prefix is available but different from the
current
+ // prefix of the attrib. We should be decalring the new
prefix
+ // as a namespace declaration
+ } else if (prefix != null && !"".equals(prefix) &&
!prefix.equals(writerPrefix)) {
+ writer.writeNamespace(prefix, namespaceName);
+ writer.writeAttribute(prefix, namespaceName,
reader.getAttributeLocalName(i), reader.getAttributeValue(i));
+
+ // prefix is null (or empty), but the namespace name is
valid! it has not
+ // being written previously also. So we need to generate a
prefix
+ // here
+ } else {
+ prefix =
generateUniquePrefix(writer.getNamespaceContext());
+ writer.writeNamespace(prefix, namespaceName);
+ writer.writeAttribute(prefix, namespaceName,
reader.getAttributeLocalName(i), reader.getAttributeValue(i));
+ }
+ } else {
+ // empty namespace is equal to no namespace!
+ writer.writeAttribute(reader.getAttributeLocalName(i),
reader.getAttributeValue(i));
+ }
+
+ }
+ }
+
+ /**
+ * Generates a unique namespace prefix that is not in the scope of the
NamespaceContext
+ *
+ * @param nsCtxt
+ * @return string
+ */
+ private String generateUniquePrefix(NamespaceContext nsCtxt) {
+ String prefix = NAMESPACE_PREFIX + namespaceSuffix++;
+ // null should be returned if the prefix is not bound!
+ while (nsCtxt.getNamespaceURI(prefix) != null) {
+ prefix = NAMESPACE_PREFIX + namespaceSuffix++;
+ }
+
+ return prefix;
+ }
+
+ /**
+ * Method serializeNamespace.
+ *
+ * @param prefix
+ * @param URI
+ * @param writer
+ * @throws XMLStreamException
+ */
+ private void serializeNamespace(String prefix, String URI, XMLStreamWriter
writer) throws XMLStreamException {
+ String prefix1 = writer.getPrefix(URI);
+ if (prefix1 == null) {
+ writer.writeNamespace(prefix, URI);
+ writer.setPrefix(prefix, URI);
+ }
+ }
+}
Property changes on:
impl\src\main\java\org\apache\tuscany\sdo\util\resource\XMLStreamSerializer.java
___________________________________________________________________
Name: svn:keywords
+ Rev,Date
Name: svn:eol-style
+ native
--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
