FELIX-1492: add a flag to exclude optional resources in both resolution and deployment
git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@917433 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/bundlerepository/src/main/java/org/apache/felix/bundlerepository/RepositoryAdmin.java b/bundlerepository/src/main/java/org/apache/felix/bundlerepository/RepositoryAdmin.java
index f346be9..8a9d9bc 100644
--- a/bundlerepository/src/main/java/org/apache/felix/bundlerepository/RepositoryAdmin.java
+++ b/bundlerepository/src/main/java/org/apache/felix/bundlerepository/RepositoryAdmin.java
@@ -22,6 +22,7 @@
package org.apache.felix.bundlerepository;
import java.net.URL;
+import java.util.Map;
import org.osgi.framework.Filter;
import org.osgi.framework.InvalidSyntaxException;
@@ -164,4 +165,13 @@
*/
Repository repository(URL repository) throws Exception;
+ /**
+ * Create a capability
+ *
+ * @param name name of this capability
+ * @param properties the properties
+ * @return
+ */
+ Capability capability(String name, Map properties);
+
}
\ No newline at end of file
diff --git a/bundlerepository/src/main/java/org/apache/felix/bundlerepository/Resolver.java b/bundlerepository/src/main/java/org/apache/felix/bundlerepository/Resolver.java
index 2f0cae8..3976832 100644
--- a/bundlerepository/src/main/java/org/apache/felix/bundlerepository/Resolver.java
+++ b/bundlerepository/src/main/java/org/apache/felix/bundlerepository/Resolver.java
@@ -24,6 +24,12 @@
public interface Resolver
{
+ int NO_OPTIONAL_RESOURCES = 0x0001;
+ int NO_LOCAL_RESOURCES = 0x0002;
+ int NO_SYSTEM_BUNDLE = 0x0004;
+ int DO_NOT_PREFER_LOCAL = 0x0008;
+ int START = 0x0010;
+
/**
* Add the following resource to the resolution.
*
@@ -60,6 +66,25 @@
*/
Requirement[] getAddedRequirements();
+ /**
+ * Start the resolution process and return whether the constraints have
+ * been successfully met or not.
+ * The resolution can be interrupted by a call to Thread.interrupt() at any
+ * time. The result will be to stop the resolver and throw an InterruptedException.
+ *
+ * @return <code>true</code> if the resolution has succeeded else <code>false</code>
+ * @throws InterruptedResolutionException if the resolution has been interrupted
+ */
+ boolean resolve() throws InterruptedResolutionException;
+
+ /**
+ * Start the resolution process with the following flags.
+ * @param flags resolution flags
+ * @return <code>true</code> if the resolution has succeeded else <code>false</code>
+ * @throws InterruptedResolutionException if the resolution has been interrupted
+ */
+ boolean resolve(int flags) throws InterruptedResolutionException;
+
Requirement[] getUnsatisfiedRequirements();
Resource[] getOptionalResources();
@@ -70,16 +95,7 @@
Resource[] getRequiredResources();
- /**
- * Start the resolution process and return whether the constraints have
- * been successfully met or not.
- * The resolution can be interrupted by a call to Thread.interrupt() at any
- * time. The result will be to stop the resolver and throw an InterruptedException.
- *
- * @return <code>true</code> if the resolution has succeeded else <code>false</code>
- * @throws InterruptedResolutionException if the resolution has been interrupted
- */
- boolean resolve();
-
void deploy(boolean start);
+
+ void deploy(int flags);
}
\ No newline at end of file
diff --git a/bundlerepository/src/main/java/org/apache/felix/bundlerepository/impl/RepositoryAdminImpl.java b/bundlerepository/src/main/java/org/apache/felix/bundlerepository/impl/RepositoryAdminImpl.java
index 5a1db98..9e59ada 100644
--- a/bundlerepository/src/main/java/org/apache/felix/bundlerepository/impl/RepositoryAdminImpl.java
+++ b/bundlerepository/src/main/java/org/apache/felix/bundlerepository/impl/RepositoryAdminImpl.java
@@ -24,6 +24,7 @@
import java.util.Arrays;
import java.util.Comparator;
import java.util.HashMap;
+import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.StringTokenizer;
@@ -252,6 +253,18 @@
return new RepositoryImpl(null, url, 0, m_logger);
}
+ public Capability capability(String name, Map properties)
+ {
+ CapabilityImpl cap = new CapabilityImpl();
+ cap.setName(name);
+ for (Iterator it = properties.entrySet().iterator(); it.hasNext();)
+ {
+ Map.Entry e = (Map.Entry) it.next();
+ cap.addP((String) e.getKey(), e.getValue());
+ }
+ return cap;
+ }
+
private void initialize()
{
m_initialized = true;
diff --git a/bundlerepository/src/main/java/org/apache/felix/bundlerepository/impl/ResolverImpl.java b/bundlerepository/src/main/java/org/apache/felix/bundlerepository/impl/ResolverImpl.java
index b5bc169..07993ef 100644
--- a/bundlerepository/src/main/java/org/apache/felix/bundlerepository/impl/ResolverImpl.java
+++ b/bundlerepository/src/main/java/org/apache/felix/bundlerepository/impl/ResolverImpl.java
@@ -27,8 +27,6 @@
public class ResolverImpl implements Resolver
{
- public static final String PREFER_LOCAL = "obr.resolver.preferLocal";
-
private final BundleContext m_context;
private final Logger m_logger;
private final Repository[] m_repositories;
@@ -42,18 +40,14 @@
private final Map m_unsatisfiedMap = new HashMap();
private boolean m_resolved = false;
private long m_resolveTimeStamp;
- private boolean m_preferLocal = true;
+ private int m_resolutionFlags;
+ private int m_deployFlags;
public ResolverImpl(BundleContext context, Repository[] repositories, Logger logger)
{
m_context = context;
m_logger = logger;
m_repositories = repositories;
- String s = context.getProperty(PREFER_LOCAL);
- if (s != null)
- {
- m_preferLocal = Boolean.parseBoolean(s);
- }
}
public synchronized void add(Resource resource)
@@ -136,6 +130,14 @@
{
if (m_repositories[repoIdx].isLocal() == local)
{
+ boolean isLocal = m_repositories[repoIdx] instanceof LocalRepositoryImpl;
+ boolean isSystem = m_repositories[repoIdx] instanceof SystemRepositoryImpl;
+ if (isLocal && (m_resolutionFlags & NO_LOCAL_RESOURCES) != 0) {
+ continue;
+ }
+ if (isSystem && (m_resolutionFlags & NO_SYSTEM_BUNDLE) != 0) {
+ continue;
+ }
resources.addAll(Arrays.asList(m_repositories[repoIdx].getResources()));
}
}
@@ -144,6 +146,11 @@
public synchronized boolean resolve()
{
+ return resolve(0);
+ }
+
+ public synchronized boolean resolve(int flags)
+ {
// Find resources
Resource[] locals = getResources(true);
Resource[] remotes = getResources(false);
@@ -166,6 +173,7 @@
m_reasonMap.clear();
m_unsatisfiedMap.clear();
m_resolved = true;
+ m_resolutionFlags = flags;
boolean result = true;
@@ -230,9 +238,14 @@
Requirement[] reqs = resource.getRequirements();
if (reqs != null)
{
- Resource candidate = null;
+ Resource candidate;
for (int reqIdx = 0; reqIdx < reqs.length; reqIdx++)
{
+ // Do not resolve optional requirements
+ if ((m_resolutionFlags & NO_OPTIONAL_RESOURCES) != 0 && reqs[reqIdx].isOptional())
+ {
+ continue;
+ }
candidate = searchResources(reqs[reqIdx], m_addedSet);
if (candidate == null)
{
@@ -258,9 +271,9 @@
Capability bestCapability = getBestCandidate(candidateCapabilities);
// Try to resolve the best resource.
- if (resolve(((CapabilityImpl) bestCapability).getResource(), locals, remotes, optional || reqs[reqIdx].isOptional()))
+ if (resolve(bestCapability.getResource(), locals, remotes, optional || reqs[reqIdx].isOptional()))
{
- candidate = ((CapabilityImpl) bestCapability).getResource();
+ candidate = bestCapability.getResource();
}
else
{
@@ -354,7 +367,8 @@
/**
* Searches for resources that do meet the given requirement
- * @param req
+ * @param req the the requirement that must be satisfied by resources
+ * @param resources list of resources to look at
* @return all resources meeting the given requirement
*/
private List searchResources(Requirement req, Resource[] resources)
@@ -398,7 +412,7 @@
for(int capIdx = 0; capIdx < caps.size(); capIdx++)
{
Capability current = (Capability) caps.get(capIdx);
- boolean isCurrentLocal = ((CapabilityImpl) current).getResource().getRepository() == null;
+ boolean isCurrentLocal = current.getResource().getRepository() == null;
if (best == null)
{
@@ -410,15 +424,15 @@
bestVersion = (Version) v;
}
}
- else if (!m_preferLocal || !bestLocal || isCurrentLocal)
+ else if ((m_resolutionFlags & DO_NOT_PREFER_LOCAL) != 0 || !bestLocal || isCurrentLocal)
{
Object v = current.getProperties().get(Resource.VERSION);
// If there is no version, then select the resource
// with the greatest number of capabilities.
if ((v == null) && (bestVersion == null)
- && (((CapabilityImpl) best).getResource().getCapabilities().length
- < ((CapabilityImpl) current).getResource().getCapabilities().length))
+ && (best.getResource().getCapabilities().length
+ < current.getResource().getCapabilities().length))
{
best = current;
bestLocal = isCurrentLocal;
@@ -438,8 +452,8 @@
// best, then select the one with the greatest
// number of capabilities.
else if ((bestVersion != null) && (bestVersion.compareTo(v) == 0)
- && (((CapabilityImpl) best).getResource().getCapabilities().length
- < ((CapabilityImpl) current).getResource().getCapabilities().length))
+ && (best.getResource().getCapabilities().length
+ < current.getResource().getCapabilities().length))
{
best = current;
bestLocal = isCurrentLocal;
@@ -462,8 +476,14 @@
public synchronized void deploy(boolean start)
{
+ deploy(START);
+ }
+
+ public synchronized void deploy(int flags)
+ {
+ m_deployFlags = flags;
// Must resolve if not already resolved.
- if (!m_resolved && !resolve())
+ if (!m_resolved && !resolve(flags))
{
m_logger.log(Logger.LOG_ERROR, "Resolver: Cannot resolve target resources.");
return;
@@ -495,10 +515,13 @@
{
deployMap.put(resources[i], resources[i]);
}
- resources = getOptionalResources();
- for (int i = 0; (resources != null) && (i < resources.length); i++)
+ if ((flags & NO_OPTIONAL_RESOURCES) == 0)
{
- deployMap.put(resources[i], resources[i]);
+ resources = getOptionalResources();
+ for (int i = 0; (resources != null) && (i < resources.length); i++)
+ {
+ deployMap.put(resources[i], resources[i]);
+ }
}
Resource[] deployResources = (Resource[])
deployMap.keySet().toArray(new Resource[deployMap.size()]);
@@ -532,7 +555,7 @@
// stop the bundle before updating to prevent
// the bundle update from throwing due to not yet
// resolved dependencies
- boolean doStartBundle = start;
+ boolean doStartBundle = (flags & START) != 0;
if (localResource.getBundle().getState() == Bundle.ACTIVE)
{
doStartBundle = true;
@@ -582,7 +605,7 @@
// If necessary, save the installed bundle to be
// started later.
- if (start)
+ if ((flags & START) != 0)
{
if (!isFragmentBundle(bundle))
{