blob: 44c4f1e2b93b7ad4af17e4cefec6030dc605a7c7 [file] [log] [blame]
/**
*
* 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);
}
}