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 }