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