summaryrefslogtreecommitdiffstats
path: root/java/sca/modules/core-databinding
diff options
context:
space:
mode:
authordims <dims@13f79535-47bb-0310-9956-ffa450edef68>2008-06-17 00:23:01 +0000
committerdims <dims@13f79535-47bb-0310-9956-ffa450edef68>2008-06-17 00:23:01 +0000
commitbdd0a41aed7edf21ec2a65cfa17a86af2ef8c48a (patch)
tree38a92061c0793434c4be189f1d70c3458b6bc41d /java/sca/modules/core-databinding
Move Tuscany from Incubator to top level.
git-svn-id: http://svn.us.apache.org/repos/asf/tuscany@668359 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'java/sca/modules/core-databinding')
-rw-r--r--java/sca/modules/core-databinding/LICENSE205
-rw-r--r--java/sca/modules/core-databinding/NOTICE6
-rw-r--r--java/sca/modules/core-databinding/pom.xml102
-rw-r--r--java/sca/modules/core-databinding/src/main/java/org/apache/tuscany/sca/core/databinding/module/DataBindingModuleActivator.java102
-rw-r--r--java/sca/modules/core-databinding/src/main/java/org/apache/tuscany/sca/core/databinding/processor/DataBindingJavaInterfaceProcessor.java210
-rw-r--r--java/sca/modules/core-databinding/src/main/java/org/apache/tuscany/sca/core/databinding/transformers/Array2ArrayTransformer.java110
-rw-r--r--java/sca/modules/core-databinding/src/main/java/org/apache/tuscany/sca/core/databinding/transformers/CallableReference2XMLStreamReader.java75
-rw-r--r--java/sca/modules/core-databinding/src/main/java/org/apache/tuscany/sca/core/databinding/transformers/CallableReferenceDataBinding.java34
-rw-r--r--java/sca/modules/core-databinding/src/main/java/org/apache/tuscany/sca/core/databinding/transformers/CallableReferenceXMLAdapter.java61
-rw-r--r--java/sca/modules/core-databinding/src/main/java/org/apache/tuscany/sca/core/databinding/transformers/Exception2ExceptionTransformer.java114
-rw-r--r--java/sca/modules/core-databinding/src/main/java/org/apache/tuscany/sca/core/databinding/transformers/Input2InputTransformer.java277
-rw-r--r--java/sca/modules/core-databinding/src/main/java/org/apache/tuscany/sca/core/databinding/transformers/Output2OutputTransformer.java254
-rw-r--r--java/sca/modules/core-databinding/src/main/java/org/apache/tuscany/sca/core/databinding/transformers/XMLStreamReader2CallableReference.java100
-rw-r--r--java/sca/modules/core-databinding/src/main/java/org/apache/tuscany/sca/core/databinding/wire/DataBindingRuntimeWireProcessor.java186
-rw-r--r--java/sca/modules/core-databinding/src/main/java/org/apache/tuscany/sca/core/databinding/wire/DataTransformationInterceptor.java264
-rw-r--r--java/sca/modules/core-databinding/src/main/java/org/apache/tuscany/sca/core/databinding/wire/PassByValueInterceptor.java268
-rw-r--r--java/sca/modules/core-databinding/src/main/resources/META-INF/services/org.apache.tuscany.sca.core.ModuleActivator18
-rw-r--r--java/sca/modules/core-databinding/src/test/java/org/apache/tuscany/sca/core/databinding/processor/DataBindingJavaInterfaceProcessorTestCase.java89
-rw-r--r--java/sca/modules/core-databinding/src/test/java/org/apache/tuscany/sca/core/databinding/transformers/IDLTransformerTestCaseFIXME.java229
19 files changed, 2704 insertions, 0 deletions
diff --git a/java/sca/modules/core-databinding/LICENSE b/java/sca/modules/core-databinding/LICENSE
new file mode 100644
index 0000000000..8aa906c321
--- /dev/null
+++ b/java/sca/modules/core-databinding/LICENSE
@@ -0,0 +1,205 @@
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ 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.
+
+
+
diff --git a/java/sca/modules/core-databinding/NOTICE b/java/sca/modules/core-databinding/NOTICE
new file mode 100644
index 0000000000..fdfa0e9faa
--- /dev/null
+++ b/java/sca/modules/core-databinding/NOTICE
@@ -0,0 +1,6 @@
+${pom.name}
+Copyright (c) 2005 - 2008 The Apache Software Foundation
+
+This product includes software developed by
+The Apache Software Foundation (http://www.apache.org/).
+
diff --git a/java/sca/modules/core-databinding/pom.xml b/java/sca/modules/core-databinding/pom.xml
new file mode 100644
index 0000000000..5d69791f30
--- /dev/null
+++ b/java/sca/modules/core-databinding/pom.xml
@@ -0,0 +1,102 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ * 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.
+-->
+<project>
+ <parent>
+ <groupId>org.apache.tuscany.sca</groupId>
+ <artifactId>tuscany-modules</artifactId>
+ <version>1.4-SNAPSHOT</version>
+ <relativePath>../pom.xml</relativePath>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>org.apache.tuscany.sca</groupId>
+ <artifactId>tuscany-core-databinding</artifactId>
+ <packaging>jar</packaging>
+ <name>Apache Tuscany SCA Core/DataBinding Integration</name>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.tuscany.sca</groupId>
+ <artifactId>tuscany-databinding</artifactId>
+ <version>${project.version}</version>
+ <scope>compile</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.tuscany.sca</groupId>
+ <artifactId>tuscany-databinding-jaxb</artifactId>
+ <version>${project.version}</version>
+ <scope>compile</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.tuscany.sca</groupId>
+ <artifactId>tuscany-core</artifactId>
+ <version>${project.version}</version>
+ <scope>compile</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.tuscany.sca</groupId>
+ <artifactId>tuscany-core-spi</artifactId>
+ <version>${project.version}</version>
+ <scope>compile</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.tuscany.sca</groupId>
+ <artifactId>tuscany-interface-java-xml</artifactId>
+ <version>${project.version}</version>
+ <scope>compile</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.tuscany.sca</groupId>
+ <artifactId>tuscany-interface-java-jaxws</artifactId>
+ <version>${project.version}</version>
+ <scope>compile</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>org.codehaus.woodstox</groupId>
+ <artifactId>wstx-asl</artifactId>
+ <scope>runtime</scope>
+ <version>3.2.1</version>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>maven-bundle-plugin</artifactId>
+
+ <configuration>
+ <instructions>
+ <Bundle-Version>${tuscany.version}</Bundle-Version>
+ <Bundle-SymbolicName>org.apache.tuscany.sca.core.databinding</Bundle-SymbolicName>
+ <Bundle-Description>${pom.name}</Bundle-Description>
+ <Export-Package>org.apache.tuscany.sca.core.databinding*</Export-Package>
+ </instructions>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+
+</project>
diff --git a/java/sca/modules/core-databinding/src/main/java/org/apache/tuscany/sca/core/databinding/module/DataBindingModuleActivator.java b/java/sca/modules/core-databinding/src/main/java/org/apache/tuscany/sca/core/databinding/module/DataBindingModuleActivator.java
new file mode 100644
index 0000000000..2056789089
--- /dev/null
+++ b/java/sca/modules/core-databinding/src/main/java/org/apache/tuscany/sca/core/databinding/module/DataBindingModuleActivator.java
@@ -0,0 +1,102 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tuscany.sca.core.databinding.module;
+
+import org.apache.tuscany.sca.contribution.ModelFactoryExtensionPoint;
+import org.apache.tuscany.sca.core.ExtensionPointRegistry;
+import org.apache.tuscany.sca.core.ModuleActivator;
+import org.apache.tuscany.sca.core.databinding.processor.DataBindingJavaInterfaceProcessor;
+import org.apache.tuscany.sca.core.databinding.transformers.Array2ArrayTransformer;
+import org.apache.tuscany.sca.core.databinding.transformers.CallableReference2XMLStreamReader;
+import org.apache.tuscany.sca.core.databinding.transformers.CallableReferenceDataBinding;
+import org.apache.tuscany.sca.core.databinding.transformers.CallableReferenceXMLAdapter;
+import org.apache.tuscany.sca.core.databinding.transformers.Exception2ExceptionTransformer;
+import org.apache.tuscany.sca.core.databinding.transformers.Input2InputTransformer;
+import org.apache.tuscany.sca.core.databinding.transformers.Output2OutputTransformer;
+import org.apache.tuscany.sca.core.databinding.transformers.XMLStreamReader2CallableReference;
+import org.apache.tuscany.sca.core.databinding.wire.DataBindingRuntimeWireProcessor;
+import org.apache.tuscany.sca.databinding.DataBindingExtensionPoint;
+import org.apache.tuscany.sca.databinding.TransformerExtensionPoint;
+import org.apache.tuscany.sca.databinding.impl.Group2GroupTransformer;
+import org.apache.tuscany.sca.databinding.impl.MediatorImpl;
+import org.apache.tuscany.sca.databinding.jaxb.XMLAdapterExtensionPoint;
+import org.apache.tuscany.sca.interfacedef.FaultExceptionMapper;
+import org.apache.tuscany.sca.interfacedef.java.JavaInterfaceFactory;
+import org.apache.tuscany.sca.interfacedef.java.jaxws.JAXWSFaultExceptionMapper;
+import org.apache.tuscany.sca.interfacedef.java.jaxws.JAXWSJavaInterfaceProcessor;
+import org.apache.tuscany.sca.runtime.RuntimeWireProcessorExtensionPoint;
+import org.osoa.sca.CallableReference;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class DataBindingModuleActivator implements ModuleActivator {
+
+ public void start(ExtensionPointRegistry registry) {
+ DataBindingExtensionPoint dataBindings = registry.getExtensionPoint(DataBindingExtensionPoint.class);
+ TransformerExtensionPoint transformers = registry.getExtensionPoint(TransformerExtensionPoint.class);
+
+ XMLAdapterExtensionPoint xmlAdapterExtensionPoint = registry.getExtensionPoint(XMLAdapterExtensionPoint.class);
+ xmlAdapterExtensionPoint.addAdapter(CallableReference.class, CallableReferenceXMLAdapter.class);
+ FaultExceptionMapper faultExceptionMapper = new JAXWSFaultExceptionMapper(dataBindings, xmlAdapterExtensionPoint);
+
+ MediatorImpl mediator = new MediatorImpl(dataBindings, transformers);
+ Input2InputTransformer input2InputTransformer = new Input2InputTransformer();
+ input2InputTransformer.setMediator(mediator);
+ transformers.addTransformer(input2InputTransformer, true);
+
+ Output2OutputTransformer output2OutputTransformer = new Output2OutputTransformer();
+ output2OutputTransformer.setMediator(mediator);
+ transformers.addTransformer(output2OutputTransformer, true);
+
+ Exception2ExceptionTransformer exception2ExceptionTransformer = new Exception2ExceptionTransformer(mediator, faultExceptionMapper);
+ transformers.addTransformer(exception2ExceptionTransformer, false);
+
+ Array2ArrayTransformer array2ArrayTransformer = new Array2ArrayTransformer();
+ array2ArrayTransformer.setMediator(mediator);
+ transformers.addTransformer(array2ArrayTransformer, true);
+
+ Group2GroupTransformer group2GroupTransformer = new Group2GroupTransformer();
+ group2GroupTransformer.setMediator(mediator);
+ transformers.addTransformer(group2GroupTransformer, true);
+
+ dataBindings.addDataBinding(new CallableReferenceDataBinding());
+ transformers.addTransformer(new CallableReference2XMLStreamReader(), true);
+ transformers.addTransformer(new XMLStreamReader2CallableReference(), false);
+
+ ModelFactoryExtensionPoint modelFactories = registry.getExtensionPoint(ModelFactoryExtensionPoint.class);
+ JavaInterfaceFactory javaFactory = modelFactories.getFactory(JavaInterfaceFactory.class);
+
+ // [rfeng] The JAX-WS processor should come before the Databinding processor to make sure @WebService
+ // is honored as Remoteable
+ javaFactory.addInterfaceVisitor(new JAXWSJavaInterfaceProcessor(dataBindings, faultExceptionMapper, xmlAdapterExtensionPoint));
+
+ javaFactory.addInterfaceVisitor(new DataBindingJavaInterfaceProcessor(dataBindings));
+
+ RuntimeWireProcessorExtensionPoint wireProcessorExtensionPoint = registry.getExtensionPoint(RuntimeWireProcessorExtensionPoint.class);
+ if (wireProcessorExtensionPoint != null) {
+ wireProcessorExtensionPoint.addWireProcessor(new DataBindingRuntimeWireProcessor(mediator, dataBindings, faultExceptionMapper));
+ }
+
+ }
+
+ public void stop(ExtensionPointRegistry registry) {
+ }
+}
diff --git a/java/sca/modules/core-databinding/src/main/java/org/apache/tuscany/sca/core/databinding/processor/DataBindingJavaInterfaceProcessor.java b/java/sca/modules/core-databinding/src/main/java/org/apache/tuscany/sca/core/databinding/processor/DataBindingJavaInterfaceProcessor.java
new file mode 100644
index 0000000000..e182b472d4
--- /dev/null
+++ b/java/sca/modules/core-databinding/src/main/java/org/apache/tuscany/sca/core/databinding/processor/DataBindingJavaInterfaceProcessor.java
@@ -0,0 +1,210 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tuscany.sca.core.databinding.processor;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Method;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.tuscany.sca.databinding.DataBindingExtensionPoint;
+import org.apache.tuscany.sca.databinding.WrapperHandler;
+import org.apache.tuscany.sca.databinding.annotation.DataBinding;
+import org.apache.tuscany.sca.databinding.javabeans.JavaBeansDataBinding;
+import org.apache.tuscany.sca.databinding.javabeans.SimpleJavaDataBinding;
+import org.apache.tuscany.sca.interfacedef.DataType;
+import org.apache.tuscany.sca.interfacedef.InvalidInterfaceException;
+import org.apache.tuscany.sca.interfacedef.Operation;
+import org.apache.tuscany.sca.interfacedef.java.JavaInterface;
+import org.apache.tuscany.sca.interfacedef.java.JavaOperation;
+import org.apache.tuscany.sca.interfacedef.java.introspect.JavaInterfaceVisitor;
+import org.apache.tuscany.sca.interfacedef.util.WrapperInfo;
+
+/**
+ * The databinding annotation processor for java interfaces
+ *
+ * @version $Rev$ $Date$
+ */
+public class DataBindingJavaInterfaceProcessor implements JavaInterfaceVisitor {
+ private static final String JAXB_DATABINDING = "javax.xml.bind.JAXBElement";
+ private DataBindingExtensionPoint dataBindingRegistry;
+
+ public DataBindingJavaInterfaceProcessor(DataBindingExtensionPoint dataBindingRegistry) {
+ super();
+ this.dataBindingRegistry = dataBindingRegistry;
+ }
+
+ public void visitInterface(JavaInterface javaInterface) throws InvalidInterfaceException {
+ if (!javaInterface.isRemotable()) {
+ return;
+ }
+ List<Operation> operations = javaInterface.getOperations();
+ processInterface(javaInterface, operations);
+ }
+
+ private void processInterface(JavaInterface javaInterface, List<Operation> operations) {
+ Class<?> clazz = javaInterface.getJavaClass();
+ DataBinding dataBinding = clazz.getAnnotation(DataBinding.class);
+ String dataBindingId = null;
+ boolean wrapperStyle = false;
+ if (dataBinding != null) {
+ dataBindingId = dataBinding.value();
+ wrapperStyle = dataBinding.wrapped();
+ }
+
+ Map<String, Operation> opMap = new HashMap<String, Operation>();
+ for (Operation op : javaInterface.getOperations()) {
+ opMap.put(op.getName(), op);
+ // In the case of @WebMethod, the method name can be different from the operation name
+ if (op instanceof JavaOperation) {
+ opMap.put(((JavaOperation)op).getJavaMethod().getName(), op);
+ }
+ if (dataBindingId != null) {
+ op.setDataBinding(dataBindingId);
+ op.setWrapperStyle(wrapperStyle);
+ }
+ }
+ for (Method method : clazz.getMethods()) {
+ if (method.getDeclaringClass() == Object.class) {
+ continue;
+ }
+ Operation operation = opMap.get(method.getName());
+ if (operation == null) { // @WebMethod exclude=true
+ continue;
+ }
+ DataBinding methodDataBinding = clazz.getAnnotation(DataBinding.class);
+ if (methodDataBinding == null) {
+ methodDataBinding = dataBinding;
+ }
+ dataBindingId = null;
+ wrapperStyle = false;
+ if (dataBinding != null) {
+ dataBindingId = dataBinding.value();
+ wrapperStyle = dataBinding.wrapped();
+ operation.setDataBinding(dataBindingId);
+ operation.setWrapperStyle(wrapperStyle);
+ }
+
+ // FIXME: We need a better way to identify simple java types
+ int i = 0;
+ for (org.apache.tuscany.sca.interfacedef.DataType<?> d : operation.getInputType().getLogical()) {
+ if (d.getDataBinding() == null) {
+ d.setDataBinding(dataBindingId);
+ }
+ for (Annotation a : method.getParameterAnnotations()[i]) {
+ if (a.annotationType() == org.apache.tuscany.sca.databinding.annotation.DataType.class) {
+ String value = ((org.apache.tuscany.sca.databinding.annotation.DataType)a).value();
+ d.setDataBinding(value);
+ }
+ }
+ dataBindingRegistry.introspectType(d, operation);
+ i++;
+ }
+ if (operation.getOutputType() != null) {
+ DataType<?> d = operation.getOutputType();
+ if (d.getDataBinding() == null) {
+ d.setDataBinding(dataBindingId);
+ }
+ org.apache.tuscany.sca.databinding.annotation.DataType dt =
+ method.getAnnotation(org.apache.tuscany.sca.databinding.annotation.DataType.class);
+ if (dt != null) {
+ d.setDataBinding(dt.value());
+ }
+ dataBindingRegistry.introspectType(d, operation);
+ }
+ for (org.apache.tuscany.sca.interfacedef.DataType<?> d : operation.getFaultTypes()) {
+ if (d.getDataBinding() == null) {
+ d.setDataBinding(dataBindingId);
+ }
+ // TODO: Handle exceptions
+ dataBindingRegistry.introspectType(d, operation);
+ }
+
+ // JIRA: TUSCANY-842
+ String db = operation.getDataBinding();
+ if (db == null || JAXB_DATABINDING.equals(db)) {
+ assignOperationDataBinding(operation);
+ db = operation.getDataBinding();
+ }
+
+ // Introspect the wrapper data type
+ if (operation.getWrapper() != null) {
+ org.apache.tuscany.sca.databinding.DataBinding dbObj =
+ dataBindingRegistry.getDataBinding(db);
+ WrapperHandler handler = dbObj == null ? null : dbObj.getWrapperHandler();
+ if (handler != null) {
+ WrapperInfo wrapper = operation.getWrapper();
+ wrapper.setInputWrapperType(handler.getWrapperType(operation, true));
+ wrapper.setOutputWrapperType(handler.getWrapperType(operation, false));
+ }
+ if (dbObj != null && handler == null) {
+ // To avoid JAXB wrapper bean generation
+ WrapperInfo wrapper = operation.getWrapper();
+ wrapper.setInputWrapperType(null);
+ wrapper.setOutputWrapperType(null);
+ }
+ }
+ }
+ }
+
+ /*
+ * Assigns an operation DB if one of the input types, output type, fault types has a non-default DB.
+ * However, if two of the input types, output type, fault types have two different non-default DBs
+ * ( e.g. SDO and JAXB), then we do nothing to the operation DB.
+ *
+ * The method logic assumes the JavaBeans DataBinding is the default
+ */
+ private void assignOperationDataBinding(Operation operation) {
+
+ Set<String> dbs = new HashSet<String>();
+
+ // Can't use DataType<?> since operation.getInputType() returns: DataType<List<DataType>>
+ List<DataType> opDataTypes = new LinkedList<DataType>();
+
+ opDataTypes.addAll(operation.getInputType().getLogical());
+ opDataTypes.add(operation.getOutputType());
+ for (DataType<DataType> ft : operation.getFaultTypes()) {
+ opDataTypes.add(ft.getLogical());
+ }
+
+ for (DataType<?> d : opDataTypes) {
+ if (d != null) {
+ String dataBinding = d.getDataBinding();
+ if ("java:array".equals(dataBinding)) {
+ dataBinding = ((DataType)d.getLogical()).getDataBinding();
+ }
+ if (dataBinding != null) {
+ dbs.add(dataBinding);
+ }
+ }
+ }
+
+ dbs.remove(JavaBeansDataBinding.NAME);
+ dbs.remove(SimpleJavaDataBinding.NAME);
+
+ if (dbs.size() == 1) {
+ operation.setDataBinding(dbs.iterator().next());
+ }
+ }
+}
diff --git a/java/sca/modules/core-databinding/src/main/java/org/apache/tuscany/sca/core/databinding/transformers/Array2ArrayTransformer.java b/java/sca/modules/core-databinding/src/main/java/org/apache/tuscany/sca/core/databinding/transformers/Array2ArrayTransformer.java
new file mode 100644
index 0000000000..38ca2cd10c
--- /dev/null
+++ b/java/sca/modules/core-databinding/src/main/java/org/apache/tuscany/sca/core/databinding/transformers/Array2ArrayTransformer.java
@@ -0,0 +1,110 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.sca.core.databinding.transformers;
+
+import java.lang.reflect.Array;
+
+import org.apache.tuscany.sca.databinding.Mediator;
+import org.apache.tuscany.sca.databinding.PullTransformer;
+import org.apache.tuscany.sca.databinding.TransformationContext;
+import org.apache.tuscany.sca.databinding.TransformationException;
+import org.apache.tuscany.sca.databinding.impl.BaseTransformer;
+import org.apache.tuscany.sca.interfacedef.DataType;
+import org.osoa.sca.annotations.Reference;
+
+/**
+ * This is a special transformer to transform the output from one IDL to the
+ * other one
+ *
+ * @version $Rev$ $Date$
+ */
+public class Array2ArrayTransformer extends BaseTransformer<Object, Object> implements PullTransformer<Object, Object> {
+
+ protected Mediator mediator;
+
+ public Array2ArrayTransformer() {
+ super();
+ }
+
+ /**
+ * @param mediator the mediator to set
+ */
+ @Reference
+ public void setMediator(Mediator mediator) {
+ this.mediator = mediator;
+ }
+
+ @Override
+ public String getSourceDataBinding() {
+ return "java:array";
+ }
+
+ @Override
+ public String getTargetDataBinding() {
+ return "java:array";
+ }
+
+ /**
+ * @see org.apache.tuscany.sca.databinding.impl.BaseTransformer#getSourceType()
+ */
+ @Override
+ protected Class<Object> getSourceType() {
+ return Object.class;
+ }
+
+ /**
+ * @see org.apache.tuscany.sca.databinding.impl.BaseTransformer#getTargetType()
+ */
+ @Override
+ protected Class<Object> getTargetType() {
+ return Object.class;
+ }
+
+ /**
+ * @see org.apache.tuscany.sca.databinding.Transformer#getWeight()
+ */
+ @Override
+ public int getWeight() {
+ return 10;
+ }
+
+ @SuppressWarnings("unchecked")
+ public Object transform(Object array, TransformationContext context) {
+ try {
+ if (array == null) {
+ return null;
+ }
+ DataType<DataType> sourceType = context.getSourceDataType();
+ DataType<DataType> targetType = context.getTargetDataType();
+ int length = Array.getLength(array);
+ Object targetArray = Array.newInstance(targetType.getPhysical().getComponentType(), length);
+ for (int i = 0; i < length; i++) {
+ Object sourceItem = Array.get(array, i);
+ Object targetItem =
+ mediator.mediate(sourceItem, sourceType.getLogical(), targetType.getLogical(), context
+ .getMetadata());
+ Array.set(targetArray, i, targetItem);
+ }
+ return targetArray;
+ } catch (Exception e) {
+ throw new TransformationException(e);
+ }
+ }
+
+}
diff --git a/java/sca/modules/core-databinding/src/main/java/org/apache/tuscany/sca/core/databinding/transformers/CallableReference2XMLStreamReader.java b/java/sca/modules/core-databinding/src/main/java/org/apache/tuscany/sca/core/databinding/transformers/CallableReference2XMLStreamReader.java
new file mode 100644
index 0000000000..124928db24
--- /dev/null
+++ b/java/sca/modules/core-databinding/src/main/java/org/apache/tuscany/sca/core/databinding/transformers/CallableReference2XMLStreamReader.java
@@ -0,0 +1,75 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.sca.core.databinding.transformers;
+
+import javax.xml.stream.XMLStreamReader;
+
+import org.apache.tuscany.sca.core.context.CallableReferenceImpl;
+import org.apache.tuscany.sca.databinding.PullTransformer;
+import org.apache.tuscany.sca.databinding.TransformationContext;
+import org.apache.tuscany.sca.databinding.TransformationException;
+import org.apache.tuscany.sca.databinding.impl.BaseTransformer;
+import org.apache.tuscany.sca.databinding.xml.StAXHelper;
+import org.osoa.sca.CallableReference;
+
+public class CallableReference2XMLStreamReader extends BaseTransformer<CallableReference, XMLStreamReader> implements
+ PullTransformer<CallableReference, XMLStreamReader> {
+
+ @Override
+ protected Class<CallableReference> getSourceType() {
+ return CallableReference.class;
+ }
+
+ @Override
+ protected Class<XMLStreamReader> getTargetType() {
+ return XMLStreamReader.class;
+ }
+
+ public XMLStreamReader transform(CallableReference source, TransformationContext context) {
+ try {
+ if (source != null) {
+ if (source instanceof CallableReferenceImpl) {
+ XMLStreamReader xmlReader = ((CallableReferenceImpl)source).getXMLReader();
+ if (xmlReader != null) {
+ return xmlReader;
+ } else {
+ String xmlString = ((CallableReferenceImpl)source).toXMLString();
+
+ // remove "<?xml...?>" processing instruction and wrap with a top-level element
+ return StAXHelper.createXMLStreamReader("<reference xmlns=\"http://callable\">"
+ + xmlString.substring(xmlString.indexOf("?>") + 2)
+ + "</reference>");
+ }
+ } else {
+ throw new TransformationException("Unrecognized transformation source object");
+ }
+ } else {
+ return null;
+ }
+ } catch (Exception e) {
+ throw new TransformationException(e);
+ }
+ }
+
+ @Override
+ public int getWeight() {
+ return 10;
+ }
+
+}
diff --git a/java/sca/modules/core-databinding/src/main/java/org/apache/tuscany/sca/core/databinding/transformers/CallableReferenceDataBinding.java b/java/sca/modules/core-databinding/src/main/java/org/apache/tuscany/sca/core/databinding/transformers/CallableReferenceDataBinding.java
new file mode 100644
index 0000000000..7384b8a31d
--- /dev/null
+++ b/java/sca/modules/core-databinding/src/main/java/org/apache/tuscany/sca/core/databinding/transformers/CallableReferenceDataBinding.java
@@ -0,0 +1,34 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tuscany.sca.core.databinding.transformers;
+
+import org.apache.tuscany.sca.databinding.impl.BaseDataBinding;
+import org.osoa.sca.CallableReference;
+
+public class CallableReferenceDataBinding extends BaseDataBinding {
+
+ public static final String NAME = CallableReference.class.getName();
+ public static final String[] ALIASES = new String[] {"callablereference"};
+
+ public CallableReferenceDataBinding() {
+ super(NAME, ALIASES, CallableReference.class);
+ }
+
+}
diff --git a/java/sca/modules/core-databinding/src/main/java/org/apache/tuscany/sca/core/databinding/transformers/CallableReferenceXMLAdapter.java b/java/sca/modules/core-databinding/src/main/java/org/apache/tuscany/sca/core/databinding/transformers/CallableReferenceXMLAdapter.java
new file mode 100644
index 0000000000..ff6e444dcd
--- /dev/null
+++ b/java/sca/modules/core-databinding/src/main/java/org/apache/tuscany/sca/core/databinding/transformers/CallableReferenceXMLAdapter.java
@@ -0,0 +1,61 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tuscany.sca.core.databinding.transformers;
+
+import java.io.StringReader;
+import java.io.StringWriter;
+
+import javax.xml.bind.annotation.adapters.XmlAdapter;
+import javax.xml.stream.XMLInputFactory;
+import javax.xml.stream.XMLStreamReader;
+import javax.xml.transform.Source;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.stream.StreamResult;
+import javax.xml.transform.stream.StreamSource;
+
+import org.apache.tuscany.sca.databinding.xml.XMLStreamReader2String;
+import org.osoa.sca.CallableReference;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class CallableReferenceXMLAdapter extends XmlAdapter<Source, CallableReference> {
+ private TransformerFactory transformerFactory = TransformerFactory.newInstance();
+ private XMLInputFactory inputFactory = XMLInputFactory.newInstance();
+
+ @Override
+ public CallableReference unmarshal(Source v) throws Exception {
+ StringWriter sw = new StringWriter();
+ StreamResult result = new StreamResult(sw);
+ transformerFactory.newTransformer().transform(v, result);
+ XMLStreamReader reader = inputFactory.createXMLStreamReader(new StringReader(sw.toString()));
+ XMLStreamReader2CallableReference t2 = new XMLStreamReader2CallableReference();
+ return t2.transform(reader, null);
+ }
+
+ @Override
+ public Source marshal(CallableReference v) throws Exception {
+ CallableReference2XMLStreamReader t = new CallableReference2XMLStreamReader();
+ XMLStreamReader reader = t.transform(v, null);
+ XMLStreamReader2String t2 = new XMLStreamReader2String();
+ String xml = t2.transform(reader, null);
+ return new StreamSource(new StringReader(xml));
+ }
+}
diff --git a/java/sca/modules/core-databinding/src/main/java/org/apache/tuscany/sca/core/databinding/transformers/Exception2ExceptionTransformer.java b/java/sca/modules/core-databinding/src/main/java/org/apache/tuscany/sca/core/databinding/transformers/Exception2ExceptionTransformer.java
new file mode 100644
index 0000000000..6e2e714bdb
--- /dev/null
+++ b/java/sca/modules/core-databinding/src/main/java/org/apache/tuscany/sca/core/databinding/transformers/Exception2ExceptionTransformer.java
@@ -0,0 +1,114 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tuscany.sca.core.databinding.transformers;
+
+import org.apache.tuscany.sca.databinding.DataBinding;
+import org.apache.tuscany.sca.databinding.Mediator;
+import org.apache.tuscany.sca.databinding.PullTransformer;
+import org.apache.tuscany.sca.databinding.TransformationContext;
+import org.apache.tuscany.sca.databinding.impl.BaseTransformer;
+import org.apache.tuscany.sca.interfacedef.DataType;
+import org.apache.tuscany.sca.interfacedef.FaultExceptionMapper;
+
+/**
+ * This is a special transformer to transform the exception from one IDL to the
+ * other one
+ *
+ * @version $Rev$ $Date$
+ */
+public class Exception2ExceptionTransformer extends BaseTransformer<Throwable, Throwable> implements
+ PullTransformer<Throwable, Throwable> {
+
+ protected Mediator mediator;
+ protected FaultExceptionMapper faultExceptionMapper;
+
+ public Exception2ExceptionTransformer(Mediator mediator, FaultExceptionMapper faultExceptionMapper) {
+ super();
+ this.mediator = mediator;
+ this.faultExceptionMapper = faultExceptionMapper;
+ }
+
+ public Exception2ExceptionTransformer() {
+ super();
+ }
+
+ @Override
+ public String getSourceDataBinding() {
+ return DataBinding.IDL_FAULT;
+ }
+
+ @Override
+ public String getTargetDataBinding() {
+ return DataBinding.IDL_FAULT;
+ }
+
+ /**
+ * @param mediator the mediator to set
+ */
+ public void setMediator(Mediator mediator) {
+ this.mediator = mediator;
+ }
+
+ /**
+ * @see org.apache.tuscany.sca.databinding.impl.BaseTransformer#getSourceType()
+ */
+ @Override
+ protected Class<Throwable> getSourceType() {
+ return Throwable.class;
+ }
+
+ /**
+ * @see org.apache.tuscany.sca.databinding.impl.BaseTransformer#getTargetType()
+ */
+ @Override
+ protected Class<Throwable> getTargetType() {
+ return Throwable.class;
+ }
+
+ /**
+ * @see org.apache.tuscany.sca.databinding.Transformer#getWeight()
+ */
+ @Override
+ public int getWeight() {
+ return 10000;
+ }
+
+ @SuppressWarnings("unchecked")
+ public Throwable transform(Throwable source, TransformationContext context) {
+ DataType<DataType> sourceType = context.getSourceDataType();
+
+ DataType<DataType> targetType = context.getTargetDataType();
+
+ Object sourceFaultInfo = faultExceptionMapper.getFaultInfo(source, sourceType.getLogical().getPhysical(), context.getSourceOperation());
+ Object targetFaultInfo =
+ mediator.mediate(sourceFaultInfo, sourceType.getLogical(), targetType.getLogical(), context.getMetadata());
+
+ Throwable targetException =
+ faultExceptionMapper.wrapFaultInfo(targetType, source.getMessage(), targetFaultInfo, source.getCause(), context.getTargetOperation());
+
+ // FIXME
+ return targetException == null ? source : targetException;
+
+ }
+
+ public void setFaultExceptionMapper(FaultExceptionMapper faultExceptionMapper) {
+ this.faultExceptionMapper = faultExceptionMapper;
+ }
+}
diff --git a/java/sca/modules/core-databinding/src/main/java/org/apache/tuscany/sca/core/databinding/transformers/Input2InputTransformer.java b/java/sca/modules/core-databinding/src/main/java/org/apache/tuscany/sca/core/databinding/transformers/Input2InputTransformer.java
new file mode 100644
index 0000000000..71694c0a0a
--- /dev/null
+++ b/java/sca/modules/core-databinding/src/main/java/org/apache/tuscany/sca/core/databinding/transformers/Input2InputTransformer.java
@@ -0,0 +1,277 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tuscany.sca.core.databinding.transformers;
+
+import java.util.List;
+import java.util.logging.Logger;
+
+import org.apache.tuscany.sca.databinding.DataBinding;
+import org.apache.tuscany.sca.databinding.Mediator;
+import org.apache.tuscany.sca.databinding.PullTransformer;
+import org.apache.tuscany.sca.databinding.TransformationContext;
+import org.apache.tuscany.sca.databinding.TransformationException;
+import org.apache.tuscany.sca.databinding.WrapperHandler;
+import org.apache.tuscany.sca.databinding.impl.BaseTransformer;
+import org.apache.tuscany.sca.interfacedef.DataType;
+import org.apache.tuscany.sca.interfacedef.Operation;
+import org.apache.tuscany.sca.interfacedef.util.ElementInfo;
+import org.apache.tuscany.sca.interfacedef.util.WrapperInfo;
+import org.apache.tuscany.sca.interfacedef.util.XMLType;
+import org.osoa.sca.annotations.Reference;
+
+/**
+ * This is a special transformer to transform the input from one IDL to the
+ * other one
+ *
+ * @version $Rev$ $Date$
+ */
+public class Input2InputTransformer extends BaseTransformer<Object[], Object[]> implements
+ PullTransformer<Object[], Object[]> {
+ private static final Logger logger = Logger.getLogger(Input2InputTransformer.class.getName());
+
+ protected Mediator mediator;
+
+ public Input2InputTransformer() {
+ super();
+ }
+
+ @Override
+ public String getSourceDataBinding() {
+ return DataBinding.IDL_INPUT;
+ }
+
+ @Override
+ public String getTargetDataBinding() {
+ return DataBinding.IDL_INPUT;
+ }
+
+ /**
+ * @param mediator the mediator to set
+ */
+ @Reference
+ public void setMediator(Mediator mediator) {
+ this.mediator = mediator;
+ }
+
+ /**
+ * @see org.apache.tuscany.sca.databinding.impl.BaseTransformer#getSourceType()
+ */
+ @Override
+ protected Class<Object[]> getSourceType() {
+ return Object[].class;
+ }
+
+ /**
+ * @see org.apache.tuscany.sca.databinding.impl.BaseTransformer#getTargetType()
+ */
+ @Override
+ protected Class<Object[]> getTargetType() {
+ return Object[].class;
+ }
+
+ /**
+ * @see org.apache.tuscany.sca.databinding.Transformer#getWeight()
+ */
+ @Override
+ public int getWeight() {
+ return 10000;
+ }
+
+ /**
+ * Match the structure of the wrapper element. If it matches, then we can do
+ * wrapper to wrapper transformation. Otherwise, we do child to child.
+ * @param w1
+ * @param w2
+ * @return
+ */
+ private boolean matches(WrapperInfo w1, WrapperInfo w2) {
+ if (w1 == null || w2 == null) {
+ return false;
+ }
+ if (!w1.getInputWrapperElement().equals(w2.getInputWrapperElement())) {
+ return false;
+ }
+
+ // Compare the child elements
+ List<ElementInfo> list1 = w1.getInputChildElements();
+ List<ElementInfo> list2 = w2.getInputChildElements();
+ if (list1.size() != list2.size()) {
+ return false;
+ }
+ // FXIME: [rfeng] At this point, the J2W generates local elments under the namespace
+ // of the interface instead of "". We only compare the local parts only to work around
+ // the namespace mismatch
+ for (int i = 0; i < list1.size(); i++) {
+ String n1 = list1.get(i).getQName().getLocalPart();
+ String n2 = list2.get(i).getQName().getLocalPart();
+ if (!n1.equals(n2)) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ @SuppressWarnings("unchecked")
+ public Object[] transform(Object[] source, TransformationContext context) {
+ // Check if the source operation is wrapped
+ DataType<List<DataType>> sourceType = context.getSourceDataType();
+ Operation sourceOp = context.getSourceOperation();
+ boolean sourceWrapped = sourceOp != null && sourceOp.isWrapperStyle();
+
+ // Find the wrapper handler for source data
+ WrapperHandler sourceWrapperHandler = null;
+ String sourceDataBinding = getDataBinding(sourceOp);
+ sourceWrapperHandler = getWrapperHandler(sourceDataBinding, sourceWrapped);
+
+ // Check if the target operation is wrapped
+ DataType<List<DataType>> targetType = context.getTargetDataType();
+ Operation targetOp = (Operation)context.getTargetOperation();
+ boolean targetWrapped = targetOp != null && targetOp.isWrapperStyle();
+
+ // Find the wrapper handler for target data
+ WrapperHandler targetWrapperHandler = null;
+ String targetDataBinding = getDataBinding(targetOp);
+ targetWrapperHandler = getWrapperHandler(targetDataBinding, targetWrapped);
+
+ if ((!sourceWrapped) && targetWrapped) {
+ // Unwrapped --> Wrapped
+ WrapperInfo wrapper = targetOp.getWrapper();
+ ElementInfo wrapperElement = wrapper.getInputWrapperElement();
+
+ Class<?> targetWrapperClass = wrapper != null ? wrapper.getInputWrapperClass() : null;
+
+ if (source == null) {
+ // Empty child elements
+ Object targetWrapper = targetWrapperHandler.create(targetOp, true);
+ return new Object[] {targetWrapper};
+ }
+
+ // If the source can be wrapped, wrapped it first
+ if (sourceWrapperHandler != null) {
+ WrapperInfo sourceWrapperInfo = sourceOp.getWrapper();
+ DataType sourceWrapperType = sourceWrapperInfo != null ? sourceWrapperInfo.getInputWrapperType() : null;
+
+ // We only do wrapper to wrapper transformation if the source has a wrapper and both sides
+ // match by XML structure
+ if (sourceWrapperType != null && matches(sourceOp.getWrapper(), targetOp.getWrapper())) {
+ Class<?> sourceWrapperClass = sourceWrapperType.getPhysical();
+
+ // Create the source wrapper
+ Object sourceWrapper = sourceWrapperHandler.create(sourceOp, true);
+
+ // Populate the source wrapper
+ if (sourceWrapper != null) {
+ sourceWrapperHandler.setChildren(sourceWrapper,
+ source,
+ sourceOp,
+ true);
+
+ // Transform the data from source wrapper to target wrapper
+ Object targetWrapper =
+ mediator.mediate(sourceWrapper, sourceWrapperType, targetType.getLogical().get(0), context
+ .getMetadata());
+ return new Object[] {targetWrapper};
+ }
+ }
+ }
+ // Fall back to child by child transformation
+ Object targetWrapper = targetWrapperHandler.create(targetOp, true);
+ List<DataType> argTypes = wrapper.getUnwrappedInputType().getLogical();
+ Object[] targetChildren = new Object[source.length];
+ for (int i = 0; i < source.length; i++) {
+ // ElementInfo argElement = wrapper.getInputChildElements().get(i);
+ DataType<XMLType> argType = argTypes.get(i);
+ targetChildren[i] =
+ mediator.mediate(source[i], sourceType.getLogical().get(i), argType, context.getMetadata());
+ }
+ targetWrapperHandler.setChildren(targetWrapper,
+ targetChildren,
+ targetOp,
+ true);
+ return new Object[] {targetWrapper};
+
+ } else if (sourceWrapped && (!targetWrapped)) {
+ // Wrapped to Unwrapped
+ Object sourceWrapper = source[0];
+ Object[] target = null;
+
+ List<ElementInfo> childElements = sourceOp.getWrapper().getInputChildElements();
+ if (targetWrapperHandler != null) {
+ ElementInfo wrapperElement = sourceOp.getWrapper().getInputWrapperElement();
+ // FIXME: This is a workaround for the wsdless support as it passes in child elements
+ // under the wrapper that only matches by position
+ if (sourceWrapperHandler.isInstance(sourceWrapper, sourceOp, true)) {
+
+ WrapperInfo targetWrapperInfo = targetOp.getWrapper();
+ DataType targetWrapperType =
+ targetWrapperInfo != null ? targetWrapperInfo.getInputWrapperType() : null;
+ if (targetWrapperType != null && matches(sourceOp.getWrapper(), targetOp.getWrapper())) {
+ Object targetWrapper =
+ mediator.mediate(sourceWrapper, sourceType.getLogical().get(0), targetWrapperType, context
+ .getMetadata());
+ target = targetWrapperHandler.getChildren(targetWrapper, targetOp, true).toArray();
+ return target;
+ }
+ }
+ }
+ Object[] sourceChildren = sourceWrapperHandler.getChildren(sourceWrapper, sourceOp, true).toArray();
+ target = new Object[sourceChildren.length];
+ for (int i = 0; i < sourceChildren.length; i++) {
+ DataType<XMLType> childType = sourceOp.getWrapper().getUnwrappedInputType().getLogical().get(i);
+ target[i] =
+ mediator.mediate(sourceChildren[i], childType, targetType.getLogical().get(i), context
+ .getMetadata());
+ }
+ return target;
+ } else {
+ // Assuming wrapper to wrapper conversion can be handled here as well
+ Object[] newArgs = new Object[source.length];
+ for (int i = 0; i < source.length; i++) {
+ Object child =
+ mediator.mediate(source[i], sourceType.getLogical().get(i), targetType.getLogical().get(i), context
+ .getMetadata());
+ newArgs[i] = child;
+ }
+ return newArgs;
+ }
+ }
+
+ private WrapperHandler getWrapperHandler(String dataBindingId, boolean required) {
+ WrapperHandler wrapperHandler = null;
+ if (dataBindingId != null) {
+ DataBinding dataBinding = mediator.getDataBindings().getDataBinding(dataBindingId);
+ wrapperHandler = dataBinding == null ? null : dataBinding.getWrapperHandler();
+ }
+ if (wrapperHandler == null && required) {
+ throw new TransformationException("No wrapper handler is provided for databinding: " + dataBindingId);
+ }
+ return wrapperHandler;
+ }
+
+ private String getDataBinding(Operation operation) {
+ WrapperInfo wrapper = operation.getWrapper();
+ if (wrapper != null) {
+ return wrapper.getDataBinding();
+ } else {
+ return null;
+ }
+ }
+
+}
diff --git a/java/sca/modules/core-databinding/src/main/java/org/apache/tuscany/sca/core/databinding/transformers/Output2OutputTransformer.java b/java/sca/modules/core-databinding/src/main/java/org/apache/tuscany/sca/core/databinding/transformers/Output2OutputTransformer.java
new file mode 100644
index 0000000000..71253f00b4
--- /dev/null
+++ b/java/sca/modules/core-databinding/src/main/java/org/apache/tuscany/sca/core/databinding/transformers/Output2OutputTransformer.java
@@ -0,0 +1,254 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.sca.core.databinding.transformers;
+
+import java.util.List;
+
+import org.apache.tuscany.sca.databinding.DataBinding;
+import org.apache.tuscany.sca.databinding.Mediator;
+import org.apache.tuscany.sca.databinding.PullTransformer;
+import org.apache.tuscany.sca.databinding.TransformationContext;
+import org.apache.tuscany.sca.databinding.TransformationException;
+import org.apache.tuscany.sca.databinding.WrapperHandler;
+import org.apache.tuscany.sca.databinding.impl.BaseTransformer;
+import org.apache.tuscany.sca.interfacedef.DataType;
+import org.apache.tuscany.sca.interfacedef.Operation;
+import org.apache.tuscany.sca.interfacedef.util.ElementInfo;
+import org.apache.tuscany.sca.interfacedef.util.WrapperInfo;
+import org.apache.tuscany.sca.interfacedef.util.XMLType;
+import org.osoa.sca.annotations.Reference;
+
+/**
+ * This is a special transformer to transform the output from one IDL to the
+ * other one
+ *
+ * @version $Rev$ $Date$
+ */
+public class Output2OutputTransformer extends BaseTransformer<Object, Object> implements
+ PullTransformer<Object, Object> {
+
+ protected Mediator mediator;
+
+ /**
+ * @param wrapperHandler
+ */
+ public Output2OutputTransformer() {
+ super();
+ }
+
+ /**
+ * @param mediator the mediator to set
+ */
+ @Reference
+ public void setMediator(Mediator mediator) {
+ this.mediator = mediator;
+ }
+
+ @Override
+ public String getSourceDataBinding() {
+ return DataBinding.IDL_OUTPUT;
+ }
+
+ @Override
+ public String getTargetDataBinding() {
+ return DataBinding.IDL_OUTPUT;
+ }
+
+ /**
+ * @see org.apache.tuscany.sca.databinding.impl.BaseTransformer#getSourceType()
+ */
+ @Override
+ protected Class<Object> getSourceType() {
+ return Object.class;
+ }
+
+ /**
+ * @see org.apache.tuscany.sca.databinding.impl.BaseTransformer#getTargetType()
+ */
+ @Override
+ protected Class<Object> getTargetType() {
+ return Object.class;
+ }
+
+ /**
+ * @see org.apache.tuscany.sca.databinding.Transformer#getWeight()
+ */
+ @Override
+ public int getWeight() {
+ return 10;
+ }
+
+ private String getDataBinding(Operation operation) {
+ WrapperInfo wrapper = operation.getWrapper();
+ if (wrapper != null) {
+ return wrapper.getDataBinding();
+ } else {
+ return null;
+ }
+ }
+
+ private WrapperHandler getWrapperHandler(String dataBindingId, boolean required) {
+ WrapperHandler wrapperHandler = null;
+ if (dataBindingId != null) {
+ DataBinding dataBinding = mediator.getDataBindings().getDataBinding(dataBindingId);
+ wrapperHandler = dataBinding == null ? null : dataBinding.getWrapperHandler();
+ }
+ if (wrapperHandler == null && required) {
+ throw new TransformationException("No wrapper handler is provided for databinding: " + dataBindingId);
+ }
+ return wrapperHandler;
+ }
+
+ /**
+ * Match the structure of the wrapper element. If it matches, then we can do
+ * wrapper to wrapper transformation. Otherwise, we do child to child.
+ * @param w1
+ * @param w2
+ * @return
+ */
+ private boolean matches(WrapperInfo w1, WrapperInfo w2) {
+ if (w1 == null || w2 == null) {
+ return false;
+ }
+ if (!w1.getOutputWrapperElement().equals(w2.getOutputWrapperElement())) {
+ return false;
+ }
+
+ // Compare the child elements
+ List<ElementInfo> list1 = w1.getOutputChildElements();
+ List<ElementInfo> list2 = w2.getOutputChildElements();
+ if (list1.size() != list2.size()) {
+ return false;
+ }
+ // FXIME: [rfeng] At this point, the J2W generates local elments under the namespace
+ // of the interface instead of "". We only compare the local parts only to work around
+ // the namespace mismatch
+ for (int i = 0; i < list1.size(); i++) {
+ String n1 = list1.get(i).getQName().getLocalPart();
+ String n2 = list2.get(i).getQName().getLocalPart();
+ if (!n1.equals(n2)) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ @SuppressWarnings("unchecked")
+ public Object transform(Object response, TransformationContext context) {
+ try {
+ DataType<DataType> sourceType = context.getSourceDataType();
+ Operation sourceOp = context.getSourceOperation();
+ boolean sourceWrapped = sourceOp != null && sourceOp.isWrapperStyle();
+
+ WrapperHandler sourceWrapperHandler = null;
+ String sourceDataBinding = getDataBinding(sourceOp);
+ sourceWrapperHandler = getWrapperHandler(sourceDataBinding, sourceWrapped);
+
+ DataType<DataType> targetType = context.getTargetDataType();
+ Operation targetOp = (Operation)context.getTargetOperation();
+ boolean targetWrapped = targetOp != null && targetOp.isWrapperStyle();
+ WrapperHandler targetWrapperHandler = null;
+ String targetDataBinding = getDataBinding(targetOp);
+ targetWrapperHandler = getWrapperHandler(targetDataBinding, targetWrapped);
+
+ if ((!sourceWrapped) && targetWrapped) {
+ // Unwrapped --> Wrapped
+ WrapperInfo wrapper = targetOp.getWrapper();
+ ElementInfo wrapperElement = wrapper.getOutputWrapperElement();
+ List<ElementInfo> childElements = wrapper.getOutputChildElements();
+ Class<?> targetWrapperClass = wrapper != null ? wrapper.getOutputWrapperClass() : null;
+
+ // If the source can be wrapped, wrapped it first
+ if (sourceWrapperHandler != null) {
+ WrapperInfo sourceWrapperInfo = sourceOp.getWrapper();
+ DataType sourceWrapperType =
+ sourceWrapperInfo != null ? sourceWrapperInfo.getOutputWrapperType() : null;
+
+ if (sourceWrapperType != null && matches(sourceOp.getWrapper(), targetOp.getWrapper())) {
+ Class<?> sourceWrapperClass = sourceWrapperType.getPhysical();
+
+ Object sourceWrapper = sourceWrapperHandler.create(sourceOp, false);
+ if (sourceWrapper != null) {
+ if (!childElements.isEmpty()) {
+ // Set the return value
+ sourceWrapperHandler.setChildren(sourceWrapper,
+ new Object[] {response},
+ sourceOp,
+ false);
+ }
+ Object targetWrapper =
+ mediator.mediate(sourceWrapper, sourceWrapperType, targetType.getLogical(), context
+ .getMetadata());
+ return targetWrapper;
+ }
+ }
+ }
+ Object targetWrapper = targetWrapperHandler.create(targetOp, false);
+
+ if (childElements.isEmpty()) {
+ // void output
+ return targetWrapper;
+ }
+
+ DataType<XMLType> argType = wrapper.getUnwrappedOutputType();
+ Object child = response;
+ child = mediator.mediate(response, sourceType.getLogical(), argType, context.getMetadata());
+ targetWrapperHandler.setChildren(targetWrapper, new Object[] {child}, targetOp, false);
+ return targetWrapper;
+ } else if (sourceWrapped && (!targetWrapped)) {
+ // Wrapped to Unwrapped
+ Object sourceWrapper = response;
+ List<ElementInfo> childElements = sourceOp.getWrapper().getOutputChildElements();
+ if (childElements.isEmpty()) {
+ // The void output
+ return null;
+ }
+ if (targetWrapperHandler != null) {
+ ElementInfo wrapperElement = sourceOp.getWrapper().getOutputWrapperElement();
+
+ // FIXME: This is a workaround for the wsdless support as it passes in child elements
+ // under the wrapper that only matches by position
+ if (sourceWrapperHandler.isInstance(sourceWrapper, sourceOp, false)) {
+
+ WrapperInfo targetWrapperInfo = targetOp.getWrapper();
+ DataType targetWrapperType =
+ targetWrapperInfo != null ? targetWrapperInfo.getOutputWrapperType() : null;
+
+ if (targetWrapperType != null && matches(sourceOp.getWrapper(), targetOp.getWrapper())) {
+ Object targetWrapper =
+ mediator.mediate(sourceWrapper, sourceType.getLogical(), targetWrapperType, context
+ .getMetadata());
+ return targetWrapperHandler.getChildren(targetWrapper, targetOp, false).get(0);
+ }
+ }
+ }
+ Object child = sourceWrapperHandler.getChildren(sourceWrapper, sourceOp, false).get(0);
+ DataType<?> childType = sourceOp.getWrapper().getUnwrappedOutputType();
+ return mediator.mediate(child, childType, targetType.getLogical(), context.getMetadata());
+ } else {
+ // FIXME: Do we want to handle wrapped to wrapped?
+ return mediator.mediate(response, sourceType.getLogical(), targetType.getLogical(), context
+ .getMetadata());
+ }
+ } catch (Exception e) {
+ throw new TransformationException(e);
+ }
+ }
+
+}
diff --git a/java/sca/modules/core-databinding/src/main/java/org/apache/tuscany/sca/core/databinding/transformers/XMLStreamReader2CallableReference.java b/java/sca/modules/core-databinding/src/main/java/org/apache/tuscany/sca/core/databinding/transformers/XMLStreamReader2CallableReference.java
new file mode 100644
index 0000000000..841efa9398
--- /dev/null
+++ b/java/sca/modules/core-databinding/src/main/java/org/apache/tuscany/sca/core/databinding/transformers/XMLStreamReader2CallableReference.java
@@ -0,0 +1,100 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.sca.core.databinding.transformers;
+
+import static javax.xml.stream.XMLStreamConstants.START_ELEMENT;
+
+import java.lang.reflect.Constructor;
+
+import javax.xml.namespace.QName;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamReader;
+
+import org.apache.tuscany.sca.core.context.CallableReferenceImpl;
+import org.apache.tuscany.sca.core.context.ServiceReferenceImpl;
+import org.apache.tuscany.sca.databinding.PullTransformer;
+import org.apache.tuscany.sca.databinding.TransformationContext;
+import org.apache.tuscany.sca.databinding.TransformationException;
+import org.apache.tuscany.sca.databinding.impl.BaseTransformer;
+import org.osoa.sca.CallableReference;
+
+@SuppressWarnings("unchecked")
+public class XMLStreamReader2CallableReference extends BaseTransformer<XMLStreamReader, CallableReference>
+ implements PullTransformer<XMLStreamReader, CallableReference> {
+
+ private static final String SCA10_NS = "http://www.osoa.org/xmlns/sca/1.0";
+ private static final String COMPOSITE = "composite";
+ public static final QName COMPOSITE_QNAME = new QName(SCA10_NS, COMPOSITE);
+
+ public CallableReference transform(XMLStreamReader source, TransformationContext context) {
+ try {
+ if (source != null) {
+ skipTopLevelElement(source);
+ Class refType = context.getTargetDataType().getPhysical();
+ Class implType;
+ if (refType.isAssignableFrom(CallableReferenceImpl.class)) {
+ implType = CallableReferenceImpl.class;
+ } else if (refType.isAssignableFrom(ServiceReferenceImpl.class)) {
+ implType = ServiceReferenceImpl.class;
+ } else {
+ throw new TransformationException("Unrecognized transformation target type");
+ }
+ Constructor constructor = implType.getConstructor(new Class[] {XMLStreamReader.class});
+ return (CallableReference)constructor.newInstance(new Object[] {source});
+ } else {
+ return null;
+ }
+ } catch (Exception e) {
+ throw new TransformationException(e);
+ }
+ }
+
+ /*
+ * Step over top-level element added by CallableReference2XMLStreamReader
+ */
+ private void skipTopLevelElement(XMLStreamReader source) throws XMLStreamException {
+ while (source.hasNext()) {
+ int event = source.getEventType();
+ if (event == START_ELEMENT) {
+ QName name = source.getName();
+ if (COMPOSITE_QNAME.equals(name)) {
+ return;
+ }
+ }
+ source.next();
+ }
+ throw new TransformationException("<composite> element not found");
+ }
+
+ @Override
+ protected Class<XMLStreamReader> getSourceType() {
+ return XMLStreamReader.class;
+ }
+
+ @Override
+ protected Class<CallableReference> getTargetType() {
+ return CallableReference.class;
+ }
+
+ @Override
+ public int getWeight() {
+ return 10;
+ }
+
+}
diff --git a/java/sca/modules/core-databinding/src/main/java/org/apache/tuscany/sca/core/databinding/wire/DataBindingRuntimeWireProcessor.java b/java/sca/modules/core-databinding/src/main/java/org/apache/tuscany/sca/core/databinding/wire/DataBindingRuntimeWireProcessor.java
new file mode 100644
index 0000000000..e5965db2c5
--- /dev/null
+++ b/java/sca/modules/core-databinding/src/main/java/org/apache/tuscany/sca/core/databinding/wire/DataBindingRuntimeWireProcessor.java
@@ -0,0 +1,186 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tuscany.sca.core.databinding.wire;
+
+import java.util.List;
+
+import org.apache.tuscany.sca.assembly.ComponentReference;
+import org.apache.tuscany.sca.databinding.DataBindingExtensionPoint;
+import org.apache.tuscany.sca.databinding.Mediator;
+import org.apache.tuscany.sca.interfacedef.DataType;
+import org.apache.tuscany.sca.interfacedef.FaultExceptionMapper;
+import org.apache.tuscany.sca.interfacedef.InterfaceContract;
+import org.apache.tuscany.sca.interfacedef.Operation;
+import org.apache.tuscany.sca.invocation.Interceptor;
+import org.apache.tuscany.sca.invocation.InvocationChain;
+import org.apache.tuscany.sca.invocation.Phase;
+import org.apache.tuscany.sca.runtime.RuntimeWire;
+import org.apache.tuscany.sca.runtime.RuntimeWireProcessor;
+
+/**
+ * This processor is responsible to add an interceptor to invocation chain if
+ * the source and target operations have different databinding requirements
+ *
+ * @version $Rev$ $Date$
+ */
+public class DataBindingRuntimeWireProcessor implements RuntimeWireProcessor {
+ private Mediator mediator;
+ private DataBindingExtensionPoint dataBindings;
+ private FaultExceptionMapper faultExceptionMapper;
+
+ public DataBindingRuntimeWireProcessor(Mediator mediator,
+ DataBindingExtensionPoint dataBindings,
+ FaultExceptionMapper faultExceptionMapper) {
+ super();
+ this.mediator = mediator;
+ this.dataBindings = dataBindings;
+ this.faultExceptionMapper = faultExceptionMapper;
+ }
+
+ public boolean isTransformationRequired(DataType source, DataType target) {
+ if (source == null || target == null) { // void return type
+ return false;
+ }
+ if (source == target) {
+ return false;
+ }
+
+ // Output type can be null
+ if (source == null && target == null) {
+ return false;
+ } else if (source == null || target == null) {
+ return true;
+ }
+ String sourceDataBinding = source.getDataBinding();
+ String targetDataBinding = target.getDataBinding();
+ if (sourceDataBinding == targetDataBinding) {
+ return false;
+ }
+ if (sourceDataBinding == null || targetDataBinding == null) {
+ // TODO: If any of the databinding is null, then no transformation
+ return false;
+ }
+ return !sourceDataBinding.equals(targetDataBinding);
+ }
+
+ public boolean isTransformationRequired(Operation source, Operation target) {
+ if (source == target) {
+ return false;
+ }
+
+ if (source.isWrapperStyle() != target.isWrapperStyle()) {
+ return true;
+ }
+
+ // Check output type
+ DataType sourceOutputType = source.getOutputType();
+ DataType targetOutputType = target.getOutputType();
+
+ // Note the target output type is now the source for checking
+ // compatibility
+ if (isTransformationRequired(targetOutputType, sourceOutputType)) {
+ return true;
+ }
+
+ List<DataType> sourceInputType = source.getInputType().getLogical();
+ List<DataType> targetInputType = target.getInputType().getLogical();
+
+ int size = sourceInputType.size();
+ if (size != targetInputType.size()) {
+ // TUSCANY-1682: The wrapper style may have different arguments
+ return true;
+ }
+ for (int i = 0; i < size; i++) {
+ if (isTransformationRequired(sourceInputType.get(i), targetInputType.get(i))) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ private boolean isTransformationRequired(InterfaceContract sourceContract,
+ Operation sourceOperation,
+ InterfaceContract targetContract,
+ Operation targetOperation) {
+ if (targetContract == null) {
+ targetContract = sourceContract;
+ }
+ if (sourceContract == targetContract) {
+ return false;
+ }
+ return isTransformationRequired(sourceOperation, targetOperation);
+ }
+
+ public void process(RuntimeWire wire) {
+ InterfaceContract sourceContract = wire.getSource().getInterfaceContract();
+ InterfaceContract targetContract = wire.getTarget().getInterfaceContract();
+ if (targetContract == null) {
+ targetContract = sourceContract;
+ }
+
+ if (!sourceContract.getInterface().isRemotable()) {
+ return;
+ }
+ List<InvocationChain> chains = wire.getInvocationChains();
+ for (InvocationChain chain : chains) {
+ Operation sourceOperation = chain.getSourceOperation();
+ Operation targetOperation = chain.getTargetOperation();
+
+ Interceptor interceptor = null;
+ if (isTransformationRequired(sourceContract, sourceOperation, targetContract, targetOperation)) {
+ // Add the interceptor to the source side because multiple
+ // references can be wired to the same service
+ interceptor =
+ new DataTransformationInterceptor(wire, sourceOperation, targetOperation, mediator,
+ faultExceptionMapper);
+ } else {
+ // assume pass-by-values copies are required if interfaces are remotable and there is no data binding
+ // transformation, i.e. a transformation will result in a copy so another pass-by-value copy is unnecessary
+ if (isRemotable(chain, sourceOperation, targetOperation)) {
+ interceptor =
+ new PassByValueInterceptor(dataBindings, faultExceptionMapper, chain, targetOperation);
+ }
+ }
+ if (interceptor != null) {
+ String phase =
+ (wire.getSource().getContract() instanceof ComponentReference) ? Phase.REFERENCE_INTERFACE
+ : Phase.SERVICE_INTERFACE;
+ chain.addInterceptor(phase, interceptor);
+ }
+ }
+
+ }
+
+ /**
+ * Pass-by-value copies are required if the interfaces are remotable unless the
+ * implementation uses the @AllowsPassByReference annotation.
+ */
+ protected boolean isRemotable(InvocationChain chain, Operation sourceOperation, Operation targetOperation) {
+ if (!sourceOperation.getInterface().isRemotable()) {
+ return false;
+ }
+ if (!targetOperation.getInterface().isRemotable()) {
+ return false;
+ }
+ return true;
+ }
+
+}
diff --git a/java/sca/modules/core-databinding/src/main/java/org/apache/tuscany/sca/core/databinding/wire/DataTransformationInterceptor.java b/java/sca/modules/core-databinding/src/main/java/org/apache/tuscany/sca/core/databinding/wire/DataTransformationInterceptor.java
new file mode 100644
index 0000000000..5814f3d215
--- /dev/null
+++ b/java/sca/modules/core-databinding/src/main/java/org/apache/tuscany/sca/core/databinding/wire/DataTransformationInterceptor.java
@@ -0,0 +1,264 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tuscany.sca.core.databinding.wire;
+
+import java.lang.reflect.InvocationTargetException;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.xml.namespace.QName;
+
+import org.apache.tuscany.sca.databinding.DataBinding;
+import org.apache.tuscany.sca.databinding.Mediator;
+import org.apache.tuscany.sca.interfacedef.DataType;
+import org.apache.tuscany.sca.interfacedef.FaultExceptionMapper;
+import org.apache.tuscany.sca.interfacedef.Operation;
+import org.apache.tuscany.sca.interfacedef.impl.DataTypeImpl;
+import org.apache.tuscany.sca.interfacedef.util.FaultException;
+import org.apache.tuscany.sca.interfacedef.util.XMLType;
+import org.apache.tuscany.sca.invocation.DataExchangeSemantics;
+import org.apache.tuscany.sca.invocation.Interceptor;
+import org.apache.tuscany.sca.invocation.Invoker;
+import org.apache.tuscany.sca.invocation.Message;
+import org.apache.tuscany.sca.runtime.RuntimeWire;
+import org.osoa.sca.ServiceRuntimeException;
+
+/**
+ * An interceptor to transform data across databindings on the wire
+ *
+ * @version $Rev$ $Date$
+ */
+public class DataTransformationInterceptor implements Interceptor, DataExchangeSemantics {
+ private Invoker next;
+
+ private Operation sourceOperation;
+
+ private Operation targetOperation;
+ private RuntimeWire wire;
+ private Mediator mediator;
+ private FaultExceptionMapper faultExceptionMapper;
+
+ public DataTransformationInterceptor(RuntimeWire wire,
+ Operation sourceOperation,
+ Operation targetOperation,
+ Mediator mediator,
+ FaultExceptionMapper faultExceptionMapper) {
+ super();
+ this.sourceOperation = sourceOperation;
+ this.targetOperation = targetOperation;
+ this.mediator = mediator;
+ this.wire = wire;
+ this.faultExceptionMapper = faultExceptionMapper;
+ }
+
+ public Invoker getNext() {
+ return next;
+ }
+
+ public Message invoke(Message msg) {
+ Object input = transform(msg.getBody(), sourceOperation.getInputType(), targetOperation.getInputType(), false);
+ msg.setBody(input);
+ Message resultMsg = next.invoke(msg);
+ Object result = resultMsg.getBody();
+ if (sourceOperation.isNonBlocking()) {
+ // Not to reset the message body
+ return resultMsg;
+ }
+
+ // FIXME: Should we fix the Operation model so that getOutputType
+ // returns DataType<DataType<T>>?
+ DataType<DataType> targetType =
+ new DataTypeImpl<DataType>(DataBinding.IDL_OUTPUT, Object.class, targetOperation.getOutputType());
+
+ DataType<DataType> sourceType =
+ new DataTypeImpl<DataType>(DataBinding.IDL_OUTPUT, Object.class, sourceOperation.getOutputType());
+
+ if (resultMsg.isFault()) {
+
+ // FIXME: We need to figure out what fault type it is and then
+ // transform it
+ // back the source fault type
+ // throw new InvocationRuntimeException((Throwable) result);
+
+ if ((result instanceof Exception) && !(result instanceof RuntimeException)) {
+ // FIXME: How to match fault data to a fault type for the
+ // operation?
+
+ // If the result is from an InvocationTargetException look at
+ // the actual cause.
+ if (result instanceof InvocationTargetException) {
+ result = ((InvocationTargetException)result).getCause();
+ }
+ DataType targetDataType = null;
+ for (DataType exType : targetOperation.getFaultTypes()) {
+ if (((Class)exType.getPhysical()).isInstance(result)) {
+ if (result instanceof FaultException) {
+ DataType faultType = (DataType)exType.getLogical();
+ if (((FaultException)result).isMatchingType(faultType.getLogical())) {
+ targetDataType = exType;
+ break;
+ }
+ } else {
+ targetDataType = exType;
+ break;
+ }
+ }
+ }
+
+ /*
+ if (targetDataType == null) {
+ // Not a business exception
+ return resultMsg;
+ }
+ */
+
+ DataType targetFaultType = getFaultType(targetDataType);
+ if (targetFaultType == null) {
+ // No matching fault type, it's a system exception
+ Throwable cause = (Throwable) result;
+ throw new ServiceRuntimeException(cause);
+ }
+
+ // FIXME: How to match a source fault type to a target fault
+ // type?
+ DataType sourceDataType = null;
+ DataType sourceFaultType = null;
+ for (DataType exType : sourceOperation.getFaultTypes()) {
+ DataType faultType = getFaultType(exType);
+ // Match by the QName (XSD element) of the fault type
+ if (faultType != null && typesMatch(targetFaultType.getLogical(), faultType.getLogical())) {
+ sourceDataType = exType;
+ sourceFaultType = faultType;
+ break;
+ }
+ }
+
+ if (sourceFaultType == null) {
+ // No matching fault type, it's a system exception
+ Throwable cause = (Throwable) result;
+ throw new ServiceRuntimeException(cause);
+ }
+
+ Object newResult =
+ transformException(result, targetDataType, sourceDataType, targetFaultType, sourceFaultType);
+ if (newResult != result) {
+ resultMsg.setFaultBody(newResult);
+ }
+ }
+
+ } else {
+ assert !(result instanceof Throwable) : "Expected messages that are not throwable " + result;
+
+ Object newResult = transform(result, targetType, sourceType, true);
+ if (newResult != result) {
+ resultMsg.setBody(newResult);
+ }
+ }
+
+ return resultMsg;
+ }
+
+ private Object transform(Object source, DataType sourceType, DataType targetType, boolean isResponse) {
+ if (sourceType == targetType || (sourceType != null && sourceType.equals(targetType))) {
+ return source;
+ }
+ Map<String, Object> metadata = new HashMap<String, Object>();
+ metadata.put("source.operation", isResponse ? targetOperation : sourceOperation);
+ metadata.put("target.operation", isResponse ? sourceOperation : targetOperation);
+ metadata.put("wire", wire);
+ return mediator.mediate(source, sourceType, targetType, metadata);
+ }
+
+ private DataType getFaultType(DataType exceptionType) {
+ return exceptionType == null ? null : (DataType)exceptionType.getLogical();
+ }
+
+ private boolean typesMatch(Object first, Object second) {
+ if (first.equals(second)) {
+ return true;
+ }
+ if (first instanceof XMLType && second instanceof XMLType) {
+ XMLType t1 = (XMLType)first;
+ XMLType t2 = (XMLType)second;
+ // TUSCANY-2113, we should compare element names only
+ return matches(t1.getElementName(), t2.getElementName());
+ }
+ return false;
+ }
+
+ /**
+ * @param qn1
+ * @param qn2
+ */
+ private boolean matches(QName qn1, QName qn2) {
+ if (qn1 == qn2) {
+ return true;
+ }
+ if (qn1 == null || qn2 == null) {
+ return false;
+ }
+ String ns1 = qn1.getNamespaceURI();
+ String ns2 = qn2.getNamespaceURI();
+ String e1 = qn1.getLocalPart();
+ String e2 = qn2.getLocalPart();
+ if (e1.equals(e2) && (ns1.equals(ns2) || ns1.equals(ns2 + "/") || ns2.equals(ns1 + "/"))) {
+ // Tolerating the trailing / which is required by JAX-WS java package --> xml ns mapping
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * @param source The source exception
+ * @param sourceExType The data type for the source exception
+ * @param targetExType The data type for the target exception
+ * @param sourceType The fault type for the source
+ * @param targetType The fault type for the target
+ * @return
+ */
+ private Object transformException(Object source,
+ DataType sourceExType,
+ DataType targetExType,
+ DataType sourceType,
+ DataType targetType) {
+ if (sourceType == targetType || (sourceType != null && sourceType.equals(targetType))) {
+ return source;
+ }
+ Map<String, Object> metadata = new HashMap<String, Object>();
+ metadata.put("source.operation", targetOperation);
+ metadata.put("target.operation", sourceOperation);
+ metadata.put("wire", wire);
+ DataType<DataType> eSourceDataType =
+ new DataTypeImpl<DataType>("idl:fault", sourceExType.getPhysical(), sourceType);
+ DataType<DataType> eTargetDataType =
+ new DataTypeImpl<DataType>("idl:fault", targetExType.getPhysical(), targetType);
+
+ return mediator.mediate(source, eSourceDataType, eTargetDataType, metadata);
+ }
+
+ public void setNext(Invoker next) {
+ this.next = next;
+ }
+
+ public boolean allowsPassByReference() {
+ return true;
+ }
+
+}
diff --git a/java/sca/modules/core-databinding/src/main/java/org/apache/tuscany/sca/core/databinding/wire/PassByValueInterceptor.java b/java/sca/modules/core-databinding/src/main/java/org/apache/tuscany/sca/core/databinding/wire/PassByValueInterceptor.java
new file mode 100644
index 0000000000..3586f54d71
--- /dev/null
+++ b/java/sca/modules/core-databinding/src/main/java/org/apache/tuscany/sca/core/databinding/wire/PassByValueInterceptor.java
@@ -0,0 +1,268 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tuscany.sca.core.databinding.wire;
+
+import java.io.Serializable;
+import java.lang.reflect.Array;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.net.URI;
+import java.util.IdentityHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
+
+import javax.xml.namespace.QName;
+
+import org.apache.tuscany.sca.databinding.DataBinding;
+import org.apache.tuscany.sca.databinding.DataBindingExtensionPoint;
+import org.apache.tuscany.sca.databinding.javabeans.JavaBeansDataBinding;
+import org.apache.tuscany.sca.databinding.jaxb.JAXBDataBinding;
+import org.apache.tuscany.sca.interfacedef.DataType;
+import org.apache.tuscany.sca.interfacedef.FaultExceptionMapper;
+import org.apache.tuscany.sca.interfacedef.Operation;
+import org.apache.tuscany.sca.interfacedef.impl.DataTypeImpl;
+import org.apache.tuscany.sca.interfacedef.util.XMLType;
+import org.apache.tuscany.sca.invocation.Interceptor;
+import org.apache.tuscany.sca.invocation.InvocationChain;
+import org.apache.tuscany.sca.invocation.Invoker;
+import org.apache.tuscany.sca.invocation.Message;
+import org.osoa.sca.ServiceRuntimeException;
+
+/**
+ * Implementation of an interceptor that enforces pass-by-value semantics
+ * on operation invocations by copying the operation input and output data.
+ *
+ * @version $Rev$ $Date$
+ */
+public class PassByValueInterceptor implements Interceptor {
+
+ private DataBindingExtensionPoint dataBindings;
+ private FaultExceptionMapper faultExceptionMapper;
+
+ private DataBinding[] inputDataBindings;
+ private DataBinding outputDataBinding;
+ private DataBinding javaBeanDataBinding;
+ private DataBinding jaxbDataBinding;
+ private Operation operation;
+ private Invoker nextInvoker;
+ private InvocationChain chain;
+
+ /**
+ * Constructs a new PassByValueInterceptor.
+ * @param dataBindings databinding extension point
+ * @param operation the intercepted operation
+ */
+ public PassByValueInterceptor(DataBindingExtensionPoint dataBindings,
+ FaultExceptionMapper faultExceptionMapper,
+ InvocationChain chain,
+ Operation operation) {
+ this.chain = chain;
+ this.operation = operation;
+
+ // Cache data bindings to use
+ this.dataBindings = dataBindings;
+ this.faultExceptionMapper = faultExceptionMapper;
+
+ jaxbDataBinding = dataBindings.getDataBinding(JAXBDataBinding.NAME);
+ javaBeanDataBinding = dataBindings.getDataBinding(JavaBeansDataBinding.NAME);
+
+ // Determine the input databindings
+ if (operation.getInputType() != null) {
+ List<DataType> inputTypes = operation.getInputType().getLogical();
+ inputDataBindings = new DataBinding[inputTypes.size()];
+ int i = 0;
+ for (DataType inputType : inputTypes) {
+ String id = inputType.getDataBinding();
+ inputDataBindings[i++] = dataBindings.getDataBinding(id);
+ }
+ }
+
+ // Determine the output databinding
+ if (operation.getOutputType() != null) {
+ String id = operation.getOutputType().getDataBinding();
+ outputDataBinding = dataBindings.getDataBinding(id);
+ }
+ }
+
+ public Message invoke(Message msg) {
+ if (chain.allowsPassByReference()) {
+ return nextInvoker.invoke(msg);
+ }
+
+ msg.setBody(copy((Object[])msg.getBody(), inputDataBindings, operation.getInputType().getLogical()));
+
+ Message resultMsg = nextInvoker.invoke(msg);
+
+ if (!msg.isFault() && operation.getOutputType() != null) {
+ resultMsg.setBody(copy(resultMsg.getBody(), outputDataBinding, operation.getOutputType()));
+ }
+
+ if (msg.isFault()) {
+ msg.setFaultBody(copyFault(msg.getBody()));
+ }
+ return resultMsg;
+ }
+
+ private Object copyFault(Object fault) {
+ if (faultExceptionMapper == null) {
+ return fault;
+ }
+ for (DataType et : operation.getFaultTypes()) {
+ if (et.getPhysical().isInstance(fault)) {
+ Throwable ex = (Throwable)fault;
+ DataType<DataType> exType =
+ new DataTypeImpl<DataType>(ex.getClass(), new DataTypeImpl<XMLType>(ex.getClass(), XMLType.UNKNOWN));
+ faultExceptionMapper.introspectFaultDataType(exType, operation, false);
+ DataType faultType = exType.getLogical();
+ Object faultInfo = faultExceptionMapper.getFaultInfo(ex, faultType.getPhysical(), operation);
+ faultInfo = copy(faultInfo, dataBindings.getDataBinding(faultType.getDataBinding()), faultType);
+ fault = faultExceptionMapper.wrapFaultInfo(exType, ex.getMessage(), faultInfo, ex.getCause(), operation);
+ return fault;
+ }
+ }
+ return fault;
+ }
+
+ /**
+ * Copy an array of data objects passed to an operation
+ * @param data array of objects to copy
+ * @return the copy
+ */
+ private Object[] copy(Object[] data, DataBinding[] dataBindings, List<DataType> dataTypes) {
+ if (data == null) {
+ return null;
+ }
+ Object[] copy = new Object[data.length];
+ Map<Object, Object> map = new IdentityHashMap<Object, Object>();
+ for (int i = 0; i < data.length; i++) {
+ Object arg = data[i];
+ if (arg == null) {
+ copy[i] = null;
+ } else {
+ Object copiedArg = map.get(arg);
+ if (copiedArg != null) {
+ copy[i] = copiedArg;
+ } else {
+ copiedArg = copy(arg, dataBindings[i], dataTypes.get(i));
+ map.put(arg, copiedArg);
+ copy[i] = copiedArg;
+ }
+ }
+ }
+ return copy;
+ }
+
+ /**
+ * Copy data using the specified databinding.
+ * @param data input data
+ * @param dataBinding databinding to use
+ * @param dataType TODO
+ * @return a copy of the data
+ */
+ private Object copy(Object data, DataBinding dataBinding, DataType dataType) {
+ if (data == null) {
+ return null;
+ }
+ Class<?> clazz = data.getClass();
+ if (String.class == clazz || clazz.isPrimitive()
+ || Number.class.isAssignableFrom(clazz)
+ || Boolean.class.isAssignableFrom(clazz)
+ || Character.class.isAssignableFrom(clazz)
+ || Byte.class.isAssignableFrom(clazz)
+ || URI.class == clazz
+ || UUID.class == clazz
+ || QName.class == clazz) {
+ // Immutable classes
+ return data;
+ }
+ // If no databinding was specified, introspect the given arg to
+ // determine its databinding
+ if (dataBinding == null) {
+ dataType = dataBindings.introspectType(data, operation);
+ if (dataType != null) {
+ String db = dataType.getDataBinding();
+ dataBinding = dataBindings.getDataBinding(db);
+ if (dataBinding == null && db != null) {
+ return data;
+ }
+ }
+ if (dataBinding == null) {
+
+ // Default to the JavaBean databinding
+ dataBinding = javaBeanDataBinding;
+ }
+ }
+
+ // Use the JAXB databinding to copy non-Serializable data
+ if (dataBinding == javaBeanDataBinding) {
+
+ // If the input data is an array containing non Serializable elements
+ // use JAXB
+ clazz = data.getClass();
+ if (clazz.isArray()) {
+ if (Array.getLength(data) != 0) {
+ Object element = Array.get(data, 0);
+ if (element != null && !(element instanceof Serializable)) {
+ dataBinding = jaxbDataBinding;
+ }
+ }
+ } else {
+
+ // If the input data is not Serializable use JAXB
+ if (!(data instanceof Serializable)) {
+ dataBinding = jaxbDataBinding;
+ }
+
+ if (data instanceof Cloneable) {
+ Method clone;
+ try {
+ clone = data.getClass().getMethod("clone", (Class[])null);
+ try {
+ return clone.invoke(data, (Object[])null);
+ } catch (InvocationTargetException e) {
+ if (e.getTargetException() instanceof CloneNotSupportedException) {
+ // Ignore
+ } else {
+ throw new ServiceRuntimeException(e);
+ }
+ } catch (Exception e) {
+ throw new ServiceRuntimeException(e);
+ }
+ } catch (NoSuchMethodException e) {
+ // Ignore it
+ }
+ }
+ }
+ }
+
+ Object copy = dataBinding.copy(data, dataType, operation);
+ return copy;
+ }
+
+ public Invoker getNext() {
+ return nextInvoker;
+ }
+
+ public void setNext(Invoker next) {
+ this.nextInvoker = next;
+ }
+
+}
diff --git a/java/sca/modules/core-databinding/src/main/resources/META-INF/services/org.apache.tuscany.sca.core.ModuleActivator b/java/sca/modules/core-databinding/src/main/resources/META-INF/services/org.apache.tuscany.sca.core.ModuleActivator
new file mode 100644
index 0000000000..baba638c9b
--- /dev/null
+++ b/java/sca/modules/core-databinding/src/main/resources/META-INF/services/org.apache.tuscany.sca.core.ModuleActivator
@@ -0,0 +1,18 @@
+# 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.
+# Implementation class for the ExtensionActivator
+org.apache.tuscany.sca.core.databinding.module.DataBindingModuleActivator
diff --git a/java/sca/modules/core-databinding/src/test/java/org/apache/tuscany/sca/core/databinding/processor/DataBindingJavaInterfaceProcessorTestCase.java b/java/sca/modules/core-databinding/src/test/java/org/apache/tuscany/sca/core/databinding/processor/DataBindingJavaInterfaceProcessorTestCase.java
new file mode 100644
index 0000000000..b0c39e18ef
--- /dev/null
+++ b/java/sca/modules/core-databinding/src/test/java/org/apache/tuscany/sca/core/databinding/processor/DataBindingJavaInterfaceProcessorTestCase.java
@@ -0,0 +1,89 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tuscany.sca.core.databinding.processor;
+
+import junit.framework.TestCase;
+
+import org.apache.tuscany.sca.databinding.DataBindingExtensionPoint;
+import org.apache.tuscany.sca.databinding.DefaultDataBindingExtensionPoint;
+import org.apache.tuscany.sca.databinding.annotation.DataBinding;
+import org.apache.tuscany.sca.interfacedef.InvalidInterfaceException;
+import org.apache.tuscany.sca.interfacedef.Operation;
+import org.apache.tuscany.sca.interfacedef.impl.OperationImpl;
+import org.apache.tuscany.sca.interfacedef.java.DefaultJavaInterfaceFactory;
+import org.apache.tuscany.sca.interfacedef.java.JavaInterface;
+import org.apache.tuscany.sca.interfacedef.java.JavaInterfaceContract;
+import org.apache.tuscany.sca.interfacedef.java.JavaInterfaceFactory;
+import org.osoa.sca.annotations.Remotable;
+import org.w3c.dom.Node;
+
+/**
+ *
+ * @version $Rev$ $Date$
+ */
+public class DataBindingJavaInterfaceProcessorTestCase extends TestCase {
+
+ /**
+ * @see junit.framework.TestCase#setUp()
+ */
+ @Override
+ protected void setUp() throws Exception {
+ }
+
+ /**
+ * @throws InvalidServiceContractException
+ */
+ public final void testVisitInterface() throws InvalidInterfaceException {
+ DataBindingExtensionPoint registry = new DefaultDataBindingExtensionPoint();
+ DataBindingJavaInterfaceProcessor processor = new DataBindingJavaInterfaceProcessor(registry);
+ JavaInterfaceFactory javaFactory = new DefaultJavaInterfaceFactory();
+
+ JavaInterface contract = javaFactory.createJavaInterface();
+ contract.setJavaClass(MockInterface.class);
+ JavaInterfaceContract interfaceContract = javaFactory.createJavaInterfaceContract();
+ interfaceContract.setInterface(contract);
+ Operation operation = newOperation("call");
+ Operation operation1 = newOperation("call1");
+ contract.getOperations().add(operation);
+ contract.getOperations().add(operation1);
+ contract.setRemotable(true);
+ processor.visitInterface(contract);
+ // Assert.assertEquals("org.w3c.dom.Node", contract.getDataBinding());
+ // Assert.assertEquals("org.w3c.dom.Node",
+ // contract.getOperations().get("call").getDataBinding());
+ // Assert.assertEquals("xml:string",
+ // contract.getOperations().get("call1").getDataBinding());
+ }
+
+ @DataBinding("org.w3c.dom.Node")
+ @Remotable
+ public static interface MockInterface {
+ Node call(Node msg);
+
+ @DataBinding("xml:string")
+ String call1(String msg);
+ }
+
+ private static Operation newOperation(String name) {
+ Operation operation = new OperationImpl();
+ operation.setName(name);
+ return operation;
+ }
+}
diff --git a/java/sca/modules/core-databinding/src/test/java/org/apache/tuscany/sca/core/databinding/transformers/IDLTransformerTestCaseFIXME.java b/java/sca/modules/core-databinding/src/test/java/org/apache/tuscany/sca/core/databinding/transformers/IDLTransformerTestCaseFIXME.java
new file mode 100644
index 0000000000..7d49fb7112
--- /dev/null
+++ b/java/sca/modules/core-databinding/src/test/java/org/apache/tuscany/sca/core/databinding/transformers/IDLTransformerTestCaseFIXME.java
@@ -0,0 +1,229 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.sca.core.databinding.transformers;
+
+//import static org.apache.tuscany.spi.databinding.DataBinding.IDL_INPUT;
+//import static org.apache.tuscany.spi.databinding.DataBinding.IDL_OUTPUT;
+//
+//import java.util.ArrayList;
+//import java.util.List;
+//
+//import javax.xml.namespace.QName;
+
+import junit.framework.TestCase;
+
+//import org.apache.tuscany.databinding.impl.DataBindingRegistryImpl;
+//import org.apache.tuscany.databinding.impl.MediatorImpl;
+//import org.apache.tuscany.databinding.impl.TransformationContextImpl;
+//import org.apache.tuscany.databinding.impl.TransformerRegistryImpl;
+//import org.apache.tuscany.databinding.javabeans.DOMNode2JavaBeanTransformer;
+//import org.apache.tuscany.databinding.javabeans.JavaBean2DOMNodeTransformer;
+//import org.apache.tuscany.databinding.xml.DOMDataBinding;
+//import org.apache.tuscany.databinding.xml.Node2String;
+//import org.apache.tuscany.databinding.xml.String2Node;
+//import org.apache.tuscany.interfacedef.DataType;
+//import org.apache.tuscany.interfacedef.Operation;
+//import org.apache.tuscany.interfacedef.impl.DataTypeImpl;
+//import org.apache.tuscany.interfacedef.impl.OperationImpl;
+//import org.apache.tuscany.interfacedef.util.ElementInfo;
+//import org.apache.tuscany.interfacedef.util.TypeInfo;
+//import org.apache.tuscany.interfacedef.util.WrapperInfo;
+//import org.apache.tuscany.interfacedef.util.XMLType;
+//import org.apache.tuscany.spi.databinding.DataBindingRegistry;
+//import org.apache.tuscany.spi.databinding.TransformationContext;
+//import org.apache.tuscany.spi.databinding.extension.DOMHelper;
+//import org.apache.tuscany.spi.databinding.extension.SimpleTypeMapperExtension;
+//import org.w3c.dom.Document;
+//import org.w3c.dom.Element;
+
+public class IDLTransformerTestCaseFIXME extends TestCase {
+// private static final String IPO_XML = "<?xml version=\"1.0\"?>" + "<order1"
+// + " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\""
+// + " xmlns:ipo=\"http://www.example.com/IPO\""
+// + " xsi:schemaLocation=\"http://www.example.com/IPO ipo.xsd\""
+// + " orderDate=\"1999-12-01\">"
+// + " <shipTo exportCode=\"1\" xsi:type=\"ipo:UKAddress\">"
+// + " <name>Helen Zoe</name>"
+// + " <street>47 Eden Street</street>"
+// + " <city>Cambridge</city>"
+// + " <postcode>CB1 1JR</postcode>"
+// + " </shipTo>"
+// + " <billTo xsi:type=\"ipo:USAddress\">"
+// + " <name>Robert Smith</name>"
+// + " <street>8 Oak Avenue</street>"
+// + " <city>Old Town</city>"
+// + " <state>PA</state>"
+// + " <zip>95819</zip>"
+// + " </billTo>"
+// + " <items>"
+// + " <item partNum=\"833-AA\">"
+// + " <productName>Lapis necklace</productName>"
+// + " <quantity>1</quantity>"
+// + " <USPrice>99.95</USPrice>"
+// + " <ipo:comment>Want this for the holidays</ipo:comment>"
+// + " <shipDate>1999-12-05</shipDate>"
+// + " </item>"
+// + " </items>"
+// + "</order1>";
+//
+// private static final String URI_ORDER_XSD = "http://example.com/order.xsd";
+//
+// /**
+// * @see junit.framework.TestCase#setUp()
+// */
+// protected void setUp() throws Exception {
+// super.setUp();
+// }
+//
+// public void testTransform() throws Exception {
+// List<DataType> types0 = new ArrayList<DataType>();
+// DataType<XMLType> wrapperType = new DataTypeImpl<XMLType>(null, Object.class,
+// new XMLType(new QName(URI_ORDER_XSD,
+// "checkOrderStatus"), null));
+// types0.add(wrapperType);
+// DataType<List<DataType>> inputType0 = new DataTypeImpl<List<DataType>>(IDL_INPUT,
+// Object[].class, types0);
+//
+// List<DataType> types1 = new ArrayList<DataType>();
+// DataType<XMLType> customerIdType = new DataTypeImpl<XMLType>(
+// null,
+// Object.class,
+// new XMLType(
+// new QName(URI_ORDER_XSD, "customerId"),
+// null));
+// DataType<XMLType> orderType = new DataTypeImpl<XMLType>(null, Object.class,
+// new XMLType(new QName(URI_ORDER_XSD, "order"), null));
+// DataType<XMLType> flagType = new DataTypeImpl<XMLType>(null, Object.class, new XMLType(new QName(URI_ORDER_XSD,
+// "flag"), null));
+// types1.add(customerIdType);
+// types1.add(orderType);
+// types1.add(flagType);
+//
+// DataType<XMLType> statusType = new DataTypeImpl<XMLType>(null, Object.class,
+// new XMLType(new QName(URI_ORDER_XSD, "status"), null));
+// DataType<XMLType> responseType = new DataTypeImpl<XMLType>(null, Object.class,
+// new XMLType(new QName(URI_ORDER_XSD,
+// "checkOrderStatusResponse"),
+// null));
+//
+// Operation op = new OperationImpl("checkOrderStatus");
+// op.setInputType(inputType0);
+// op.setOutputType(responseType);
+//// op.setDataBinding(DOMDataBinding.NAME);
+////
+//// inputType0.setOperation(op);
+// op.setWrapperStyle(true);
+// ElementInfo inputElement = new ElementInfo(new QName(URI_ORDER_XSD, "checkOrderStatus"), new TypeInfo(null,
+// false,
+// null));
+//// wrapperType.setMetadata(ElementInfo.class.getName(), inputElement);
+//
+// ElementInfo customerId = new ElementInfo(new QName("", "customerId"),
+// SimpleTypeMapperExtension.XSD_SIMPLE_TYPES.get("string"));
+// ElementInfo order = new ElementInfo(new QName("", "order"), new TypeInfo(new QName(URI_ORDER_XSD), false, null));
+// ElementInfo flag = new ElementInfo(new QName("", "flag"), SimpleTypeMapperExtension.XSD_SIMPLE_TYPES.get("int"));
+//
+//// customerIdType.setMetadata(ElementInfo.class.getName(), customerId);
+//// orderType.setMetadata(ElementInfo.class.getName(), order);
+//// flagType.setMetadata(ElementInfo.class.getName(), flag);
+////
+//// customerIdType.setOperation(op);
+//// orderType.setOperation(op);
+//// flagType.setOperation(op);
+//
+// List<ElementInfo> inputElements = new ArrayList<ElementInfo>();
+// inputElements.add(customerId);
+// inputElements.add(order);
+// inputElements.add(flag);
+//
+// ElementInfo statusElement = new ElementInfo(new QName("", "status"), SimpleTypeMapperExtension.XSD_SIMPLE_TYPES
+// .get("string"));
+//
+//// statusType.setMetadata(ElementInfo.class.getName(), statusElement);
+//// statusType.setOperation(op);
+//
+// List<ElementInfo> outputElements = new ArrayList<ElementInfo>();
+// outputElements.add(statusElement);
+//
+// ElementInfo outputElement = new ElementInfo(new QName(URI_ORDER_XSD, "checkOrderStatusResponse"),
+// new TypeInfo(null, false, null));
+//
+//// responseType.setMetadata(ElementInfo.class.getName(), inputElement);
+//// responseType.setOperation(op);
+//
+// WrapperInfo wrapperInfo = new WrapperInfo(DOMDataBinding.NAME, inputElement, outputElement, inputElements,
+// outputElements);
+// op.setWrapper(wrapperInfo);
+//// op.setDataBinding(DOMDataBinding.NAME);
+//
+// MediatorImpl m = new MediatorImpl();
+// TransformerRegistryImpl tr = new TransformerRegistryImpl();
+// tr.registerTransformer(new String2Node());
+// tr.registerTransformer(new Node2String());
+// tr.registerTransformer(new DOMNode2JavaBeanTransformer());
+// tr.registerTransformer(new JavaBean2DOMNodeTransformer());
+// m.setTransformerRegistry(tr);
+// DataBindingRegistry dataBindingRegistry = new DataBindingRegistryImpl();
+// dataBindingRegistry.register(new DOMDataBinding());
+// m.setDataBindingRegistry(dataBindingRegistry);
+//
+// Object[] source = new Object[] {"cust001", IPO_XML, Integer.valueOf(1)};
+// Input2InputTransformer t = new Input2InputTransformer();
+// t.setMediator(m);
+//
+// TransformationContext context = new TransformationContextImpl();
+// context.setSourceOperation(op);
+// List<DataType<Class>> types = new ArrayList<DataType<Class>>();
+// types.add(new DataTypeImpl<Class>(Object.class.getName(), String.class, String.class));
+// types.add(new DataTypeImpl<Class>("java.lang.String", String.class, String.class));
+// types.add(new DataTypeImpl<Class>(Object.class.getName(), int.class, int.class));
+// DataType<List<DataType<Class>>> inputType1 = new DataTypeImpl<List<DataType<Class>>>(IDL_INPUT, Object[].class,
+// types);
+// context.setSourceDataType(inputType1);
+// context.setTargetDataType(op.getInputType());
+// Object[] results = t.transform(source, context);
+// assertEquals(1, results.length);
+// assertTrue(results[0] instanceof Element);
+// Element element = (Element)results[0];
+// assertEquals("http://example.com/order.xsd", element.getNamespaceURI());
+// assertEquals("checkOrderStatus", element.getLocalName());
+//
+// TransformationContext context1 = new TransformationContextImpl();
+// DataType<DataType> sourceType = new DataTypeImpl<DataType>(IDL_OUTPUT, Object.class, op.getOutputType());
+//
+// context1.setSourceDataType(sourceType);
+// DataType<DataType> targetType = new DataTypeImpl<DataType>(IDL_OUTPUT, Object.class,
+// new DataTypeImpl<Class>("java.lang.Object",
+// String.class, String.class));
+// context1.setTargetDataType(targetType);
+//
+// Document factory = DOMHelper.newDocument();
+// Element responseElement = factory
+// .createElementNS("http://example.com/order.wsdl", "p:checkOrderStatusResponse");
+// Element status = factory.createElement("status");
+// responseElement.appendChild(status);
+// status.appendChild(factory.createTextNode("shipped"));
+// Output2OutputTransformer t2 = new Output2OutputTransformer();
+// t2.setMediator(m);
+// Object st = t2.transform(responseElement, context1);
+// assertEquals("shipped", st);
+//
+// }
+//
+}