]> git.argeo.org Git - gpl/argeo-slc.git/blob - runtime/org.argeo.slc.launcher/src/main/java/org/argeo/slc/cli/OsgiLauncher.java
Start preparing OSGi runtime
[gpl/argeo-slc.git] / runtime / org.argeo.slc.launcher / src / main / java / org / argeo / slc / cli / OsgiLauncher.java
1 package org.argeo.slc.cli;
2
3 import java.io.File;
4 import java.io.FileInputStream;
5 import java.io.InputStream;
6 import java.lang.reflect.Method;
7 import java.util.Hashtable;
8 import java.util.Iterator;
9 import java.util.List;
10 import java.util.Map;
11 import java.util.Properties;
12 import java.util.StringTokenizer;
13 import java.util.Vector;
14
15 import org.eclipse.core.runtime.adaptor.EclipseStarter;
16 import org.osgi.framework.Bundle;
17 import org.osgi.framework.BundleContext;
18 import org.osgi.framework.BundleException;
19
20 public class OsgiLauncher {
21 public final static String PROP_SLC_HOME = "slc.home";
22 public final static String PROP_SLC_OSGI_START = "slc.osgi.start";
23 public final static String PROP_SLC_OSGI_SCAN_CLASSPATH = "slc.osgi.scanClasspath";
24 public final static String PROP_SLC_OSGI_EQUINOX_ARGS = "slc.osgi.equinox.args";
25
26 private final static String DEV_BUNDLE_PREFIX = "slc.osgi.devbundle.";
27
28 public static void main(String[] args) {
29 info("Argeo SLC Detached launcher starting...");
30 try {
31 // Load properties
32 String propertyPath = "slc-detached.properties";
33 Properties config = prepareConfig(propertyPath);
34
35 // Start app (in main class loader)
36 startApp(config);
37
38 // Start OSGi framework
39 try {
40 startEquinox(config);
41 } catch (Exception e) {
42 // TODO Auto-generated catch block
43 e.printStackTrace();
44 }
45 info("Argeo SLC Detached launcher started.");
46 } catch (Exception e) {
47 e.printStackTrace();
48 System.exit(-1);
49 }
50 }
51
52 protected static Properties prepareConfig(String propertyFilePath)
53 throws Exception {
54 // Format slc.home
55 String slcHome = System.getProperty(PROP_SLC_HOME);
56 if (slcHome != null) {
57 slcHome = new File(slcHome).getCanonicalPath();
58 System.setProperty(PROP_SLC_HOME, slcHome);
59 }
60
61 // Load config
62 Properties config = new Properties();
63 InputStream in = null;
64 try {
65 File file = new File(propertyFilePath);
66 if (file.exists()) {
67 in = new FileInputStream(propertyFilePath);
68 config.load(in);
69 }
70 } finally {
71 if (in != null)
72 in.close();
73 }
74
75 // System properties have priority.
76 config.putAll(System.getProperties());
77 return config;
78 }
79
80 public static void startEquinox(Properties config) throws Exception {
81 info("java.class.path=" + System.getProperty("java.class.path"));
82
83 File baseDir = new File(System.getProperty("user.dir"))
84 .getCanonicalFile();
85 String equinoxConfigurationPath = baseDir.getPath() + File.separator
86 + "slc-detached" + File.separator + "equinoxConfiguration";
87
88 String equinoxArgsLineDefault = "-console -noExit -clean -debug -configuration "
89 + equinoxConfigurationPath;
90 String equinoxArgsLine = System.getProperty(PROP_SLC_OSGI_EQUINOX_ARGS,
91 equinoxArgsLineDefault);
92 // String[] equinoxArgs = { "-console", "-noExit", "-clean", "-debug",
93 // "-configuration", equinoxConfigurationPath };
94 String[] equinoxArgs = equinoxArgsLine.split(" ");
95
96 BundleContext context = EclipseStarter.startup(equinoxArgs, null);
97
98 // Load from class path (dev environment, maven)
99 if (config.getProperty(PROP_SLC_OSGI_SCAN_CLASSPATH, "false").equals(
100 "true")) {
101 StringTokenizer st = new StringTokenizer(System
102 .getProperty("java.class.path"), File.pathSeparator);
103 while (st.hasMoreTokens()) {
104 try {
105 String path = st.nextToken();
106 String url = "reference:file:"
107 + new File(path).getCanonicalPath();
108 context.installBundle(url);
109 info("Installed from classpath " + url);
110 } catch (Exception e) {
111 bundleInstallWarn(e.getMessage());
112 }
113 }
114 }
115
116 // Load from dev bundles
117 Map devBundleUrls = getDevBundleUrls(config);
118 Iterator devBundles = devBundleUrls.keySet().iterator();
119 while (devBundles.hasNext()) {
120 try {
121 String bundleName = (String) devBundles.next();
122 String url = (String) devBundleUrls.get(bundleName);
123 context.installBundle(url);
124 info("Installed as dev bundle " + url);
125 } catch (Exception e) {
126 bundleInstallWarn(e.getMessage());
127 }
128 }
129
130 // Load from distribution
131 String slcHome = config.getProperty(PROP_SLC_HOME);
132 if (slcHome != null) {
133 File libDir = new File(slcHome + File.separator + "lib");
134 File[] bundleFiles = libDir.listFiles();
135 for (int i = 0; i < bundleFiles.length; i++) {
136 try {
137 String url = "reference:file:"
138 + bundleFiles[i].getCanonicalPath();
139 context.installBundle(url);
140 info("INFO: Installed from SLC home " + url);
141 } catch (Exception e) {
142 bundleInstallWarn(e.getMessage());
143 }
144
145 }
146 }
147
148 // Start bundles
149 String bundleStart = config.getProperty(PROP_SLC_OSGI_START,
150 "org.springframework.osgi.extender,org.argeo.slc.detached");
151 StringTokenizer stBundleStart = new StringTokenizer(bundleStart, ",");
152 while (stBundleStart.hasMoreTokens()) {
153 String bundleSymbolicName = stBundleStart.nextToken();
154 startBundle(context, bundleSymbolicName);
155 }
156 }
157
158 private static Map getDevBundleUrls(Properties config) {
159 Map bundles = new Hashtable();
160 Iterator keys = config.keySet().iterator();
161 while (keys.hasNext()) {
162 String key = (String) keys.next();
163 if (key.startsWith(DEV_BUNDLE_PREFIX)) {
164 String bundle = key.substring(DEV_BUNDLE_PREFIX.length());
165 String path = config.getProperty(key);
166 bundles.put(bundle, path);
167 }
168 }
169 return bundles;
170 }
171
172 private static void startBundle(BundleContext bundleContext,
173 String symbolicName) throws BundleException {
174 info("Starting bundle " + symbolicName + "...");
175 Bundle bundle = findBundleBySymbolicName(bundleContext, symbolicName);
176 if (bundle != null)
177 bundle.start();
178 else
179 throw new RuntimeException("Bundle " + symbolicName + " not found");
180 info("Started " + symbolicName);
181 }
182
183 /** WARNING: return the first one found! */
184 private static Bundle findBundleBySymbolicName(BundleContext bundleContext,
185 String symbolicName) {
186 Bundle[] bundles = bundleContext.getBundles();
187 for (int i = 0; i < bundles.length; i++) {
188 Bundle bundle = bundles[i];
189 String bundleSymbolicName = bundle.getSymbolicName();
190 if (bundleSymbolicName == null)
191 throw new RuntimeException("Bundle " + bundle.getBundleId()
192 + " (" + bundle.getLocation()
193 + ") has no symbolic name.");
194
195 if (bundleSymbolicName.equals(symbolicName)) {
196 return bundle;
197 }
198 }
199 return null;
200 }
201
202 public static void startApp(Properties config) throws Exception {
203 String className = config.getProperty("slc.detached.appclass");
204 String[] uiArgs = readArgumentsFromLine(config.getProperty(
205 "slc.detached.appargs", ""));
206
207 if (className == null) {
208 info("No slc.detached.appclass property define: does not try to launch an app from the standard classpath.");
209 } else {
210 // Launch main method using reflection
211 Class clss = Class.forName(className);
212 Class[] mainArgsClasses = new Class[] { uiArgs.getClass() };
213 Object[] mainArgs = { uiArgs };
214 Method mainMethod = clss.getMethod("main", mainArgsClasses);
215 mainMethod.invoke(null, mainArgs);
216 }
217 }
218
219 /* UTILITIES */
220
221 /**
222 * Transform a line into an array of arguments, taking "" as single
223 * arguments. (nested \" are not supported)
224 */
225 private static String[] readArgumentsFromLine(String lineOrig) {
226
227 String line = lineOrig.trim();// remove trailing spaces
228 // System.out.println("line=" + line);
229 List args = new Vector();
230 StringBuffer curr = new StringBuffer("");
231 boolean inQuote = false;
232 char[] arr = line.toCharArray();
233 for (int i = 0; i < arr.length; i++) {
234 char c = arr[i];
235 switch (c) {
236 case '\"':
237 inQuote = !inQuote;
238 break;
239 case ' ':
240 if (!inQuote) {// otherwise, no break: goes to default
241 if (curr.length() > 0) {
242 args.add(curr.toString());
243 curr = new StringBuffer("");
244 }
245 break;
246 }
247 default:
248 curr.append(c);
249 break;
250 }
251 }
252
253 // Add last arg
254 if (curr.length() > 0) {
255 args.add(curr.toString());
256 curr = null;
257 }
258
259 String[] res = new String[args.size()];
260 for (int i = 0; i < args.size(); i++) {
261 res[i] = args.get(i).toString();
262 // System.out.println("res[i]=" + res[i]);
263 }
264 return res;
265 }
266
267 private static void info(Object obj) {
268 System.out.println("[INFO] " + obj);
269 }
270
271 private static void bundleInstallWarn(Object obj) {
272 System.err.println("[WARN] " + obj);
273 }
274 }