Repository: karaf Updated Branches: refs/heads/karaf-2.x 6f3015add -> 127849f43
[KARAF-2104] Add regex support in features management Project: http://git-wip-us.apache.org/repos/asf/karaf/repo Commit: http://git-wip-us.apache.org/repos/asf/karaf/commit/127849f4 Tree: http://git-wip-us.apache.org/repos/asf/karaf/tree/127849f4 Diff: http://git-wip-us.apache.org/repos/asf/karaf/diff/127849f4 Branch: refs/heads/karaf-2.x Commit: 127849f4366d8387ce144b26df078c715bf8135a Parents: 6f3015a Author: Jean-Baptiste Onofré <[email protected]> Authored: Fri Dec 19 15:09:23 2014 +0100 Committer: Jean-Baptiste Onofré <[email protected]> Committed: Fri Dec 19 15:09:23 2014 +0100 ---------------------------------------------------------------------- .../apache/karaf/features/FeaturesService.java | 4 + .../features/internal/FeaturesServiceImpl.java | 244 +++++++++++-------- .../karaf/features/FeaturesServiceTest.java | 8 - .../internal/FeaturesServiceMBeanImpl.java | 2 +- .../karaf/tooling/features/InstallKarsMojo.java | 8 + 5 files changed, 161 insertions(+), 105 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/karaf/blob/127849f4/features/core/src/main/java/org/apache/karaf/features/FeaturesService.java ---------------------------------------------------------------------- diff --git a/features/core/src/main/java/org/apache/karaf/features/FeaturesService.java b/features/core/src/main/java/org/apache/karaf/features/FeaturesService.java index 3a39b48..dd26698 100644 --- a/features/core/src/main/java/org/apache/karaf/features/FeaturesService.java +++ b/features/core/src/main/java/org/apache/karaf/features/FeaturesService.java @@ -87,6 +87,10 @@ public interface FeaturesService { boolean isInstalled(Feature f); + Feature[] getFeatures(String name, String version) throws Exception; + + Feature[] getFeatures(String name) throws Exception; + Feature getFeature(String name, String version) throws Exception; Feature getFeature(String name) throws Exception; http://git-wip-us.apache.org/repos/asf/karaf/blob/127849f4/features/core/src/main/java/org/apache/karaf/features/internal/FeaturesServiceImpl.java ---------------------------------------------------------------------- diff --git a/features/core/src/main/java/org/apache/karaf/features/internal/FeaturesServiceImpl.java b/features/core/src/main/java/org/apache/karaf/features/internal/FeaturesServiceImpl.java index 1b74006..afa3c4f 100644 --- a/features/core/src/main/java/org/apache/karaf/features/internal/FeaturesServiceImpl.java +++ b/features/core/src/main/java/org/apache/karaf/features/internal/FeaturesServiceImpl.java @@ -410,7 +410,7 @@ public class FeaturesServiceImpl implements FeaturesService { /** * Install a feature identified by a name and a version. * - * @param name the name of the feature. + * @param name the name of the feature (supporting regex). * @param version the version of the feature. * @throws Exception in case of installation failure. */ @@ -418,13 +418,31 @@ public class FeaturesServiceImpl implements FeaturesService { installFeature(name, version, EnumSet.noneOf(Option.class)); } + /** + * Install a feature identified by a name and a version, and installation option. + * + * @param name the name of the feature (supporting regex). + * @param version the version of the feature. + * @param options the installation option. + * @throws Exception in case of installation failure. + */ public void installFeature(String name, String version, EnumSet<Option> options) throws Exception { - Feature f = getFeature(name, version); - if (f == null) { - throw new Exception("No feature named '" + name - + "' with version '" + version + "' available"); + ArrayList<Exception> exceptions = new ArrayList<Exception>(); + Feature[] features = getFeatures(name, version); + for (Feature f : features) { + try { + installFeature(f, options); + } catch (Exception e) { + exceptions.add(e); + } + } + if (!exceptions.isEmpty()) { + StringBuilder builder = new StringBuilder(); + for (Exception exception : exceptions) { + builder.append("\t\n").append(exception.getMessage()); + } + throw new IllegalStateException("Can't install feature " + name + "/" + version + ": " + builder.toString()); } - installFeature(f, options); } public void installFeature(Feature f, EnumSet<Option> options) throws Exception { @@ -1040,27 +1058,20 @@ public class FeaturesServiceImpl implements FeaturesService { } public void uninstallFeature(String name, EnumSet<Option> options) throws Exception { - List<String> versions = new ArrayList<String>(); + ArrayList<Feature> featuresToUninstall = new ArrayList<Feature>(); + Pattern pattern = Pattern.compile(name); for (Feature f : installed.keySet()) { - if (name.equals(f.getName())) { - versions.add(f.getVersion()); + Matcher matcher = pattern.matcher(f.getName()); + if (matcher.matches()) { + featuresToUninstall.add(f); } } - if (versions.size() == 0) { - throw new Exception("Feature named '" + name + "' is not installed"); - } else if (versions.size() > 1) { - StringBuilder sb = new StringBuilder(); - sb.append("Feature named '").append(name).append("' has multiple versions installed ("); - for (int i = 0; i < versions.size(); i++) { - if (i > 0) { - sb.append(", "); - } - sb.append(versions.get(i)); - } - sb.append("). Please specify the version to uninstall."); - throw new Exception(sb.toString()); + if (featuresToUninstall.isEmpty()) { + throw new IllegalStateException("No installed feature matching " + name); + } + for (Feature f : featuresToUninstall) { + uninstallFeature(f.getName(), f.getVersion(), options); } - uninstallFeature(name, versions.get(0), options); } public void uninstallFeature(String name, String version) throws Exception { @@ -1068,60 +1079,79 @@ public class FeaturesServiceImpl implements FeaturesService { } public void uninstallFeature(String name, String version, EnumSet<Option> options) throws Exception { - Feature feature = getFeature(name, version); - if (feature == null || !installed.containsKey(feature)) { - throw new Exception("Feature named '" + name - + "' with version '" + version + "' is not installed"); - } - boolean verbose = options != null && options.contains(Option.Verbose); - boolean refresh = options == null || !options.contains(Option.NoAutoRefreshBundles); - if (verbose) { - System.out.println("Uninstalling feature " + feature.getName() + " " + feature.getVersion()); - } - // Grab all the bundles installed by this feature - // and remove all those who will still be in use. - // This gives this list of bundles to uninstall. - Set<Long> bundles = installed.remove(feature); - - // Also remove bundles installed as conditionals - for (Conditional conditional : feature.getConditional()) { - Set<Long> ids = installed.remove(conditional.asFeature(feature.getName(), feature.getVersion())); - if (ids != null) { - bundles.addAll(ids); + ArrayList<Exception> exceptions = new ArrayList<Exception>(); + Feature[] features = getFeatures(name, version); + ArrayList<Feature> featuresToUninstall = new ArrayList<Feature>(); + for (Feature feature : features) { + if (installed.containsKey(feature)) { + featuresToUninstall.add(feature); } } - // Verify all other conditionals - for (Feature dep : new ArrayList<Feature>(installed.keySet())) { - Feature f = getFeature(dep.getName(), dep.getVersion()); - if (f != null) { - for (Conditional conditional : f.getConditional()) { - if (!dependenciesSatisfied(conditional.getCondition(), installed.keySet())) { - Set<Long> ids = installed.remove(conditional.asFeature(f.getName(), f.getVersion())); - if (ids != null) { - bundles.addAll(ids); + if (featuresToUninstall.isEmpty()) { + throw new IllegalStateException("No installed feature matching " + name + "/" + version); + } + for (Feature feature : featuresToUninstall) { + try { + boolean verbose = options != null && options.contains(Option.Verbose); + boolean refresh = options == null || !options.contains(Option.NoAutoRefreshBundles); + if (verbose) { + System.out.println("Uninstalling feature " + feature.getName() + " " + feature.getVersion()); + } + // Grab all the bundles installed by this feature + // and remove all those who will still be in use. + // This gives this list of bundles to uninstall. + Set<Long> bundles = installed.remove(feature); + + // Also remove bundles installed as conditionals + for (Conditional conditional : feature.getConditional()) { + Set<Long> ids = installed.remove(conditional.asFeature(feature.getName(), feature.getVersion())); + if (ids != null) { + bundles.addAll(ids); + } + } + // Verify all other conditionals + for (Feature dep : new ArrayList<Feature>(installed.keySet())) { + Feature f = getFeature(dep.getName(), dep.getVersion()); + if (f != null) { + for (Conditional conditional : f.getConditional()) { + if (!dependenciesSatisfied(conditional.getCondition(), installed.keySet())) { + Set<Long> ids = installed.remove(conditional.asFeature(f.getName(), f.getVersion())); + if (ids != null) { + bundles.addAll(ids); + } + } } } } - } - } - for (Set<Long> b : installed.values()) { - bundles.removeAll(b); - } - for (long bundleId : bundles) { - Bundle b = getBundleContext().getBundle(bundleId); - if (b != null) { - b.uninstall(); + for (Set<Long> b : installed.values()) { + bundles.removeAll(b); + } + for (long bundleId : bundles) { + Bundle b = getBundleContext().getBundle(bundleId); + if (b != null) { + b.uninstall(); + } + } + if (refresh) { + if (verbose) { + System.out.println("Refreshing packages"); + } + refreshPackages(null); + } + callListeners(new FeatureEvent(feature, FeatureEvent.EventType.FeatureUninstalled, false)); + saveState(); + } catch (Exception e) { + exceptions.add(e); } } - if (refresh) { - if (verbose) { - System.out.println("Refreshing packages"); + if (!exceptions.isEmpty()) { + StringBuilder builder = new StringBuilder(); + for (Exception exception : exceptions) { + builder.append("\t\n").append(exception.getMessage()); } - refreshPackages(null); + throw new IllegalStateException("Can't uninstall feature " + name + "/" + version + ": " + builder.toString()); } - callListeners(new FeatureEvent(feature, FeatureEvent.EventType.FeatureUninstalled, false)); - saveState(); } public Feature[] listFeatures() throws Exception { @@ -1143,42 +1173,64 @@ public class FeaturesServiceImpl implements FeaturesService { return installed.containsKey(f); } - public Feature getFeature(String name) throws Exception { - return getFeature(name, FeatureImpl.DEFAULT_VERSION); - } - - public Feature getFeature(String name, String version) throws Exception { + public Feature[] getFeatures(String name, String version) throws Exception { + ArrayList<Feature> features = new ArrayList<Feature>(); if (version != null) { version = version.trim(); } - Map<String, Feature> versions = getFeatures().get(name); - if (versions == null || versions.isEmpty()) { - return null; - } else { - Feature feature = versions.get(version); - if (feature == null) { - if (FeatureImpl.DEFAULT_VERSION.equals(version)) { - Version latest = new Version(cleanupVersion(version)); - for (String available : versions.keySet()) { - Version availableVersion = new Version(cleanupVersion(available)); - if (availableVersion.compareTo(latest) > 0) { - feature = versions.get(available); - latest = availableVersion; - } - } - } else { - Version latest = new Version(cleanupVersion(FeatureImpl.DEFAULT_VERSION)); - VersionRange versionRange = new VersionRange(version, true, true); - for (String available : versions.keySet()) { - Version availableVersion = new Version(cleanupVersion(available)); - if (availableVersion.compareTo(latest) > 0 && versionRange.contains(availableVersion)) { - feature = versions.get(available); - latest = availableVersion; + Pattern pattern = Pattern.compile(name); + for (String featureName : getFeatures().keySet()) { + Matcher matcher = pattern.matcher(featureName); + if (matcher.matches()) { + Map<String, Feature> versions = getFeatures().get(featureName); + if (versions != null && !versions.isEmpty()) { + Feature feature = versions.get(version); + if (feature == null) { + if (FeatureImpl.DEFAULT_VERSION.equals(version)) { + Version latest = new Version(cleanupVersion(version)); + for (String available : versions.keySet()) { + Version availableVersion = new Version(cleanupVersion(available)); + if (availableVersion.compareTo(latest) > 0) { + feature = versions.get(available); + latest = availableVersion; + } + } + } else { + Version latest = new Version(cleanupVersion(FeatureImpl.DEFAULT_VERSION)); + VersionRange versionRange = new VersionRange(version, true, true); + for (String available : versions.keySet()) { + Version availableVersion = new Version(cleanupVersion(available)); + if (availableVersion.compareTo(latest) > 0 && versionRange.contains(availableVersion)) { + feature = versions.get(available); + latest = availableVersion; + } + } } } + features.add(feature); } } - return feature; + } + return features.toArray(new Feature[features.size()]); + } + + public Feature[] getFeatures(String name) throws Exception { + return getFeatures(name, FeatureImpl.DEFAULT_VERSION); + } + + public Feature getFeature(String name) throws Exception { + if (getFeatures(name).length < 1) { + return null; + } else { + return getFeatures(name)[0]; + } + } + + public Feature getFeature(String name, String version) throws Exception { + if (getFeatures(name, version).length < 1) { + return null; + } else { + return getFeatures(name, version)[0]; } } http://git-wip-us.apache.org/repos/asf/karaf/blob/127849f4/features/core/src/test/java/org/apache/karaf/features/FeaturesServiceTest.java ---------------------------------------------------------------------- diff --git a/features/core/src/test/java/org/apache/karaf/features/FeaturesServiceTest.java b/features/core/src/test/java/org/apache/karaf/features/FeaturesServiceTest.java index 4171032..46897bb 100644 --- a/features/core/src/test/java/org/apache/karaf/features/FeaturesServiceTest.java +++ b/features/core/src/test/java/org/apache/karaf/features/FeaturesServiceTest.java @@ -239,14 +239,6 @@ public class FeaturesServiceTest extends TestCase { svc.installFeature("f1", "0.1", EnumSet.of(FeaturesService.Option.NoAutoRefreshBundles)); svc.installFeature("f1", "0.2", EnumSet.of(FeaturesService.Option.NoAutoRefreshBundles)); - try { - svc.uninstallFeature("f1"); - fail("Uninstall should have failed as feature is installed in multiple versions"); - } catch (Exception e) { - // ok - } - - svc.uninstallFeature("f1", "0.1"); svc.uninstallFeature("f1"); } http://git-wip-us.apache.org/repos/asf/karaf/blob/127849f4/features/management/src/main/java/org/apache/karaf/features/management/internal/FeaturesServiceMBeanImpl.java ---------------------------------------------------------------------- diff --git a/features/management/src/main/java/org/apache/karaf/features/management/internal/FeaturesServiceMBeanImpl.java b/features/management/src/main/java/org/apache/karaf/features/management/internal/FeaturesServiceMBeanImpl.java index 2cbfe81..0e577ea 100644 --- a/features/management/src/main/java/org/apache/karaf/features/management/internal/FeaturesServiceMBeanImpl.java +++ b/features/management/src/main/java/org/apache/karaf/features/management/internal/FeaturesServiceMBeanImpl.java @@ -164,7 +164,7 @@ public class FeaturesServiceMBeanImpl extends StandardEmitterMBean implements public void removeRepositoryByName(String name) throws Exception { removeRepositoryByName(name, false); } - + public void removeRepositoryByName(String name, boolean uninstall) throws Exception { Pattern pattern = Pattern.compile(name); ArrayList<URI> urisToRemove = new ArrayList<URI>(); http://git-wip-us.apache.org/repos/asf/karaf/blob/127849f4/tooling/features-maven-plugin/src/main/java/org/apache/karaf/tooling/features/InstallKarsMojo.java ---------------------------------------------------------------------- diff --git a/tooling/features-maven-plugin/src/main/java/org/apache/karaf/tooling/features/InstallKarsMojo.java b/tooling/features-maven-plugin/src/main/java/org/apache/karaf/tooling/features/InstallKarsMojo.java index d406eb1..25e8895 100644 --- a/tooling/features-maven-plugin/src/main/java/org/apache/karaf/tooling/features/InstallKarsMojo.java +++ b/tooling/features-maven-plugin/src/main/java/org/apache/karaf/tooling/features/InstallKarsMojo.java @@ -189,6 +189,14 @@ public class InstallKarsMojo extends MojoSupport { return false; } + public Feature[] getFeatures(String name, String version) throws Exception { + return null; + } + + public Feature[] getFeatures(String name) throws Exception { + return null; + } + public Feature getFeature(String name, String version) throws Exception { return null; }
