diff options
Diffstat (limited to 'sandbox/old/contrib/binding-celtix/binding/src/main/java/org/apache/tuscany/binding/celtix/io/NodeDataWriter.java')
-rw-r--r-- | sandbox/old/contrib/binding-celtix/binding/src/main/java/org/apache/tuscany/binding/celtix/io/NodeDataWriter.java | 322 |
1 files changed, 322 insertions, 0 deletions
diff --git a/sandbox/old/contrib/binding-celtix/binding/src/main/java/org/apache/tuscany/binding/celtix/io/NodeDataWriter.java b/sandbox/old/contrib/binding-celtix/binding/src/main/java/org/apache/tuscany/binding/celtix/io/NodeDataWriter.java new file mode 100644 index 0000000000..d870cafa87 --- /dev/null +++ b/sandbox/old/contrib/binding-celtix/binding/src/main/java/org/apache/tuscany/binding/celtix/io/NodeDataWriter.java @@ -0,0 +1,322 @@ +/* + * 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.binding.celtix.io; + +import java.util.List; +import javax.xml.namespace.QName; +import javax.xml.stream.XMLStreamConstants; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamReader; + +import org.w3c.dom.Attr; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; + +import org.apache.tuscany.spi.wire.InvocationRuntimeException; + +import commonj.sdo.DataObject; +import commonj.sdo.Property; +import commonj.sdo.Type; +import commonj.sdo.helper.DataFactory; +import commonj.sdo.helper.TypeHelper; +import commonj.sdo.helper.XMLDocument; +import commonj.sdo.helper.XMLHelper; +import commonj.sdo.helper.XSDHelper; +import org.apache.tuscany.databinding.sdo.XMLDocument2XMLStreamReader; +import org.apache.tuscany.sdo.util.SDOUtil; +import org.objectweb.celtix.bindings.DataWriter; +import org.objectweb.celtix.context.ObjectMessageContext; + +public class NodeDataWriter implements DataWriter<Node> { + private static final String XML_NS = "http://www.w3.org/2000/xmlns/"; + private SCADataBindingCallback callback; + + public NodeDataWriter(SCADataBindingCallback cb) { + callback = cb; + } + + public void write(Object obj, Node output) { + write(obj, null, output); + } + + public void write(Object obj, QName elName, Node output) { + boolean isWrapped = false; + + XMLDocument document = toXMLDocument(callback.getTypeHelper(), new Object[]{obj}, elName, isWrapped); + // HACK: [rfeng] We should use the transformer in an interceptor + XMLDocument2XMLStreamReader transformer = new XMLDocument2XMLStreamReader(); + XMLStreamReader reader = transformer.transform(document, null); + + try { + //CeltixFire supports Stax, we should not need to do following anymore. + readDocElements(output, reader, true, null); + } catch (XMLStreamException e) { + throw new InvocationRuntimeException(e.getMessage()); + } + } + + public void writeWrapper(ObjectMessageContext objCtx, boolean isOutbound, Node output) { + boolean isWrapped = true; + QName wrapperName; + if (isOutbound) { + wrapperName = callback.getOperationInfo().getResponseWrapperQName(); + } else { + wrapperName = callback.getOperationInfo().getRequestWrapperQName(); + } + + XMLDocument document = toXMLDocument( + callback.getTypeHelper(), objCtx.getMessageObjects(), wrapperName, isWrapped); + // HACK: [rfeng] We should use the transformer in an interceptor + XMLDocument2XMLStreamReader transformer = new XMLDocument2XMLStreamReader(); + XMLStreamReader reader = transformer.transform(document, null); + + try { + readDocElements(output, reader, true, null); + } catch (XMLStreamException e) { + e.printStackTrace(); + throw new InvocationRuntimeException(e.getMessage()); + } + } +/* + private DataObject toWrappedDataObject(TypeHelper typeHelper, + Object ret, + Object[] os, + QName typeQN) { + XSDHelper xsdHelper = new XSDHelperImpl(typeHelper); + Property property = xsdHelper.getGlobalProperty(typeQN.getNamespaceURI(), + typeQN.getLocalPart(), true); + DataObject dataObject = new DataFactoryImpl(typeHelper).create(property.getType()); + List ips = dataObject.getInstanceProperties(); + int offset = 0; + if (ret != null) { + dataObject.set(0, ret); + offset = 1; + } + for (int i = offset; i < ips.size(); i++) { + if (os[i - offset] instanceof Holder) { + Holder<?> holder = (Holder<?>)os[i - offset]; + dataObject.set(i, holder.value); + } else { + dataObject.set(i, os[i - offset]); + } + } + return dataObject; + } +*/ + + /** + * Convert objects to typed DataObject + * + * @param typeHelper + * @param os + * @param elementQName + * @param isWrapped + * @return the DataObject + */ + private static XMLDocument toXMLDocument(TypeHelper typeHelper, + Object[] os, + QName elementQName, + boolean isWrapped) { + XSDHelper xsdHelper = SDOUtil.createXSDHelper(typeHelper); + + Property property = xsdHelper.getGlobalProperty( + elementQName.getNamespaceURI(), elementQName.getLocalPart(), true); + if (null == property) { + throw new InvocationRuntimeException( + "Type '" + elementQName.toString() + "' not found in registered SDO types."); + } + DataObject dataObject; + if (isWrapped) { + DataFactory dataFactory = SDOUtil.createDataFactory(typeHelper); + dataObject = dataFactory.create(property.getType()); + List ips = dataObject.getInstanceProperties(); + for (int i = 0; i < ips.size(); i++) { + dataObject.set(i, os[i]); + } + } else { + Object value = os[0]; + Type type = property.getType(); + if (!type.isDataType()) { + dataObject = (DataObject) value; + } else { + dataObject = SDOUtil.createDataTypeWrapper(type, value); + } + } + + XMLHelper xmlHelper = SDOUtil.createXMLHelper(typeHelper); + return xmlHelper.createDocument(dataObject, elementQName.getNamespaceURI(), elementQName.getLocalPart()); + + } + + //REVISIT: We should not need to do following anymore with CeltixFire. + //As CeltixFire supports stax directly. + + /** + * @param parent + * @param reader + * @param repairing + * @param stopAt: stop at the specified element + * @throws XMLStreamException + */ + public static void readDocElements(Node parent, XMLStreamReader reader, boolean repairing, QName stopAt) + throws XMLStreamException { + Document doc = getDocument(parent); + + int event = reader.getEventType(); + + while (reader.hasNext()) { + switch (event) { + case XMLStreamConstants.START_ELEMENT: + if (startElement(parent, reader, repairing, stopAt) == null) { + return; + } + if (parent instanceof Document && stopAt != null) { + if (reader.hasNext()) { + reader.next(); + } + return; + } + break; + case XMLStreamConstants.END_ELEMENT: + return; + case XMLStreamConstants.NAMESPACE: + break; + case XMLStreamConstants.ATTRIBUTE: + break; + case XMLStreamConstants.CHARACTERS: + if (parent != null) { + parent.appendChild(doc.createTextNode(reader.getText())); + } + + break; + case XMLStreamConstants.COMMENT: + if (parent != null) { + parent.appendChild(doc.createComment(reader.getText())); + } + + break; + case XMLStreamConstants.CDATA: + parent.appendChild(doc.createCDATASection(reader.getText())); + + break; + case XMLStreamConstants.PROCESSING_INSTRUCTION: + parent.appendChild(doc.createProcessingInstruction(reader.getPITarget(), reader.getPIData())); + + break; + case XMLStreamConstants.ENTITY_REFERENCE: + parent.appendChild(doc.createProcessingInstruction(reader.getPITarget(), reader.getPIData())); + + break; + default: + break; + } + + if (reader.hasNext()) { + event = reader.next(); + } + } + } + + private static Document getDocument(Node parent) { + return (parent instanceof Document) ? (Document) parent : parent.getOwnerDocument(); + } + + /** + * @param parent + * @param reader + * @return + * @throws XMLStreamException + */ + private static Element startElement(Node parent, XMLStreamReader reader, boolean repairing, QName stopAt) + throws XMLStreamException { + Document doc = getDocument(parent); + + if (stopAt != null && stopAt.getNamespaceURI().equals(reader.getNamespaceURI()) + && stopAt.getLocalPart().equals(reader.getLocalName())) { + return null; + } + + Element e = doc.createElementNS(reader.getNamespaceURI(), reader.getLocalName()); + + if (reader.getPrefix() != null) { + e.setPrefix(reader.getPrefix()); + } + + parent.appendChild(e); + + for (int ns = 0; ns < reader.getNamespaceCount(); ns++) { + String uri = reader.getNamespaceURI(ns); + String prefix = reader.getNamespacePrefix(ns); + + declare(e, uri, prefix); + } + + for (int att = 0; att < reader.getAttributeCount(); att++) { + String name = reader.getAttributeLocalName(att); + String prefix = reader.getAttributePrefix(att); + if (prefix != null && prefix.length() > 0) { + name = prefix + ":" + name; + } + + Attr attr = doc.createAttributeNS(reader.getAttributeNamespace(att), name); + attr.setValue(reader.getAttributeValue(att)); + e.setAttributeNode(attr); + } + + reader.next(); + + readDocElements(e, reader, repairing, stopAt); + + if (repairing && !isDeclared(e, reader.getNamespaceURI(), reader.getPrefix())) { + declare(e, reader.getNamespaceURI(), reader.getPrefix()); + } + + return e; + } + + private static void declare(Element node, String uri, String prefix) { + if (prefix != null && prefix.length() > 0) { + node.setAttributeNS(XML_NS, "xmlns:" + prefix, uri); + } else { + if (uri != null /* && uri.length() > 0 */) { + node.setAttributeNS(XML_NS, "xmlns", uri); + } + } + } + + private static boolean isDeclared(Element e, String namespaceURI, String prefix) { + Attr att; + if (prefix != null && prefix.length() > 0) { + att = e.getAttributeNodeNS(XML_NS, "xmlns:" + prefix); + } else { + att = e.getAttributeNode("xmlns"); + } + + if (att != null && att.getNodeValue().equals(namespaceURI)) { + return true; + } + + if (e.getParentNode() instanceof Element) { + return isDeclared((Element) e.getParentNode(), namespaceURI, prefix); + } + + return false; + } +} |