karaf-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Guillaume Nodet <gno...@apache.org>
Subject Re: karaf git commit: [KARAF-4973] Refactoring of features extension
Date Tue, 09 May 2017 08:14:03 GMT
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 <cschneider@apache.org>:

> 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 <chris@die-schneider.net>
> Authored: Wed Feb 1 15:07:42 2017 +0100
> Committer: Christian Schneider <chris@die-schneider.net>
> 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);
> +       }
> +}
>
>


-- 
------------------------
Guillaume Nodet

Mime
  • Unnamed multipart/alternative (inline, None, 0 bytes)
View raw message