You are viewing a plain text version of this content. The canonical link for it is here.
Posted to scm@geronimo.apache.org by am...@apache.org on 2003/10/20 04:46:36 UTC

cvs commit: incubator-geronimo/modules/core/src/java/org/apache/geronimo/deployment/app ApplicationDeployer.java

ammulder    2003/10/19 19:46:36

  Modified:    modules/core/src/java/org/apache/geronimo/console/cli
                        DeploymentContext.java TextController.java
               modules/core/src/java/org/apache/geronimo/console/cli/controller
                        ControlDeployments.java DeploymentOptions.java
                        ListDeployments.java WorkWithEJBJAR.java
                        WorkWithWAR.java
               modules/core/src/java/org/apache/geronimo/deployment/app
                        ApplicationDeployer.java
  Added:       modules/core/src/java/org/apache/geronimo/console/cli/controller
                        SelectDistributedModules.java
  Log:
  Updates to JSR-88 command-line client
   - now can redeploy, start, stop, etc. (still not fully implemented on
     the server side, but the client can invoke it)
   - cut out some extra navigation
  
  Revision  Changes    Path
  1.2       +4 -2      incubator-geronimo/modules/core/src/java/org/apache/geronimo/console/cli/DeploymentContext.java
  
  Index: DeploymentContext.java
  ===================================================================
  RCS file: /home/cvs/incubator-geronimo/modules/core/src/java/org/apache/geronimo/console/cli/DeploymentContext.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- DeploymentContext.java	19 Oct 2003 01:56:14 -0000	1.1
  +++ DeploymentContext.java	20 Oct 2003 02:46:35 -0000	1.2
  @@ -61,6 +61,7 @@
   import javax.enterprise.deploy.spi.DeploymentManager;
   import javax.enterprise.deploy.spi.DeploymentConfiguration;
   import javax.enterprise.deploy.spi.Target;
  +import javax.enterprise.deploy.spi.TargetModuleID;
   import javax.enterprise.deploy.model.DeployableObject;
   
   /**
  @@ -76,6 +77,7 @@
       public BufferedReader in;
       public ModuleInfo moduleInfo;
       public File saveDir = new File(System.getProperty("user.dir"));
  -    public Target[] targets = new Target[0];
       public boolean connected = false;
  +    public Target[] targets = new Target[0];
  +    public TargetModuleID[] modules = new TargetModuleID[0];
   }
  
  
  
  1.2       +48 -1     incubator-geronimo/modules/core/src/java/org/apache/geronimo/console/cli/TextController.java
  
  Index: TextController.java
  ===================================================================
  RCS file: /home/cvs/incubator-geronimo/modules/core/src/java/org/apache/geronimo/console/cli/TextController.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- TextController.java	19 Oct 2003 01:56:14 -0000	1.1
  +++ TextController.java	20 Oct 2003 02:46:35 -0000	1.2
  @@ -57,8 +57,10 @@
   
   import java.util.ArrayList;
   import java.util.List;
  +import java.io.IOException;
   import javax.enterprise.deploy.spi.Target;
   import javax.enterprise.deploy.spi.DConfigBean;
  +import javax.enterprise.deploy.spi.TargetModuleID;
   import javax.enterprise.deploy.spi.exceptions.ConfigurationException;
   import javax.enterprise.deploy.model.DDBean;
   
  @@ -101,6 +103,7 @@
       public abstract void execute();
   
       // Some common utility methods
  +
       protected Target[] available(Target[] all, Target[] selected) {
           List list = new ArrayList();
           for(int i=0; i<all.length; i++) {
  @@ -118,6 +121,50 @@
           return (Target[])list.toArray(new Target[list.size()]);
       }
   
  +    protected TargetModuleID[] available(TargetModuleID[] all, TargetModuleID[] selected) {
  +        List list = new ArrayList();
  +        for(int i=0; i<all.length; i++) {
  +            boolean found = false;
  +            for(int j = 0; j < selected.length; j++) {
  +                if(equals(all[i], selected[j])) {
  +                    found = true;
  +                    break;
  +                }
  +            }
  +            if(!found) {
  +                list.add(all[i]);
  +            }
  +        }
  +        return (TargetModuleID[])list.toArray(new TargetModuleID[list.size()]);
  +    }
  +
  +    private static boolean equals(TargetModuleID one, TargetModuleID two) {
  +        if(one == null) {
  +            return two == null;
  +        } else if(two == null) {
  +            return false;
  +        }
  +        return one.getTarget().getName().equals(two.getTarget().getName()) &&
  +                one.getModuleID().equals(two.getModuleID()) &&
  +                equals(one.getParentTargetModuleID(), two.getParentTargetModuleID());
  +    }
  +
  +
  +    protected boolean confirmModuleAction(String action) throws IOException {
  +        if(context.modules.length == 0) {
  +            return false;
  +        }
  +        println("");
  +        String choice;
  +        while(true) {
  +            print(action+" "+context.modules.length+" selected module(s)? ");
  +            context.out.flush();
  +            choice = context.in.readLine().trim().toLowerCase();
  +            if(choice.equals("n") || choice.equals("y")) {
  +                return choice.equals("y");
  +            }
  +        }
  +    }
       /**
        * Marches recursively through the DConfigBean tree to initialize
        * DConfigBeans for all the interesting DDBeans.  Once this is done, and
  
  
  
  1.2       +70 -19    incubator-geronimo/modules/core/src/java/org/apache/geronimo/console/cli/controller/ControlDeployments.java
  
  Index: ControlDeployments.java
  ===================================================================
  RCS file: /home/cvs/incubator-geronimo/modules/core/src/java/org/apache/geronimo/console/cli/controller/ControlDeployments.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- ControlDeployments.java	19 Oct 2003 01:56:14 -0000	1.1
  +++ ControlDeployments.java	20 Oct 2003 02:46:36 -0000	1.2
  @@ -57,6 +57,8 @@
   
   import java.io.IOException;
   import javax.enterprise.deploy.spi.Target;
  +import javax.enterprise.deploy.spi.TargetModuleID;
  +import javax.enterprise.deploy.spi.status.ProgressObject;
   import org.apache.commons.logging.Log;
   import org.apache.commons.logging.LogFactory;
   import org.apache.geronimo.console.cli.TextController;
  @@ -69,6 +71,7 @@
    */
   public class ControlDeployments extends TextController {
       private static final Log log = LogFactory.getLog(ControlDeployments.class);
  +    Boolean running;
   
       public ControlDeployments(DeploymentContext context) {
           super(context);
  @@ -84,9 +87,9 @@
               }
               context.out.println((context.targets.length == 0 ? "No" : String.valueOf(context.targets.length))+" target"+(context.targets.length != 1 ? "s" : "")+" currently selected.");
               context.out.println("  1) Select targets (usually servers or clusters) to work with");
  -            context.out.println("  "+(context.targets.length > 0 ? "UN" : "--")+" Start non-running modules on the selected servers/clusters");
  -            context.out.println("  "+(context.targets.length > 0 ? "UN" : "--")+" Stop running modules on the selected servers/clusters");
  -            context.out.println("  "+(context.targets.length > 0 ? "UN" : "--")+" Undeploy modules from the selected servers/clusters");
  +            context.out.println("  "+(context.targets.length > 0 ? "2)" : "--")+" Start non-running modules on the selected servers/clusters");
  +            context.out.println("  "+(context.targets.length > 0 ? "3)" : "--")+" Stop running modules on the selected servers/clusters");
  +            context.out.println("  "+(context.targets.length > 0 ? "4)" : "--")+" Undeploy modules from the selected servers/clusters");
               context.out.println("  "+(context.targets.length > 0 ? "5)" : "--")+" View modules on the selected servers/clusters");
               String choice;
               while(true) {
  @@ -94,23 +97,71 @@
                   context.out.flush();
                   try {
                       choice = context.in.readLine().trim().toLowerCase();
  +                    if(choice.equals("1")) {
  +                        new SelectServer(context).execute();
  +                        break;
  +                    } else if(choice.equals("2")) {
  +                        if(running == null || running.booleanValue()) {
  +                            context.modules = new TargetModuleID[0];
  +                        }
  +                        new SelectDistributedModules(context, new SelectDistributedModules.NonRunningModules("start")).execute();
  +                        running = Boolean.FALSE;
  +                        if(confirmModuleAction("Start")) {
  +                            ProgressObject po = context.deployer.start(context.modules);
  +                            if(po != null) {
  +                                new ProgressMonitor(context, po).execute();
  +                                if(po.getDeploymentStatus().isCompleted()) {
  +                                    running = Boolean.TRUE;
  +                                } else {
  +                                    running = null;
  +                                }
  +                            } else { // assume success
  +                                running = Boolean.TRUE;
  +                            }
  +                        }
  +                        break;
  +                    } else if(choice.equals("3")) {
  +                        if(running == null || !running.booleanValue()) {
  +                            context.modules = new TargetModuleID[0];
  +                        }
  +                        new SelectDistributedModules(context, new SelectDistributedModules.RunningModules("stop")).execute();
  +                        running = Boolean.TRUE;
  +                        if(confirmModuleAction("Stop")) {
  +                            ProgressObject po = context.deployer.stop(context.modules);
  +                            if(po != null) {
  +                                new ProgressMonitor(context, po).execute();
  +                                if(po.getDeploymentStatus().isCompleted()) {
  +                                    running = Boolean.FALSE;
  +                                } else {
  +                                    running = null;
  +                                }
  +                            } else { // assume success
  +                                running = Boolean.FALSE;
  +                            }
  +                        }
  +                        break;
  +                    } else if(choice.equals("4")) {
  +                        if(running == null || running.booleanValue()) {
  +                            context.modules = new TargetModuleID[0];
  +                        }
  +                        new SelectDistributedModules(context, new SelectDistributedModules.NonRunningModules("undeploy")).execute();
  +                        running = Boolean.FALSE;
  +                        if(confirmModuleAction("Undeploy")) {
  +                            ProgressObject po = context.deployer.undeploy(context.modules);
  +                            if(po != null) {
  +                                new ProgressMonitor(context, po).execute();
  +                            }
  +                            running = null;
  +                        }
  +                        break;
  +                    } else if(choice.equals("5")) {
  +                        new ListDeployments(context).execute();
  +                        break;
  +                    } else if(choice.equals("b")) {
  +                        return;
  +                    }
                   } catch(IOException e) {
                       log.error("Unable to read user input", e);
  -                    return;
  -                }
  -                if(choice.equals("1")) {
  -                    new SelectServer(context).execute();
  -                    break;
  -                } else if(choice.equals("2")) { //todo
  -                    break;
  -                } else if(choice.equals("3")) { //todo
  -                    break;
  -                } else if(choice.equals("4")) { //todo
  -                    break;
  -                } else if(choice.equals("5")) {
  -                    new ListDeployments(context).execute();
  -                    break;
  -                } else if(choice.equals("b")) {
                       return;
                   }
               }
  
  
  
  1.2       +36 -7     incubator-geronimo/modules/core/src/java/org/apache/geronimo/console/cli/controller/DeploymentOptions.java
  
  Index: DeploymentOptions.java
  ===================================================================
  RCS file: /home/cvs/incubator-geronimo/modules/core/src/java/org/apache/geronimo/console/cli/controller/DeploymentOptions.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- DeploymentOptions.java	19 Oct 2003 01:56:14 -0000	1.1
  +++ DeploymentOptions.java	20 Oct 2003 02:46:36 -0000	1.2
  @@ -65,6 +65,8 @@
   import java.io.BufferedOutputStream;
   import java.io.FileOutputStream;
   import javax.enterprise.deploy.spi.exceptions.ConfigurationException;
  +import javax.enterprise.deploy.spi.status.ProgressObject;
  +import javax.enterprise.deploy.spi.TargetModuleID;
   import org.apache.commons.logging.Log;
   import org.apache.commons.logging.LogFactory;
   import org.apache.geronimo.console.cli.TextController;
  @@ -92,8 +94,8 @@
               context.out.println((context.targets.length == 0 ? "No" : String.valueOf(context.targets.length))+" target"+(context.targets.length != 1 ? "s" : "")+" currently selected.");
               context.out.println("  1) Select targets (usually servers or clusters) to work with");
               context.out.println("  "+(context.targets.length > 0 ? "2)" : "--")+" Distribute "+context.moduleInfo.file.getName()+" to selected targets");
  -            context.out.println("  "+(context.targets.length > 0 ? "UN" : "--")+" Deploy "+context.moduleInfo.file.getName()+" to selected targets");
  -            context.out.println("  "+(context.targets.length > 0 ? "UN" : "--")+" Redeploy "+context.moduleInfo.file.getName()+" to selected targets");
  +            context.out.println("  "+(context.targets.length > 0 ? "3)" : "--")+" Deploy "+context.moduleInfo.file.getName()+" to selected targets");
  +            context.out.println("  "+(context.targets.length > 0 && context.deployer.isRedeploySupported() ? "4)" : "--")+" Redeploy "+context.moduleInfo.file.getName()+" to selected targets");
               String choice;
               while(true) {
                   context.out.print("Action ([1"+(context.targets.length > 0 ? "-4" : "")+"] or [B]ack): ");
  @@ -111,9 +113,32 @@
                       } else if(choice.equals("2")) {
                           distribute();
                           break;
  -                    } else if(choice.equals("3")) { //todo
  +                    } else if(choice.equals("3")) {
  +                        ProgressObject po = distribute();
  +                        if(po != null) {
  +                            TargetModuleID[] ids = po.getResultTargetModuleIDs();
  +                            println("Successfully distributed "+ids.length+" modules."+(ids.length > 0 ? "Now starting them..." : ""));
  +                            if(ids.length > 0) {
  +                                po = context.deployer.start(ids);
  +                                if(po != null) {
  +                                    new ProgressMonitor(context, po).execute();
  +                                }
  +                            }
  +                        } else {
  +                            println("ERROR: Modules have been distributed but must be manually started.");
  +                        }
                           break;
  -                    } else if(choice.equals("4")) { //todo
  +                    } else if(choice.equals("4")) {
  +                        new SelectDistributedModules(context, new SelectDistributedModules.NonRunningModules("redeploy")).execute();
  +                        if(context.modules.length > 0) {
  +                            println("Prepared to update "+context.modules.length+" deployments with new "+context.moduleInfo.file.getName());
  +                            if(confirmModuleAction("Redeploy")) {
  +                                ProgressObject po = context.deployer.redeploy(context.modules, context.moduleInfo.file, spool());
  +                                if(po != null) {
  +                                    new ProgressMonitor(context, po).execute();
  +                                }
  +                            }
  +                        }
                           break;
                       } else if(choice.equals("b")) {
                           return;
  @@ -127,9 +152,13 @@
           }
       }
   
  -    private void distribute() throws ConfigurationException, IOException {
  +    private ProgressObject distribute() throws ConfigurationException, IOException {
           File dd = spool();
  -        context.deployer.distribute(context.targets, context.moduleInfo.file, dd);
  +        ProgressObject po = context.deployer.distribute(context.targets, context.moduleInfo.file, dd);
  +        if(po != null) {
  +            new ProgressMonitor(context, po).execute();
  +        }
  +        return po;
       }
   
       private File spool() throws IOException, ConfigurationException {
  
  
  
  1.2       +2 -1      incubator-geronimo/modules/core/src/java/org/apache/geronimo/console/cli/controller/ListDeployments.java
  
  Index: ListDeployments.java
  ===================================================================
  RCS file: /home/cvs/incubator-geronimo/modules/core/src/java/org/apache/geronimo/console/cli/controller/ListDeployments.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- ListDeployments.java	19 Oct 2003 01:56:14 -0000	1.1
  +++ ListDeployments.java	20 Oct 2003 02:46:36 -0000	1.2
  @@ -128,6 +128,7 @@
                       break;
                   } else if(choice.equals("l")) {
                       selected = true;
  +                    type = null;
                       break;
                   }
               }
  
  
  
  1.2       +3 -3      incubator-geronimo/modules/core/src/java/org/apache/geronimo/console/cli/controller/WorkWithEJBJAR.java
  
  Index: WorkWithEJBJAR.java
  ===================================================================
  RCS file: /home/cvs/incubator-geronimo/modules/core/src/java/org/apache/geronimo/console/cli/controller/WorkWithEJBJAR.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- WorkWithEJBJAR.java	19 Oct 2003 01:56:14 -0000	1.1
  +++ WorkWithEJBJAR.java	20 Oct 2003 02:46:36 -0000	1.2
  @@ -110,8 +110,8 @@
                       new SelectModule(context).execute();
                       return;
                   } else if(choice.equals("8")) { //todo: prompt to save if modifications were made
  -                    context.moduleInfo = null;
  -                    return;
  +                    new ControlDeployments(context).execute();
  +                    break;
                   } else if(choice.equals("b")) {
                       context.moduleInfo = null;
                       return;
  
  
  
  1.2       +8 -5      incubator-geronimo/modules/core/src/java/org/apache/geronimo/console/cli/controller/WorkWithWAR.java
  
  Index: WorkWithWAR.java
  ===================================================================
  RCS file: /home/cvs/incubator-geronimo/modules/core/src/java/org/apache/geronimo/console/cli/controller/WorkWithWAR.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- WorkWithWAR.java	19 Oct 2003 01:56:14 -0000	1.1
  +++ WorkWithWAR.java	20 Oct 2003 02:46:36 -0000	1.2
  @@ -80,12 +80,12 @@
               context.out.println("  2) Edit the corresponding server-specific deployment information");
               context.out.println("  3) Load a saved set of server-specific deployment information");
               context.out.println("  4) Save the current set of server-specific deployment information");
  -            context.out.println("  UN Deploy or redeploy the WAR into the application server");
  +            context.out.println("  5) Deploy or redeploy the WAR into the application server");
               context.out.println("  6) Select a new EJB JAR or WAR to work with"); //todo: adjust text when other modules are accepted
               context.out.println("  7) Manage existing deployments in the server");
               String choice;
               while(true) {
  -                context.out.print("Action ([2-4,7,8] or [B]ack): ");
  +                context.out.print("Action ([2-7] or [B]ack): ");
                   context.out.flush();
                   try {
                       choice = context.in.readLine().trim().toLowerCase();
  @@ -102,12 +102,15 @@
                   } else if(choice.equals("4")) {
                       new SaveServerSpecificDD(context).execute();
                       break;
  +                } else if(choice.equals("5")) {
  +                    new DeploymentOptions(context).execute();
  +                    break;
                   } else if(choice.equals("6")) {
                       new SelectModule(context).execute();
                       return;
                   } else if(choice.equals("7")) { //todo: prompt to save if modifications were made
  -                    context.moduleInfo = null;
  -                    return;
  +                    new ControlDeployments(context).execute();
  +                    break;
                   } else if(choice.equals("b")) {
                       context.moduleInfo = null;
                       return;
  
  
  
  1.1                  incubator-geronimo/modules/core/src/java/org/apache/geronimo/console/cli/controller/SelectDistributedModules.java
  
  Index: SelectDistributedModules.java
  ===================================================================
  /* ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2003 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Apache" and "Apache Software Foundation" and
   *    "Apache Geronimo" must not be used to endorse or promote products
   *    derived from this software without prior written permission. For
   *    written permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    "Apache Geronimo", nor may "Apache" appear in their name, without
   *    prior written permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   * ====================================================================
   */
  package org.apache.geronimo.console.cli.controller;
  
  import java.io.IOException;
  import java.util.List;
  import java.util.ArrayList;
  import java.util.Arrays;
  import javax.enterprise.deploy.shared.ModuleType;
  import javax.enterprise.deploy.spi.TargetModuleID;
  import javax.enterprise.deploy.spi.Target;
  import javax.enterprise.deploy.spi.exceptions.TargetException;
  import org.apache.commons.logging.Log;
  import org.apache.commons.logging.LogFactory;
  import org.apache.geronimo.console.cli.TextController;
  import org.apache.geronimo.console.cli.DeploymentContext;
  
  /**
   * Chooses a set of distributed but running or not running modules, so the
   * caller can start, stop, or undeploy, or redeploy them.
   *
   * @version $Revision: 1.1 $ $Date: 2003/10/20 02:46:36 $
   */
  public class SelectDistributedModules extends TextController {
      private static final Log log = LogFactory.getLog(SelectDistributedModules.class);
      private Runner runner;
  
      /**
       * Pass in either a new SelectDistributedModules.RunningModules or a new
       * SelectDistributedModules.NonRunningModules to indicate whether the user
       * is selecting running or non-running modules.
       */
      public SelectDistributedModules(DeploymentContext context, Runner runner) {
          super(context);
          this.runner = runner;
      }
  
      public void execute() {
          while(true) {
              newScreen("Select Modules to "+runner.getAction());
              if(!context.connected) {
                  println("ERROR: cannot "+runner.getAction()+" modules in disconnected mode.");
                  context.targets = new Target[0];
                  context.modules = new TargetModuleID[0];
                  return;
              }
              println((context.targets.length == 0 ? "No" : String.valueOf(context.targets.length))+" target"+(context.targets.length != 1 ? "s" : "")+" currently selected.");
              println((context.modules.length == 0 ? "No" : String.valueOf(context.modules.length))+" module"+(context.modules.length != 1 ? "s" : "")+" currently selected"+(context.modules.length > 0 ? ":" : "."));
              for(int i=0; i<context.modules.length; i++) {
                  println("  "+(i+1)+") "+context.modules[i]);
              }
              String choice;
              while(true) {
                  context.out.print("Action ("+(context.modules.length > 0 ? "Remove Module [1"+(context.modules.length > 1 ? "-"+context.modules.length : "")+"], " : "")+"[A]dd Module, manage [T]argets, or [B]ack): ");
                  context.out.flush();
                  try {
                      choice = context.in.readLine().trim().toLowerCase();
                  } catch(IOException e) {
                      log.error("Unable to read user input", e);
                      return;
                  }
                  if(choice.equals("a")) {
                      executeAdd();
                      break;
                  } else if(choice.equals("b")) {
                      return;
                  } else if(choice.equals("t")) {
                      new SelectServer(context).execute();
                      break;
                  } else {
                      int i = 0;
                      try {
                          i = Integer.parseInt(choice);
                      } catch(NumberFormatException e) {
                          continue;
                      }
                      if(i < 1 || i > context.modules.length) {
                          println("  ERROR: There are only "+context.modules.length+" module(s) selected");
                      } else {
                          TargetModuleID[] list = new TargetModuleID[context.modules.length-1];
                          System.arraycopy(context.modules, 0, list, 0, i-1);
                          System.arraycopy(context.modules, i, list, i-1, context.modules.length-i);
                          context.modules = list;
                          break;
                      }
                  }
              }
          }
      }
  
      private boolean selected;
      private ModuleType type;
  
      public void executeAdd() {
          selected = false;
          while(true) {
              TargetModuleID[] available = new TargetModuleID[0];
              newScreen("Add Module");
              if(!context.connected) {
                  println("ERROR: cannot select modules in disconnected mode.");
                  return;
              }
  
              if(context.modules.length > 0) {
                  println("Selected Modules");
                  for(int i=0; i<context.modules.length; i++) {
                      println("  "+context.modules[i]);
                  }
              }
  
              if(selected) {
                  available = showModules();
                  if(!context.connected) {
                      return;
                  }
              }
  
  
              String choice;
              while(true) {
                  print("List [E]JB, [C]lient, [W]eb app, [R]A, [A]pp, A[L]L modules");
                  if(available.length > 0) {
                      println("");
                      print("  or add Module [1"+(available.length > 1 ? "-"+available.length : "")+"]");
                  }
                  print(" or [B]ack): ");
                  context.out.flush();
                  try {
                      choice = context.in.readLine().trim().toLowerCase();
                  } catch(IOException e) {
                      log.error("Unable to read user input", e);
                      return;
                  }
                  if(choice.equals("b")) {
                      return;
                  } else if(choice.equals("e")) {
                      selected = true;
                      type = ModuleType.EJB;
                      break;
                  } else if(choice.equals("c")) {
                      selected = true;
                      type = ModuleType.CAR;
                      break;
                  } else if(choice.equals("w")) {
                      selected = true;
                      type = ModuleType.WAR;
                      break;
                  } else if(choice.equals("r")) {
                      selected = true;
                      type = ModuleType.RAR;
                      break;
                  } else if(choice.equals("a")) {
                      selected = true;
                      type = ModuleType.EAR;
                      break;
                  } else if(choice.equals("l")) {
                      selected = true;
                      type = null;
                      break;
                  } else {
                      int i = 0;
                      try {
                          i = Integer.parseInt(choice);
                      } catch(NumberFormatException e) {
                          continue;
                      }
                      if(i < 1 || i > available.length) {
                          println("  ERROR: There are only "+available.length+" module(s) available");
                      } else {
                          TargetModuleID[] list = new TargetModuleID[context.modules.length+1];
                          System.arraycopy(context.modules, 0, list, 0, context.modules.length);
                          list[context.modules.length] = available[i-1];
                          context.modules = list;
                          break;
                      }
                  }
              }
          }
      }
  
      private TargetModuleID[] showModules() {
          TargetModuleID[] ids;
          try {
              if(type != null) {
                  ids = runner.getModules(type, context);
              } else {
                  List list = new ArrayList();
                  list.addAll(Arrays.asList(runner.getModules(ModuleType.CAR, context)));
                  list.addAll(Arrays.asList(runner.getModules(ModuleType.EAR, context)));
                  list.addAll(Arrays.asList(runner.getModules(ModuleType.EJB, context)));
                  list.addAll(Arrays.asList(runner.getModules(ModuleType.RAR, context)));
                  list.addAll(Arrays.asList(runner.getModules(ModuleType.WAR, context)));
                  ids = (TargetModuleID[])list.toArray(new TargetModuleID[list.size()]);
              }
              ids = available(ids, context.modules);
              println(ids.length == 0 ? "No matching modules found." : "Found "+ids.length+" matching module"+(ids.length == 1 ? "" : "s"));
              for(int i=0; i<ids.length; i++) {
                  println("  "+(i+1)+") "+ids[i]);
              }
              println("");
              return ids;
          } catch(TargetException e) {
              println("ERROR: "+e.getMessage());
          } catch(IllegalStateException e) {
              println("ERROR: No longer connected to server.");
              context.connected = false;
          }
          return new TargetModuleID[0];
      }
  
      private static abstract class Runner {
          private final String action;
  
          /**
           * @param action The action that the user is trying to perform on the
           *               selected modules (i.e. "start" or "undeploy").
           */
          public Runner(String action) {
              this.action = action;
          }
  
          public String getAction() {
              return action;
          }
  
          abstract TargetModuleID[] getModules(ModuleType type, DeploymentContext context) throws TargetException;
      }
  
      public static class RunningModules extends Runner {
          /**
           * @param action The action that the user is trying to perform on the
           *               selected modules (i.e. "stop" or "redeploy").
           */
          public RunningModules(String action) {
              super(action);
          }
  
          public TargetModuleID[] getModules(ModuleType type, DeploymentContext context) throws TargetException {
              return context.deployer.getRunningModules(type, context.targets);
          }
      }
  
      public static class NonRunningModules extends Runner {
          /**
           * @param action The action that the user is trying to perform on the
           *               selected modules (i.e. "start" or "undeploy").
           */
          public NonRunningModules(String action) {
              super(action);
          }
  
          public TargetModuleID[] getModules(ModuleType type, DeploymentContext context) throws TargetException {
              return context.deployer.getNonRunningModules(type, context.targets);
          }
      }
  }
  
  
  
  1.3       +20 -5     incubator-geronimo/modules/core/src/java/org/apache/geronimo/deployment/app/ApplicationDeployer.java
  
  Index: ApplicationDeployer.java
  ===================================================================
  RCS file: /home/cvs/incubator-geronimo/modules/core/src/java/org/apache/geronimo/deployment/app/ApplicationDeployer.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- ApplicationDeployer.java	19 Oct 2003 01:56:14 -0000	1.2
  +++ ApplicationDeployer.java	20 Oct 2003 02:46:36 -0000	1.3
  @@ -182,30 +182,35 @@
           ModuleType type = verifyDeployment(module, dd);
           //todo: Create and start an MBean for the deployment, use that later to check status of the deployment
           ServerTargetModule tm = new ServerTargetModule(type, localServerTarget, name); //todo: specify URL for web apps
  -        deployments.add(tm);
  +        if(!deployments.contains(tm)) {
  +            deployments.add(tm);
  +        }
       }
   
       /**
        * @jmx:managed-operation
        */
  -    public void start(TargetModuleID[] moduleIDList) {
  +    public void start(TargetModuleID[] modules) {
           //todo: what should this return?  Some sort of ID that the ProgressObject can poll?  Perhaps it should use notifications instead?
  +        validateModules(modules, false);
           //todo: implement me
       }
   
       /**
        * @jmx:managed-operation
        */
  -    public void stop(TargetModuleID[] moduleIDList) {
  +    public void stop(TargetModuleID[] modules) {
           //todo: what should this return?  Some sort of ID that the ProgressObject can poll?  Perhaps it should use notifications instead?
  +        validateModules(modules, true);
           //todo: implement me
       }
   
       /**
        * @jmx:managed-operation
        */
  -    public void undeploy(TargetModuleID[] moduleIDList) {
  +    public void undeploy(TargetModuleID[] modules) {
           //todo: what should this return?  Some sort of ID that the ProgressObject can poll?  Perhaps it should use notifications instead?
  +        validateModules(modules, false);
           //todo: implement me
       }
   
  @@ -300,6 +305,16 @@
           } else {
               log.error("Validation Error: cannot determine the J2EE module type for "+module.getName());
               return null;
  +        }
  +    }
  +
  +    private void validateModules(TargetModuleID[] modules, boolean running) {
  +        for(int i = 0; i < modules.length; i++) {
  +            TargetModuleID module = modules[i];
  +            if(!module.getTarget().equals(localServerTarget)) {
  +                throw new IllegalArgumentException("Cannot affect modules for target "+module.getTarget().getName());
  +            }
  +            //todo: validate whether module is running according to the running argument
           }
       }
   }