001 /**
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements. See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License. You may obtain a copy of the License at
008 *
009 * http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017 package org.apache.geronimo.axis.builder;
018
019 import java.lang.reflect.Method;
020 import java.util.List;
021 import java.util.Iterator;
022
023 import javax.xml.namespace.QName;
024 import javax.wsdl.Part;
025 import javax.wsdl.BindingOperation;
026
027 import org.apache.geronimo.axis.client.OperationInfo;
028 import org.apache.geronimo.common.DeploymentException;
029 import org.apache.axis.soap.SOAPConstants;
030 import org.apache.axis.description.OperationDesc;
031 import org.apache.axis.description.ParameterDesc;
032 import org.apache.axis.constants.Style;
033 import org.apache.axis.constants.Use;
034 import org.objectweb.asm.Type;
035
036 /**
037 * @version $Rev: 706640 $ $Date: 2008-10-21 14:44:05 +0000 (Tue, 21 Oct 2008) $
038 */
039 public class LightweightOperationDescBuilder extends OperationDescBuilder {
040
041 private final Method method;
042
043 public LightweightOperationDescBuilder(BindingOperation bindingOperation, Method method) throws DeploymentException{
044 super(bindingOperation);
045 if (bindingOperation == null) {
046 throw new DeploymentException("No BindingOperation supplied for method " + method.getName());
047 }
048
049 this.method = method;
050
051 operationDesc.setName(operationName);
052 operationDesc.setStyle(Style.RPC);
053 operationDesc.setUse(Use.ENCODED);
054 }
055
056 public OperationInfo buildOperationInfo(SOAPConstants soapVersion) throws DeploymentException {
057 buildOperationDesc();
058 String soapActionURI = soapOperation.getSoapActionURI();
059 boolean usesSOAPAction = (soapActionURI != null);
060 QName operationQName = getOperationNameFromSOAPBody();
061
062 String methodName = method.getName();
063 String methodDesc = Type.getMethodDescriptor(method);
064
065
066 OperationInfo operationInfo = new OperationInfo(operationDesc, usesSOAPAction, soapActionURI, soapVersion, operationQName, methodName, methodDesc);
067 return operationInfo;
068 }
069
070 public OperationDesc buildOperationDesc() throws DeploymentException {
071 if (built) {
072 return operationDesc;
073 }
074
075 built = true;
076
077 operationDesc.setMethod(method);
078
079 //section 7.3.2, we don't have to look at parameter ordering.
080 //unless it turns out we have to validate it.
081 // List order = operation.getParameterOrdering();
082
083 // Verify we have the right number of args for this method
084 Class[] methodParamTypes = method.getParameterTypes();
085 List inputParts = input.getOrderedParts(null);
086 if (methodParamTypes.length != inputParts.size()) {
087 throw new DeploymentException("mismatch in parameter counts: method has " + methodParamTypes.length + " whereas the input message has " + inputParts.size());
088 }
089
090 // Map the input parts to method args
091 int i = 0;
092 for (Iterator parts = inputParts.iterator(); parts.hasNext();) {
093 Part part = (Part) parts.next();
094 String partName = part.getName();
095 QName name = new QName("", partName);
096 byte mode = ParameterDesc.IN;
097 QName typeQName = part.getTypeName() == null ? part.getElementName() : part.getTypeName();
098 Class javaClass = methodParamTypes[i++];
099 //lightweight mapping has no parts in headers, so inHeader and outHeader are false
100 ParameterDesc parameter = new ParameterDesc(name, mode, typeQName, javaClass, false, false);
101 operationDesc.addParameter(parameter);
102 }
103
104 // Can't have multiple return values
105 if (output != null && output.getParts().size() > 1) {
106 throw new DeploymentException("Lightweight mapping has at most one part in the (optional) output message, not: " + output.getParts().size());
107 }
108
109 // Map the return message, if there is one
110 if (output != null && output.getParts().size() == 1) {
111 Part part = (Part) output.getParts().values().iterator().next();
112
113 // Set the element name
114 QName returnName = part.getElementName() == null ? new QName(part.getName()) : part.getElementName();
115 operationDesc.setReturnQName(returnName);
116
117 // Set the element type
118 QName returnType = part.getTypeName() == null ? part.getElementName() : part.getTypeName();
119 operationDesc.setReturnType(returnType);
120
121 operationDesc.setReturnClass(method.getReturnType());
122 }
123
124 //TODO add faults
125 // TFault[] faults = tOperation.getFaultArray();
126 // for (int i = 0; i < faults.length; i++) {
127 // TFault fault = faults[i];
128 // QName faultQName = new QName("", fault.getName());
129 // String className = ;
130 // QName faultTypeQName = ;
131 // boolean isComplex = ;
132 // FaultDesc faultDesc = new FaultDesc(faultQName, className, faultTypeQName, isComplex)
133 // }
134 return operationDesc;
135 }
136 }