001 /** 002 * 003 * Copyright 2003-2004 The Apache Software Foundation 004 * 005 * Licensed under the Apache License, Version 2.0 (the "License"); 006 * you may not use this file except in compliance with the License. 007 * You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017 018 package org.apache.geronimo.deployment.cli; 019 020 import java.io.File; 021 import java.io.PrintWriter; 022 import java.util.ArrayList; 023 import java.util.List; 024 import java.util.StringTokenizer; 025 026 import javax.enterprise.deploy.spi.DeploymentManager; 027 import javax.enterprise.deploy.spi.Target; 028 import javax.enterprise.deploy.spi.TargetModuleID; 029 import javax.enterprise.deploy.spi.status.ProgressObject; 030 031 import org.apache.geronimo.common.DeploymentException; 032 import org.apache.geronimo.deployment.plugin.jmx.JMXDeploymentManager; 033 034 /** 035 * The CLI deployer logic to distribute. 036 * 037 * @version $Rev: 405624 $ $Date: 2006-05-09 21:08:49 -0700 (Tue, 09 May 2006) $ 038 */ 039 public class CommandDistribute extends AbstractCommand { 040 public CommandDistribute() { 041 super("distribute", "2. Other Commands", "[--inPlace] [--targets target;target;...] [module] [plan]", 042 "Processes a module and adds it to the server environment, but does "+ 043 "not start it or mark it to be started in the future. " + 044 "Normally both a module and plan are passed to the deployer. " + 045 "Sometimes the module contains a plan, or requires no plan, in which case " + 046 "the plan may be omitted. Sometimes the plan references a module already " + 047 "deployed in the Geronimo server environment, in which case a module does " + 048 "not need to be provided.\n" + 049 "If no targets are provided, the module is distributed to all available " + 050 "targets. Geronimo only provides one target (ever), so this is primarily " + 051 "useful when using a different driver.\n" + 052 "If inPlace is provided, the module is not copied to the configuration " + 053 "store of the selected targets. The targets directly use the module."); 054 } 055 056 protected CommandDistribute(String command, String group, String helpArgumentList, String helpText) { 057 super(command, group, helpArgumentList, helpText); 058 } 059 060 protected ProgressObject runCommand(DeploymentManager mgr, PrintWriter out, boolean inPlace, Target[] tlist, File module, File plan) throws DeploymentException { 061 if (inPlace) { 062 if (!(mgr instanceof JMXDeploymentManager)) { 063 throw new DeploymentSyntaxException( 064 "Target DeploymentManager is not a Geronimo one. \n" + 065 "Cannot perform in-place deployment."); 066 } 067 JMXDeploymentManager jmxMgr = (JMXDeploymentManager) mgr; 068 try { 069 jmxMgr.setInPlace(true); 070 return mgr.distribute(tlist, module, plan); 071 } finally { 072 jmxMgr.setInPlace(false); 073 } 074 } else { 075 return mgr.distribute(tlist, module, plan); 076 } 077 } 078 079 protected String getAction() { 080 return "Distributed"; 081 } 082 083 public void execute(PrintWriter out, ServerConnection connection, String[] args) throws DeploymentException { 084 if(args.length == 0) { 085 throw new DeploymentSyntaxException("Must specify a module or plan (or both)"); 086 } 087 088 BooleanHolder inPlaceHolder = new BooleanHolder(); 089 args = processInPlace(args, inPlaceHolder); 090 091 List targets = new ArrayList(); 092 args = processTargets(args, targets); 093 if(args.length > 2) { 094 throw new DeploymentSyntaxException("Too many arguments"); 095 } 096 File module = null; 097 File plan = null; 098 if(args.length > 0) { 099 File test = new File(args[0]); 100 if(DeployUtils.isJarFile(test) || test.isDirectory()) { 101 if(module != null) { 102 throw new DeploymentSyntaxException("Module and plan cannot both be JAR files or directories!"); 103 } 104 module = test; 105 } else { 106 if(plan != null) { 107 throw new DeploymentSyntaxException("Module or plan must be a JAR file or directory!"); 108 } 109 plan = test; 110 } 111 } 112 if(args.length > 1) { 113 File test = new File(args[1]); 114 if(DeployUtils.isJarFile(test) || test.isDirectory()) { 115 if(module != null) { 116 throw new DeploymentSyntaxException("Module and plan cannot both be JAR files or directories!"); 117 } 118 module = test; 119 } else { 120 if(plan != null) { 121 throw new DeploymentSyntaxException("Module or plan must be a JAR file or directory!"); 122 } 123 plan = test; 124 } 125 } 126 if(module != null) { 127 module = module.getAbsoluteFile(); 128 } 129 if(plan != null) { 130 plan = plan.getAbsoluteFile(); 131 } 132 executeOnline(connection, inPlaceHolder.inPlace, targets, out, module, plan); 133 } 134 135 private void executeOnline(ServerConnection connection, boolean inPlace, List targets, PrintWriter out, File module, File plan) throws DeploymentException { 136 final DeploymentManager mgr = connection.getDeploymentManager(); 137 TargetModuleID[] results; 138 boolean multipleTargets; 139 ProgressObject po; 140 if(targets.size() > 0) { 141 Target[] tlist = identifyTargets(targets, mgr); 142 multipleTargets = tlist.length > 1; 143 po = runCommand(mgr, out, inPlace, tlist, module, plan); 144 waitForProgress(out, po); 145 } else { 146 final Target[] tlist = mgr.getTargets(); 147 multipleTargets = tlist.length > 1; 148 po = runCommand(mgr, out, inPlace, tlist, module, plan); 149 waitForProgress(out, po); 150 } 151 152 // print the results that succeeded 153 results = po.getResultTargetModuleIDs(); 154 for (int i = 0; i < results.length; i++) { 155 TargetModuleID result = results[i]; 156 out.print(DeployUtils.reformat(getAction()+" "+result.getModuleID()+(multipleTargets ? " to "+result.getTarget().getName() : "")+(result.getWebURL() == null || !getAction().equals("Deployed") ? "" : " @ "+result.getWebURL()), 4, 72)); 157 if(result.getChildTargetModuleID() != null) { 158 for (int j = 0; j < result.getChildTargetModuleID().length; j++) { 159 TargetModuleID child = result.getChildTargetModuleID()[j]; 160 out.print(DeployUtils.reformat(" `-> "+child.getModuleID()+(child.getWebURL() == null || !getAction().equals("Deployed") ? "" : " @ "+child.getWebURL()),4, 72)); 161 } 162 } 163 } 164 165 // if any results failed then throw so that we'll return non-0 166 // to the operating system 167 if(po.getDeploymentStatus().isFailed()) { 168 throw new DeploymentException("Operation failed: "+po.getDeploymentStatus().getMessage()); 169 } 170 } 171 172 private String[] processTargets(String[] args, List targets) { 173 if(args.length >= 2 && args[0].equals("--targets")) { 174 String value = args[1]; 175 StringTokenizer tok = new StringTokenizer(value, ";", false); 176 while(tok.hasMoreTokens()) { 177 targets.add(tok.nextToken()); 178 } 179 String[] temp = new String[args.length-2]; 180 System.arraycopy(args, 2, temp, 0, temp.length); 181 args = temp; 182 } 183 return args; 184 } 185 186 private String[] processInPlace(String[] args, BooleanHolder inPlaceHolder) { 187 if(args.length >= 2 && args[0].equals("--inPlace")) { 188 inPlaceHolder.inPlace = true; 189 String[] temp = new String[args.length - 1]; 190 System.arraycopy(args, 1, temp, 0, temp.length); 191 args = temp; 192 } 193 return args; 194 } 195 196 private final class BooleanHolder { 197 public boolean inPlace; 198 } 199 }