//
// XMLNode.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 XMLNode.java
// 
// The Initial Developer of the Original Code is David Simons.
//
// Contributor(s): Scott Baker,Adrian Schuur
//
//
// 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: XMLNode.java,v 1.1 2003/07/17 18:32:55 kumpf Exp $
//
// $Log: XMLNode.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:17:52  karl
// import of SNIA 0_7
//
// Revision 1.15  2002/10/30 15:10:07  jyu
// - Added XML_ELEMENT_VALUE_REFARRAY.
//
// Revision 1.14  2001/07/22 19:38:50  davidsi
// - Added xml-element keywords for indication support
// - changed  mustChildFindElement(int) to a public method
//
// Revision 1.13  2001/06/23 10:41:59  davidsi
// - Added XML_ELEMENT_MULTIREQ.
//
// Revision 1.12  2001/01/07 16:58:41  davidsi
// - Fixed handling of null values when building exceptions.
//
// Revision 1.11  2000/11/18 14:18:17  davidsi
// - Fixes for xerces 1.0.4.
//
// Revision 1.10  2000/11/09 17:47:26  davidsi
// - Fixed getXMLNode() to return a null if it is passed a null
//
// Revision 1.9  2000/11/06 19:23:24  davidsi
// - Reconciled error ids.
// - Fixed problem with case sensitivity on attribute names.
//
// Revision 1.8  2000/08/16 05:59:59  shawn
// merge P_TOMCAT31 branch
//
// Revision 1.7.6.1  2000/08/10 00:03:36  shawn
// head merge
//
// Revision 1.7  2000/07/10 18:13:02  davidsi
// - Added debug.
//
// Revision 1.6  2000/05/11 10:11:25  davidsi
// - Fixed tabs.
//
// Revision 1.5  2000/05/06 17:20:04  davidsi
// - Brought in line with SUN WBEM APIs 2.2
//
// Revision 1.4  2000/04/10 23:33:23  davidsi
// - Added support for using new xerces based classes (those from
//   xml4j had been deprecated).
//
// Revision 1.3  2000/04/09 14:43:25  davidsi
// - Removed XML_ELEMENT_METHODPARAMETER and XML_ELEMENT_VALUE_NAMEDINSTANCE.
//
// Revision 1.2  2000/02/13 15:10:07  davidsi
// - Added text to cover re-use of Solaris WBEM APIs.
//
// Revision 1.1.1.1  2000/02/06 16:41:02  davidsi
// Initial version.
//
//
//
package org.snia.wbemcmd.xml;	       
		    
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.util.Vector;
import org.xml.sax.Attributes;
import org.snia.wbem.cim.CIMException;
import org.snia.wbem.cim.CIMObjectPath;


public class XMLNode extends org.apache.xerces.dom.NodeImpl {
    //
    // Encodings for elements
    //
    // If you add elements the constructor must be updated!
    //
    public static int XML_ELEMENT_UNKNOWN=0;
    public static int XML_ELEMENT_CIM=1;
    public static int XML_ELEMENT_MESSAGE=2;
    public static int XML_ELEMENT_SIMPLEREQ=3;
    public static int XML_ELEMENT_IMETHODCALL=4;
    public static int XML_ELEMENT_LOCALNAMESPACEPATH=5;
    public static int XML_ELEMENT_NAMESPACE=6;
    public static int XML_ELEMENT_MULTIREQ=7;
    public static int XML_ELEMENT_IMETHODRESPONSE=8;
    public static int XML_ELEMENT_IRETURNVALUE=10;
    public static int XML_ELEMENT_CLASS=12;
    public static int XML_ELEMENT_QUALIFIER=13;
    public static int XML_ELEMENT_SIMPLERSP=15;
    public static int XML_ELEMENT_PROPERTY=16;
    public static int XML_ELEMENT_PROPERTY_ARRAY=17;
    public static int XML_ELEMENT_PARAMETER_REFERENCE=19;
    public static int XML_ELEMENT_PARAMETER_ARRAY=20;
    public static int XML_ELEMENT_PARAMETER_REFARRAY=21;
    public static int XML_ELEMENT_PARAMETER=22;
    public static int XML_ELEMENT_METHOD=23;
    public static int XML_ELEMENT_INSTANCE=24;
    public static int XML_ELEMENT_INSTANCENAME=25;
    public static int XML_ELEMENT_KEYBINDING=26;
    public static int XML_ELEMENT_KEYVALUE=27;

    public static int XML_ELEMENT_IMPLICITKEY=30;
    public static int XML_ELEMENT_METHODCALL=33;
    public static int XML_ELEMENT_RETURNVALUE=34;
    public static int XML_ELEMENT_METHODRESPONSE=35;
    public static int XML_ELEMENT_PROPERTY_REF=36;
    public static int XML_ELEMENT_ERROR=37;
    public static int XML_ELEMENT_QUALIFIER_DECLARATION=38;
    public static int XML_ELEMENT_SCOPE=39;
    public static int XML_ELEMENT_DECLARATION=40;
    public static int XML_ELEMENT_DECLGROUP=2000;
    public static int XML_ELEMENT_DECLGROUP_WITHNAME=2001;
    public static int XML_ELEMENT_PARAMVALUE=7;
    public static int XML_ELEMENT_IPARAMVALUE=42;
    public static int XML_ELEMENT_CLASSPATH=1000;
    public static int XML_ELEMENT_LOCALCLASSPATH=1001;
    public static int XML_ELEMENT_CLASSNAME=1002;
    public static int XML_ELEMENT_INSTANCEPATH=1003;
    public static int XML_ELEMENT_LOCALINSTANCEPATH=1004;
    public static int XML_ELEMENT_HOST=1005;
    public static int XML_ELEMENT_NAMESPACEPATH=1006;
    public static int XML_ELEMENT_OBJECTPATH=1006;
    public static int XML_ELEMENT_VALUE=4000;
    public static int XML_ELEMENT_VALUE_ARRAY=4001;
    public static int XML_ELEMENT_VALUE_NAMEDOBJECT=4002;
    public static int XML_ELEMENT_VALUE_REFERENCE=4003;
    public static int XML_ELEMENT_VALUE_OBJECT=4004;
    public static int XML_ELEMENT_VALUE_OBJECTWITHLOCALPATH=4005;
    public static int XML_ELEMENT_VALUE_OBJECTWITHPATH=4006;
    public static int XML_ELEMENT_DECLGROUP_WITHPATH=10000;
    public static int XML_ELEMENT_VALUE_NAMEDINSTANCE=4007;
    public static int XML_ELEMENT_VALUE_REFARRAY=4008;
	    
    // For Indications (BAPU)
    public static int XML_ELEMENT_SIMPLEEXPREQ=3999;
    public static int XML_ELEMENT_SIMPLEEXPRSP=3998;
    public static int XML_ELEMENT_EXPMETHODCALL=3997;
    public static int XML_ELEMENT_EXPMETHODRESPONSE=3996;
    public static int XML_ELEMENT_EXPPARAMVALUE=3995;

    XMLNode nextNode=null;
    XMLNode childNode=null;
    XMLNode lastChildNode=null;
    int token=XML_ELEMENT_UNKNOWN;
    
    Vector attrs=null;
    String text;
    static int MAX_ARR_SIZE='z'-'a'+2;
    static int MAX_HITS=10;
    static String[][] stringMap=new String[MAX_ARR_SIZE][MAX_HITS];
    static int[][] stringMapTokens=new int[MAX_ARR_SIZE][MAX_HITS];
    static int[] stringMapIndex=new int[MAX_ARR_SIZE];
	    
    static void addToMap(String str,int tkid) {
	char[] values=str.toUpperCase().toCharArray();
	int arrIndex;
	if (str.length()<0)
	    return;
	char firstChar=values[0];
	
	
	if ((firstChar>='A' && firstChar<='Z'))
	    arrIndex=firstChar-'A';
	else
	    arrIndex=MAX_ARR_SIZE-1;

	stringMap[arrIndex][stringMapIndex[arrIndex]]=str;
	stringMapTokens[arrIndex][stringMapIndex[arrIndex]]=tkid;
	stringMapIndex[arrIndex] += 1;
    }

    static {
	addToMap("CIM",XML_ELEMENT_CIM);
	addToMap("MESSAGE",XML_ELEMENT_MESSAGE);
	addToMap("SIMPLEREQ",XML_ELEMENT_SIMPLEREQ);
	addToMap("MULTIREQ",XML_ELEMENT_MULTIREQ);
	addToMap("IMETHODCALL",XML_ELEMENT_IMETHODCALL);
	addToMap("LOCALNAMESPACEPATH",XML_ELEMENT_LOCALNAMESPACEPATH);
	addToMap("NAMESPACEPATH",XML_ELEMENT_NAMESPACEPATH);
	addToMap("NAMESPACE",XML_ELEMENT_NAMESPACE);
	addToMap("PARAMVALUE",XML_ELEMENT_PARAMVALUE);
	addToMap("IMETHODRESPONSE",XML_ELEMENT_IMETHODRESPONSE);
	addToMap("VALUE",XML_ELEMENT_VALUE);
	addToMap("IRETURNVALUE",XML_ELEMENT_IRETURNVALUE);
	addToMap("VALUE.NAMEDOBJECT",XML_ELEMENT_VALUE_NAMEDOBJECT);
	addToMap("CLASS",XML_ELEMENT_CLASS);
	addToMap("QUALIFIER",XML_ELEMENT_QUALIFIER);
	addToMap("VALUE.ARRAY",XML_ELEMENT_VALUE_ARRAY);
	addToMap("SIMPLERSP",XML_ELEMENT_SIMPLERSP);
	addToMap("PROPERTY.ARRAY",XML_ELEMENT_PROPERTY_ARRAY);
	addToMap("PROPERTY",XML_ELEMENT_PROPERTY);
	addToMap("PARAMETER.REFERENCE",XML_ELEMENT_PARAMETER_REFERENCE);
	addToMap("PARAMETER.ARRAY",XML_ELEMENT_PARAMETER_ARRAY);
	addToMap("PARAMETER.REFARRAY",XML_ELEMENT_PARAMETER_REFARRAY);
	addToMap("PARAMETER",XML_ELEMENT_PARAMETER);
	addToMap("METHOD",XML_ELEMENT_METHOD);
	addToMap("INSTANCE",XML_ELEMENT_INSTANCE);
	addToMap("INSTANCENAME",XML_ELEMENT_INSTANCENAME);
	addToMap("KEYBINDING",XML_ELEMENT_KEYBINDING);
	addToMap("KEYVALUE",XML_ELEMENT_KEYVALUE);	
	addToMap("IMPLICITKEY",XML_ELEMENT_IMPLICITKEY);
	addToMap("METHODCALL",XML_ELEMENT_METHODCALL);
	addToMap("RETURNVALUE",XML_ELEMENT_RETURNVALUE);
	addToMap("METHODRESPONSE",XML_ELEMENT_METHODRESPONSE);
	addToMap("PROPERTY.REFERENCE",XML_ELEMENT_PROPERTY_REF);
	addToMap("ERROR",XML_ELEMENT_ERROR);
	addToMap("QUALIFIER.DECLARATION",XML_ELEMENT_QUALIFIER_DECLARATION);
	addToMap("SCOPE",XML_ELEMENT_SCOPE);

	addToMap("VALUE.OBJECT",XML_ELEMENT_VALUE_OBJECT);
	addToMap("IPARAMVALUE",XML_ELEMENT_IPARAMVALUE);
	addToMap("VALUE.REFERENCE",XML_ELEMENT_VALUE_REFERENCE);
	addToMap("CLASSPATH",XML_ELEMENT_CLASSPATH);
	addToMap("LOCALCLASSPATH",XML_ELEMENT_LOCALCLASSPATH);
	addToMap("CLASSNAME",XML_ELEMENT_CLASSNAME);
	addToMap("INSTANCEPATH",XML_ELEMENT_INSTANCEPATH);
	addToMap("LOCALINSTANCEPATH",XML_ELEMENT_LOCALINSTANCEPATH);
	addToMap("HOST",XML_ELEMENT_HOST);
	
	addToMap("VALUE.OBJECTWITHLOCALPATH",XML_ELEMENT_VALUE_OBJECTWITHLOCALPATH);
	addToMap("VALUE.OBJECTWITHPATH",XML_ELEMENT_VALUE_OBJECTWITHPATH);	
	addToMap("DECLARATION",XML_ELEMENT_DECLARATION);
	addToMap("DECLGROUP",XML_ELEMENT_DECLGROUP);
	addToMap("DECLGROUP.WITHNAME",XML_ELEMENT_DECLGROUP_WITHNAME);
	addToMap("DECLGROUP.WITHPATH",XML_ELEMENT_DECLGROUP_WITHPATH);
	addToMap("OBJECTPATH",XML_ELEMENT_OBJECTPATH);
	addToMap("VALUE.NAMEDINSTANCE",XML_ELEMENT_VALUE_NAMEDINSTANCE);
	addToMap("VALUE.REFARRAY",XML_ELEMENT_VALUE_REFARRAY);

	// For Indications (BAPU)
        addToMap("SIMPLEEXPREQ",XML_ELEMENT_SIMPLEEXPREQ);
        addToMap("SIMPLEEXPREQ",XML_ELEMENT_SIMPLEEXPRSP);
        addToMap("EXPMETHODCALL",XML_ELEMENT_EXPMETHODCALL);
        addToMap("EXPMETHODRESPONSE",XML_ELEMENT_EXPMETHODRESPONSE);
        addToMap("EXPPARAMVALUE",XML_ELEMENT_EXPPARAMVALUE);
    }
    
    public XMLNode(String iName,Attributes iAttrs) {
	int i;
	int arrIndex;
	String name;
	int tsize;

	if (iAttrs!=null && (tsize=iAttrs.getLength())!=0) {
	    attrs=new Vector();
	    for (i = 0; i < tsize ; i++)
		attrs.addElement(new XMLAttribute(
		    iAttrs.getQName(i),
		    iAttrs.getValue(i)));
	}
	// TODO, should XML element names be case insenstive when compared?
	//  name=iName.toUpperCase();
	name=iName;

	if (name.length()<1) {
	    //token will already be set to unknown
	    return;
	}
	
	char firstChar=name.charAt(0);
	if ((firstChar>='A' && firstChar<='Z'))
	    arrIndex=firstChar-'A';
	else
	    arrIndex=MAX_ARR_SIZE-1;
	    
	String[] stringsToCompare=stringMap[arrIndex];
	int index=stringMapIndex[arrIndex];
	
	for(i=0;i<index;i++) {
	    if (stringsToCompare[i].equals(name)) {
		token=stringMapTokens[arrIndex][i];
		break;
	    }
	}
    }
    
    public void assignText(String iText) {
	text=iText;
    }
    

    
    
    //
    // Vector contains XMLAttribute instances
    public String getAttribute(String name) {
    
	if (attrs==null)
	    return(null);
	int tsize=attrs.size();     
	for(int i=0;i<tsize;i++) {
	    XMLAttribute attr=(XMLAttribute)(attrs.elementAt(i));
	    
	    if (attr.getName().equalsIgnoreCase(name)) {
		return(attr.getValue());
	    }		
	}
	return(null);
    }
    //
    // Returns an attribute or throws an exception
    public String mustGetAttribute(String name) throws CIMException {
	String value;

	if (attrs!=null) {
	    int tsize=attrs.size();	
	    for(int i=0;i<tsize;i++) {
		XMLAttribute attr=(XMLAttribute)(attrs.elementAt(i));
		
		if (attr.getName().equalsIgnoreCase(name)) {
		    value=attr.getValue();
		    return(value);
		}	    
	    }
	}
	throw new CIMException(CIMException.CIM_ERR_NOT_FOUND,name);
    }
    

    //
    // Can return null
    //
    public Vector getAttrs() {
	return(attrs);
    }
    
    public String getText() {
	return(text);
    }
    
    
	

    //
    // Unescapes text
    //
    public String getUnescapeText() {
	if (text==null)
	    return(text);
	return(XMLCIM.xmlCIMEscape.xmlCIMUnescape(text));
    }
    
    public int getToken() {
	return(token);
    }
    
    public XMLNode findElement(int elementToken) {
	XMLNode node;
	
	for(node=this;node!=null;node=node.nextNode) {
	    if (node.token==elementToken)
		return(node);
	}
	
	return(null);
    }
	
    public XMLNode mustFindElement(int elementToken) throws CIMException {
	XMLNode node;
	
	for(node=this;node!=null;node=node.nextNode) {
	    if (node.token==elementToken)
		return(node);
	}
	
	throw new CIMException(CIMException.CIM_ERR_FAILED,
		       "Token id ="+elementToken);
    }
    
    
    public XMLNode nextElement(int elementToken) throws CIMException {
	XMLNode node;
	
	node=nextNode;
	if (node==null)
	    return(null);
	    
	if (node.token==elementToken)
	    return(node);
	return(null);
    }
    
    
	    
    public XMLNode mustNextElement(int elementToken) throws CIMException {
	XMLNode node;
	
	node=nextNode;
	if (node==null)
	    return(null);   
	if (node.token==elementToken)
	    return(node);
	throw new CIMException(CIMException.CIM_ERR_FAILED,
				       "Needed tokenid="+elementToken+
					",found tokenid="+node.token);
    }
    
    
		
    public void mustElement(int elementToken) throws CIMException {
	    
	if (token!=elementToken)
	    throw new CIMException(CIMException.CIM_ERR_FAILED,
			"Token id ="+elementToken+", found="+token);
    }
    public XMLNode mustElementChild(int elementToken) throws CIMException {
	    
	if (token!=elementToken)
	    throw new CIMException(CIMException.CIM_ERR_FAILED,
			"Token id ="+elementToken+", found="+getToken());
	XMLNode node=childNode;
	if (node==null)
	    throw new CIMException(CIMException.CIM_ERR_FAILED,
			    "Token id ="+elementToken);
	return(node);
    }
    
    public XMLNode mustChildElement(int elementToken) throws CIMException {
	XMLNode node=childNode;
	if (node==null)
	    throw new CIMException(CIMException.CIM_ERR_FAILED,
			    "Token id ="+elementToken);
	
	if (node.token!=elementToken)
	    throw new CIMException(CIMException.CIM_ERR_FAILED,
			    "Token id ="+elementToken+", found="+node.getToken());
	return(node);
    }	
    
    public XMLNode mustChildElementChild(int elementToken) throws CIMException {
	XMLNode node=childNode;
	if (node==null)
	    throw new CIMException(CIMException.CIM_ERR_FAILED,
			"Token id ="+elementToken);
	
	if (node.token!=elementToken)
	    throw new CIMException(CIMException.CIM_ERR_FAILED,
			"Token id ="+elementToken+", found="+node.getToken());
	node=node.childNode;
	if (node==null)
	    throw new CIMException(CIMException.CIM_ERR_FAILED,
			"Token id ="+elementToken);
	return(node);
    }
    
    
    
    //
    // Advances to child before beginning search
    //
    public XMLNode mustChildFindElement(int elementToken) throws CIMException {
	XMLNode node;
	
	node=childNode;
	if (node==null)
	    throw new CIMException(CIMException.CIM_ERR_FAILED,
			"Token id ="+elementToken);
	
	for(;node!=null;node=node.nextNode) {
	    if (node.token==elementToken)
		return(node);
	}
	
	throw new CIMException(CIMException.CIM_ERR_FAILED,
		    "Token id ="+elementToken);
    }
    
	
    
    
    //
    // Returns the first child of the node identified by the
    // token
    //
    XMLNode findElementChild(int elementToken) {
	XMLNode node;
	
	for(node=this;node!=null;node=node.nextNode) {
	    if (node.token==elementToken)
		return(node.childNode);
	}
	
	return(null);
    }
    
    XMLNode mustFindElementChild(int elementToken) throws CIMException {
	XMLNode node;
	
	for(node=this;node!=null;node=node.nextNode) {
	    if (node.token==elementToken)
		return(node.childNode);
	}
	
	throw new CIMException(CIMException.CIM_ERR_FAILED,
		    "Token id ="+elementToken);
    }
    
    
    XMLNode mustChildFindElementChild(int elementToken) throws CIMException {
	XMLNode node;
	
	node=childNode;
	if (node==null)
	    throw new CIMException(CIMException.CIM_ERR_FAILED,
		    "Token id ="+elementToken);
	
	for(;node!=null;node=node.nextNode) {
	    if (node.token==elementToken)
		return(node.childNode);
	}
	
	throw new CIMException(CIMException.CIM_ERR_FAILED,
			"Token id ="+elementToken);
    }
    
    protected XMLNode findElementAndParameter(String nameOfParameter) throws CIMException {
	int i;
	XMLNode node;
	
	for(node=this;node!=null;node=node.nextNode) {
	    if (node.token!=XMLNode.XML_ELEMENT_IPARAMVALUE)
		continue;
	    
	    Vector nodeattrs=node.getAttrs();
	    if (nodeattrs==null)
		continue;
	    
	    for(int j=0;j<nodeattrs.size();j++) {
		XMLAttribute nattr=(XMLAttribute)(nodeattrs.elementAt(j));
		if (nattr.getName().equalsIgnoreCase(XMLClass.paramName) 
		    && nattr.getValue().equalsIgnoreCase(nameOfParameter))
		    return(node.childNode);
	    }
	}
	return(null);
    }
    
    //
    // Looks for the specified token and then the request attribute. If neither is found
    // the default value is returned. If they are found, then values within <VALUE> or
    // VALUE.ARRAY
    protected String extractParameterValue(String value,String defaultValue) throws CIMException {
	int i;
	XMLNode node;
	
	for(node=this;node!=null;node=node.nextNode) {
	    XMLAttribute nattr;
	    Vector nodeattrs;
	    
	    if (node.token!=XMLNode.XML_ELEMENT_IPARAMVALUE)
		continue;
	    
	    nodeattrs=node.getAttrs();
	    if (nodeattrs==null)
		continue;
	    
	    for(int j=0;j<nodeattrs.size();j++) {
		nattr=(XMLAttribute)(nodeattrs.elementAt(j));
		if (nattr.getName().equalsIgnoreCase(XMLClass.paramName) 
		    && nattr.getValue().equalsIgnoreCase(value)) {
		    node=node.childNode;
		    if (node==null)
			return(defaultValue);
		    node=node.findElement(XMLNode.XML_ELEMENT_VALUE);
		    if (node==null)
			throw new CIMException(CIMException.CIM_ERR_INVALID_PARAMETER,
			    "Could not find <VALUE> element for parameter "+value);
		    String retvalue=node.getUnescapeText();
		    return(retvalue);
		}
	    }
	}
	return(defaultValue);
    }

    protected String mustExtractParameterValue(String value) throws CIMException {
	String ret=extractParameterValue(value,(String)null);
	if (ret==null)
	    throw new CIMException(CIMException.CIM_ERR_INVALID_PARAMETER,
		    "Missing required parameter");  
	return(ret);
    }
	
    protected boolean extractParameterValue(String value,boolean defaultValue)throws CIMException{
	String res=extractParameterValue(value,(String)null);
	
	if (res==null)
	    return(defaultValue);
	
	if (res.equalsIgnoreCase("TRUE"))
	    return(true);
	
	return(false);
    }	

    
    protected String[] extractParameterStringArray(String value) throws CIMException {
	int i;
	XMLNode node;
	    
	for(node=this;node!=null;node=node.nextNode) {
	    XMLAttribute nattr;
	    Vector nodeattrs;
		
	    if (node.token!=XMLNode.XML_ELEMENT_IPARAMVALUE)
		continue;
		
	    nodeattrs=node.getAttrs();
	    if (nodeattrs==null)
		continue;
		
	    for(int j=0;j<nodeattrs.size();j++) {
		nattr=(XMLAttribute)(nodeattrs.elementAt(j));
		if (nattr.getName().equalsIgnoreCase(XMLClass.paramName) 
			&& nattr.getValue().equalsIgnoreCase(value)) {
		    node=node.childNode;
		    if (node==null)
			return(null);
		    node=node.findElement(XMLNode.XML_ELEMENT_VALUE_ARRAY);
		    if (node==null)
			throw new CIMException(CIMException.CIM_ERR_INVALID_PARAMETER,
			    "Missing paramter 2");
		    Vector v=new Vector();
		    for(;;) {
			node=node.findElement(XMLNode.XML_ELEMENT_VALUE);
			if (node==null)
			    break;
			v.addElement(node.getUnescapeText());
		    }
		    String []strings=new String[v.size()];
		    v.copyInto(strings);
		    return(strings);
		}
	    }
	}
	return(null);
    }
    
    //
    // Looks for an <IPARAMVALUE> whose "Name" param is given by paramName and whose
    // following element is of the form tokenId, It returns the attribute value 
    // specified.
    String extractParameterValueAttr(String iparamName,int tokenid,
				     String attrName) throws CIMException {
	XMLNode tmpNode=this;
	for(;tmpNode!=null;tmpNode=tmpNode.nextNode) {
	    if (tmpNode.token!=XMLNode.XML_ELEMENT_IPARAMVALUE)
		continue;
	    String attr=tmpNode.getAttribute(XMLClass.paramName);
	    if (attr==null || !attr.equalsIgnoreCase(iparamName))
		continue;
	    tmpNode=tmpNode.childNode;
	    if (tmpNode==null)
		throw new CIMException(CIMException.CIM_ERR_FAILED,
				"Needed a child for <IPARAMVALUE>");
	    if (tmpNode.token==tokenid)
		return(tmpNode.mustGetAttribute("NAME"));
	}
	return(null);
    }


    
    public void setNext(XMLNode ptr) {
	nextNode=ptr;
    }
    
    public XMLNode getNext() {
	return(nextNode);
    }
    
    public void setChild(XMLNode ptr) {
	if (childNode==null) {
	    childNode=ptr;
	    lastChildNode=ptr;
	} else {
	    lastChildNode.nextNode=ptr;
	    lastChildNode=ptr;
	}
    }
    
    public XMLNode mustGetChild() throws CIMException {
	if (childNode==null)
	    throw new CIMException(CIMException.CIM_ERR_FAILED,
				    "Could not find child element");
	return(childNode);
    }
    
    public XMLNode getChild() {
	return(childNode);
    }
     
    //
    // TODO-GLUE
    //
    public short getNodeType() {
	return(0);
    }
    
    static public XMLNode getXMLNode(org.w3c.dom.Node node) {
	if (node instanceof XMLNode) {
	    return((XMLNode)node);
	}
	if (node==null)
	    return(null);
	throw new InternalError("Regular org.w3c.dom.Node instances not supported");
    }

    public  java.lang.String getNodeName() {
	return(null);
    }
}
