More fixes to calculating resolved caps/deps, such as ignoring
unknown effective times and handling fragments as a special case.
Also start to implement adapt(BundleRevisions.class). (FELIX-2950)
git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@1143199 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/framework/src/main/java/org/apache/felix/framework/BundleImpl.java b/framework/src/main/java/org/apache/felix/framework/BundleImpl.java
index 2a28114..701a986 100644
--- a/framework/src/main/java/org/apache/felix/framework/BundleImpl.java
+++ b/framework/src/main/java/org/apache/felix/framework/BundleImpl.java
@@ -40,12 +40,13 @@
import org.osgi.framework.Version;
import org.osgi.framework.startlevel.BundleStartLevel;
import org.osgi.framework.wiring.BundleRevision;
+import org.osgi.framework.wiring.BundleRevisions;
import org.osgi.framework.wiring.BundleWire;
import org.osgi.framework.wiring.BundleWiring;
-class BundleImpl implements Bundle
+class BundleImpl implements Bundle, BundleRevisions
{
- // No one should use this field directly, use getFramework() instead.
+ // No one should use this field directlhttp://www.youtube.com/watch?v=zQwxwPDU4bwy, use getFramework() instead.
private final Felix __m_felix;
private final BundleArchive m_archive;
@@ -871,9 +872,9 @@
synchronized boolean isExtension()
{
- for (int i = (m_revisions.size() - 1); i > -1; i--)
+ for (BundleRevision revision : m_revisions)
{
- if (((BundleRevisionImpl) m_revisions.get(i)).isExtension())
+ if (((BundleRevisionImpl) revision).isExtension())
{
return true;
}
@@ -1022,11 +1023,19 @@
}
else if (type == BundleRevision.class)
{
- return (A) m_revisions.get(m_revisions.size() - 1);
+ if (m_state == Bundle.UNINSTALLED)
+ {
+ return null;
+ }
+ return (A) m_revisions.get(0);
+ }
+ else if (type == BundleRevisions.class)
+ {
+ return (A) this;
}
else if (type == BundleWiring.class)
{
- return (A) m_revisions.get(m_revisions.size() - 1).getWiring();
+ return (A) m_revisions.get(0).getWiring();
}
return null;
}
@@ -1060,21 +1069,14 @@
// Revision management.
//
- /**
- * Returns an array of all modules associated with the bundle represented by
- * this <tt>BundleInfo</tt> object. A module in the array corresponds to a
- * revision of the bundle's JAR file and is ordered from oldest to newest.
- * Multiple revisions of a bundle JAR file might exist if a bundle is
- * updated, without refreshing the framework. In this case, exports from
- * the prior revisions of the bundle JAR file are still offered; the
- * current revision will be bound to packages from the prior revision,
- * unless the packages were not offered by the prior revision. There is
- * no limit on the potential number of bundle JAR file revisions.
- * @return array of modules corresponding to the bundle JAR file revisions.
- **/
- synchronized List<BundleRevision> getRevisions()
+ public Bundle getBundle()
{
- return m_revisions;
+ return this;
+ }
+
+ public synchronized List<BundleRevision> getRevisions()
+ {
+ return new ArrayList<BundleRevision>(m_revisions);
}
/**
@@ -1085,14 +1087,7 @@
**/
synchronized boolean hasRevision(BundleRevision revision)
{
- for (int i = 0; i < m_revisions.size(); i++)
- {
- if (m_revisions.get(i) == revision)
- {
- return true;
- }
- }
- return false;
+ return m_revisions.contains(revision);
}
synchronized void revise(String location, InputStream is)
@@ -1115,7 +1110,7 @@
synchronized boolean rollbackRevise() throws Exception
{
boolean isExtension = isExtension();
- BundleRevision br = m_revisions.remove(m_revisions.size() - 1);
+ BundleRevision br = m_revisions.remove(0);
if (!isExtension)
{
// Since revising a bundle adds a revision to the global
@@ -1131,7 +1126,7 @@
// which is the normal case.
synchronized void addRevision(BundleRevision revision) throws Exception
{
- m_revisions.add(revision);
+ m_revisions.add(0, revision);
// Set protection domain after adding the revision to the bundle,
// since this requires that the bundle has a revision.
@@ -1147,7 +1142,7 @@
}
catch (Exception ex)
{
- m_revisions.remove(m_revisions.size() - 1);
+ m_revisions.remove(0);
throw ex;
}
}
diff --git a/framework/src/main/java/org/apache/felix/framework/BundleRevisionDependencies.java b/framework/src/main/java/org/apache/felix/framework/BundleRevisionDependencies.java
index 749ee3a..1611842 100644
--- a/framework/src/main/java/org/apache/felix/framework/BundleRevisionDependencies.java
+++ b/framework/src/main/java/org/apache/felix/framework/BundleRevisionDependencies.java
@@ -30,6 +30,7 @@
import org.osgi.framework.Bundle;
import org.osgi.framework.wiring.BundleCapability;
import org.osgi.framework.wiring.BundleRevision;
+import org.osgi.framework.wiring.BundleRevisions;
import org.osgi.framework.wiring.BundleWire;
import org.osgi.framework.wiring.BundleWiring;
@@ -111,9 +112,9 @@
return false;
}
- public synchronized boolean hasDependents(BundleImpl bundle)
+ public synchronized boolean hasDependents(Bundle bundle)
{
- List<BundleRevision> revisions = bundle.getRevisions();
+ List<BundleRevision> revisions = bundle.adapt(BundleRevisions.class).getRevisions();
for (BundleRevision revision : revisions)
{
if (hasDependents(revision))
@@ -145,11 +146,11 @@
return providedWires;
}
- public synchronized Set<Bundle> getDependentBundles(BundleImpl bundle)
+ public synchronized Set<Bundle> getDependentBundles(Bundle bundle)
{
Set<Bundle> result = new HashSet<Bundle>();
- List<BundleRevision> revisions = bundle.getRevisions();
+ List<BundleRevision> revisions = bundle.adapt(BundleRevisions.class).getRevisions();
for (BundleRevision revision : revisions)
{
// TODO: OSGi R4.3 - This is sort of a hack. We need to special case fragments,
@@ -188,7 +189,7 @@
}
public synchronized Set<Bundle> getImportingBundles(
- BundleImpl exporter, BundleCapability exportCap)
+ Bundle exporter, BundleCapability exportCap)
{
// Create set for storing importing bundles.
Set<Bundle> result = new HashSet<Bundle>();
@@ -199,7 +200,7 @@
// Get all importers and requirers for all revisions of the bundle.
// The spec says that require-bundle should be returned with importers.
- for (BundleRevision revision : exporter.getRevisions())
+ for (BundleRevision revision : exporter.adapt(BundleRevisions.class).getRevisions())
{
Map<BundleCapability, Set<BundleWire>>
caps = m_dependentsMap.get(revision);
@@ -229,13 +230,13 @@
return result;
}
- public synchronized Set<Bundle> getRequiringBundles(BundleImpl bundle)
+ public synchronized Set<Bundle> getRequiringBundles(Bundle bundle)
{
// Create set for storing requiring bundles.
Set<Bundle> result = new HashSet<Bundle>();
// Get all requirers for all revisions of the bundle.
- for (BundleRevision revision : bundle.getRevisions())
+ for (BundleRevision revision : bundle.adapt(BundleRevisions.class).getRevisions())
{
Map<BundleCapability, Set<BundleWire>>
caps = m_dependentsMap.get(revision);
@@ -262,9 +263,9 @@
return result;
}
- public synchronized void removeDependencies(BundleImpl bundle)
+ public synchronized void removeDependencies(Bundle bundle)
{
- List<BundleRevision> revs = bundle.getRevisions();
+ List<BundleRevision> revs = bundle.adapt(BundleRevisions.class).getRevisions();
for (BundleRevision rev : revs)
{
BundleWiring wiring = rev.getWiring();
diff --git a/framework/src/main/java/org/apache/felix/framework/BundleWiringImpl.java b/framework/src/main/java/org/apache/felix/framework/BundleWiringImpl.java
index dc496f2..9ee7f28 100644
--- a/framework/src/main/java/org/apache/felix/framework/BundleWiringImpl.java
+++ b/framework/src/main/java/org/apache/felix/framework/BundleWiringImpl.java
@@ -234,39 +234,59 @@
// Calculate resolved list of capabilities, which includes:
// 1. All capabilities from host and any fragments except for exported
// packages that we have an import (i.e., the export was substituted).
- // And nothing else at this time.
- List<BundleCapability> capList = new ArrayList<BundleCapability>();
- for (BundleCapability cap : m_revision.getDeclaredCapabilities(null))
+ // And nothing else at this time. Fragments currently have no capabilities.
+ boolean isFragment = Util.isFragment(revision);
+ List<BundleCapability> capList = (isFragment)
+ ? Collections.EMPTY_LIST
+ : new ArrayList<BundleCapability>();
+// TODO: OSGi R4.4 - Fragments currently have no capabilities, but they may
+// have an identity capability in the future.
+ if (!isFragment)
{
- if (!cap.getNamespace().equals(BundleRevision.PACKAGE_NAMESPACE)
- || (cap.getNamespace().equals(BundleRevision.PACKAGE_NAMESPACE)
- && !imports.contains(cap.getAttributes()
- .get(BundleRevision.PACKAGE_NAMESPACE).toString())))
+ for (BundleCapability cap : m_revision.getDeclaredCapabilities(null))
{
- capList.add(cap);
- }
- }
- if (m_fragments != null)
- {
- for (BundleRevision fragment : m_fragments)
- {
- for (BundleCapability cap : fragment.getDeclaredCapabilities(null))
+ if (!cap.getNamespace().equals(BundleRevision.PACKAGE_NAMESPACE)
+ || (cap.getNamespace().equals(BundleRevision.PACKAGE_NAMESPACE)
+ && !imports.contains(cap.getAttributes()
+ .get(BundleRevision.PACKAGE_NAMESPACE).toString())))
{
-// TODO: OSGi R4.4 - OSGi R4.4 may introduce an identity capability, if so
-// that will need to be excluded from here.
- capList.add((BundleCapabilityImpl) cap);
- if (!cap.getNamespace().equals(BundleRevision.PACKAGE_NAMESPACE)
- || (cap.getNamespace().equals(BundleRevision.PACKAGE_NAMESPACE)
- && !imports.contains(cap.getAttributes()
- .get(BundleRevision.PACKAGE_NAMESPACE).toString())))
+// TODO: OSGi R4.4 - We may need to make this more flexible since in the future it may
+// be possible to consider other effective values via OBR's Environment.isEffective().
+ String effective = cap.getDirectives().get(Constants.EFFECTIVE_DIRECTIVE);
+ if ((effective == null) || (effective.equals(Constants.EFFECTIVE_RESOLVE)))
{
capList.add(cap);
}
}
}
+ if (m_fragments != null)
+ {
+ for (BundleRevision fragment : m_fragments)
+ {
+ for (BundleCapability cap : fragment.getDeclaredCapabilities(null))
+ {
+// TODO: OSGi R4.4 - OSGi R4.4 may introduce an identity capability, if so
+// that will need to be excluded from here.
+ if (!cap.getNamespace().equals(BundleRevision.PACKAGE_NAMESPACE)
+ || (cap.getNamespace().equals(BundleRevision.PACKAGE_NAMESPACE)
+ && !imports.contains(cap.getAttributes()
+ .get(BundleRevision.PACKAGE_NAMESPACE).toString())))
+ {
+// TODO: OSGi R4.4 - We may need to make this more flexible since in the future it may
+// be possible to consider other effective values via OBR's Environment.isEffective().
+ String effective = cap.getDirectives().get(Constants.EFFECTIVE_DIRECTIVE);
+ if ((effective == null) || (effective.equals(Constants.EFFECTIVE_RESOLVE)))
+ {
+ capList.add(cap);
+ }
+ }
+ }
+ }
+ }
}
m_resolvedCaps = Collections.unmodifiableList(capList);
+
List<R4Library> libList = (m_revision.getDeclaredNativeLibraries() == null)
? new ArrayList<R4Library>()
: new ArrayList<R4Library>(m_revision.getDeclaredNativeLibraries());
diff --git a/framework/src/main/java/org/apache/felix/framework/Felix.java b/framework/src/main/java/org/apache/felix/framework/Felix.java
index 4e5d173..a5e5423 100644
--- a/framework/src/main/java/org/apache/felix/framework/Felix.java
+++ b/framework/src/main/java/org/apache/felix/framework/Felix.java
@@ -23,17 +23,13 @@
import java.net.*;
import java.security.*;
import java.util.*;
-import java.util.Map.Entry;
import org.apache.felix.framework.ServiceRegistry.ServiceRegistryCallbacks;
import org.apache.felix.framework.cache.BundleArchive;
import org.apache.felix.framework.cache.BundleCache;
import org.apache.felix.framework.capabilityset.CapabilitySet;
import org.apache.felix.framework.capabilityset.SimpleFilter;
-import org.apache.felix.framework.resolver.ResolverWire;
import org.apache.felix.framework.ext.SecurityProvider;
import org.apache.felix.framework.resolver.ResolveException;
-import org.apache.felix.framework.resolver.Resolver;
-import org.apache.felix.framework.resolver.ResolverImpl;
import org.apache.felix.framework.util.EventDispatcher;
import org.apache.felix.framework.util.FelixConstants;
import org.apache.felix.framework.util.ListenerHookInfoImpl;
@@ -44,9 +40,7 @@
import org.apache.felix.framework.util.ThreadGate;
import org.apache.felix.framework.util.Util;
import org.apache.felix.framework.util.manifestparser.R4LibraryClause;
-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;
import org.osgi.framework.BundleActivator;
@@ -72,9 +66,8 @@
import org.osgi.framework.hooks.service.ListenerHook;
import org.osgi.framework.startlevel.FrameworkStartLevel;
import org.osgi.framework.wiring.BundleCapability;
-import org.osgi.framework.wiring.BundleRequirement;
import org.osgi.framework.wiring.BundleRevision;
-import org.osgi.framework.wiring.BundleWire;
+import org.osgi.framework.wiring.BundleRevisions;
import org.osgi.framework.wiring.FrameworkWiring;
import org.osgi.service.packageadmin.ExportedPackage;
import org.osgi.service.startlevel.StartLevel;
@@ -3480,7 +3473,7 @@
for (Iterator<BundleCapability> it = exports.iterator(); it.hasNext(); )
{
// Get the bundle associated with the current exporting revision.
- BundleImpl bundle = (BundleImpl) it.next().getRevision().getBundle();
+ Bundle bundle = it.next().getRevision().getBundle();
// We need to find the version of the exported package, but this
// is tricky since there may be multiple versions of the package
@@ -3488,11 +3481,14 @@
// bundle JAR file may exist if the bundle was updated without
// refreshing the framework. In this case, each revision of the
// bundle JAR file is represented as a revision ordered from
- // oldest to newest. We assume that the first revision found to
+ // newest to oldest. We assume that the first revision found to
// be exporting the package is the provider of the package,
// which makes sense since it must have been resolved first.
- for (BundleRevision br : bundle.getRevisions())
+ List<BundleRevision> revisions =
+ bundle.adapt(BundleRevisions.class).getRevisions();
+ for (int i = revisions.size() - 1; i >= 0; i--)
{
+ BundleRevision br = revisions.get(i);
List<BundleCapability> caps = (br.getWiring() == null)
? br.getDeclaredCapabilities(null)
: br.getWiring().getCapabilities(null);
@@ -3503,7 +3499,7 @@
{
pkgs.add(
new ExportedPackageImpl(
- this, bundle, br, cap));
+ this, (BundleImpl) bundle, br, cap));
}
}
}
@@ -3587,12 +3583,12 @@
* @param bundle The bundle from which to retrieve exported packages.
* @param list The list to which the exported packages are added
**/
- private void getExportedPackages(BundleImpl bundle, List list)
+ private void getExportedPackages(Bundle bundle, List list)
{
// Since a bundle may have many revisions associated with it,
// one for each revision in the cache, search each revision
// to get all exports.
- for (BundleRevision br : bundle.getRevisions())
+ for (BundleRevision br : bundle.adapt(BundleRevisions.class).getRevisions())
{
List<BundleCapability> caps = (br.getWiring() == null)
? br.getDeclaredCapabilities(null)
@@ -3629,7 +3625,8 @@
if ((provider.getRevision().getWiring() != null)
&& (provider == cap))
{
- list.add(new ExportedPackageImpl(this, bundle, br, cap));
+ list.add(new ExportedPackageImpl(
+ this, (BundleImpl) bundle, br, cap));
}
}
}
diff --git a/framework/src/main/java/org/apache/felix/framework/PackageAdminImpl.java b/framework/src/main/java/org/apache/felix/framework/PackageAdminImpl.java
index e1f1e70..28a4696 100644
--- a/framework/src/main/java/org/apache/felix/framework/PackageAdminImpl.java
+++ b/framework/src/main/java/org/apache/felix/framework/PackageAdminImpl.java
@@ -24,6 +24,7 @@
import org.osgi.framework.Constants;
import org.osgi.framework.Version;
import org.osgi.framework.wiring.BundleRevision;
+import org.osgi.framework.wiring.BundleRevisions;
import org.osgi.framework.wiring.BundleWire;
import org.osgi.framework.wiring.FrameworkWiring;
import org.osgi.service.packageadmin.ExportedPackage;
@@ -164,7 +165,7 @@
{
List<Bundle> list = new ArrayList<Bundle>();
// Iterate through revisions
- for (BundleRevision revision : ((BundleImpl) bundle).getRevisions())
+ for (BundleRevision revision : bundle.adapt(BundleRevisions.class).getRevisions())
{
// Get attached fragments.
if (revision.getWiring() != null)
@@ -196,7 +197,7 @@
{
List<Bundle> list = new ArrayList<Bundle>();
// Iterate through revisions
- for (BundleRevision revision : ((BundleImpl) bundle).getRevisions())
+ for (BundleRevision revision : bundle.adapt(BundleRevisions.class).getRevisions())
{
// Get hosts
if (revision.getWiring() != null)
diff --git a/framework/src/main/java/org/apache/felix/framework/URLHandlersBundleURLConnection.java b/framework/src/main/java/org/apache/felix/framework/URLHandlersBundleURLConnection.java
index 1be90ea..cdf8e19 100644
--- a/framework/src/main/java/org/apache/felix/framework/URLHandlersBundleURLConnection.java
+++ b/framework/src/main/java/org/apache/felix/framework/URLHandlersBundleURLConnection.java
@@ -1,4 +1,4 @@
-/*
+/*
* 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
@@ -23,10 +23,11 @@
import java.net.URL;
import java.net.URLConnection;
import java.security.Permission;
-import java.util.List;
import org.apache.felix.framework.util.Util;
+import org.osgi.framework.Bundle;
import org.osgi.framework.wiring.BundleRevision;
+import org.osgi.framework.wiring.BundleRevisions;
class URLHandlersBundleURLConnection extends URLConnection
{
@@ -81,7 +82,7 @@
// bundle://<revision-id>:<bundle-classpath-index>/<resource-path>
// Where <revision-id> = <bundle-id>.<revision>
long bundleId = Util.getBundleIdFromRevisionId(url.getHost());
- BundleImpl bundle = (BundleImpl) m_framework.getBundle(bundleId);
+ Bundle bundle = m_framework.getBundle(bundleId);
if (bundle == null)
{
throw new IOException("No bundle associated with resource: " + url);
@@ -89,14 +90,14 @@
m_contentTime = bundle.getLastModified();
// Get the bundle's revisions to find the target revision.
- List<BundleRevision> revisions = bundle.getRevisions();
- if ((revisions == null) || revisions.isEmpty())
+ BundleRevisions revisions = bundle.adapt(BundleRevisions.class);
+ if ((revisions == null) || revisions.getRevisions().isEmpty())
{
throw new IOException("Resource does not exist: " + url);
}
// Search for matching revision name.
- for (BundleRevision br : revisions)
+ for (BundleRevision br : revisions.getRevisions())
{
if (((BundleRevisionImpl) br).getId().equals(url.getHost()))
{
@@ -108,7 +109,7 @@
// If not found, assume the current revision.
if (m_targetRevision == null)
{
- m_targetRevision = revisions.get(revisions.size() - 1);
+ m_targetRevision = revisions.getRevisions().get(0);
}
// If the resource cannot be found at the current class path index,
diff --git a/framework/src/main/java/org/apache/felix/framework/wiring/BundleRequirementImpl.java b/framework/src/main/java/org/apache/felix/framework/wiring/BundleRequirementImpl.java
index 6f267b3..300cd4d 100644
--- a/framework/src/main/java/org/apache/felix/framework/wiring/BundleRequirementImpl.java
+++ b/framework/src/main/java/org/apache/felix/framework/wiring/BundleRequirementImpl.java
@@ -64,7 +64,7 @@
BundleRevision revision, String namespace,
Map<String, String> dirs, Map<String, Object> attrs)
{
- this(revision, namespace, dirs, attrs, convertToFilter(attrs));
+ this(revision, namespace, dirs, Collections.EMPTY_MAP, convertToFilter(attrs));
}
public String getNamespace()