summaryrefslogtreecommitdiffstats
path: root/branches/sca-java-M2/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml
diff options
context:
space:
mode:
Diffstat (limited to 'branches/sca-java-M2/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml')
-rw-r--r--branches/sca-java-M2/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/DOMDataBinding.java42
-rw-r--r--branches/sca-java-M2/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/DOMWrapperHandler.java79
-rw-r--r--branches/sca-java-M2/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/DOMXMLStreamReader.java1410
-rw-r--r--branches/sca-java-M2/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/InputSource2Node.java65
-rw-r--r--branches/sca-java-M2/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/InputSource2SAX.java63
-rw-r--r--branches/sca-java-M2/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/InputStream2Node.java67
-rw-r--r--branches/sca-java-M2/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/InputStream2SAX.java62
-rw-r--r--branches/sca-java-M2/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/Node2Object.java49
-rw-r--r--branches/sca-java-M2/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/Node2OutputStream.java66
-rwxr-xr-xbranches/sca-java-M2/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/Node2String.java59
-rw-r--r--branches/sca-java-M2/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/Node2Writer.java65
-rw-r--r--branches/sca-java-M2/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/Node2XMLStreamReader.java60
-rw-r--r--branches/sca-java-M2/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/Object2Node.java62
-rw-r--r--branches/sca-java-M2/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/Reader2Node.java65
-rw-r--r--branches/sca-java-M2/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/Reader2SAX.java58
-rw-r--r--branches/sca-java-M2/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/SAX2DOM.java244
-rw-r--r--branches/sca-java-M2/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/SAX2DOMPipe.java67
-rwxr-xr-xbranches/sca-java-M2/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/Source2ResultTransformer.java60
-rw-r--r--branches/sca-java-M2/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/StAX2SAXAdapter.java256
-rwxr-xr-xbranches/sca-java-M2/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/StAXHelper.java820
-rwxr-xr-xbranches/sca-java-M2/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/StreamDataPipe.java57
-rwxr-xr-xbranches/sca-java-M2/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/String2Node.java60
-rw-r--r--branches/sca-java-M2/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/String2SAX.java59
-rwxr-xr-xbranches/sca-java-M2/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/String2XMLStreamReader.java55
-rwxr-xr-xbranches/sca-java-M2/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/Writer2ReaderDataPipe.java56
-rw-r--r--branches/sca-java-M2/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/XMLStreamReader2Node.java62
-rw-r--r--branches/sca-java-M2/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/XMLStreamReader2SAX.java73
-rwxr-xr-xbranches/sca-java-M2/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/XMLStreamReader2String.java55
-rw-r--r--branches/sca-java-M2/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/XMLStringDataBinding.java33
29 files changed, 4229 insertions, 0 deletions
diff --git a/branches/sca-java-M2/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/DOMDataBinding.java b/branches/sca-java-M2/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/DOMDataBinding.java
new file mode 100644
index 0000000000..9fc1cc5152
--- /dev/null
+++ b/branches/sca-java-M2/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/DOMDataBinding.java
@@ -0,0 +1,42 @@
+/*
+ * 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.core.databinding.xml;
+
+
+import org.apache.tuscany.spi.databinding.WrapperHandler;
+import org.apache.tuscany.spi.databinding.extension.DataBindingExtension;
+import org.w3c.dom.Node;
+
+/**
+ * DOM DataBinding
+ */
+public class DOMDataBinding extends DataBindingExtension {
+ public static final String NAME = Node.class.getName();
+
+ public DOMDataBinding() {
+ super(Node.class);
+ }
+
+ @Override
+ public WrapperHandler getWrapperHandler() {
+ return new DOMWrapperHandler();
+ }
+
+}
diff --git a/branches/sca-java-M2/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/DOMWrapperHandler.java b/branches/sca-java-M2/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/DOMWrapperHandler.java
new file mode 100644
index 0000000000..0373ebcdfe
--- /dev/null
+++ b/branches/sca-java-M2/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/DOMWrapperHandler.java
@@ -0,0 +1,79 @@
+/*
+ * 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.core.databinding.xml;
+
+import javax.xml.namespace.QName;
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.apache.tuscany.spi.databinding.TransformationContext;
+import org.apache.tuscany.spi.databinding.TransformationException;
+import org.apache.tuscany.spi.databinding.WrapperHandler;
+import org.apache.tuscany.spi.databinding.extension.DOMHelper;
+import org.apache.tuscany.spi.idl.ElementInfo;
+import org.w3c.dom.Document;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+public class DOMWrapperHandler implements WrapperHandler<Node> {
+
+ private Document document;
+
+ public DOMWrapperHandler() {
+ super();
+ try {
+ this.document = DOMHelper.newDocument();
+ } catch (ParserConfigurationException e) {
+ throw new TransformationException(e);
+ }
+ }
+
+ public Node create(ElementInfo element, TransformationContext context) {
+ QName name = element.getQName();
+ return DOMHelper.createElement(document, name);
+ }
+
+ public Object getChild(Node wrapper, int i, ElementInfo element) {
+ int index = 0;
+ NodeList nodes = wrapper.getChildNodes();
+ for (int j = 0; j < nodes.getLength(); j++) {
+ Node node = nodes.item(j);
+ if (node.getNodeType() != Node.ELEMENT_NODE) {
+ continue;
+ }
+ if (index != i) {
+ index++;
+ } else {
+ QName name = DOMHelper.getQName(node);
+ if (name.equals(element.getQName())) {
+ return node;
+ }
+ }
+ }
+ return null;
+ }
+
+ public void setChild(Node wrapper, int i, ElementInfo childElement, Object value) {
+ Node node = (Node) value;
+ if (node.getNodeType() == Node.DOCUMENT_NODE) {
+ node = ((Document) node).getDocumentElement();
+ }
+ wrapper.appendChild(wrapper.getOwnerDocument().importNode(node, true));
+ }
+} \ No newline at end of file
diff --git a/branches/sca-java-M2/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/DOMXMLStreamReader.java b/branches/sca-java-M2/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/DOMXMLStreamReader.java
new file mode 100644
index 0000000000..5a12cc72cb
--- /dev/null
+++ b/branches/sca-java-M2/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/DOMXMLStreamReader.java
@@ -0,0 +1,1410 @@
+/*
+ * 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.core.databinding.xml;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import javax.xml.XMLConstants;
+import javax.xml.namespace.NamespaceContext;
+import javax.xml.namespace.QName;
+import javax.xml.stream.Location;
+import javax.xml.stream.XMLStreamException;
+
+import org.w3c.dom.Attr;
+import org.w3c.dom.CharacterData;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+import org.apache.tuscany.core.databinding.xml.StAXHelper.XMLFragmentStreamReader;
+
+public class DOMXMLStreamReader implements XMLFragmentStreamReader {
+ protected static class DelegatingNamespaceContext implements NamespaceContext {
+ private int counter;
+
+ private NamespaceContext parent;
+
+ private Map<String, String> prefixToNamespaceMapping = new HashMap<String, String>();
+
+ public DelegatingNamespaceContext(NamespaceContext parent) {
+ super();
+ this.parent = parent;
+
+ prefixToNamespaceMapping.put("xml", "http://www.w3.org/XML/1998/namespace");
+ prefixToNamespaceMapping.put("xmlns", "http://www.w3.org/2000/xmlns/");
+ prefixToNamespaceMapping.put("xsi", "http://www.w3.org/2001/XMLSchema-instance");
+ }
+
+ public synchronized QName createQName(String nsURI, String name) {
+ String prefix = nsURI != null ? (String) getPrefix(nsURI) : null;
+ if (prefix == null && nsURI != null && !nsURI.equals("")) {
+ prefix = "p" + (counter++);
+ }
+ if (prefix == null) {
+ prefix = "";
+ }
+ if (nsURI != null) {
+ prefixToNamespaceMapping.put(prefix, nsURI);
+ }
+ return new QName(nsURI, name, prefix);
+ }
+
+ public String getNamespaceURI(String prefix) {
+ if (prefix == null) {
+ throw new IllegalArgumentException("Prefix is null");
+ }
+
+ String ns = (String) prefixToNamespaceMapping.get(prefix);
+ if (ns != null) {
+ return ns;
+ } else if (parent != null) {
+ return parent.getNamespaceURI(prefix);
+ } else {
+ return null;
+ }
+ }
+
+ public String getPrefix(String nsURI) {
+ if (nsURI == null) {
+ throw new IllegalArgumentException("Namespace is null");
+ }
+ for (Map.Entry<String, String> entry1 : prefixToNamespaceMapping.entrySet()) {
+ Map.Entry entry = entry1;
+ if (entry.getValue().equals(nsURI)) {
+ return (String) entry.getKey();
+ }
+ }
+ if (parent != null) {
+ return parent.getPrefix(nsURI);
+ } else {
+ return null;
+ }
+ }
+
+ public Iterator getPrefixes(String nsURI) {
+ List<String> prefixList = new ArrayList<String>();
+ for (Map.Entry<String, String> entry : prefixToNamespaceMapping.entrySet()) {
+ if (entry.getValue().equals(nsURI)) {
+ prefixList.add(entry.getKey());
+ }
+ }
+ if (parent != null) {
+ for (Iterator i = parent.getPrefixes(nsURI); i.hasNext();) {
+ prefixList.add((String) i.next());
+ }
+ }
+ return prefixList.iterator();
+ }
+
+ public void registerMapping(String prefix, String nsURI) {
+ prefixToNamespaceMapping.put(prefix, nsURI);
+ }
+
+ public void removeMapping(String prefix) {
+ prefixToNamespaceMapping.remove(prefix);
+ }
+
+ public void setParent(NamespaceContext parent) {
+ this.parent = parent;
+ }
+ }
+
+ protected static class NameValuePair implements Map.Entry {
+ private Object key;
+
+ private Object value;
+
+ public NameValuePair(Object key, Object value) {
+ this.key = key;
+ this.value = value;
+ }
+
+ public Object getKey() {
+ return key;
+ }
+
+ public Object getValue() {
+ return value;
+ }
+
+ public Object setValue(Object value) {
+ Object v = this.value;
+ this.value = value;
+ return v;
+ }
+
+ }
+
+ protected static class SimpleElementStreamReader implements XMLFragmentStreamReader {
+
+ private static final int END_ELEMENT_STATE = 2;
+
+ private static final int START_ELEMENT_STATE = 0;
+
+ private static final int START_ELEMENT_STATE_WITH_NULL = 3;
+
+ private static final int TEXT_STATE = 1;
+
+ private static final QName XSI_NIL_QNAME =
+ new QName("http://www.w3.org/2001/XMLSchema-instance", "nil", "xsi");
+
+ private QName name;
+
+ private DelegatingNamespaceContext namespaceContext = new DelegatingNamespaceContext(null);
+
+ private int state = START_ELEMENT_STATE;
+
+ private String value;
+
+ public SimpleElementStreamReader(QName name, String value) {
+ this.name = name;
+ this.value = value;
+ if (value == null) {
+ state = START_ELEMENT_STATE_WITH_NULL;
+ }
+ }
+
+ public void close() throws XMLStreamException {
+ // Do nothing - we've nothing to free here
+ }
+
+ public int getAttributeCount() {
+ if (state == START_ELEMENT_STATE_WITH_NULL) {
+ return 1;
+ }
+ if (state == START_ELEMENT_STATE) {
+ return 0;
+ } else {
+ throw new IllegalStateException();
+ }
+
+ }
+
+ public String getAttributeLocalName(int i) {
+ if (state == START_ELEMENT_STATE_WITH_NULL && i == 0) {
+ return XSI_NIL_QNAME.getLocalPart();
+ }
+ if (state == START_ELEMENT_STATE) {
+ return null;
+ } else {
+ throw new IllegalStateException();
+ }
+ }
+
+ public QName getAttributeName(int i) {
+ if (state == START_ELEMENT_STATE_WITH_NULL && i == 0) {
+ return XSI_NIL_QNAME;
+ }
+ if (state == START_ELEMENT_STATE) {
+ return null;
+ } else {
+ throw new IllegalStateException();
+ }
+ }
+
+ public String getAttributeNamespace(int i) {
+ if (state == START_ELEMENT_STATE_WITH_NULL && i == 0) {
+ return XSI_NIL_QNAME.getNamespaceURI();
+ }
+ if (state == START_ELEMENT_STATE) {
+ return null;
+ } else {
+ throw new IllegalStateException();
+ }
+ }
+
+ public String getAttributePrefix(int i) {
+ if (state == START_ELEMENT_STATE_WITH_NULL && i == 0) {
+ return XSI_NIL_QNAME.getPrefix();
+ }
+ if (state == START_ELEMENT_STATE) {
+ return null;
+ } else {
+ throw new IllegalStateException();
+ }
+ }
+
+ public String getAttributeType(int i) {
+ return null; // not implemented
+ }
+
+ public String getAttributeValue(int i) {
+ if (state == START_ELEMENT_STATE_WITH_NULL && i == 0) {
+ return "true";
+ }
+ if (state == START_ELEMENT_STATE) {
+ return null;
+ } else {
+ throw new IllegalStateException();
+ }
+ }
+
+ public String getAttributeValue(String string, String string1) {
+ if (state == TEXT_STATE) {
+ // todo something
+ return null;
+ } else {
+ return null;
+ }
+
+ }
+
+ public String getCharacterEncodingScheme() {
+ return null;
+ }
+
+ public String getElementText() throws XMLStreamException {
+ if (state == START_ELEMENT) {
+ // move to the end state and return the value
+ state = END_ELEMENT_STATE;
+ return value;
+ } else {
+ throw new XMLStreamException();
+ }
+
+ }
+
+ public String getEncoding() {
+ return "UTF-8";
+ }
+
+ public int getEventType() {
+ switch (state) {
+ case START_ELEMENT_STATE:
+ case START_ELEMENT_STATE_WITH_NULL:
+ return START_ELEMENT;
+ case END_ELEMENT_STATE:
+ return END_ELEMENT;
+ case TEXT_STATE:
+ return CHARACTERS;
+ default:
+ throw new UnsupportedOperationException();
+ // we've no idea what this is!!!!!
+ }
+
+ }
+
+ public String getLocalName() {
+ if (state != TEXT_STATE) {
+ return name.getLocalPart();
+ } else {
+ return null;
+ }
+ }
+
+ public Location getLocation() {
+ return new Location() {
+ public int getCharacterOffset() {
+ return 0;
+ }
+
+ public int getColumnNumber() {
+ return 0;
+ }
+
+ public int getLineNumber() {
+ return 0;
+ }
+
+ public String getPublicId() {
+ return null;
+ }
+
+ public String getSystemId() {
+ return null;
+ }
+ };
+ }
+
+ public QName getName() {
+ if (state != TEXT_STATE) {
+ return name;
+ } else {
+ return null;
+ }
+ }
+
+ public NamespaceContext getNamespaceContext() {
+ return this.namespaceContext;
+ }
+
+ public int getNamespaceCount() {
+ if (state == START_ELEMENT_STATE_WITH_NULL && isXsiNamespacePresent()) {
+ return 1;
+ } else {
+ return 0;
+ }
+
+ }
+
+ public String getNamespacePrefix(int i) {
+ if (state == START_ELEMENT_STATE_WITH_NULL && isXsiNamespacePresent() && i == 0) {
+ return XSI_NIL_QNAME.getPrefix();
+ } else {
+ return null;
+ }
+ }
+
+ public String getNamespaceURI() {
+ if (state != TEXT_STATE) {
+ return name.getNamespaceURI();
+ } else {
+ return null;
+ }
+
+ }
+
+ public String getNamespaceURI(int i) {
+ if (state == START_ELEMENT_STATE_WITH_NULL && isXsiNamespacePresent() && i == 0) {
+ return XSI_NIL_QNAME.getNamespaceURI();
+ } else {
+ return null;
+ }
+ }
+
+ public String getNamespaceURI(String prefix) {
+ return namespaceContext.getNamespaceURI(prefix);
+ }
+
+ public String getPIData() {
+ return null;
+ }
+
+ public String getPITarget() {
+ return null;
+ }
+
+ public String getPrefix() {
+ if (state != TEXT_STATE) {
+ return name.getPrefix();
+ } else {
+ return null;
+ }
+ }
+
+ public Object getProperty(String key) throws IllegalArgumentException {
+ return null;
+ }
+
+ public String getText() {
+ if (state == TEXT_STATE) {
+ return value;
+ } else {
+ throw new IllegalStateException();
+ }
+ }
+
+ public char[] getTextCharacters() {
+ if (state == TEXT_STATE) {
+ return value.toCharArray();
+ } else {
+ throw new IllegalStateException();
+ }
+ }
+
+ public int getTextCharacters(int i, char[] chars, int i1, int i2) throws XMLStreamException {
+ // not implemented
+ throw new UnsupportedOperationException();
+ }
+
+ public int getTextLength() {
+ if (state == TEXT_STATE) {
+ return value.length();
+ } else {
+ throw new IllegalStateException();
+ }
+
+ }
+
+ public int getTextStart() {
+ if (state == TEXT_STATE) {
+ return 0;
+ } else {
+ throw new IllegalStateException();
+ }
+ }
+
+ public String getVersion() {
+ return null; // todo 1.0 ?
+ }
+
+ public boolean hasName() {
+ return state != TEXT_STATE;
+
+ }
+
+ public boolean hasNext() throws XMLStreamException {
+ return state != END_ELEMENT_STATE;
+ }
+
+ public boolean hasText() {
+ return state == TEXT_STATE;
+ }
+
+ public void init() {
+ // just add the current elements namespace and prefix to the this
+ // elements nscontext
+ registerNamespace(name.getPrefix(), name.getNamespaceURI());
+
+ }
+
+ public boolean isAttributeSpecified(int i) {
+ return false; // no attribs here
+ }
+
+ public boolean isCharacters() {
+ return state == TEXT_STATE;
+ }
+
+ public boolean isEndElement() {
+ return state == END_ELEMENT_STATE;
+ }
+
+ public boolean isEndOfFragment() {
+ return state == END_ELEMENT_STATE;
+ }
+
+ public boolean isStandalone() {
+ return false;
+ }
+
+ public boolean isStartElement() {
+ return state == START_ELEMENT_STATE || state == START_ELEMENT_STATE_WITH_NULL;
+ }
+
+ public boolean isWhiteSpace() {
+ return false; // no whitespaces here
+ }
+
+ /**
+ * Test whether the xsi namespace is present
+ *
+ * @return
+ */
+ private boolean isXsiNamespacePresent() {
+ return namespaceContext.getNamespaceURI(XSI_NIL_QNAME.getPrefix()) != null;
+ }
+
+ public int next() throws XMLStreamException {
+ switch (state) {
+ case START_ELEMENT_STATE:
+ state = TEXT_STATE;
+ return CHARACTERS;
+ case START_ELEMENT_STATE_WITH_NULL:
+ state = END_ELEMENT_STATE;
+ return END_ELEMENT;
+ case END_ELEMENT_STATE:
+ // oops, not supposed to happen!
+ throw new XMLStreamException("end already reached!");
+ case TEXT_STATE:
+ state = END_ELEMENT_STATE;
+ return END_ELEMENT;
+ default:
+ throw new XMLStreamException("unknown event type!");
+ }
+ }
+
+ public int nextTag() throws XMLStreamException {
+ return 0; // todo
+ }
+
+ /**
+ * @param prefix
+ * @param uri
+ */
+ private void registerNamespace(String prefix, String uri) {
+ // todo - need to fix this up to cater for cases where
+ // namespaces are having no prefixes
+ if (!uri.equals(namespaceContext.getNamespaceURI(prefix))) {
+ // this namespace is not there. Need to declare it
+ namespaceContext.registerMapping(prefix, uri);
+ }
+ }
+
+ public void require(int i, String string, String string1) throws XMLStreamException {
+ // not implemented
+ }
+
+ public void setParentNamespaceContext(NamespaceContext nsContext) {
+ this.namespaceContext.setParent(nsContext);
+ }
+
+ public boolean standaloneSet() {
+ return false;
+ }
+
+ }
+
+ private static final int DELEGATED_STATE = 2;
+
+ private static final int END_ELEMENT_STATE = 1;
+
+ // states for this pullparser - it can only have three states
+ private static final int START_ELEMENT_STATE = 0;
+
+ private static final int TEXT_STATE = 3;
+
+ private Map.Entry[] attributes;
+
+ // reference to the child reader
+ private XMLFragmentStreamReader childReader;
+
+ // current property index
+ private int currentPropertyIndex;
+
+ private Map<String, String> declaredNamespaceMap = new HashMap<String, String>();
+
+ private QName elementQName;
+
+ // we always create a new namespace context
+ private DelegatingNamespaceContext namespaceContext = new DelegatingNamespaceContext(null);
+
+ private Map.Entry[] properties;
+
+ private Element rootElement;
+
+ private String rootElementName;
+
+ private String rootElementURI;
+
+ // integer field that keeps the state of this
+ // parser.
+ private int state = START_ELEMENT_STATE;
+
+ public DOMXMLStreamReader(Node node) {
+ switch (node.getNodeType()) {
+ case Node.DOCUMENT_NODE:
+ this.rootElement = ((Document) node).getDocumentElement();
+ break;
+ case Node.ELEMENT_NODE:
+ this.rootElement = (Element) node;
+ break;
+ default:
+ throw new IllegalArgumentException("Illegal Node");
+ }
+ this.rootElementName = rootElement.getLocalName();
+ this.rootElementURI = rootElement.getNamespaceURI();
+
+ declaredNamespaceMap.put("xml", "http://www.w3.org/XML/1998/namespace");
+ declaredNamespaceMap.put("xmlns", "http://www.w3.org/2000/xmlns/");
+ declaredNamespaceMap.put("xsi", "http://www.w3.org/2001/XMLSchema-instance");
+
+ populateProperties();
+ }
+
+ /*
+ * we need to pass in a namespace context since when delegated, we've no
+ * idea of the current namespace context. So it needs to be passed on here!
+ */
+ protected DOMXMLStreamReader(QName elementQName, Map.Entry[] properties, Map.Entry[] attributes) {
+ // validate the lengths, since both the arrays are supposed
+ // to have
+ this.properties = properties;
+ this.elementQName = elementQName;
+ this.attributes = attributes;
+
+ }
+
+ public void close() throws XMLStreamException {
+ // do nothing here - we have no resources to free
+ }
+
+ public int getAttributeCount() {
+ return (state == DELEGATED_STATE) ? childReader.getAttributeCount()
+ : ((attributes != null) && (state == START_ELEMENT_STATE) ? attributes.length : 0);
+ }
+
+ public String getAttributeLocalName(int i) {
+ if (state == DELEGATED_STATE) {
+ return childReader.getAttributeLocalName(i);
+ } else if (state == START_ELEMENT_STATE) {
+ QName name = getAttributeName(i);
+ if (name == null) {
+ return null;
+ } else {
+ return name.getLocalPart();
+ }
+ } else {
+ throw new IllegalStateException();
+ }
+ }
+
+ /**
+ * @param i
+ * @return
+ */
+ public QName getAttributeName(int i) {
+ if (state == DELEGATED_STATE) {
+ return childReader.getAttributeName(i);
+ } else if (state == START_ELEMENT_STATE) {
+ if (attributes == null) {
+ return null;
+ } else {
+ if ((i >= (attributes.length)) || i < 0) { // out of range
+ return null;
+ } else {
+ // get the attribute pointer
+ Object attribPointer = attributes[i].getKey();
+ // case one - attrib name is null
+ // this should be the pointer to the OMAttribute then
+ if (attribPointer instanceof String) {
+ return new QName((String) attribPointer);
+ } else if (attribPointer instanceof QName) {
+ return (QName) attribPointer;
+ } else {
+ return null;
+ }
+ }
+ }
+ } else {
+ throw new IllegalStateException(); // as per the api contract
+ }
+
+ }
+
+ public String getAttributeNamespace(int i) {
+ if (state == DELEGATED_STATE) {
+ return childReader.getAttributeNamespace(i);
+ } else if (state == START_ELEMENT_STATE) {
+ QName name = getAttributeName(i);
+ if (name == null) {
+ return null;
+ } else {
+ return name.getNamespaceURI();
+ }
+ } else {
+ throw new IllegalStateException();
+ }
+ }
+
+ public String getAttributePrefix(int i) {
+ if (state == DELEGATED_STATE) {
+ return childReader.getAttributePrefix(i);
+ } else if (state == START_ELEMENT_STATE) {
+ QName name = getAttributeName(i);
+ if (name == null) {
+ return null;
+ } else {
+ return name.getPrefix();
+ }
+ } else {
+ throw new IllegalStateException();
+ }
+ }
+
+ public String getAttributeType(int i) {
+ return null; // not supported
+ }
+
+ public String getAttributeValue(int i) {
+ if (state == DELEGATED_STATE) {
+ return childReader.getAttributeValue(i);
+ } else if (state == START_ELEMENT_STATE) {
+ if (attributes == null) {
+ return null;
+ } else {
+ if ((i >= (attributes.length)) || i < 0) { // out of range
+ return null;
+ } else {
+ // get the attribute pointer
+ Object attribPointer = attributes[i].getKey();
+ Object omAttribObj = attributes[i].getValue();
+ // case one - attrib name is null
+ // this should be the pointer to the OMAttribute then
+ if (attribPointer instanceof String) {
+ return (String) omAttribObj;
+ } else if (attribPointer instanceof QName) {
+ return (String) omAttribObj;
+ } else {
+ return null;
+ }
+ }
+ }
+ } else {
+ throw new IllegalStateException();
+ }
+
+ }
+
+ public String getAttributeValue(String nsUri, String localName) {
+
+ int attribCount = getAttributeCount();
+ String returnValue = null;
+ QName attribQualifiedName;
+ for (int i = 0; i < attribCount; i++) {
+ attribQualifiedName = getAttributeName(i);
+ if (nsUri == null) {
+ if (localName.equals(attribQualifiedName.getLocalPart())) {
+ returnValue = getAttributeValue(i);
+ break;
+ }
+ } else {
+ if (localName.equals(attribQualifiedName.getLocalPart()) && nsUri.equals(attribQualifiedName
+ .getNamespaceURI())) {
+ returnValue = getAttributeValue(i);
+ break;
+ }
+ }
+
+ }
+
+ return returnValue;
+ }
+
+ public String getCharacterEncodingScheme() {
+ return null; // todo - should we return something for this ?
+ }
+
+ /**
+ * todo implement the right contract for this
+ *
+ * @return
+ * @throws XMLStreamException
+ */
+ public String getElementText() throws XMLStreamException {
+ if (state == DELEGATED_STATE) {
+ return childReader.getElementText();
+ } else {
+ return null;
+ }
+
+ }
+
+ public String getEncoding() {
+ if (state == DELEGATED_STATE) {
+ return childReader.getEncoding();
+ } else {
+ // we've no idea what the encoding is going to be in this case
+ // perhaps we ought to return some constant here, which the user
+ // might
+ // have access to change!
+ return null;
+ }
+ }
+
+ // /////////////////////////////////////////////////////////////////////////
+ // / attribute handling
+ // /////////////////////////////////////////////////////////////////////////
+
+ public int getEventType() {
+ if (state == START_ELEMENT_STATE) {
+ return START_ELEMENT;
+ } else if (state == END_ELEMENT_STATE) {
+ return END_ELEMENT;
+ } else { // this is the delegated state
+ return childReader.getEventType();
+ }
+
+ }
+
+ public String getLocalName() {
+ if (state == DELEGATED_STATE) {
+ return childReader.getLocalName();
+ } else if (state != TEXT_STATE) {
+ return elementQName.getLocalPart();
+ } else {
+ throw new IllegalStateException();
+ }
+ }
+
+ /**
+ * @return
+ */
+ public Location getLocation() {
+ // return a default location
+ return new Location() {
+ public int getCharacterOffset() {
+ return 0;
+ }
+
+ public int getColumnNumber() {
+ return 0;
+ }
+
+ public int getLineNumber() {
+ return 0;
+ }
+
+ public String getPublicId() {
+ return null;
+ }
+
+ public String getSystemId() {
+ return null;
+ }
+ };
+ }
+
+ public QName getName() {
+ if (state == DELEGATED_STATE) {
+ return childReader.getName();
+ } else if (state != TEXT_STATE) {
+ return elementQName;
+ } else {
+ throw new IllegalStateException();
+ }
+
+ }
+
+ public NamespaceContext getNamespaceContext() {
+ if (state == DELEGATED_STATE) {
+ return childReader.getNamespaceContext();
+ } else {
+ return namespaceContext;
+ }
+
+ }
+
+ public int getNamespaceCount() {
+ if (state == DELEGATED_STATE) {
+ return childReader.getNamespaceCount();
+ } else {
+ return declaredNamespaceMap.size();
+ }
+ }
+
+ /**
+ * @param i
+ * @return
+ */
+ public String getNamespacePrefix(int i) {
+ if (state == DELEGATED_STATE) {
+ return childReader.getNamespacePrefix(i);
+ } else if (state != TEXT_STATE) {
+ // order the prefixes
+ String[] prefixes = makePrefixArray();
+ if ((i >= prefixes.length) || (i < 0)) {
+ return null;
+ } else {
+ return prefixes[i];
+ }
+
+ } else {
+ throw new IllegalStateException();
+ }
+
+ }
+
+ public String getNamespaceURI() {
+ if (state == DELEGATED_STATE) {
+ return childReader.getNamespaceURI();
+ } else if (state == TEXT_STATE) {
+ return null;
+ } else {
+ return elementQName.getNamespaceURI();
+ }
+ }
+
+ public String getNamespaceURI(int i) {
+ if (state == DELEGATED_STATE) {
+ return childReader.getNamespaceURI(i);
+ } else if (state != TEXT_STATE) {
+ String namespacePrefix = getNamespacePrefix(i);
+ return namespacePrefix == null ? null : (String) declaredNamespaceMap.get(namespacePrefix);
+ } else {
+ throw new IllegalStateException();
+ }
+
+ }
+
+ // /////////////////////////////////////////////////////////////////////////
+ // //////////// end of attribute handling
+ // /////////////////////////////////////////////////////////////////////////
+
+ // //////////////////////////////////////////////////////////////////////////
+ // //////////// namespace handling
+ // //////////////////////////////////////////////////////////////////////////
+
+ public String getNamespaceURI(String prefix) {
+ return namespaceContext.getNamespaceURI(prefix);
+ }
+
+ public String getPIData() {
+ throw new UnsupportedOperationException("Yet to be implemented !!");
+ }
+
+ public String getPITarget() {
+ throw new UnsupportedOperationException("Yet to be implemented !!");
+ }
+
+ public String getPrefix() {
+ if (state == DELEGATED_STATE) {
+ return childReader.getPrefix();
+ } else if (state == TEXT_STATE) {
+ return null;
+ } else {
+ return elementQName.getPrefix();
+ }
+ }
+
+ /**
+ * @param key
+ * @return
+ * @throws IllegalArgumentException
+ */
+ public Object getProperty(String key) throws IllegalArgumentException {
+ if (state == START_ELEMENT_STATE || state == END_ELEMENT_STATE) {
+ return null;
+ } else if (state == TEXT_STATE) {
+ return null;
+ } else if (state == DELEGATED_STATE) {
+ return childReader.getProperty(key);
+ } else {
+ return null;
+ }
+
+ }
+
+ // /////////////////////////////////////////////////////////////////////////
+ // /////// end of namespace handling
+ // /////////////////////////////////////////////////////////////////////////
+
+ public String getText() {
+ if (state == DELEGATED_STATE) {
+ return childReader.getText();
+ } else if (state == TEXT_STATE) {
+ return (String) properties[currentPropertyIndex - 1].getValue();
+ } else {
+ throw new IllegalStateException();
+ }
+ }
+
+ public char[] getTextCharacters() {
+ if (state == DELEGATED_STATE) {
+ return childReader.getTextCharacters();
+ } else if (state == TEXT_STATE) {
+ return properties[currentPropertyIndex - 1].getValue() == null ? new char[0]
+ : ((String) properties[currentPropertyIndex - 1].getValue()).toCharArray();
+ } else {
+ throw new IllegalStateException();
+ }
+ }
+
+ public int getTextCharacters(int i, char[] chars, int i1, int i2) throws XMLStreamException {
+ if (state == DELEGATED_STATE) {
+ return childReader.getTextCharacters(i, chars, i1, i2);
+ } else if (state == TEXT_STATE) {
+ // todo - implement this
+ return 0;
+ } else {
+ throw new IllegalStateException();
+ }
+ }
+
+ public int getTextLength() {
+ if (state == DELEGATED_STATE) {
+ return childReader.getTextLength();
+ } else if (state == TEXT_STATE) {
+ return 0; // assume text always starts at 0
+ } else {
+ throw new IllegalStateException();
+ }
+ }
+
+ public int getTextStart() {
+ if (state == DELEGATED_STATE) {
+ return childReader.getTextStart();
+ } else if (state == TEXT_STATE) {
+ return 0; // assume text always starts at 0
+ } else {
+ throw new IllegalStateException();
+ }
+ }
+
+ public String getVersion() {
+ return null;
+ }
+
+ public boolean hasName() {
+ // since this parser always has a name, the hasname
+ // has to return true if we are still navigating this element
+ // if not we should ask the child reader for it.
+ if (state == DELEGATED_STATE) {
+ return childReader.hasName();
+ } else {
+ return state != TEXT_STATE;
+ }
+ }
+
+ /**
+ * @return
+ * @throws XMLStreamException
+ */
+ public boolean hasNext() throws XMLStreamException {
+ if (state == DELEGATED_STATE) {
+ if (childReader.isEndOfFragment()) {
+ // the child reader is done. We shouldn't be getting the
+ // hasnext result from the child pullparser then
+ return true;
+ } else {
+ return childReader.hasNext();
+ }
+ } else {
+ return state == START_ELEMENT_STATE || state == TEXT_STATE;
+
+ }
+ }
+
+ /**
+ * check the validity of this implementation
+ *
+ * @return
+ */
+ public boolean hasText() {
+ if (state == DELEGATED_STATE) {
+ return childReader.hasText();
+ } else {
+ return state == TEXT_STATE;
+ }
+ }
+
+ /**
+ * we need to split out the calling to the populate namespaces seperately since this needs to be done *after*
+ * setting the parent namespace context. We cannot assume it will happen at construction!
+ */
+ public void init() {
+ // here we have an extra issue to attend to. we need to look at the
+ // prefixes and uris (the combination) and populate a hashmap of
+ // namespaces. The hashmap of namespaces will be used to serve the
+ // namespace context
+
+ populateNamespaceContext();
+ }
+
+ public boolean isAttributeSpecified(int i) {
+ return false; // not supported
+ }
+
+ public boolean isCharacters() {
+ if (state == START_ELEMENT_STATE || state == END_ELEMENT_STATE) {
+ return false;
+ }
+ return childReader.isCharacters();
+ }
+
+ public boolean isEndElement() {
+ if (state == START_ELEMENT_STATE) {
+ return false;
+ } else if (state == END_ELEMENT_STATE) {
+ return true;
+ }
+ return childReader.isEndElement();
+ }
+
+ /**
+ * are we done ?
+ *
+ * @return
+ */
+ public boolean isEndOfFragment() {
+ return state == END_ELEMENT_STATE;
+ }
+
+ public boolean isStandalone() {
+ return true;
+ }
+
+ public boolean isStartElement() {
+ if (state == START_ELEMENT_STATE) {
+ return true;
+ } else if (state == END_ELEMENT_STATE) {
+ return false;
+ }
+ return childReader.isStartElement();
+ }
+
+ public boolean isWhiteSpace() {
+ if (state == START_ELEMENT_STATE || state == END_ELEMENT_STATE) {
+ return false;
+ }
+ return childReader.isWhiteSpace();
+ }
+
+ /**
+ * Get the prefix list from the hastable and take that into an array
+ *
+ * @return
+ */
+ private String[] makePrefixArray() {
+ String[] prefixes =
+ (String[]) declaredNamespaceMap.keySet().toArray(new String[declaredNamespaceMap.size()]);
+ Arrays.sort(prefixes);
+ return prefixes;
+ }
+
+ public int next() throws XMLStreamException {
+ return updateStatus();
+ }
+
+ /**
+ * todo implement this
+ *
+ * @return
+ * @throws XMLStreamException
+ */
+ public int nextTag() throws XMLStreamException {
+ return 0;
+ }
+
+ // /////////////////////////////////////////////////////////////////////////
+ // / Other utility methods
+ // ////////////////////////////////////////////////////////////////////////
+
+ /**
+ * Populates a namespace context
+ */
+ private void populateNamespaceContext() {
+
+ // first add the current element namespace to the namespace context
+ // declare it if not found
+ registerNamespace(elementQName.getPrefix(), elementQName.getNamespaceURI());
+
+ // traverse through the attributes and populate the namespace context
+ // the attrib list can be of many combinations
+ // the valid combinations are
+ // String - String
+ // QName - QName
+ // null - OMAttribute
+
+ if (attributes != null) {
+ for (int i = 0; i < attributes.length; i++) { // jump in two
+ Object attribName = attributes[i].getKey();
+ if (attribName instanceof String) {
+ // ignore this case - Nothing to do
+ } else if (attribName instanceof QName) {
+ QName attribQName = (QName) attribName;
+ registerNamespace(attribQName.getPrefix(), attribQName.getNamespaceURI());
+
+ }
+ }
+ }
+
+ }
+
+ public final void populateProperties() {
+ if (properties != null) {
+ return;
+ }
+ if (elementQName == null) {
+ elementQName = namespaceContext.createQName(this.rootElementURI, this.rootElementName);
+ } else {
+ elementQName =
+ namespaceContext.createQName(elementQName.getNamespaceURI(), elementQName.getLocalPart());
+ }
+
+ List<Object> elementList = new ArrayList<Object>();
+ List<Object> attributeList = new ArrayList<Object>();
+ NamedNodeMap nodeMap = rootElement.getAttributes();
+ for (int i = 0; i < nodeMap.getLength(); i++) {
+ Attr attr = (Attr) nodeMap.item(i);
+ if (XMLConstants.XMLNS_ATTRIBUTE_NS_URI.equals(attr.getNamespaceURI())) {
+ // Skip xmlns:xxx
+ registerNamespace(attr.getLocalName(), attr.getValue());
+ continue;
+ }
+ QName attrName = new QName(attr.getNamespaceURI(), attr.getLocalName());
+ NameValuePair pair = new NameValuePair(attrName, attr.getValue());
+ attributeList.add(pair);
+ }
+ NodeList nodeList = rootElement.getChildNodes();
+ for (int i = 0; i < nodeList.getLength(); i++) {
+ Node node = nodeList.item(i);
+ switch (node.getNodeType()) {
+ case Node.TEXT_NODE:
+ case Node.CDATA_SECTION_NODE:
+ NameValuePair pair = new NameValuePair(ELEMENT_TEXT, ((CharacterData) node).getData());
+ elementList.add(pair);
+ break;
+
+ case Node.ELEMENT_NODE:
+ Element element = (Element) node;
+ QName elementName = new QName(element.getNamespaceURI(), element.getLocalName());
+ pair = new NameValuePair(elementName, new DOMXMLStreamReader(element));
+ elementList.add(pair);
+ break;
+ }
+ }
+ properties = elementList.toArray(new Map.Entry[elementList.size()]);
+ attributes = attributeList.toArray(new Map.Entry[attributeList.size()]);
+ }
+
+ /**
+ * A convenient method to reuse the properties
+ *
+ * @return event to be thrown
+ * @throws XMLStreamException
+ */
+ private int processProperties() throws XMLStreamException {
+ // move to the next property depending on the current property
+ // index
+ Object propPointer = properties[currentPropertyIndex].getKey();
+ QName propertyQName = null;
+ boolean textFound = false;
+ if (propPointer == null) {
+ throw new XMLStreamException("property key cannot be null!");
+ } else if (propPointer instanceof String) {
+ // propPointer being a String has a special case
+ // that is it can be a the special constant ELEMENT_TEXT that
+ // says this text event
+ if (ELEMENT_TEXT.equals(propPointer)) {
+ textFound = true;
+ } else {
+ propertyQName = new QName((String) propPointer);
+ }
+ } else if (propPointer instanceof QName) {
+ propertyQName = (QName) propPointer;
+ } else {
+ // oops - we've no idea what kind of key this is
+ throw new XMLStreamException("unidentified property key!!!" + propPointer);
+ }
+
+ // ok! we got the key. Now look at the value
+ Object propertyValue = properties[currentPropertyIndex].getValue();
+ // cater for the special case now
+ if (textFound) {
+ // no delegation here - make the parser null and immediately
+ // return with the event characters
+ childReader = null;
+ state = TEXT_STATE;
+ currentPropertyIndex++;
+ return CHARACTERS;
+ } else if (propertyValue == null || propertyValue instanceof String) {
+ // strings are handled by the NameValuePairStreamReader
+ childReader = new SimpleElementStreamReader(propertyQName, (String) propertyValue);
+ childReader.setParentNamespaceContext(this.namespaceContext);
+ childReader.init();
+ } else if (propertyValue instanceof DOMXMLStreamReader) {
+ // ADBbean has it's own method to get a reader
+ XMLFragmentStreamReader reader = (DOMXMLStreamReader) propertyValue;
+ // we know for sure that this is an ADB XMLStreamreader.
+ // However we need to make sure that it is compatible
+ childReader = reader;
+ childReader.setParentNamespaceContext(this.namespaceContext);
+ childReader.init();
+ } else {
+ // all special possiblilities has been tried! Let's treat
+ // the thing as a bean and try generating events from it
+ throw new UnsupportedOperationException("Not supported");
+ // childReader = new
+ // WrappingXMLStreamReader(BeanUtil.getPullParser(propertyValue,
+ // propertyQName));
+ // we cannot register the namespace context here
+ }
+
+ // set the state here
+ state = DELEGATED_STATE;
+ // we are done with the delegation
+ // increment the property index
+ currentPropertyIndex++;
+ return childReader.getEventType();
+ }
+
+ /**
+ * @param prefix
+ * @param uri
+ */
+ private void registerNamespace(String prefix, String uri) {
+ if (!uri.equals(namespaceContext.getNamespaceURI(prefix))) {
+ namespaceContext.registerMapping(prefix, uri);
+ declaredNamespaceMap.put(prefix, uri);
+ }
+ }
+
+ public void require(int i, String string, String string1) throws XMLStreamException {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * add the namespace context
+ */
+
+ public void setParentNamespaceContext(NamespaceContext nsContext) {
+ // register the namespace context passed in to this
+ this.namespaceContext.setParent(nsContext);
+
+ }
+
+ public boolean standaloneSet() {
+ return true;
+ }
+
+ /**
+ * By far this should be the most important method in this class this method changes the state of the parser
+ * according to the change in the
+ */
+ private int updateStatus() throws XMLStreamException {
+ int returnEvent = -1; // invalid state is the default state
+ switch (state) {
+ case START_ELEMENT_STATE:
+ // current element is start element. We should be looking at the
+ // property list and making a pullparser for the property value
+ if (properties == null || properties.length == 0) {
+ // no properties - move to the end element state
+ // straightaway
+ state = END_ELEMENT_STATE;
+ returnEvent = END_ELEMENT;
+ } else {
+ // there are properties. now we should delegate this task to
+ // a
+ // child reader depending on the property type
+ returnEvent = processProperties();
+
+ }
+ break;
+ case END_ELEMENT_STATE:
+ // we've reached the end element already. If the user tries to
+ // push
+ // further ahead then it is an exception
+ throw new XMLStreamException("Trying to go beyond the end of the pullparser");
+
+ case DELEGATED_STATE:
+ if (childReader.isEndOfFragment()) {
+ // we've reached the end!
+ if (currentPropertyIndex > (properties.length - 1)) {
+ state = END_ELEMENT_STATE;
+ returnEvent = END_ELEMENT;
+ } else {
+ returnEvent = processProperties();
+ }
+ } else {
+ returnEvent = childReader.next();
+ }
+ break;
+
+ case TEXT_STATE:
+ // if there are any more event we should be delegating to
+ // processProperties. if not we just return an end element
+ if (currentPropertyIndex > (properties.length - 1)) {
+ state = END_ELEMENT_STATE;
+ returnEvent = END_ELEMENT;
+ } else {
+ returnEvent = processProperties();
+ }
+ break;
+ }
+ return returnEvent;
+ }
+
+}
diff --git a/branches/sca-java-M2/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/InputSource2Node.java b/branches/sca-java-M2/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/InputSource2Node.java
new file mode 100644
index 0000000000..e9757fa13c
--- /dev/null
+++ b/branches/sca-java-M2/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/InputSource2Node.java
@@ -0,0 +1,65 @@
+/*
+ * 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.core.databinding.xml;
+
+import javax.xml.transform.Source;
+import javax.xml.transform.dom.DOMResult;
+import javax.xml.transform.stream.StreamSource;
+
+import org.apache.tuscany.spi.databinding.PullTransformer;
+import org.apache.tuscany.spi.databinding.TransformationContext;
+import org.apache.tuscany.spi.databinding.TransformationException;
+import org.apache.tuscany.spi.databinding.Transformer;
+import org.apache.tuscany.spi.databinding.extension.TransformerExtension;
+import org.osoa.sca.annotations.Service;
+import org.w3c.dom.Node;
+import org.xml.sax.InputSource;
+
+/**
+ * Push DOM InputSource to Node
+ */
+@Service(Transformer.class)
+public class InputSource2Node extends TransformerExtension<InputSource, Node> implements
+ PullTransformer<InputSource, Node> {
+ private static final Source2ResultTransformer TRANSFORMER = new Source2ResultTransformer();
+
+ public Node transform(InputSource source, TransformationContext context) {
+ try {
+ Source streamSource = new StreamSource(source.getCharacterStream());
+ DOMResult result = new DOMResult();
+ TRANSFORMER.transform(streamSource, result, context);
+ return result.getNode();
+ } catch (Exception e) {
+ throw new TransformationException(e);
+ }
+ }
+
+ public Class getSourceType() {
+ return InputSource.class;
+ }
+
+ public Class getTargetType() {
+ return Node.class;
+ }
+
+ public int getWeight() {
+ return 40;
+ }
+
+}
diff --git a/branches/sca-java-M2/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/InputSource2SAX.java b/branches/sca-java-M2/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/InputSource2SAX.java
new file mode 100644
index 0000000000..be78a07ede
--- /dev/null
+++ b/branches/sca-java-M2/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/InputSource2SAX.java
@@ -0,0 +1,63 @@
+/*
+ * 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.core.databinding.xml;
+
+import org.apache.tuscany.spi.databinding.PushTransformer;
+import org.apache.tuscany.spi.databinding.TransformationContext;
+import org.apache.tuscany.spi.databinding.TransformationException;
+import org.apache.tuscany.spi.databinding.Transformer;
+import org.apache.tuscany.spi.databinding.extension.TransformerExtension;
+import org.osoa.sca.annotations.Service;
+import org.xml.sax.ContentHandler;
+import org.xml.sax.InputSource;
+import org.xml.sax.XMLReader;
+import org.xml.sax.helpers.XMLReaderFactory;
+
+/**
+ * Push InputSource to SAX
+ */
+@Service(Transformer.class)
+public class InputSource2SAX extends TransformerExtension<InputSource, ContentHandler> implements
+ PushTransformer<InputSource, ContentHandler> {
+
+ public void transform(InputSource source, ContentHandler target, TransformationContext context) {
+ try {
+ XMLReader reader = XMLReaderFactory.createXMLReader();
+ reader.setFeature("http://xml.org/sax/features/namespaces", true);
+ reader.setFeature("http://xml.org/sax/features/namespace-prefixes", false);
+ reader.setContentHandler(target);
+ reader.parse(source);
+ } catch (Exception e) {
+ throw new TransformationException(e);
+ }
+ }
+
+ public Class getSourceType() {
+ return InputSource.class;
+ }
+
+ public Class getTargetType() {
+ return ContentHandler.class;
+ }
+
+ public int getWeight() {
+ return 40;
+ }
+
+}
diff --git a/branches/sca-java-M2/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/InputStream2Node.java b/branches/sca-java-M2/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/InputStream2Node.java
new file mode 100644
index 0000000000..e103c82b33
--- /dev/null
+++ b/branches/sca-java-M2/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/InputStream2Node.java
@@ -0,0 +1,67 @@
+/*
+ * 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.core.databinding.xml;
+
+import java.io.InputStream;
+
+import javax.xml.transform.Source;
+import javax.xml.transform.dom.DOMResult;
+import javax.xml.transform.sax.SAXSource;
+
+import org.apache.tuscany.spi.databinding.PullTransformer;
+import org.apache.tuscany.spi.databinding.TransformationContext;
+import org.apache.tuscany.spi.databinding.TransformationException;
+import org.apache.tuscany.spi.databinding.Transformer;
+import org.apache.tuscany.spi.databinding.extension.TransformerExtension;
+import org.osoa.sca.annotations.Service;
+import org.w3c.dom.Node;
+import org.xml.sax.InputSource;
+
+/**
+ * Push DOM InputSource to Node
+ */
+@Service(Transformer.class)
+public class InputStream2Node extends TransformerExtension<InputStream, Node> implements
+ PullTransformer<InputStream, Node> {
+ private static final Source2ResultTransformer TRANSFORMER = new Source2ResultTransformer();
+
+ public Node transform(InputStream source, TransformationContext context) {
+ try {
+ Source streamSource = new SAXSource(new InputSource(source));
+ DOMResult result = new DOMResult();
+ TRANSFORMER.transform(streamSource, result, context);
+ return result.getNode();
+ } catch (Exception e) {
+ throw new TransformationException(e);
+ }
+ }
+
+ public Class getSourceType() {
+ return InputStream.class;
+ }
+
+ public Class getTargetType() {
+ return Node.class;
+ }
+
+ public int getWeight() {
+ return 40;
+ }
+
+}
diff --git a/branches/sca-java-M2/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/InputStream2SAX.java b/branches/sca-java-M2/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/InputStream2SAX.java
new file mode 100644
index 0000000000..d74863ea95
--- /dev/null
+++ b/branches/sca-java-M2/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/InputStream2SAX.java
@@ -0,0 +1,62 @@
+/*
+ * 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.core.databinding.xml;
+
+import java.io.InputStream;
+
+import org.apache.tuscany.spi.databinding.PushTransformer;
+import org.apache.tuscany.spi.databinding.TransformationContext;
+import org.apache.tuscany.spi.databinding.TransformationException;
+import org.apache.tuscany.spi.databinding.Transformer;
+import org.apache.tuscany.spi.databinding.extension.TransformerExtension;
+import org.osoa.sca.annotations.Service;
+import org.xml.sax.ContentHandler;
+import org.xml.sax.InputSource;
+import org.xml.sax.XMLReader;
+import org.xml.sax.helpers.XMLReaderFactory;
+
+/**
+ * Push InputStream to SAX
+ */
+@Service(Transformer.class)
+public class InputStream2SAX extends TransformerExtension<InputStream, ContentHandler> implements
+ PushTransformer<InputStream, ContentHandler> {
+ public void transform(InputStream source, ContentHandler target, TransformationContext context) {
+ try {
+ XMLReader reader = XMLReaderFactory.createXMLReader();
+ reader.setContentHandler(target);
+ reader.parse(new InputSource(source));
+ } catch (Exception e) {
+ throw new TransformationException(e);
+ }
+ }
+
+ public Class getSourceType() {
+ return InputStream.class;
+ }
+
+ public Class getTargetType() {
+ return ContentHandler.class;
+ }
+
+ public int getWeight() {
+ return 40;
+ }
+
+}
diff --git a/branches/sca-java-M2/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/Node2Object.java b/branches/sca-java-M2/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/Node2Object.java
new file mode 100644
index 0000000000..ec0560e878
--- /dev/null
+++ b/branches/sca-java-M2/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/Node2Object.java
@@ -0,0 +1,49 @@
+/*
+ * 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.core.databinding.xml;
+
+import org.apache.tuscany.spi.databinding.Transformer;
+import org.apache.tuscany.spi.databinding.extension.SimpleType2JavaTransformer;
+import org.osoa.sca.annotations.Service;
+import org.w3c.dom.Document;
+import org.w3c.dom.Node;
+
+/**
+ * Transformer to convert data from an simple Node to Java Object
+ */
+@Service(Transformer.class)
+public class Node2Object extends SimpleType2JavaTransformer<Node> {
+
+ public Node2Object() {
+ super(null);
+ }
+
+ @Override
+ protected String getText(Node source) {
+ if (source instanceof Document) {
+ source = ((Document)source).getDocumentElement();
+ }
+ return source.getTextContent();
+ }
+
+ public Class getSourceType() {
+ return Node.class;
+ }
+
+}
diff --git a/branches/sca-java-M2/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/Node2OutputStream.java b/branches/sca-java-M2/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/Node2OutputStream.java
new file mode 100644
index 0000000000..34fbdf8c6f
--- /dev/null
+++ b/branches/sca-java-M2/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/Node2OutputStream.java
@@ -0,0 +1,66 @@
+/*
+ * 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.core.databinding.xml;
+
+import java.io.OutputStream;
+
+import javax.xml.transform.Result;
+import javax.xml.transform.Source;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamResult;
+
+import org.apache.tuscany.spi.databinding.PushTransformer;
+import org.apache.tuscany.spi.databinding.TransformationContext;
+import org.apache.tuscany.spi.databinding.TransformationException;
+import org.apache.tuscany.spi.databinding.Transformer;
+import org.apache.tuscany.spi.databinding.extension.TransformerExtension;
+import org.osoa.sca.annotations.Service;
+import org.w3c.dom.Node;
+
+/**
+ * Push DOM Node to OutputStream
+ */
+@Service(Transformer.class)
+public class Node2OutputStream extends TransformerExtension<Node, OutputStream> implements
+ PushTransformer<Node, OutputStream> {
+ private static final Source2ResultTransformer TRANSFORMER = new Source2ResultTransformer();
+
+ public void transform(Node source, OutputStream writer, TransformationContext context) {
+ try {
+ Source domSource = new DOMSource(source);
+ Result result = new StreamResult(writer);
+ TRANSFORMER.transform(domSource, result, context);
+ } catch (Exception e) {
+ throw new TransformationException(e);
+ }
+ }
+
+ public Class getSourceType() {
+ return Node.class;
+ }
+
+ public Class getTargetType() {
+ return OutputStream.class;
+ }
+
+ public int getWeight() {
+ return 40;
+ }
+
+}
diff --git a/branches/sca-java-M2/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/Node2String.java b/branches/sca-java-M2/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/Node2String.java
new file mode 100755
index 0000000000..92378e96a3
--- /dev/null
+++ b/branches/sca-java-M2/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/Node2String.java
@@ -0,0 +1,59 @@
+/*
+ * 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.core.databinding.xml;
+
+import java.io.StringWriter;
+
+import org.apache.tuscany.spi.databinding.PullTransformer;
+import org.apache.tuscany.spi.databinding.TransformationContext;
+import org.apache.tuscany.spi.databinding.TransformationException;
+import org.apache.tuscany.spi.databinding.extension.TransformerExtension;
+import org.osoa.sca.annotations.Service;
+import org.w3c.dom.Node;
+
+/**
+ * Transform DOM Node to XML String
+ */
+@Service(org.apache.tuscany.spi.databinding.Transformer.class)
+public class Node2String extends TransformerExtension<Node, String> implements PullTransformer<Node, String> {
+ private static final Node2Writer TRANSFORMER = new Node2Writer();
+
+ public String transform(Node source, TransformationContext context) {
+ try {
+ StringWriter writer = new StringWriter();
+ TRANSFORMER.transform(source, writer, context);
+ return writer.toString();
+ } catch (Exception e) {
+ throw new TransformationException(e);
+ }
+ }
+
+ public Class getSourceType() {
+ return Node.class;
+ }
+
+ public Class getTargetType() {
+ return String.class;
+ }
+
+ public int getWeight() {
+ return 40;
+ }
+
+}
diff --git a/branches/sca-java-M2/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/Node2Writer.java b/branches/sca-java-M2/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/Node2Writer.java
new file mode 100644
index 0000000000..96328fdd2f
--- /dev/null
+++ b/branches/sca-java-M2/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/Node2Writer.java
@@ -0,0 +1,65 @@
+/*
+ * 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.core.databinding.xml;
+
+import java.io.Writer;
+
+import javax.xml.transform.Result;
+import javax.xml.transform.Source;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamResult;
+
+import org.apache.tuscany.spi.databinding.PushTransformer;
+import org.apache.tuscany.spi.databinding.TransformationContext;
+import org.apache.tuscany.spi.databinding.TransformationException;
+import org.apache.tuscany.spi.databinding.Transformer;
+import org.apache.tuscany.spi.databinding.extension.TransformerExtension;
+import org.osoa.sca.annotations.Service;
+import org.w3c.dom.Node;
+
+/**
+ * Push DOM Node to Writer
+ */
+@Service(Transformer.class)
+public class Node2Writer extends TransformerExtension<Node, Writer> implements PushTransformer<Node, Writer> {
+ private static final Source2ResultTransformer TRANSFORMER = new Source2ResultTransformer();
+
+ public void transform(Node source, Writer writer, TransformationContext context) {
+ try {
+ Source domSource = new DOMSource(source);
+ Result result = new StreamResult(writer);
+ TRANSFORMER.transform(domSource, result, context);
+ } catch (Exception e) {
+ throw new TransformationException(e);
+ }
+ }
+
+ public Class getSourceType() {
+ return Node.class;
+ }
+
+ public Class getTargetType() {
+ return Writer.class;
+ }
+
+ public int getWeight() {
+ return 40;
+ }
+
+}
diff --git a/branches/sca-java-M2/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/Node2XMLStreamReader.java b/branches/sca-java-M2/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/Node2XMLStreamReader.java
new file mode 100644
index 0000000000..bff9051e01
--- /dev/null
+++ b/branches/sca-java-M2/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/Node2XMLStreamReader.java
@@ -0,0 +1,60 @@
+/*
+ * 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.core.databinding.xml;
+
+import javax.xml.stream.XMLStreamReader;
+
+import org.apache.tuscany.core.databinding.xml.StAXHelper.XMLDocumentStreamReader;
+import org.apache.tuscany.spi.databinding.PullTransformer;
+import org.apache.tuscany.spi.databinding.TransformationContext;
+import org.apache.tuscany.spi.databinding.TransformationException;
+import org.apache.tuscany.spi.databinding.Transformer;
+import org.apache.tuscany.spi.databinding.extension.TransformerExtension;
+import org.osoa.sca.annotations.Service;
+import org.w3c.dom.Node;
+
+/**
+ * Transform DOM Node to XML XMLStreamReader
+ */
+@Service(Transformer.class)
+public class Node2XMLStreamReader extends TransformerExtension<Node, XMLStreamReader> implements
+ PullTransformer<Node, XMLStreamReader> {
+
+ public XMLStreamReader transform(Node source, TransformationContext context) {
+ try {
+ DOMXMLStreamReader reader = new DOMXMLStreamReader(source);
+ return new XMLDocumentStreamReader(reader);
+ } catch (Exception e) {
+ throw new TransformationException(e);
+ }
+ }
+
+ public Class getSourceType() {
+ return Node.class;
+ }
+
+ public Class getTargetType() {
+ return XMLStreamReader.class;
+ }
+
+ public int getWeight() {
+ return 40;
+ }
+
+}
diff --git a/branches/sca-java-M2/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/Object2Node.java b/branches/sca-java-M2/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/Object2Node.java
new file mode 100644
index 0000000000..7f472ba4ff
--- /dev/null
+++ b/branches/sca-java-M2/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/Object2Node.java
@@ -0,0 +1,62 @@
+/*
+ * 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.core.databinding.xml;
+
+import javax.xml.namespace.QName;
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.apache.tuscany.spi.databinding.TransformationContext;
+import org.apache.tuscany.spi.databinding.TransformationException;
+import org.apache.tuscany.spi.databinding.Transformer;
+import org.apache.tuscany.spi.databinding.extension.DOMHelper;
+import org.apache.tuscany.spi.databinding.extension.Java2SimpleTypeTransformer;
+import org.apache.tuscany.spi.idl.ElementInfo;
+import org.osoa.sca.annotations.Service;
+import org.w3c.dom.Document;
+import org.w3c.dom.Node;
+
+/**
+ * Transformer to convert data from a simple java object to Node
+ */
+@Service(Transformer.class)
+public class Object2Node extends Java2SimpleTypeTransformer<Node> {
+
+ private Document factory;
+
+ public Object2Node() {
+ super(null);
+ try {
+ factory = DOMHelper.newDocument();
+ } catch (ParserConfigurationException e) {
+ throw new TransformationException(e);
+ }
+ }
+
+ protected Node createElement(ElementInfo element, String text, TransformationContext context) {
+ QName name = element.getQName();
+ Node root = DOMHelper.createElement(factory, name);
+ root.appendChild(factory.createTextNode(text));
+ return root;
+ }
+
+ public Class getTargetType() {
+ return Node.class;
+ }
+
+}
diff --git a/branches/sca-java-M2/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/Reader2Node.java b/branches/sca-java-M2/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/Reader2Node.java
new file mode 100644
index 0000000000..02de055c35
--- /dev/null
+++ b/branches/sca-java-M2/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/Reader2Node.java
@@ -0,0 +1,65 @@
+/*
+ * 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.core.databinding.xml;
+
+import java.io.Reader;
+
+import javax.xml.transform.Source;
+import javax.xml.transform.dom.DOMResult;
+import javax.xml.transform.stream.StreamSource;
+
+import org.apache.tuscany.spi.databinding.PullTransformer;
+import org.apache.tuscany.spi.databinding.TransformationContext;
+import org.apache.tuscany.spi.databinding.TransformationException;
+import org.apache.tuscany.spi.databinding.Transformer;
+import org.apache.tuscany.spi.databinding.extension.TransformerExtension;
+import org.osoa.sca.annotations.Service;
+import org.w3c.dom.Node;
+
+/**
+ * Push DOM Reader to Node
+ */
+@Service(Transformer.class)
+public class Reader2Node extends TransformerExtension<Reader, Node> implements PullTransformer<Reader, Node> {
+ private static final Source2ResultTransformer TRANSFORMER = new Source2ResultTransformer();
+
+ public Node transform(Reader source, TransformationContext context) {
+ try {
+ Source streamSource = new StreamSource(source);
+ DOMResult result = new DOMResult();
+ TRANSFORMER.transform(streamSource, result, context);
+ return result.getNode();
+ } catch (Exception e) {
+ throw new TransformationException(e);
+ }
+ }
+
+ public Class getSourceType() {
+ return Reader.class;
+ }
+
+ public Class getTargetType() {
+ return Node.class;
+ }
+
+ public int getWeight() {
+ return 40;
+ }
+
+}
diff --git a/branches/sca-java-M2/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/Reader2SAX.java b/branches/sca-java-M2/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/Reader2SAX.java
new file mode 100644
index 0000000000..0a4504b3de
--- /dev/null
+++ b/branches/sca-java-M2/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/Reader2SAX.java
@@ -0,0 +1,58 @@
+/*
+ * 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.core.databinding.xml;
+
+import java.io.Reader;
+
+import org.apache.tuscany.spi.databinding.PushTransformer;
+import org.apache.tuscany.spi.databinding.TransformationContext;
+import org.apache.tuscany.spi.databinding.TransformationException;
+import org.apache.tuscany.spi.databinding.Transformer;
+import org.apache.tuscany.spi.databinding.extension.TransformerExtension;
+import org.osoa.sca.annotations.Service;
+import org.xml.sax.ContentHandler;
+import org.xml.sax.InputSource;
+
+/**
+ * Transform XML string to SAX
+ */
+@Service(Transformer.class)
+public class Reader2SAX extends TransformerExtension<Reader, ContentHandler> implements
+ PushTransformer<Reader, ContentHandler> {
+ public void transform(Reader source, ContentHandler target, TransformationContext context) {
+ try {
+ new InputSource2SAX().transform(new InputSource(source), target, context);
+ } catch (Exception e) {
+ throw new TransformationException(e);
+ }
+ }
+
+ public Class getSourceType() {
+ return Reader.class;
+ }
+
+ public Class getTargetType() {
+ return ContentHandler.class;
+ }
+
+ public int getWeight() {
+ return 40;
+ }
+
+}
diff --git a/branches/sca-java-M2/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/SAX2DOM.java b/branches/sca-java-M2/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/SAX2DOM.java
new file mode 100644
index 0000000000..8f8f0f952e
--- /dev/null
+++ b/branches/sca-java-M2/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/SAX2DOM.java
@@ -0,0 +1,244 @@
+/*
+ * Copyright 2001-2004 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.core.databinding.xml;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Stack;
+
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.apache.tuscany.spi.databinding.extension.DOMHelper;
+import org.w3c.dom.Comment;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.ProcessingInstruction;
+import org.w3c.dom.Text;
+import org.xml.sax.Attributes;
+import org.xml.sax.ContentHandler;
+import org.xml.sax.Locator;
+import org.xml.sax.SAXException;
+import org.xml.sax.ext.LexicalHandler;
+
+/**
+ * SAX2DOM adapter
+ */
+public class SAX2DOM implements ContentHandler, LexicalHandler {
+ public static final String EMPTYSTRING = "";
+ public static final String XML_PREFIX = "xml";
+ public static final String XMLNS_PREFIX = "xmlns";
+ public static final String XMLNS_STRING = "xmlns:";
+ public static final String XMLNS_URI = "http://www.w3.org/2000/xmlns/";
+
+ private Node root;
+
+ private Document document;
+
+ private Node nextSibling;
+
+ private Stack<Node> nodeStk = new Stack<Node>();
+
+ private List<String> namespaceDecls;
+
+ private Node lastSibling;
+
+ public SAX2DOM() throws ParserConfigurationException {
+ this.document = DOMHelper.newDocument();
+ this.root = document;
+ }
+
+ public SAX2DOM(Node root, Node nextSibling) throws ParserConfigurationException {
+ this.root = root;
+ if (root instanceof Document) {
+ this.document = (Document)root;
+ } else if (root != null) {
+ this.document = root.getOwnerDocument();
+ } else {
+ this.document = DOMHelper.newDocument();
+ this.root = document;
+ }
+
+ this.nextSibling = nextSibling;
+ }
+
+ public SAX2DOM(Node root) throws ParserConfigurationException {
+ this(root, null);
+ }
+
+ public Node getDOM() {
+ return root;
+ }
+
+ public void characters(char[] ch, int start, int length) {
+ final Node last = (Node)nodeStk.peek();
+
+ // No text nodes can be children of root (DOM006 exception)
+ if (last != document) {
+ final String text = new String(ch, start, length);
+ if (lastSibling != null && lastSibling.getNodeType() == Node.TEXT_NODE) {
+ ((Text)lastSibling).appendData(text);
+ } else if (last == root && nextSibling != null) {
+ lastSibling = last.insertBefore(document.createTextNode(text), nextSibling);
+ } else {
+ lastSibling = last.appendChild(document.createTextNode(text));
+ }
+
+ }
+ }
+
+ public void startDocument() {
+ nodeStk.push(root);
+ }
+
+ public void endDocument() {
+ nodeStk.pop();
+ }
+
+ public void startElement(String namespace, String localName, String qName, Attributes attrs) {
+ final Element tmp = (Element)document.createElementNS(namespace, qName);
+
+ // Add namespace declarations first
+ if (namespaceDecls != null) {
+ final int nDecls = namespaceDecls.size();
+ for (int i = 0; i < nDecls; i++) {
+ final String prefix = (String)namespaceDecls.get(i++);
+
+ if (prefix == null || prefix.equals(EMPTYSTRING)) {
+ tmp.setAttributeNS(XMLNS_URI, XMLNS_PREFIX, (String)namespaceDecls.get(i));
+ } else {
+ tmp.setAttributeNS(XMLNS_URI, XMLNS_STRING + prefix, (String)namespaceDecls.get(i));
+ }
+ }
+ namespaceDecls.clear();
+ }
+
+ // Add attributes to element
+ final int nattrs = attrs.getLength();
+ for (int i = 0; i < nattrs; i++) {
+ if (attrs.getLocalName(i) == null) {
+ tmp.setAttribute(attrs.getQName(i), attrs.getValue(i));
+ } else {
+ tmp.setAttributeNS(attrs.getURI(i), attrs.getQName(i), attrs.getValue(i));
+ }
+ }
+
+ // Append this new node onto current stack node
+ Node last = (Node)nodeStk.peek();
+
+ // If the SAX2DOM is created with a non-null next sibling node,
+ // insert the result nodes before the next sibling under the root.
+ if (last == root && nextSibling != null) {
+ last.insertBefore(tmp, nextSibling);
+ } else {
+ last.appendChild(tmp);
+ }
+
+ // Push this node onto stack
+ nodeStk.push(tmp);
+ lastSibling = null;
+ }
+
+ public void endElement(String namespace, String localName, String qName) {
+ nodeStk.pop();
+ lastSibling = null;
+ }
+
+ public void startPrefixMapping(String prefix, String uri) {
+ if (namespaceDecls == null) {
+ namespaceDecls = new ArrayList<String>(2);
+ }
+ namespaceDecls.add(prefix);
+ namespaceDecls.add(uri);
+ }
+
+ public void endPrefixMapping(String prefix) {
+ // do nothing
+ }
+
+ /**
+ * This class is only used internally so this method should never be called.
+ */
+ public void ignorableWhitespace(char[] ch, int start, int length) {
+ }
+
+ /**
+ * adds processing instruction node to DOM.
+ */
+ public void processingInstruction(String target, String data) {
+ final Node last = (Node)nodeStk.peek();
+ ProcessingInstruction pi = document.createProcessingInstruction(target, data);
+ if (pi != null) {
+ if (last == root && nextSibling != null) {
+ last.insertBefore(pi, nextSibling);
+ } else {
+ last.appendChild(pi);
+ }
+
+ lastSibling = pi;
+ }
+ }
+
+ /**
+ * This class is only used internally so this method should never be called.
+ */
+ public void setDocumentLocator(Locator locator) {
+ }
+
+ /**
+ * This class is only used internally so this method should never be called.
+ */
+ public void skippedEntity(String name) {
+ }
+
+ /**
+ * Lexical Handler method to create comment node in DOM tree.
+ */
+ public void comment(char[] ch, int start, int length) {
+ final Node last = (Node)nodeStk.peek();
+ Comment comment = document.createComment(new String(ch, start, length));
+ if (comment != null) {
+ if (last == root && nextSibling != null) {
+ last.insertBefore(comment, nextSibling);
+ } else {
+ last.appendChild(comment);
+ }
+
+ lastSibling = comment;
+ }
+ }
+
+ // Lexical Handler methods- not implemented
+ public void startCDATA() {
+ }
+
+ public void endCDATA() {
+ }
+
+ public void startEntity(java.lang.String name) {
+ }
+
+ public void endDTD() {
+ }
+
+ public void endEntity(String name) {
+ }
+
+ public void startDTD(String name, String publicId, String systemId) throws SAXException {
+ }
+
+}
diff --git a/branches/sca-java-M2/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/SAX2DOMPipe.java b/branches/sca-java-M2/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/SAX2DOMPipe.java
new file mode 100644
index 0000000000..79118b4a2c
--- /dev/null
+++ b/branches/sca-java-M2/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/SAX2DOMPipe.java
@@ -0,0 +1,67 @@
+/*
+ * 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.core.databinding.xml;
+
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.apache.tuscany.spi.databinding.DataPipe;
+import org.apache.tuscany.spi.databinding.Transformer;
+import org.apache.tuscany.spi.databinding.extension.TransformerExtension;
+import org.osoa.sca.annotations.Service;
+import org.w3c.dom.Node;
+import org.xml.sax.ContentHandler;
+
+@Service(Transformer.class)
+public class SAX2DOMPipe extends TransformerExtension<ContentHandler, Node> implements
+ DataPipe<ContentHandler, Node> {
+ private SAX2DOM pipe;
+
+ /**
+ *
+ */
+ public SAX2DOMPipe() {
+ super();
+ try {
+ this.pipe = new SAX2DOM();
+ } catch (ParserConfigurationException e) {
+ throw new IllegalArgumentException(e);
+ }
+ }
+
+ public Node getResult() {
+ return pipe.getDOM();
+ }
+
+ public Class getTargetType() {
+ return Node.class;
+ }
+
+ public ContentHandler getSink() {
+ return pipe;
+ }
+
+ public Class getSourceType() {
+ return ContentHandler.class;
+ }
+
+ public int getWeight() {
+ return 30;
+ }
+
+}
diff --git a/branches/sca-java-M2/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/Source2ResultTransformer.java b/branches/sca-java-M2/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/Source2ResultTransformer.java
new file mode 100755
index 0000000000..7db14efb39
--- /dev/null
+++ b/branches/sca-java-M2/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/Source2ResultTransformer.java
@@ -0,0 +1,60 @@
+/*
+ * 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.core.databinding.xml;
+
+import javax.xml.transform.Result;
+import javax.xml.transform.Source;
+import javax.xml.transform.TransformerFactory;
+
+import org.apache.tuscany.spi.databinding.PushTransformer;
+import org.apache.tuscany.spi.databinding.TransformationContext;
+import org.apache.tuscany.spi.databinding.TransformationException;
+import org.apache.tuscany.spi.databinding.extension.TransformerExtension;
+import org.osoa.sca.annotations.Service;
+
+/**
+ * Transform TrAX Source to Result
+ */
+@Service(org.apache.tuscany.spi.databinding.Transformer.class)
+public class Source2ResultTransformer extends TransformerExtension<Source, Result> implements
+ PushTransformer<Source, Result> {
+ private static final TransformerFactory FACTORY = TransformerFactory.newInstance();
+
+ public void transform(Source source, Result result, TransformationContext context) {
+ try {
+ javax.xml.transform.Transformer transformer = FACTORY.newTransformer();
+ transformer.transform(source, result);
+ } catch (Exception e) {
+ throw new TransformationException(e);
+ }
+ }
+
+ public Class getSourceType() {
+ return Source.class;
+ }
+
+ public Class getTargetType() {
+ return Result.class;
+ }
+
+ public int getWeight() {
+ return 40;
+ }
+
+}
diff --git a/branches/sca-java-M2/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/StAX2SAXAdapter.java b/branches/sca-java-M2/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/StAX2SAXAdapter.java
new file mode 100644
index 0000000000..63fa53edb4
--- /dev/null
+++ b/branches/sca-java-M2/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/StAX2SAXAdapter.java
@@ -0,0 +1,256 @@
+/*
+ * 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.core.databinding.xml;
+
+import javax.xml.namespace.QName;
+import javax.xml.stream.Location;
+import javax.xml.stream.XMLStreamConstants;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamReader;
+
+import org.xml.sax.Attributes;
+import org.xml.sax.ContentHandler;
+import org.xml.sax.Locator;
+import org.xml.sax.SAXException;
+import org.xml.sax.helpers.AttributesImpl;
+
+/**
+ * Adapter that converts from StAX to SAX event streams. Currently the following
+ * SAX events are not generated:
+ * <ul>
+ * <li>ignorableWhitespace</li>
+ * <li>skippedEntity</li>
+ * <ul>
+ * Also the following StAX events are not mapped:
+ * <ul>
+ * <li>CDATA</li>
+ * <li>COMMENT</li>
+ * <li>DTD</li>
+ * <li>ENTITY_DECLARATION</li>
+ * <li>ENTITY_REFERENCE</li>
+ * <li>NOTATION_DECLARATION</li>
+ * <li>SPACE</li>
+ * </ul>
+ * StAX ATTRIBUTE events are ignored but the equivalent attributes (derived from
+ * the START_ELEMENT event) are supplied in the SAX startElement event's
+ * Attributes parameter. If the adaptor is configured to pass namespace prefixes
+ * then namespace information will also be included in the Attributes; StAX
+ * NAMESPACE events are ignored. <p/> Another issue is namespace processing. If
+ * the reader is positioned at a sub-node, we cannot capture all the in-scope
+ * namespace bindings. Therefore we cannot re-create a proper SAX event stream
+ * from a StAX parser. <p/> For example <p/> &lt;a:root xmlns:a="foo"
+ * xmlns:b="bar"&gt;&lt;b:sub&gt;a:foo&lt;/b:sub&gt;&lt;/a:root&gt; <p/> And if
+ * you are handed a parser at &lt;b:sub&gt;, then your SAX events should look
+ * like: <p/> &lt;b:sub xmlns:a="foo" xmlns:b="bar"&gt;a:foo&lt;/b:sub&gt; <p/>
+ * not: <p/> &lt;b:sub&gt;a:foo&lt;/b:sub&gt; <p/> <p/> Proposal: we change the
+ * receiver of SAX events (SDOXMLResourceImpl) so that it uses NamespaceContext
+ * to resolve prefix (as opposed to record start/endPrefixMappings and use it
+ * for resolution.)
+ *
+ * @version $Rev$ $Date$
+ */
+public class StAX2SAXAdapter {
+ private final boolean namespacePrefixes;
+
+ /**
+ * Construct a new StAX to SAX adapter that will convert a StAX event stream
+ * into a SAX event stream.
+ *
+ * @param namespacePrefixes whether xmlns attributes should be included in
+ * startElement events;
+ */
+ public StAX2SAXAdapter(boolean namespacePrefixes) {
+ this.namespacePrefixes = namespacePrefixes;
+ }
+
+ /**
+ * Pull events from the StAX stream and dispatch to the SAX ContentHandler.
+ * The StAX stream would typically be located on a START_DOCUMENT or
+ * START_ELEMENT event and when this method returns it will be located on
+ * the associated END_DOCUMENT or END_ELEMENT event. Behaviour with other
+ * start events is undefined.
+ *
+ * @param reader StAX event source to read
+ * @param handler SAX ContentHandler for processing events
+ * @throws XMLStreamException if there was a problem reading the stream
+ * @throws SAXException passed through from the ContentHandler
+ */
+ public void parse(XMLStreamReader reader, ContentHandler handler) throws XMLStreamException, SAXException {
+ handler.setDocumentLocator(new LocatorAdaptor(reader.getLocation()));
+
+ // remembers the nest level of elements to know when we are done
+ int level = 0;
+ int event = reader.getEventType();
+ while (true) {
+ switch (event) {
+ case XMLStreamConstants.START_DOCUMENT:
+ level++;
+ handler.startDocument();
+ break;
+ case XMLStreamConstants.START_ELEMENT:
+ level++;
+ handleStartElement(reader, handler);
+ break;
+ case XMLStreamConstants.PROCESSING_INSTRUCTION:
+ handler.processingInstruction(reader.getPITarget(), reader.getPIData());
+ break;
+ case XMLStreamConstants.CHARACTERS:
+ handler.characters(reader.getTextCharacters(), reader.getTextStart(), reader
+ .getTextLength());
+ break;
+ case XMLStreamConstants.END_ELEMENT:
+ handleEndElement(reader, handler);
+ level--;
+ if (level == 0) {
+ return;
+ }
+ break;
+ case XMLStreamConstants.END_DOCUMENT:
+ handler.endDocument();
+ return;
+ /*
+ * uncomment to handle all events rather than just mapped
+ * ones // StAX events that are not mapped to SAX case
+ * XMLStreamConstants.COMMENT: case
+ * XMLStreamConstants.SPACE: case
+ * XMLStreamConstants.ENTITY_REFERENCE: case
+ * XMLStreamConstants.DTD: case XMLStreamConstants.CDATA:
+ * case XMLStreamConstants.NOTATION_DECLARATION: case
+ * XMLStreamConstants.ENTITY_DECLARATION: break; // StAX
+ * events handled in START_ELEMENT case
+ * XMLStreamConstants.ATTRIBUTE: case
+ * XMLStreamConstants.NAMESPACE: break; default: throw new
+ * AssertionError("Unknown StAX event: " + event);
+ */
+ }
+ event = reader.next();
+ }
+ }
+
+ private void handleStartElement(XMLStreamReader reader, ContentHandler handler) throws SAXException {
+ // send startPrefixMapping events immediately before startElement event
+ int nsCount = reader.getNamespaceCount();
+ for (int i = 0; i < nsCount; i++) {
+ String prefix = reader.getNamespacePrefix(i);
+ if (prefix == null) { // true for default namespace
+ prefix = "";
+ }
+ handler.startPrefixMapping(prefix, reader.getNamespaceURI(i));
+ }
+
+ // fire startElement
+ QName qname = reader.getName();
+ String prefix = qname.getPrefix();
+ String rawname;
+ if (prefix == null || prefix.length() == 0) {
+ rawname = qname.getLocalPart();
+ } else {
+ rawname = prefix + ':' + qname.getLocalPart();
+ }
+ Attributes attrs = getAttributes(reader);
+ handler.startElement(qname.getNamespaceURI(), qname.getLocalPart(), rawname, attrs);
+ }
+
+ private static void handleEndElement(XMLStreamReader reader, ContentHandler handler) throws SAXException {
+ // fire endElement
+ QName qname = reader.getName();
+ handler.endElement(qname.getNamespaceURI(), qname.getLocalPart(), qname.toString());
+
+ // send endPrefixMapping events immediately after endElement event
+ // we send them in the opposite order to that returned but this is not
+ // actually required by SAX
+ int nsCount = reader.getNamespaceCount();
+ for (int i = nsCount - 1; i >= 0; i--) {
+ String prefix = reader.getNamespacePrefix(i);
+ if (prefix == null) { // true for default namespace
+ prefix = "";
+ }
+ handler.endPrefixMapping(prefix);
+ }
+ }
+
+ /**
+ * Get the attributes associated with the current START_ELEMENT event.
+ *
+ * @return the StAX attributes converted to org.xml.sax.Attributes
+ */
+ private Attributes getAttributes(XMLStreamReader reader) {
+ assert reader.getEventType() == XMLStreamConstants.START_ELEMENT;
+
+ AttributesImpl attrs = new AttributesImpl();
+
+ // add namespace declarations if required
+ if (namespacePrefixes) {
+ for (int i = 0; i < reader.getNamespaceCount(); i++) {
+ String prefix = reader.getNamespacePrefix(i);
+ String uri = reader.getNamespaceURI(i);
+ attrs.addAttribute(null, prefix, "xmlns:" + prefix, "CDATA", uri);
+ }
+ }
+
+ // Regular attributes
+ for (int i = 0; i < reader.getAttributeCount(); i++) {
+ String uri = reader.getAttributeNamespace(i);
+ if (uri == null) {
+ uri = "";
+ }
+ String localName = reader.getAttributeLocalName(i);
+ String prefix = reader.getAttributePrefix(i);
+ String qname;
+ if (prefix == null || prefix.length() == 0) {
+ qname = localName;
+ } else {
+ qname = prefix + ':' + localName;
+ }
+ String type = reader.getAttributeType(i);
+ String value = reader.getAttributeValue(i);
+
+ attrs.addAttribute(uri, localName, qname, type, value);
+ }
+
+ return attrs;
+ }
+
+ /**
+ * Adaptor for mapping Locator information.
+ */
+ private static final class LocatorAdaptor implements Locator {
+ private final Location location;
+
+ private LocatorAdaptor(Location location) {
+ this.location = location;
+ }
+
+ public int getColumnNumber() {
+ return location == null ? 0 : location.getColumnNumber();
+ }
+
+ public int getLineNumber() {
+ return location == null ? 0 : location.getLineNumber();
+ }
+
+ public String getPublicId() {
+ return location == null ? "" : location.getPublicId();
+ }
+
+ public String getSystemId() {
+ return location == null ? "" : location.getSystemId();
+ }
+ }
+}
diff --git a/branches/sca-java-M2/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/StAXHelper.java b/branches/sca-java-M2/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/StAXHelper.java
new file mode 100755
index 0000000000..db0eae165f
--- /dev/null
+++ b/branches/sca-java-M2/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/StAXHelper.java
@@ -0,0 +1,820 @@
+/*
+ * 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.core.databinding.xml;
+
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.Reader;
+import java.io.StringReader;
+import java.io.StringWriter;
+import java.io.Writer;
+import java.util.NoSuchElementException;
+
+import javax.xml.namespace.NamespaceContext;
+import javax.xml.namespace.QName;
+import javax.xml.stream.Location;
+import javax.xml.stream.XMLInputFactory;
+import javax.xml.stream.XMLOutputFactory;
+import javax.xml.stream.XMLStreamConstants;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamReader;
+import javax.xml.stream.XMLStreamWriter;
+import javax.xml.transform.Source;
+
+public final class StAXHelper {
+
+ private static final XMLInputFactory INPUT_FACTORY = XMLInputFactory.newInstance();
+
+ private static final XMLOutputFactory OUTPUT_FACTORY = XMLOutputFactory.newInstance();
+
+ private StAXHelper() {
+ }
+
+ /**
+ * This class is derived from Apache Axis2 class
+ * org.apache.axis2.util.StreamWrapper</a>. It's used wrap a
+ * XMLStreamReader to create a XMLStreamReader representing a document and
+ * it will produce START_DOCUMENT, END_DOCUMENT events.
+ */
+ public static class XMLDocumentStreamReader implements XMLStreamReader {
+ private static final int STATE_COMPLETE_AT_NEXT = 2; // The wrapper
+ // will produce
+ // END_DOCUMENT
+
+ private static final int STATE_COMPLETED = 3; // Done
+
+ private static final int STATE_INIT = 0; // The wrapper will produce
+ // START_DOCUMENT
+
+ private static final int STATE_SWITCHED = 1; // The real reader will
+ // produce events
+
+ private XMLStreamReader realReader;
+
+ private int state = STATE_INIT;
+
+ public XMLDocumentStreamReader(XMLStreamReader realReader) {
+ if (realReader == null) {
+ throw new UnsupportedOperationException("Reader cannot be null");
+ }
+
+ this.realReader = realReader;
+
+ // If the real reader is positioned at START_DOCUMENT, always use
+ // the real reader
+ if (realReader.getEventType() == START_DOCUMENT) {
+ state = STATE_SWITCHED;
+ }
+ }
+
+ public void close() throws XMLStreamException {
+ realReader.close();
+ }
+
+ public int getAttributeCount() {
+ if (isDelegating()) {
+ return realReader.getAttributeCount();
+ } else {
+ throw new IllegalStateException();
+ }
+ }
+
+ public String getAttributeLocalName(int i) {
+ if (isDelegating()) {
+ return realReader.getAttributeLocalName(i);
+ } else {
+ throw new IllegalStateException();
+ }
+ }
+
+ public QName getAttributeName(int i) {
+ if (isDelegating()) {
+ return realReader.getAttributeName(i);
+ } else {
+ throw new IllegalStateException();
+ }
+ }
+
+ public String getAttributeNamespace(int i) {
+ if (isDelegating()) {
+ return realReader.getAttributeNamespace(i);
+ } else {
+ throw new IllegalStateException();
+ }
+ }
+
+ public String getAttributePrefix(int i) {
+ if (isDelegating()) {
+ return realReader.getAttributePrefix(i);
+ } else {
+ throw new IllegalStateException();
+ }
+ }
+
+ public String getAttributeType(int i) {
+ if (isDelegating()) {
+ return realReader.getAttributeType(i);
+ } else {
+ throw new IllegalStateException();
+ }
+ }
+
+ public String getAttributeValue(int i) {
+ if (isDelegating()) {
+ return realReader.getAttributeValue(i);
+ } else {
+ throw new IllegalStateException();
+ }
+ }
+
+ public String getAttributeValue(String s, String s1) {
+ if (isDelegating()) {
+ return realReader.getAttributeValue(s, s1);
+ } else {
+ throw new IllegalStateException();
+ }
+ }
+
+ public String getCharacterEncodingScheme() {
+ return realReader.getCharacterEncodingScheme();
+ }
+
+ public String getElementText() throws XMLStreamException {
+ if (isDelegating()) {
+ return realReader.getElementText();
+ } else {
+ throw new XMLStreamException();
+ }
+ }
+
+ public String getEncoding() {
+ return realReader.getEncoding();
+ }
+
+ public int getEventType() {
+ int event = -1;
+ switch (state) {
+ case STATE_SWITCHED:
+ case STATE_COMPLETE_AT_NEXT:
+ event = realReader.getEventType();
+ break;
+ case STATE_INIT:
+ event = START_DOCUMENT;
+ break;
+ case STATE_COMPLETED:
+ event = END_DOCUMENT;
+ break;
+ }
+ return event;
+ }
+
+ public String getLocalName() {
+ if (isDelegating()) {
+ return realReader.getLocalName();
+ } else {
+ throw new IllegalStateException();
+ }
+ }
+
+ public Location getLocation() {
+ if (isDelegating()) {
+ return realReader.getLocation();
+ } else {
+ return null;
+ }
+ }
+
+ public QName getName() {
+ if (isDelegating()) {
+ return realReader.getName();
+ } else {
+ throw new IllegalStateException();
+ }
+ }
+
+ public NamespaceContext getNamespaceContext() {
+ return realReader.getNamespaceContext();
+ }
+
+ public int getNamespaceCount() {
+ if (isDelegating()) {
+ return realReader.getNamespaceCount();
+ } else {
+ throw new IllegalStateException();
+ }
+ }
+
+ public String getNamespacePrefix(int i) {
+ if (isDelegating()) {
+ return realReader.getNamespacePrefix(i);
+ } else {
+ throw new IllegalStateException();
+ }
+ }
+
+ public String getNamespaceURI() {
+ if (isDelegating()) {
+ return realReader.getNamespaceURI();
+ } else {
+ throw new IllegalStateException();
+ }
+ }
+
+ public String getNamespaceURI(int i) {
+ if (isDelegating()) {
+ return realReader.getNamespaceURI(i);
+ } else {
+ throw new IllegalStateException();
+ }
+ }
+
+ public String getNamespaceURI(String s) {
+ if (isDelegating()) {
+ return realReader.getNamespaceURI(s);
+ } else {
+ throw new IllegalStateException();
+ }
+ }
+
+ public String getPIData() {
+ if (isDelegating()) {
+ return realReader.getPIData();
+ } else {
+ throw new IllegalStateException();
+ }
+ }
+
+ public String getPITarget() {
+ if (isDelegating()) {
+ return realReader.getPITarget();
+ } else {
+ throw new IllegalStateException();
+ }
+ }
+
+ public String getPrefix() {
+ if (isDelegating()) {
+ return realReader.getPrefix();
+ } else {
+ throw new IllegalStateException();
+ }
+ }
+
+ public Object getProperty(String s) throws IllegalArgumentException {
+ if (isDelegating()) {
+ return realReader.getProperty(s);
+ } else {
+ throw new IllegalArgumentException();
+ }
+ }
+
+ public String getText() {
+ if (isDelegating()) {
+ return realReader.getText();
+ } else {
+ throw new IllegalStateException();
+ }
+ }
+
+ public char[] getTextCharacters() {
+ if (isDelegating()) {
+ return realReader.getTextCharacters();
+ } else {
+ throw new IllegalStateException();
+ }
+ }
+
+ public int getTextCharacters(int i, char[] chars, int i1, int i2) throws XMLStreamException {
+ if (isDelegating()) {
+ return realReader.getTextCharacters(i, chars, i1, i2);
+ } else {
+ throw new IllegalStateException();
+ }
+ }
+
+ public int getTextLength() {
+ if (isDelegating()) {
+ return realReader.getTextLength();
+ } else {
+ throw new IllegalStateException();
+ }
+ }
+
+ public int getTextStart() {
+ if (isDelegating()) {
+ return realReader.getTextStart();
+ } else {
+ throw new IllegalStateException();
+ }
+ }
+
+ public String getVersion() {
+ if (isDelegating()) {
+ return realReader.getVersion();
+ } else {
+ return null;
+ }
+ }
+
+ public boolean hasName() {
+ if (isDelegating()) {
+ 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 (state == STATE_SWITCHED) {
+ return realReader.hasNext();
+ } else {
+ return true;
+ }
+ }
+
+ public boolean hasText() {
+ if (isDelegating()) {
+ return realReader.hasText();
+ } else {
+ return false;
+ }
+ }
+
+ public boolean isAttributeSpecified(int i) {
+ if (isDelegating()) {
+ return realReader.isAttributeSpecified(i);
+ } else {
+ return false;
+ }
+ }
+
+ public boolean isCharacters() {
+ if (isDelegating()) {
+ return realReader.isCharacters();
+ } else {
+ return false;
+ }
+ }
+
+ private boolean isDelegating() {
+ return state == STATE_SWITCHED || state == STATE_COMPLETE_AT_NEXT;
+ }
+
+ public boolean isEndElement() {
+ if (isDelegating()) {
+ return realReader.isEndElement();
+ } else {
+ return false;
+ }
+ }
+
+ public boolean isStandalone() {
+ if (isDelegating()) {
+ return realReader.isStandalone();
+ } else {
+ return false;
+ }
+ }
+
+ public boolean isStartElement() {
+ if (isDelegating()) {
+ return realReader.isStartElement();
+ } else {
+ return false;
+ }
+ }
+
+ public boolean isWhiteSpace() {
+ if (isDelegating()) {
+ return realReader.isWhiteSpace();
+ } else {
+ return false;
+ }
+ }
+
+ public int next() throws XMLStreamException {
+ int returnEvent = -1;
+
+ switch (state) {
+ 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_INIT:
+ 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 NoSuchElementException("End of stream has reached.");
+ default:
+ throw new UnsupportedOperationException();
+ }
+
+ return returnEvent;
+ }
+
+ public int nextTag() throws XMLStreamException {
+ if (isDelegating()) {
+ return realReader.nextTag();
+ } else {
+ throw new XMLStreamException();
+ }
+ }
+
+ public void require(int i, String s, String s1) throws XMLStreamException {
+ if (isDelegating()) {
+ realReader.require(i, s, s1);
+ }
+ }
+
+ public boolean standaloneSet() {
+ if (isDelegating()) {
+ return realReader.standaloneSet();
+ } else {
+ return false;
+ }
+ }
+ }
+
+ public static interface XMLFragmentStreamReader extends XMLStreamReader {
+
+ // this will help to handle Text within the current element.
+ // user should pass the element text to the property list as this
+ // ELEMENT_TEXT as the key. This key deliberately has a space in it
+ // so that it is not a valid XML name
+ String ELEMENT_TEXT = "Element Text";
+
+ /**
+ * Initiate the parser - this will do whatever the needed tasks to
+ * initiate the parser and must be called before attempting any specific
+ * parsing using this parser
+ */
+ void init();
+
+ /**
+ * Extra method to query the state of the pullparser
+ *
+ * @return
+ */
+ boolean isEndOfFragment();
+
+ /**
+ * add the parent namespace context to this parser
+ */
+ void setParentNamespaceContext(NamespaceContext nsContext);
+ }
+
+ /**
+ * The XMLStreamSerializer pulls events from the XMLStreamReader and dumps
+ * into the XMLStreamWriter
+ */
+ public static class XMLStreamSerializer implements XMLStreamConstants {
+
+ public static final String NAMESPACE_PREFIX = "ns";
+
+ private static int namespaceSuffix = 0;
+
+ /*
+ * 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;
+
+ /**
+ * 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 = null;
+ String namespaceName = null;
+ String writerPrefix = null;
+ 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.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 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 {
+ 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();
+ }
+
+ /**
+ * 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 {
+ // 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 serializeText(XMLStreamReader reader, XMLStreamWriter writer)
+ throws XMLStreamException {
+ writer.writeCharacters(reader.getText());
+ }
+ }
+
+ public static XMLStreamReader createXMLStreamReader(InputStream inputStream) throws XMLStreamException {
+ XMLStreamReader streamReader = INPUT_FACTORY.createXMLStreamReader(inputStream);
+ return streamReader;
+ }
+
+ public static XMLStreamReader createXMLStreamReader(Reader reader) throws XMLStreamException {
+ XMLStreamReader streamReader = INPUT_FACTORY.createXMLStreamReader(reader);
+ return streamReader;
+ }
+
+ public static XMLStreamReader createXMLStreamReader(Source source) throws XMLStreamException {
+ XMLStreamReader reader = INPUT_FACTORY.createXMLStreamReader(source);
+ return reader;
+ }
+
+ public static XMLStreamReader createXMLStreamReader(String string) throws XMLStreamException {
+ StringReader reader = new StringReader(string);
+ return createXMLStreamReader(reader);
+ }
+
+ public static String save(XMLStreamReader reader) throws XMLStreamException {
+ StringWriter writer = new StringWriter();
+ save(reader, writer);
+ return writer.toString();
+ }
+
+ public static void save(XMLStreamReader reader, OutputStream outputStream) throws XMLStreamException {
+ XMLStreamSerializer serializer = new XMLStreamSerializer();
+ XMLStreamWriter streamWriter = OUTPUT_FACTORY.createXMLStreamWriter(outputStream);
+ serializer.serialize(reader, streamWriter);
+ streamWriter.flush();
+ }
+
+ public static void save(XMLStreamReader reader, Writer writer) throws XMLStreamException {
+ XMLStreamSerializer serializer = new XMLStreamSerializer();
+ XMLStreamWriter streamWriter = OUTPUT_FACTORY.createXMLStreamWriter(writer);
+ serializer.serialize(reader, streamWriter);
+ streamWriter.flush();
+ }
+
+ public static void save(XMLStreamReader reader, XMLStreamWriter writer) throws XMLStreamException {
+ XMLStreamSerializer serializer = new XMLStreamSerializer();
+ serializer.serialize(reader, writer);
+ writer.flush();
+ }
+
+}
diff --git a/branches/sca-java-M2/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/StreamDataPipe.java b/branches/sca-java-M2/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/StreamDataPipe.java
new file mode 100755
index 0000000000..d0b6ce07f2
--- /dev/null
+++ b/branches/sca-java-M2/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/StreamDataPipe.java
@@ -0,0 +1,57 @@
+/*
+ * 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.core.databinding.xml;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+import org.apache.tuscany.spi.databinding.DataPipe;
+import org.apache.tuscany.spi.databinding.Transformer;
+import org.apache.tuscany.spi.databinding.extension.TransformerExtension;
+import org.osoa.sca.annotations.Service;
+
+@Service(Transformer.class)
+public class StreamDataPipe extends TransformerExtension<OutputStream, InputStream> implements
+ DataPipe<OutputStream, InputStream> {
+
+ private ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+
+ public InputStream getResult() {
+ return new ByteArrayInputStream(outputStream.toByteArray());
+ }
+
+ public Class getTargetType() {
+ return InputStream.class;
+ }
+
+ public int getWeight() {
+ return 50;
+ }
+
+ public OutputStream getSink() {
+ return outputStream;
+ }
+
+ public Class getSourceType() {
+ return OutputStream.class;
+ }
+
+}
diff --git a/branches/sca-java-M2/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/String2Node.java b/branches/sca-java-M2/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/String2Node.java
new file mode 100755
index 0000000000..3f878a07b9
--- /dev/null
+++ b/branches/sca-java-M2/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/String2Node.java
@@ -0,0 +1,60 @@
+/*
+ * 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.core.databinding.xml;
+
+import java.io.StringReader;
+
+import javax.xml.parsers.DocumentBuilder;
+
+import org.apache.tuscany.spi.databinding.PullTransformer;
+import org.apache.tuscany.spi.databinding.TransformationContext;
+import org.apache.tuscany.spi.databinding.TransformationException;
+import org.apache.tuscany.spi.databinding.Transformer;
+import org.apache.tuscany.spi.databinding.extension.DOMHelper;
+import org.apache.tuscany.spi.databinding.extension.TransformerExtension;
+import org.osoa.sca.annotations.Service;
+import org.w3c.dom.Node;
+import org.xml.sax.InputSource;
+
+@Service(Transformer.class)
+public class String2Node extends TransformerExtension<String, Node> implements PullTransformer<String, Node> {
+
+ public Node transform(String source, TransformationContext context) {
+ try {
+ DocumentBuilder builder = DOMHelper.newDocumentBuilder();
+ InputSource inputSource = new InputSource(new StringReader(source));
+ return builder.parse(inputSource);
+ } catch (Exception e) {
+ throw new TransformationException(e);
+ }
+ }
+
+ public Class getSourceType() {
+ return String.class;
+ }
+
+ public Class getTargetType() {
+ return Node.class;
+ }
+
+ public int getWeight() {
+ return 50;
+ }
+
+}
diff --git a/branches/sca-java-M2/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/String2SAX.java b/branches/sca-java-M2/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/String2SAX.java
new file mode 100644
index 0000000000..50ea110b17
--- /dev/null
+++ b/branches/sca-java-M2/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/String2SAX.java
@@ -0,0 +1,59 @@
+/*
+ * 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.core.databinding.xml;
+
+import java.io.StringReader;
+
+import org.apache.tuscany.spi.databinding.PushTransformer;
+import org.apache.tuscany.spi.databinding.TransformationContext;
+import org.apache.tuscany.spi.databinding.TransformationException;
+import org.apache.tuscany.spi.databinding.Transformer;
+import org.apache.tuscany.spi.databinding.extension.TransformerExtension;
+import org.osoa.sca.annotations.Service;
+import org.xml.sax.ContentHandler;
+import org.xml.sax.InputSource;
+
+/**
+ * Transform XML string to SAX
+ */
+@Service(Transformer.class)
+public class String2SAX extends TransformerExtension<String, ContentHandler> implements
+ PushTransformer<String, ContentHandler> {
+
+ public void transform(String source, ContentHandler target, TransformationContext context) {
+ try {
+ new InputSource2SAX().transform(new InputSource(new StringReader(source)), target, context);
+ } catch (Exception e) {
+ throw new TransformationException(e);
+ }
+ }
+
+ public Class getSourceType() {
+ return String.class;
+ }
+
+ public Class getTargetType() {
+ return ContentHandler.class;
+ }
+
+ public int getWeight() {
+ return 40;
+ }
+
+}
diff --git a/branches/sca-java-M2/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/String2XMLStreamReader.java b/branches/sca-java-M2/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/String2XMLStreamReader.java
new file mode 100755
index 0000000000..9793cc3f7e
--- /dev/null
+++ b/branches/sca-java-M2/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/String2XMLStreamReader.java
@@ -0,0 +1,55 @@
+/*
+ * 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.core.databinding.xml;
+
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamReader;
+
+import org.apache.tuscany.spi.databinding.PullTransformer;
+import org.apache.tuscany.spi.databinding.TransformationContext;
+import org.apache.tuscany.spi.databinding.TransformationException;
+import org.apache.tuscany.spi.databinding.Transformer;
+import org.apache.tuscany.spi.databinding.extension.TransformerExtension;
+import org.osoa.sca.annotations.Service;
+
+@Service(Transformer.class)
+public class String2XMLStreamReader extends TransformerExtension<String, XMLStreamReader> implements
+ PullTransformer<String, XMLStreamReader> {
+
+ public XMLStreamReader transform(String source, TransformationContext context) {
+ try {
+ return StAXHelper.createXMLStreamReader(source);
+ } catch (XMLStreamException e) {
+ throw new TransformationException(e);
+ }
+ }
+
+ public Class getSourceType() {
+ return String.class;
+ }
+
+ public Class getTargetType() {
+ return XMLStreamReader.class;
+ }
+
+ public int getWeight() {
+ return 50;
+ }
+
+}
diff --git a/branches/sca-java-M2/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/Writer2ReaderDataPipe.java b/branches/sca-java-M2/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/Writer2ReaderDataPipe.java
new file mode 100755
index 0000000000..c66d0fd934
--- /dev/null
+++ b/branches/sca-java-M2/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/Writer2ReaderDataPipe.java
@@ -0,0 +1,56 @@
+/*
+ * 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.core.databinding.xml;
+
+import java.io.Reader;
+import java.io.StringReader;
+import java.io.StringWriter;
+import java.io.Writer;
+
+import org.apache.tuscany.spi.databinding.DataPipe;
+import org.apache.tuscany.spi.databinding.Transformer;
+import org.apache.tuscany.spi.databinding.extension.TransformerExtension;
+import org.osoa.sca.annotations.Service;
+
+@Service(Transformer.class)
+public class Writer2ReaderDataPipe extends TransformerExtension<Writer, Reader> implements DataPipe<Writer, Reader> {
+
+ private StringWriter writer = new StringWriter();
+
+ public Reader getResult() {
+ return new StringReader(writer.toString());
+ }
+
+ public Class getTargetType() {
+ return Reader.class;
+ }
+
+ public int getWeight() {
+ return 50;
+ }
+
+ public Writer getSink() {
+ return writer;
+ }
+
+ public Class getSourceType() {
+ return Writer.class;
+ }
+
+}
diff --git a/branches/sca-java-M2/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/XMLStreamReader2Node.java b/branches/sca-java-M2/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/XMLStreamReader2Node.java
new file mode 100644
index 0000000000..6ecaa85be4
--- /dev/null
+++ b/branches/sca-java-M2/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/XMLStreamReader2Node.java
@@ -0,0 +1,62 @@
+/*
+ * 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.core.databinding.xml;
+
+import javax.xml.stream.XMLStreamReader;
+
+import org.apache.tuscany.spi.databinding.PullTransformer;
+import org.apache.tuscany.spi.databinding.TransformationContext;
+import org.apache.tuscany.spi.databinding.TransformationException;
+import org.apache.tuscany.spi.databinding.Transformer;
+import org.apache.tuscany.spi.databinding.extension.TransformerExtension;
+import org.osoa.sca.annotations.Service;
+import org.w3c.dom.Node;
+
+/**
+ * Transform DOM Node to XML XMLStreamReader
+ */
+@Service(Transformer.class)
+public class XMLStreamReader2Node extends TransformerExtension<XMLStreamReader, Node> implements
+ PullTransformer<XMLStreamReader, Node> {
+ private SAX2DOMPipe pipe = new SAX2DOMPipe();
+
+ private XMLStreamReader2SAX stax2sax = new XMLStreamReader2SAX();
+
+ public Node transform(XMLStreamReader source, TransformationContext context) {
+ try {
+ stax2sax.transform(source, pipe.getSink(), context);
+ return pipe.getResult();
+ } catch (Exception e) {
+ throw new TransformationException(e);
+ }
+ }
+
+ public Class getSourceType() {
+ return XMLStreamReader.class;
+ }
+
+ public Class getTargetType() {
+ return Node.class;
+ }
+
+ public int getWeight() {
+ return 40;
+ }
+
+}
diff --git a/branches/sca-java-M2/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/XMLStreamReader2SAX.java b/branches/sca-java-M2/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/XMLStreamReader2SAX.java
new file mode 100644
index 0000000000..0c6f0b8df7
--- /dev/null
+++ b/branches/sca-java-M2/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/XMLStreamReader2SAX.java
@@ -0,0 +1,73 @@
+/*
+ * 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.core.databinding.xml;
+
+import javax.xml.stream.XMLStreamReader;
+
+import org.apache.tuscany.spi.databinding.PushTransformer;
+import org.apache.tuscany.spi.databinding.TransformationContext;
+import org.apache.tuscany.spi.databinding.TransformationException;
+import org.apache.tuscany.spi.databinding.Transformer;
+import org.apache.tuscany.spi.databinding.extension.TransformerExtension;
+import org.osoa.sca.annotations.Service;
+import org.xml.sax.ContentHandler;
+
+/**
+ * XMLStreamReader to SAX events
+ */
+@Service(Transformer.class)
+public class XMLStreamReader2SAX extends TransformerExtension<XMLStreamReader, ContentHandler> implements
+ PushTransformer<XMLStreamReader, ContentHandler> {
+
+ /**
+ * @see org.apache.tuscany.spi.databinding.PushTransformer#getSourceType()
+ */
+ public Class getTargetType() {
+ return ContentHandler.class;
+ }
+
+ /**
+ * @see org.apache.tuscany.spi.databinding.PushTransformer#getSourceType()
+ */
+ public Class getSourceType() {
+ return XMLStreamReader.class;
+ }
+
+ /**
+ * @see org.apache.tuscany.spi.databinding.PushTransformer#getWeight()
+ */
+ public int getWeight() {
+ return 20;
+ }
+
+ /**
+ * @see org.apache.tuscany.spi.databinding.PushTransformer#transform(java.lang.Object,
+ * java.lang.Object,
+ * org.apache.tuscany.spi.databinding.TransformationContext)
+ */
+ public void transform(XMLStreamReader source, ContentHandler sink, TransformationContext context) {
+ StAX2SAXAdapter adapter = new StAX2SAXAdapter(false);
+ try {
+ adapter.parse(source, sink);
+ } catch (Exception e) {
+ throw new TransformationException(e);
+ }
+ }
+
+}
diff --git a/branches/sca-java-M2/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/XMLStreamReader2String.java b/branches/sca-java-M2/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/XMLStreamReader2String.java
new file mode 100755
index 0000000000..85ac7b5af6
--- /dev/null
+++ b/branches/sca-java-M2/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/XMLStreamReader2String.java
@@ -0,0 +1,55 @@
+/*
+ * 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.core.databinding.xml;
+
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamReader;
+
+import org.apache.tuscany.spi.databinding.PullTransformer;
+import org.apache.tuscany.spi.databinding.TransformationContext;
+import org.apache.tuscany.spi.databinding.TransformationException;
+import org.apache.tuscany.spi.databinding.Transformer;
+import org.apache.tuscany.spi.databinding.extension.TransformerExtension;
+import org.osoa.sca.annotations.Service;
+
+@Service(Transformer.class)
+public class XMLStreamReader2String extends TransformerExtension<XMLStreamReader, String> implements
+ PullTransformer<XMLStreamReader, String> {
+
+ public String transform(XMLStreamReader source, TransformationContext context) {
+ try {
+ return StAXHelper.save(source);
+ } catch (XMLStreamException e) {
+ throw new TransformationException(e);
+ }
+ }
+
+ public Class getSourceType() {
+ return XMLStreamReader.class;
+ }
+
+ public Class getTargetType() {
+ return String.class;
+ }
+
+ public int getWeight() {
+ return 40;
+ }
+
+}
diff --git a/branches/sca-java-M2/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/XMLStringDataBinding.java b/branches/sca-java-M2/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/XMLStringDataBinding.java
new file mode 100644
index 0000000000..39e9362524
--- /dev/null
+++ b/branches/sca-java-M2/sca/kernel/core/src/main/java/org/apache/tuscany/core/databinding/xml/XMLStringDataBinding.java
@@ -0,0 +1,33 @@
+/*
+ * 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.core.databinding.xml;
+
+import org.apache.tuscany.spi.databinding.extension.DataBindingExtension;
+
+/**
+ * A DataBinding for the XML string
+ */
+public class XMLStringDataBinding extends DataBindingExtension {
+ public static final String NAME = String.class.getName();
+
+ public XMLStringDataBinding() {
+ super(NAME, String.class);
+ }
+}