/** * * 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); } }