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: 476049 $ $Date: 2006-11-16 23:35:17 -0500 (Thu, 16 Nov 2006) $
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    }