summaryrefslogtreecommitdiffstats
path: root/sca-java-2.x/tags/2.0.1-RC1/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/impl/JAXWSProcessor.java
diff options
context:
space:
mode:
Diffstat (limited to 'sca-java-2.x/tags/2.0.1-RC1/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/impl/JAXWSProcessor.java')
-rw-r--r--sca-java-2.x/tags/2.0.1-RC1/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/impl/JAXWSProcessor.java337
1 files changed, 337 insertions, 0 deletions
diff --git a/sca-java-2.x/tags/2.0.1-RC1/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/impl/JAXWSProcessor.java b/sca-java-2.x/tags/2.0.1-RC1/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/impl/JAXWSProcessor.java
new file mode 100644
index 0000000000..0db8a96229
--- /dev/null
+++ b/sca-java-2.x/tags/2.0.1-RC1/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/impl/JAXWSProcessor.java
@@ -0,0 +1,337 @@
+/*
+ * 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.implementation.java.introspect.impl;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Method;
+
+import javax.jws.WebParam;
+import javax.jws.WebResult;
+import javax.jws.WebService;
+import javax.jws.soap.SOAPBinding;
+import javax.xml.ws.BindingType;
+import javax.xml.ws.ServiceMode;
+import javax.xml.ws.WebServiceProvider;
+
+import org.apache.tuscany.sca.assembly.AssemblyFactory;
+import org.apache.tuscany.sca.assembly.Service;
+import org.apache.tuscany.sca.assembly.xml.Constants;
+import org.apache.tuscany.sca.binding.ws.WebServiceBinding;
+import org.apache.tuscany.sca.binding.ws.WebServiceBindingFactory;
+import org.apache.tuscany.sca.binding.ws.xml.WebServiceConstants;
+import org.apache.tuscany.sca.core.ExtensionPointRegistry;
+import org.apache.tuscany.sca.core.FactoryExtensionPoint;
+import org.apache.tuscany.sca.implementation.java.IntrospectionException;
+import org.apache.tuscany.sca.implementation.java.JavaImplementation;
+import org.apache.tuscany.sca.implementation.java.introspect.BaseJavaClassVisitor;
+import org.apache.tuscany.sca.interfacedef.InvalidInterfaceException;
+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.apache.tuscany.sca.interfacedef.wsdl.WSDLFactory;
+import org.apache.tuscany.sca.interfacedef.wsdl.WSDLInterface;
+import org.apache.tuscany.sca.interfacedef.wsdl.WSDLInterfaceContract;
+import org.apache.tuscany.sca.policy.ExtensionType;
+import org.apache.tuscany.sca.policy.Intent;
+import org.apache.tuscany.sca.policy.PolicyFactory;
+import org.apache.tuscany.sca.policy.PolicySubject;
+
+/**
+ * Process JAXWS annotations and updates the component type accordingly
+ *
+ */
+public class JAXWSProcessor extends BaseJavaClassVisitor {
+
+ private PolicyFactory policyFactory;
+ private WSDLFactory wsdlFactory;
+ private WebServiceBindingFactory wsBindingFactory;
+
+ public JAXWSProcessor(ExtensionPointRegistry registry) {
+ super(registry);
+ FactoryExtensionPoint factories = registry.getExtensionPoint(FactoryExtensionPoint.class);
+ this.wsdlFactory = factories.getFactory(WSDLFactory.class);
+ this.assemblyFactory = factories.getFactory(AssemblyFactory.class);
+ this.policyFactory = factories.getFactory(PolicyFactory.class);
+ this.javaInterfaceFactory = factories.getFactory(JavaInterfaceFactory.class);
+ this.wsBindingFactory = factories.getFactory(WebServiceBindingFactory.class);
+ }
+
+ @Override
+ public <T> void visitClass(Class<T> clazz, JavaImplementation type) throws IntrospectionException {
+
+ boolean hasJaxwsAnnotation = false;
+
+ // Process @ServiceMode annotation - JCA 11013
+ if ( clazz.getAnnotation(ServiceMode.class) != null ) {
+ addSOAPIntent(type);
+ hasJaxwsAnnotation = true;
+ }
+
+ // Process @WebService annotation - POJO_8029, POJO_8030
+ WebService webServiceAnnotation = clazz.getAnnotation(WebService.class);
+ org.oasisopen.sca.annotation.Service serviceAnnotation = clazz.getAnnotation(org.oasisopen.sca.annotation.Service.class);
+
+ if (webServiceAnnotation != null &&
+ serviceAnnotation == null) {
+ String serviceName = clazz.getSimpleName();
+ serviceName = getValue(webServiceAnnotation.name(), serviceName);
+
+ String serviceInterfaceClassName = webServiceAnnotation.endpointInterface();
+
+ String wsdlLocation = webServiceAnnotation.wsdlLocation();
+
+ try {
+ createService(type, clazz, serviceName, serviceInterfaceClassName, wsdlLocation, false);
+ } catch (InvalidInterfaceException e) {
+ throw new IntrospectionException(e);
+ }
+ hasJaxwsAnnotation = true;
+ }
+
+ // Process @WebServiceProvider annotation - JCA_11015, POJO_8034
+ WebServiceProvider webServiceProviderAnnotation = clazz.getAnnotation(WebServiceProvider.class);
+ if (webServiceProviderAnnotation != null) {
+ // if the implmentation already has a service set, use it's name
+ // and the new service, which uses the implementation as an interface,
+ // will be replaced
+ String serviceName = clazz.getSimpleName();
+
+ if (type.getServices().size() > 0){
+ serviceName = ((Service)type.getServices().get(0)).getName();
+ }
+
+ // the annotation may specify a service name
+ serviceName = getValue(webServiceProviderAnnotation.serviceName(), serviceName);
+
+ String wsdlLocation = webServiceProviderAnnotation.wsdlLocation();
+
+ // Make sure that there is a service with an interface
+ // based on the implementation class and have it replace
+ // any service with the same name
+ try {
+ createService(type, clazz, serviceName, null, wsdlLocation, true);
+ } catch (InvalidInterfaceException e) {
+ throw new IntrospectionException(e);
+ }
+
+ // Make sure all service references are remotable
+ for ( Service service : type.getServices() ) {
+ service.getInterfaceContract().getInterface().setRemotable(true);
+ }
+
+ hasJaxwsAnnotation = true;
+ }
+
+ // Process @WebParam and @WebResult annotations - POJO_8031, POJO_8032
+ Class<?> interfaze = clazz;
+ Method[] implMethods = interfaze.getDeclaredMethods();
+ for ( Service service : type.getServices() ) {
+ JavaInterface javaInterface = (JavaInterface)service.getInterfaceContract().getInterface();
+ interfaze = javaInterface.getJavaClass();
+
+ if (interfaze == null){
+ // this interface has come from an @WebService enpointInterface annotation
+ // so hasn't been resolved. Use the implementation class as the interface
+ interfaze = clazz;
+ }
+
+ boolean hasHeaderParam = false;
+ for (Method method : interfaze.getDeclaredMethods()){
+ // find the impl method for this service method
+ for (int i = 0; i < implMethods.length; i++){
+ Method implMethod = implMethods[i];
+ if (implMethod.getName().equals(method.getName())){
+ for (int j = 0; j < implMethod.getParameterTypes().length; j++) {
+ WebParam webParamAnnotation = getParameterAnnotation(implMethod, j, WebParam.class);
+ if (webParamAnnotation != null &&
+ webParamAnnotation.header()) {
+ hasHeaderParam = true;
+ break;
+ }
+ }
+
+ WebResult webResultAnnotation = implMethod.getAnnotation(WebResult.class);
+ if (webResultAnnotation != null &&
+ webResultAnnotation.header()){
+ hasHeaderParam = true;
+ break;
+ }
+ }
+ }
+ }
+
+ if (hasHeaderParam){
+ // Add a SOAP intent to the service
+ addSOAPIntent(service);
+ hasJaxwsAnnotation = true;
+ }
+ }
+
+ // Process @SOAPBinding annotation - POJO_8033
+ if ( clazz.getAnnotation(SOAPBinding.class) != null ) {
+ // If the implementation is annotated with @SOAPBinding,
+ // give all services a SOAP intent
+ for ( Service service : type.getServices() ) {
+ addSOAPIntent(service);
+ }
+ hasJaxwsAnnotation = true;
+ }
+
+
+ // Process @BindingType annotation - POJO_8037
+ BindingType bindingType = clazz.getAnnotation(BindingType.class);
+
+ if ( bindingType != null ) {
+ String bindingTypeValue = bindingType.value();
+ for ( Service service : type.getServices() ) {
+ addBindingTypeIntent(service, bindingTypeValue);
+ }
+ hasJaxwsAnnotation = true;
+ }
+
+ if (hasJaxwsAnnotation == true){
+ // Note that services are based on JAXWS annotations in case
+ // we need to know later. Add a ws binding and a JAXWS annotation
+ // implies a WS binding
+ for ( Service service : type.getServices() ) {
+ service.setJAXWSService(true);
+ createWSBinding(type, service);
+ }
+ }
+
+
+
+ }
+
+ private void addBindingTypeIntent(PolicySubject subject,
+ String bindingTypeValue) {
+
+ Intent soapIntent = policyFactory.createIntent();
+ if ( javax.xml.ws.soap.SOAPBinding.SOAP11HTTP_BINDING.equals(bindingTypeValue)) {
+ soapIntent.setName(Constants.SOAP11_INTENT);
+ } else if ( javax.xml.ws.soap.SOAPBinding.SOAP12HTTP_BINDING.equals(bindingTypeValue)) {
+ soapIntent.setName(Constants.SOAP12_INTENT);
+ } else {
+ soapIntent.setName(Constants.SOAP11_INTENT);
+ }
+
+ subject.getRequiredIntents().add(soapIntent);
+
+ }
+
+ /**
+ * Utility methods
+ */
+
+ private static String getValue(String value, String defaultValue) {
+ return "".equals(value) ? defaultValue : value;
+ }
+
+ private Service createService(JavaImplementation type, Class<?> clazz, String serviceName, String javaInterfaceName, String wsdlFileName, boolean replace) throws InvalidInterfaceException, IntrospectionException {
+ Service service = assemblyFactory.createService();
+
+ if (serviceName != null) {
+ service.setName(serviceName);
+ } else if (javaInterfaceName != null){
+ service.setName(javaInterfaceName.substring(javaInterfaceName.lastIndexOf('.')));
+ }
+
+ // create the physical Java interface contract
+ JavaInterfaceContract javaInterfaceContract = javaInterfaceFactory.createJavaInterfaceContract();;
+ service.setInterfaceContract(javaInterfaceContract);
+
+ if (javaInterfaceName != null &&
+ javaInterfaceName.length() > 0){
+ JavaInterface callInterface = javaInterfaceFactory.createJavaInterface();
+ callInterface.setName(javaInterfaceName);
+ callInterface.setRemotable(true);
+ callInterface.setUnresolved(true);
+ javaInterfaceContract.setInterface(callInterface);
+ } else {
+ // we use the bean class as the service interface
+ JavaInterface callInterface = javaInterfaceFactory.createJavaInterface(clazz);
+ callInterface.setRemotable(true);
+ callInterface.setUnresolved(false); // this will already be false but this makes it easy to follow the logic
+ javaInterfaceContract.setInterface(callInterface);
+ }
+
+ // create the logical WSDL interface if it's specified in
+ // the @WebService annotation
+ if (wsdlFileName != null &&
+ wsdlFileName.length() > 0){
+ WSDLInterface callInterface = wsdlFactory.createWSDLInterface();
+ callInterface.setUnresolved(true);
+ callInterface.setRemotable(true);
+
+ WSDLInterfaceContract wsdlInterfaceContract = wsdlFactory.createWSDLInterfaceContract();
+ wsdlInterfaceContract.setInterface(callInterface);
+ wsdlInterfaceContract.setLocation(wsdlFileName);
+ javaInterfaceContract.setNormalizedWSDLContract(wsdlInterfaceContract);
+ }
+
+ // add the service model into the implementation type
+ Service serviceAlreadyPresent = null;
+ for (Service typeService : type.getServices()){
+ if (typeService.getName().equals(service.getName())){
+ serviceAlreadyPresent = typeService;
+ break;
+ }
+ }
+
+ if (replace == true){
+ type.getServices().remove(serviceAlreadyPresent);
+ type.getServices().add(service);
+ } else {
+ if (serviceAlreadyPresent == null){
+ type.getServices().add(service);
+ }
+ }
+
+ return service;
+ }
+
+ private <T extends Annotation> T getParameterAnnotation(Method method, int index, Class<T> annotationType) {
+ Annotation[] annotations = method.getParameterAnnotations()[index];
+ for (Annotation annotation : annotations) {
+ if (annotation.annotationType() == annotationType) {
+ return annotationType.cast(annotation);
+ }
+ }
+ return null;
+ }
+
+ private void addSOAPIntent(PolicySubject policySubject){
+ Intent soapIntent = policyFactory.createIntent();
+ soapIntent.setName(Constants.SOAP_INTENT);
+ policySubject.getRequiredIntents().add(soapIntent);
+ }
+
+ private void createWSBinding(JavaImplementation javaImplementation, Service service){
+ if(service.getBindings().size() == 0){
+ WebServiceBinding wsBinding = wsBindingFactory.createWebServiceBinding();
+ wsBinding.setName(service.getName());
+ ExtensionType bindingType = policyFactory.createBindingType();
+ bindingType.setType(WebServiceConstants.BINDING_WS_QNAME);
+ bindingType.setUnresolved(true);
+ ((PolicySubject)wsBinding).setExtensionType(bindingType);
+ service.getBindings().add(wsBinding);
+ }
+ }
+
+}