/*
 * Copyright (c) 2003, 2018 Oracle and/or its affiliates. All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0, which is available at
 * http://www.eclipse.org/legal/epl-2.0.
 *
 * This Source Code may also be made available under the following Secondary
 * Licenses when the conditions for such availability set forth in the
 * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
 * version 2 with the GNU Classpath Exception, which is available at
 * https://www.gnu.org/software/classpath/license.html.
 *
 * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
 */

package devtests.deployment.util;

import java.io.*;
import java.util.*;
import java.net.*;
import java.beans.*;
import java.util.jar.Manifest;
import javax.enterprise.deploy.model.*;
import javax.enterprise.deploy.shared.factories.*;
import javax.enterprise.deploy.spi.factories.*;
import javax.enterprise.deploy.spi.*;
import javax.enterprise.deploy.spi.status.*;
import javax.enterprise.deploy.shared.ModuleType;

/**
 *
 * @author  administrator
 */
public class JSR88Deployer implements ProgressListener {

    private String host;
    private String port;
    private String user;
    private String password;
    private String uri;
    private DeploymentFactory deploymentFactory;
    private DeploymentManager dm;
    private Target[] targets;
    private final String J2EE_DEPLOYMENT_MANAGER =
                        "J2EE-DeploymentFactory-Implementation-Class";
    private static List systemApps = new ArrayList();
    
    /** Record all events delivered to this deployer (which is also a progress listener. */
    private Vector receivedEvents = new Vector();
    
    /** Record the TargetModuleIDs that resulted from the most recent operation. */
    private TargetModuleID [] mostRecentTargetModuleIDs = null;
    
    /** Creates a new instance of JSR88Deployer */
    public JSR88Deployer(String uri, String user, String password) {
        this.user = user;
        this.password = password;
        this.uri = uri;
        loadDeploymentFactory();
        loadSystemApps(); //system apps to be filtered

        log("Connecting using uri = " + uri + "; user = " + user + "; password = " + password);
        try {
            dm = DeploymentFactoryManager.getInstance().getDeploymentManager(uri, user, password);
        } catch (Exception ex) {
            ex.printStackTrace();
            System.exit(-1);              
        }

        Target[] allTargets = dm.getTargets();
        if (allTargets.length == 0) {
            log("Can't find deployment targets...");
            System.exit(-1);              
        }
        
        // If test being run on EE, exclude the DAS server instance from the deploy targets
        String targetPlatform = System.getProperty("deploymentTarget");
        List filteredTargets = new ArrayList();
        if( ("SERVER".equals(targetPlatform)) || ("CLUSTER".equals(targetPlatform)) ) {
            for(int i=0; i<allTargets.length; i++) {
                if(allTargets[i].getName().equals("server")) {
                    continue;
                }
                filteredTargets.add(allTargets[i]);
            }
            targets = (Target[])(filteredTargets.toArray(new Target[filteredTargets.size()]));
        } else {
            targets = allTargets;
        }

        for(int i=0; i<targets.length; i++) {
            log("DBG : Target " + i + " -> " + targets[i].getName());
        }
    }

    private int waitTillComplete(ProgressObject po) throws Exception {
        DeploymentStatus deploymentStatus = null;
        do {
            /*
             *The progress object may return a DeploymentStatus object that is a snapshot of the
             *current status and will never change.  (The spec is unclear on this behavior.)  So
             *to be sure, get a new deployment status every time through the loop to be sure of
             *getting the up-to-date status.
             */
            deploymentStatus = po.getDeploymentStatus();
            Thread.currentThread().sleep(200);
        } while (!(deploymentStatus.isCompleted() || deploymentStatus.isFailed()));   
        log("Deployment status is " + deploymentStatus.getState().toString());
        if(deploymentStatus.isFailed())
                return(-1);
        return(0);
    }

    public ProgressObject deploy(File archive, File deploymentPlan,
                                boolean startByDefault, boolean useStream,
                                ModuleType type) 
        throws Exception {

        ProgressObject dpo = null;
        ProgressObject po = null;
        if (deploymentPlan == null || deploymentPlan.getName().equals("null")) {
            log("Warning, deploying with null deployment plan");
            if (useStream) {
                if (type == null) {
                    dpo = dm.distribute(targets, 
                                    new FileInputStream(archive.getAbsolutePath()),
                                    null);
                } else {
                    dpo = dm.distribute(targets, type,
                                    new FileInputStream(archive.getAbsolutePath()),
                                    null);
                }
            } else {
                dpo = dm.distribute(targets, archive, null);          
            }
        } else {
            if (useStream) {
                if (type == null) {
                    dpo = dm.distribute(targets, 
                                    new FileInputStream(archive.getAbsolutePath()),
                                    new FileInputStream(deploymentPlan.getAbsolutePath()));
                } else {
                    dpo = dm.distribute(targets, type,
                                    new FileInputStream(archive.getAbsolutePath()),
                                    new FileInputStream(deploymentPlan.getAbsolutePath()));
                }
            } else {
                dpo = dm.distribute(targets, archive, deploymentPlan);          
            }
        }            
        if (dpo!=null) {
            dpo.addProgressListener(this);
            if(waitTillComplete(dpo) != 0) {
                log("DEPLOY Action Failed");
                return(null);
            }

            TargetModuleID[] targetModuleIDs = dpo.getResultTargetModuleIDs();        
            this.mostRecentTargetModuleIDs = targetModuleIDs;
            dumpResultModuleIDs("Deployed " , dpo);

            if (startByDefault) {
                log("STARTINNG... " + targetModuleIDs);
                po = dm.start(targetModuleIDs);
                if (po!=null) {
                    po.addProgressListener(this);
                    if(waitTillComplete(po) != 0) {
                        log("START Action Failed");
                        return(null);
                    }
                }
                return po;
            }
        }
        return(dpo);
    }

    public ProgressObject redeploy(String moduleID, File archive,
                                File deploymentPlan, boolean useStream) throws Exception {

        TargetModuleID[] list = null;
        if (moduleID == null) { //redeploy all but system apps
            throw new UnsupportedOperationException("DO NOT SUPPORT REDEPLOY MULTIPLE APPS");
        } else {
            list = findApplication(moduleID, null);
        }

        TargetModuleID[] modules = filterSystemApps(list);
        if (modules != null && modules.length > 0) {
            for (int i = 0; i < modules.length; i++) {
                log("REDEPLOYING... " + modules[i]);
            }
        }

        ProgressObject dpo = null;
        if (deploymentPlan == null || deploymentPlan.getName().equals("null")) {
            log("Warning, redeploying with null deployment plan");
            if (useStream) {            
                dpo = dm.redeploy(modules, 
                                    new FileInputStream(archive.getAbsolutePath()),
                                    null);
            } else {
                dpo = dm.redeploy(modules, archive, null);
            }
        } else {
            if (useStream) {            
                dpo = dm.redeploy(modules, 
                                    new FileInputStream(archive.getAbsolutePath()),
                                    new FileInputStream(deploymentPlan.getAbsolutePath()));
            } else {
                dpo = dm.redeploy(modules, archive, deploymentPlan);          
            }
        }            
        if (dpo!=null) {
            dpo.addProgressListener(this);
            if(waitTillComplete(dpo) != 0) {
                log("REDEPLOY Action Failed");
                return(null);
            }

            TargetModuleID[] targetModuleIDs = dpo.getResultTargetModuleIDs();        
            this.mostRecentTargetModuleIDs = targetModuleIDs;
            dumpResultModuleIDs("Redeployed " , dpo);
        }
        return(dpo);
    }

    public ProgressObject stop(String moduleID) throws Exception {
        TargetModuleID[] list = null;
        if (moduleID == null) { //stop all but system apps
            list = getAllApplications(Boolean.TRUE);
        } else {
            list = findApplication(moduleID, Boolean.TRUE);
        }

        ProgressObject dpo = null;
        TargetModuleID[] modules = filterSystemApps(list);
        if (modules != null && modules.length > 0) {
            for (int i = 0; i < modules.length; i++) {
                log("STOPPING... " + modules[i]);
            }
            dpo = dm.stop(modules);
            if (dpo!=null) {
                dpo.addProgressListener(this);
                if(waitTillComplete(dpo) != 0) {
                    log("STOP Action Failed");
                    return(null);
                }
                this.mostRecentTargetModuleIDs = dpo.getResultTargetModuleIDs();
            }
        }
        return(dpo);
    }

    /**
     *Starts an application, with an option of waiting between the time the operation is requested
     *and the time the deployer is added as a listener.  This option helps with the test for race
     *conditions involved with managing the list of listeners and the list of delivered events.
     */
    public ProgressObject start(String moduleID, int delayBeforeRegisteringListener) throws Exception {
        TargetModuleID[] list = null;
        if (moduleID == null) { //start all but system apps
            list = getAllApplications(Boolean.FALSE);
        } else {
            list = findApplication(moduleID, Boolean.FALSE);
        }

        TargetModuleID[] modules = filterSystemApps(list);
        ProgressObject dpo = null;
        if (modules != null && modules.length > 0) {
            for (int i = 0; i < modules.length; i++) {
                log("STARTINNG... " + modules[i]);
            }
            dpo = dm.start(modules);
            if (delayBeforeRegisteringListener > 0) {
                try {
                    log("Pausing before adding self as a progress listener");
                    Thread.currentThread().sleep(delayBeforeRegisteringListener);
                } catch (InterruptedException ie) {
                    throw new RuntimeException(this.getClass().getName() + " was interrupted sleeping before adding itself as a progresslistener", ie);
                }
            }
            if (dpo!=null) {
                dpo.addProgressListener(this);
                if (delayBeforeRegisteringListener > 0) {
                    log("Now registered as a progress listener");
                }
                if(waitTillComplete(dpo) != 0) {
                    log("START Action Failed");
                    return(null);
                }
                this.mostRecentTargetModuleIDs = dpo.getResultTargetModuleIDs();
            }
        }
        return(dpo);
    }

    public ProgressObject start(String moduleID) throws Exception {
        return start(moduleID, 0);
    }

    public ProgressObject undeploy(String moduleID) throws Exception {
        TargetModuleID[] list = null;
        //log ("000 trying to undeploy moduleID = " + moduleID);
        if (moduleID == null) { //undeploy all but system apps
            list = getAllApplications(null);
        } else {
            list = findApplication(moduleID, null);
        }

        ProgressObject dpo = null;
        TargetModuleID[] modules = filterSystemApps(list);
        if (modules != null && modules.length > 0) {
            for (int i = 0; i < modules.length; i++) {
                log("UNDEPLOYING... " + modules[i]);
            }
            dpo = dm.undeploy(modules);
            if (dpo!=null) {
                dpo.addProgressListener(this);
                if(waitTillComplete(dpo) != 0) {
                    log("UNDEPLOY Action Failed");
                    return(null);
                }
                this.mostRecentTargetModuleIDs = dpo.getResultTargetModuleIDs();
            }
        }
        return(dpo);
    }

    protected void dumpResultModuleIDs(String prefix, ProgressObject po) {
        TargetModuleID[] targetModuleIDs = po.getResultTargetModuleIDs();
	dumpModulesIDs(prefix, targetModuleIDs);
    }

    protected void dumpModulesIDs(String prefix, TargetModuleID[] targetModuleIDs) {
        for (int i=0;i<targetModuleIDs.length;i++) {            
            dumpModulesIDs(prefix, targetModuleIDs[i]);            
        }
    }
    
    protected void dumpModulesIDs(String prefix, TargetModuleID targetModuleID) {
        log(prefix + targetModuleID);
        TargetModuleID[] subs = targetModuleID.getChildTargetModuleID();
        if (subs!=null) {
            for (int i=0;i<subs.length;i++) {
                log(" Child " + i + " = " + subs[i]);
            }
        }
    }

    public TargetModuleID[] getApplications(ModuleType moduleType, Boolean running) 
        throws Exception {
        TargetModuleID[] modules = null;
        if (running==null) {
            modules = dm.getAvailableModules(moduleType, targets);
        } else if (running.booleanValue()) {
            modules = dm.getRunningModules(moduleType, targets);
        } else {
            modules = dm.getNonRunningModules(moduleType, targets);
        }

        return modules;
    }

    public TargetModuleID[] getAllApplications(Boolean running) 
        throws Exception {
        //log("222. getAllApplications, running = " + running);
        TargetModuleID[] ears = getApplications(ModuleType.EAR, running);
        TargetModuleID[] wars = getApplications(ModuleType.WAR, running);
        TargetModuleID[] cars = getApplications(ModuleType.CAR, running);
        TargetModuleID[] ejbs = getApplications(ModuleType.EJB, running);
        TargetModuleID[] rars = getApplications(ModuleType.RAR, running);

        List list = new ArrayList();
        for (int i = 0; i < ears.length; i++) { list.add(ears[i]); }
        for (int i = 0; i < wars.length; i++) { list.add(wars[i]); }
        for (int i = 0; i < cars.length; i++) { list.add(cars[i]); }
        for (int i = 0; i < ejbs.length; i++) { list.add(ejbs[i]); }
        for (int i = 0; i < rars.length; i++) { list.add(rars[i]); }
    
        TargetModuleID[] results = new TargetModuleID[list.size()];
        for (int i = 0; i < list.size(); i++) { 
            results[i] = (TargetModuleID) list.get(i);
        }
        return results;
    }

    protected TargetModuleID[] findApplication(String moduleID, ModuleType moduleType, Boolean running) 
        throws Exception {
        /*
         *The DeploymentFacility requires that start, stop, redeploy, and undeploy requests
         *operate on the same set of targets that the original deployment did.  As written currently, this test
         *class always deploys to all available targets so the other functions should also
         *apply to all available targets.
         */
        TargetModuleID[] list = getApplications(moduleType, running);
        return filterTargetModuleIDsByModule(list, moduleID);
    }

    protected TargetModuleID[] findApplication(String moduleID, Boolean running) 
        throws Exception {
        //log("111 trying to get everything, moduleid = " + moduleID + "; boolean = " + running);
        TargetModuleID[] list = getAllApplications(running);
        return filterTargetModuleIDsByModule(list, moduleID);
    }

    /**
     *Filter an array of TargetModuleID, keeping only those that match the specified module ID.
     *@param tmids the array of TargetModuleID to be filtered
     *@param moduleID the name of the module of interest
     *@return new TargetModuleID array, containing only the elements from the original array that match the module ID
     */
    protected TargetModuleID[] filterTargetModuleIDsByModule(TargetModuleID [] tmids, String moduleID) {
        List tmidsToUse = new ArrayList();
        /*
         *Add to the vector of TMIDs each TMID from getApplications that also matches the
         *module ID.
         */
        for (int i = 0; i < tmids.length; i++) {
            if (moduleID.equals(tmids[i].getModuleID())) {
                tmidsToUse.add(tmids[i]);
            }
        }
        return (TargetModuleID [])(tmidsToUse.toArray(new TargetModuleID[tmidsToUse.size()]));
    }
    
    public void listApplications(ModuleType moduleType, Boolean running) 
        throws Exception {
        TargetModuleID[] modules = getApplications(moduleType, running); 
        if (modules == null) {
        } else {
            for (int i = 0; i < modules.length; i++) {
                if (running==null) {
                    dumpModulesIDs("    AVAILABLE ", modules[i]);
                } else if (running.booleanValue()) {
                    dumpModulesIDs("    RUNNING ", modules[i]);
                } else {
                    dumpModulesIDs("    NOT RUNNING ", modules[i]); 
                }
            }
        }
    }
    
    private void invokeAppClient(ProgressObject po, TargetModuleID targetModuleID) {
        TargetModuleID[] subs = targetModuleID.getChildTargetModuleID();   
        if (subs==null) {
            return;
        }
        for (int i=0;i<subs.length;i++) {
            if (subs[i].getModuleID().indexOf("client")!=-1) {
                log(" App Client child " + subs[i]);
                ClientConfiguration cc = po.getClientConfiguration(subs[i]);
                try {
                    cc.execute();
                } catch(Throwable t) {
                    t.printStackTrace();
                }
            }
        }
    }    

    
    public static void main(String[] args) {

        int finalExitValue = 0;

        if (args.length == 0 || "help".equals(args[0])) { 
            usage(); 
            System.exit(1);
        }
        if (args.length < 5) {
            usage(); 
            System.exit(1);
        }

        JSR88Deployer deployer = new JSR88Deployer(args[1], args[2], args[3]);
        if ("deploy".equals(args[0]) || "deploy-stream".equals(args[0])) {
            if (args.length < 6) { 
                usage(); 
                System.exit(1);
            }
            boolean useStream = "deploy-stream".equals(args[0]);
            boolean startByDefault = "true".equals(args[4]);
            java.io.File inputFile = new java.io.File(args[5]);
            if (!inputFile.exists()) {
                error("File not found : " + inputFile.getPath());
                System.exit(1);
            }
            File deploymentFile = null;
            if (args.length > 6) {
                deploymentFile = new File(args[6]);
                if (!args[6].equals("null")) {
                    if (!deploymentFile.exists()) {
                        error("Deployment File not found : " + deploymentFile.getPath());
                        System.exit(1);
                    }
                }
            }
            try {
                log("Deploying " + inputFile + " plan: " + deploymentFile);
                if(deployer.deploy(inputFile, deploymentFile,
                                        startByDefault, useStream, null) == null)
                    finalExitValue = -1;
            } catch(Exception e) {
                e.printStackTrace();
                System.exit(1);
            }
        } else if ("deploy-stream-withtype".equals(args[0])) {
            if (args.length < 7) { 
                usage(); 
                System.exit(1);
            }
            boolean useStream = true;
            boolean startByDefault = "true".equals(args[4]);
            java.io.File inputFile = new java.io.File(args[5]);
            if (!inputFile.exists()) {
                error("File not found : " + inputFile.getPath());
                System.exit(1);
            }
            ModuleType t = 
                ModuleType.getModuleType((new Integer(args[6])).intValue());
            File deploymentFile = null;
            if (args.length > 7) {
                deploymentFile = new File(args[7]);
                if (!args[7].equals("null")) {
                    if (!deploymentFile.exists()) {
                        error("Deployment File not found : " + deploymentFile.getPath());
                        System.exit(1);
                    }
                }
            }
            try {
                log("Deploying " + inputFile + " plan: " + deploymentFile);
                if(deployer.deploy(inputFile, deploymentFile,
                                        startByDefault, useStream, t) == null)
                    finalExitValue = -1;
            } catch(Exception e) {
                e.printStackTrace();
                System.exit(1);
            }
        } else if ("list".equals(args[0])) {

            if (args.length != 5) { 
                usage(); 
                System.exit(0);
            }

            try {
                if ("all".equals(args[4])) {
                    deployer.listApplications(ModuleType.EAR, null);
                    deployer.listApplications(ModuleType.WAR, null);
                    deployer.listApplications(ModuleType.EJB, null);
                    deployer.listApplications(ModuleType.CAR, null);
                    deployer.listApplications(ModuleType.RAR, null);
                } else if ("running".equals(args[4])) {
                    deployer.listApplications(ModuleType.EAR, Boolean.TRUE);
                    deployer.listApplications(ModuleType.WAR, Boolean.TRUE);
                    deployer.listApplications(ModuleType.EJB, Boolean.TRUE);
                    deployer.listApplications(ModuleType.CAR, Boolean.TRUE);
                    deployer.listApplications(ModuleType.RAR, Boolean.TRUE);
                } else if ("nonrunning".equals(args[4])) {
                    deployer.listApplications(ModuleType.EAR, Boolean.FALSE);
                    deployer.listApplications(ModuleType.WAR, Boolean.FALSE);
                    deployer.listApplications(ModuleType.EJB, Boolean.FALSE);
                    deployer.listApplications(ModuleType.CAR, Boolean.FALSE);
                    deployer.listApplications(ModuleType.RAR, Boolean.FALSE);
                } else {
                    usage();
                    finalExitValue = 1;
                }
            } catch (Exception e) {
                e.printStackTrace();
                System.exit(-1);
            }
        } else if ("redeploy".equals(args[0]) || "redeploy-stream".equals(args[0])) {
            if (args.length < 6) { 
                usage(); 
                System.exit(-1);
            }
            
            boolean useStream = "redeploy-stream".equals(args[0]);
            java.io.File inputFile = new java.io.File(args[5]);
            if (!inputFile.exists()) {
                error("File not found : " + inputFile.getPath());
                System.exit(1);
            }
            File deploymentFile = null;
            if (args.length > 6) {
                deploymentFile = new File(args[6]);
                if (!args[6].equals("null")) {
                    if (!deploymentFile.exists()) {
                        error("Deployment File not found : " + deploymentFile.getPath());
                        System.exit(1);
                    }
                }
            }
            try {
                log("Redeploying " + inputFile + " plan: " + deploymentFile);
                if ("all".equals(args[4])) {
                    if(deployer.redeploy(null, inputFile, deploymentFile, useStream) == null)
                        finalExitValue = -1;
                } else {
                    if(deployer.redeploy(args[4], inputFile, deploymentFile, useStream) == null)
                        finalExitValue = -1;
                }
            } catch(Exception e) {
                e.printStackTrace();
                System.exit(1);
            }
        } else {
            if (args.length != 5) { 
                usage(); 
                System.exit(1);
            }

            try {
                if ("all".equals(args[4])) {
                    if ("undeploy".equals(args[0])) {
                        if(deployer.undeploy(null) == null)
                            finalExitValue = -1;
                    } else if ("start".equals(args[0])) {
                        if(deployer.start(null) == null)
                            finalExitValue = -1;
                    } else if ("stop".equals(args[0])) {
                        if(deployer.stop(null) == null)
                            finalExitValue = -1;
                    } else {
                        usage();
                        finalExitValue = 1;
                    }
                } else {
                    if ("undeploy".equals(args[0])) {
                        if(deployer.undeploy(args[4]) == null)
                            finalExitValue = -1;
                    } else if ("start".equals(args[0])) {
                        if(deployer.start(args[4]) == null)
                            finalExitValue = -1;
                    } else if ("stop".equals(args[0])) {
                        if(deployer.stop(args[4]) == null)
                            finalExitValue = -1;
                    } else {
                        usage();
                        finalExitValue = 1;
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
                System.exit(-1);
            }
        }
        System.exit(finalExitValue);
    }
    
    /** Invoked when a deployment progress event occurs.
     *
     * @param event the progress status event.
     */
    public void handleProgressEvent(ProgressEvent event) {
        DeploymentStatus ds = event.getDeploymentStatus();
        System.out.println("Received Progress Event state " + ds.getState() + " msg = " + ds.getMessage());
        TargetModuleID tmid = event.getTargetModuleID();
        System.out.println("Received Progress Event target module id " + tmid.getModuleID());
        /*
         *Add this event to the vector collecting them.
         */
        this.receivedEvents.add(event);
    }

    /**
     *Report all the events received by this deployer.
     *
     *@return array of Objects containing the received events
     */
    public ProgressEvent [] getReceivedEvents() {
        ProgressEvent [] answer = new ProgressEvent[this.receivedEvents.size()];
        return (ProgressEvent []) this.receivedEvents.toArray(answer);
    }
    
    /**
     *Clear the collection of received events recorded by this deployer.
     */
    public void clearReceivedEvents() {
        this.receivedEvents.clear();
    }

    public TargetModuleID [] getMostRecentTargetModuleIDs() {
        return this.mostRecentTargetModuleIDs;
    }
    
    public void clearMostRecentTargetModuleIDs() {
        this.mostRecentTargetModuleIDs = null;
    }
    
    private void loadDeploymentFactory() {
        try {
            File file = new File(System.getProperty("com.sun.aas.installRoot")
                + File.separator+ "lib" + File.separator + "deployment"
                + File.separator + "sun-as-jsr88-dm.jar");

            Manifest mf = new java.util.jar.JarFile(file).getManifest();
            String className = mf.getMainAttributes().getValue(J2EE_DEPLOYMENT_MANAGER);
            URL[] urls = new URL[]{file.toURL()};
            URLClassLoader urlClassLoader = new java.net.URLClassLoader(urls, getClass().getClassLoader());

            Class factory = null;
            try {
                factory=urlClassLoader.loadClass(className);
            } catch (ClassNotFoundException cnfe) {
                cnfe.printStackTrace();
            }   

            Object df = null;
            try {   
                df = factory.newInstance();
            } catch (Exception ie) {
                ie.printStackTrace();
            }
            if (df instanceof DeploymentFactory) {
                DeploymentFactoryManager.getInstance().registerDeploymentFactory((DeploymentFactory) df);
            } else {
                System.exit(-1);
            }  

        } catch (Exception ex) {
            log("Failed to load the deployment factory.");
            ex.printStackTrace();
            System.exit(-1);
        }
    }

    private static void usage() {
        System.out.println("Usage: command <JSR88.URI> <admin-user> <admin-password> [command-parameters]");
        System.out.println("    where command is one of [deploy<-stream> | redeploy<-stream> | undeploy | start | stop | list]");
        System.out.println("    where <JSR88.URI> is: deployer:Sun:AppServer::${admin.host}:${admin.port} for PE");
        System.out.println("    where <JSR88.URI> is: deployer:Sun:AppServer::${admin.host}:${admin.port}:https for EE");
        System.out.println("    where command-parameters are as follows");
        System.out.println("      deploy: <startByDefault> <archiveFile> [<deploymentFile>]");
        System.out.println("      deploy-stream: <startByDefault> <archiveFile> [<deploymentFile>]");
        System.out.println("      deploy-stream-withtype: <startByDefault> <archiveFile> <moduleType> [<deploymentFile>]");
        System.out.println("      redeploy: <moduleID> <archiveFile> [<deploymentFile>]");
        System.out.println("      redeploy-stream: <moduleID> <archiveFile> [<deploymentFile>]");
        System.out.println("      undeploy: [all | moduleID]");
        System.out.println("      start: [all | moduleID]");
        System.out.println("      stop: [all | moduleID]");
        System.out.println("      list: [all | running | nonrunning]");
    }

    public static void log(String message) {
        System.out.println("[JSR88Deployer]:: " + message);
    }

    public static void error(String message) {
        System.err.println("[JSR88Deployer]:: " + message);
    }
    
    private void loadSystemApps() {
        systemApps.add("MEjbApp");
        systemApps.add("__ejb_container_timer_app");
        systemApps.add("adminapp");
        systemApps.add("admingui");
        systemApps.add("com_sun_web_ui");
    }

    private TargetModuleID[] filterSystemApps(TargetModuleID[] list) {

        //Comment out the following logic as we will move to use the MBean
        //that returns only non-system apps.
/*
        List l = new ArrayList();
        for (int i = 0; i < list.length; i++) {
            String moduleID = list[i].getModuleID();
            log("found module = " + moduleID);
            if (!systemApps.contains(moduleID)) {
                l.add(list[i]);
            }
        }

        TargetModuleID[] ids = new TargetModuleID[l.size()];
        for (int i = 0; i < l.size(); i++) {
            ids[i] = (TargetModuleID) l.get(i);
        }
        return ids;
*/
        return list;
    }
}
