1 package org
.argeo
.slc
.detached
.launcher
;
4 import java
.io
.FileInputStream
;
5 import java
.io
.InputStream
;
6 import java
.lang
.reflect
.Method
;
7 import java
.util
.ArrayList
;
8 import java
.util
.Hashtable
;
9 import java
.util
.Iterator
;
10 import java
.util
.List
;
12 import java
.util
.Properties
;
13 import java
.util
.StringTokenizer
;
14 import java
.util
.Vector
;
16 import org
.eclipse
.core
.runtime
.adaptor
.EclipseStarter
;
17 import org
.osgi
.framework
.Bundle
;
18 import org
.osgi
.framework
.BundleContext
;
19 import org
.osgi
.framework
.BundleException
;
22 public final static String PROP_SLC_HOME
= "slc.home";
23 public final static String PROP_SLC_OSGI_START
= "slc.osgi.start";
24 public final static String PROP_SLC_OSGI_SCAN_CLASSPATH
= "slc.osgi.scanClasspath";
25 public final static String PROP_SLC_OSGI_EQUINOX_ARGS
= "slc.osgi.equinox.args";
27 private final static String DEV_BUNDLE_PREFIX
= "slc.osgi.devbundle.";
29 public static void main(String
[] args
) {
30 info("Argeo SLC Detached launcher starting...");
33 String propertyPath
= "slc-detached.properties";
34 Properties config
= prepareConfig(propertyPath
);
36 // Start app (in main class loader)
39 // Start OSGi framework
42 } catch (Exception e
) {
43 // TODO Auto-generated catch block
46 info("Argeo SLC Detached launcher started.");
47 } catch (Exception e
) {
53 protected static Properties
prepareConfig(String propertyFilePath
)
56 String slcHome
= System
.getProperty(PROP_SLC_HOME
);
57 if (slcHome
!= null) {
58 slcHome
= new File(slcHome
).getCanonicalPath();
59 System
.setProperty(PROP_SLC_HOME
, slcHome
);
63 Properties config
= new Properties();
64 InputStream in
= null;
66 File file
= new File(propertyFilePath
);
68 in
= new FileInputStream(propertyFilePath
);
76 // System properties have priority.
77 config
.putAll(System
.getProperties());
81 public static void startEquinox(Properties config
) throws Exception
{
82 info("java.class.path=" + System
.getProperty("java.class.path"));
84 File baseDir
= new File(System
.getProperty("user.dir"))
86 String equinoxConfigurationPath
= baseDir
.getPath() + File
.separator
87 + "slc-detached" + File
.separator
+ "equinoxConfiguration";
89 String equinoxArgsLineDefault
= "-console -noExit -clean -debug -configuration "
90 + equinoxConfigurationPath
;
91 String equinoxArgsLine
= config
.getProperty(PROP_SLC_OSGI_EQUINOX_ARGS
,
92 equinoxArgsLineDefault
);
93 // String[] equinoxArgs = { "-console", "-noExit", "-clean", "-debug",
94 // "-configuration", equinoxConfigurationPath };
95 String
[] equinoxArgs
= equinoxArgsLine
.split(" ");
97 BundleContext context
= EclipseStarter
.startup(equinoxArgs
, null);
99 List installBundleNames
= new ArrayList();
101 // Load from class path (dev environment, maven)
102 if (config
.getProperty(PROP_SLC_OSGI_SCAN_CLASSPATH
, "false").equals(
104 StringTokenizer st
= new StringTokenizer(System
105 .getProperty("java.class.path"), File
.pathSeparator
);
106 while (st
.hasMoreTokens()) {
108 String path
= st
.nextToken();
109 String url
= "reference:file:"
110 + new File(path
).getCanonicalPath();
111 Bundle bundle
= context
.installBundle(url
);
112 installBundleNames
.add(bundle
.getSymbolicName());
113 info("Installed from classpath " + url
);
114 } catch (Exception e
) {
115 bundleInstallWarn(e
.getMessage());
120 // Load from dev bundles
121 Map devBundleUrls
= getDevBundleUrls(config
);
122 Iterator devBundles
= devBundleUrls
.keySet().iterator();
123 while (devBundles
.hasNext()) {
125 String bundleName
= (String
) devBundles
.next();
126 String url
= (String
) devBundleUrls
.get(bundleName
);
127 Bundle bundle
= context
.installBundle(url
);
128 installBundleNames
.add(bundle
.getSymbolicName());
129 info("Installed as dev bundle " + url
);
130 } catch (Exception e
) {
131 bundleInstallWarn(e
.getMessage());
135 // Load from distribution
136 String slcHome
= config
.getProperty(PROP_SLC_HOME
);
137 if (slcHome
!= null) {
138 File libDir
= new File(slcHome
+ File
.separator
+ "lib");
139 File
[] bundleFiles
= libDir
.listFiles();
140 for (int i
= 0; i
< bundleFiles
.length
; i
++) {
142 String url
= "reference:file:"
143 + bundleFiles
[i
].getCanonicalPath();
144 Bundle bundle
= context
.installBundle(url
);
145 installBundleNames
.add(bundle
.getSymbolicName());
146 info("INFO: Installed from SLC home " + url
);
147 } catch (Exception e
) {
148 bundleInstallWarn(e
.getMessage());
155 String bundleStart
= config
.getProperty(PROP_SLC_OSGI_START
,
156 "org.springframework.osgi.extender,org.argeo.slc.detached");
158 if (bundleStart
.trim().equals("*")) {
159 for (int i
= 0; i
< installBundleNames
.size(); i
++) {
160 String bundleSymbolicName
= installBundleNames
.get(i
)
163 startBundle(context
, bundleSymbolicName
);
164 } catch (Exception e
) {
165 bundleInstallWarn(e
.getMessage());
169 StringTokenizer stBundleStart
= new StringTokenizer(bundleStart
,
171 while (stBundleStart
.hasMoreTokens()) {
172 String bundleSymbolicName
= stBundleStart
.nextToken();
173 startBundle(context
, bundleSymbolicName
);
178 private static Map
getDevBundleUrls(Properties config
) {
179 Map bundles
= new Hashtable();
180 Iterator keys
= config
.keySet().iterator();
181 while (keys
.hasNext()) {
182 String key
= (String
) keys
.next();
183 if (key
.startsWith(DEV_BUNDLE_PREFIX
)) {
184 String bundle
= key
.substring(DEV_BUNDLE_PREFIX
.length());
185 String path
= config
.getProperty(key
);
186 bundles
.put(bundle
, path
);
192 private static void startBundle(BundleContext bundleContext
,
193 String symbolicName
) throws BundleException
{
194 info("Starting bundle " + symbolicName
+ "...");
195 Bundle bundle
= findBundleBySymbolicName(bundleContext
, symbolicName
);
199 throw new RuntimeException("Bundle " + symbolicName
+ " not found");
200 info("Started " + symbolicName
);
203 /** WARNING: return the first one found! */
204 private static Bundle
findBundleBySymbolicName(BundleContext bundleContext
,
205 String symbolicName
) {
206 Bundle
[] bundles
= bundleContext
.getBundles();
207 for (int i
= 0; i
< bundles
.length
; i
++) {
208 Bundle bundle
= bundles
[i
];
209 String bundleSymbolicName
= bundle
.getSymbolicName();
210 if (bundleSymbolicName
== null)
211 throw new RuntimeException("Bundle " + bundle
.getBundleId()
212 + " (" + bundle
.getLocation()
213 + ") has no symbolic name.");
215 if (bundleSymbolicName
.equals(symbolicName
)) {
222 public static void startApp(Properties config
) throws Exception
{
223 String className
= config
.getProperty("slc.detached.appclass");
224 String
[] uiArgs
= readArgumentsFromLine(config
.getProperty(
225 "slc.detached.appargs", ""));
227 if (className
== null) {
228 info("No slc.detached.appclass property define: does not try to launch an app from the standard classpath.");
230 // Launch main method using reflection
231 Class clss
= Class
.forName(className
);
232 Class
[] mainArgsClasses
= new Class
[] { uiArgs
.getClass() };
233 Object
[] mainArgs
= { uiArgs
};
234 Method mainMethod
= clss
.getMethod("main", mainArgsClasses
);
235 mainMethod
.invoke(null, mainArgs
);
242 * Transform a line into an array of arguments, taking "" as single
243 * arguments. (nested \" are not supported)
245 private static String
[] readArgumentsFromLine(String lineOrig
) {
247 String line
= lineOrig
.trim();// remove trailing spaces
248 // System.out.println("line=" + line);
249 List args
= new Vector();
250 StringBuffer curr
= new StringBuffer("");
251 boolean inQuote
= false;
252 char[] arr
= line
.toCharArray();
253 for (int i
= 0; i
< arr
.length
; i
++) {
260 if (!inQuote
) {// otherwise, no break: goes to default
261 if (curr
.length() > 0) {
262 args
.add(curr
.toString());
263 curr
= new StringBuffer("");
274 if (curr
.length() > 0) {
275 args
.add(curr
.toString());
279 String
[] res
= new String
[args
.size()];
280 for (int i
= 0; i
< args
.size(); i
++) {
281 res
[i
] = args
.get(i
).toString();
282 // System.out.println("res[i]=" + res[i]);
287 private static void info(Object obj
) {
288 //System.out.println("[INFO] " + obj);
291 private static void bundleInstallWarn(Object obj
) {
292 System
.err
.println("[WARN] " + obj
);