]> git.argeo.org Git - gpl/argeo-slc.git/blob - runtime/org.argeo.slc.launcher/src/main/java/org/argeo/slc/cli/SlcMain.java
Start preparing OSGi runtime
[gpl/argeo-slc.git] / runtime / org.argeo.slc.launcher / src / main / java / org / argeo / slc / cli / SlcMain.java
1 package org.argeo.slc.cli;
2
3 import java.io.FileInputStream;
4 import java.util.Properties;
5
6 import org.apache.commons.cli.CommandLine;
7 import org.apache.commons.cli.CommandLineParser;
8 import org.apache.commons.cli.GnuParser;
9 import org.apache.commons.cli.HelpFormatter;
10 import org.apache.commons.cli.Option;
11 import org.apache.commons.cli.OptionBuilder;
12 import org.apache.commons.cli.Options;
13 import org.apache.commons.cli.ParseException;
14 import org.apache.commons.io.IOUtils;
15 import org.apache.commons.logging.Log;
16 import org.apache.commons.logging.LogFactory;
17 import org.argeo.slc.SlcException;
18 import org.argeo.slc.logging.Log4jUtils;
19 import org.argeo.slc.runtime.SlcExecutionContext;
20 import org.argeo.slc.runtime.SlcRuntime;
21
22 public class SlcMain {
23 public enum Mode {
24 single, agent
25 }
26
27 private static Log log = null;
28
29 private final static String BOOTSTRAP_LOG4J_CONFIG = "org/argeo/slc/cli/bootstrapLog4j.properties";
30
31 private final static Option modeOpt = OptionBuilder.withLongOpt("mode")
32 .withArgName("mode").hasArg().withDescription(
33 "SLC execution mode, one of: " + listModeValues()).create(
34 'm');
35
36 private final static Option propertyOpt = OptionBuilder.withLongOpt(
37 "property").withArgName("prop1=val1,prop2=val2").hasArgs()
38 .withValueSeparator(',').withDescription(
39 "use value for given property").create('p');
40
41 private final static Option propertiesOpt = OptionBuilder.withLongOpt(
42 "properties").withArgName("properties file").hasArgs()
43 .withValueSeparator(',').withDescription(
44 "load properties from file (-p has priority)").create('P');
45
46 private final static Option scriptOpt = OptionBuilder.withLongOpt("script")
47 .withArgName("script").hasArg().withDescription(
48 "SLC script to execute").create('s');
49
50 private final static Option targetsOpt = OptionBuilder.withLongOpt(
51 "targets").withArgName("targets").hasArg().withDescription(
52 "Targets to execute").create('t');
53
54 private final static Option runtimeOpt = OptionBuilder.withLongOpt(
55 "runtime").withArgName("runtime").hasArg().withDescription(
56 "Runtime to use, either a full path or relative to slc app conf dir: "
57 + "<conf dir>/runtime/<runtime>/.xml").create('r');
58
59 private final static Options options;
60
61 private final static String commandName = "slc";
62
63 static {
64 options = new Options();
65 options.addOption(modeOpt);
66 options.addOption(scriptOpt);
67 options.addOption(targetsOpt);
68 options.addOption(propertyOpt);
69 options.addOption(propertiesOpt);
70 options.addOption(runtimeOpt);
71 }
72
73 public static void main(String[] args) {
74 Mode mode = null;
75 Properties properties = new Properties();
76 String script = null;
77 String targets = null;
78 String runtimeStr = null;
79
80 try {
81
82 CommandLineParser clParser = new GnuParser();
83 CommandLine cl = clParser.parse(options, args);
84
85 // Mode
86 String modeStr = cl.getOptionValue(modeOpt.getOpt());
87 if (modeStr == null) {
88 mode = Mode.single;
89 } else {
90 try {
91 mode = Mode.valueOf(modeStr);
92 } catch (IllegalArgumentException e) {
93 throw new SlcException("Unrecognized mode '" + modeStr
94 + "'", e);
95 }
96 }
97
98 // Script
99 if (mode.equals(Mode.single)) {
100 if (!cl.hasOption(scriptOpt.getOpt()))
101 throw new SlcException("Mode " + Mode.single
102 + " requires option '" + scriptOpt.getLongOpt()
103 + "'");
104 script = cl.getOptionValue(scriptOpt.getOpt());
105
106 // Targets
107 if (cl.hasOption(targetsOpt.getOpt()))
108 targets = cl.getOptionValue(targetsOpt.getOpt());
109 }
110
111 // Properties
112 if (cl.hasOption(propertiesOpt.getOpt())) {
113 for (String propertyFile : cl.getOptionValues(propertiesOpt
114 .getOpt())) {
115 loadPropertyFile(properties, propertyFile);
116 }
117 }
118 if (cl.hasOption(propertyOpt.getOpt())) {
119 for (String property : cl.getOptionValues(propertyOpt.getOpt())) {
120 addProperty(properties, property);
121 }
122 }
123
124 // Runtime
125 if (cl.hasOption(runtimeOpt.getOpt())) {
126 runtimeStr = cl.getOptionValue(runtimeOpt.getOpt());
127 }
128 } catch (ParseException e) {
129 System.err.println("Problem with command line arguments. "
130 + e.getMessage());
131 badExit();
132 } catch (SlcException e) {
133 System.err.println(e.getMessage());
134 badExit();
135 } catch (Exception e) {
136 System.err.println("Unexpected exception when bootstrapping.");
137 e.printStackTrace();
138 badExit();
139 }
140
141 // Initializes logging and log arguments
142 initLogging(properties);
143 if (log.isDebugEnabled()) {
144 log.debug("Mode: " + mode);
145 if (runtimeStr != null)
146 log.debug("Runtime: " + runtimeStr);
147 log.debug("User properties: " + properties);
148 if (script != null)
149 log.debug("Script: " + script);
150 if (targets != null)
151 log.debug("Targets: " + targets);
152 }
153
154 // Execution
155 if (mode.equals(Mode.single)) {
156 try {
157 // DefaultSlcRuntime runtime = new DefaultSlcRuntime();
158 // FIXME: inject this more cleanly
159 ClassLoader cl = Thread.currentThread().getContextClassLoader();
160 Class clss = cl.loadClass("org.argeo.slc.ant.AntSlcRuntime");
161 SlcRuntime<? extends SlcExecutionContext> runtime = (SlcRuntime<? extends SlcExecutionContext>) clss
162 .newInstance();
163 runtime.executeScript(runtimeStr, script, targets, properties,
164 null, null);
165 // System.exit(0);
166 } catch (Exception e) {
167 log.error("SLC client terminated with an error: ", e);
168 System.exit(1);
169 }
170 }
171 }
172
173 public static void printUsage() {
174 new HelpFormatter().printHelp(commandName, options, true);
175 }
176
177 private static String listModeValues() {
178 StringBuffer buf = new StringBuffer("");
179 for (Mode mode : Mode.values()) {
180 buf.append(mode).append(", ");
181 }
182 String str = buf.toString();
183 // unsafe, but there will be at least one value in the enum
184 return str.substring(0, str.length() - 2);
185 }
186
187 protected static void addProperty(Properties properties, String property) {
188 int eqIndex = property.indexOf('=');
189 if (eqIndex == 0)
190 throw new SlcException("Badly formatted property " + property);
191
192 if (eqIndex > 0) {
193 String key = property.substring(0, eqIndex);
194 String value = property.substring(eqIndex + 1);
195 properties.setProperty(key, value);
196
197 } else {
198 properties.setProperty(property, "true");
199 }
200 }
201
202 protected static void loadPropertyFile(Properties properties,
203 String propertyFile) {
204 FileInputStream in = null;
205 try {
206 in = new FileInputStream(propertyFile);
207 properties.load(in);
208 } catch (Exception e) {
209 throw new SlcException("Could not load proeprty file "
210 + propertyFile);
211 } finally {
212 IOUtils.closeQuietly(in);
213 }
214 }
215
216 private static void initLogging(Properties userProperties) {
217 System.setProperty("log4j.defaultInitOverride", "true");
218
219 // Add log4j user properties to System properties
220 for (Object obj : userProperties.keySet()) {
221 String key = obj.toString();
222 if (key.startsWith("log4j.")) {
223 System.setProperty(key, userProperties.getProperty(key));
224 }
225 }
226 Log4jUtils.initLog4j(System.getProperty("log4j.configuration",
227 "classpath:" + BOOTSTRAP_LOG4J_CONFIG));
228 log = LogFactory.getLog(SlcMain.class);
229
230 }
231
232 private static void badExit() {
233 printUsage();
234 System.exit(1);
235 }
236 }