//
// XMLQuery.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 XMLQuery.java
//
// The Initial Developer of the Original Code is Adrian Schuur.
//
// 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.
//
//
//
package org.snia.wbemcmd.xml;

import java.util.Enumeration;
import java.util.Vector;
import java.net.MalformedURLException;
import org.snia.wbem.cim.CIMException;
import org.snia.wbem.cim.CIMObjectPath;
import org.snia.wbem.cim.CIMClass;
import org.snia.wbem.cim.CIMInstance;
import org.snia.wbem.cim.CIMValue;
import org.snia.wbemcmd.utils.SimpleEnum;
import org.snia.wbem.client.CIMOMHandle;

public class XMLQuery extends XMLClass {
    static String commandName="ExecQuery";


    public void execute(HTTPWriter pw,XMLNode node,CIMObjectPath path,CIMOMHandle hdl)
                throws CIMException,MalformedURLException {
        String className;
        Enumeration enum;
        String query;
        String qls;
        int ql;
        boolean localOnly=false,includeQualifiers=true,includeClassOrigin=false;


        className=node.extractParameterValueAttr(XMLP_CLASSNAME,XMLNode.XML_ELEMENT_CLASSNAME,
                                                   paramName);
        if (className==null) {
            throw new CIMException(CIMException.CIM_ERR_NOT_FOUND,"Class was null");
        }
        query=XMLCIM.xmlCIMEscape.xmlCIMUnescape(
            node.extractParameterValue(XMLP_QUERY,""));
        qls=node.extractParameterValue(XMLP_QUERYLANGUAGE,"1");
        ql=Integer.parseInt(qls);
        //
        // Get class
        //
        path.setObjectName(className);
        CIMClass cimClass=hdl.getClass(path,false);

        //
        // Get Instance
        //
        path.setObjectName(className);

        enum=hdl.execQuery(path,query,ql);

        while (enum.hasMoreElements()) {
            CIMInstance ci=(CIMInstance)(enum.nextElement());
            CIMObjectPath cop=new CIMObjectPath(ci.getClassName(),ci.getKeyValuePairs());
            cop.setNameSpace(path.getNameSpace());
            pw.println("<VALUE.NAMEDINSTANCE>");
            pw.println(cop.toXml());
            pw.println(ci.toXml(null,localOnly,includeQualifiers,includeClassOrigin,null));
            pw.println("</VALUE.NAMEDINSTANCE>");
        }
        return;
    }


    //
    //
    //
    public static Enumeration execQuery(HTTPOutput output,
                    CIMObjectPath path,
                    String query,
                    int ql) throws CIMException {
        XMLNode result;
        XMLAttribute attr;
        String className=path.getObjectName();
        SimpleEnum se=new SimpleEnum();
        Vector params=new Vector();

        output.setMethod(commandName);

        if (className!=null)
            params.addElement(new Param(XMLP_CLASSNAME,Param.VALUESET,
                        "<CLASSNAME NAME=\""+className+"\"/>"));
        else
            throw new CIMException(CIMException.CIM_ERR_NOT_FOUND,"Class was null");
        params.addElement(new Param(XMLP_QUERY,
                XMLCIM.xmlCIMEscape.XMLEscape(query)));
        params.addElement(new Param(XMLP_QUERYLANGUAGE,""+ql));

        result=intrinsicMethod(output,path,commandName,params);

        if (result==null) {
            return(se);
        }

        // Now find XML_ELEMENT_INSTANCE element
        for(;;) {
            XMLNode child;
            if (result==null) {
                return(se);
            }
            // Now find XML_ELEMENT_VALUE_NAMEDOBJECT element which
            // shouldn't be comming back but some implementations
            // insist on using it
            if (result.getToken()==XMLNode.XML_ELEMENT_VALUE_NAMEDOBJECT
                || result.getToken()==XMLNode.XML_ELEMENT_VALUE_NAMEDINSTANCE) {
                XMLNode lresult=result.getChild();
                if (lresult==null || lresult.getToken()!=XMLNode.XML_ELEMENT_INSTANCENAME) {
                   throw new CIMException(CIMException.XMLERROR,"XMLEnumerationInstances.enumInstances","Need <INSTANCENAME>");
                }
                // getInstanceName(tmpNode, path);
                lresult=lresult.getNext();
                if (lresult==null)
                    throw new CIMException(CIMException.XMLERROR,
                                "XMLEnumerationInstances.enumInstances",
                                "Need <INSTANCE> - no node");

                lresult=lresult.findElement(XMLNode.XML_ELEMENT_INSTANCE);
                if (lresult==null) {
                    throw new CIMException(CIMException.XMLERROR,                                               "XMLEnumerationInstances.enumInstances",
                                "Need <INSTANCE> - no node found");
                }
                CIMInstance cimInstance=new CIMInstance(lresult);
                se.addElement(cimInstance);
                result=result.getNext();
            } else if (result.getToken()==XMLNode.XML_ELEMENT_VALUE_OBJECT) {
                XMLNode lresult=result.getChild();
                lresult=lresult.findElement(XMLNode.XML_ELEMENT_INSTANCE);
                if (lresult==null) {
                    return(se);
                }
                se.addElement( new CIMInstance(result) );
                result=result.getNext();
            } else {
                result=result.findElement(XMLNode.XML_ELEMENT_INSTANCE);
                if (result==null) {
                    return(se);
                }
                se.addElement( new CIMInstance(result) );
                result=result.getNext();
            }
        }
    }
}

