/*
* JBoss, the OpenSource J2EE webOS
*
* Distributable under LGPL license.
* See terms of license at gnu.org.
*/
package org.jboss.webservice.server;

import org.jboss.axis.MessageContext;
import org.jboss.axis.description.OperationDesc;
import org.jboss.axis.description.ParameterDesc;
import org.jboss.axis.description.ServiceDesc;
import org.jboss.axis.message.SOAPEnvelopeAxisImpl;
import org.jboss.axis.providers.java.RPCInvocation;
import org.jboss.axis.providers.java.RPCProvider;
import org.jboss.logging.Logger;
import org.jboss.webservice.PortComponentInfo;
import org.jboss.webservice.deployment.OperationDescription;
import org.jboss.webservice.deployment.ServiceDescription;

import javax.xml.namespace.QName;
import java.util.ArrayList;
import java.util.Iterator;

/**
 * @author <a href="mailto:telrod@e2technologies.net">Tom Elrod</a>
 */
public class JBossRPCInvocation extends RPCInvocation
{
   private Logger log = Logger.getLogger(JBossRPCInvocation.class);

   public JBossRPCInvocation(RPCProvider rpcProvider, MessageContext messageContext, SOAPEnvelopeAxisImpl soapEnvelopeDirty, SOAPEnvelopeAxisImpl soapEnvelopeDirty1, Object o)
   {
      super(rpcProvider, messageContext, soapEnvelopeDirty, soapEnvelopeDirty1, o);
   }

   public JBossRPCInvocation(RPCInvocation rpcInvocation)
   {
      super(rpcInvocation);
   }

   public OperationDesc getOperation(ServiceDesc serviceDesc, QName qname)
   {
      OperationDesc op = null;
      op = serviceDesc.getOperationByElementQName(qname);

      RPCProvider provider = getProvider();

      if (provider instanceof InvokerProvider)
      {
         PortComponentInfo pcInfo = ((InvokerProvider)provider).getPortComponentInfo();
         ServiceDescription svcDesc = pcInfo.getServiceDescription();
         OperationDescription custOp = svcDesc.getOperation(qname.getLocalPart());
         if (custOp != null)
         {
            String opName = custOp.getJavaName();
            QName returnName = custOp.getReturnQName();
            QName returnType = custOp.getReturnType();

            op.setName(opName);
            op.setReturnQName(returnName);
            op.setReturnType(returnType);

            // set parameters if there are any
            Iterator itr = custOp.getParameters();
            ArrayList paramList = new ArrayList();

            while (itr.hasNext())
            {
               OperationDescription.Parameter param = (OperationDescription.Parameter)itr.next();
               // no namespace uri for param name
               QName paramName = new QName("", param.getName());
               QName paramType = param.getType();
               String mode = param.getMode();
               ParameterDesc paramDesc = new ParameterDesc(paramName, convertMode(mode), paramType);
               paramList.add(paramDesc);
            }

            if (paramList.size() > 0)
            {
               op.setParameters(paramList);
            }
            // no faults in Operation currently
         }
      }

      return op;
   }

   private byte convertMode(String mode)
   {
      if ("INOUT".equals(mode))
      {
         return ParameterDesc.INOUT;
      }
      else if ("OUT".equals(mode))
      {
         return ParameterDesc.OUT;
      }
      else
      {
         return ParameterDesc.IN;
      }
   }

}