//
// CIMParameter.java
//
// The contents of this file are subject to the SNIA Public License Version 1.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.snia.org/resources/openSource.html
//
// Software distributed under the License is distributed on an "AS IS" basis,
// WITHOUT WARRANTY OF ANY KIND, either express or implied. See the 
// License for the specific language governing rights and limitations
// under the License.
//
// The Original Code is CIMParameter.java
// 
// The Initial Developer of the Original Code is David Simons.
//
// Contributor(s):
//
//
// This source uses the Solaris WBEM APIs version 2.2. 
// Synchronization will be maintained with the Solaris WBEM APIS,
// which are being standardized through the Java Community Process.
//
//
// $Id: CIMParameter.java,v 1.1 2003/07/17 18:32:55 kumpf Exp $
//
// $Log: CIMParameter.java,v $
// Revision 1.1  2003/07/17 18:32:55  kumpf
// HP-BAPU: PEP-64 CIM Client and CIM Listener Java Interface
//
// Revision 1.1.1.1  2001/10/31 18:14:31  karl
// import of SNIA 0_7
//
// Revision 1.6  2000/08/16 05:59:52  shawn
// merge P_TOMCAT31 branch
//
// Revision 1.5.8.1  2000/08/10 00:03:27  shawn
// head merge
//
// Revision 1.5  2000/05/11 10:12:20  davidsi
// - Fixed tabs.
//
// Revision 1.4  2000/05/06 17:04:22  davidsi
// - Modifications to bring classes inline with the SUN WBEM APIs 2.2.
//
// Revision 1.3  2000/04/09 13:19:15  davidsi
// - Switched to StringBuffer (from String) for XML generation.
//
// Revision 1.2  2000/02/13 15:09:07  davidsi
// - Added text to cover re-use of Solaris WBEM APIs.
//
// Revision 1.1.1.1  2000/02/06 16:41:03  davidsi
// Initial version.
//
//
//
package org.snia.wbem.cim;

import java.io.*;
import java.util.Vector;
import java.net.MalformedURLException;
import org.snia.wbemcmd.xml.*;

/**
    Creates and instantiates a CIM parameter, a value passed to a CIM
    method from a calling method.
 */

public class CIMParameter extends CIMElement implements Cloneable {
    CIMDataType datatype=null;
    Vector qualifiers=null;


    // CIMParameter 
    //
    public CIMParameter() {
    }


    //
    // CIMParameter 
    // 
    // Creates a parameter with a name
    //
    public CIMParameter(String name){
	setName(name);
    }

    // CIMMethod
    //
    // Create a method using a XML definition
    //
    // @param node The node containing an XML definition of CIMMethod
    //
    public CIMParameter(org.w3c.dom.Node node) {
	XMLNode qnode=XMLNode.getXMLNode(node);
	int paramToken=qnode.getToken();
	if (paramToken!=XMLNode.XML_ELEMENT_PARAMETER &&
		 paramToken!=XMLNode.XML_ELEMENT_PARAMETER_REFERENCE &&
		 paramToken!=XMLNode.XML_ELEMENT_PARAMETER_ARRAY &&
		 paramToken!=XMLNode.XML_ELEMENT_PARAMETER_REFARRAY ) 
	    throw new java.lang.InstantiationError("Not a parameter node");
	
	try {
	    //
	    // Fetch name
	    //
	    String parameterName=qnode.getAttribute(XMLParameters.paramName);
	    setName(parameterName);
		
	    //
	    // Get parameter type
	    //
	    if (paramToken==XMLNode.XML_ELEMENT_PARAMETER) {
		String cimType=qnode.getAttribute(XMLParameters.paramTypeAssign);
		datatype=CIMDataType.getDataType(cimType);
	    } else if (paramToken==XMLNode.XML_ELEMENT_PARAMETER_REFERENCE) {
		String cimType=qnode.getAttribute(XMLParameters.paramRefClass);
		datatype=new CIMDataType(cimType);
	    } else if (paramToken==XMLNode.XML_ELEMENT_PARAMETER_ARRAY) {
		String cimType=qnode.getAttribute(XMLParameters.paramTypeAssign);
		datatype=CIMDataType.getDataType(cimType);

		String arraySize=qnode.getAttribute(XMLParameters.paramArraySize);
		if (arraySize!=null) {
		    datatype=new CIMDataType(datatype.getType(),new Integer(arraySize).intValue());
		} else
		    datatype=new CIMDataType(CIMDataType.findArrayType(datatype.getType()));
	    } else if (paramToken==XMLNode.XML_ELEMENT_PARAMETER_REFARRAY) {
		String cimType=qnode.getAttribute(XMLParameters.paramRefClass);
		datatype=new CIMDataType(cimType);
		String arraySize=qnode.getAttribute(XMLParameters.paramArraySize);
		if (arraySize!=null) {
		    datatype=new CIMDataType(datatype.getType(),new Integer(arraySize).intValue());
		} else
		    datatype=new CIMDataType(CIMDataType.findArrayType(datatype.getType()));
		    
	    } else 
		throw new CIMException(CIMException.CIM_ERR_INVALID_PARAMETER,
		    "Could not decode parameter");
	    
	    //
	    // See if there are qualifiers
	    //
	    qualifiers=new Vector();
	    for(qnode=qnode.getChild();qnode!=null && qnode.getToken()==XMLNode.XML_ELEMENT_QUALIFIER;
		    qnode=qnode.getNext())
		qualifiers.addElement(new CIMQualifier(qnode));
	} catch (CIMException ce) {
	    throw new java.lang.InstantiationError("Not a parameter node");
	}
    }
    
    //
    // setQualifiers 
    //
    // Sets the qualifiers
    //
    public void setQualifiers(Vector list){
	int tsize=list.size();
	for(int i=0;i<tsize;i++)
	    if (!(list.elementAt(i) instanceof CIMQualifier))
		return;
	qualifiers=list;
    }


    //
    // getQualifiers 
    //
    // Returns the qualifiers 
    //
    public Vector getQualifiers(){
	return(qualifiers);
    }



    // setType 
    //
    // Sets the data type 
    //
    public void setType(CIMDataType type){
	datatype=type;
    }


    // getType 
    //
    // Returns the data type
    //
    public CIMDataType getType(){
	return(datatype);
    }


    // getSize 
    //
    // Returns the size of this parameter 
    //
    public int getSize(){
	return(datatype.getSize());
    }



    // setSize 
    //
    // Sets the size of this parameter
    //
    // public void setSize(int aSize){
    // SUNDIFF : Why? The datatype does this for us
    //}


    //toString 
    public String toString(){
	return("CIMParameter("+getName()+")");
    }


    //toMOF 
    public String toMOF(){
	String ret;
	int i;
	
	ret=new String();
	if (qualifiers!=null && qualifiers.size()>0) {
	    ret=ret.concat("[");
	    for(i=0;i<qualifiers.size();i++) {
		CIMQualifier nq=((CIMQualifier)(qualifiers.elementAt(i)));
		if (i>0)
		    ret=ret.concat(",");
		ret=ret.concat(nq.toMOF());
	    }
	    ret=ret.concat("]");
	}

	
	ret=ret.concat(datatype.toMOF());
	ret=ret.concat(" ");
	ret=ret.concat(getName());
	return(ret);
    }



    //clone 
    public Object clone(){
	CIMParameter cp=new CIMParameter();
	
	cp.datatype=datatype;
	if (qualifiers!=null) {
	    cp.qualifiers=new Vector();
	    for(int i=0;i<qualifiers.size();i++)
		cp.qualifiers.addElement(qualifiers.elementAt(i));
	}
	return(cp);
    }


    //toXml 
    public String toXml() throws MalformedURLException {
	StringBuffer text=new StringBuffer();
	String cimName=getName();
	String cimType;
	StringBuffer qualifierText=new StringBuffer();
	
	if (cimName==null)
	    throw new MalformedURLException("parameter must have name");
	


	//
	// Handle qualifiers
	//
	if (qualifiers!=null) {
	    int tsize=qualifiers.size();
	    for(int i=0;i<tsize;i++) {
		CIMQualifier cq=(CIMQualifier)(qualifiers.elementAt(i));
		qualifierText.append(cq.toXml());
	    }
	}
	if (datatype==null)
	    throw new MalformedURLException("parameter must have datatype");
	
	boolean isArray=datatype.isArrayType();
	    
	if (isArray)
	    cimType=CIMDataType.getPredefinedType(
			CIMDataType.findSimpleType(datatype.getType())).toXml();
	else
	    cimType=datatype.toXml();
	if (cimType==null)
	    throw new MalformedURLException("parameter must have string datatype thats not null");

		
	    
	if (datatype.isReferenceType()) {
	    //
	    // Data type is a reference
	    //
	    String classref=datatype.getRefClassName();
	    if (classref!=null)
		classref="REFERENCECLASS=\""+classref+"\"";
	    else
		classref="";
		
	    if (isArray) {
		if (datatype.getSize()==-1)
		    text=text.append("<PARAMETER.REFARRAY "+classref+
				" NAME=\""+cimName+"\">"+
				qualifierText+
				"</PARAMETER.REFARRAY>");
		else
		    text=text.append("<PARAMETER.REFARRAY "+classref+
				     " NAME=\""+cimName+"\""+
				     " ARRAYSIZE=\""+datatype.getSize()+"\">"+
				     qualifierText+
				     "</PARAMETER.REFARRAY>");
	    } else
		text=text.append("<PARAMETER.REFERENCE "+classref+
				 " NAME=\""+cimName+"\">"+
				 qualifierText+
				 "</PARAMETER.REFERENCE>");
	} else {
	    //
	    // Data type is not a ref
	    if (isArray) {
		if (datatype.getSize()==-1)
		    text=text.append("<PARAMETER.ARRAY TYPE=\""+cimType+
				"\" NAME=\""+cimName+"\">"+
				qualifierText+
				"</PARAMETER.ARRAY>");
		else
		    text=text.append("<PARAMETER.ARRAY TYPE=\""+cimType+
				     "\" NAME=\""+cimName+"\""+
				     " ARRAYSIZE=\""+datatype.getSize()+"\">"+
				     qualifierText+
				     "</PARAMETER.ARRAY>");
	    } else
		text=text.append("<PARAMETER TYPE=\""+cimType+
				 "\"  NAME=\""+cimName+"\""+">"+
				 qualifierText+"</PARAMETER>");
	}

	return(text.toString());
    }

    // getQualifier 
    //
    // Returns a qualifier
    //
    public CIMQualifier getQualifier(String name) {
	int i;
	if (qualifiers!=null) {
	    int tsize=qualifiers.size();
	    for(i=0;i<tsize;i++) {
		CIMQualifier nq=((CIMQualifier)(qualifiers.elementAt(i)));
		if (nq.getName().equalsIgnoreCase(name)) {
		   return(((CIMQualifier)(qualifiers.elementAt(i))));
		} 
	    }
	}
	return(null);
    }
}
