/**
 * JOnAS: Java(TM) Open Application Server
 * Copyright (C) 1999 Bull S.A.
 * Contact: jonas-team@ow2.org
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
 * USA
 *
 * Initial developer(s): Florent BENOIT & Ludovic BERT
 * --------------------------------------------------------------------------
 * $Id: Ear.java 15428 2008-10-07 11:20:29Z sauthieg $
 * --------------------------------------------------------------------------
 */

package org.ow2.jonas.ear.internal.mbean;

import java.net.URL;
import java.util.ArrayList;
import java.util.Iterator;

import javax.management.MBeanServer;
import javax.management.ObjectName;

import org.ow2.jonas.jmx.JmxService;
import org.ow2.jonas.lib.management.javaee.J2EEDeployedObject;
import org.ow2.jonas.lib.management.javaee.J2eeObjectName;


/**
 * Class representing an Ear structure which is composed of :
 * <ul>
 * <li>array of URL of ejb-jar files</li>
 * <li>array of URL of war files</li>
 * <li>array of URL of rar files</li>
 * </ul>
 * @author Florent Benoit
 * @author Michel-Ange Anton (JSR77: J2EEApplication)
 * @author Adriana Danes
 */
public class Ear extends J2EEDeployedObject {

    /**
     * URLs of ejb-jars files
     */
    private URL[] ejbJars = null;


    /**
     * Urls of wars files
     */
    private URL[] wars = null;

    /**
     * Urls of rars files
     */
    private URL[] rars = null;

    /**
     * Url of this EAR
     */
    private URL earUrl = null;

    /**
     * The name of this EAR (J2EEApplication name).
     */
    private String name = null;

    /**
     * The unpack work copy of this EAR.
     */
    private String unpackName = null;

    /**
     * The modules OBJECT_NAMEs
     */
    private String[] modules = null;

    /**
     * The web modules OBJECT_NAMEs
     */
    private String[] webModules = null;

    private MBeanServer localMBeanServer = null;

    /**
     * Construct an Ear structure with the specified files
     * @param objectName  The object name of the deployed object
     * @param pName name of the application
     * @param pUnpackName name of the working copy of the ear
     * @param earUrl the url of this ear
     * @param deploymentDescriptor the deployment descriptor of the file
     * @param ejbJars the URLs of ejb-jar files
     * @param wars the URLs of the war files
     * @param rars the URLs of the rar files
     */
    public Ear(String objectName, String pName, String pUnpackName, URL earUrl, String deploymentDescriptor, URL[] ejbJars, URL[] wars,
            URL[] rars, JmxService jmx) {
        super(objectName);
        this.earUrl = earUrl;
        this.name = pName;
        this.unpackName = pUnpackName;
        setDeploymentDescriptor(deploymentDescriptor);
        this.ejbJars = ejbJars;
        this.wars = wars;
        this.rars = rars;
        localMBeanServer = jmx.getJmxServer();
        if (localMBeanServer == null) {
            throw new RuntimeException("could not get a reference on the MBean Server");
        }
        setModules();
        setWebModules();
    }

    /**
     * Return the url of this Ear
     * @return the url of this Ear
     */
    public URL getEarUrl() {
        return earUrl;
    }

    /**
     * Return the ejb-jar files
     * @return the ejb-jar files
     */
    public URL[] getEjbJars() {
        return ejbJars;
    }

    /**
     * Return the war files
     * @return the war files
     */
    public URL[] getWars() {
        return wars;
    }

    /**
     * Return the rar files
     * @return the rar files
     */
    public URL[] getRars() {
        return rars;
    }

    /**
     * The application name.
     * @return application name
     */
    public String getName() {
        return name;
    }

    /**
     * The name of the working copy of the ear
     * @return work name
     */
    public String getUnpackName() {
        return unpackName;
    }

    /**
     * Determine the J2EEModules used by this J2EEApplication (jar, war, rar).
     */
    private void setModules() {
        // List of ObjectNames corresponding to J2EEModules
        ArrayList al = new ArrayList();
        try {
            // ear ObjectName
            ObjectName on = ObjectName.getInstance(getObjectName());
            String domain = on.getDomain();
            String serverName = on.getKeyProperty(J2EE_TYPE_SERVER);
            String appName = on.getKeyProperty(NAME);
            ObjectName modulesOn = null;
            // Add EJBModules
            modulesOn = J2eeObjectName.getEJBModules(domain, serverName, appName);
            addModuleObjectNames(al, modulesOn);
            // Add WebModules
            modulesOn = J2eeObjectName.getWebModules(domain, serverName, appName);
            addModuleObjectNames(al, modulesOn);
            // Add ResourceAdapterModules
            modulesOn = J2eeObjectName.getResourceAdapterModules(domain, serverName, appName);
            addModuleObjectNames(al, modulesOn);
            // Add AppClientModules
            modulesOn = J2eeObjectName.getAppClientModules(domain, serverName, appName);
            addModuleObjectNames(al, modulesOn);
        } catch (Exception e) {
            // none action
            throw new RuntimeException("Error while using an objectname", e);
        }
        //modules = ((String[]) al.toArray(new String[al.size()]));
        modules = new String[al.size()];
        for (int i = 0; i < modules.length; i++) {
            modules[i] = al.get(i).toString();
        }
    }

    /**
     * Return the J2EEModules used by this J2EEApplication (jar, war, rar).
     * @return A array of OBJECT_NAMEs corresponding to these modules.
     */
    public String[] getModules() {
        return modules;
    }
    /**
     * @return Returns the webModules.
     */
    public String[] getWebModules() {
        return webModules;
    }
    /**
     * Determine the web modules contained in this J2EEApplication
     */
    public void setWebModules() {
        ArrayList al = new ArrayList();
        try {
            // ear ObjectName
            ObjectName on = ObjectName.getInstance(getObjectName());
            String domain = on.getDomain();
            String serverName = on.getKeyProperty(J2EE_TYPE_SERVER);
            String appName = on.getKeyProperty(NAME);
            // Add WebModules
            ObjectName modulesOn = J2eeObjectName.getWebModules(domain, serverName, appName);
            addModuleObjectNames(al, modulesOn);
        } catch (Exception e) {
            // none action
            throw new RuntimeException("Error while using an objectname", e);
        }
        //webModules = ((String[]) al.toArray(new String[al.size()]));
        webModules = new String[al.size()];
        for (int i = 0; i < webModules.length; i++) {
            webModules[i] = al.get(i).toString();
        }
    }
    /**
     * Add to a destination list ObjectNames corresponding to J2EEModules ObjectName patterns found
     * in the local MBeanServer
     * @param al destination list
     * @param modulesOn J2EEModules ObjectName patterns
     */
    private void addModuleObjectNames (ArrayList al, ObjectName modulesOn) {
        Iterator itNames = localMBeanServer.queryNames(modulesOn, null).iterator();
        while (itNames.hasNext()) {
            al.add(itNames.next());
        }
   }
}