/*
 * Copyright 2002,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.catalina.ant.jmx;


import java.util.ArrayList;
import java.util.List;

import javax.management.MBeanServerConnection;
import javax.management.ObjectName;

import org.apache.tools.ant.BuildException;


/**
 * Access <em>JMX</em> JSR 160 MBeans Server. 
 * <ul>
 * <li>open more then one JSR 160 rmi connection</li>
 * <li>Get/Set Mbeans attributes</li>
 * <li>Call Mbean Operation with arguments</li>
 * <li>Argument values can be converted from string to int,long,float,double,boolean,ObjectName or InetAddress </li>
 * <li>Query Mbeans</li>
 * <li>Show Get, Call, Query result at Ant console log</li>
 * <li>Bind Get, Call, Query result at Ant properties</li>
 * </ul>
 *
 * Examples:
 * <ul>
 * <li>
 * Get a session attribute hello from session with ref <em>${sessionid.0}</em> form 
 * app <em>Catalina:type=Manager,path=/ClusterTest,host=localhost</em> 
 * <pre>
 *   &lt;jmx:invoke
 *           name="Catalina:type=Manager,path=/ClusterTest,host=localhost" 
 *           operation="getSessionAttribute"
 *           resultproperty="hello"&gt;
 *         &lt;arg value="${sessionid.0}"/&gt;
 *         &lt;arg value="Hello"/&gt;
 *   &lt;/jmx:invoke&gt;
 * </pre>
 * </li>
 * <li>
 * Create new AccessLogger at localhost 
 * <code>
 *   &lt;jmx:invoke
 *           name="Catalina:type=MBeanFactory" 
 *           operation="createAcccesLoggerValve"
 *           resultproperty="acccesLoggerObjectName"
 *       &gt;
 *         &lt;arg value="Catalina:type=Host,host=localhost"/&gt;
 *   &lt;/jmx:invoke&gt;
 *
 * </code>
 * </li>
 * <li>
 * Remove existing AccessLogger at localhost 
 * <code>
 *   &lt;jmx:invoke
 *           name="Catalina:type=MBeanFactory" 
 *           operation="removeValve"
 *       &gt;
 *         &lt;arg value="Catalina:type=Valve,name=AccessLogValve,host=localhost"/&gt;
 *   &lt;/jmx:invoke&gt;
 *
 * </code>
 * </li>
 * </ul>
 * <p>
 * First call to a remote MBeanserver save the JMXConnection a referenz <em>jmx.server</em>
 * </p>
 * These tasks require Ant 1.6 or later interface.
 *
 * @author Peter Rossbach
 * @version $Revision$ $Date$
 * @since 5.5.10
 */

public class JMXAccessorInvokeTask extends JMXAccessorTask {


    // ----------------------------------------------------- Instance Variables

    private String operation ;
    private List args=new ArrayList();

    // ----------------------------------------------------- Instance Info

    /**
     * Descriptive information describing this implementation.
     */
    private static final String info = "org.apache.catalina.ant.JMXAccessorInvokeTask/1.0";

    /**
     * Return descriptive information about this implementation and the
     * corresponding version number, in the format
     * <code>&lt;description&gt;/&lt;version&gt;</code>.
     */
    public String getInfo() {

        return (info);

    }

    // ------------------------------------------------------------- Properties
    
    /**
     * @return Returns the operation.
     */
    public String getOperation() {
        return operation;
    }
    /**
     * @param operation The operation to set.
     */
    public void setOperation(String operation) {
        this.operation = operation;
    }

    public void addArg(Arg arg ) {
        args.add(arg);
    }

    /**
     * @return Returns the args.
     */
    public List getArgs() {
        return args;
    }
    /**
     * @param args The args to set.
     */
    public void setArgs(List args) {
        this.args = args;
    }
    
    // ------------------------------------------------------ protected Methods
    
    /**
     * Execute the specified command, based on the configured properties. The
     * input stream will be closed upon completion of this task, whether it was
     * executed successfully or not.
     * 
     * @exception BuildException
     *                if an error occurs
     */
    public String jmxExecute(MBeanServerConnection jmxServerConnection)
        throws Exception {

        if (getName() == null) {
            throw new BuildException("Must specify a 'name'");
        }
        if ((operation == null)) {
            throw new BuildException(
                    "Must specify a 'operation' for call");
        }
        return  jmxInvoke(jmxServerConnection, getName());
     }

    /**
     * @param jmxServerConnection
     * @throws Exception
     */
    protected String jmxInvoke(MBeanServerConnection jmxServerConnection, String name) throws Exception {
        Object result ;
        if (args == null) {
             result = jmxServerConnection.invoke(new ObjectName(name),
                    operation, null, null);
        } else {
            Object argsA[]=new Object[ args.size()];
            String sigA[]=new String[args.size()];
            for( int i=0; i<args.size(); i++ ) {
                Arg arg=(Arg)args.get(i);
                if( arg.type==null) {
                    arg.type="java.lang.String";
                    sigA[i]=arg.getType();
                    argsA[i]=arg.getValue();
                } else {
                    sigA[i]=arg.getType();
                    argsA[i]=convertStringToType(arg.getValue(),arg.getType());
                }                
            }
            result = jmxServerConnection.invoke(new ObjectName(name), operation, argsA, sigA);
        }
        if(result != null) {
            echoResult(operation,result);
            createProperty(result);
        }
        return null;
    }

}
