You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@karaf.apache.org by gn...@apache.org on 2014/04/18 23:35:52 UTC

[2/6] [KARAF-2923] Region support in features service

http://git-wip-us.apache.org/repos/asf/karaf/blob/2705ad88/features/core/src/test/java/org/apache/karaf/features/internal/region/SubsystemTest.java
----------------------------------------------------------------------
diff --git a/features/core/src/test/java/org/apache/karaf/features/internal/region/SubsystemTest.java b/features/core/src/test/java/org/apache/karaf/features/internal/region/SubsystemTest.java
new file mode 100644
index 0000000..0ef26cb
--- /dev/null
+++ b/features/core/src/test/java/org/apache/karaf/features/internal/region/SubsystemTest.java
@@ -0,0 +1,213 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.karaf.features.internal.region;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.MalformedURLException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.jar.JarOutputStream;
+import java.util.jar.Manifest;
+
+import org.apache.karaf.features.Repository;
+import org.apache.karaf.features.internal.download.StreamProvider;
+import org.apache.karaf.features.internal.service.FeaturesServiceImpl;
+import org.apache.karaf.features.internal.service.RepositoryImpl;
+import org.apache.karaf.features.internal.download.simple.SimpleDownloader;
+import org.junit.Test;
+import org.osgi.framework.namespace.IdentityNamespace;
+import org.osgi.resource.Capability;
+import org.osgi.resource.Resource;
+import org.osgi.resource.Wire;
+
+import static org.apache.karaf.features.internal.util.MapUtils.addToMapSet;
+import static org.junit.Assert.assertEquals;
+
+public class SubsystemTest {
+
+    @Test
+    public void test1() throws Exception {
+        RepositoryImpl repo = new RepositoryImpl(getClass().getResource("data1/features.xml").toURI());
+
+        Map<String, Set<String>> features = new HashMap<String, Set<String>>();
+        addToMapSet(features, "root", "f1");
+        addToMapSet(features, "root/apps1", "f2");
+
+        Map<String, Set<String>> expected = new HashMap<String, Set<String>>();
+        addToMapSet(expected, "root", "a/1.0.0");
+        addToMapSet(expected, "root", "c/1.0.0");
+        addToMapSet(expected, "root/apps1", "b/1.0.0");
+
+        SubsystemResolver resolver = new SubsystemResolver(new TestDownloadManager("data1"));
+        resolver.resolve(Collections.<Repository>singletonList(repo),
+                         features,
+                         Collections.<Resource>emptyList(),
+                         FeaturesServiceImpl.DEFAULT_FEATURE_RESOLUTION_RANGE);
+
+        verify(resolver, expected);
+    }
+
+    @Test
+    public void test2() throws Exception {
+
+        RepositoryImpl repo = new RepositoryImpl(getClass().getResource("data2/features.xml").toURI());
+
+        Map<String, Set<String>> features = new HashMap<String, Set<String>>();
+        addToMapSet(features, "root/apps1", "f1");
+        addToMapSet(features, "root/apps1", "f3");
+        addToMapSet(features, "root/apps2", "f1");
+
+        Map<String, Set<String>> expected = new HashMap<String, Set<String>>();
+        addToMapSet(expected, "root/apps1", "c/1.0.0");
+        addToMapSet(expected, "root/apps1", "b/1.0.0");
+        addToMapSet(expected, "root/apps1", "e/1.0.0");
+        addToMapSet(expected, "root/apps1#f1", "a/1.0.0");
+        addToMapSet(expected, "root/apps1#f1", "d/1.0.0");
+        addToMapSet(expected, "root/apps2", "b/1.0.0");
+        addToMapSet(expected, "root/apps2", "c/1.0.0");
+        addToMapSet(expected, "root/apps2#f1", "a/1.0.0");
+
+        SubsystemResolver resolver = new SubsystemResolver(new TestDownloadManager("data2"));
+        resolver.resolve(Collections.<Repository>singletonList(repo),
+                         features,
+                         Collections.<Resource>emptyList(),
+                         FeaturesServiceImpl.DEFAULT_FEATURE_RESOLUTION_RANGE);
+
+        verify(resolver, expected);
+    }
+
+    private void verify(SubsystemResolver resolver, Map<String, Set<String>> expected) {
+        Map<String, Set<String>> mapping = getBundleNamesPerRegions(resolver);
+        if (!expected.equals(mapping)) {
+            dumpBundles(resolver);
+            dumpWiring(resolver);
+            assertEquals("Resolution failed", expected, mapping);
+        }
+    }
+
+    private void dumpBundles(SubsystemResolver resolver) {
+        System.out.println("Bundle mapping");
+        Map<String, Set<Resource>> bundles = resolver.getBundlesPerRegions();
+        for (Map.Entry<String, Set<Resource>> entry : bundles.entrySet()) {
+            System.out.println("    " + entry.getKey());
+            for (Resource b : entry.getValue()) {
+                System.out.println("        " + b);
+            }
+        }
+    }
+
+    private Map<String, Set<String>> getBundleNamesPerRegions(SubsystemResolver resolver) {
+        Map<String, Set<String>> mapping = new HashMap<String, Set<String>>();
+        Map<String, Set<Resource>> bundles = resolver.getBundlesPerRegions();
+        for (Map.Entry<String,Set<Resource>> entry : bundles.entrySet()) {
+            for (Resource r : entry.getValue()) {
+                addToMapSet(mapping, entry.getKey(), r.toString());
+            }
+        }
+        return mapping;
+    }
+
+
+    private void dumpWiring(SubsystemResolver resolver) {
+        System.out.println("Wiring");
+        Map<Resource, List<Wire>> wiring = resolver.getWiring();
+        List<Resource> resources = new ArrayList<Resource>(wiring.keySet());
+        Collections.sort(resources, new Comparator<Resource>() {
+            @Override
+            public int compare(Resource o1, Resource o2) {
+                return getName(o1).compareTo(getName(o2));
+            }
+        });
+        for (Resource resource : resources) {
+            System.out.println("    " + getName(resource));
+            for (Wire wire : wiring.get(resource)) {
+                System.out.println("        " + wire);
+            }
+        }
+    }
+
+    private String getName(Resource resource) {
+        Capability cap = resource.getCapabilities(IdentityNamespace.IDENTITY_NAMESPACE).get(0);
+        return cap.getAttributes().get(IdentityNamespace.CAPABILITY_TYPE_ATTRIBUTE) + ": "
+                + cap.getAttributes().get(IdentityNamespace.IDENTITY_NAMESPACE) + "/"
+                + cap.getAttributes().get(IdentityNamespace.CAPABILITY_VERSION_ATTRIBUTE);
+    }
+
+    class TestDownloadManager extends SimpleDownloader {
+
+        private final String dir;
+
+        TestDownloadManager(String dir) {
+            this.dir = dir;
+        }
+
+        @Override
+        protected StreamProvider createProvider(String location) throws MalformedURLException {
+            return new TestProvider(location);
+        }
+
+        class TestProvider implements StreamProvider {
+            private final IOException exception;
+            private final Map<String, String> headers;
+            private final byte[] data;
+
+            TestProvider(String location) {
+                Map<String, String> headers = null;
+                byte[] data = null;
+                IOException exception = null;
+                try {
+                    Manifest man = new Manifest(getClass().getResourceAsStream(dir +"/" + location + ".mf"));
+                    ByteArrayOutputStream baos = new ByteArrayOutputStream();
+                    JarOutputStream jos = new JarOutputStream(baos, man);
+                    jos.close();
+                    data = baos.toByteArray();
+                    headers = new HashMap<String, String>();
+                    for (Map.Entry attr : man.getMainAttributes().entrySet()) {
+                        headers.put(attr.getKey().toString(), attr.getValue().toString());
+                    }
+                } catch (IOException e) {
+                    exception = e;
+                }
+                this.headers = headers;
+                this.data = data;
+                this.exception = exception;
+            }
+
+            @Override
+            public InputStream open() throws IOException {
+                if (exception != null)
+                    throw exception;
+                return new ByteArrayInputStream(data);
+            }
+
+            @Override
+            public Map<String, String> getMetadata() throws IOException {
+                if (exception != null)
+                    throw exception;
+                return headers;
+            }
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/karaf/blob/2705ad88/features/core/src/test/java/org/apache/karaf/features/internal/service/FeaturesServiceImplTest.java
----------------------------------------------------------------------
diff --git a/features/core/src/test/java/org/apache/karaf/features/internal/service/FeaturesServiceImplTest.java b/features/core/src/test/java/org/apache/karaf/features/internal/service/FeaturesServiceImplTest.java
index b8b5fc0..3627c0f 100644
--- a/features/core/src/test/java/org/apache/karaf/features/internal/service/FeaturesServiceImplTest.java
+++ b/features/core/src/test/java/org/apache/karaf/features/internal/service/FeaturesServiceImplTest.java
@@ -49,7 +49,7 @@ public class FeaturesServiceImplTest extends TestBase {
     public void testGetFeature() throws Exception {
         Feature transactionFeature = feature("transaction", "1.0.0");
         final Map<String, Map<String, Feature>> features = features(transactionFeature);
-        final FeaturesServiceImpl impl = new FeaturesServiceImpl(null, null, new Storage(), null, null, null, "", null, null, null) {
+        final FeaturesServiceImpl impl = new FeaturesServiceImpl(null, null, new Storage(), null, null, null, null, "", null, null, null) {
             protected Map<String,Map<String,Feature>> getFeatures() throws Exception {
                 return features;
             }
@@ -60,7 +60,7 @@ public class FeaturesServiceImplTest extends TestBase {
     
     @Test
     public void testGetFeatureStripVersion() throws Exception {
-        final FeaturesServiceImpl impl = new FeaturesServiceImpl(null, null, new Storage(), null, null, null, "", null, null, null) {
+        final FeaturesServiceImpl impl = new FeaturesServiceImpl(null, null, new Storage(), null, null, null, null, "", null, null, null) {
             protected Map<String,Map<String,Feature>> getFeatures() throws Exception {
                 return features(feature("transaction", "1.0.0"));
             }
@@ -72,7 +72,7 @@ public class FeaturesServiceImplTest extends TestBase {
     
     @Test
     public void testGetFeatureNotAvailable() throws Exception {
-        final FeaturesServiceImpl impl = new FeaturesServiceImpl(null, null, new Storage(), null, null, null, "", null, null, null) {
+        final FeaturesServiceImpl impl = new FeaturesServiceImpl(null, null, new Storage(), null, null, null, null, "", null, null, null) {
             protected Map<String,Map<String,Feature>> getFeatures() throws Exception {
                 return features(feature("transaction", "1.0.0"));
             }
@@ -86,7 +86,7 @@ public class FeaturesServiceImplTest extends TestBase {
                 feature("transaction", "1.0.0"),
                 feature("transaction", "2.0.0")
         );
-        final FeaturesServiceImpl impl = new FeaturesServiceImpl(null, null, new Storage(), null, null, null, "", null, null, null) {
+        final FeaturesServiceImpl impl = new FeaturesServiceImpl(null, null, new Storage(), null, null, null, null, "", null, null, null) {
             protected Map<String,Map<String,Feature>> getFeatures() throws Exception {
                 return features;
             }

http://git-wip-us.apache.org/repos/asf/karaf/blob/2705ad88/features/core/src/test/java/org/apache/karaf/features/internal/service/OverridesTest.java
----------------------------------------------------------------------
diff --git a/features/core/src/test/java/org/apache/karaf/features/internal/service/OverridesTest.java b/features/core/src/test/java/org/apache/karaf/features/internal/service/OverridesTest.java
index c4976cf..2d4d4ae 100644
--- a/features/core/src/test/java/org/apache/karaf/features/internal/service/OverridesTest.java
+++ b/features/core/src/test/java/org/apache/karaf/features/internal/service/OverridesTest.java
@@ -16,36 +16,25 @@
  */
 package org.apache.karaf.features.internal.service;
 
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.FileWriter;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
-import java.io.Writer;
-import java.net.URI;
 import java.util.Arrays;
 import java.util.HashMap;
-import java.util.List;
 import java.util.Map;
 import java.util.Set;
 
 import org.apache.felix.utils.manifest.Clause;
 import org.apache.felix.utils.manifest.Parser;
-import org.apache.karaf.features.BundleInfo;
-import org.apache.karaf.features.internal.model.Bundle;
 import org.apache.karaf.features.internal.resolver.ResourceBuilder;
-import org.apache.karaf.features.internal.resolver.UriNamespace;
 import org.junit.Before;
 import org.junit.Test;
-import org.ops4j.pax.tinybundles.core.TinyBundles;
 import org.osgi.framework.BundleException;
 import org.osgi.resource.Resource;
 
-import static org.apache.karaf.features.internal.resolver.UriNamespace.getUri;
+import static org.apache.karaf.features.internal.resolver.ResourceUtils.getUri;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
 
 public class OverridesTest {
 

http://git-wip-us.apache.org/repos/asf/karaf/blob/2705ad88/features/core/src/test/java/org/apache/karaf/features/internal/service/StateStorageTest.java
----------------------------------------------------------------------
diff --git a/features/core/src/test/java/org/apache/karaf/features/internal/service/StateStorageTest.java b/features/core/src/test/java/org/apache/karaf/features/internal/service/StateStorageTest.java
new file mode 100644
index 0000000..5bee904
--- /dev/null
+++ b/features/core/src/test/java/org/apache/karaf/features/internal/service/StateStorageTest.java
@@ -0,0 +1,80 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.karaf.features.internal.service;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashSet;
+
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+
+public class StateStorageTest {
+
+    @Test
+    public void testStoreLoad() throws Exception {
+
+        State oldState = new State();
+        oldState.bootDone.set(true);
+        oldState.bundleChecksums.put(4l, 32794l);
+        oldState.features.put("bar", Collections.singleton("f1"));
+        oldState.managedBundles.put("reg", Collections.singleton(32l));
+        oldState.managedBundles.put("reg2", new HashSet<Long>(Arrays.asList(24l, 43l)));
+        oldState.repositories.add("repo");
+
+        TestStorage storage = new TestStorage();
+
+        storage.save(oldState);
+
+        System.out.println(storage.baos.toString());
+
+        State newState = new State();
+        storage.load(newState);
+
+        assertEquals(oldState.bootDone.get(), newState.bootDone.get());
+        assertEquals(oldState.bundleChecksums, newState.bundleChecksums);
+        assertEquals(oldState.features, newState.features);
+        assertEquals(oldState.managedBundles, newState.managedBundles);
+        assertEquals(oldState.repositories, newState.repositories);
+    }
+
+    static class TestStorage extends StateStorage {
+        ByteArrayOutputStream baos;
+
+        @Override
+        protected InputStream getInputStream() throws IOException {
+            if (baos != null) {
+                return new ByteArrayInputStream(baos.toByteArray());
+            }
+            return null;
+        }
+
+        @Override
+        protected OutputStream getOutputStream() throws IOException {
+            baos = new ByteArrayOutputStream();
+            return baos;
+        }
+    }
+
+
+}

http://git-wip-us.apache.org/repos/asf/karaf/blob/2705ad88/features/core/src/test/resources/org/apache/karaf/features/internal/region/data1/a.mf
----------------------------------------------------------------------
diff --git a/features/core/src/test/resources/org/apache/karaf/features/internal/region/data1/a.mf b/features/core/src/test/resources/org/apache/karaf/features/internal/region/data1/a.mf
new file mode 100644
index 0000000..b5e522b
--- /dev/null
+++ b/features/core/src/test/resources/org/apache/karaf/features/internal/region/data1/a.mf
@@ -0,0 +1,6 @@
+Manifest-Version: 1
+Bundle-ManifestVersion: 2
+Bundle-SymbolicName: a
+Bundle-Version: 1.0.0
+Require-Capability: ns;filter:="(ns=c)"
+

http://git-wip-us.apache.org/repos/asf/karaf/blob/2705ad88/features/core/src/test/resources/org/apache/karaf/features/internal/region/data1/b.mf
----------------------------------------------------------------------
diff --git a/features/core/src/test/resources/org/apache/karaf/features/internal/region/data1/b.mf b/features/core/src/test/resources/org/apache/karaf/features/internal/region/data1/b.mf
new file mode 100644
index 0000000..2ee6678
--- /dev/null
+++ b/features/core/src/test/resources/org/apache/karaf/features/internal/region/data1/b.mf
@@ -0,0 +1,6 @@
+Manifest-Version: 1
+Bundle-ManifestVersion: 2
+Bundle-SymbolicName: b
+Bundle-Version: 1.0.0
+Require-Capability: ns;filter:="(ns=c)"
+

http://git-wip-us.apache.org/repos/asf/karaf/blob/2705ad88/features/core/src/test/resources/org/apache/karaf/features/internal/region/data1/c.mf
----------------------------------------------------------------------
diff --git a/features/core/src/test/resources/org/apache/karaf/features/internal/region/data1/c.mf b/features/core/src/test/resources/org/apache/karaf/features/internal/region/data1/c.mf
new file mode 100644
index 0000000..8c731fb
--- /dev/null
+++ b/features/core/src/test/resources/org/apache/karaf/features/internal/region/data1/c.mf
@@ -0,0 +1,6 @@
+Manifest-Version: 1
+Bundle-ManifestVersion: 2
+Bundle-SymbolicName: c
+Bundle-Version: 1.0.0
+Provide-Capability: ns;ns=c
+

http://git-wip-us.apache.org/repos/asf/karaf/blob/2705ad88/features/core/src/test/resources/org/apache/karaf/features/internal/region/data1/features.xml
----------------------------------------------------------------------
diff --git a/features/core/src/test/resources/org/apache/karaf/features/internal/region/data1/features.xml b/features/core/src/test/resources/org/apache/karaf/features/internal/region/data1/features.xml
new file mode 100644
index 0000000..72c261c
--- /dev/null
+++ b/features/core/src/test/resources/org/apache/karaf/features/internal/region/data1/features.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+    Licensed to the Apache Software Foundation (ASF) under one or more
+    contributor license agreements. See the NOTICE file distributed with
+    this work for additional information regarding copyright ownership.
+    The ASF licenses this file to You under the Apache License, Version 2.0
+    (the "License"); you may not use this file except in compliance with
+    the License. You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+
+-->
+<features name="test" xmlns="http://karaf.apache.org/xmlns/features/v1.3.0">
+
+    <feature name="f1">
+        <bundle dependency="true">c</bundle>
+        <bundle>a</bundle>
+    </feature>
+
+    <feature name="f2">
+        <bundle dependency="true">c</bundle>
+        <bundle>b</bundle>
+    </feature>
+
+</features>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/karaf/blob/2705ad88/features/core/src/test/resources/org/apache/karaf/features/internal/region/data2/a.mf
----------------------------------------------------------------------
diff --git a/features/core/src/test/resources/org/apache/karaf/features/internal/region/data2/a.mf b/features/core/src/test/resources/org/apache/karaf/features/internal/region/data2/a.mf
new file mode 100644
index 0000000..99ed0c4
--- /dev/null
+++ b/features/core/src/test/resources/org/apache/karaf/features/internal/region/data2/a.mf
@@ -0,0 +1,7 @@
+Manifest-Version: 1
+Bundle-ManifestVersion: 2
+Bundle-SymbolicName: a
+Bundle-Version: 1.0.0
+Provide-Capability: ns;ns=a
+Require-Capability: ns;filter:="(ns=b)"
+

http://git-wip-us.apache.org/repos/asf/karaf/blob/2705ad88/features/core/src/test/resources/org/apache/karaf/features/internal/region/data2/b.mf
----------------------------------------------------------------------
diff --git a/features/core/src/test/resources/org/apache/karaf/features/internal/region/data2/b.mf b/features/core/src/test/resources/org/apache/karaf/features/internal/region/data2/b.mf
new file mode 100644
index 0000000..f66fd1e
--- /dev/null
+++ b/features/core/src/test/resources/org/apache/karaf/features/internal/region/data2/b.mf
@@ -0,0 +1,7 @@
+Manifest-Version: 1
+Bundle-ManifestVersion: 2
+Bundle-SymbolicName: b
+Bundle-Version: 1.0.0
+Provide-Capability: ns;ns=b
+Require-Capability: ns;filter:="(ns=c)"
+

http://git-wip-us.apache.org/repos/asf/karaf/blob/2705ad88/features/core/src/test/resources/org/apache/karaf/features/internal/region/data2/c.mf
----------------------------------------------------------------------
diff --git a/features/core/src/test/resources/org/apache/karaf/features/internal/region/data2/c.mf b/features/core/src/test/resources/org/apache/karaf/features/internal/region/data2/c.mf
new file mode 100644
index 0000000..8c731fb
--- /dev/null
+++ b/features/core/src/test/resources/org/apache/karaf/features/internal/region/data2/c.mf
@@ -0,0 +1,6 @@
+Manifest-Version: 1
+Bundle-ManifestVersion: 2
+Bundle-SymbolicName: c
+Bundle-Version: 1.0.0
+Provide-Capability: ns;ns=c
+

http://git-wip-us.apache.org/repos/asf/karaf/blob/2705ad88/features/core/src/test/resources/org/apache/karaf/features/internal/region/data2/d.mf
----------------------------------------------------------------------
diff --git a/features/core/src/test/resources/org/apache/karaf/features/internal/region/data2/d.mf b/features/core/src/test/resources/org/apache/karaf/features/internal/region/data2/d.mf
new file mode 100644
index 0000000..b1172fa
--- /dev/null
+++ b/features/core/src/test/resources/org/apache/karaf/features/internal/region/data2/d.mf
@@ -0,0 +1,6 @@
+Manifest-Version: 1
+Bundle-ManifestVersion: 2
+Bundle-SymbolicName: d
+Bundle-Version: 1.0.0
+
+

http://git-wip-us.apache.org/repos/asf/karaf/blob/2705ad88/features/core/src/test/resources/org/apache/karaf/features/internal/region/data2/e.mf
----------------------------------------------------------------------
diff --git a/features/core/src/test/resources/org/apache/karaf/features/internal/region/data2/e.mf b/features/core/src/test/resources/org/apache/karaf/features/internal/region/data2/e.mf
new file mode 100644
index 0000000..42b5ff9
--- /dev/null
+++ b/features/core/src/test/resources/org/apache/karaf/features/internal/region/data2/e.mf
@@ -0,0 +1,6 @@
+Manifest-Version: 1
+Bundle-ManifestVersion: 2
+Bundle-SymbolicName: e
+Bundle-Version: 1.0.0
+
+

http://git-wip-us.apache.org/repos/asf/karaf/blob/2705ad88/features/core/src/test/resources/org/apache/karaf/features/internal/region/data2/features.xml
----------------------------------------------------------------------
diff --git a/features/core/src/test/resources/org/apache/karaf/features/internal/region/data2/features.xml b/features/core/src/test/resources/org/apache/karaf/features/internal/region/data2/features.xml
new file mode 100644
index 0000000..b1cc8d6
--- /dev/null
+++ b/features/core/src/test/resources/org/apache/karaf/features/internal/region/data2/features.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+    Licensed to the Apache Software Foundation (ASF) under one or more
+    contributor license agreements. See the NOTICE file distributed with
+    this work for additional information regarding copyright ownership.
+    The ASF licenses this file to You under the Apache License, Version 2.0
+    (the "License"); you may not use this file except in compliance with
+    the License. You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+
+-->
+<features name="test" xmlns="http://karaf.apache.org/xmlns/features/v1.3.0">
+    <feature name="f1">
+        <feature>f2</feature>
+        <bundle dependency="true">b</bundle>
+        <bundle>a</bundle>
+        <conditional>
+            <condition>f3</condition>
+            <bundle>d</bundle>
+        </conditional>
+        <scoping acceptDependencies="false">
+            <import namespace="ns">(ns=b)</import>
+            <export namespace="ns">(ns=a)</export>
+        </scoping>
+    </feature>
+    
+    <feature name="f2">
+        <bundle>c</bundle>
+    </feature>
+
+    <feature name="f3">
+        <bundle>e</bundle>
+    </feature>
+
+</features>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/karaf/blob/2705ad88/features/core/src/test/resources/org/apache/karaf/features/internal/service/f07.xml
----------------------------------------------------------------------
diff --git a/features/core/src/test/resources/org/apache/karaf/features/internal/service/f07.xml b/features/core/src/test/resources/org/apache/karaf/features/internal/service/f07.xml
index b62ffda..8165d14 100644
--- a/features/core/src/test/resources/org/apache/karaf/features/internal/service/f07.xml
+++ b/features/core/src/test/resources/org/apache/karaf/features/internal/service/f07.xml
@@ -30,6 +30,17 @@
         <capability>
             service-reference;effective:=active;objectClass=org.apache.aries.proxy.ProxyManager
         </capability>
+        <scoping>
+            <export namespace="osgi.service">
+                (objectClass=org.apache.aries.proxy.ProxyManager)
+            </export>
+            <export namespace="osgi.wiring.package">
+                (|(osgi.wiring.package=org.apache.aries.proxy)(osgi.wiring.package=org.apache.aries.proxy.*))
+            </export>
+            <import namespace="org.eclipse.equinox.allow.all">
+                (|(!(all=*))(all=*))
+            </import>
+        </scoping>
     </feature>
 </features>
 

http://git-wip-us.apache.org/repos/asf/karaf/blob/2705ad88/itests/src/test/java/org/apache/karaf/itests/RegionTest.java
----------------------------------------------------------------------
diff --git a/itests/src/test/java/org/apache/karaf/itests/RegionTest.java b/itests/src/test/java/org/apache/karaf/itests/RegionTest.java
deleted file mode 100644
index 0af20fe..0000000
--- a/itests/src/test/java/org/apache/karaf/itests/RegionTest.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.karaf.itests;
-
-import static org.junit.Assert.assertTrue;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.ops4j.pax.exam.junit.PaxExam;
-import org.ops4j.pax.exam.spi.reactors.ExamReactorStrategy;
-import org.ops4j.pax.exam.spi.reactors.PerClass;
-
-@RunWith(PaxExam.class)
-@ExamReactorStrategy(PerClass.class)
-public class RegionTest extends KarafTestSupport {
-
-    @Test
-    public void infoCommand() throws Exception {
-        installAndAssertFeature("region");
-
-        String infoOutput = executeCommand("region:info");
-        System.out.println(infoOutput);
-        assertTrue("Region org.eclipse.equinox.region.kernel should be present", infoOutput.contains("org.eclipse.equinox.region.kernel"));
-        assertTrue("Region org.apache.karaf.region.application should be present", infoOutput.contains("org.apache.karaf.region.application"));
-    }
-
-    @Test
-    public void addRegionCommand() throws Exception {
-        installAndAssertFeature("region");
-
-        System.out.println(executeCommand("region:region-add itest"));
-        String infoOutput = executeCommand("region:info");
-        System.out.println(infoOutput);
-        assertTrue("Region itest should be present", infoOutput.contains("itest"));
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/karaf/blob/2705ad88/itests/src/test/java/org/apache/karaf/itests/features/StandardFeaturesTest.java
----------------------------------------------------------------------
diff --git a/itests/src/test/java/org/apache/karaf/itests/features/StandardFeaturesTest.java b/itests/src/test/java/org/apache/karaf/itests/features/StandardFeaturesTest.java
index c0e2086..3a1e741 100644
--- a/itests/src/test/java/org/apache/karaf/itests/features/StandardFeaturesTest.java
+++ b/itests/src/test/java/org/apache/karaf/itests/features/StandardFeaturesTest.java
@@ -60,11 +60,6 @@ public class StandardFeaturesTest extends KarafTestSupport {
     }
     
     @Test
-    public void installRegionFeature() throws Exception {
-        installAssertAndUninstallFeatures("region");
-    }
-    
-    @Test
     public void installPackageFeature() throws Exception {
         installAssertAndUninstallFeatures("package");
     }

http://git-wip-us.apache.org/repos/asf/karaf/blob/2705ad88/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index 2ef129f..0cc1447 100644
--- a/pom.xml
+++ b/pom.xml
@@ -40,7 +40,6 @@
         <module>main</module>
         <module>features</module>
         <module>kar</module>
-        <module>region</module>
         <module>bundle</module>
         <module>config</module>
         <module>instance</module>
@@ -526,11 +525,6 @@
                 <artifactId>org.apache.karaf.features.command</artifactId>
                 <version>${project.version}</version>
             </dependency>
-            <dependency>
-                <groupId>org.apache.karaf.features</groupId>
-                <artifactId>org.apache.karaf.features.obr</artifactId>
-                <version>${project.version}</version>
-            </dependency>
 
             <dependency>
                 <groupId>org.apache.karaf.diagnostic</groupId>
@@ -563,12 +557,6 @@
             </dependency>
 
             <dependency>
-                <groupId>org.apache.karaf.region</groupId>
-                <artifactId>org.apache.karaf.region.core</artifactId>
-                <version>${project.version}</version>
-            </dependency>
-
-            <dependency>
                 <groupId>org.apache.karaf.shell</groupId>
                 <artifactId>org.apache.karaf.shell.console</artifactId>
                 <version>${project.version}</version>
@@ -2248,6 +2236,8 @@
                                 <exclude>manual/**/*.css</exclude>
                                 <exclude>manual/**/*.ssp</exclude>
                                 <exclude>manual/**/*.conf</exclude>
+                                <!-- test manifests -->
+                                <exclude>**/*.mf</exclude>
                             </excludes>
                         </configuration>
                     </plugin>

http://git-wip-us.apache.org/repos/asf/karaf/blob/2705ad88/region/NOTICE
----------------------------------------------------------------------
diff --git a/region/NOTICE b/region/NOTICE
deleted file mode 100644
index b70f1f9..0000000
--- a/region/NOTICE
+++ /dev/null
@@ -1,71 +0,0 @@
-Apache Karaf
-Copyright 2010-2014 The Apache Software Foundation
-
-
-I. Included Software
-
-This product includes software developed at
-The Apache Software Foundation (http://www.apache.org/).
-Licensed under the Apache License 2.0.
-
-This product uses software developed at
-The OSGi Alliance (http://www.osgi.org/).
-Copyright (c) OSGi Alliance (2000, 2010).
-Licensed under the Apache License 2.0.
-
-This product includes software developed at
-OW2 (http://www.ow2.org/).
-Licensed under the BSD License.
-
-This product includes software developed at
-OPS4J (http://www.ops4j.org/).
-Licensed under the Apache License 2.0.
-
-This product includes software developed at
-Eclipse Foundation (http://www.eclipse.org/).
-Licensed under the EPL.
-
-This product includes software written by
-Antony Lesuisse.
-Licensed under Public Domain.
-
-
-II. Used Software
-
-This product uses software developed at
-FUSE Source (http://www.fusesource.org/).
-Licensed under the Apache License 2.0.
-
-This product uses software developed at
-AOP Alliance (http://aopalliance.sourceforge.net/).
-Licensed under the Public Domain.
-
-This product uses software developed at
-Tanuki Software (http://www.tanukisoftware.com/).
-Licensed under the Apache License 2.0.
-
-This product uses software developed at
-Jasypt (http://jasypt.sourceforge.net/).
-Licensed under the Apache License 2.0.
-
-This product uses software developed at
-JLine (http://jline.sourceforge.net).
-Licensed under the BSD License.
-
-This product uses software developed at
-SLF4J (http://www.slf4j.org/).
-Licensed under the MIT License.
-
-This product uses software developed at
-SpringSource (http://www.springsource.org/).
-Licensed under the Apache License 2.0.
-
-This product includes software from http://www.json.org.
-Copyright (c) 2002 JSON.org
-
-
-III. License Summary
-- Apache License 2.0
-- BSD License
-- EPL License
-- MIT License

http://git-wip-us.apache.org/repos/asf/karaf/blob/2705ad88/region/pom.xml
----------------------------------------------------------------------
diff --git a/region/pom.xml b/region/pom.xml
deleted file mode 100644
index 2375fcc..0000000
--- a/region/pom.xml
+++ /dev/null
@@ -1,136 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-
-    <!--
-
-        Licensed to the Apache Software Foundation (ASF) under one or more
-        contributor license agreements.  See the NOTICE file distributed with
-        this work for additional information regarding copyright ownership.
-        The ASF licenses this file to You under the Apache License, Version 2.0
-        (the "License"); you may not use this file except in compliance with
-        the License.  You may obtain a copy of the License at
-
-           http://www.apache.org/licenses/LICENSE-2.0
-
-        Unless required by applicable law or agreed to in writing, software
-        distributed under the License is distributed on an "AS IS" BASIS,
-        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-        See the License for the specific language governing permissions and
-        limitations under the License.
-    -->
-
-    <modelVersion>4.0.0</modelVersion>
-
-    <parent>
-        <groupId>org.apache.karaf</groupId>
-        <artifactId>karaf</artifactId>
-        <version>4.0.0-SNAPSHOT</version>
-    </parent>
-
-    <groupId>org.apache.karaf.region</groupId>
-    <artifactId>org.apache.karaf.region.core</artifactId>
-    <packaging>bundle</packaging>
-    <name>Apache Karaf :: Region :: Persistence</name>
-    <description>This bundle provides an xml regions model and install/dump actions.</description>
-
-    <properties>
-        <appendedResourcesDirectory>${basedir}/../../etc/appended-resources</appendedResourcesDirectory>
-    </properties>
-
-    <dependencies>
-        <dependency>
-            <groupId>org.osgi</groupId>
-            <artifactId>org.osgi.core</artifactId>
-            <scope>provided</scope>
-        </dependency>
-
-        <dependency>
-            <groupId>org.apache.karaf</groupId>
-            <artifactId>org.apache.karaf.util</artifactId>
-            <scope>provided</scope>
-        </dependency>
-
-        <dependency>
-            <groupId>org.osgi</groupId>
-            <artifactId>org.osgi.compendium</artifactId>
-            <scope>provided</scope>
-        </dependency>
-
-        <dependency>
-            <groupId>org.slf4j</groupId>
-            <artifactId>slf4j-api</artifactId>
-            <scope>provided</scope>
-        </dependency>
-
-        <dependency>
-            <groupId>org.apache.karaf.features</groupId>
-            <artifactId>org.apache.karaf.features.core</artifactId>
-        </dependency>
-
-        <dependency>
-            <groupId>org.eclipse.equinox</groupId>
-            <artifactId>region</artifactId>
-            <version>1.0.0.v20110506</version>
-        </dependency>
-
-        <dependency>
-            <groupId>org.apache.karaf.shell</groupId>
-            <artifactId>org.apache.karaf.shell.core</artifactId>
-            <optional>true</optional>
-        </dependency>
-        <dependency>
-            <groupId>org.apache.aries</groupId>
-            <artifactId>org.apache.aries.util</artifactId>
-        </dependency>
-
-        <dependency>
-            <groupId>org.easymock</groupId>
-            <artifactId>easymock</artifactId>
-            <scope>test</scope>
-        </dependency>
-		<dependency>
-            <groupId>org.slf4j</groupId>
-            <artifactId>slf4j-jdk14</artifactId>
-            <scope>test</scope>
-        </dependency>
-    </dependencies>
-
-    <build>
-        <resources>
-            <resource>
-                <directory>${project.basedir}/src/main/resources</directory>
-                <includes>
-                    <include>**/*</include>
-                </includes>
-            </resource>
-            <resource>
-                <directory>${project.basedir}/src/main/resources</directory>
-                <filtering>true</filtering>
-                <includes>
-                    <include>**/*.info</include>
-                </includes>
-            </resource>
-        </resources>
-        <plugins>
-            <plugin>
-                <groupId>org.apache.felix</groupId>
-                <artifactId>maven-bundle-plugin</artifactId>
-                <configuration>
-                    <instructions>
-                        <Bundle-Activator>
-                            org.apache.karaf.region.persist.internal.Activator
-                        </Bundle-Activator>
-                        <Private-Package>
-                            org.apache.karaf.region.commands,
-                            org.apache.karaf.region.commands.util,
-                            org.apache.karaf.region.persist.internal.*,
-                            org.apache.karaf.util.tracker
-                        </Private-Package>
-                        <Karaf-Commands>*</Karaf-Commands>
-                    </instructions>
-                </configuration>
-            </plugin>
-        </plugins>
-    </build>
-
-</project>

http://git-wip-us.apache.org/repos/asf/karaf/blob/2705ad88/region/src/main/java/org/apache/karaf/region/commands/AddBundleCommand.java
----------------------------------------------------------------------
diff --git a/region/src/main/java/org/apache/karaf/region/commands/AddBundleCommand.java b/region/src/main/java/org/apache/karaf/region/commands/AddBundleCommand.java
deleted file mode 100644
index 30af1e0..0000000
--- a/region/src/main/java/org/apache/karaf/region/commands/AddBundleCommand.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.karaf.region.commands;
-
-import java.util.List;
-
-import org.apache.karaf.shell.api.action.Argument;
-import org.apache.karaf.shell.api.action.Command;
-import org.apache.karaf.shell.api.action.lifecycle.Service;
-import org.eclipse.equinox.region.Region;
-import org.eclipse.equinox.region.RegionDigraph;
-import org.osgi.framework.Bundle;
-
-@Command(scope = "region", name = "bundle-add", description = "Adds a list of known bundles by id to a specified region.")
-@Service
-public class AddBundleCommand extends RegionCommandSupport {
-
-    @Argument(index = 0, name = "region", description = "Region to add the bundles to", required = true, multiValued = false)
-    String region;
-
-    @Argument(index = 1, name = "bundles", description = "Bundles by id to add to the region", required = true, multiValued = true)
-    List<Long> ids;
-
-    protected void doExecute(RegionDigraph regionDigraph) throws Exception {
-        Region r = getRegion(regionDigraph, region);
-        for (Long id : ids) {
-            for (Region existing: regionDigraph.getRegions()) {
-                if (existing.contains(id)) {
-                    Bundle b = bundleContext.getBundle(id);
-                    System.out.println("Removing bundle " + id + " from region " + existing.getName());
-                    existing.removeBundle(b);
-                    break;
-                }
-            }
-            r.addBundle(id);
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/karaf/blob/2705ad88/region/src/main/java/org/apache/karaf/region/commands/AddFilterCommand.java
----------------------------------------------------------------------
diff --git a/region/src/main/java/org/apache/karaf/region/commands/AddFilterCommand.java b/region/src/main/java/org/apache/karaf/region/commands/AddFilterCommand.java
deleted file mode 100644
index ec3766d..0000000
--- a/region/src/main/java/org/apache/karaf/region/commands/AddFilterCommand.java
+++ /dev/null
@@ -1,169 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.karaf.region.commands;
-
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import org.apache.aries.util.VersionRange;
-import org.apache.aries.util.manifest.ManifestHeaderProcessor;
-import org.apache.karaf.shell.api.action.Argument;
-import org.apache.karaf.shell.api.action.Command;
-import org.apache.karaf.shell.api.action.lifecycle.Service;
-import org.eclipse.equinox.region.Region;
-import org.eclipse.equinox.region.RegionDigraph;
-import org.eclipse.equinox.region.RegionFilter;
-import org.eclipse.equinox.region.RegionFilterBuilder;
-import org.osgi.framework.Bundle;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.Constants;
-
-@Command(scope = "region", name = "filter-add", description = "Adds a filter between two regions.")
-@Service
-public class AddFilterCommand extends RegionCommandSupport {
-
-    @Argument(index = 0, name = "from", description = "The from region.", required = true, multiValued = false)
-    String fromRegion;
-
-    @Argument(index = 1, name = "to", description = "The to region.", required = true, multiValued = false)
-    String toRegion;
-
-    @Argument(index = 2, name = "items", description = "The bundles by id and packages with version to allow.", required = false, multiValued = true)
-    List<String> items;
-
-    protected void doExecute(RegionDigraph regionDigraph) throws Exception {
-        Region rFrom = getRegion(regionDigraph, fromRegion);
-        Region rTo = getRegion(regionDigraph, toRegion);
-        RegionFilterBuilder builder = regionDigraph.createRegionFilterBuilder();
-        BundleContext framework = bundleContext.getBundle(0).getBundleContext();
-        if (items != null) {
-            for (String item : items) {
-                try {
-                    long id = Long.parseLong(item);
-                    Bundle b = framework.getBundle(id);
-                    builder.allow("osgi.wiring.bundle", "(osgi.wiring.bundle=" + b.getSymbolicName() + ")");
-                } catch (NumberFormatException e) {
-                    for (Map.Entry<String, Map<String, String>> parsed: ManifestHeaderProcessor.parseImportString(item).entrySet()) {
-                        String packageName = parsed.getKey();
-                        Map<String, String> attributes = new HashMap<String, String>(parsed.getValue());
-                        attributes.put("osgi.wiring.package", packageName);
-                        String filter = generateFilter(attributes);
-                        System.out.println("adding filter " + filter);
-                        builder.allow("osgi.wiring.package", filter);
-                    }
-                }
-
-            }
-        }
-        RegionFilter f = builder.build();
-        regionDigraph.connect(rFrom, f, rTo);
-    }
-
-    //from aries util, with obr specific weirdness removed
-    public static String generateFilter(Map<String, String> attribs) {
-        StringBuilder filter = new StringBuilder("(&");
-        boolean realAttrib = false;
-        StringBuffer realAttribs = new StringBuffer();
-
-        if (attribs == null) {
-            attribs = new HashMap<String, String>();
-        }
-
-        for (Map.Entry<String, String> attrib : attribs.entrySet()) {
-            String attribName = attrib.getKey();
-
-            if (attribName.endsWith(":")) {
-                // skip all directives. It is used to affect the attribs on the
-                // filter xml.
-            } else if ((Constants.VERSION_ATTRIBUTE.equals(attribName))
-                    || (Constants.BUNDLE_VERSION_ATTRIBUTE.equals(attribName))) {
-                // version and bundle-version attrib requires special
-                // conversion.
-                realAttrib = true;
-
-                VersionRange vr = ManifestHeaderProcessor
-                        .parseVersionRange(attrib.getValue());
-
-                filter.append("(" + attribName + ">=" + vr.getMinimumVersion());
-
-                if (vr.getMaximumVersion() != null) {
-                    filter.append(")(" + attribName + "<=");
-                    filter.append(vr.getMaximumVersion());
-                }
-
-                if (vr.getMaximumVersion() != null && vr.isMinimumExclusive()) {
-                    filter.append(")(!(" + attribName + "=");
-                    filter.append(vr.getMinimumVersion());
-                    filter.append(")");
-                }
-
-                if (vr.getMaximumVersion() != null && vr.isMaximumExclusive()) {
-                    filter.append(")(!(" + attribName + "=");
-                    filter.append(vr.getMaximumVersion());
-                    filter.append(")");
-                }
-                filter.append(")");
-
-            } else if (Constants.OBJECTCLASS.equals(attribName)) {
-                realAttrib = true;
-                // objectClass has a "," separated list of interfaces
-                String[] values = attrib.getValue().split(",");
-                for (String s : values)
-                    filter.append("(" + Constants.OBJECTCLASS + "=" + s + ")");
-
-            } else {
-                // attribName was not version..
-                realAttrib = true;
-
-                filter.append("(" + attribName + "=" + attrib.getValue() + ")");
-                // store all attributes in order to build up the mandatory
-                // filter and separate them with ", "
-                // skip bundle-symbolic-name in the mandatory directive query
-                if (!!!Constants.BUNDLE_SYMBOLICNAME_ATTRIBUTE
-                        .equals(attribName)) {
-                    realAttribs.append(attribName);
-                    realAttribs.append(", ");
-                }
-            }
-        }
-
-        // Prune (& off the front and ) off end
-        String filterString = filter.toString();
-        int openBraces = 0;
-        for (int i = 0; openBraces < 3; i++) {
-            i = filterString.indexOf('(', i);
-            if (i == -1) {
-                break;
-            } else {
-                openBraces++;
-            }
-        }
-        if (openBraces < 3 && filterString.length() > 2) {
-            filter.delete(0, 2);
-        } else {
-            filter.append(")");
-        }
-
-        String result = "";
-        if (realAttrib != false) {
-            result = filter.toString();
-        }
-        return result;
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/karaf/blob/2705ad88/region/src/main/java/org/apache/karaf/region/commands/AddRegionCommand.java
----------------------------------------------------------------------
diff --git a/region/src/main/java/org/apache/karaf/region/commands/AddRegionCommand.java b/region/src/main/java/org/apache/karaf/region/commands/AddRegionCommand.java
deleted file mode 100644
index 22c817b..0000000
--- a/region/src/main/java/org/apache/karaf/region/commands/AddRegionCommand.java
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.karaf.region.commands;
-
-import java.util.List;
-
-import org.apache.karaf.shell.api.action.Argument;
-import org.apache.karaf.shell.api.action.Command;
-import org.apache.karaf.shell.api.action.lifecycle.Service;
-import org.eclipse.equinox.region.RegionDigraph;
-
-@Command(scope = "region", name = "region-add", description = "Adds a list of regions to the region digraph service.")
-@Service
-public class AddRegionCommand extends RegionCommandSupport {
-
-    @Argument(index = 0, name = "name", description = "Regions to add to the region digraph service separated by whitespaces.", required = true, multiValued = true)
-    List<String> regions;
-
-    protected void doExecute(RegionDigraph regionDigraph) throws Exception {
-        for (String region : regions) {
-            regionDigraph.createRegion(region);
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/karaf/blob/2705ad88/region/src/main/java/org/apache/karaf/region/commands/InfoCommand.java
----------------------------------------------------------------------
diff --git a/region/src/main/java/org/apache/karaf/region/commands/InfoCommand.java b/region/src/main/java/org/apache/karaf/region/commands/InfoCommand.java
deleted file mode 100644
index 7c71e36..0000000
--- a/region/src/main/java/org/apache/karaf/region/commands/InfoCommand.java
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.karaf.region.commands;
-
-import java.util.Collection;
-import java.util.List;
-import java.util.Map;
-
-import org.apache.karaf.shell.api.action.Argument;
-import org.apache.karaf.shell.api.action.Command;
-import org.apache.karaf.shell.api.action.Option;
-import org.apache.karaf.shell.api.action.lifecycle.Service;
-import org.eclipse.equinox.region.Region;
-import org.eclipse.equinox.region.RegionDigraph;
-import org.eclipse.equinox.region.RegionFilter;
-import org.osgi.framework.Bundle;
-
-@Command(scope = "region", name = "info", description = "Prints information about region digraph.")
-@Service
-public class InfoCommand extends RegionCommandSupport {
-
-    @Option(name = "-v", aliases = "--verbose", required = false, description = "Show all info.")
-    boolean verbose;
-
-    @Option(name = "-b", aliases = "--bundles", required = false, description = "Show bundles in each region.")
-    boolean bundles;
-
-    @Option(name = "-f", aliases = "--filters", required = false, description = "Show filters.")
-    boolean filters;
-
-    @Option(name = "-n", aliases = "--namespaces", required = false, description = "Show namespaces in each filter.")
-    boolean namespaces;
-
-    @Argument(index = 0, name = "regions", description = "Regions to provide detailed info for.", required = false, multiValued = true)
-    List<String> regions;
-
-    protected void doExecute(RegionDigraph regionDigraph) throws Exception {
-        System.out.println("Regions");
-        if (regions == null) {
-            for (Region region : regionDigraph.getRegions()) {
-                showRegion(region);
-            }
-        } else {
-            bundles = true;
-            filters = true;
-            namespaces = true;
-            for (String regionName : regions) {
-                Region region = regionDigraph.getRegion(regionName);
-                if (region == null) {
-                    System.out.println("No region " + regionName);
-                } else {
-                    showRegion(region);
-                }
-            }
-        }
-    }
-
-    private void showRegion(Region region) {
-        System.out.println(region.getName());
-        if (verbose || bundles) {
-            for (Long id : region.getBundleIds()) {
-                Bundle b = bundleContext.getBundle(id);
-                System.out.println("  " + id + "  " + getStateString(b) + b);
-            }
-        }
-        if (verbose || filters || namespaces) {
-            for (RegionDigraph.FilteredRegion f : region.getEdges()) {
-                System.out.println("  filter to " + f.getRegion().getName());
-                if (verbose || namespaces) {
-                    RegionFilter rf = f.getFilter();
-                    for (Map.Entry<String, Collection<String>> policy : rf.getSharingPolicy().entrySet()) {
-                        String namespace = policy.getKey();
-                        System.out.println("  namespace: " + namespace);
-                        for (String e : policy.getValue()) {
-                            System.out.println("    " + e);
-                        }
-                    }
-                }
-            }
-        }
-    }
-
-    public String getStateString(Bundle bundle) {
-        if (bundle == null) {
-            return "Bundle null";
-        }
-        int state = bundle.getState();
-        if (state == Bundle.ACTIVE) {
-            return "Active     ";
-        } else if (state == Bundle.INSTALLED) {
-            return "Installed  ";
-        } else if (state == Bundle.RESOLVED) {
-            return "Resolved   ";
-        } else if (state == Bundle.STARTING) {
-            return "Starting   ";
-        } else if (state == Bundle.STOPPING) {
-            return "Stopping   ";
-        } else {
-            return "Unknown    ";
-        }
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/karaf/blob/2705ad88/region/src/main/java/org/apache/karaf/region/commands/RegionCommandSupport.java
----------------------------------------------------------------------
diff --git a/region/src/main/java/org/apache/karaf/region/commands/RegionCommandSupport.java b/region/src/main/java/org/apache/karaf/region/commands/RegionCommandSupport.java
deleted file mode 100644
index bcdfb6c..0000000
--- a/region/src/main/java/org/apache/karaf/region/commands/RegionCommandSupport.java
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.karaf.region.commands;
-
-import java.io.PrintStream;
-
-import org.apache.karaf.shell.api.action.Action;
-import org.apache.karaf.shell.api.action.lifecycle.Reference;
-import org.eclipse.equinox.region.Region;
-import org.eclipse.equinox.region.RegionDigraph;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.BundleException;
-import org.osgi.framework.ServiceReference;
-
-public abstract class RegionCommandSupport implements Action {
-
-    protected static final char VERSION_DELIM = ',';
-
-    @Reference
-    BundleContext bundleContext;
-
-    @Override
-    public Object execute() throws Exception {
-        // Get repository instance service.
-        ServiceReference ref = bundleContext.getServiceReference(RegionDigraph.class.getName());
-        if (ref == null) {
-            System.out.println("RegionDigraph service is unavailable.");
-            return null;
-        }
-        try {
-            RegionDigraph admin = (RegionDigraph) bundleContext.getService(ref);
-            if (admin == null) {
-                System.out.println("RegionDigraph service is unavailable.");
-                return null;
-            }
-
-            doExecute(admin);
-        }
-        finally {
-            bundleContext.ungetService(ref);
-        }
-        return null;
-    }
-
-    abstract void doExecute(RegionDigraph admin) throws Exception;
-
-    protected void printUnderline(PrintStream out, int length)
-    {
-        for (int i = 0; i < length; i++)
-        {
-            out.print('-');
-        }
-        out.println("");
-    }
-
-
-    protected Region getRegion(RegionDigraph regionDigraph, String region) throws BundleException {
-        Region r = regionDigraph.getRegion(region);
-        if (r == null) {
-            System.out.println("No region: " + region + ", creating it");
-            r = regionDigraph.createRegion(region);
-        }
-        return r;
-    }
-}

http://git-wip-us.apache.org/repos/asf/karaf/blob/2705ad88/region/src/main/java/org/apache/karaf/region/commands/util/FileUtil.java
----------------------------------------------------------------------
diff --git a/region/src/main/java/org/apache/karaf/region/commands/util/FileUtil.java b/region/src/main/java/org/apache/karaf/region/commands/util/FileUtil.java
deleted file mode 100644
index 07c39e9..0000000
--- a/region/src/main/java/org/apache/karaf/region/commands/util/FileUtil.java
+++ /dev/null
@@ -1,177 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.karaf.region.commands.util;
-
-import java.io.BufferedOutputStream;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.io.PrintStream;
-import java.net.URL;
-import java.net.URLConnection;
-import java.util.jar.JarEntry;
-import java.util.jar.JarInputStream;
-
-public class FileUtil
-{
-    public static void downloadSource(
-        PrintStream out, PrintStream err,
-        URL srcURL, String dirStr, boolean extract)
-    {
-        // Get the file name from the URL.
-        String fileName = (srcURL.getFile().lastIndexOf('/') > 0)
-            ? srcURL.getFile().substring(srcURL.getFile().lastIndexOf('/') + 1)
-            : srcURL.getFile();
-
-        try
-        {
-            out.println("Connecting...");
-
-            File dir = new File(dirStr);
-            if (!dir.exists())
-            {
-                err.println("Destination directory does not exist.");
-            }
-            File file = new File(dir, fileName);
-
-            OutputStream os = new FileOutputStream(file);
-            URLConnection conn = srcURL.openConnection();
-            int total = conn.getContentLength();
-            InputStream is = conn.getInputStream();
-
-            if (total > 0)
-            {
-                out.println("Downloading " + fileName
-                    + " ( " + total + " bytes ).");
-            }
-            else
-            {
-                out.println("Downloading " + fileName + ".");
-            }
-            byte[] buffer = new byte[4096];
-            int count = 0;
-            for (int len = is.read(buffer); len > 0; len = is.read(buffer))
-            {
-                count += len;
-                os.write(buffer, 0, len);
-            }
-
-            os.close();
-            is.close();
-
-            if (extract)
-            {
-                is = new FileInputStream(file);
-                JarInputStream jis = new JarInputStream(is);
-                out.println("Extracting...");
-                unjar(jis, dir);
-                jis.close();
-                file.delete();
-            }
-        }
-        catch (Exception ex)
-        {
-            err.println(ex);
-        }
-    }
-
-    public static void unjar(JarInputStream jis, File dir)
-        throws IOException
-    {
-        // Reusable buffer.
-        byte[] buffer = new byte[4096];
-
-        // Loop through JAR entries.
-        for (JarEntry je = jis.getNextJarEntry();
-             je != null;
-             je = jis.getNextJarEntry())
-        {
-            if (je.getName().startsWith("/"))
-            {
-                throw new IOException("JAR resource cannot contain absolute paths.");
-            }
-
-            File target = new File(dir, je.getName());
-
-            // Check to see if the JAR entry is a directory.
-            if (je.isDirectory())
-            {
-                if (!target.exists())
-                {
-                    if (!target.mkdirs())
-                    {
-                        throw new IOException("Unable to create target directory: "
-                            + target);
-                    }
-                }
-                // Just continue since directories do not have content to copy.
-                continue;
-            }
-
-            int lastIndex = je.getName().lastIndexOf('/');
-            String name = (lastIndex >= 0) ?
-                je.getName().substring(lastIndex + 1) : je.getName();
-            String destination = (lastIndex >= 0) ?
-                je.getName().substring(0, lastIndex) : "";
-
-            // JAR files use '/', so convert it to platform separator.
-            destination = destination.replace('/', File.separatorChar);
-            copy(jis, dir, name, destination, buffer);
-        }
-    }
-
-    public static void copy(
-        InputStream is, File dir, String destName, String destDir, byte[] buffer)
-        throws IOException
-    {
-        if (destDir == null)
-        {
-            destDir = "";
-        }
-
-        // Make sure the target directory exists and
-        // that is actually a directory.
-        File targetDir = new File(dir, destDir);
-        if (!targetDir.exists())
-        {
-            if (!targetDir.mkdirs())
-            {
-                throw new IOException("Unable to create target directory: "
-                    + targetDir);
-            }
-        }
-        else if (!targetDir.isDirectory())
-        {
-            throw new IOException("Target is not a directory: "
-                + targetDir);
-        }
-
-        BufferedOutputStream bos = new BufferedOutputStream(
-            new FileOutputStream(new File(targetDir, destName)));
-        int count = 0;
-        while ((count = is.read(buffer)) > 0)
-        {
-            bos.write(buffer, 0, count);
-        }
-        bos.close();
-    }
-}

http://git-wip-us.apache.org/repos/asf/karaf/blob/2705ad88/region/src/main/java/org/apache/karaf/region/persist/internal/Activator.java
----------------------------------------------------------------------
diff --git a/region/src/main/java/org/apache/karaf/region/persist/internal/Activator.java b/region/src/main/java/org/apache/karaf/region/persist/internal/Activator.java
deleted file mode 100644
index aa7215f..0000000
--- a/region/src/main/java/org/apache/karaf/region/persist/internal/Activator.java
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *  http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-
-package org.apache.karaf.region.persist.internal;
-
-import java.util.concurrent.atomic.AtomicReference;
-
-import org.apache.karaf.features.RegionsPersistence;
-import org.apache.karaf.util.tracker.SingleServiceTracker;
-import org.eclipse.equinox.region.RegionDigraph;
-import org.osgi.framework.Bundle;
-import org.osgi.framework.BundleActivator;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.ServiceRegistration;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class Activator implements BundleActivator {
-
-    private static final Logger log = LoggerFactory.getLogger(Activator.class);
-
-    private SingleServiceTracker<RegionDigraph> tracker;
-    private final AtomicReference<RegionsPersistenceImpl> persistence = new AtomicReference<RegionsPersistenceImpl>();
-    private final AtomicReference<RegionsBundleTracker> bundleTracker = new AtomicReference<RegionsBundleTracker>();
-    private ServiceRegistration<RegionsPersistence> reg;
-
-    @Override
-    public void start(final BundleContext bundleContext) throws Exception {
-        tracker = new SingleServiceTracker<RegionDigraph>(bundleContext, RegionDigraph.class, new SingleServiceTracker.SingleServiceListener() {
-            public void serviceFound() {
-                log.debug("Found RegionDigraph service, initializing");
-                RegionDigraph regionDigraph = tracker.getService();
-                Bundle framework = bundleContext.getBundle(0);
-                RegionsPersistenceImpl persistence = null;
-                try {
-                    persistence = new RegionsPersistenceImpl(regionDigraph, framework);
-                    reg = bundleContext.registerService(RegionsPersistence.class, persistence, null);
-
-                    RegionsBundleTracker bundleTracker = new RegionsBundleTracker();
-                    bundleTracker.start(bundleContext, persistence);
-                    Activator.this.bundleTracker.set(bundleTracker);
-                } catch (Exception e) {
-                    log.info("Could not create RegionsPersistenceImpl", e);
-                }
-                Activator.this.persistence.set(persistence);
-            }
-
-            public void serviceLost() {
-                if (reg != null) {
-                    reg.unregister();
-                    reg = null;
-                }
-                Activator.this.persistence.set(null);
-                Activator.this.bundleTracker.set(null);
-            }
-
-            public void serviceReplaced() {
-                //??
-            }
-        });
-        tracker.open();
-    }
-
-    @Override
-    public void stop(BundleContext bundleContext) throws Exception {
-        tracker.close();
-        persistence.set(null);
-        RegionsBundleTracker tracker = bundleTracker.getAndSet(null);
-        if (tracker != null) {
-            tracker.stop();
-        }
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/karaf/blob/2705ad88/region/src/main/java/org/apache/karaf/region/persist/internal/RegionsBundleTracker.java
----------------------------------------------------------------------
diff --git a/region/src/main/java/org/apache/karaf/region/persist/internal/RegionsBundleTracker.java b/region/src/main/java/org/apache/karaf/region/persist/internal/RegionsBundleTracker.java
deleted file mode 100644
index 7035303..0000000
--- a/region/src/main/java/org/apache/karaf/region/persist/internal/RegionsBundleTracker.java
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *  http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-
-package org.apache.karaf.region.persist.internal;
-
-import org.apache.karaf.features.RegionsPersistence;
-import org.osgi.framework.Bundle;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.BundleEvent;
-import org.osgi.framework.BundleException;
-import org.osgi.util.tracker.BundleTracker;
-import org.osgi.util.tracker.BundleTrackerCustomizer;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class RegionsBundleTracker {
-    private static final Logger log = LoggerFactory.getLogger(RegionsBundleTracker.class);
-
-    private BundleTracker bundleTracker;
-    private RegionsPersistence regionsPersistence;
-
-    void start(BundleContext bundleContext, RegionsPersistence regionsPersistence) {
-        this.regionsPersistence = regionsPersistence;
-        int stateMask = Bundle.INSTALLED;
-        bundleTracker = new BundleTracker<Bundle>(bundleContext, stateMask, new BundleTrackerCustomizer<Bundle>() {
-            @Override
-            public Bundle addingBundle(Bundle bundle, BundleEvent bundleEvent) {
-                return RegionsBundleTracker.this.addingBundle(bundle);
-            }
-
-            @Override
-            public void modifiedBundle(Bundle bundle, BundleEvent bundleEvent, Bundle o) {
-            }
-
-            @Override
-            public void removedBundle(Bundle bundle, BundleEvent bundleEvent, Bundle o) {
-            }
-        });
-        bundleTracker.open();
-    }
-
-    private Bundle addingBundle(Bundle bundle) {
-        String region = bundle.getHeaders().get("Region");
-        if (region != null) {
-            try {
-                regionsPersistence.install(bundle, region);
-                log.debug("Installed bundle " + bundle + " in region " + region);
-                return bundle;
-            } catch (BundleException e) {
-                log.info("Could not install bundle " + bundle + " in region " + region, e);
-            }
-        }
-        return null;
-    }
-
-    void stop() {
-        bundleTracker.close();
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/karaf/blob/2705ad88/region/src/main/java/org/apache/karaf/region/persist/internal/RegionsPersistenceImpl.java
----------------------------------------------------------------------
diff --git a/region/src/main/java/org/apache/karaf/region/persist/internal/RegionsPersistenceImpl.java b/region/src/main/java/org/apache/karaf/region/persist/internal/RegionsPersistenceImpl.java
deleted file mode 100644
index dcf5d26..0000000
--- a/region/src/main/java/org/apache/karaf/region/persist/internal/RegionsPersistenceImpl.java
+++ /dev/null
@@ -1,203 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *  http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.karaf.region.persist.internal;
-
-import java.io.File;
-import java.io.FileReader;
-import java.io.IOException;
-import java.io.Reader;
-import java.io.Writer;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import javax.xml.bind.JAXBContext;
-import javax.xml.bind.JAXBException;
-import javax.xml.bind.Marshaller;
-import javax.xml.bind.Unmarshaller;
-
-import org.apache.karaf.features.RegionsPersistence;
-import org.apache.karaf.region.persist.internal.model.FilterAttributeType;
-import org.apache.karaf.region.persist.internal.model.FilterBundleType;
-import org.apache.karaf.region.persist.internal.model.FilterNamespaceType;
-import org.apache.karaf.region.persist.internal.model.FilterPackageType;
-import org.apache.karaf.region.persist.internal.model.FilterType;
-import org.apache.karaf.region.persist.internal.model.RegionBundleType;
-import org.apache.karaf.region.persist.internal.model.RegionType;
-import org.apache.karaf.region.persist.internal.model.RegionsType;
-import org.apache.karaf.region.persist.internal.util.ManifestHeaderProcessor;
-import org.eclipse.equinox.region.Region;
-import org.eclipse.equinox.region.RegionDigraph;
-import org.eclipse.equinox.region.RegionFilterBuilder;
-import org.osgi.framework.Bundle;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.BundleException;
-import org.osgi.framework.InvalidSyntaxException;
-import org.osgi.framework.wiring.BundleCapability;
-import org.osgi.framework.wiring.BundleRevision;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class RegionsPersistenceImpl implements RegionsPersistence {
-
-    private static final Logger log = LoggerFactory.getLogger(RegionsPersistenceImpl.class);
-
-    private JAXBContext jaxbContext;
-    private RegionDigraph regionDigraph;
-    private Region kernel;
-    private Bundle framework;
-
-    public RegionsPersistenceImpl(RegionDigraph regionDigraph, Bundle framework) throws JAXBException, BundleException, IOException, InvalidSyntaxException {
-        log.info("Loading region digraph persistence");
-        this.framework = framework;
-        this.regionDigraph = regionDigraph;
-        kernel = regionDigraph.getRegion(0);
-        jaxbContext = JAXBContext.newInstance(RegionsType.class);
-        load();
-    }
-
-    @Override
-    public void install(Bundle b, String regionName) throws BundleException {
-        Region region = regionDigraph.getRegion(regionName);
-        if (region == null) {
-            region = regionDigraph.createRegion(regionName);
-        }
-        kernel.removeBundle(b);
-        region.addBundle(b);
-    }
-
-    void save(RegionsType regionsType, Writer out) throws JAXBException {
-        Marshaller marshaller = jaxbContext.createMarshaller();
-        marshaller.marshal(regionsType, out);
-    }
-
-    void load() throws IOException, BundleException, JAXBException, InvalidSyntaxException {
-        if (this.regionDigraph.getRegions().size() <= 1) {
-            File etc = new File(System.getProperty("karaf.etc"));
-            File regionsConfig = new File(etc, "regions-config.xml");
-            if (regionsConfig.exists()) {
-                log.info("initializing region digraph from etc/regions-config.xml");
-                Reader in = new FileReader(regionsConfig);
-                try {
-                        load(this.regionDigraph, in);
-                    } finally {
-                        in.close();
-                    }
-            } else {
-                log.info("no regions config file");
-            }
-        }
-
-    }
-
-    void  load(RegionDigraph regionDigraph, Reader in) throws JAXBException, BundleException, InvalidSyntaxException {
-        RegionsType regionsType = load(in);
-        load(regionsType, regionDigraph);
-    }
-
-    RegionsType load(Reader in) throws JAXBException {
-        Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
-        return (RegionsType) unmarshaller.unmarshal(in);
-    }
-
-    void load(RegionsType regionsType, RegionDigraph regionDigraph) throws BundleException, InvalidSyntaxException {
-        BundleContext frameworkContext = framework.getBundleContext();
-        for (RegionType regionType: regionsType.getRegion()) {
-            String name = regionType.getName();
-            log.debug("Creating region: " + name);
-            Region region = regionDigraph.createRegion(name);
-            for (RegionBundleType bundleType: regionType.getBundle()) {
-                if (bundleType.getId() != null) {
-                    region.addBundle(bundleType.getId());
-                } else {
-                    Bundle b = frameworkContext.getBundle(bundleType.getLocation());
-                    region.addBundle(b);
-                }
-            }
-        }
-        for (FilterType filterType: regionsType.getFilter()) {
-            Region from = regionDigraph.getRegion(filterType.getFrom());
-            Region to = regionDigraph.getRegion(filterType.getTo());
-            log.debug("Creating filter between " + from.getName() + " to " + to.getName());
-            RegionFilterBuilder builder = regionDigraph.createRegionFilterBuilder();
-            for (FilterBundleType bundleType: filterType.getBundle()) {
-                String symbolicName = bundleType.getSymbolicName();
-                String version = bundleType.getVersion();
-                if (bundleType.getId() != null) {
-                    Bundle b = frameworkContext.getBundle(bundleType.getId());
-                    symbolicName = b.getSymbolicName();
-                    version = b.getVersion().toString();
-                }
-                String namespace = BundleRevision.BUNDLE_NAMESPACE;
-                List<FilterAttributeType> attributeTypes = bundleType.getAttribute();
-                buildFilter(symbolicName, version, namespace, attributeTypes, builder);
-            }
-            for (FilterPackageType packageType: filterType.getPackage()) {
-                String packageName = packageType.getName();
-                String version = packageType.getVersion();
-                String namespace = BundleRevision.PACKAGE_NAMESPACE;
-                List<FilterAttributeType> attributeTypes = packageType.getAttribute();
-                buildFilter(packageName, version, namespace, attributeTypes, builder);
-            }
-            if (to == kernel) {
-                //add framework exports
-                BundleRevision rev = framework.adapt(BundleRevision.class);
-                List<BundleCapability> caps = rev.getDeclaredCapabilities(BundleRevision.PACKAGE_NAMESPACE);
-                for (BundleCapability cap : caps) {
-                    String filter = ManifestHeaderProcessor.generateFilter(filter(cap.getAttributes()));
-                    builder.allow(BundleRevision.PACKAGE_NAMESPACE, filter);
-                }
-            }
-            //TODO explicit services?
-            for (FilterNamespaceType namespaceType: filterType.getNamespace()) {
-                String namespace = namespaceType.getName();
-                HashMap<String, Object> attributes = new HashMap<String, Object>();
-                for (FilterAttributeType attributeType: namespaceType.getAttribute()) {
-                    attributes.put(attributeType.getName(), attributeType.getValue());
-                }
-                String filter = ManifestHeaderProcessor.generateFilter(attributes);
-                builder.allow(namespace, filter);
-            }
-            regionDigraph.connect(from, builder.build(), to);
-        }
-    }
-
-    private Map<String, Object> filter(Map<String, Object> attributes) {
-        Map<String, Object> result = new HashMap<String, Object>(attributes);
-        result.remove("bundle-version");
-        result.remove("bundle-symbolic-name");
-        return result;
-    }
-
-    private void buildFilter(String packageName, String version, String namespace, List<FilterAttributeType> attributeTypes, RegionFilterBuilder builder) throws InvalidSyntaxException {
-        HashMap<String, Object> attributes = new HashMap<String, Object>();
-        if (namespace != null) {
-            attributes.put(namespace, packageName);
-        }
-        if (version != null) {
-            attributes.put("version", version);
-        }
-        for (FilterAttributeType attributeType: attributeTypes) {
-            attributes.put(attributeType.getName(), attributeType.getValue());
-        }
-        String filter = ManifestHeaderProcessor.generateFilter(attributes);
-        builder.allow(namespace, filter);
-    }
-
-}