Author: pauls
Date: Fri Mar 16 13:44:36 2018
New Revision: 1826988

URL: http://svn.apache.org/viewvc?rev=1826988&view=rev
Log:
FELIX-5797: Allow extension bundles to have imports and handle them like 
fragments would be handled (as required by the R7 spec). Furthermore, fix some 
bugs in the extension bundle support while we go along.

Modified:
    
felix/trunk/osgi-r7/framework/src/main/java/org/apache/felix/framework/BundleImpl.java
    
felix/trunk/osgi-r7/framework/src/main/java/org/apache/felix/framework/BundleRevisionImpl.java
    
felix/trunk/osgi-r7/framework/src/main/java/org/apache/felix/framework/BundleWiringImpl.java
    
felix/trunk/osgi-r7/framework/src/main/java/org/apache/felix/framework/ExtensionManager.java
    
felix/trunk/osgi-r7/framework/src/main/java/org/apache/felix/framework/Felix.java
    
felix/trunk/osgi-r7/framework/src/main/java/org/apache/felix/framework/util/manifestparser/ManifestParser.java

Modified: 
felix/trunk/osgi-r7/framework/src/main/java/org/apache/felix/framework/BundleImpl.java
URL: 
http://svn.apache.org/viewvc/felix/trunk/osgi-r7/framework/src/main/java/org/apache/felix/framework/BundleImpl.java?rev=1826988&r1=1826987&r2=1826988&view=diff
==============================================================================
--- 
felix/trunk/osgi-r7/framework/src/main/java/org/apache/felix/framework/BundleImpl.java
 (original)
+++ 
felix/trunk/osgi-r7/framework/src/main/java/org/apache/felix/framework/BundleImpl.java
 Fri Mar 16 13:44:36 2018
@@ -1228,14 +1228,11 @@ class BundleImpl implements Bundle, Bund
 
     synchronized boolean rollbackRevise() throws Exception
     {
-        boolean isExtension = isExtension();
         BundleRevision br = m_revisions.remove(0);
-        if (!isExtension)
-        {
-            // Since revising a bundle adds a revision to the global
-            // state, we must remove it from the global state on rollback.
-            getFramework().getResolver().removeRevision(br);
-        }
+        // Since revising a bundle adds a revision to the global
+        // state, we must remove it from the global state on rollback.
+        getFramework().getResolver().removeRevision(br);
+
         return m_archive.rollbackRevise();
     }
 
@@ -1257,14 +1254,9 @@ class BundleImpl implements Bundle, Bund
             throw ex;
         }
 
-        // TODO: REFACTOR - consider nulling capabilities for extension bundles
-        // so we don't need this check anymore.
-        if (!isExtension())
-        {
-            // Now that the revision is added to the bundle, we can update
-            // the resolver's state to be aware of any new capabilities.
-            getFramework().getResolver().addRevision(revision);
-        }
+        /// Now that the revision is added to the bundle, we can update
+        // the resolver's state to be aware of any new capabilities.
+        getFramework().getResolver().addRevision(revision);
     }
 
     private BundleRevisionImpl createRevision(boolean isUpdate) throws 
Exception

Modified: 
felix/trunk/osgi-r7/framework/src/main/java/org/apache/felix/framework/BundleRevisionImpl.java
URL: 
http://svn.apache.org/viewvc/felix/trunk/osgi-r7/framework/src/main/java/org/apache/felix/framework/BundleRevisionImpl.java?rev=1826988&r1=1826987&r2=1826988&view=diff
==============================================================================
--- 
felix/trunk/osgi-r7/framework/src/main/java/org/apache/felix/framework/BundleRevisionImpl.java
 (original)
+++ 
felix/trunk/osgi-r7/framework/src/main/java/org/apache/felix/framework/BundleRevisionImpl.java
 Fri Mar 16 13:44:36 2018
@@ -62,6 +62,7 @@ public class BundleRevisionImpl implemen
     private final Version m_version;
 
     private final List<BundleCapability> m_declaredCaps;
+    private final List<BundleCapability> m_declaredExtensionCaps;
     private final List<BundleRequirement> m_declaredReqs;
     private final List<NativeLibrary> m_declaredNativeLibs;
     private final int m_declaredActivationPolicy;
@@ -97,6 +98,7 @@ public class BundleRevisionImpl implemen
         m_isFragment = false;
         m_version = null;
         m_declaredCaps = Collections.emptyList();
+        m_declaredExtensionCaps = Collections.emptyList();
         m_declaredReqs = Collections.emptyList();
         m_declaredNativeLibs = null;
         m_declaredActivationPolicy = EAGER_ACTIVATION;
@@ -122,9 +124,13 @@ public class BundleRevisionImpl implemen
         // Record some of the parsed metadata. Note, if this is an extension
         // bundle it's exports are removed, since they will be added to the
         // system bundle directly later on.
+
+        m_isExtension = mp.isExtension();
         m_manifestVersion = mp.getManifestVersion();
         m_version = mp.getBundleVersion();
         m_declaredCaps = mp.getCapabilities();
+        m_declaredExtensionCaps = m_isExtension ? 
ManifestParser.aliasSymbolicName(mp.getExtensionCapabilites(),
+            bundle.getFramework().adapt(BundleRevisionImpl.class)) : 
Collections.EMPTY_LIST;
         m_declaredReqs = mp.getRequirements();
         m_declaredNativeLibs = mp.getLibraries();
         m_declaredActivationPolicy = mp.getActivationPolicy();
@@ -135,7 +141,6 @@ public class BundleRevisionImpl implemen
             ? null
             : 
ManifestParser.parseDelimitedString(mp.getActivationIncludeDirective(), ",");
         m_symbolicName = mp.getSymbolicName();
-        m_isExtension = mp.isExtension();
         m_isFragment = m_headerMap.containsKey(Constants.FRAGMENT_HOST);
     }
 
@@ -212,6 +217,23 @@ public class BundleRevisionImpl implemen
             {
                 if (cap.getNamespace().equals(namespace))
                 {
+                    result.add(cap);
+                }
+            }
+        }
+        return result;
+    }
+
+    public List<BundleCapability> getDeclaredExtensionCapabilities(String 
namespace)
+    {
+        List<BundleCapability> result = m_declaredExtensionCaps;
+        if (namespace != null)
+        {
+            result = new ArrayList<BundleCapability>();
+            for (BundleCapability cap : m_declaredExtensionCaps)
+            {
+                if (cap.getNamespace().equals(namespace))
+                {
                     result.add(cap);
                 }
             }

Modified: 
felix/trunk/osgi-r7/framework/src/main/java/org/apache/felix/framework/BundleWiringImpl.java
URL: 
http://svn.apache.org/viewvc/felix/trunk/osgi-r7/framework/src/main/java/org/apache/felix/framework/BundleWiringImpl.java?rev=1826988&r1=1826987&r2=1826988&view=diff
==============================================================================
--- 
felix/trunk/osgi-r7/framework/src/main/java/org/apache/felix/framework/BundleWiringImpl.java
 (original)
+++ 
felix/trunk/osgi-r7/framework/src/main/java/org/apache/felix/framework/BundleWiringImpl.java
 Fri Mar 16 13:44:36 2018
@@ -174,13 +174,12 @@ public class BundleWiringImpl implements
     private volatile ConcurrentHashMap<String, ClassLoader> 
m_accessorLookupCache;
 
     BundleWiringImpl(
-            Logger logger, Map configMap, StatefulResolver resolver,
-            BundleRevisionImpl revision, List<BundleRevision> fragments,
-            List<BundleWire> wires,
-            Map<String, BundleRevision> importedPkgs,
-            Map<String, List<BundleRevision>> requiredPkgs)
-                    throws Exception
-                    {
+        Logger logger, Map configMap, StatefulResolver resolver,
+        BundleRevisionImpl revision, List<BundleRevision> fragments,
+        List<BundleWire> wires,
+        Map<String, BundleRevision> importedPkgs,
+        Map<String, List<BundleRevision>> requiredPkgs) throws Exception
+    {
         m_logger = logger;
         m_configMap = configMap;
         m_resolver = resolver;
@@ -423,52 +422,50 @@ public class BundleWiringImpl implements
         List<NativeLibrary> libList = (m_revision.getDeclaredNativeLibraries() 
== null)
                 ? new ArrayList<NativeLibrary>()
                         : new 
ArrayList<NativeLibrary>(m_revision.getDeclaredNativeLibraries());
-                for (int fragIdx = 0;
-                        (m_fragments != null) && (fragIdx < 
m_fragments.size());
-                        fragIdx++)
-                {
-                    List<NativeLibrary> libs =
-                            ((BundleRevisionImpl) m_fragments.get(fragIdx))
-                            .getDeclaredNativeLibraries();
-                    for (int reqIdx = 0;
-                            (libs != null) && (reqIdx < libs.size());
-                            reqIdx++)
-                    {
-                        libList.add(libs.get(reqIdx));
-                    }
-                }
-                // We need to return null here if we don't have any libraries, 
since a
-                // zero-length array is used to indicate that matching native 
libraries
-                // could not be found when resolving the bundle.
-                m_resolvedNativeLibs = (libList.isEmpty())
-                        ? null
-                                : ImmutableList.newInstance(libList);
+        for (int fragIdx = 0;
+                (m_fragments != null) && (fragIdx < m_fragments.size());
+                fragIdx++)
+        {
+            List<NativeLibrary> libs =
+                    ((BundleRevisionImpl) m_fragments.get(fragIdx))
+                    .getDeclaredNativeLibraries();
+            for (int reqIdx = 0;
+                    (libs != null) && (reqIdx < libs.size());
+                    reqIdx++)
+            {
+                libList.add(libs.get(reqIdx));
+            }
+        }
+        // We need to return null here if we don't have any libraries, since a
+        // zero-length array is used to indicate that matching native libraries
+        // could not be found when resolving the bundle.
+        m_resolvedNativeLibs = (libList.isEmpty()) ? null : 
ImmutableList.newInstance(libList);
 
-                ClassLoader bootLoader = m_defBootClassLoader;
-                if (revision.getBundle().getBundleId() != 0)
+        ClassLoader bootLoader = m_defBootClassLoader;
+        if (revision.getBundle().getBundleId() != 0)
+        {
+            Object map = 
m_configMap.get(FelixConstants.BOOT_CLASSLOADERS_PROP);
+            if (map instanceof Map)
+            {
+                Object l = ((Map) map).get(m_revision.getBundle());
+                if (l instanceof ClassLoader)
                 {
-                    Object map = 
m_configMap.get(FelixConstants.BOOT_CLASSLOADERS_PROP);
-                    if (map instanceof Map)
-                    {
-                        Object l = ((Map) map).get(m_revision.getBundle());
-                        if (l instanceof ClassLoader)
-                        {
-                            bootLoader = (ClassLoader) l;
-                        }
-                    }
+                    bootLoader = (ClassLoader) l;
                 }
-                m_bootClassLoader = bootLoader;
+            }
+        }
+        m_bootClassLoader = bootLoader;
 
-                m_implicitBootDelegation =
-                        
(m_configMap.get(FelixConstants.IMPLICIT_BOOT_DELEGATION_PROP) == null)
-                        || Boolean.valueOf(
-                                (String) m_configMap.get(
-                                        
FelixConstants.IMPLICIT_BOOT_DELEGATION_PROP)).booleanValue();
-
-                m_useLocalURLs =
-                        (m_configMap.get(FelixConstants.USE_LOCALURLS_PROP) == 
null)
-                        ? false : true;
-                    }
+        m_implicitBootDelegation =
+            (m_configMap.get(FelixConstants.IMPLICIT_BOOT_DELEGATION_PROP) == 
null)
+            || Boolean.valueOf(
+                    (String) m_configMap.get(
+                            
FelixConstants.IMPLICIT_BOOT_DELEGATION_PROP)).booleanValue();
+
+        m_useLocalURLs =
+                (m_configMap.get(FelixConstants.USE_LOCALURLS_PROP) == null)
+                ? false : true;
+    }
 
     private static List<List<String>> parsePkgFilters(BundleCapability cap, 
String filtername)
     {
@@ -672,18 +669,22 @@ public class BundleWiringImpl implements
         // Make new wires list.
         List<BundleWire> wires = new ArrayList<BundleWire>(m_wires);
         wires.add(wire);
-        // Make new imported package map.
-        Map<String, BundleRevision> importedPkgs =
-                new HashMap<String, BundleRevision>(m_importedPkgs);
-        importedPkgs.put(
-                (String) 
wire.getCapability().getAttributes().get(BundleRevision.PACKAGE_NAMESPACE),
-                wire.getProviderWiring().getRevision());
+        if 
(wire.getCapability().getAttributes().get(BundleRevision.PACKAGE_NAMESPACE) != 
null)
+        {
+            // Make new imported package map.
+            Map<String, BundleRevision> importedPkgs =
+                    new HashMap<String, BundleRevision>(m_importedPkgs);
+            importedPkgs.put(
+                    (String) 
wire.getCapability().getAttributes().get(BundleRevision.PACKAGE_NAMESPACE),
+                    wire.getProviderWiring().getRevision());
+
+            m_importedPkgs = importedPkgs;
+        }
         // Update associated member values.
         // Technically, there is a window here where readers won't see
         // both values updates at the same time, but it seems unlikely
         // to cause any issues.
         m_wires = ImmutableList.newInstance(wires);
-        m_importedPkgs = importedPkgs;
     }
 
     @Override

Modified: 
felix/trunk/osgi-r7/framework/src/main/java/org/apache/felix/framework/ExtensionManager.java
URL: 
http://svn.apache.org/viewvc/felix/trunk/osgi-r7/framework/src/main/java/org/apache/felix/framework/ExtensionManager.java?rev=1826988&r1=1826987&r2=1826988&view=diff
==============================================================================
--- 
felix/trunk/osgi-r7/framework/src/main/java/org/apache/felix/framework/ExtensionManager.java
 (original)
+++ 
felix/trunk/osgi-r7/framework/src/main/java/org/apache/felix/framework/ExtensionManager.java
 Fri Mar 16 13:44:36 2018
@@ -30,6 +30,7 @@ import org.apache.felix.framework.util.m
 import org.apache.felix.framework.util.manifestparser.NativeLibrary;
 import org.apache.felix.framework.util.manifestparser.NativeLibraryClause;
 import org.apache.felix.framework.wiring.BundleCapabilityImpl;
+import org.apache.felix.framework.wiring.BundleRequirementImpl;
 import org.apache.felix.framework.wiring.BundleWireImpl;
 import org.osgi.framework.AdminPermission;
 import org.osgi.framework.Bundle;
@@ -39,6 +40,7 @@ import org.osgi.framework.BundleExceptio
 import org.osgi.framework.Constants;
 import org.osgi.framework.FrameworkEvent;
 import org.osgi.framework.Version;
+import org.osgi.framework.namespace.ExecutionEnvironmentNamespace;
 import org.osgi.framework.namespace.NativeNamespace;
 import org.osgi.framework.wiring.BundleCapability;
 import org.osgi.framework.wiring.BundleRequirement;
@@ -59,6 +61,7 @@ import java.util.Enumeration;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Iterator;
+import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Map.Entry;
@@ -66,6 +69,7 @@ import java.util.NoSuchElementException;
 import java.util.Properties;
 import java.util.ServiceLoader;
 import java.util.Set;
+import java.util.concurrent.CopyOnWriteArrayList;
 
 /**
  * The ExtensionManager class is used in several ways.
@@ -162,12 +166,16 @@ class ExtensionManager implements Conten
     private final Logger m_logger;
     private final Map m_configMap;
     private final Map m_headerMap = new StringMap();
+    private final Map m_originalHeaderMap = new StringMap();
     private final BundleRevisionImpl m_systemBundleRevision;
     private volatile List<BundleCapability> m_capabilities = 
Collections.EMPTY_LIST;
     private volatile Set<String> m_exportNames = Collections.EMPTY_SET;
     private volatile Object m_securityContext = null;
     private final List<ExtensionTuple> m_extensionTuples = 
Collections.synchronizedList(new ArrayList<ExtensionTuple>());
 
+    private final List<BundleRevisionImpl> m_resolvedExtensions = new 
CopyOnWriteArrayList<BundleRevisionImpl>();
+    private final List<BundleRevisionImpl> m_unresolvedExtensions = new 
CopyOnWriteArrayList<BundleRevisionImpl>();
+
     private static class ExtensionTuple
     {
         private final BundleActivator m_activator;
@@ -256,11 +264,12 @@ class ExtensionManager implements Conten
         syscaps = ((capextra == null) || (capextra.trim().length() == 0))
             ? syscaps : syscaps + (capextra.trim().startsWith(",") ? capextra 
: "," + capextra);
         m_headerMap.put(FelixConstants.PROVIDE_CAPABILITY, syscaps);
+        m_originalHeaderMap.putAll(m_headerMap);
         try
         {
             ManifestParser mp = new ManifestParser(
                 m_logger, m_configMap, m_systemBundleRevision, m_headerMap);
-            List<BundleCapability> caps = 
aliasSymbolicName(mp.getCapabilities());
+            List<BundleCapability> caps = 
ManifestParser.aliasSymbolicName(mp.getCapabilities(), m_systemBundleRevision);
             caps.add(buildNativeCapabilites());
             appendCapabilities(caps);
         }
@@ -307,83 +316,11 @@ class ExtensionManager implements Conten
         return new BundleCapabilityImpl(getRevision(), 
NativeNamespace.NATIVE_NAMESPACE, Collections.<String, String> emptyMap(), 
attributes);
     }
 
-    private static List<BundleCapability> 
aliasSymbolicName(List<BundleCapability> caps)
-    {
-        if (caps == null)
-        {
-            return new ArrayList<BundleCapability>(0);
-        }
-
-        List<BundleCapability> aliasCaps = new 
ArrayList<BundleCapability>(caps);
-
-        String[] aliases = {
-            FelixConstants.SYSTEM_BUNDLE_SYMBOLICNAME,
-            Constants.SYSTEM_BUNDLE_SYMBOLICNAME };
-
-        for (int capIdx = 0; capIdx < aliasCaps.size(); capIdx++)
-        {
-            BundleCapability cap = aliasCaps.get(capIdx);
-
-            // Need to alias bundle and host capabilities.
-            if (cap.getNamespace().equals(BundleRevision.BUNDLE_NAMESPACE)
-                || cap.getNamespace().equals(BundleRevision.HOST_NAMESPACE))
-            {
-                // Make a copy of the attribute array.
-                Map<String, Object> aliasAttrs =
-                    new HashMap<String, Object>(cap.getAttributes());
-                // Add the aliased value.
-                aliasAttrs.put(cap.getNamespace(), aliases);
-                // Create the aliased capability to replace the old capability.
-                cap = new BundleCapabilityImpl(
-                    cap.getRevision(),
-                    cap.getNamespace(),
-                    cap.getDirectives(),
-                    aliasAttrs);
-                aliasCaps.set(capIdx, cap);
-            }
-
-            // Further, search attributes for bundle symbolic name and alias 
it too.
-            for (Entry<String, Object> entry : cap.getAttributes().entrySet())
-            {
-                // If there is a bundle symbolic name attribute, add the
-                // standard alias as a value.
-                if 
(entry.getKey().equalsIgnoreCase(Constants.BUNDLE_SYMBOLICNAME_ATTRIBUTE))
-                {
-                    // Make a copy of the attribute array.
-                    Map<String, Object> aliasAttrs =
-                        new HashMap<String, Object>(cap.getAttributes());
-                    // Add the aliased value.
-                    aliasAttrs.put(Constants.BUNDLE_SYMBOLICNAME_ATTRIBUTE, 
aliases);
-                    // Create the aliased capability to replace the old 
capability.
-                    aliasCaps.set(capIdx, new BundleCapabilityImpl(
-                        cap.getRevision(),
-                        cap.getNamespace(),
-                        cap.getDirectives(),
-                        aliasAttrs));
-                    // Continue with the next capability.
-                    break;
-                }
-            }
-        }
-
-        return aliasCaps;
-    }
-
     public BundleRevisionImpl getRevision()
     {
         return m_systemBundleRevision;
     }
 
-    public Object getSecurityContext()
-    {
-        return m_securityContext;
-    }
-
-    public synchronized void setSecurityContext(Object securityContext)
-    {
-        m_securityContext = securityContext;
-    }
-
     /**
      * Add an extension bundle. The bundle will be added to the parent 
classloader
      * and it's exported packages will be added to the module definition
@@ -398,8 +335,7 @@ class ExtensionManager implements Conten
      *          AdminPermission.EXTENSIONLIFECYCLE and security is enabled.
      * @throws Exception in case something goes wrong.
      */
-    synchronized void addExtensionBundle(Felix felix, BundleImpl bundle)
-        throws SecurityException, BundleException, Exception
+    synchronized void addExtensionBundle(Felix felix, BundleImpl bundle) 
throws Exception
     {
         Object sm = System.getSecurityManager();
         if (sm != null)
@@ -419,29 +355,20 @@ class ExtensionManager implements Conten
 
         final ClassPathExtenderFactory.ClassPathExtender extender;
 
-        if (m_extenderBoot != null && 
Constants.EXTENSION_BOOTCLASSPATH.equals(directive))
-        {
-            extender = m_extenderBoot;
-        }
-        // We only support classpath extensions (not bootclasspath).
-        else if (!Constants.EXTENSION_FRAMEWORK.equals(directive))
+        if (!Constants.EXTENSION_FRAMEWORK.equals(directive))
         {
            throw new BundleException("Unsupported Extension Bundle type: " +
-                    directive, new UnsupportedOperationException(
-                    "Unsupported Extension Bundle type!"));
+                directive, new UnsupportedOperationException(
+                "Unsupported Extension Bundle type!"));
         }
         else if (m_extenderFramework == null)
         {
             // We don't support extensions
             m_logger.log(bundle, Logger.LOG_WARNING,
-                    "Unable to add extension bundle - Maybe ClassLoader is not 
supported (on java9, try 
--add-opens=java.base/jdk.internal.loader=ALL-UNNAMED)?");
+                "Unable to add extension bundle - Maybe ClassLoader is not 
supported (on java9, try 
--add-opens=java.base/jdk.internal.loader=ALL-UNNAMED)?");
 
             throw new UnsupportedOperationException(
-                    "Unable to add extension bundle.");
-        }
-        else
-        {
-            extender = m_extenderFramework;
+                "Unable to add extension bundle.");
         }
 
         Content content = bundle.adapt(BundleRevisionImpl.class).getContent();
@@ -467,73 +394,153 @@ class ExtensionManager implements Conten
             throw new UnsupportedOperationException(
                     "Unable to add extension bundle.");
         }
+
+        BundleRevisionImpl bri = bundle.adapt(BundleRevisionImpl.class);
+
+        bri.resolve(null);
+
+        m_unresolvedExtensions.add(bri);
+    }
+
+    public void removeExtensionBundles(Felix felix)
+    {
+        m_resolvedExtensions.clear();
+        m_unresolvedExtensions.clear();
+        m_headerMap.clear();
+        m_headerMap.putAll(m_originalHeaderMap);
         try
         {
-            // Merge the exported packages with the exported packages of the 
systembundle.
-            List<BundleCapability> exports = null;
-            if (Constants.EXTENSION_FRAMEWORK.equals(directive))
-            {
-                try
+            ManifestParser mp = new ManifestParser(
+                    m_logger, m_configMap, m_systemBundleRevision, 
m_headerMap);
+            List<BundleCapability> caps = 
ManifestParser.aliasSymbolicName(mp.getCapabilities(), m_systemBundleRevision);
+            caps.add(buildNativeCapabilites());
+            appendCapabilities(caps);
+        }
+        catch (Exception ex)
+        {
+            m_capabilities = Collections.EMPTY_LIST;
+            m_logger.log(
+                    Logger.LOG_ERROR,
+                    "Error parsing system bundle export statement", ex);
+        }
+    }
+
+    public List<Bundle> resolveExtensionBundles(Felix felix)
+    {
+        if (m_unresolvedExtensions.isEmpty())
+        {
+            return Collections.emptyList();
+        }
+
+        // Collect all resolved extensions and the highest version of 
unresolved that are not already resolved bsn
+        List<BundleRevisionImpl> extensions = new 
ArrayList<BundleRevisionImpl>(m_resolvedExtensions);
+
+        outer : for (BundleRevisionImpl revision : m_unresolvedExtensions)
+        {
+            if (revision.getWiring() == null) {
+                for (BundleRevisionImpl existing : extensions)
                 {
-                    exports = ManifestParser.parseExportHeader(
-                            m_logger, m_systemBundleRevision,
-                            (String) 
bundle.adapt(BundleRevisionImpl.class).getHeaders().get(Constants.EXPORT_PACKAGE),
-                            m_systemBundleRevision.getSymbolicName(), 
m_systemBundleRevision.getVersion());
-                    exports = aliasSymbolicName(exports);
+                    if 
(existing.getSymbolicName().equals(revision.getSymbolicName()))
+                    {
+                        continue outer;
+                    }
                 }
-                catch (Exception ex)
+                for (BundleRevisionImpl other : m_unresolvedExtensions)
                 {
-                    m_logger.log(
-                            bundle,
-                            Logger.LOG_ERROR,
-                            "Error parsing extension bundle export statement: "
-                                    + 
bundle.adapt(BundleRevisionImpl.class).getHeaders().get(Constants.EXPORT_PACKAGE),
 ex);
-                    return;
+                    if ((revision != other) && 
(revision.getSymbolicName().equals(other.getSymbolicName())) &&
+                        revision.getVersion().compareTo(other.getVersion()) < 
0)
+                    {
+                        continue outer;
+                    }
                 }
+
+                extensions.add(revision);
+            }
+        }
+
+        Map<BundleRevisionImpl, List<BundleWire>> wirings = 
findResolvableExtensions(extensions);
+
+        List<Bundle> result = new ArrayList<Bundle>();
+
+        for (Map.Entry<BundleRevisionImpl, List<BundleWire>> entry : 
wirings.entrySet())
+        {
+            BundleRevisionImpl revision = entry.getKey();
+
+            m_unresolvedExtensions.remove(revision);
+            m_resolvedExtensions.add(revision);
+
+            BundleWire wire = new BundleWireImpl(revision,
+                
revision.getDeclaredRequirements(BundleRevision.HOST_NAMESPACE).get(0),
+                m_systemBundleRevision, 
getCapabilities(BundleRevision.HOST_NAMESPACE).get(0));
+
+            try
+            {
+                revision.resolve(new BundleWiringImpl(m_logger, m_configMap, 
null, revision, null,
+                    Collections.singletonList(wire), Collections.EMPTY_MAP, 
Collections.EMPTY_MAP));
             }
-            AccessController.doPrivileged(new PrivilegedExceptionAction<Void>()
+            catch (Exception ex)
+            {
+                m_logger.log(revision.getBundle(), Logger.LOG_ERROR,
+                        "Error resolving extension bundle : " + 
revision.getBundle(), ex);
+            }
+
+            felix.getDependencies().addDependent(wire);
+
+            
appendCapabilities(entry.getKey().getDeclaredExtensionCapabilities(null));
+            for (BundleWire w : entry.getValue())
             {
-                @Override
-                public Void run() throws Exception
+                if 
(!w.getRequirement().getNamespace().equals(BundleRevision.HOST_NAMESPACE) &&
+                    
!w.getRequirement().getNamespace().equals(BundleRevision.PACKAGE_NAMESPACE))
                 {
-                    extender.add(file);
-                    return null;
+                    ((BundleWiringImpl) 
w.getRequirer().getWiring()).addDynamicWire(w);
+                    felix.getDependencies().addDependent(w);
                 }
-            });
-            if (exports != null)
+            }
+
+            final File f;
+            Content revisionContent = revision.getContent();
+            if (revisionContent instanceof JarContent)
+            {
+                f = ((JarContent) revisionContent).getFile();
+            }
+            else
             {
-                appendCapabilities(exports);
+                f = ((DirectoryContent) revisionContent).getFile();
             }
+            try
+            {
+                AccessController.doPrivileged(new 
PrivilegedExceptionAction<Void>()
+                {
+                    @Override
+                    public Void run() throws Exception {
+                        m_extenderFramework.add(f);
+                        return null;
+                    }
+                });
+            }
+            catch (Exception ex)
+            {
+                m_logger.log(revision.getBundle(), Logger.LOG_ERROR,
+                    "Error adding extension bundle to framework classloader: " 
+ revision.getBundle(), ex);
+            }
+
+            felix.setBundleStateAndNotify(revision.getBundle(), 
Bundle.RESOLVED);
+            result.add(revision.getBundle());
         }
-        catch (Exception ex)
+
+        if (!wirings.isEmpty())
         {
-            throw ex;
+            felix.getResolver().addRevision(getRevision());
         }
 
-        BundleRevisionImpl bri = bundle.adapt(BundleRevisionImpl.class);
-        List<BundleRequirement> reqs = 
bri.getDeclaredRequirements(BundleRevision.HOST_NAMESPACE);
-        List<BundleCapability> caps = 
getCapabilities(BundleRevision.HOST_NAMESPACE);
-        BundleWire bw = new BundleWireImpl(bri, reqs.get(0), 
m_systemBundleRevision, caps.get(0));
-        bri.resolve(
-            new BundleWiringImpl(
-                m_logger,
-                m_configMap,
-                null,
-                bri,
-                null,
-                Collections.singletonList(bw),
-                Collections.EMPTY_MAP,
-                Collections.EMPTY_MAP));
-        felix.getDependencies().addDependent(bw);
-        felix.setBundleStateAndNotify(bundle, Bundle.RESOLVED);
+        return result;
     }
 
     /**
-     * This is a Felix specific extension mechanism that allows extension 
bundles
-     * to have activators and be started via this method.
+     * Start extension bundles that hasve an activator
      *
      * @param felix the framework instance the extension bundle is installed 
in.
-     * @param bundle the extension bundle to start if it has a Felix specific 
activator.
+     * @param bundle the extension bundle to start if it has a an extension 
bundle activator.
      */
     void startExtensionBundle(Felix felix, BundleImpl bundle)
     {
@@ -553,7 +560,7 @@ class ExtensionManager implements Conten
             {
 // TODO: SECURITY - Should this consider security?
                 BundleActivator activator = (BundleActivator)
-                    felix.getClass().getClassLoader().loadClass(
+                    
Felix.m_secureAction.getClassLoader(felix.getClass()).loadClass(
                         activatorClass.trim()).newInstance();
 
                 BundleContext context = felix._getBundleContext();
@@ -643,6 +650,85 @@ class ExtensionManager implements Conten
         m_extensionTuples.clear();
     }
 
+    private Map<BundleRevisionImpl, List<BundleWire>> 
findResolvableExtensions(List<BundleRevisionImpl> extensions)
+    {
+        // The idea is to loop through the extensions and try to resolve all 
unresolved extension. If we can't resolve
+        // a given extension, we will call the method again with the extension 
in question removed.
+        Map<BundleRevisionImpl, List<BundleWire>> wires = new 
LinkedHashMap<BundleRevisionImpl, List<BundleWire>>();
+
+        for (BundleRevisionImpl bri : extensions)
+        {
+            // Ignore resolved extensions
+            if (bri.getWiring() == null)
+            {
+                List<BundleWire> wi = new ArrayList<BundleWire>();
+                boolean resolved = true;
+                outer: for (BundleRequirement req : 
bri.getDeclaredRequirements(null))
+                {
+                    // first see if we can resolve from the system bundle
+                    for (BundleCapability cap : 
getCapabilities(req.getNamespace()))
+                    {
+                        if (req.matches(cap))
+                        {
+                            // we can, create the wire but in the case of an 
ee requirement, make it from the extension
+                            wi.add(new BundleWireImpl(
+                                    
req.getNamespace().equals(ExecutionEnvironmentNamespace.EXECUTION_ENVIRONMENT_NAMESPACE)
 ?
+                                            bri : m_systemBundleRevision, req, 
m_systemBundleRevision, cap));
+
+                            continue outer;
+                        }
+                    }
+
+                    // now loop through the other extensions
+                    for (BundleRevisionImpl extension : extensions)
+                    {
+                        // check the caps that will be lifted to the system 
bundle
+                        for (BundleCapability cap : 
extension.getDeclaredExtensionCapabilities(req.getNamespace()))
+                        {
+                            if (req.matches(cap))
+                            {
+                                // we could use a yet unresolved extension 
(resolved one are implicitly checked by the
+                                // system bundle loop above as they would be 
attached.
+                                wi.add(new 
BundleWireImpl(m_systemBundleRevision, req, m_systemBundleRevision, cap));
+                                continue outer;
+                            }
+                        }
+
+                        // now check the caps that will not be lifted (i.e., 
identity)
+                        for (BundleCapability cap : 
extension.getDeclaredCapabilities(req.getNamespace()))
+                        {
+                            if (req.matches(cap))
+                            {
+                                // it was identity - hence, use the extension 
itself as provider
+                                wi.add(new 
BundleWireImpl(m_systemBundleRevision, req, extension, cap));
+                                continue outer;
+                            }
+                        }
+                    }
+                    // we couldn't find a provider - was it optional?
+                    if (!((BundleRequirementImpl)req).isOptional())
+                    {
+                        resolved = false;
+                        break;
+                    }
+                }
+                if(resolved)
+                {
+                    wires.put(bri, wi);
+                }
+                else
+                {
+                    // we failed to resolve this extension - try again without 
it. Yes, this throws away the work done
+                    // up to this point
+                    List<BundleRevisionImpl> next = new 
ArrayList<BundleRevisionImpl>(extensions);
+                    next.remove(bri);
+                    return next.isEmpty() ? Collections.EMPTY_MAP : 
findResolvableExtensions(next);
+                }
+            }
+        }
+        return wires;
+    }
+
     private List<BundleCapability> getCapabilities(String namespace)
     {
         List<BundleCapability> caps = m_capabilities;
@@ -663,8 +749,7 @@ class ExtensionManager implements Conten
 
     private synchronized void appendCapabilities(List<BundleCapability> caps)
     {
-        List<BundleCapability> newCaps =
-            new ArrayList<BundleCapability>(m_capabilities.size() + 
caps.size());
+        List<BundleCapability> newCaps = new 
ArrayList<BundleCapability>(m_capabilities.size() + caps.size());
         newCaps.addAll(m_capabilities);
         newCaps.addAll(caps);
         m_capabilities = ImmutableList.newInstance(newCaps);

Modified: 
felix/trunk/osgi-r7/framework/src/main/java/org/apache/felix/framework/Felix.java
URL: 
http://svn.apache.org/viewvc/felix/trunk/osgi-r7/framework/src/main/java/org/apache/felix/framework/Felix.java?rev=1826988&r1=1826987&r2=1826988&view=diff
==============================================================================
--- 
felix/trunk/osgi-r7/framework/src/main/java/org/apache/felix/framework/Felix.java
 (original)
+++ 
felix/trunk/osgi-r7/framework/src/main/java/org/apache/felix/framework/Felix.java
 Fri Mar 16 13:44:36 2018
@@ -821,6 +821,11 @@ public class Felix extends BundleImpl im
                     }
                 }
 
+                for (Bundle extension : 
m_extensionManager.resolveExtensionBundles(this))
+                {
+                    m_extensionManager.startExtensionBundle(this, (BundleImpl) 
extension);
+                }
+
                 // Now that we have loaded all cached bundles and have 
determined the
                 // max bundle ID of cached bundles, we need to try to load the 
next
                 // bundle ID from persistent storage. In case of failure, we 
should
@@ -1278,6 +1283,52 @@ public class Felix extends BundleImpl im
         }).start();
     }
 
+    private void stopRefresh() throws BundleException
+    {
+        Object sm = System.getSecurityManager();
+
+        if (sm != null)
+        {
+            ((SecurityManager) sm).checkPermission(new AdminPermission(this,
+                    AdminPermission.EXECUTE));
+        }
+
+
+        // Stop the framework on a separate thread.
+        new Thread(new Runnable() {
+            @Override
+            public void run()
+            {
+                try
+                {
+                    // First acquire the system bundle lock to verify the 
state.
+                    acquireBundleLock(Felix.this, Bundle.STARTING | 
Bundle.ACTIVE);
+                    // Set the reason for the shutdown.
+                    m_shutdownGate.setMessage(
+                            new 
FrameworkEvent(FrameworkEvent.STOPPED_SYSTEM_REFRESHED, Felix.this, null));
+                    // Record the state and stop the system bundle.
+                    int oldState = Felix.this.getState();
+                    try
+                    {
+                        stop();
+                    }
+                    catch (BundleException ex)
+                    {
+                        m_logger.log(Logger.LOG_WARNING, "Exception stopping 
framework.", ex);
+                    }
+                    finally
+                    {
+                        releaseBundleLock(Felix.this);
+                    }
+                }
+                catch (Exception ex)
+                {
+                    m_logger.log(Logger.LOG_WARNING, "Cannot update an 
inactive framework.");
+                }
+            }
+        }).start();
+    }
+
     @Override
     public String toString()
     {
@@ -2494,10 +2545,6 @@ public class Felix extends BundleImpl im
                         if (!wasExtension && bundle.isExtension())
                         {
                             m_extensionManager.addExtensionBundle(this, 
bundle);
-// TODO: REFACTOR - Perhaps we could move this into extension manager.
-                            
m_resolver.addRevision(m_extensionManager.getRevision());
-// TODO: REFACTOR - Not clear why this is here. We should look at all of these 
steps more closely.
-                            setBundleStateAndNotify(bundle, Bundle.RESOLVED);
                         }
                         else if (wasExtension)
                         {
@@ -2542,9 +2589,10 @@ public class Felix extends BundleImpl im
                 {
                     setBundleStateAndNotify(bundle, Bundle.INSTALLED);
                 }
-                else
+
+                for (Bundle extension : 
m_extensionManager.resolveExtensionBundles(this))
                 {
-                    m_extensionManager.startExtensionBundle(this, bundle);
+                    m_extensionManager.startExtensionBundle(this, (BundleImpl) 
extension);
                 }
 
                 fireBundleEvent(BundleEvent.UNRESOLVED, bundle);
@@ -3089,7 +3137,6 @@ public class Felix extends BundleImpl im
                 if (bundle.isExtension())
                 {
                     m_extensionManager.addExtensionBundle(this, bundle);
-                    m_resolver.addRevision(m_extensionManager.getRevision());
                 }
 
                 // Use a copy-on-write approach to add the bundle
@@ -3124,11 +3171,6 @@ public class Felix extends BundleImpl im
             }
         }
 
-        if (bundle.isExtension())
-        {
-            m_extensionManager.startExtensionBundle(this, bundle);
-        }
-
         return bundle;
     }
 
@@ -3215,7 +3257,6 @@ public class Felix extends BundleImpl im
                     else
                     {
                         m_extensionManager.addExtensionBundle(this, bundle);
-                        
m_resolver.addRevision(m_extensionManager.getRevision());
                     }
                 }
                 catch (Throwable ex)
@@ -3278,9 +3319,9 @@ public class Felix extends BundleImpl im
                     releaseGlobalLock();
                 }
 
-                if (bundle.isExtension())
+                for (Bundle extension : 
m_extensionManager.resolveExtensionBundles(this))
                 {
-                    m_extensionManager.startExtensionBundle(this, bundle);
+                    m_extensionManager.startExtensionBundle(this, (BundleImpl) 
extension);
                 }
             }
         }
@@ -4381,6 +4422,7 @@ public class Felix extends BundleImpl im
         try
         {
             boolean restart = false;
+            boolean extensionBundle = false;
 
             Bundle systemBundle = this;
 
@@ -4391,9 +4433,14 @@ public class Felix extends BundleImpl im
             {
                 for (Bundle b : bundles)
                 {
-                    if ((systemBundle == b) || ((BundleImpl) b).isExtension())
+                    if (systemBundle == b)
+                    {
+                        restart = true;
+                    }
+                    else if (((BundleImpl) b).isExtension())
                     {
                         restart = true;
+                        extensionBundle = true;
                         break;
                     }
                 }
@@ -4450,13 +4497,25 @@ public class Felix extends BundleImpl im
                 }
                 else
                 {
-                    try
+                    if (!extensionBundle)
                     {
-                        update();
+                        try
+                        {
+                            update();
+                        }
+                        catch (BundleException ex) {
+                            m_logger.log(Logger.LOG_ERROR, "Framework restart 
error.", ex);
+                        }
                     }
-                    catch (BundleException ex)
+                    else
                     {
-                        m_logger.log(Logger.LOG_ERROR, "Framework restart 
error.", ex);
+                        try
+                        {
+                            stopRefresh();
+                        }
+                        catch (BundleException ex) {
+                            m_logger.log(Logger.LOG_ERROR, "Framework stop 
error.", ex);
+                        }
                     }
                 }
             }
@@ -5147,6 +5206,7 @@ public class Felix extends BundleImpl im
                 m_securityManager = null;
             }
 
+            m_extensionManager.removeExtensionBundles(Felix.this);
             m_dependencies.removeDependents(adapt(BundleRevision.class));
 
             // Dispose of the bundle cache.

Modified: 
felix/trunk/osgi-r7/framework/src/main/java/org/apache/felix/framework/util/manifestparser/ManifestParser.java
URL: 
http://svn.apache.org/viewvc/felix/trunk/osgi-r7/framework/src/main/java/org/apache/felix/framework/util/manifestparser/ManifestParser.java?rev=1826988&r1=1826987&r2=1826988&view=diff
==============================================================================
--- 
felix/trunk/osgi-r7/framework/src/main/java/org/apache/felix/framework/util/manifestparser/ManifestParser.java
 (original)
+++ 
felix/trunk/osgi-r7/framework/src/main/java/org/apache/felix/framework/util/manifestparser/ManifestParser.java
 Fri Mar 16 13:44:36 2018
@@ -18,16 +18,6 @@
  */
 package org.apache.felix.framework.util.manifestparser;
 
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
-
 import org.apache.felix.framework.BundleRevisionImpl;
 import org.apache.felix.framework.Logger;
 import org.apache.felix.framework.capabilityset.SimpleFilter;
@@ -46,6 +36,16 @@ import org.osgi.framework.wiring.BundleC
 import org.osgi.framework.wiring.BundleRequirement;
 import org.osgi.framework.wiring.BundleRevision;
 
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+
 public class ManifestParser
 {
     private static final String BUNDLE_LICENSE_HEADER = "Bundle-License"; // 
No constant defined by OSGi...
@@ -60,6 +60,7 @@ public class ManifestParser
     private volatile String m_bundleSymbolicName;
     private volatile Version m_bundleVersion;
     private volatile List<BundleCapability> m_capabilities;
+    private volatile List<BundleCapability> m_extensionCapabilities;
     private volatile List<BundleRequirement> m_requirements;
     private volatile List<NativeLibraryClause> m_libraryClauses;
     private volatile boolean m_libraryHeadersOptional = false;
@@ -157,6 +158,8 @@ public class ManifestParser
                 "R4 bundle manifests must include bundle symbolic name.");
         }
 
+        m_isExtension = checkExtensionBundle(headerMap);
+
         //
         // Parse Fragment-Host.
         //
@@ -222,7 +225,7 @@ public class ManifestParser
 
         List<ParsedHeaderClause> provideClauses =
             parseStandardHeader((String) 
headerMap.get(Constants.PROVIDE_CAPABILITY));
-        exportClauses = normalizeCapabilityClauses(
+        provideClauses = normalizeCapabilityClauses(
             logger, provideClauses, getManifestVersion());
         List<BundleCapability> provideCaps = 
convertProvideCapabilities(provideClauses, owner);
 
@@ -281,8 +284,19 @@ public class ManifestParser
         m_capabilities = new ArrayList<BundleCapability>(
              capList.size() + exportCaps.size() + provideCaps.size());
         m_capabilities.addAll(capList);
-        m_capabilities.addAll(exportCaps);
-        m_capabilities.addAll(provideCaps);
+
+        if (m_isExtension)
+        {
+            m_extensionCapabilities = new ArrayList<BundleCapability>();
+            m_extensionCapabilities.addAll(exportCaps);
+            m_extensionCapabilities.addAll(provideCaps);
+        }
+        else
+        {
+            m_extensionCapabilities = Collections.EMPTY_LIST;
+            m_capabilities.addAll(exportCaps);
+            m_capabilities.addAll(provideCaps);
+        }
 
         //
         // Parse activation policy.
@@ -291,8 +305,6 @@ public class ManifestParser
         // This sets m_activationPolicy, m_includedPolicyClasses, and
         // m_excludedPolicyClasses.
         parseActivationPolicy(headerMap);
-
-        m_isExtension = checkExtensionBundle(headerMap);
     }
 
     private static List<ParsedHeaderClause> normalizeImportClauses(
@@ -1038,11 +1050,6 @@ public class ManifestParser
         return m_requirements;
     }
 
-    public List<NativeLibraryClause> getLibraryClauses()
-    {
-        return m_libraryClauses;
-    }
-
     /**
      * <p>
      * This method returns the selected native library metadata from
@@ -1351,8 +1358,7 @@ public class ManifestParser
                 throw new BundleException(
                     "Extension bundle must have either 'extension:=framework' 
or 'extension:=bootclasspath'");
             }
-            if (headerMap.containsKey(Constants.IMPORT_PACKAGE) ||
-                headerMap.containsKey(Constants.REQUIRE_BUNDLE) ||
+            if (headerMap.containsKey(Constants.REQUIRE_BUNDLE) ||
                 headerMap.containsKey(Constants.BUNDLE_NATIVECODE) ||
                 headerMap.containsKey(Constants.DYNAMICIMPORT_PACKAGE) ||
                 headerMap.containsKey(Constants.BUNDLE_ACTIVATOR))
@@ -1555,24 +1561,6 @@ public class ManifestParser
         return reqs;
     }
 
-    public static List<BundleCapability> parseExportHeader(
-        Logger logger, BundleRevision owner, String header, String bsn, 
Version bv)
-    {
-
-        List<BundleCapability> caps = null;
-        try
-        {
-            List<ParsedHeaderClause> exportClauses = 
parseStandardHeader(header);
-            exportClauses = normalizeExportClauses(logger, exportClauses, "2", 
bsn, bv);
-            caps = convertExports(exportClauses, owner);
-        }
-        catch (BundleException ex)
-        {
-            caps = null;
-        }
-        return caps;
-    }
-
     private static List<BundleRequirement> parseBreeHeader(String header, 
BundleRevision owner)
     {
         List<String> filters = new ArrayList<String>();
@@ -1686,7 +1674,8 @@ public class ManifestParser
         }
     }
 
-    private static String getBreeVersionClause(Version ver) {
+    private static String getBreeVersionClause(Version ver)
+    {
         if (ver == null)
             return null;
 
@@ -2150,4 +2139,71 @@ public class ManifestParser
 
         return libList;
     }
+
+    public static List<BundleCapability> 
aliasSymbolicName(List<BundleCapability> caps, BundleRevision owner)
+    {
+        if (caps == null)
+        {
+            return new ArrayList<BundleCapability>(0);
+        }
+
+        List<BundleCapability> aliasCaps = new 
ArrayList<BundleCapability>(caps);
+
+        String[] aliases = {
+                FelixConstants.SYSTEM_BUNDLE_SYMBOLICNAME,
+                Constants.SYSTEM_BUNDLE_SYMBOLICNAME };
+
+        for (int capIdx = 0; capIdx < aliasCaps.size(); capIdx++)
+        {
+            BundleCapability cap = aliasCaps.get(capIdx);
+
+            // Need to alias bundle and host capabilities.
+            if (cap.getNamespace().equals(BundleRevision.BUNDLE_NAMESPACE)
+                    || 
cap.getNamespace().equals(BundleRevision.HOST_NAMESPACE))
+            {
+                // Make a copy of the attribute array.
+                Map<String, Object> aliasAttrs =
+                        new HashMap<String, Object>(cap.getAttributes());
+                // Add the aliased value.
+                aliasAttrs.put(cap.getNamespace(), aliases);
+                // Create the aliased capability to replace the old capability.
+                cap = new BundleCapabilityImpl(
+                        owner,
+                        cap.getNamespace(),
+                        cap.getDirectives(),
+                        aliasAttrs);
+                aliasCaps.set(capIdx, cap);
+            }
+
+            // Further, search attributes for bundle symbolic name and alias 
it too.
+            for (Entry<String, Object> entry : cap.getAttributes().entrySet())
+            {
+                // If there is a bundle symbolic name attribute, add the
+                // standard alias as a value.
+                if 
(entry.getKey().equalsIgnoreCase(Constants.BUNDLE_SYMBOLICNAME_ATTRIBUTE))
+                {
+                    // Make a copy of the attribute array.
+                    Map<String, Object> aliasAttrs =
+                            new HashMap<String, Object>(cap.getAttributes());
+                    // Add the aliased value.
+                    aliasAttrs.put(Constants.BUNDLE_SYMBOLICNAME_ATTRIBUTE, 
aliases);
+                    // Create the aliased capability to replace the old 
capability.
+                    aliasCaps.set(capIdx, new BundleCapabilityImpl(
+                            owner,
+                            cap.getNamespace(),
+                            cap.getDirectives(),
+                            aliasAttrs));
+                    // Continue with the next capability.
+                    break;
+                }
+            }
+        }
+
+        return aliasCaps;
+    }
+
+    public List<BundleCapability> getExtensionCapabilites()
+    {
+        return m_extensionCapabilities;
+    }
 }


Reply via email to