/*
 * Copyright 2001-2004 The Apache Software Foundation.
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *      http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.apache.axis.message;

import org.apache.axis.components.logger.LogFactory;
import org.apache.axis.description.ParameterDesc;
import org.apache.axis.encoding.SerializationContext;
import org.apache.axis.utils.JavaUtils;
import org.apache.axis.utils.Messages;
import org.apache.axis.constants.Style;
import org.apache.axis.Constants;
import org.apache.axis.MessageContext;
import org.apache.commons.logging.Log;

import javax.xml.namespace.QName;
import javax.xml.soap.SOAPElement;
import javax.xml.soap.SOAPException;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.lang.reflect.Method;
import java.util.ArrayList;

/** An RPC parameter
 *
 * @author Glen Daniels (gdaniels@apache.org)
 */
public class RPCParam extends MessageElement implements Serializable
{
    protected static Log log =
        LogFactory.getLog(RPCParam.class.getName());

    private Object value = null;
    private int countSetCalls = 0; // counts number of calls to set

    private ParameterDesc paramDesc;

    /**
     * Do we definitely want (or don't want) to send xsi:types?  If null
     * (the default), just do whatever our SerializationContext is configured
     * to do.  If TRUE or FALSE, the SerializationContext will do what we
     * want.
     */
    private Boolean wantXSIType = null;

    private static Method valueSetMethod;
    static {
        Class cls = RPCParam.class;
        try {
            valueSetMethod = cls.getMethod("set", new Class[] {Object.class});
        } catch (NoSuchMethodException e) {
            log.error(Messages.getMessage("noValue00", "" + e));
            throw new RuntimeException(e.getMessage());
        }
    }

    /** Constructor for building up messages.
     */
    public RPCParam(String name, Object value)
    {
        this(new QName("", name), value);
    }

    public RPCParam(QName qname, Object value)
    {
        super(qname);
        if (value instanceof java.lang.String) {
            try {
                this.addTextNode((String) value);
            } catch (SOAPException e) {
                throw new RuntimeException(Messages.getMessage("cannotCreateTextNode00"));
            } 
        } else {
            this.value = value;
        }
    }

    public RPCParam(String namespace, String name, Object value)
    {
        this(new QName(namespace, name), value);
    }
    
    public void setRPCCall(RPCElement call)
    {
        parent = call;
    }
    
    public Object getObjectValue()
    {
        return value;
    }
    
    public void setObjectValue(Object value)
    {
        this.value = value;
    }

    /**
     * This set method is registered during deserialization
     * to set the deserialized value.
     * If the method is called multiple times, the 
     * value is automatically changed into a container to 
     * hold all of the values.
     * @param newValue is the deserialized object
     */
    public void set(Object newValue) {
        countSetCalls++;
        // If this is the first call,
        // simply set the value.
        if (countSetCalls==1) {
            this.value = newValue;
            return;
        }
        // If this is the second call, create an
        // ArrayList to hold all the values
        else if (countSetCalls==2) {
            ArrayList list = new ArrayList();
            list.add(this.value);
            this.value = list;
        } 
        // Add the new value to the list
        ((ArrayList) this.value).add(newValue);
    }

    public static Method getValueSetMethod()
    {
        return valueSetMethod;
    }

    public ParameterDesc getParamDesc() {
        return paramDesc;
    }

    public void setParamDesc(ParameterDesc paramDesc) {
        this.paramDesc = paramDesc;
    }

    public void setXSITypeGeneration(Boolean value) {
        this.wantXSIType = value; 
    }

    public Boolean getXSITypeGeneration() {
        return this.wantXSIType;
    }

    public void serialize(SerializationContext context)
        throws IOException
    {
        // Set the javaType to value's class unless 
        // parameter description information exists.
        // Set the xmlType using the parameter description
        // information.  (an xmlType=null causes the
        // serialize method to search for a compatible xmlType)
        Class javaType = value == null ? null: value.getClass();
        QName xmlType = null;
        if (paramDesc != null) {
            if (javaType == null) {
                javaType = paramDesc.getJavaType() != null ?
                    paramDesc.getJavaType(): javaType;
            } else if (!(javaType.equals(paramDesc.getJavaType()))) {
                Class clazz = JavaUtils.getPrimitiveClass(javaType);
                if(clazz == null || !clazz.equals(paramDesc.getJavaType())) {
                    if (!(javaType.equals(
                            JavaUtils.getHolderValueType(paramDesc.getJavaType())))) {
                        
                        // This must (assumedly) be a polymorphic type - in ALL
                        // such cases, we must send an xsi:type attribute.
                        wantXSIType = Boolean.TRUE;
                    }
                }
            }
            xmlType = paramDesc.getTypeQName();
            QName itemQName = paramDesc.getItemQName();
            if (itemQName == null) {
                MessageContext mc = context.getMessageContext();
                if (mc != null && mc.getOperation() != null && mc.getOperation().getStyle() == Style.DOCUMENT) {
                    itemQName = Constants.QNAME_LITERAL_ITEM;
                }
            }
            context.setItemQName(itemQName);

            QName itemType = paramDesc.getItemType();
            context.setItemType(itemType);
        }
        context.serialize(getQName(),  // element qname
                          null,   // no extra attrs
                          value,  // value
                          xmlType, // java/xml type
                          Boolean.TRUE, wantXSIType); 
    }

    private void writeObject(ObjectOutputStream out)
        throws IOException {
        if (getQName() == null) {
            out.writeBoolean(false);
        } else {
            out.writeBoolean(true);
            out.writeObject(getQName().getNamespaceURI());
            out.writeObject(getQName().getLocalPart());
        }
        out.defaultWriteObject();
    }

    private void readObject(ObjectInputStream in) 
        throws IOException, ClassNotFoundException {
        if (in.readBoolean()) {
            setQName(new QName((String)in.readObject(),
                              (String)in.readObject()));
        } 
        in.defaultReadObject();
    }

    protected void outputImpl(SerializationContext context) throws Exception {
        serialize(context);
    }

    public String getValue() {
        return getValueDOM();
    }

    /**
     * @see javax.xml.soap.SOAPElement#addTextNode(java.lang.String)
     */
    public SOAPElement addTextNode(String s) throws SOAPException {
        value = s;
        return super.addTextNode(s);
    }
    /**
     * @see javax.xml.soap.Node#setValue(java.lang.String)
     */
    public void setValue(String value) {
        this.value = value;
        super.setValue(value);
    }
}
