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]