001: /**
002: *
003: * Licensed to the Apache Software Foundation (ASF) under one or more
004: * contributor license agreements. See the NOTICE file distributed with
005: * this work for additional information regarding copyright ownership.
006: * The ASF licenses this file to You under the Apache License, Version 2.0
007: * (the "License"); you may not use this file except in compliance with
008: * the License. You may obtain a copy of the License at
009: *
010: * http://www.apache.org/licenses/LICENSE-2.0
011: *
012: * Unless required by applicable law or agreed to in writing, software
013: * distributed under the License is distributed on an "AS IS" BASIS,
014: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015: * See the License for the specific language governing permissions and
016: * limitations under the License.
017: */package org.apache.openejb.server.axis;
018:
019: import org.apache.axis.constants.Style;
020: import org.apache.axis.constants.Use;
021: import org.apache.axis.description.FaultDesc;
022: import org.apache.axis.description.JavaServiceDesc;
023: import org.apache.axis.description.OperationDesc;
024: import org.apache.axis.description.ParameterDesc;
025: import org.apache.axis.encoding.DefaultJAXRPC11TypeMappingImpl;
026: import org.apache.axis.encoding.DefaultSOAPEncodingTypeMappingImpl;
027: import org.apache.axis.encoding.TypeMapping;
028: import org.apache.axis.encoding.TypeMappingImpl;
029: import org.apache.axis.encoding.TypeMappingRegistryImpl;
030: import org.apache.axis.encoding.XMLType;
031: import org.apache.axis.encoding.ser.ArrayDeserializerFactory;
032: import org.apache.axis.encoding.ser.ArraySerializerFactory;
033: import org.apache.axis.encoding.ser.BaseDeserializerFactory;
034: import org.apache.axis.encoding.ser.BaseSerializerFactory;
035: import org.apache.axis.encoding.ser.BeanDeserializerFactory;
036: import org.apache.axis.encoding.ser.BeanSerializerFactory;
037: import org.apache.axis.encoding.ser.EnumDeserializerFactory;
038: import org.apache.axis.encoding.ser.EnumSerializerFactory;
039: import org.apache.axis.encoding.ser.SimpleListDeserializerFactory;
040: import org.apache.axis.encoding.ser.SimpleListSerializerFactory;
041: import org.apache.openejb.OpenEJBException;
042: import org.apache.openejb.server.axis.assembler.BindingStyle;
043: import org.apache.openejb.server.axis.assembler.JaxRpcFaultInfo;
044: import org.apache.openejb.server.axis.assembler.JaxRpcOperationInfo;
045: import org.apache.openejb.server.axis.assembler.JaxRpcParameterInfo;
046: import org.apache.openejb.server.axis.assembler.JaxRpcServiceInfo;
047: import org.apache.openejb.server.axis.assembler.JaxRpcTypeInfo;
048:
049: import javax.wsdl.OperationType;
050: import javax.xml.rpc.encoding.DeserializerFactory;
051: import javax.xml.rpc.encoding.SerializerFactory;
052: import java.lang.reflect.Method;
053: import java.util.ArrayList;
054:
055: public class JavaServiceDescBuilder {
056: private static final TypeMappingImpl SOAP_TYPE_MAPPING = DefaultSOAPEncodingTypeMappingImpl
057: .getSingleton();
058: private static final TypeMappingImpl JAXRPC_TYPE_MAPPING = DefaultJAXRPC11TypeMappingImpl
059: .getSingleton();
060:
061: private final JaxRpcServiceInfo serviceInfo;
062: private final ClassLoader classLoader;
063:
064: public JavaServiceDescBuilder(JaxRpcServiceInfo serviceInfo,
065: ClassLoader classLoader) {
066: this .serviceInfo = serviceInfo;
067: this .classLoader = classLoader;
068: }
069:
070: public JavaServiceDesc createServiceDesc() throws OpenEJBException {
071: Class serviceEndpointInterface;
072: try {
073: serviceEndpointInterface = classLoader
074: .loadClass(serviceInfo.serviceEndpointInterface);
075: } catch (ClassNotFoundException e) {
076: throw new OpenEJBException(
077: "Unable to load the service endpoint interface "
078: + serviceInfo.serviceEndpointInterface, e);
079: }
080:
081: JavaServiceDesc serviceDesc = new JavaServiceDesc();
082: serviceDesc.setName(serviceInfo.name);
083: serviceDesc.setEndpointURL(serviceInfo.endpointURL);
084: serviceDesc.setWSDLFile(serviceInfo.wsdlFile);
085:
086: BindingStyle bindingStyle = serviceInfo.defaultBindingStyle;
087: switch (bindingStyle) {
088: case RPC_ENCODED:
089: serviceDesc.setStyle(Style.RPC);
090: serviceDesc.setUse(Use.ENCODED);
091: break;
092: case RPC_LITERAL:
093: serviceDesc.setStyle(Style.RPC);
094: serviceDesc.setUse(Use.LITERAL);
095: break;
096: case DOCUMENT_ENCODED:
097: serviceDesc.setStyle(Style.DOCUMENT);
098: serviceDesc.setUse(Use.ENCODED);
099: break;
100: case DOCUMENT_LITERAL:
101: serviceDesc.setStyle(Style.DOCUMENT);
102: serviceDesc.setUse(Use.LITERAL);
103: break;
104: case DOCUMENT_LITERAL_WRAPPED:
105: serviceDesc.setStyle(Style.WRAPPED);
106: serviceDesc.setUse(Use.LITERAL);
107: break;
108: }
109:
110: // Operations
111: for (JaxRpcOperationInfo operationInfo : serviceInfo.operations) {
112: OperationDesc operationDesc = buildOperationDesc(
113: operationInfo, serviceEndpointInterface);
114: serviceDesc.addOperationDesc(operationDesc);
115: }
116:
117: // Type mapping registry
118: TypeMappingRegistryImpl typeMappingRegistry = new TypeMappingRegistryImpl();
119: typeMappingRegistry.doRegisterFromVersion("1.3");
120: serviceDesc.setTypeMappingRegistry(typeMappingRegistry);
121:
122: // Type mapping
123: TypeMapping typeMapping = typeMappingRegistry
124: .getOrMakeTypeMapping(serviceDesc.getUse()
125: .getEncoding());
126: serviceDesc.setTypeMapping(typeMapping);
127:
128: // Types
129: for (JaxRpcTypeInfo type : serviceInfo.types) {
130: registerType(type, typeMapping);
131: }
132:
133: return new ReadOnlyServiceDesc(serviceDesc);
134: }
135:
136: private OperationDesc buildOperationDesc(
137: JaxRpcOperationInfo operationInfo,
138: Class serviceEndpointInterface) throws OpenEJBException {
139: OperationDesc operationDesc = new OperationDesc();
140: operationDesc.setName(operationInfo.name);
141:
142: // Binding type
143: switch (operationInfo.bindingStyle) {
144: case RPC_ENCODED:
145: operationDesc.setStyle(Style.RPC);
146: operationDesc.setUse(Use.ENCODED);
147: break;
148: case RPC_LITERAL:
149: operationDesc.setStyle(Style.RPC);
150: operationDesc.setUse(Use.LITERAL);
151: break;
152: case DOCUMENT_ENCODED:
153: operationDesc.setStyle(Style.DOCUMENT);
154: operationDesc.setUse(Use.ENCODED);
155: break;
156: case DOCUMENT_LITERAL:
157: operationDesc.setStyle(Style.DOCUMENT);
158: operationDesc.setUse(Use.LITERAL);
159: break;
160: case DOCUMENT_LITERAL_WRAPPED:
161: operationDesc.setStyle(Style.WRAPPED);
162: operationDesc.setUse(Use.LITERAL);
163: break;
164: }
165:
166: // Operation style
167: switch (operationInfo.operationStyle) {
168: case NOTIFICATION:
169: operationDesc.setMep(OperationType.NOTIFICATION);
170: break;
171: case ONE_WAY:
172: operationDesc.setMep(OperationType.ONE_WAY);
173: break;
174: case REQUEST_RESPONSE:
175: operationDesc.setMep(OperationType.REQUEST_RESPONSE);
176: break;
177: case SOLICIT_RESPONSE:
178: operationDesc.setMep(OperationType.SOLICIT_RESPONSE);
179: break;
180: }
181:
182: // Build parameters
183: Class[] paramTypes = new Class[operationInfo.parameters.size()];
184: int i = 0;
185: for (JaxRpcParameterInfo parameterInfo : operationInfo.parameters) {
186: ParameterDesc parameterDesc = buildParameterDesc(parameterInfo);
187: operationDesc.addParameter(parameterDesc);
188: paramTypes[i++] = parameterDesc.getJavaType();
189: }
190:
191: // Java method
192: try {
193: Method method = serviceEndpointInterface.getMethod(
194: operationInfo.javaMethodName, paramTypes);
195: operationDesc.setMethod(method);
196: } catch (NoSuchMethodException e) {
197: String args = "";
198: for (Class paramType : paramTypes) {
199: if (args.length() > 0) {
200: args += ", ";
201: }
202: args += paramType.getName();
203: }
204: throw new OpenEJBException(
205: "Mapping references non-existent method in service-endpoint: "
206: + operationInfo.javaMethodName + "(" + args
207: + ")");
208: }
209:
210: //
211: // Set return
212: //
213: if (operationInfo.returnQName != null) {
214: operationDesc.setReturnQName(operationInfo.returnQName);
215: operationDesc.setReturnType(operationInfo.returnXmlType);
216: try {
217: Class<?> returnClass = classLoader
218: .loadClass(operationInfo.returnJavaType);
219: operationDesc.setReturnClass(returnClass);
220: } catch (ClassNotFoundException e) {
221: throw new OpenEJBException();
222: }
223: } else if (operationInfo.operationStyle == JaxRpcOperationInfo.OperationStyle.REQUEST_RESPONSE) {
224: operationDesc.setReturnQName(null);
225: operationDesc.setReturnType(XMLType.AXIS_VOID);
226: operationDesc.setReturnClass(void.class);
227: }
228:
229: // Build faults
230: for (JaxRpcFaultInfo faultInfo : operationInfo.faults) {
231: FaultDesc faultDesc = buildFaultDesc(faultInfo);
232: operationDesc.addFault(faultDesc);
233: }
234:
235: return operationDesc;
236: }
237:
238: private ParameterDesc buildParameterDesc(
239: JaxRpcParameterInfo parameterInfo) throws OpenEJBException {
240: byte mode = ParameterDesc.modeFromString(parameterInfo.mode
241: .toString());
242:
243: boolean inHeader = parameterInfo.soapHeader
244: && parameterInfo.mode.isIn();
245: boolean outHeader = parameterInfo.soapHeader
246: && parameterInfo.mode.isOut();
247:
248: Class<?> javaType;
249: try {
250: javaType = classLoader.loadClass(parameterInfo.javaType);
251: } catch (ClassNotFoundException e) {
252: throw new OpenEJBException("Unable to load parameter type "
253: + parameterInfo.javaType);
254: }
255:
256: ParameterDesc parameterDesc = new ParameterDesc(
257: parameterInfo.qname, mode, parameterInfo.xmlType,
258: javaType, inHeader, outHeader);
259: return parameterDesc;
260: }
261:
262: private FaultDesc buildFaultDesc(JaxRpcFaultInfo faultInfo)
263: throws OpenEJBException {
264: FaultDesc faultDesc = new FaultDesc(faultInfo.qname,
265: faultInfo.javaType, faultInfo.xmlType,
266: faultInfo.complex);
267:
268: ArrayList<ParameterDesc> parameters = new ArrayList<ParameterDesc>();
269: for (JaxRpcParameterInfo parameterInfo : faultInfo.parameters) {
270: ParameterDesc parameterDesc = buildParameterDesc(parameterInfo);
271: parameters.add(parameterDesc);
272: }
273: faultDesc.setParameters(parameters);
274:
275: return faultDesc;
276: }
277:
278: private void registerType(JaxRpcTypeInfo type,
279: TypeMapping typeMapping) throws OpenEJBException {
280: Class javaType;
281: try {
282: javaType = classLoader.loadClass(type.javaType);
283: } catch (ClassNotFoundException e) {
284: throw new OpenEJBException(
285: "Could not load class for JaxRpc mapping "
286: + type.javaType);
287: }
288:
289: // Default uses the generic Java Beans serializer/deserializer
290: Class serializerFactoryClass = BeanSerializerFactory.class;
291: Class deserializerFactoryClass = BeanDeserializerFactory.class;
292: switch (type.serializerType) {
293: case ARRAY:
294: serializerFactoryClass = ArraySerializerFactory.class;
295: deserializerFactoryClass = ArrayDeserializerFactory.class;
296: break;
297: case ENUM:
298: serializerFactoryClass = EnumSerializerFactory.class;
299: deserializerFactoryClass = EnumDeserializerFactory.class;
300: break;
301: case LIST:
302: serializerFactoryClass = SimpleListSerializerFactory.class;
303: deserializerFactoryClass = SimpleListDeserializerFactory.class;
304: break;
305: default:
306: if (type.simpleBaseType != null) {
307: Class clazz = SOAP_TYPE_MAPPING.getClassForQName(
308: type.simpleBaseType, null, null);
309: if (null != clazz) {
310: // Built in SOAP type
311: serializerFactoryClass = SOAP_TYPE_MAPPING
312: .getSerializer(clazz, type.simpleBaseType)
313: .getClass();
314: deserializerFactoryClass = SOAP_TYPE_MAPPING
315: .getDeserializer(clazz,
316: type.simpleBaseType, null)
317: .getClass();
318: } else {
319: clazz = JAXRPC_TYPE_MAPPING.getClassForQName(
320: type.simpleBaseType, null, null);
321: if (null != clazz) {
322: // Built in XML schema type
323: serializerFactoryClass = JAXRPC_TYPE_MAPPING
324: .getSerializer(clazz,
325: type.simpleBaseType).getClass();
326: deserializerFactoryClass = JAXRPC_TYPE_MAPPING
327: .getDeserializer(clazz,
328: type.simpleBaseType, null)
329: .getClass();
330: }
331: }
332: }
333: break;
334: }
335:
336: SerializerFactory serializerFactory = BaseSerializerFactory
337: .createFactory(serializerFactoryClass, javaType,
338: type.qname);
339: DeserializerFactory deserializerFactory = BaseDeserializerFactory
340: .createFactory(deserializerFactoryClass, javaType,
341: type.qname);
342:
343: typeMapping.register(javaType, type.qname, serializerFactory,
344: deserializerFactory);
345: }
346: }
|