+1

@Christian: can you revert quickly ? Thanks !

Regards
JB

On 05/09/2017 10:14 AM, Guillaume Nodet wrote:
The feature is completely broken as the {{BundleWires#wiring}} map is never
modified.
Please revert and try with a again correct fix ;-)

2017-02-06 16:00 GMT+01:00 <[email protected]>:

Repository: karaf
Updated Branches:
  refs/heads/master d2f944057 -> 9ce324f57


[KARAF-4973] Refactoring of features extension


Project: http://git-wip-us.apache.org/repos/asf/karaf/repo
Commit: http://git-wip-us.apache.org/repos/asf/karaf/commit/9ce324f5
Tree: http://git-wip-us.apache.org/repos/asf/karaf/tree/9ce324f5
Diff: http://git-wip-us.apache.org/repos/asf/karaf/diff/9ce324f5

Branch: refs/heads/master
Commit: 9ce324f577d427d501558740b440f264eb6e2d27
Parents: d2f9440
Author: Christian Schneider <[email protected]>
Authored: Wed Feb 1 15:07:42 2017 +0100
Committer: Christian Schneider <[email protected]>
Committed: Mon Feb 6 15:44:34 2017 +0100

----------------------------------------------------------------------
 .../karaf/features/extension/Activator.java     | 214 +++----------------
 .../karaf/features/extension/BundleWires.java   | 140 ++++++++++++
 .../extension/StoredWiringResolver.java         | 112 ++++++++++
 3 files changed, 284 insertions(+), 182 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/karaf/blob/9ce324f5/
features/extension/src/main/java/org/apache/karaf/
features/extension/Activator.java
----------------------------------------------------------------------
diff --git a/features/extension/src/main/java/org/apache/karaf/
features/extension/Activator.java b/features/extension/src/main/
java/org/apache/karaf/features/extension/Activator.java
index f0be0e8..19e2769 100644
--- a/features/extension/src/main/java/org/apache/karaf/
features/extension/Activator.java
+++ b/features/extension/src/main/java/org/apache/karaf/
features/extension/Activator.java
@@ -16,35 +16,25 @@
  */
 package org.apache.karaf.features.extension;

-import org.osgi.framework.*;
-import org.osgi.framework.hooks.resolver.ResolverHook;
-import org.osgi.framework.hooks.resolver.ResolverHookFactory;
-import org.osgi.framework.namespace.HostNamespace;
-import org.osgi.framework.namespace.IdentityNamespace;
-import org.osgi.framework.wiring.*;
-import org.osgi.resource.Capability;
-import org.osgi.resource.Namespace;
-import org.osgi.resource.Requirement;
-import org.osgi.resource.Resource;
-
-import java.io.*;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.nio.file.StandardOpenOption;
-import java.util.*;
-import java.util.stream.Collectors;
+import java.util.Arrays;

-public class Activator implements BundleActivator, ResolverHook,
SynchronousBundleListener, ResolverHookFactory {
+import org.osgi.framework.BundleActivator;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.BundleEvent;
+import org.osgi.framework.ServiceRegistration;
+import org.osgi.framework.SynchronousBundleListener;
+import org.osgi.framework.hooks.resolver.ResolverHookFactory;
+import org.osgi.framework.wiring.FrameworkWiring;

+public class Activator implements BundleActivator,
SynchronousBundleListener {
     private static final String WIRING_PATH = "wiring";
-
-    private final Map<Long, Map<String, String>> wiring = new HashMap<>();
-    private BundleContext bundleContext;
+       private StoredWiringResolver resolver;
+       private BundleContext context;

     @Override
     public void start(BundleContext context) throws Exception {
-        this.bundleContext = context;
-        load();
+       this.context = context;
+        resolver = new StoredWiringResolver(context.
getDataFile(WIRING_PATH).toPath());
         context.addBundleListener(this);
     }

@@ -53,163 +43,23 @@ public class Activator implements BundleActivator,
ResolverHook, SynchronousBund
         context.removeBundleListener(this);
     }

-    @Override
-    public void bundleChanged(BundleEvent event) {
-        if (event.getBundle().getBundleId() == 0 && event.getType() ==
BundleEvent.STARTED) {
-            ServiceRegistration<ResolverHookFactory> registration =
bundleContext.registerService(ResolverHookFactory.class, this, null);
-            try {
-                List<Bundle> bundles = wiring.keySet().stream()
-                        .map(id -> bundleContext.getBundle(id))
-                        .collect(Collectors.toList());
-                bundleContext.getBundle().adapt(FrameworkWiring.class)
-                        .resolveBundles(bundles);
-            } finally {
-                registration.unregister();
-            }
-        } else if (event.getType() == BundleEvent.RESOLVED ||
event.getType() == BundleEvent.UNRESOLVED) {
-            synchronized (wiring) {
-                long id = event.getBundle().getBundleId();
-                if (event.getType() == BundleEvent.RESOLVED) {
-                    Map<String, String> bw = new HashMap<>();
-                    for (BundleWire wire : event.getBundle().adapt(
BundleWiring.class).getRequiredWires(null)) {
-                        bw.put(getRequirementId(wire.getRequirement()),
getCapabilityId(wire.getCapability()));
-                    }
-                    wiring.put(id, bw);
-                    saveWiring(id, bw);
-                } else {
-                    wiring.remove(id);
-                    saveWiring(id, null);
-                }
-            }
-        }
-    }
-
-    @Override
-    public void filterResolvable(Collection<BundleRevision> candidates) {
-    }
-
-    @Override
-    public void filterSingletonCollisions(BundleCapability singleton,
Collection<BundleCapability> collisionCandidates) {
-    }
-
-    @Override
-    public void filterMatches(BundleRequirement requirement,
Collection<BundleCapability> candidates) {
-        long sourceId = requirement.getRevision().
getBundle().getBundleId();
-        if (isFragment(requirement.getRevision())
-                && 
!requirement.getNamespace().equals(HostNamespace.HOST_NAMESPACE))
{
-            sourceId = wiring.get(sourceId).entrySet().stream()
-                    .filter(e -> e.getKey().startsWith(
HostNamespace.HOST_NAMESPACE))
-                    .map(Map.Entry::getValue)
-                    .mapToLong(s -> {
-                        int idx = s.indexOf(';');
-                        if (idx > 0) {
-                            s = s.substring(0, idx);
-                        }
-                        return Long.parseLong(s.trim());
-                    })
-                    .findFirst()
-                    .orElse(-1);
-        }
-        Map<String, String> bw = wiring.get(sourceId);
-        String cap = bw.get(getRequirementId(requirement));
-        for (Iterator<BundleCapability> candIter = candidates.iterator();
candIter.hasNext();) {
-            BundleCapability cand = candIter.next();
-            if (cap != null && !cap.equals(getCapabilityId(cand))
-                    || cap == null && 
cand.getRevision().getBundle().getBundleId()
!= sourceId) {
-                candIter.remove();
-            }
-        }
-    }
-
-    @Override
-    public void end() {
-    }
-
-    @Override
-    public ResolverHook begin(Collection<BundleRevision> triggers) {
-        return this;
-    }
-
-    private void load() {
-        try {
-            Path dir = bundleContext.getDataFile(WIRING_PATH).toPath();
-            Files.createDirectories(dir);
-            Files.list(dir).forEach(p -> {
-                String name = p.getFileName().toString();
-                if (name.matches("[0-9]+")) {
-                    try (BufferedReader reader =
Files.newBufferedReader(p)) {
-                        long id = Long.parseLong(name);
-                        Map<String, String> map = new HashMap<>();
-                        while (true) {
-                            String key = reader.readLine();
-                            String val = reader.readLine();
-                            if (key != null && val != null) {
-                                map.put(key, val);
-                            } else {
-                                break;
-                            }
-                        }
-                        wiring.put(id, map);
-                    } catch (IOException e) {
-                        throw new UncheckedIOException(e);
-                    }
-                }
-            });
-        } catch (IOException e) {
-            throw new UncheckedIOException(e);
-        }
-    }
-
-    private void saveWiring(long id, Map<String, String> wiring) {
-        try {
-            Path dir = bundleContext.getDataFile(WIRING_PATH).toPath();
-            Files.createDirectories(dir);
-            Path file = dir.resolve(Long.toString(id));
-            if (wiring != null) {
-                Files.createDirectories(file.getParent());
-                try (BufferedWriter fw = Files.newBufferedWriter(file,
-                        StandardOpenOption.TRUNCATE_EXISTING,
-                        StandardOpenOption.WRITE,
-                        StandardOpenOption.CREATE)) {
-                    for (Map.Entry<String, String> wire :
wiring.entrySet()) {
-                        fw.append(wire.getKey()).append('\n');
-                        fw.append(wire.getValue()).append('\n');
-                    }
-                }
-            } else {
-                Files.deleteIfExists(file);
-            }
-        } catch (IOException e) {
-            throw new UncheckedIOException(e);
-        }
-    }
-
-    private String getRequirementId(Requirement requirement) {
-        String filter = requirement.getDirectives().
get(Namespace.REQUIREMENT_FILTER_DIRECTIVE);
-        if (filter != null) {
-            return requirement.getNamespace() + "; " + filter;
-        } else {
-            return requirement.getNamespace();
-        }
-    }
-
-    private String getCapabilityId(BundleCapability capability) {
-        StringBuilder sb = new StringBuilder(64);
-        sb.append(capability.getRevision().getBundle().getBundleId());
-        Object v = capability.getAttributes().get(Constants.VERSION_
ATTRIBUTE);
-        if (v != null) {
-            sb.append("; version=").append(v.toString());
-        }
-        return sb.toString();
-    }
-
-    private static boolean isFragment(Resource resource) {
-        for (Capability cap : resource.getCapabilities(null)) {
-            if 
(IdentityNamespace.IDENTITY_NAMESPACE.equals(cap.getNamespace()))
{
-                return IdentityNamespace.TYPE_FRAGMENT.equals(
-                        cap.getAttributes().get(
IdentityNamespace.CAPABILITY_TYPE_ATTRIBUTE));
-            }
-        }
-        return false;
-    }
+       @Override
+       public void bundleChanged(BundleEvent event) {
+               if (event.getBundle().getBundleId() == 0 &&
event.getType() == BundleEvent.STARTED) {
+                       resolveAll();
+               } else if (event.getType() == BundleEvent.RESOLVED) {
+                       resolver.update(event.getBundle());
+               } else if (event.getType() == BundleEvent.UNRESOLVED) {
+                       resolver.delete(event.getBundle());
+               }
+       }
+
+       private void resolveAll() {
+               ServiceRegistration<ResolverHookFactory> registration =
context.registerService(ResolverHookFactory.class, (triggers) ->
resolver, null);
+               try {
+                   context.getBundle().adapt(FrameworkWiring.class).
resolveBundles(Arrays.asList(context.getBundles()));
+               } finally {
+                   registration.unregister();
+               }
+       }
 }

http://git-wip-us.apache.org/repos/asf/karaf/blob/9ce324f5/
features/extension/src/main/java/org/apache/karaf/features/extension/
BundleWires.java
----------------------------------------------------------------------
diff --git a/features/extension/src/main/java/org/apache/karaf/
features/extension/BundleWires.java b/features/extension/src/main/
java/org/apache/karaf/features/extension/BundleWires.java
new file mode 100644
index 0000000..48b289a
--- /dev/null
+++ b/features/extension/src/main/java/org/apache/karaf/
features/extension/BundleWires.java
@@ -0,0 +1,140 @@
+/*
+ * 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.extension;
+
+import static java.nio.file.StandardOpenOption.CREATE;
+import static java.nio.file.StandardOpenOption.TRUNCATE_EXISTING;
+import static java.nio.file.StandardOpenOption.WRITE;
+
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.IOException;
+import java.io.UncheckedIOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+import org.osgi.framework.Bundle;
+import org.osgi.framework.Constants;
+import org.osgi.framework.namespace.HostNamespace;
+import org.osgi.framework.wiring.BundleCapability;
+import org.osgi.framework.wiring.BundleRequirement;
+import org.osgi.framework.wiring.BundleWire;
+import org.osgi.framework.wiring.BundleWiring;
+import org.osgi.resource.Namespace;
+import org.osgi.resource.Requirement;
+
+class BundleWires {
+       long bundleId;
+       Map<String, String> wiring;
+
+       BundleWires(Bundle bundle) {
+               this.bundleId = bundle.getBundleId();
+               this.wiring = new HashMap<>();
+        Map<String, String> bw = new HashMap<>();
+        for (BundleWire wire : 
bundle.adapt(BundleWiring.class).getRequiredWires(null))
{
+            bw.put(getRequirementId(wire.getRequirement()),
getCapabilityId(wire.getCapability()));
+        }
+       }
+
+       BundleWires(BufferedReader reader) throws IOException {
+               Map<String, String> map = new HashMap<>();
+               while (true) {
+                       String key = reader.readLine();
+                       String val = reader.readLine();
+                       if (key != null && val != null) {
+                               map.put(key, val);
+                       } else {
+                               break;
+                       }
+               }
+       }
+
+       void save(Path path) {
+               try {
+                       Files.createDirectories(path);
+                       Path file = path.resolve(Long.toString(
this.bundleId));
+                       Files.createDirectories(file.getParent());
+                       try (BufferedWriter fw =
Files.newBufferedWriter(file, TRUNCATE_EXISTING, WRITE, CREATE)) {
+                               for (Map.Entry<String, String> wire :
wiring.entrySet()) {
+                                       fw.append(wire.getKey()).
append('\n');
+                                       fw.append(wire.getValue()).
append('\n');
+                               }
+                       }
+               } catch (IOException e) {
+                       throw new UncheckedIOException(e);
+               }
+       }
+
+       void delete(Path path) {
+               try {
+                       Files.createDirectories(path);
+                       Path file = path.resolve(Long.toString(
this.bundleId));
+                       Files.deleteIfExists(file);
+               } catch (IOException e) {
+                       throw new UncheckedIOException(e);
+               }
+       }
+
+       long getFragmentHost() {
+               return wiring.entrySet().stream()
+        .filter(e -> e.getKey().startsWith(HostNamespace.HOST_NAMESPACE))
+        .map(Map.Entry::getValue)
+        .mapToLong(s -> {
+            int idx = s.indexOf(';');
+            if (idx > 0) {
+                s = s.substring(0, idx);
+            }
+            return Long.parseLong(s.trim());
+        })
+        .findFirst()
+        .orElse(-1);
+       }
+
+       void filterMatches(BundleRequirement requirement,
Collection<BundleCapability> candidates) {
+        String cap = wiring.get(getRequirementId(requirement));
+        for (Iterator<BundleCapability> candIter = candidates.iterator();
candIter.hasNext();) {
+            BundleCapability cand = candIter.next();
+            if (cap != null && !cap.equals(getCapabilityId(cand))
+                       || cap == null && 
cand.getRevision().getBundle().getBundleId()
!= this.bundleId) {
+                candIter.remove();
+            }
+        }
+       }
+
+       private String getRequirementId(Requirement requirement) {
+        String filter = requirement.getDirectives().
get(Namespace.REQUIREMENT_FILTER_DIRECTIVE);
+        if (filter != null) {
+            return requirement.getNamespace() + "; " + filter;
+        } else {
+            return requirement.getNamespace();
+        }
+    }
+
+    private String getCapabilityId(BundleCapability capability) {
+        StringBuilder sb = new StringBuilder(64);
+        sb.append(capability.getRevision().getBundle().getBundleId());
+        Object v = capability.getAttributes().get(Constants.VERSION_
ATTRIBUTE);
+        if (v != null) {
+            sb.append("; version=").append(v.toString());
+        }
+        return sb.toString();
+    }
+}

http://git-wip-us.apache.org/repos/asf/karaf/blob/9ce324f5/
features/extension/src/main/java/org/apache/karaf/features/extension/
StoredWiringResolver.java
----------------------------------------------------------------------
diff --git a/features/extension/src/main/java/org/apache/karaf/
features/extension/StoredWiringResolver.java
b/features/extension/src/main/java/org/apache/karaf/features/extension/
StoredWiringResolver.java
new file mode 100644
index 0000000..3ebd8b4
--- /dev/null
+++ b/features/extension/src/main/java/org/apache/karaf/
features/extension/StoredWiringResolver.java
@@ -0,0 +1,112 @@
+/*
+ * 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.extension;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.UncheckedIOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.osgi.framework.Bundle;
+import org.osgi.framework.hooks.resolver.ResolverHook;
+import org.osgi.framework.namespace.HostNamespace;
+import org.osgi.framework.namespace.IdentityNamespace;
+import org.osgi.framework.wiring.BundleCapability;
+import org.osgi.framework.wiring.BundleRequirement;
+import org.osgi.framework.wiring.BundleRevision;
+import org.osgi.resource.Capability;
+import org.osgi.resource.Resource;
+
+class StoredWiringResolver implements ResolverHook {
+    private final Map<Long, BundleWires> wiring = new HashMap<>();
+       private Path path;
+
+    StoredWiringResolver(Path path) {
+       this.path = path;
+       load();
+       }
+
+       void load() {
+        try {
+            Files.createDirectories(path);
+            Files.list(path).forEach(p -> {
+                String name = p.getFileName().toString();
+                if (name.matches("[0-9]+")) {
+                    try (BufferedReader reader =
Files.newBufferedReader(p)) {
+                       long id = Long.parseLong(name);
+                        wiring.put(id, new BundleWires(reader));
+                    } catch (IOException e) {
+                        throw new UncheckedIOException(e);
+                    }
+                }
+            });
+        } catch (IOException e) {
+            throw new UncheckedIOException(e);
+        }
+    }
+
+    @Override
+    public void filterResolvable(Collection<BundleRevision> candidates) {
+    }
+
+    @Override
+    public void filterSingletonCollisions(BundleCapability singleton,
Collection<BundleCapability> collisionCandidates) {
+    }
+
+    @Override
+    public void filterMatches(BundleRequirement requirement,
Collection<BundleCapability> candidates) {
+        long sourceId = getBundleId(requirement);
+        wiring.get(sourceId).filterMatches(requirement, candidates);
+    }
+
+    @Override
+    public void end() {
+    }
+
+       private long getBundleId(BundleRequirement requirement) {
+               long sourceId = requirement.getRevision().
getBundle().getBundleId();
+        if (isFragment(requirement.getRevision())
+                && 
!requirement.getNamespace().equals(HostNamespace.HOST_NAMESPACE))
{
+            sourceId = wiring.get(sourceId).getFragmentHost();
+        }
+               return sourceId;
+       }
+
+    private static boolean isFragment(Resource resource) {
+        for (Capability cap : resource.getCapabilities(null)) {
+            if 
(IdentityNamespace.IDENTITY_NAMESPACE.equals(cap.getNamespace()))
{
+                return IdentityNamespace.TYPE_FRAGMENT.equals(
+                        cap.getAttributes().get(
IdentityNamespace.CAPABILITY_TYPE_ATTRIBUTE));
+            }
+        }
+        return false;
+    }
+
+       synchronized void update(Bundle bundle) {
+               BundleWires bw = new BundleWires(bundle);
+               bw.save(path);
+               wiring.put(bundle.getBundleId(), bw);
+       }
+
+       synchronized void delete(Bundle bundle) {
+               wiring.get(bundle.getBundleId()).delete(path);
+       }
+}





--
Jean-Baptiste Onofré
[email protected]
http://blog.nanthrax.net
Talend - http://www.talend.com

Reply via email to