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 }