| /** |
| * |
| * 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.openejb.server.axis; |
| |
| import org.apache.axis.constants.Style; |
| import org.apache.axis.constants.Use; |
| import org.apache.axis.description.FaultDesc; |
| import org.apache.axis.description.JavaServiceDesc; |
| import org.apache.axis.description.OperationDesc; |
| import org.apache.axis.description.ParameterDesc; |
| import org.apache.axis.encoding.DefaultJAXRPC11TypeMappingImpl; |
| import org.apache.axis.encoding.DefaultSOAPEncodingTypeMappingImpl; |
| import org.apache.axis.encoding.TypeMapping; |
| import org.apache.axis.encoding.TypeMappingImpl; |
| import org.apache.axis.encoding.TypeMappingRegistryImpl; |
| import org.apache.axis.encoding.XMLType; |
| import org.apache.axis.encoding.ser.ArrayDeserializerFactory; |
| import org.apache.axis.encoding.ser.ArraySerializerFactory; |
| import org.apache.axis.encoding.ser.BaseDeserializerFactory; |
| import org.apache.axis.encoding.ser.BaseSerializerFactory; |
| import org.apache.axis.encoding.ser.BeanDeserializerFactory; |
| import org.apache.axis.encoding.ser.BeanSerializerFactory; |
| import org.apache.axis.encoding.ser.EnumDeserializerFactory; |
| import org.apache.axis.encoding.ser.EnumSerializerFactory; |
| import org.apache.axis.encoding.ser.SimpleListDeserializerFactory; |
| import org.apache.axis.encoding.ser.SimpleListSerializerFactory; |
| import org.apache.openejb.OpenEJBException; |
| import org.apache.openejb.server.axis.assembler.BindingStyle; |
| import org.apache.openejb.server.axis.assembler.JaxRpcFaultInfo; |
| import org.apache.openejb.server.axis.assembler.JaxRpcOperationInfo; |
| import org.apache.openejb.server.axis.assembler.JaxRpcParameterInfo; |
| import org.apache.openejb.server.axis.assembler.JaxRpcServiceInfo; |
| import org.apache.openejb.server.axis.assembler.JaxRpcTypeInfo; |
| |
| import javax.wsdl.OperationType; |
| import javax.xml.rpc.encoding.DeserializerFactory; |
| import javax.xml.rpc.encoding.SerializerFactory; |
| import java.lang.reflect.Method; |
| import java.util.ArrayList; |
| |
| public class JavaServiceDescBuilder { |
| private static final TypeMappingImpl SOAP_TYPE_MAPPING = DefaultSOAPEncodingTypeMappingImpl.getSingleton(); |
| private static final TypeMappingImpl JAXRPC_TYPE_MAPPING = DefaultJAXRPC11TypeMappingImpl.getSingleton(); |
| |
| private final JaxRpcServiceInfo serviceInfo; |
| private final ClassLoader classLoader; |
| |
| public JavaServiceDescBuilder(JaxRpcServiceInfo serviceInfo, ClassLoader classLoader) { |
| this.serviceInfo = serviceInfo; |
| this.classLoader = classLoader; |
| } |
| |
| public JavaServiceDesc createServiceDesc() throws OpenEJBException { |
| Class serviceEndpointInterface; |
| try { |
| serviceEndpointInterface = classLoader.loadClass(serviceInfo.serviceEndpointInterface); |
| } catch (ClassNotFoundException e) { |
| throw new OpenEJBException("Unable to load the service endpoint interface " + serviceInfo.serviceEndpointInterface, e); |
| } |
| |
| JavaServiceDesc serviceDesc = new JavaServiceDesc(); |
| serviceDesc.setName(serviceInfo.name); |
| serviceDesc.setEndpointURL(serviceInfo.endpointURL); |
| serviceDesc.setWSDLFile(serviceInfo.wsdlFile); |
| |
| BindingStyle bindingStyle = serviceInfo.defaultBindingStyle; |
| switch (bindingStyle) { |
| case RPC_ENCODED: |
| serviceDesc.setStyle(Style.RPC); |
| serviceDesc.setUse(Use.ENCODED); |
| break; |
| case RPC_LITERAL: |
| serviceDesc.setStyle(Style.RPC); |
| serviceDesc.setUse(Use.LITERAL); |
| break; |
| case DOCUMENT_ENCODED: |
| serviceDesc.setStyle(Style.DOCUMENT); |
| serviceDesc.setUse(Use.ENCODED); |
| break; |
| case DOCUMENT_LITERAL: |
| serviceDesc.setStyle(Style.DOCUMENT); |
| serviceDesc.setUse(Use.LITERAL); |
| break; |
| case DOCUMENT_LITERAL_WRAPPED: |
| serviceDesc.setStyle(Style.WRAPPED); |
| serviceDesc.setUse(Use.LITERAL); |
| break; |
| } |
| |
| // Operations |
| for (JaxRpcOperationInfo operationInfo : serviceInfo.operations) { |
| OperationDesc operationDesc = buildOperationDesc(operationInfo, serviceEndpointInterface); |
| serviceDesc.addOperationDesc(operationDesc); |
| } |
| |
| // Type mapping registry |
| TypeMappingRegistryImpl typeMappingRegistry = new TypeMappingRegistryImpl(); |
| typeMappingRegistry.doRegisterFromVersion("1.3"); |
| serviceDesc.setTypeMappingRegistry(typeMappingRegistry); |
| |
| // Type mapping |
| TypeMapping typeMapping = typeMappingRegistry.getOrMakeTypeMapping(serviceDesc.getUse().getEncoding()); |
| serviceDesc.setTypeMapping(typeMapping); |
| |
| // Types |
| for (JaxRpcTypeInfo type : serviceInfo.types) { |
| registerType(type, typeMapping); |
| } |
| |
| return new ReadOnlyServiceDesc(serviceDesc); |
| } |
| |
| private OperationDesc buildOperationDesc(JaxRpcOperationInfo operationInfo, Class serviceEndpointInterface) throws OpenEJBException { |
| OperationDesc operationDesc = new OperationDesc(); |
| operationDesc.setName(operationInfo.name); |
| |
| // Binding type |
| switch (operationInfo.bindingStyle) { |
| case RPC_ENCODED: |
| operationDesc.setStyle(Style.RPC); |
| operationDesc.setUse(Use.ENCODED); |
| break; |
| case RPC_LITERAL: |
| operationDesc.setStyle(Style.RPC); |
| operationDesc.setUse(Use.LITERAL); |
| break; |
| case DOCUMENT_ENCODED: |
| operationDesc.setStyle(Style.DOCUMENT); |
| operationDesc.setUse(Use.ENCODED); |
| break; |
| case DOCUMENT_LITERAL: |
| operationDesc.setStyle(Style.DOCUMENT); |
| operationDesc.setUse(Use.LITERAL); |
| break; |
| case DOCUMENT_LITERAL_WRAPPED: |
| operationDesc.setStyle(Style.WRAPPED); |
| operationDesc.setUse(Use.LITERAL); |
| break; |
| } |
| |
| // Operation style |
| switch (operationInfo.operationStyle) { |
| case NOTIFICATION: |
| operationDesc.setMep(OperationType.NOTIFICATION); |
| break; |
| case ONE_WAY: |
| operationDesc.setMep(OperationType.ONE_WAY); |
| break; |
| case REQUEST_RESPONSE: |
| operationDesc.setMep(OperationType.REQUEST_RESPONSE); |
| break; |
| case SOLICIT_RESPONSE: |
| operationDesc.setMep(OperationType.SOLICIT_RESPONSE); |
| break; |
| } |
| |
| // Build parameters |
| Class[] paramTypes = new Class[operationInfo.parameters.size()]; |
| int i = 0; |
| for (JaxRpcParameterInfo parameterInfo : operationInfo.parameters) { |
| ParameterDesc parameterDesc = buildParameterDesc(parameterInfo); |
| operationDesc.addParameter(parameterDesc); |
| paramTypes[i++] = parameterDesc.getJavaType(); |
| } |
| |
| // Java method |
| try { |
| Method method = serviceEndpointInterface.getMethod(operationInfo.javaMethodName, paramTypes); |
| operationDesc.setMethod(method); |
| } catch (NoSuchMethodException e) { |
| String args = ""; |
| for (Class paramType : paramTypes) { |
| if (args.length() > 0) { |
| args += ", "; |
| } |
| args += paramType.getName(); |
| } |
| throw new OpenEJBException("Mapping references non-existent method in service-endpoint: " + operationInfo.javaMethodName + "(" + args + ")"); |
| } |
| |
| // |
| // Set return |
| // |
| if (operationInfo.returnQName != null) { |
| operationDesc.setReturnQName(operationInfo.returnQName); |
| operationDesc.setReturnType(operationInfo.returnXmlType); |
| try { |
| Class<?> returnClass = classLoader.loadClass(operationInfo.returnJavaType); |
| operationDesc.setReturnClass(returnClass); |
| } catch (ClassNotFoundException e) { |
| throw new OpenEJBException(); |
| } |
| } else if (operationInfo.operationStyle == JaxRpcOperationInfo.OperationStyle.REQUEST_RESPONSE) { |
| operationDesc.setReturnQName(null); |
| operationDesc.setReturnType(XMLType.AXIS_VOID); |
| operationDesc.setReturnClass(void.class); |
| } |
| |
| // Build faults |
| for (JaxRpcFaultInfo faultInfo : operationInfo.faults) { |
| FaultDesc faultDesc = buildFaultDesc(faultInfo); |
| operationDesc.addFault(faultDesc); |
| } |
| |
| return operationDesc; |
| } |
| |
| private ParameterDesc buildParameterDesc(JaxRpcParameterInfo parameterInfo) throws OpenEJBException { |
| byte mode = ParameterDesc.modeFromString(parameterInfo.mode.toString()); |
| |
| boolean inHeader = parameterInfo.soapHeader && parameterInfo.mode.isIn(); |
| boolean outHeader = parameterInfo.soapHeader && parameterInfo.mode.isOut(); |
| |
| Class<?> javaType; |
| try { |
| javaType = classLoader.loadClass(parameterInfo.javaType); |
| } catch (ClassNotFoundException e) { |
| throw new OpenEJBException("Unable to load parameter type " + parameterInfo.javaType); |
| } |
| |
| ParameterDesc parameterDesc = new ParameterDesc(parameterInfo.qname, mode, parameterInfo.xmlType, javaType, inHeader, outHeader); |
| return parameterDesc; |
| } |
| |
| private FaultDesc buildFaultDesc(JaxRpcFaultInfo faultInfo) throws OpenEJBException { |
| FaultDesc faultDesc = new FaultDesc(faultInfo.qname, faultInfo.javaType, faultInfo.xmlType, faultInfo.complex); |
| |
| ArrayList<ParameterDesc> parameters = new ArrayList<ParameterDesc>(); |
| for (JaxRpcParameterInfo parameterInfo : faultInfo.parameters) { |
| ParameterDesc parameterDesc = buildParameterDesc(parameterInfo); |
| parameters.add(parameterDesc); |
| } |
| faultDesc.setParameters(parameters); |
| |
| return faultDesc; |
| } |
| |
| private void registerType(JaxRpcTypeInfo type, TypeMapping typeMapping) throws OpenEJBException { |
| Class javaType; |
| try { |
| javaType = classLoader.loadClass(type.javaType); |
| } catch (ClassNotFoundException e) { |
| throw new OpenEJBException("Could not load class for JaxRpc mapping " + type.javaType); |
| } |
| |
| // Default uses the generic Java Beans serializer/deserializer |
| Class serializerFactoryClass = BeanSerializerFactory.class; |
| Class deserializerFactoryClass = BeanDeserializerFactory.class; |
| switch (type.serializerType) { |
| case ARRAY: |
| serializerFactoryClass = ArraySerializerFactory.class; |
| deserializerFactoryClass = ArrayDeserializerFactory.class; |
| break; |
| case ENUM: |
| serializerFactoryClass = EnumSerializerFactory.class; |
| deserializerFactoryClass = EnumDeserializerFactory.class; |
| break; |
| case LIST: |
| serializerFactoryClass = SimpleListSerializerFactory.class; |
| deserializerFactoryClass = SimpleListDeserializerFactory.class; |
| break; |
| default: |
| if (type.simpleBaseType != null) { |
| Class clazz = SOAP_TYPE_MAPPING.getClassForQName(type.simpleBaseType, null, null); |
| if (null != clazz) { |
| // Built in SOAP type |
| serializerFactoryClass = SOAP_TYPE_MAPPING.getSerializer(clazz, type.simpleBaseType).getClass(); |
| deserializerFactoryClass = SOAP_TYPE_MAPPING.getDeserializer(clazz, type.simpleBaseType, null).getClass(); |
| } else { |
| clazz = JAXRPC_TYPE_MAPPING.getClassForQName(type.simpleBaseType, null, null); |
| if (null != clazz) { |
| // Built in XML schema type |
| serializerFactoryClass = JAXRPC_TYPE_MAPPING.getSerializer(clazz, type.simpleBaseType).getClass(); |
| deserializerFactoryClass = JAXRPC_TYPE_MAPPING.getDeserializer(clazz, type.simpleBaseType, null).getClass(); |
| } |
| } |
| } |
| break; |
| } |
| |
| SerializerFactory serializerFactory = BaseSerializerFactory.createFactory(serializerFactoryClass, javaType, type.qname); |
| DeserializerFactory deserializerFactory = BaseDeserializerFactory.createFactory(deserializerFactoryClass, javaType, type.qname); |
| |
| typeMapping.register(javaType, type.qname, serializerFactory, deserializerFactory); |
| } |
| } |