1 package org
.argeo
.slc
.cli
;
3 import java
.io
.FileInputStream
;
4 import java
.io
.IOException
;
5 import java
.util
.Properties
;
7 import org
.apache
.commons
.cli
.CommandLine
;
8 import org
.apache
.commons
.cli
.CommandLineParser
;
9 import org
.apache
.commons
.cli
.GnuParser
;
10 import org
.apache
.commons
.cli
.HelpFormatter
;
11 import org
.apache
.commons
.cli
.Option
;
12 import org
.apache
.commons
.cli
.OptionBuilder
;
13 import org
.apache
.commons
.cli
.Options
;
14 import org
.apache
.commons
.cli
.ParseException
;
15 import org
.apache
.commons
.io
.IOUtils
;
16 import org
.apache
.commons
.logging
.Log
;
17 import org
.apache
.commons
.logging
.LogFactory
;
18 import org
.argeo
.slc
.SlcException
;
19 import org
.argeo
.slc
.logging
.Log4jUtils
;
20 import org
.argeo
.slc
.runtime
.SlcExecutionContext
;
21 import org
.argeo
.slc
.runtime
.SlcRuntime
;
22 import org
.springframework
.context
.ConfigurableApplicationContext
;
23 import org
.springframework
.context
.support
.ClassPathXmlApplicationContext
;
24 import org
.springframework
.context
.support
.FileSystemXmlApplicationContext
;
26 public class SlcMain
{
31 private static Log log
= null;
33 private final static String BOOTSTRAP_LOG4J_CONFIG
= "org/argeo/slc/cli/bootstrapLog4j.properties";
34 private final static String DEFAULT_AGENT_CONTEXT
= "classpath:org/argeo/slc/cli/spring-agent-default.xml";
36 private final static Option modeOpt
= OptionBuilder
.withLongOpt("mode")
37 .withArgName("mode").hasArg().withDescription(
38 "SLC execution mode, one of: " + listModeValues()).create(
41 private final static Option propertyOpt
= OptionBuilder
.withLongOpt(
42 "property").withArgName("prop1=val1,prop2=val2").hasArgs()
43 .withValueSeparator(',').withDescription(
44 "use value for given property").create('p');
46 private final static Option propertiesOpt
= OptionBuilder
.withLongOpt(
47 "properties").withArgName("properties file").hasArgs()
48 .withValueSeparator(',').withDescription(
49 "load properties from file (-p has priority)").create('P');
51 private final static Option scriptOpt
= OptionBuilder
.withLongOpt("script")
52 .withArgName("script").hasArg().withDescription(
53 "SLC script to execute").create('s');
55 private final static Option targetsOpt
= OptionBuilder
.withLongOpt(
56 "targets").withArgName("targets").hasArg().withDescription(
57 "Targets to execute").create('t');
59 private final static Option runtimeOpt
= OptionBuilder
.withLongOpt(
60 "runtime").withArgName("runtime").hasArg().withDescription(
61 "Runtime to use, either a full path or relative to slc app conf dir: "
62 + "<conf dir>/runtime/<runtime>/.xml").create('r');
64 private final static Options options
;
66 private final static String commandName
= "slc";
69 options
= new Options();
70 options
.addOption(modeOpt
);
71 options
.addOption(scriptOpt
);
72 options
.addOption(targetsOpt
);
73 options
.addOption(propertyOpt
);
74 options
.addOption(propertiesOpt
);
75 options
.addOption(runtimeOpt
);
78 public static void main(String
[] args
) {
80 Properties properties
= new Properties();
82 String targets
= null;
83 String runtimeStr
= null;
87 CommandLineParser clParser
= new GnuParser();
88 CommandLine cl
= clParser
.parse(options
, args
);
91 String modeStr
= cl
.getOptionValue(modeOpt
.getOpt());
92 if (modeStr
== null) {
96 mode
= Mode
.valueOf(modeStr
);
97 } catch (IllegalArgumentException e
) {
98 throw new SlcException("Unrecognized mode '" + modeStr
104 if (mode
.equals(Mode
.single
)) {
105 if (!cl
.hasOption(scriptOpt
.getOpt()))
106 throw new SlcException("Mode " + Mode
.single
107 + " requires option '" + scriptOpt
.getLongOpt()
109 script
= cl
.getOptionValue(scriptOpt
.getOpt());
112 if (cl
.hasOption(targetsOpt
.getOpt()))
113 targets
= cl
.getOptionValue(targetsOpt
.getOpt());
117 if (cl
.hasOption(propertiesOpt
.getOpt())) {
118 for (String propertyFile
: cl
.getOptionValues(propertiesOpt
120 loadPropertyFile(properties
, propertyFile
);
123 if (cl
.hasOption(propertyOpt
.getOpt())) {
124 for (String property
: cl
.getOptionValues(propertyOpt
.getOpt())) {
125 addProperty(properties
, property
);
130 if (cl
.hasOption(runtimeOpt
.getOpt())) {
131 runtimeStr
= cl
.getOptionValue(runtimeOpt
.getOpt());
133 } catch (ParseException e
) {
134 System
.err
.println("Problem with command line arguments. "
137 } catch (SlcException e
) {
138 System
.err
.println(e
.getMessage());
140 } catch (Exception e
) {
141 System
.err
.println("Unexpected exception when bootstrapping.");
146 // Initializes logging and log arguments
147 initLogging(properties
);
148 if (log
.isDebugEnabled()) {
149 log
.debug("Mode: " + mode
);
150 if (runtimeStr
!= null)
151 log
.debug("Runtime: " + runtimeStr
);
152 log
.debug("User properties: " + properties
);
154 log
.debug("Script: " + script
);
156 log
.debug("Targets: " + targets
);
160 if (mode
.equals(Mode
.single
)) {
162 // DefaultSlcRuntime runtime = new DefaultSlcRuntime();
163 // FIXME: inject this more cleanly
164 ClassLoader cl
= Thread
.currentThread().getContextClassLoader();
165 Class clss
= cl
.loadClass("org.argeo.slc.ant.AntSlcRuntime");
166 SlcRuntime
<?
extends SlcExecutionContext
> runtime
= (SlcRuntime
<?
extends SlcExecutionContext
>) clss
168 runtime
.executeScript(runtimeStr
, script
, targets
, properties
,
171 } catch (Exception e
) {
172 log
.error("SLC client terminated with an error: ", e
);
177 else if (mode
.equals(Mode
.agent
)) {
178 final ConfigurableApplicationContext applicationContext
;
179 if (runtimeStr
== null) {
180 applicationContext
= new ClassPathXmlApplicationContext(
181 DEFAULT_AGENT_CONTEXT
);
183 applicationContext
= new FileSystemXmlApplicationContext(
186 applicationContext
.registerShutdownHook();
187 applicationContext
.start();
188 log
.info("SLC Agent context started.");
192 public static void printUsage() {
193 new HelpFormatter().printHelp(commandName
, options
, true);
196 private static String
listModeValues() {
197 StringBuffer buf
= new StringBuffer("");
198 for (Mode mode
: Mode
.values()) {
199 buf
.append(mode
).append(", ");
201 String str
= buf
.toString();
202 // unsafe, but there will be at least one value in the enum
203 return str
.substring(0, str
.length() - 2);
206 protected static void addProperty(Properties properties
, String property
) {
207 int eqIndex
= property
.indexOf('=');
209 throw new SlcException("Badly formatted property " + property
);
212 String key
= property
.substring(0, eqIndex
);
213 String value
= property
.substring(eqIndex
+ 1);
214 properties
.setProperty(key
, value
);
217 properties
.setProperty(property
, "true");
221 protected static void loadPropertyFile(Properties properties
,
222 String propertyFile
) {
223 FileInputStream in
= null;
225 in
= new FileInputStream(propertyFile
);
227 } catch (Exception e
) {
228 throw new SlcException("Could not load proeprty file "
231 IOUtils
.closeQuietly(in
);
235 private static void initLogging(Properties userProperties
) {
236 System
.setProperty("log4j.defaultInitOverride", "true");
238 // Add log4j user properties to System properties
239 for (Object obj
: userProperties
.keySet()) {
240 String key
= obj
.toString();
241 if (key
.startsWith("log4j.")) {
242 System
.setProperty(key
, userProperties
.getProperty(key
));
245 Log4jUtils
.initLog4j(System
.getProperty("log4j.configuration",
246 "classpath:" + BOOTSTRAP_LOG4J_CONFIG
));
247 log
= LogFactory
.getLog(SlcMain
.class);
251 private static void badExit() {