summaryrefslogtreecommitdiffstats
path: root/sca-java-1.x/branches/sca-java-1.6.2/modules/databinding/src/main/java/org/apache/tuscany/sca/databinding/xml/XMLStreamSerializer.java
diff options
context:
space:
mode:
Diffstat (limited to 'sca-java-1.x/branches/sca-java-1.6.2/modules/databinding/src/main/java/org/apache/tuscany/sca/databinding/xml/XMLStreamSerializer.java')
-rw-r--r--sca-java-1.x/branches/sca-java-1.6.2/modules/databinding/src/main/java/org/apache/tuscany/sca/databinding/xml/XMLStreamSerializer.java287
1 files changed, 287 insertions, 0 deletions
diff --git a/sca-java-1.x/branches/sca-java-1.6.2/modules/databinding/src/main/java/org/apache/tuscany/sca/databinding/xml/XMLStreamSerializer.java b/sca-java-1.x/branches/sca-java-1.6.2/modules/databinding/src/main/java/org/apache/tuscany/sca/databinding/xml/XMLStreamSerializer.java
new file mode 100644
index 0000000000..920ebb511c
--- /dev/null
+++ b/sca-java-1.x/branches/sca-java-1.6.2/modules/databinding/src/main/java/org/apache/tuscany/sca/databinding/xml/XMLStreamSerializer.java
@@ -0,0 +1,287 @@
+/*
+ * 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.tuscany.sca.databinding.xml;
+
+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
+ *
+ * @version $Rev$ $Date$
+ */
+public class XMLStreamSerializer implements XMLStreamConstants {
+ public static final String NAMESPACE_PREFIX = "ns";
+ private static int namespaceSuffix;
+
+ /*
+ * 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 Serializer and tells it when to return. Note that it is assumed
+ * that this Serialization starts on an Element.
+ */
+
+ /**
+ * Field depth
+ */
+ private int depth;
+
+ /**
+ * 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 serialize.
+ *
+ * @param node
+ * @param writer
+ * @throws XMLStreamException
+ */
+ public void serialize(XMLStreamReader node, XMLStreamWriter writer) throws XMLStreamException {
+ serializeNode(node, writer);
+ }
+
+ /**
+ * @param reader
+ * @param writer
+ * @throws XMLStreamException
+ */
+ protected void serializeAttributes(XMLStreamReader reader, XMLStreamWriter writer) throws XMLStreamException {
+ int count = reader.getAttributeCount();
+ String prefix;
+ String namespaceName;
+ String writerPrefix;
+ for (int i = 0; i < count; i++) {
+ prefix = reader.getAttributePrefix(i);
+ namespaceName = reader.getAttributeNamespace(i);
+ /*
+ * Due to parser implementations returning null as the namespace URI (for the empty namespace) we need to
+ * make sure that we deal with a namespace name that is not null. The best way to work around this issue is
+ * to set the namespace URI to "" if it is null
+ */
+ if (namespaceName == null) {
+ namespaceName = "";
+ }
+
+ writerPrefix = writer.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 declaring 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 if (prefix == null || prefix.equals("")) {
+ prefix = generateUniquePrefix(writer.getNamespaceContext());
+ writer.writeNamespace(prefix, namespaceName);
+ writer.writeAttribute(prefix, namespaceName, reader.getAttributeLocalName(i), reader
+ .getAttributeValue(i));
+ } else {
+ 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));
+ }
+
+ }
+ }
+
+ /**
+ * 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 serializeElement(XMLStreamReader reader, XMLStreamWriter writer) throws XMLStreamException {
+ String prefix = reader.getPrefix();
+ String nameSpaceName = reader.getNamespaceURI();
+ if (nameSpaceName != null) {
+ String writerPrefix = writer.getPrefix(nameSpaceName);
+ if (writerPrefix != 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 {
+ // [rfeng] We need to set default NS 1st before calling writeStateElement
+ writer.setDefaultNamespace(nameSpaceName);
+ writer.writeStartElement(nameSpaceName, reader.getLocalName());
+ writer.writeDefaultNamespace(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);
+ // [rfeng] The following is commented out to allow to default ns
+ // 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();
+ }
+
+ /**
+ * 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);
+ }
+ }
+
+ /**
+ * Method serializeNode.
+ *
+ * @param reader
+ * @param writer
+ * @throws XMLStreamException
+ */
+ protected void serializeNode(XMLStreamReader reader, XMLStreamWriter writer) throws XMLStreamException {
+ while (true) {
+ int event = reader.getEventType();
+ 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
+ writer.writeStartDocument();
+ // the depth
+ } else if (event == END_DOCUMENT) {
+ if (depth != 0) {
+ depth--; // for the end document - reduce the depth
+ }
+ writer.writeEndDocument();
+ }
+ if (depth == 0) {
+ break;
+ }
+ if (reader.hasNext()) {
+ reader.next();
+ } else {
+ break;
+ }
+ }
+ }
+
+ /**
+ * @param reader
+ * @param writer
+ * @throws XMLStreamException
+ */
+ protected void serializeText(XMLStreamReader reader, XMLStreamWriter writer) throws XMLStreamException {
+ writer.writeCharacters(reader.getText());
+ }
+}