summaryrefslogtreecommitdiffstats
path: root/sca-java-1.x/tags/java-M1-final/java/sca/model/src/main/java/org/apache/tuscany/model/types/wsdl/impl/WSDLServiceContractImpl.java
diff options
context:
space:
mode:
Diffstat (limited to 'sca-java-1.x/tags/java-M1-final/java/sca/model/src/main/java/org/apache/tuscany/model/types/wsdl/impl/WSDLServiceContractImpl.java')
-rw-r--r--sca-java-1.x/tags/java-M1-final/java/sca/model/src/main/java/org/apache/tuscany/model/types/wsdl/impl/WSDLServiceContractImpl.java234
1 files changed, 234 insertions, 0 deletions
diff --git a/sca-java-1.x/tags/java-M1-final/java/sca/model/src/main/java/org/apache/tuscany/model/types/wsdl/impl/WSDLServiceContractImpl.java b/sca-java-1.x/tags/java-M1-final/java/sca/model/src/main/java/org/apache/tuscany/model/types/wsdl/impl/WSDLServiceContractImpl.java
new file mode 100644
index 0000000000..a596eb539f
--- /dev/null
+++ b/sca-java-1.x/tags/java-M1-final/java/sca/model/src/main/java/org/apache/tuscany/model/types/wsdl/impl/WSDLServiceContractImpl.java
@@ -0,0 +1,234 @@
+/**
+ *
+ * Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.tuscany.model.types.wsdl.impl;
+
+import static org.objectweb.asm.Opcodes.ACC_ABSTRACT;
+import static org.objectweb.asm.Opcodes.ACC_INTERFACE;
+import static org.objectweb.asm.Opcodes.ACC_PUBLIC;
+import static org.objectweb.asm.Opcodes.V1_5;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.wsdl.Operation;
+import javax.wsdl.Part;
+import javax.wsdl.PortType;
+import javax.xml.namespace.QName;
+
+import org.apache.tuscany.common.resource.ResourceLoader;
+import org.apache.tuscany.model.assembly.AssemblyContext;
+import org.apache.tuscany.model.assembly.impl.ServiceContractImpl;
+import org.apache.tuscany.model.types.wsdl.WSDLServiceContract;
+import org.apache.tuscany.model.util.XMLNameUtil;
+import org.apache.tuscany.sdo.util.SDOUtil;
+import org.objectweb.asm.ClassWriter;
+import org.objectweb.asm.Type;
+
+import commonj.sdo.Property;
+import commonj.sdo.helper.TypeHelper;
+import commonj.sdo.helper.XSDHelper;
+
+/**
+ * An implementation of WSDLServiceContract.
+ */
+public class WSDLServiceContractImpl extends ServiceContractImpl implements WSDLServiceContract {
+
+ private PortType portType;
+
+ private PortType callbackPortType;
+
+ private static final String[] EMPTY_STRINGS = new String[0];
+
+ /**
+ * Constructor
+ */
+ public WSDLServiceContractImpl() {
+ }
+
+ public PortType getPortType() {
+ return portType;
+ }
+
+ public void setPortType(PortType portType) {
+ checkNotFrozen();
+ this.portType = portType;
+ }
+
+ public PortType getCallbackPortType() {
+ return callbackPortType;
+ }
+
+ public void setCallbackPortType(PortType portType) {
+ checkNotFrozen();
+ callbackPortType = portType;
+ }
+
+ /**
+ * @see org.apache.tuscany.model.assembly.impl.ExtensibleImpl#initialize(org.apache.tuscany.model.assembly.AssemblyContext)
+ */
+ public void initialize(AssemblyContext modelContext) {
+ if (isInitialized())
+ return;
+ super.initialize(modelContext);
+
+ // Load the Java interface for the portType
+ if (portType != null && getInterface() == null) {
+ QName qname = portType.getQName();
+ String interfaceName = XMLNameUtil.getFullyQualifiedClassNameFromQName(qname.getNamespaceURI(), qname.getLocalPart());
+ Class<?> interfaceClass;
+ try {
+ // Load the interface
+ interfaceClass = modelContext.getApplicationResourceLoader().loadClass(interfaceName);
+ } catch (ClassNotFoundException e) {
+ // Generate the interface on the fly
+ interfaceClass = generateJavaInterface(modelContext.getTypeHelper(), modelContext.getApplicationResourceLoader(), portType, interfaceName);
+ }
+ super.setInterface(interfaceClass);
+ }
+
+ // Load the Java interface for the callback portType
+ if (callbackPortType != null && getCallbackInterface() == null) {
+ QName qname = callbackPortType.getQName();
+ String interfaceName = XMLNameUtil.getFullyQualifiedClassNameFromQName(qname.getNamespaceURI(), qname.getLocalPart());
+ Class<?> interfaceClass;
+ try {
+ // Load the interface
+ interfaceClass = modelContext.getApplicationResourceLoader().loadClass(interfaceName);
+ } catch (ClassNotFoundException e) {
+ // Generate the interface on the fly
+ interfaceClass = generateJavaInterface(modelContext.getTypeHelper(), modelContext.getApplicationResourceLoader(), portType, interfaceName);
+ }
+ super.setCallbackInterface(interfaceClass);
+ }
+ }
+
+ /**
+ * Generate a Java interface from a WSDL portType.
+ *
+ * @param portType
+ * @param interfaceName
+ * @return a Java interface that provides the same service contract as the WSDL portType
+ */
+ @SuppressWarnings("unchecked")
+ private static Class<?> generateJavaInterface(TypeHelper typeHelper, ResourceLoader resourceLoader, PortType portType, String interfaceName) {
+
+ ClassLoader cl=Thread.currentThread().getContextClassLoader();
+ try {
+ Thread.currentThread().setContextClassLoader(resourceLoader.getClassLoader());
+
+ // Create an XSD helper
+ XSDHelper xsdHelper = SDOUtil.createXSDHelper(typeHelper);
+
+ ClassWriter cw = new ClassWriter(false);
+
+ // Generate the interface
+ interfaceName = interfaceName.replace('.', '/');
+ cw.visit(V1_5, ACC_PUBLIC + ACC_ABSTRACT + ACC_INTERFACE, interfaceName, null, "java/lang/Object", EMPTY_STRINGS);
+
+ // Generate methods from the WSDL operations
+ for (Operation operation : (List<Operation>) portType.getOperations()) {
+
+ //FIXME Workaround for TUSCANY-170, we will need to make this consistent with the algorithm used by Axis2 WSDL2Java
+ // to generate method names from operations names
+ //String methodName = XMLNameUtil.getJavaNameFromXMLName(operation.getName(), false);
+ String methodName = operation.getName();
+
+ // FIXME later we may want to wwitch to use the Axis2 WSDL2Java (not to generate the Java source,
+ // just to figure the WSDL to Java mapping)
+
+ // Derive the method signature from the input message part (and check if it's a doc-wrapped or doc-bare operation)
+ List<Class> inputTypes=new ArrayList<Class>();
+ boolean wrapped = false;
+ if (operation.getInput() != null && operation.getInput().getMessage()!=null && !operation.getInput().getMessage().getParts().isEmpty()) {
+ QName qname=((Part)operation.getInput().getMessage().getParts().values().iterator().next()).getElementName();
+ if (qname!=null) {
+ Property property = xsdHelper.getGlobalProperty(qname.getNamespaceURI(), qname.getLocalPart(), true);
+ commonj.sdo.Type type = property.getType();
+ if (property.getName().equals(operation.getName())) {
+ String localName = xsdHelper.getLocalName(type);
+ if (localName.indexOf("_._")!=-1) {
+ for (Property param : (List<Property>)type.getProperties()) {
+ Class inputType = param.getType().getInstanceClass();
+ if (inputType == null)
+ inputType = Object.class;
+ inputTypes.add(inputType);
+ }
+ wrapped=true;
+ }
+ }
+
+ // Bare doc style
+ if (!wrapped) {
+ Class inputType = type.getInstanceClass();
+ if (inputType == null)
+ inputType = Object.class;
+ inputTypes.add(inputType);
+ }
+
+ } else {
+ // FIXME only support elements for now
+ }
+ }
+
+ // Derive the return type from the output message part (also support doc-wrapped and doc-bare here)
+ Class outputType=Void.class;
+ if (operation.getOutput() != null && operation.getOutput().getMessage()!=null && !operation.getOutput().getMessage().getParts().isEmpty()) {
+ QName qname=((Part)operation.getOutput().getMessage().getParts().values().iterator().next()).getElementName();
+ if (qname!=null) {
+ Property property = xsdHelper.getGlobalProperty(qname.getNamespaceURI(), qname.getLocalPart(), true);
+ commonj.sdo.Type type = property.getType();
+ if (wrapped) {
+ if (!type.getProperties().isEmpty()) {
+ outputType=((Property)type.getProperties().get(0)).getType().getInstanceClass();
+ if (outputType==null)
+ outputType=Object.class;
+ }
+ } else {
+ outputType = type.getInstanceClass();
+ if (outputType==null)
+ outputType=Object.class;
+ }
+ } else {
+ // FIXME only support elements for now
+ }
+ }
+
+ // FIXME integrate XSD to Java type mapping here
+ StringBuffer inputSignature=new StringBuffer();
+ for (Class inputType : inputTypes) {
+ inputSignature.append(Type.getDescriptor(inputType));
+ }
+ String outputSignature = Type.getDescriptor(outputType);
+
+ cw.visitMethod(ACC_PUBLIC + ACC_ABSTRACT, methodName, '(' + inputSignature.toString() + ')' + outputSignature, null, null).visitEnd();
+ }
+
+ // Generate the bytecodes
+ cw.visitEnd();
+ byte[] bytes = cw.toByteArray();
+
+ // Add the class to the resource loader
+
+ return resourceLoader.addClass(bytes);
+
+ } finally {
+ Thread.currentThread().setContextClassLoader(cl);
+ }
+
+ }
+
+}