001 /**
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements. See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License. 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.BufferedReader;
021 import java.io.File;
022 import java.io.FileReader;
023 import java.io.IOException;
024 import java.io.InputStream;
025 import java.io.OutputStreamWriter;
026 import java.io.PrintWriter;
027 import java.util.Arrays;
028 import java.util.IdentityHashMap;
029 import java.util.Iterator;
030 import java.util.LinkedList;
031 import java.util.List;
032
033 import javax.enterprise.deploy.spi.factories.DeploymentFactory;
034
035 import org.apache.geronimo.cli.deployer.CommandArgs;
036 import org.apache.geronimo.cli.deployer.CommandFileCommandMetaData;
037 import org.apache.geronimo.cli.deployer.CommandMetaData;
038 import org.apache.geronimo.cli.deployer.DeployCommandMetaData;
039 import org.apache.geronimo.cli.deployer.DeployerCLParser;
040 import org.apache.geronimo.cli.deployer.DistributeCommandMetaData;
041 import org.apache.geronimo.cli.deployer.InstallLibraryCommandMetaData;
042 import org.apache.geronimo.cli.deployer.InstallPluginCommandMetaData;
043 import org.apache.geronimo.cli.deployer.ListModulesCommandMetaData;
044 import org.apache.geronimo.cli.deployer.ListTargetsCommandMetaData;
045 import org.apache.geronimo.cli.deployer.LoginCommandMetaData;
046 import org.apache.geronimo.cli.deployer.RedeployCommandMetaData;
047 import org.apache.geronimo.cli.deployer.RestartCommandMetaData;
048 import org.apache.geronimo.cli.deployer.SearchPluginsCommandMetaData;
049 import org.apache.geronimo.cli.deployer.StartCommandMetaData;
050 import org.apache.geronimo.cli.deployer.StopCommandMetaData;
051 import org.apache.geronimo.cli.deployer.UndeployCommandMetaData;
052 import org.apache.geronimo.common.DeploymentException;
053 import org.apache.geronimo.gbean.GBeanInfo;
054 import org.apache.geronimo.gbean.GBeanInfoBuilder;
055 import org.apache.geronimo.kernel.Kernel;
056 import org.apache.geronimo.kernel.util.Main;
057 import jline.ConsoleReader;
058
059
060 /**
061 * The main class for the CLI deployer. Handles chunking the input arguments
062 * and formatting help text and maintaining the list of individual commands.
063 * Uses a ServerConnection to handle the server connection and arguments, and
064 * a list of DeployCommands to manage the details of the various available
065 * commands.
066 *
067 * Returns 0 normally, or 1 of any exceptions or error messages were generated
068 * (whether for syntax or other failure).
069 *
070 * @version $Rev: 706640 $ $Date: 2008-10-21 14:44:05 +0000 (Tue, 21 Oct 2008) $
071 */
072 public class DeployTool implements Main {
073
074 private static final IdentityHashMap<CommandMetaData, DeployCommand> commands = new IdentityHashMap<CommandMetaData, DeployCommand>();
075
076 static {
077 commands.put(LoginCommandMetaData.META_DATA, new CommandLogin());
078 commands.put(DeployCommandMetaData.META_DATA, new CommandDeploy());
079 commands.put(DistributeCommandMetaData.META_DATA, new CommandDistribute());
080 commands.put(ListModulesCommandMetaData.META_DATA, new CommandListModules());
081 commands.put(ListTargetsCommandMetaData.META_DATA, new CommandListTargets());
082 commands.put(RedeployCommandMetaData.META_DATA, new CommandRedeploy());
083 commands.put(StartCommandMetaData.META_DATA, new CommandStart());
084 commands.put(StopCommandMetaData.META_DATA, new CommandStop());
085 commands.put(RestartCommandMetaData.META_DATA, new CommandRestart());
086 commands.put(UndeployCommandMetaData.META_DATA, new CommandUndeploy());
087 commands.put(SearchPluginsCommandMetaData.META_DATA, new CommandListConfigurations());
088 commands.put(InstallPluginCommandMetaData.META_DATA, new CommandInstallCAR());
089 commands.put(InstallLibraryCommandMetaData.META_DATA, new CommandInstallLibrary());
090 }
091
092 private boolean failed = false;
093 String[] generalArgs = new String[0];
094 ServerConnection con = null;
095 private boolean multipleCommands = false;
096 private final Kernel kernel;
097 private final DeploymentFactory deploymentFactory;
098
099 public DeployTool(Kernel kernel, DeploymentFactory deploymentFactory) {
100 if (null == kernel) {
101 throw new IllegalArgumentException("kernel is required");
102 } else if (null == deploymentFactory) {
103 throw new IllegalArgumentException("deploymentFactory is required");
104 }
105 this.kernel = kernel;
106 this.deploymentFactory = deploymentFactory;
107 }
108
109 public int execute(Object opaque) {
110 if (! (opaque instanceof DeployerCLParser)) {
111 throw new IllegalArgumentException("Argument type is [" + opaque.getClass() + "]; expected [" + DeployerCLParser.class + "]");
112 }
113 DeployerCLParser parser = (DeployerCLParser) opaque;
114
115 PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out), true);
116 InputStream in = System.in;
117
118 CommandMetaData commandMetaData = parser.getCommandMetaData();
119 CommandArgs commandArgs = parser.getCommandArgs();
120 if(commandMetaData == CommandFileCommandMetaData.META_DATA) {
121 multipleCommands = true;
122 String arg = commandArgs.getArgs()[0];
123 File source = new File(arg);
124 if(!source.exists() || !source.canRead() || source.isDirectory()) {
125 processException(out, new DeploymentSyntaxException("Cannot read command file "+source.getAbsolutePath()));
126 } else {
127 try {
128 BufferedReader commands = new BufferedReader(new FileReader(source));
129 String line;
130 boolean oneFailed = false;
131 while((line = commands.readLine()) != null) {
132 line = line.trim();
133 if(!line.equals("")) {
134 String[] lineArgs = splitCommand(line);
135 if(failed) {
136 oneFailed = true;
137 }
138 failed = false;
139 execute(lineArgs);
140 }
141 }
142 failed = oneFailed;
143 } catch (IOException e) {
144 processException(out, new DeploymentException("Unable to read command file", e));
145 } finally {
146 try {
147 con.close();
148 } catch (DeploymentException e) {
149 processException(out, e);
150 }
151 }
152 }
153 } else {
154 DeployCommand dc = commands.get(commandMetaData);
155 if(dc == null) {
156 out.println();
157 processException(out, new DeploymentSyntaxException("No such command: '"+commandMetaData+"'"));
158 } else {
159 try {
160 if(con == null) {
161 con = new ServerConnection(parser, out, in, kernel, deploymentFactory);
162 }
163 try {
164 dc.execute(new ConsoleReader(in, out), con, commandArgs);
165 } catch (DeploymentSyntaxException e) {
166 processException(out, e);
167 } catch (DeploymentException e) {
168 processException(out, e);
169 } catch (IOException e) {
170 processException(out, e);
171 } finally {
172 if(!multipleCommands) {
173 try {
174 con.close();
175 } catch(DeploymentException e) {
176 processException(out, e);
177 }
178 }
179 }
180 } catch(DeploymentException e) {
181 processException(out, e);
182 }
183 }
184 }
185 out.flush();
186 System.out.flush();
187 return failed ? 1 : 0;
188 }
189
190 public static String[] splitCommand(String line) {
191 String[] chunks = line.split("\"");
192 List list = new LinkedList();
193 for (int i = 0; i < chunks.length; i++) {
194 String chunk = chunks[i];
195 if(i % 2 == 1) { // it's in quotes
196 list.add(chunk);
197 } else { // it's not in quotes
198 list.addAll(Arrays.asList(chunk.split("\\s")));
199 }
200 }
201 for (Iterator it = list.iterator(); it.hasNext();) {
202 String test = (String) it.next();
203 if(test.trim().equals("")) {
204 it.remove();
205 }
206 }
207 return (String[]) list.toArray(new String[list.size()]);
208 }
209
210 private void processException(PrintWriter out, Exception e) {
211 failed = true;
212 out.print(DeployUtils.reformat("Error: "+e.getMessage(),4,72));
213 if(e.getCause() != null) {
214 e.getCause().printStackTrace(out);
215 }
216 }
217
218 public static final GBeanInfo GBEAN_INFO;
219 public static final String GBEAN_REF_DEPLOYMENT_FACTORY = "DeploymentFactory";
220
221 static {
222 GBeanInfoBuilder infoBuilder = GBeanInfoBuilder.createStatic("DeployTool", DeployTool.class, "DeployTool");
223
224 infoBuilder.addReference(GBEAN_REF_DEPLOYMENT_FACTORY, DeploymentFactory.class);
225 infoBuilder.addInterface(Main.class);
226
227 infoBuilder.setConstructor(new String[] {"kernel", GBEAN_REF_DEPLOYMENT_FACTORY});
228
229 GBEAN_INFO = infoBuilder.getBeanInfo();
230 }
231
232 public static GBeanInfo getGBeanInfo() {
233 return GBEAN_INFO;
234 }
235
236 }