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