You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@servicemix.apache.org by gn...@apache.org on 2008/04/01 15:41:47 UTC
svn commit: r643395 - in
/servicemix/smx4/kernel/trunk/gshell/gshell-features/src/main/java/org/apache/servicemix/gshell/features:
Feature.java internal/FeatureImpl.java internal/FeaturesServiceImpl.java
internal/RepositoryImpl.java
Author: gnodet
Date: Tue Apr 1 06:41:40 2008
New Revision: 643395
URL: http://svn.apache.org/viewvc?rev=643395&view=rev
Log:
SMX4KNL-25: Improve features service
Modified:
servicemix/smx4/kernel/trunk/gshell/gshell-features/src/main/java/org/apache/servicemix/gshell/features/Feature.java
servicemix/smx4/kernel/trunk/gshell/gshell-features/src/main/java/org/apache/servicemix/gshell/features/internal/FeatureImpl.java
servicemix/smx4/kernel/trunk/gshell/gshell-features/src/main/java/org/apache/servicemix/gshell/features/internal/FeaturesServiceImpl.java
servicemix/smx4/kernel/trunk/gshell/gshell-features/src/main/java/org/apache/servicemix/gshell/features/internal/RepositoryImpl.java
Modified: servicemix/smx4/kernel/trunk/gshell/gshell-features/src/main/java/org/apache/servicemix/gshell/features/Feature.java
URL: http://svn.apache.org/viewvc/servicemix/smx4/kernel/trunk/gshell/gshell-features/src/main/java/org/apache/servicemix/gshell/features/Feature.java?rev=643395&r1=643394&r2=643395&view=diff
==============================================================================
--- servicemix/smx4/kernel/trunk/gshell/gshell-features/src/main/java/org/apache/servicemix/gshell/features/Feature.java (original)
+++ servicemix/smx4/kernel/trunk/gshell/gshell-features/src/main/java/org/apache/servicemix/gshell/features/Feature.java Tue Apr 1 06:41:40 2008
@@ -26,6 +26,8 @@
String getName();
+ List<String> getDependencies();
+
List<String> getBundles();
Map<String, Map<String, String>> getConfigurations();
Modified: servicemix/smx4/kernel/trunk/gshell/gshell-features/src/main/java/org/apache/servicemix/gshell/features/internal/FeatureImpl.java
URL: http://svn.apache.org/viewvc/servicemix/smx4/kernel/trunk/gshell/gshell-features/src/main/java/org/apache/servicemix/gshell/features/internal/FeatureImpl.java?rev=643395&r1=643394&r2=643395&view=diff
==============================================================================
--- servicemix/smx4/kernel/trunk/gshell/gshell-features/src/main/java/org/apache/servicemix/gshell/features/internal/FeatureImpl.java (original)
+++ servicemix/smx4/kernel/trunk/gshell/gshell-features/src/main/java/org/apache/servicemix/gshell/features/internal/FeatureImpl.java Tue Apr 1 06:41:40 2008
@@ -29,6 +29,7 @@
public class FeatureImpl implements Feature {
private String name;
+ private List<String> dependencies = new ArrayList<String>();
private List<String> bundles = new ArrayList<String>();
private Map<String, Map<String,String>> configs = new HashMap<String, Map<String,String>>();
@@ -40,12 +41,20 @@
return name;
}
+ public List<String> getDependencies() {
+ return dependencies;
+ }
+
public List<String> getBundles() {
return bundles;
}
public Map<String, Map<String, String>> getConfigurations() {
return configs;
+ }
+
+ public void addDependency(String dependency) {
+ dependencies.add(dependency);
}
public void addBundle(String bundle) {
Modified: servicemix/smx4/kernel/trunk/gshell/gshell-features/src/main/java/org/apache/servicemix/gshell/features/internal/FeaturesServiceImpl.java
URL: http://svn.apache.org/viewvc/servicemix/smx4/kernel/trunk/gshell/gshell-features/src/main/java/org/apache/servicemix/gshell/features/internal/FeaturesServiceImpl.java?rev=643395&r1=643394&r2=643395&view=diff
==============================================================================
--- servicemix/smx4/kernel/trunk/gshell/gshell-features/src/main/java/org/apache/servicemix/gshell/features/internal/FeaturesServiceImpl.java (original)
+++ servicemix/smx4/kernel/trunk/gshell/gshell-features/src/main/java/org/apache/servicemix/gshell/features/internal/FeaturesServiceImpl.java Tue Apr 1 06:41:40 2008
@@ -16,7 +16,9 @@
*/
package org.apache.servicemix.gshell.features.internal;
+import java.io.BufferedInputStream;
import java.io.IOException;
+import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
@@ -25,17 +27,27 @@
import java.util.HashMap;
import java.util.HashSet;
import java.util.Hashtable;
+import java.util.List;
import java.util.Map;
import java.util.Set;
+import java.util.jar.JarInputStream;
+import java.util.jar.Manifest;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
import org.apache.servicemix.gshell.features.Feature;
import org.apache.servicemix.gshell.features.FeaturesService;
import org.apache.servicemix.gshell.features.Repository;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.framework.Version;
+import org.osgi.framework.BundleException;
import org.osgi.service.cm.Configuration;
import org.osgi.service.cm.ConfigurationAdmin;
+import org.osgi.service.prefs.BackingStoreException;
+import org.osgi.service.prefs.Preferences;
import org.osgi.service.prefs.PreferencesService;
import org.springframework.osgi.context.BundleContextAware;
@@ -50,12 +62,15 @@
private static final String ALIAS_KEY = "_alias_factory_pid";
+ private static final Log LOGGER = LogFactory.getLog(FeaturesServiceImpl.class);
+
private BundleContext bundleContext;
private ConfigurationAdmin configAdmin;
private PreferencesService preferences;
private Set<URL> urls;
private Map<URL, RepositoryImpl> repositories = new HashMap<URL, RepositoryImpl>();
private Map<String, Feature> features;
+ private Set<String> installed = new HashSet<String>();
public BundleContext getBundleContext() {
return bundleContext;
@@ -90,6 +105,11 @@
}
public void addRepository(URL url) throws Exception {
+ internalAddRepository(url);
+ saveState();
+ }
+
+ protected void internalAddRepository(URL url) throws Exception {
RepositoryImpl repo = new RepositoryImpl(url);
repositories.put(url, repo);
features = null;
@@ -101,6 +121,11 @@
}
public void removeRepository(URL url) {
+ internalRemoveRepository(url);
+ saveState();
+ }
+
+ public void internalRemoveRepository(URL url) {
Repository repo = repositories.remove(url);
features = null;
}
@@ -115,6 +140,9 @@
if (f == null) {
throw new Exception("No feature named '" + name + "' available");
}
+ for (String dependency : f.getDependencies()) {
+ installFeature(dependency);
+ }
for (String config : f.getConfigurations().keySet()) {
Dictionary<String,String> props = new Hashtable<String, String>(f.getConfigurations().get(config));
String[] pid = parsePid(config);
@@ -127,14 +155,51 @@
}
cfg.update(props);
}
- for (String bundle : f.getBundles()) {
- Bundle b = getBundleContext().installBundle(bundle, null);
+ for (String bundleLocation : f.getBundles()) {
+ Bundle b = installBundleIfNeeded(bundleLocation);
b.start();
}
+ installed.add(name);
+ saveState();
+ }
+
+ protected Bundle installBundleIfNeeded(String bundleLocation) throws IOException, BundleException {
+ LOGGER.debug("Checking " + bundleLocation);
+ InputStream is = new BufferedInputStream(new URL(bundleLocation).openStream());
+ try {
+ is.mark(256 * 1024);
+ JarInputStream jar = new JarInputStream(is);
+ Manifest m = jar.getManifest();
+ String sn = m.getMainAttributes().getValue(Constants.BUNDLE_SYMBOLICNAME);
+ String vStr = m.getMainAttributes().getValue(Constants.BUNDLE_VERSION);
+ Version v = vStr == null ? Version.emptyVersion : Version.parseVersion(vStr);
+ boolean install = true;
+ for (Bundle b : bundleContext.getBundles()) {
+ if (b.getSymbolicName().equals(sn)) {
+ vStr = (String) b.getHeaders().get(Constants.BUNDLE_VERSION);
+ Version bv = vStr == null ? Version.emptyVersion : Version.parseVersion(vStr);
+ if (v.equals(bv)) {
+ LOGGER.debug(" found installed bundle: " + b);
+ return b;
+ }
+ }
+ }
+ try {
+ is.reset();
+ } catch (IOException e) {
+ is.close();
+ is = new BufferedInputStream(new URL(bundleLocation).openStream());
+ }
+ LOGGER.debug("Installing bundle " + bundleLocation);
+ return getBundleContext().installBundle(bundleLocation, is);
+ } finally {
+ is.close();
+ }
}
public void uninstallFeature(String name) throws Exception {
- //To change body of implemented methods use File | Settings | File Templates.
+ // TODO
+ //saveState();
}
public String[] listFeatures() {
@@ -148,7 +213,7 @@
}
public String[] listInstalledFeatures() {
- return new String[0]; //To change body of implemented methods use File | Settings | File Templates.
+ return installed.toArray(new String[installed.size()]);
}
protected Feature getFeature(String name) {
@@ -169,17 +234,20 @@
}
public void start() throws Exception {
- if (urls != null) {
- for (URL url : urls) {
- addRepository(url);
+ if (!loadState()) {
+ if (urls != null) {
+ for (URL url : urls) {
+ internalAddRepository(url);
+ }
}
+ saveState();
}
}
public void stop() throws Exception {
urls = new HashSet<URL>(repositories.keySet());
while (!repositories.isEmpty()) {
- removeRepository(repositories.keySet().iterator().next());
+ internalRemoveRepository(repositories.keySet().iterator().next());
}
}
@@ -206,6 +274,52 @@
} else {
return configurationAdmin.getConfiguration(pid, null);
}
+ }
+
+ protected void saveState() {
+ try {
+ Preferences prefs = preferences.getUserPreferences("FeaturesServiceState");
+ saveSet(prefs.node("repositories"), repositories.keySet());
+ saveSet(prefs.node("features"), installed);
+ prefs.flush();
+ } catch (Exception e) {
+ LOGGER.error("Error persisting FeaturesService state", e);
+ }
+ }
+
+ protected boolean loadState() {
+ try {
+ Preferences prefs = preferences.getUserPreferences("FeaturesServiceState");
+ if (prefs.nodeExists("repositories")) {
+ Set<String> repositories = loadSet(prefs.node("repositories"));
+ for (String repo : repositories) {
+ internalAddRepository(new URL(repo));
+ }
+ installed = loadSet(prefs.node("features"));
+ return true;
+ }
+ } catch (Exception e) {
+ LOGGER.error("Error loading FeaturesService state", e);
+ }
+ return false;
+ }
+
+ protected void saveSet(Preferences node, Set set) throws BackingStoreException {
+ List l = new ArrayList(set);
+ node.clear();
+ node.putInt("count", l.size());
+ for (int i = 0; i < l.size(); i++) {
+ node.put("item." + i, l.get(i).toString());
+ }
+ }
+
+ protected Set<String> loadSet(Preferences node) {
+ Set<String> l = new HashSet<String>();
+ int count = node.getInt("count", 0);
+ for (int i = 0; i < count; i++) {
+ l.add(node.get("item." + i, null));
+ }
+ return l;
}
}
Modified: servicemix/smx4/kernel/trunk/gshell/gshell-features/src/main/java/org/apache/servicemix/gshell/features/internal/RepositoryImpl.java
URL: http://svn.apache.org/viewvc/servicemix/smx4/kernel/trunk/gshell/gshell-features/src/main/java/org/apache/servicemix/gshell/features/internal/RepositoryImpl.java?rev=643395&r1=643394&r2=643395&view=diff
==============================================================================
--- servicemix/smx4/kernel/trunk/gshell/gshell-features/src/main/java/org/apache/servicemix/gshell/features/internal/RepositoryImpl.java (original)
+++ servicemix/smx4/kernel/trunk/gshell/gshell-features/src/main/java/org/apache/servicemix/gshell/features/internal/RepositoryImpl.java Tue Apr 1 06:41:40 2008
@@ -66,6 +66,11 @@
Element e = (Element) nodes.item(i);
String name = e.getAttribute("name");
FeatureImpl f = new FeatureImpl(name);
+ NodeList featureNodes = e.getElementsByTagName("feature");
+ for (int j = 0; j < featureNodes.getLength(); j++) {
+ Element b = (Element) featureNodes.item(j);
+ f.addDependency(b.getTextContent());
+ }
NodeList configNodes = e.getElementsByTagName("config");
for (int j = 0; j < configNodes.getLength(); j++) {
Element c = (Element) configNodes.item(j);