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 }