KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > geronimo > axis > builder > HeavyweightOperationDescBuilder


1 /**
2  * Licensed to the Apache Software Foundation (ASF) under one or more
3  * contributor license agreements. See the NOTICE file distributed with
4  * this work for additional information regarding copyright ownership.
5  * The ASF licenses this file to You under the Apache License, Version 2.0
6  * (the "License"); you may not use this file except in compliance with
7  * the License. You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */

17 package org.apache.geronimo.axis.builder;
18
19 import java.lang.reflect.Method JavaDoc;
20 import java.math.BigDecimal JavaDoc;
21 import java.math.BigInteger JavaDoc;
22 import java.net.URI JavaDoc;
23 import java.util.ArrayList JavaDoc;
24 import java.util.Calendar JavaDoc;
25 import java.util.Collection JavaDoc;
26 import java.util.Collections JavaDoc;
27 import java.util.HashMap JavaDoc;
28 import java.util.HashSet JavaDoc;
29 import java.util.Iterator JavaDoc;
30 import java.util.Map JavaDoc;
31 import java.util.Set JavaDoc;
32
33 import javax.wsdl.BindingInput;
34 import javax.wsdl.BindingOperation;
35 import javax.wsdl.Fault;
36 import javax.wsdl.Message;
37 import javax.wsdl.Part;
38 import javax.wsdl.OperationType;
39 import javax.wsdl.extensions.soap.SOAPBody;
40 import javax.xml.namespace.QName JavaDoc;
41
42 import org.apache.axis.constants.Style;
43 import org.apache.axis.constants.Use;
44 import org.apache.axis.description.FaultDesc;
45 import org.apache.axis.description.OperationDesc;
46 import org.apache.axis.description.ParameterDesc;
47 import org.apache.axis.soap.SOAPConstants;
48 import org.apache.axis.encoding.XMLType;
49 import org.apache.geronimo.axis.client.OperationInfo;
50 import org.apache.geronimo.common.DeploymentException;
51 import org.apache.geronimo.kernel.ClassLoading;
52 import org.apache.geronimo.xbeans.j2ee.ConstructorParameterOrderType;
53 import org.apache.geronimo.xbeans.j2ee.ExceptionMappingType;
54 import org.apache.geronimo.xbeans.j2ee.JavaWsdlMappingType;
55 import org.apache.geronimo.xbeans.j2ee.MethodParamPartsMappingType;
56 import org.apache.geronimo.xbeans.j2ee.ServiceEndpointMethodMappingType;
57 import org.apache.geronimo.xbeans.j2ee.WsdlMessageMappingType;
58 import org.apache.geronimo.xbeans.j2ee.WsdlReturnValueMappingType;
59 import org.apache.xmlbeans.SchemaParticle;
60 import org.apache.xmlbeans.SchemaProperty;
61 import org.apache.xmlbeans.SchemaType;
62 import org.objectweb.asm.Type;
63 import org.apache.geronimo.xbeans.j2ee.JavaXmlTypeMappingType;
64 import org.apache.geronimo.webservices.builder.SchemaInfoBuilder;
65 import org.apache.geronimo.webservices.builder.WSDescriptorParser;
66
67 /**
68  * @version $Rev: 476049 $ $Date: 2006-11-16 23:35:17 -0500 (Thu, 16 Nov 2006) $
69  */

70 public class HeavyweightOperationDescBuilder extends OperationDescBuilder {
71
72     private final JavaWsdlMappingType mapping;
73     private final ServiceEndpointMethodMappingType methodMapping;
74     private final SOAPBody soapBody;
75
76
77     private final Map JavaDoc exceptionMap;
78     private final SchemaInfoBuilder schemaInfoBuilder;
79     private final ClassLoader JavaDoc classLoader;
80     private final boolean rpcStyle;
81     private final boolean documentStyle;
82     private final boolean wrappedStyle;
83     private final boolean isEncoded;
84     private final Map JavaDoc publicTypes = new HashMap JavaDoc();
85     private final Map JavaDoc anonymousTypes = new HashMap JavaDoc();
86
87     /* Keep track of in and out parameter names so we can verify that
88      * everything has been mapped and mapped correctly
89      */

90     private final Set JavaDoc inParamNames = new HashSet JavaDoc();
91     private final Set JavaDoc outParamNames = new HashSet JavaDoc();
92     private final Class JavaDoc serviceEndpointInterface;
93
94     /**
95      * Track the wrapper elements
96      */

97     private final Set JavaDoc wrapperElementQNames = new HashSet JavaDoc();
98
99     public HeavyweightOperationDescBuilder(BindingOperation bindingOperation, JavaWsdlMappingType mapping, ServiceEndpointMethodMappingType methodMapping, Style defaultStyle, Map JavaDoc exceptionMap, SchemaInfoBuilder schemaInfoBuilder, JavaXmlTypeMappingType[] javaXmlTypeMappingTypes, ClassLoader JavaDoc classLoader, Class JavaDoc serviceEndpointInterface) throws DeploymentException {
100         super(bindingOperation);
101         this.mapping = mapping;
102         this.methodMapping = methodMapping;
103         this.exceptionMap = exceptionMap;
104         this.schemaInfoBuilder = schemaInfoBuilder;
105         for (int i = 0; i < javaXmlTypeMappingTypes.length; i++) {
106             JavaXmlTypeMappingType javaXmlTypeMappingType = javaXmlTypeMappingTypes[i];
107             String JavaDoc javaClassName = javaXmlTypeMappingType.getJavaType().getStringValue().trim();
108             if (javaXmlTypeMappingType.isSetAnonymousTypeQname()) {
109                 String JavaDoc anonymousTypeQName = javaXmlTypeMappingType.getAnonymousTypeQname().getStringValue().trim();
110                 anonymousTypes.put(anonymousTypeQName, javaClassName);
111             } else if (javaXmlTypeMappingType.isSetRootTypeQname()) {
112                 QName JavaDoc qname = javaXmlTypeMappingType.getRootTypeQname().getQNameValue();
113                 publicTypes.put(qname, javaClassName);
114             }
115         }
116         this.classLoader = classLoader;
117         this.serviceEndpointInterface = serviceEndpointInterface;
118         BindingInput bindingInput = bindingOperation.getBindingInput();
119         this.soapBody = (SOAPBody) SchemaInfoBuilder.getExtensibilityElement(SOAPBody.class, bindingInput.getExtensibilityElements());
120
121         wrappedStyle = methodMapping.isSetWrappedElement();
122         if (false == wrappedStyle) {
123             Style style = Style.getStyle(soapOperation.getStyle(), defaultStyle);
124             if (style == Style.RPC) {
125                 rpcStyle = true;
126                 documentStyle = false;
127             } else {
128                 rpcStyle = false;
129                 documentStyle = true;
130             }
131         } else {
132             rpcStyle = false;
133             documentStyle = false;
134         }
135         isEncoded = Use.getUse(soapBody.getUse()) == Use.ENCODED;
136     }
137
138     public Set JavaDoc getWrapperElementQNames() throws DeploymentException {
139         buildOperationDesc();
140
141         return Collections.unmodifiableSet(wrapperElementQNames);
142     }
143
144     public boolean isEncoded() {
145         return isEncoded;
146     }
147
148     public OperationInfo buildOperationInfo(SOAPConstants soapVersion) throws DeploymentException {
149         buildOperationDesc();
150
151         String JavaDoc soapActionURI = soapOperation.getSoapActionURI();
152         boolean usesSOAPAction = (soapActionURI != null);
153         QName JavaDoc operationQName = getOperationQName();
154
155         String JavaDoc methodName = methodMapping.getJavaMethodName().getStringValue().trim();
156
157         ArrayList JavaDoc parameters = operationDesc.getParameters();
158         Type[] parameterASMTypes = new Type[parameters.size()];
159         for (int i = 0; i < parameters.size(); i++) {
160             ParameterDesc parameterDesc = (ParameterDesc) parameters.get(i);
161             parameterASMTypes[i] = Type.getType(parameterDesc.getJavaType());
162         }
163
164         Type returnASMType = (operationDesc.getReturnClass() != null) ? Type.getType(operationDesc.getReturnClass()) : Type.VOID_TYPE;
165
166         String JavaDoc methodDesc = Type.getMethodDescriptor(returnASMType, parameterASMTypes);
167         OperationInfo operationInfo = new OperationInfo(operationDesc, usesSOAPAction, soapActionURI, soapVersion, operationQName, methodName, methodDesc);
168         return operationInfo;
169     }
170
171     private QName JavaDoc getOperationQName() {
172         if (wrappedStyle) {
173             Map JavaDoc parts = operation.getInput().getMessage().getParts();
174             if (parts != null && !parts.isEmpty()) {
175                 for (Iterator JavaDoc iterator = parts.values().iterator(); iterator.hasNext();) {
176                     Part part = (Part) iterator.next();
177                     return part.getElementName();
178                 }
179             }
180         }
181         return getOperationNameFromSOAPBody();
182
183     }
184
185     public OperationDesc buildOperationDesc() throws DeploymentException {
186         if (built) {
187             return operationDesc;
188         }
189         built = true;
190
191         operationDesc.setName(operationName);
192
193         // Set to 'document', 'rpc' or 'wrapped'
194
if (wrappedStyle) {
195             operationDesc.setStyle(Style.WRAPPED);
196         } else if (rpcStyle) {
197             operationDesc.setStyle(Style.RPC);
198         } else {
199             operationDesc.setStyle(Style.DOCUMENT);
200         }
201
202         // Set to 'encoded' or 'literal'
203
Use use = Use.getUse(soapBody.getUse());
204         operationDesc.setUse(use);
205
206
207         MethodParamPartsMappingType[] paramMappings = methodMapping.getMethodParamPartsMappingArray();
208
209         /* Put the ParameterDesc instance in an array so they can be ordered properly
210          * before they are added to the the OperationDesc.
211          */

212         ParameterDesc[] parameterDescriptions = new ParameterDesc[paramMappings.length];
213
214
215         // MAP PARAMETERS
216
for (int i = 0; i < paramMappings.length; i++) {
217             MethodParamPartsMappingType paramMapping = paramMappings[i];
218             int position = paramMapping.getParamPosition().getBigIntegerValue().intValue();
219
220             ParameterDesc parameterDesc = mapParameter(paramMapping);
221
222             parameterDescriptions[position] = parameterDesc;
223         }
224
225         if (wrappedStyle) {
226             Part inputPart = getWrappedPart(input);
227             QName JavaDoc name = inputPart.getElementName();
228             SchemaType operationType = (SchemaType) schemaInfoBuilder.getComplexTypesInWsdl().get(name);
229
230             Set JavaDoc expectedInParams = new HashSet JavaDoc();
231
232             // schemaType should be complex using xsd:sequence compositor
233
SchemaParticle parametersType = operationType.getContentModel();
234             //parametersType can be null if the element has empty content such as
235
// <element name="getMarketSummary">
236
// <complexType>
237
// <sequence/>
238
// </complexType>
239
// </element>
240

241             if (parametersType != null) {
242                 if (SchemaParticle.ELEMENT == parametersType.getParticleType()) {
243                     expectedInParams.add(parametersType.getName().getLocalPart());
244                 } else if (SchemaParticle.SEQUENCE == parametersType.getParticleType()) {
245                     SchemaParticle[] parameters = parametersType.getParticleChildren();
246                     for (int i = 0; i < parameters.length; i++) {
247                         expectedInParams.add(parameters[i].getName().getLocalPart());
248                     }
249                 }
250             }
251             if (!inParamNames.equals(expectedInParams)) {
252                 throw new DeploymentException("Not all wrapper children were mapped for operation name" + operationName);
253             }
254         } else {
255             //check that all input message parts are mapped
256
if (!inParamNames.equals(input.getParts().keySet())) {
257                 throw new DeploymentException("Not all input message parts were mapped for operation name" + operationName);
258             }
259         }
260
261         Class JavaDoc[] paramTypes = new Class JavaDoc[parameterDescriptions.length];
262         for (int i = 0; i < parameterDescriptions.length; i++) {
263             ParameterDesc parameterDescription = parameterDescriptions[i];
264             if (parameterDescription == null) {
265                 throw new DeploymentException("There is no mapping for parameter number " + i + " for operation " + operationName);
266             }
267             operationDesc.addParameter(parameterDescription);
268             paramTypes[i] = parameterDescription.getJavaType();
269         }
270
271         String JavaDoc methodName = methodMapping.getJavaMethodName().getStringValue().trim();
272         Method JavaDoc method = null;
273         try {
274             method = serviceEndpointInterface.getMethod(methodName, paramTypes);
275         } catch (NoSuchMethodException JavaDoc e) {
276             String JavaDoc args = "(";
277             for (int i = 0; i < paramTypes.length; i++) {
278                 args += paramTypes[i].getName();
279                 if (i < paramTypes.length - 1) {
280                     args += ",";
281                 }
282             }
283             args += ")";
284
285             throw new DeploymentException("Mapping references non-existent method in service-endpoint: " + methodName + args);
286         }
287
288         operationDesc.setMethod(method);
289
290         // MAP RETURN TYPE
291
operationDesc.setMep(operation.getStyle());
292         if (methodMapping.isSetWsdlReturnValueMapping()) {
293             mapReturnType();
294         } else if (operation.getStyle() == OperationType.REQUEST_RESPONSE) {
295             //TODO WARNING THIS APPEARS TO SUBVERT THE COMMENT IN j2ee_jaxrpc_mapping_1_1.xsd IN service-endpoint-method-mappingType:
296
//The wsdl-return-value-mapping is not specified for one-way operations.
297
operationDesc.setReturnQName(null); //??
298
operationDesc.setReturnType(XMLType.AXIS_VOID);
299             operationDesc.setReturnClass(void.class);
300         }
301
302         if (null != output && wrappedStyle) {
303             Part inputPart = getWrappedPart(output);
304             QName JavaDoc name = inputPart.getElementName();
305             SchemaType operationType = (SchemaType) schemaInfoBuilder.getComplexTypesInWsdl().get(name);
306
307             Set JavaDoc expectedOutParams = new HashSet JavaDoc();
308
309             // schemaType should be complex using xsd:sequence compositor
310
SchemaParticle parametersType = operationType.getContentModel();
311             //again, no output can give null parametersType
312
if (parametersType != null) {
313                 if (SchemaParticle.ELEMENT == parametersType.getParticleType()) {
314                     expectedOutParams.add(parametersType.getName().getLocalPart());
315                 } else if (SchemaParticle.SEQUENCE == parametersType.getParticleType()) {
316                     SchemaParticle[] parameters = parametersType.getParticleChildren();
317                     for (int i = 0; i < parameters.length; i++) {
318                         expectedOutParams.add(parameters[i].getName().getLocalPart());
319                     }
320                 }
321             }
322             if (!outParamNames.equals(expectedOutParams)) {
323                 throw new DeploymentException("Not all wrapper children were mapped to parameters or a return value for operation " + operationName);
324             }
325         } else if (null != output) {
326             if (!outParamNames.equals(output.getParts().keySet())) {
327                 throw new DeploymentException("Not all output message parts were mapped to parameters or a return value for operation " + operationName);
328             }
329         }
330
331         Map JavaDoc faultMap = operation.getFaults();
332         for (Iterator JavaDoc iterator = faultMap.entrySet().iterator(); iterator.hasNext();) {
333             Map.Entry JavaDoc entry = (Map.Entry JavaDoc) iterator.next();
334             String JavaDoc faultName = (String JavaDoc) entry.getKey();
335             Fault fault = (Fault) entry.getValue();
336             FaultDesc faultDesc = mapException(faultName, fault);
337
338             operationDesc.addFault(faultDesc);
339         }
340         return operationDesc;
341     }
342
343     //see jaxrpc 1.1 4.2.1
344
private static final Map JavaDoc qnameToClassMap = new HashMap JavaDoc();
345
346     static {
347         qnameToClassMap.put(new QName JavaDoc("http://www.w3.org/2001/XMLSchema", "string"), String JavaDoc.class);
348         qnameToClassMap.put(new QName JavaDoc("http://www.w3.org/2001/XMLSchema", "integer"), BigInteger JavaDoc.class);
349         qnameToClassMap.put(new QName JavaDoc("http://www.w3.org/2001/XMLSchema", "int"), int.class);
350         qnameToClassMap.put(new QName JavaDoc("http://www.w3.org/2001/XMLSchema", "long"), long.class);
351         qnameToClassMap.put(new QName JavaDoc("http://www.w3.org/2001/XMLSchema", "short"), short.class);
352         qnameToClassMap.put(new QName JavaDoc("http://www.w3.org/2001/XMLSchema", "decimal"), BigDecimal JavaDoc.class);
353         qnameToClassMap.put(new QName JavaDoc("http://www.w3.org/2001/XMLSchema", "float"), float.class);
354         qnameToClassMap.put(new QName JavaDoc("http://www.w3.org/2001/XMLSchema", "double"), double.class);
355         qnameToClassMap.put(new QName JavaDoc("http://www.w3.org/2001/XMLSchema", "boolean"), boolean.class);
356         qnameToClassMap.put(new QName JavaDoc("http://www.w3.org/2001/XMLSchema", "byte"), byte.class);
357         qnameToClassMap.put(new QName JavaDoc("http://www.w3.org/2001/XMLSchema", "unsignedInt"), long.class);
358         qnameToClassMap.put(new QName JavaDoc("http://www.w3.org/2001/XMLSchema", "unsignedShort"), int.class);
359         qnameToClassMap.put(new QName JavaDoc("http://www.w3.org/2001/XMLSchema", "unsignedByte"), short.class);
360         qnameToClassMap.put(new QName JavaDoc("http://www.w3.org/2001/XMLSchema", "QName"), QName JavaDoc.class);
361         qnameToClassMap.put(new QName JavaDoc("http://www.w3.org/2001/XMLSchema", "dateTime"), Calendar JavaDoc.class);
362         qnameToClassMap.put(new QName JavaDoc("http://www.w3.org/2001/XMLSchema", "date"), Calendar JavaDoc.class);
363         qnameToClassMap.put(new QName JavaDoc("http://www.w3.org/2001/XMLSchema", "time"), Calendar JavaDoc.class);
364         qnameToClassMap.put(new QName JavaDoc("http://www.w3.org/2001/XMLSchema", "anyURI"), URI JavaDoc.class);
365         qnameToClassMap.put(new QName JavaDoc("http://www.w3.org/2001/XMLSchema", "base64Binary"), byte[].class);
366         qnameToClassMap.put(new QName JavaDoc("http://www.w3.org/2001/XMLSchema", "hexBinary"), byte[].class);
367         qnameToClassMap.put(new QName JavaDoc("http://www.w3.org/2001/XMLSchema", "anySimpleType"), String JavaDoc.class);
368     }
369
370
371     private FaultDesc mapException(String JavaDoc faultName, Fault fault) throws DeploymentException {
372         Message message = fault.getMessage();
373         QName JavaDoc messageQName = message.getQName();
374         ExceptionMappingType exceptionMapping = (ExceptionMappingType) exceptionMap.get(messageQName);
375         if (exceptionMapping == null) {
376             throw new DeploymentException("No exception mapping for fault " + faultName + " and fault message " + messageQName + " for operation " + operationName);
377         }
378         String JavaDoc className = exceptionMapping.getExceptionType().getStringValue().trim();
379         //TODO investigate whether there are other cases in which the namespace of faultQName can be determined.
380
//this is weird, but I can't figure out what it should be.
381
//if part has an element rather than a type, it should be part.getElementName() (see below)
382
QName JavaDoc faultQName = new QName JavaDoc("", faultName);
383         Part part;
384         if (exceptionMapping.isSetWsdlMessagePartName()) {
385             //According to schema documentation, this will only be set when several headerfaults use the same message.
386
String JavaDoc headerFaultMessagePartName = exceptionMapping.getWsdlMessagePartName().getStringValue();
387             part = message.getPart(headerFaultMessagePartName);
388         } else {
389             part = (Part) message.getOrderedParts(null).iterator().next();
390         }
391         QName JavaDoc faultTypeQName;// = part.getElementName() == null ? part.getTypeName() : part.getElementName();
392
if (part.getElementName() == null) {
393             faultTypeQName = part.getTypeName();
394             if (faultTypeQName == null) {
395                 throw new DeploymentException("Neither type nor element name supplied for part: " + part);
396             }
397         } else {
398             faultQName = part.getElementName();
399             faultTypeQName = (QName JavaDoc) schemaInfoBuilder.getElementToTypeMap().get(part.getElementName());
400             if (faultTypeQName == null) {
401                 throw new DeploymentException("Can not find type for: element: " + part.getElementName() + ", known elements: " + schemaInfoBuilder.getElementToTypeMap());
402             }
403         }
404         SchemaType complexType = (SchemaType) schemaInfoBuilder.getComplexTypesInWsdl().get(faultTypeQName);
405         boolean isComplex = complexType != null;
406         FaultDesc faultDesc = new FaultDesc(faultQName, className, faultTypeQName, isComplex);
407
408         //constructor parameters
409
if (exceptionMapping.isSetConstructorParameterOrder()) {
410             if (!isComplex) {
411                 throw new DeploymentException("ConstructorParameterOrder can only be set for complex types, not " + faultTypeQName);
412             }
413             Map JavaDoc elementMap = new HashMap JavaDoc();
414             SchemaProperty[] properties = complexType.getProperties();
415             for (int i = 0; i < properties.length; i++) {
416                 SchemaProperty property = properties[i];
417                 QName JavaDoc elementName = property.getName();
418                 SchemaType elementType = property.getType();
419                 elementMap.put(elementName.getLocalPart(), elementType);
420             }
421             ArrayList JavaDoc parameterTypes = new ArrayList JavaDoc();
422             ConstructorParameterOrderType constructorParameterOrder = exceptionMapping.getConstructorParameterOrder();
423             for (int i = 0; i < constructorParameterOrder.getElementNameArray().length; i++) {
424                 String JavaDoc elementName = constructorParameterOrder.getElementNameArray(i).getStringValue().trim();
425                 SchemaType elementType = (SchemaType) elementMap.get(elementName);
426                 Class JavaDoc javaElementType;
427
428                 QName JavaDoc elementTypeQName = elementType.getName();
429                 if (elementTypeQName != null) {
430                     if (schemaInfoBuilder.getComplexTypesInWsdl().containsKey(elementType)) {
431                         String JavaDoc javaClassName = (String JavaDoc) publicTypes.get(elementTypeQName);
432                         if (javaClassName == null) {
433                             throw new DeploymentException("No class mapped for element type: " + elementType);
434                         }
435                         javaElementType = getJavaClass(javaClassName);
436                     } else {
437                         javaElementType = (Class JavaDoc) qnameToClassMap.get(elementTypeQName);
438                         if (javaElementType == null) {
439                             throw new DeploymentException("Unknown type: " + elementType + " of name: " + elementName + " and QName: " + elementTypeQName);
440                         }
441                     }
442                 } else {
443                     //anonymous type
444
//anonymous type qname is constructed using rules 1.b and 2.b
445
String JavaDoc anonymousQName = complexType.getName().getNamespaceURI() + ":>" + complexType.getName().getLocalPart() + ">" + elementName;
446                     String JavaDoc javaClassName = (String JavaDoc) anonymousTypes.get(anonymousQName);
447                     if (javaClassName == null) {
448                         if (elementType.isSimpleType()) {
449                             //maybe it's a restriction of a built in simple type
450
SchemaType baseType = elementType.getBaseType();
451                             QName JavaDoc simpleTypeQName = baseType.getName();
452                             javaElementType = (Class JavaDoc) qnameToClassMap.get(simpleTypeQName);
453                             if (javaElementType == null) {
454                                 throw new DeploymentException("Unknown simple type: " + elementType + " of name: " + elementName + " and QName: " + simpleTypeQName);
455                             }
456                         } else {
457                             throw new DeploymentException("No class mapped for anonymous type: " + anonymousQName);
458                         }
459                     } else {
460                         javaElementType = getJavaClass(javaClassName);
461                     }
462                 }
463                 //todo faultTypeQName is speculative
464
//todo outheader might be true!
465
ParameterDesc parameterDesc = new ParameterDesc(faultTypeQName, ParameterDesc.OUT, elementTypeQName, javaElementType, false, false);
466                 parameterTypes.add(parameterDesc);
467             }
468             faultDesc.setParameters(parameterTypes);
469         }
470         return faultDesc;
471     }
472
473     private Class JavaDoc getJavaClass(String JavaDoc javaClassName) throws DeploymentException {
474         try {
475             Class JavaDoc javaClass = ClassLoading.loadClass(javaClassName, classLoader);
476             return javaClass;
477         } catch (ClassNotFoundException JavaDoc e) {
478             throw new DeploymentException("Could not load class", e);
479         }
480     }
481
482     private void mapReturnType() throws DeploymentException {
483         QName JavaDoc returnType = null;
484         QName JavaDoc returnQName = null;
485         Class JavaDoc returnClass = null;
486
487         if (output == null) {
488             throw new DeploymentException("No output message, but a mapping for it for operation " + operationName);
489         }
490         WsdlReturnValueMappingType wsdlReturnValueMapping = methodMapping.getWsdlReturnValueMapping();
491         String JavaDoc returnClassName = wsdlReturnValueMapping.getMethodReturnValue().getStringValue().trim();
492         try {
493             returnClass = ClassLoading.loadClass(returnClassName, classLoader);
494         } catch (ClassNotFoundException JavaDoc e) {
495             throw new DeploymentException("Could not load return type for operation " + operationName, e);
496         }
497
498         QName JavaDoc wsdlMessageQName = wsdlReturnValueMapping.getWsdlMessage().getQNameValue();
499
500         if (!wsdlMessageQName.equals(output.getQName())) {
501             throw new DeploymentException("OutputMessage has QName: " + output.getQName() + " but mapping specifies: " + wsdlMessageQName + " for operation " + operationName);
502         }
503
504         if (wsdlReturnValueMapping.isSetWsdlMessagePartName()) {
505             String JavaDoc wsdlMessagePartName = wsdlReturnValueMapping.getWsdlMessagePartName().getStringValue().trim();
506             if (outParamNames.contains(wsdlMessagePartName)) {
507                 throw new DeploymentException("output message part " + wsdlMessagePartName + " has both an INOUT or OUT mapping and a return value mapping for operation " + operationName);
508             }
509
510             if (wrappedStyle) {
511                 Part outPart = getWrappedPart(output);
512                 SchemaParticle returnParticle = getWrapperChild(outPart, wsdlMessagePartName);
513                 //TODO this makes little sense but may be correct, see comments in axis Parameter class
514
//the part name qname is really odd.
515
returnQName = new QName JavaDoc("", returnParticle.getName().getLocalPart());
516                 returnType = returnParticle.getType().getName();
517             } else if (rpcStyle) {
518                 Part part = output.getPart(wsdlMessagePartName);
519                 if (part == null) {
520                     throw new DeploymentException("No part for wsdlMessagePartName " + wsdlMessagePartName + " in output message for operation " + operationName);
521                 }
522                 returnQName = new QName JavaDoc("", part.getName());
523                 returnType = part.getTypeName();
524             } else {
525                 Part part = output.getPart(wsdlMessagePartName);
526                 if (part == null) {
527                     throw new DeploymentException("No part for wsdlMessagePartName " + wsdlMessagePartName + " in output message for operation " + operationName);
528                 }
529                 returnQName = getPartName(part);
530                 returnType = returnQName;
531             }
532
533             outParamNames.add(wsdlMessagePartName);
534         } else {
535             //what does this mean????
536
}
537
538         operationDesc.setReturnQName(returnQName);
539         operationDesc.setReturnType(returnType);
540         operationDesc.setReturnClass(returnClass);
541     }
542
543     private ParameterDesc mapParameter(MethodParamPartsMappingType paramMapping) throws DeploymentException {
544         WsdlMessageMappingType wsdlMessageMappingType = paramMapping.getWsdlMessageMapping();
545         QName JavaDoc wsdlMessageQName = wsdlMessageMappingType.getWsdlMessage().getQNameValue();
546         String JavaDoc wsdlMessagePartName = wsdlMessageMappingType.getWsdlMessagePartName().getStringValue().trim();
547
548         String JavaDoc parameterMode = wsdlMessageMappingType.getParameterMode().getStringValue().trim();
549         byte mode = ParameterDesc.modeFromString(parameterMode);
550         boolean isInParam = mode == ParameterDesc.IN || mode == ParameterDesc.INOUT;
551         boolean isOutParam = mode == ParameterDesc.OUT || mode == ParameterDesc.INOUT;
552
553         if (isOutParam && output == null) {
554             throw new DeploymentException("Mapping for output parameter " + wsdlMessagePartName + " found, but no output message for operation " + operationName);
555         }
556         boolean isSoapHeader = wsdlMessageMappingType.isSetSoapHeader();
557         boolean inHeader = isSoapHeader && isInParam;
558         boolean outHeader = isSoapHeader && isOutParam;
559
560         QName JavaDoc paramQName;
561         QName JavaDoc paramTypeQName;
562
563         Part part = null;
564         SchemaParticle inParameter = null;
565         if (isInParam) {
566             if (!wsdlMessageQName.equals(input.getQName())) {
567                 throw new DeploymentException("QName of input message: " + input.getQName() +
568                         " does not match mapping message QName: " + wsdlMessageQName + " for operation " + operationName);
569             }
570             if (wrappedStyle) {
571                 Part inPart = getWrappedPart(input);
572                 // the local name of the global element refered by the part is equal to the operation name
573
QName JavaDoc name = inPart.getElementName();
574                 if (false == name.getLocalPart().equals(operationName)) {
575                     throw new DeploymentException("message " + input.getQName() + " refers to a global element named " +
576                             name.getLocalPart() + ", which is not equal to the operation name " + operationName);
577                 }
578                 inParameter = getWrapperChild(inPart, wsdlMessagePartName);
579                 //TODO this makes little sense but may be correct, see comments in axis Parameter class
580
//the part name qname is really odd.
581
paramQName = new QName JavaDoc("", inParameter.getName().getLocalPart());
582                 paramTypeQName = inParameter.getType().getName();
583             } else if (rpcStyle) {
584                 part = input.getPart(wsdlMessagePartName);
585                 if (part == null) {
586                     throw new DeploymentException("No part for wsdlMessagePartName " + wsdlMessagePartName + " in input message for operation " + operationName);
587                 }
588                 //TODO this makes little sense but may be correct, see comments in axis Parameter class
589
//the part name qname is really odd.
590
paramQName = new QName JavaDoc("", part.getName());
591                 paramTypeQName = part.getTypeName();
592             } else {
593                 part = input.getPart(wsdlMessagePartName);
594                 if (part == null) {
595                     throw new DeploymentException("No part for wsdlMessagePartName " + wsdlMessagePartName + " in input message for operation " + operationName);
596                 }
597                 paramQName = getPartName(part);
598                 paramTypeQName = paramQName;
599             }
600             inParamNames.add(wsdlMessagePartName);
601             if (isOutParam) {
602                 if (wrappedStyle) {
603                     Part outPart = getWrappedPart(output);
604                     SchemaParticle outParameter = getWrapperChild(outPart, wsdlMessagePartName);
605                     if (inParameter.getType() != outParameter.getType()) {
606                         throw new DeploymentException("The wrapper children " + wsdlMessagePartName +
607                                 " do not have the same type for operation " + operationName);
608                     }
609                 } else if (rpcStyle) {
610                     //inout, check that part of same name and type is in output message
611
Part outPart = output.getPart(wsdlMessagePartName);
612                     if (outPart == null) {
613                         throw new DeploymentException("No part for wsdlMessagePartName " + wsdlMessagePartName + " in output message for INOUT parameter of operation " + operationName);
614                     }
615                     // TODO this cannot happen.
616
if (!part.getName().equals(outPart.getName())) {
617                         throw new DeploymentException("Mismatched input part name: " + part.getName() + " and output part name: " + outPart.getName() + " for INOUT parameter for wsdlMessagePartName " + wsdlMessagePartName + " for operation " + operationName);
618                     }
619                     if (!(part.getElementName() == null ? outPart.getElementName() == null : part.getElementName().equals(outPart.getElementName()))) {
620                         throw new DeploymentException("Mismatched input part element name: " + part.getElementName() + " and output part element name: " + outPart.getElementName() + " for INOUT parameter for wsdlMessagePartName " + wsdlMessagePartName + " for operation " + operationName);
621                     }
622                     if (!(part.getTypeName() == null ? outPart.getTypeName() == null : part.getTypeName().equals(outPart.getTypeName()))) {
623                         throw new DeploymentException("Mismatched input part type name: " + part.getTypeName() + " and output part type name: " + outPart.getTypeName() + " for INOUT parameter for wsdlMessagePartName " + wsdlMessagePartName + " for operation " + operationName);
624                     }
625                 } else {
626                     part = output.getPart(wsdlMessagePartName);
627                     if (part == null) {
628                         throw new DeploymentException("No part for wsdlMessagePartName " + wsdlMessagePartName + " in output message for operation " + operationName);
629                     }
630                     paramQName = getPartName(part);
631                     paramTypeQName = paramQName;
632                 }
633                 outParamNames.add(wsdlMessagePartName);
634             }
635         } else if (isOutParam) {
636             if (!wsdlMessageQName.equals(output.getQName())) {
637                 throw new DeploymentException("QName of output message: " + output.getQName() +
638                         " does not match mapping message QName: " + wsdlMessageQName + " for operation " + operationName);
639             }
640             if (wrappedStyle) {
641                 Part outPart = getWrappedPart(output);
642                 SchemaParticle outParameter = getWrapperChild(outPart, wsdlMessagePartName);
643                 //TODO this makes little sense but may be correct, see comments in axis Parameter class
644
//the part name qname is really odd.
645
paramQName = new QName JavaDoc("", outParameter.getName().getLocalPart());
646                 paramTypeQName = outParameter.getType().getName();
647             } else if (rpcStyle) {
648                 part = output.getPart(wsdlMessagePartName);
649                 if (part == null) {
650                     throw new DeploymentException("No part for wsdlMessagePartName " + wsdlMessagePartName + " in output message for operation " + operationName);
651                 }
652                 //TODO this makes little sense but may be correct, see comments in axis Parameter class
653
//the part name qname is really odd.
654
paramQName = new QName JavaDoc("", part.getName());
655                 paramTypeQName = part.getTypeName();
656             } else {
657                 part = output.getPart(wsdlMessagePartName);
658                 if (part == null) {
659                     throw new DeploymentException("No part for wsdlMessagePartName " + wsdlMessagePartName + " in output message for operation " + operationName);
660                 }
661                 paramQName = getPartName(part);
662                 paramTypeQName = paramQName;
663             }
664             outParamNames.add(wsdlMessagePartName);
665         } else {
666             throw new AssertionError JavaDoc("a param mapping has to be IN or OUT or INOUT");
667         }
668
669         //use complexTypeMap
670
boolean isComplexType = schemaInfoBuilder.getComplexTypesInWsdl().containsKey(paramTypeQName);
671         String JavaDoc paramJavaTypeName = paramMapping.getParamType().getStringValue().trim();
672         boolean isInOnly = mode == ParameterDesc.IN;
673         Class JavaDoc actualParamJavaType = WSDescriptorParser.getHolderType(paramJavaTypeName, isInOnly, paramTypeQName, isComplexType, mapping, classLoader);
674
675         ParameterDesc parameterDesc = new ParameterDesc(paramQName, mode, paramTypeQName, actualParamJavaType, inHeader, outHeader);
676         return parameterDesc;
677     }
678
679     private QName JavaDoc getPartName(Part part) {
680         return null == part.getElementName() ? part.getTypeName() : part.getElementName();
681     }
682
683     private Part getWrappedPart(Message message) throws DeploymentException {
684         // in case of wrapped element, the message has only one part.
685
Collection JavaDoc parts = message.getParts().values();
686         if (1 != parts.size()) {
687             throw new DeploymentException("message " + message.getQName() + " has " + parts.size() +
688                     " parts and should only have one as wrapper style mapping is specified for operation " +
689                     operationName);
690         }
691         return (Part) parts.iterator().next();
692     }
693
694     private SchemaParticle getWrapperChild(Part part, String JavaDoc wsdlMessagePartName) throws DeploymentException {
695         QName JavaDoc name = part.getElementName();
696
697         wrapperElementQNames.add(name);
698
699         SchemaType operationType = (SchemaType) schemaInfoBuilder.getComplexTypesInWsdl().get(name);
700         if (null == operationType) {
701             throw new DeploymentException("No global element named " + name + " for operation " + operationName);
702         }
703
704         // schemaType should be complex using xsd:sequence compositor
705
SchemaParticle parametersType = operationType.getContentModel();
706         if (SchemaParticle.ELEMENT == parametersType.getParticleType()) {
707             if (parametersType.getName().getLocalPart().equals(wsdlMessagePartName)) {
708                 return parametersType;
709             }
710             throw new DeploymentException("Global element named " + name +
711                     " does not define a child element named " + wsdlMessagePartName +
712                     " required by the operation " + operationName);
713         } else if (SchemaParticle.SEQUENCE == parametersType.getParticleType()) {
714             SchemaParticle[] parameters = parametersType.getParticleChildren();
715             for (int i = 0; i < parameters.length; i++) {
716                 SchemaParticle parameter = parameters[i];
717                 QName JavaDoc element = parameter.getName();
718                 if (element.getLocalPart().equals(wsdlMessagePartName)) {
719                     return parameter;
720                 }
721             }
722             throw new DeploymentException("Global element named " + name +
723                     " does not define a child element named " + wsdlMessagePartName +
724                     " required by the operation " + operationName);
725         } else {
726             throw new DeploymentException("Global element named " + name +
727                     " is not a sequence for operation " + operationName);
728         }
729     }
730
731     /**
732      * Supporting the Document/Literal Wrapped pattern
733      *
734      * See http://www-106.ibm.com/developerworks/webservices/library/ws-whichwsdl/ for a nice explanation and example
735      *
736      * wrapped-element tag is used
737      * WSDL message with a single part
738      * part uses the 'element' attribute to point to an elemement in the types section
739      * the element type and the element's name match the operation name
740      */

741 }
742
Popular Tags