package org.argeo.slc.osgiboot;
+import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
+import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.StringTokenizer;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
import org.osgi.framework.BundleException;
+import org.osgi.framework.Constants;
public class OsgiBoot {
public final static String PROP_SLC_OSGI_START = "slc.osgi.start";
public final static String PROP_SLC_OSGI_BUNDLES = "slc.osgi.bundles";
public final static String PROP_SLC_OSGI_LOCATIONS = "slc.osgi.locations";
public final static String PROP_SLC_OSGI_BASE_URL = "slc.osgi.baseUrl";
+ public final static String PROP_SLC_OSGI_MODULES_URL = "slc.osgi.modulesUrl";
public final static String PROP_SLC_OSGIBOOT_DEBUG = "slc.osgiboot.debug";
public final static String DEFAULT_BASE_URL = "reference:file:";
public final static String EXCLUDES_SVN_PATTERN = "**/.svn/**";
- private Boolean debug = Boolean.parseBoolean(System.getProperty(
- PROP_SLC_OSGIBOOT_DEBUG, "false"));
+ private boolean debug = Boolean.valueOf(
+ System.getProperty(PROP_SLC_OSGIBOOT_DEBUG, "false"))
+ .booleanValue();
private boolean excludeSvn = true;
+ private String modulesUrlSeparator = ";";
private final BundleContext bundleContext;
this.bundleContext = bundleContext;
}
- public void installUrls(List<String> urls) {
- Map<String, Bundle> installedBundles = getInstalledBundles();
- for (String url : urls) {
+ public void installUrls(List urls) {
+ Map installedBundles = getInstalledBundles();
+ for (int i = 0; i < urls.size(); i++) {
+ String url = (String) urls.get(i);
try {
if (installedBundles.containsKey(url)) {
- Bundle bundle = installedBundles.get(url);
+ Bundle bundle = (Bundle) installedBundles.get(url);
// bundle.update();
if (debug)
debug("Bundle " + bundle.getSymbolicName()
}
+ public void installOrUpdateUrls(Map urls) {
+ Map installedBundles = getBundles();
+
+ for (Iterator modules = urls.keySet().iterator(); modules.hasNext();) {
+ String moduleName = (String) modules.next();
+ String urlStr = (String) urls.get(moduleName);
+ if (installedBundles.containsKey(moduleName)) {
+ Bundle bundle = (Bundle) installedBundles.get(moduleName);
+ InputStream in;
+ try {
+ URL url = new URL(urlStr);
+ in = url.openStream();
+ bundle.update(in);
+ info("Updated bundle " + moduleName + " from " + urlStr);
+ } catch (Exception e) {
+ throw new RuntimeException("Cannot update " + moduleName
+ + " from " + urlStr);
+ }
+ if (in != null)
+ try {
+ in.close();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ } else {
+ try {
+ Bundle bundle = bundleContext.installBundle(urlStr);
+ if (debug)
+ debug("Installed bundle " + bundle.getSymbolicName()
+ + " from " + urlStr);
+ } catch (BundleException e) {
+ warn("Could not install bundle from " + urlStr + ": "
+ + e.getMessage());
+ }
+ }
+ }
+
+ }
+
public void startBundles() throws Exception {
String bundlesToStart = getProperty(PROP_SLC_OSGI_START);
startBundles(bundlesToStart);
}
- public void startBundles(String bundlesToStart) throws Exception {
- if (bundlesToStart == null)
+ public void startBundles(String bundlesToStartStr) throws Exception {
+ if (bundlesToStartStr == null)
return;
- StringTokenizer st = new StringTokenizer(bundlesToStart, ",");
- Map<String, Bundle> bundles = getBundles();
+ StringTokenizer st = new StringTokenizer(bundlesToStartStr, ",");
+ List bundlesToStart = new ArrayList();
while (st.hasMoreTokens()) {
String name = st.nextToken().trim();
- Bundle bundle = bundles.get(name);
- if (bundle != null)
+ bundlesToStart.add(name);
+ }
+ startBundles(bundlesToStart);
+ }
+
+ public void startBundles(List bundlesToStart) throws Exception {
+ if (bundlesToStart.size() == 0)
+ return;
+
+ List notStartedBundles = new ArrayList(bundlesToStart);
+ Bundle[] bundles = bundleContext.getBundles();
+ for (int i = 0; i < bundles.length; i++) {
+ Bundle bundle = bundles[i];
+ String symbolicName = bundle.getSymbolicName();
+ if (bundlesToStart.contains(symbolicName))
try {
bundle.start();
+ notStartedBundles.remove(symbolicName);
} catch (Exception e) {
- warn("Bundle " + name + " cannot be started: "
+ warn("Bundle " + symbolicName + " cannot be started: "
+ e.getMessage());
}
- else
- warn("Bundle " + name + " not installed.");
-
}
+
+ for (int i = 0; i < notStartedBundles.size(); i++)
+ warn("Bundle " + notStartedBundles.get(i)
+ + " not started because it was not found.");
}
/** Key is location */
- public Map<String, Bundle> getInstalledBundles() {
- Map<String, Bundle> installedBundles = new HashMap<String, Bundle>();
+ public Map getInstalledBundles() {
+ Map installedBundles = new HashMap();
- for (Bundle bundle : bundleContext.getBundles()) {
- installedBundles.put(bundle.getLocation(), bundle);
+ Bundle[] bundles = bundleContext.getBundles();
+ for (int i = 0; i < bundles.length; i++) {
+ installedBundles.put(bundles[i].getLocation(), bundles[i]);
}
return installedBundles;
}
/** Key is symbolic name */
- public Map<String, Bundle> getBundles() {
- Map<String, Bundle> installedBundles = new HashMap<String, Bundle>();
- for (Bundle bundle : bundleContext.getBundles())
- installedBundles.put(bundle.getSymbolicName(), bundle);
- return installedBundles;
+ public Map getBundles() {
+ Map namedBundles = new HashMap();
+ Bundle[] bundles = bundleContext.getBundles();
+ for (int i = 0; i < bundles.length; i++) {
+ namedBundles.put(bundles[i].getSymbolicName(), bundles[i]);
+ }
+ return namedBundles;
}
- public List<String> getLocationsUrls() {
+ public List getLocationsUrls() {
String baseUrl = getProperty(PROP_SLC_OSGI_BASE_URL, DEFAULT_BASE_URL);
String bundleLocations = getProperty(PROP_SLC_OSGI_LOCATIONS);
return getLocationsUrls(baseUrl, bundleLocations);
}
- public List<String> getLocationsUrls(String baseUrl, String bundleLocations) {
- List<String> urls = new ArrayList<String>();
+ public List getModulesUrls() {
+ List urls = new ArrayList();
+ String modulesUrlStr = getProperty(PROP_SLC_OSGI_MODULES_URL);
+ if (modulesUrlStr == null)
+ return urls;
+
+ Map installedBundles = getBundles();
+
+ BufferedReader reader = null;
+ try {
+ URL modulesUrl = new URL(modulesUrlStr);
+ reader = new BufferedReader(new InputStreamReader(modulesUrl
+ .openStream()));
+ String line = null;
+ while ((line = reader.readLine()) != null) {
+ StringTokenizer st = new StringTokenizer(line,
+ modulesUrlSeparator);
+ String moduleName = st.nextToken();
+ String moduleVersion = st.nextToken();
+ String url = st.nextToken();
+
+ if (installedBundles.containsKey(moduleName)) {
+ Bundle bundle = (Bundle) installedBundles.get(moduleName);
+ String bundleVersion = bundle.getHeaders().get(
+ Constants.BUNDLE_VERSION).toString();
+ int comp = compareVersions(bundleVersion, moduleVersion);
+ if (comp > 0) {
+ warn("Installed version " + bundleVersion
+ + " of bundle " + moduleName
+ + " is newer than provided version "
+ + moduleVersion);
+ } else if (comp < 0) {
+ urls.add(url);
+ info("Updated bundle " + moduleName + " with version "
+ + moduleVersion + " (old version was "
+ + bundleVersion + ")");
+ } else {
+ // do nothing
+ }
+ } else {
+ urls.add(url);
+ }
+ }
+ } catch (Exception e1) {
+ throw new RuntimeException("Cannot read url " + modulesUrlStr, e1);
+ } finally {
+ if (reader != null)
+ try {
+ reader.close();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+ return urls;
+ }
+
+ /**
+ * @return ==0: versions are identical, <0: tested version is newer, >0:
+ * currentVersion is newer.
+ */
+ protected int compareVersions(String currentVersion, String testedVersion) {
+ List cToks = new ArrayList();
+ StringTokenizer cSt = new StringTokenizer(currentVersion, ".");
+ while (cSt.hasMoreTokens())
+ cToks.add(cSt.nextToken());
+ List tToks = new ArrayList();
+ StringTokenizer tSt = new StringTokenizer(currentVersion, ".");
+ while (tSt.hasMoreTokens())
+ tToks.add(tSt.nextToken());
+
+ int comp = 0;
+ comp: for (int i = 0; i < cToks.size(); i++) {
+ if (tToks.size() <= i) {
+ // equals until then, tested shorter
+ comp = 1;
+ break comp;
+ }
+
+ String c = (String) cToks.get(i);
+ String t = (String) tToks.get(i);
+
+ try {
+ int cInt = Integer.parseInt(c);
+ int tInt = Integer.parseInt(t);
+ if (cInt == tInt)
+ continue comp;
+ else {
+ comp = (cInt - tInt);
+ break comp;
+ }
+ } catch (NumberFormatException e) {
+ if (c.equals(t))
+ continue comp;
+ else {
+ comp = c.compareTo(t);
+ break comp;
+ }
+ }
+ }
+
+ if (comp == 0 && tToks.size() > cToks.size()) {
+ // equals until then, current shorter
+ comp = -1;
+ }
+
+ return comp;
+ }
+
+ public List getLocationsUrls(String baseUrl, String bundleLocations) {
+ List urls = new ArrayList();
if (bundleLocations == null)
return urls;
return urls;
}
- public List<String> getBundlesUrls() {
+ public List getBundlesUrls() {
String baseUrl = getProperty(PROP_SLC_OSGI_BASE_URL, DEFAULT_BASE_URL);
String bundlePatterns = getProperty(PROP_SLC_OSGI_BUNDLES);
return getBundlesUrls(baseUrl, bundlePatterns);
}
- public List<String> getBundlesUrls(String baseUrl, String bundlePatterns) {
- List<String> urls = new ArrayList<String>();
+ public List getBundlesUrls(String baseUrl, String bundlePatterns) {
+ List urls = new ArrayList();
- List<BundlesSet> bundlesSets = new ArrayList<BundlesSet>();
+ List bundlesSets = new ArrayList();
if (bundlePatterns == null)
return urls;
bundlePatterns = SystemPropertyUtils
bundlesSets.add(new BundlesSet(st.nextToken()));
}
- List<String> included = new ArrayList<String>();
+ List included = new ArrayList();
PathMatcher matcher = new AntPathMatcher();
- for (BundlesSet bundlesSet : bundlesSets)
- for (String pattern : bundlesSet.getIncludes())
+ for (int i = 0; i < bundlesSets.size(); i++) {
+ BundlesSet bundlesSet = (BundlesSet) bundlesSets.get(i);
+ for (int j = 0; j < bundlesSet.getIncludes().size(); j++) {
+ String pattern = (String) bundlesSet.getIncludes().get(j);
match(matcher, included, bundlesSet.getDir(), null, pattern);
+ }
+ }
- List<String> excluded = new ArrayList<String>();
- for (BundlesSet bundlesSet : bundlesSets)
- for (String pattern : bundlesSet.getExcludes())
+ List excluded = new ArrayList();
+ for (int i = 0; i < bundlesSets.size(); i++) {
+ BundlesSet bundlesSet = (BundlesSet) bundlesSets.get(i);
+ for (int j = 0; j < bundlesSet.getExcludes().size(); j++) {
+ String pattern = (String) bundlesSet.getExcludes().get(j);
match(matcher, excluded, bundlesSet.getDir(), null, pattern);
+ }
+ }
- for (String fullPath : included) {
+ for (int i = 0; i < included.size(); i++) {
+ String fullPath = (String) included.get(i);
if (!excluded.contains(fullPath))
urls.add(baseUrl + fullPath);
}
return urls;
}
- protected void match(PathMatcher matcher, List<String> matched,
- String base, String currentPath, String pattern) {
+ protected void match(PathMatcher matcher, List matched, String base,
+ String currentPath, String pattern) {
if (currentPath == null) {
// Init
File baseDir = new File(base.replace('/', File.separatorChar));
return;
}
- for (File file : files)
- match(matcher, matched, base, file.getName(), pattern);
+ for (int i = 0; i < files.length; i++)
+ match(matcher, matched, base, files[i].getName(), pattern);
} else {
String fullPath = base + '/' + currentPath;
if (matched.contains(fullPath))
matched.add(fullPath);
return;
} else {
- String newFullPath = (base + '/' + currentPath).replace('/',
- File.separatorChar);
- File[] files = new File(newFullPath).listFiles();
+ String newFullPath = relativeToFullPath(base, currentPath);
+ File newFile = new File(newFullPath);
+ File[] files = newFile.listFiles();
if (files != null) {
- for (File file : files)
- if (file.isDirectory()) {
- String newCurrentPath = currentPath + '/'
- + file.getName();
+ for (int i = 0; i < files.length; i++) {
+ String newCurrentPath = currentPath + '/'
+ + files[i].getName();
+ if (files[i].isDirectory()) {
if (matcher.matchStart(pattern, newCurrentPath)) {
// recurse only if start matches
match(matcher, matched, base, newCurrentPath,
+ pattern);
}
+ } else {
+ boolean nonDirectoryOk = matcher.match(pattern,
+ newCurrentPath);
+ if (debug)
+ debug(currentPath + " " + (ok ? "" : " not ")
+ + " matched with " + pattern);
+ if (nonDirectoryOk)
+ matched.add(relativeToFullPath(base,
+ newCurrentPath));
}
- } else {
- warn("Not a directory: " + newFullPath);
+ }
}
}
}
}
- protected void info(Object obj) {
- System.out.println("# INFO " + obj);
+ /** Transforms a relative path in a full system path. */
+ protected String relativeToFullPath(String basePath, String relativePath) {
+ return (basePath + '/' + relativePath).replace('/', File.separatorChar);
+ }
+
+ protected static void info(Object obj) {
+ System.out.println("#OSGiBOOT# " + obj);
}
protected void debug(Object obj) {
if (debug)
- System.out.println("# DBUG " + obj);
+ System.out.println("#OSGiBOOT DEBUG# " + obj);
}
protected void warn(Object obj) {
return getProperty(name, null);
}
- public Boolean getDebug() {
+ public boolean getDebug() {
return debug;
}
- public void setDebug(Boolean debug) {
+ public void setDebug(boolean debug) {
this.debug = debug;
}
protected class BundlesSet {
private String baseUrl = "reference:file";// not used yet
private final String dir;
- private List<String> includes = new ArrayList<String>();
- private List<String> excludes = new ArrayList<String>();
+ private List includes = new ArrayList();
+ private List excludes = new ArrayList();
public BundlesSet(String def) {
StringTokenizer st = new StringTokenizer(def, ";");
throw new RuntimeException("Base dir not defined.");
try {
String dirPath = st.nextToken();
+
+ if (dirPath.startsWith("file:"))
+ dirPath = dirPath.substring("file:".length());
+
dir = new File(dirPath.replace('/', File.separatorChar))
.getCanonicalPath();
if (debug)
return dir;
}
- public List<String> getIncludes() {
+ public List getIncludes() {
return includes;
}
- public List<String> getExcludes() {
+ public List getExcludes() {
return excludes;
}