FELIX-2110: The resolver should be able to resolve for some requirements in addition to resources
git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@912353 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/bundlerepository/src/main/java/org/apache/felix/bundlerepository/RepositoryAdminImpl.java b/bundlerepository/src/main/java/org/apache/felix/bundlerepository/RepositoryAdminImpl.java
index 4209595..3ee0d5f 100644
--- a/bundlerepository/src/main/java/org/apache/felix/bundlerepository/RepositoryAdminImpl.java
+++ b/bundlerepository/src/main/java/org/apache/felix/bundlerepository/RepositoryAdminImpl.java
@@ -33,6 +33,7 @@
import org.osgi.framework.InvalidSyntaxException;
import org.osgi.service.obr.Repository;
import org.osgi.service.obr.RepositoryAdmin;
+import org.osgi.service.obr.Requirement;
import org.osgi.service.obr.Resolver;
import org.osgi.service.obr.Resource;
@@ -163,6 +164,21 @@
return resources;
}
+ public Requirement requirement(String name, String filter) {
+ RequirementImpl req = new RequirementImpl();
+ req.setName(name);
+ if (filter != null)
+ {
+ req.setFilter(filter);
+ }
+ return req;
+ }
+
+ public Filter filter(String filter) throws InvalidSyntaxException
+ {
+ return new FilterImpl(filter);
+ }
+
private void initialize()
{
m_initialized = true;
diff --git a/bundlerepository/src/main/java/org/apache/felix/bundlerepository/ResolverImpl.java b/bundlerepository/src/main/java/org/apache/felix/bundlerepository/ResolverImpl.java
index 6b58621..5f6dd3d 100644
--- a/bundlerepository/src/main/java/org/apache/felix/bundlerepository/ResolverImpl.java
+++ b/bundlerepository/src/main/java/org/apache/felix/bundlerepository/ResolverImpl.java
@@ -34,6 +34,7 @@
private final Logger m_logger;
private final LocalRepositoryImpl m_local;
private final Set m_addedSet = new HashSet();
+ private final Set m_addedRequirementSet = new HashSet();
private final Set m_failedSet = new HashSet();
private final Set m_resolveSet = new HashSet();
private final Set m_requiredSet = new HashSet();
@@ -49,7 +50,7 @@
m_context = context;
m_admin = admin;
m_logger = logger;
- m_local = admin.getLocalRepository();
+ m_local = admin.getLocalRepository();
String s = context.getProperty(PREFER_LOCAL);
if (s != null)
{
@@ -63,6 +64,22 @@
m_addedSet.add(resource);
}
+ public synchronized Resource[] getAddedResources()
+ {
+ return (Resource[]) m_addedSet.toArray(new Resource[m_addedSet.size()]);
+ }
+
+ public synchronized void add(Requirement requirement)
+ {
+ m_resolved = false;
+ m_addedRequirementSet.add(requirement);
+ }
+
+ public synchronized Requirement[] getAddedRequirements()
+ {
+ return (Requirement[]) m_addedRequirementSet.toArray(new Requirement[m_addedRequirementSet.size()]);
+ }
+
public synchronized Requirement[] getUnsatisfiedRequirements()
{
if (m_resolved)
@@ -114,11 +131,6 @@
throw new IllegalStateException("The resources have not been resolved.");
}
- public synchronized Resource[] getAddedResources()
- {
- return (Resource[]) m_addedSet.toArray(new Resource[m_addedSet.size()]);
- }
-
public synchronized boolean resolve()
{
// time of the resolution process start
@@ -135,6 +147,20 @@
boolean result = true;
+ // Add a fake resource if needed
+ if (!m_addedRequirementSet.isEmpty())
+ {
+ ResourceImpl fake = new ResourceImpl();
+ for (Iterator iter = m_addedRequirementSet.iterator(); iter.hasNext(); )
+ {
+ fake.addRequire((Requirement) iter.next());
+ }
+ if (!resolve(fake))
+ {
+ result = false;
+ }
+ }
+
// Loop through each resource in added list and resolve.
for (Iterator iter = m_addedSet.iterator(); iter.hasNext(); )
{
diff --git a/bundlerepository/src/test/java/org/apache/felix/bundlerepository/ResolverImplTest.java b/bundlerepository/src/test/java/org/apache/felix/bundlerepository/ResolverImplTest.java
index 293ef34..65bcca1 100644
--- a/bundlerepository/src/test/java/org/apache/felix/bundlerepository/ResolverImplTest.java
+++ b/bundlerepository/src/test/java/org/apache/felix/bundlerepository/ResolverImplTest.java
@@ -53,6 +53,16 @@
}
+ public void testResolveReq() throws Exception
+ {
+ RepositoryAdminImpl repoAdmin = createRepositoryAdmin();
+ repoAdmin.addRepository(getClass().getResource("/repo_for_resolvertest.xml"));
+
+ Resolver resolver = repoAdmin.resolver();
+ resolver.add(repoAdmin.requirement("package", "(package=org.apache.felix.test.osgi)"));
+ assertTrue(resolver.resolve());
+ }
+
public static void main(String[] args) throws Exception {
new ResolverImplTest().testReferral1();
diff --git a/org.osgi.service.obr/src/main/java/org/osgi/service/obr/RepositoryAdmin.java b/org.osgi.service.obr/src/main/java/org/osgi/service/obr/RepositoryAdmin.java
index 7468871..29fad00 100644
--- a/org.osgi.service.obr/src/main/java/org/osgi/service/obr/RepositoryAdmin.java
+++ b/org.osgi.service.obr/src/main/java/org/osgi/service/obr/RepositoryAdmin.java
@@ -23,6 +23,9 @@
import java.net.URL;
+import org.osgi.framework.Filter;
+import org.osgi.framework.InvalidSyntaxException;
+
/**
* Provides centralized access to the distributed repository.
*
@@ -75,7 +78,6 @@
/**
* Create a resolver.
*
- * @param resource
* @return
*/
Resolver resolver();
@@ -100,5 +102,22 @@
*/
Repository[] listRepositories();
- Resource getResource(String respositoryId);
+ Resource getResource(String repositoryId);
+
+ /**
+ * Create a simple requirement to be used for selection
+ * @param name
+ * @param filter
+ * @return
+ */
+ Requirement requirement(String name, String filter) throws InvalidSyntaxException;
+
+ /**
+ * Create an extender filter supporting the SUBSET, SUPERSET and other extensions
+ *
+ * @param filter the string filter
+ * @return
+ */
+ Filter filter(String filter) throws InvalidSyntaxException;
+
}
\ No newline at end of file
diff --git a/org.osgi.service.obr/src/main/java/org/osgi/service/obr/Resolver.java b/org.osgi.service.obr/src/main/java/org/osgi/service/obr/Resolver.java
index 629159b..a8a552d 100644
--- a/org.osgi.service.obr/src/main/java/org/osgi/service/obr/Resolver.java
+++ b/org.osgi.service.obr/src/main/java/org/osgi/service/obr/Resolver.java
@@ -24,8 +24,42 @@
public interface Resolver
{
+ /**
+ * Add the following resource to the resolution.
+ *
+ * The resource will be part of the output and all its requirements
+ * will be satisfied.
+ *
+ * It has the same effect has adding a requirement that will match
+ * this resource by symbolicname and version.
+ *
+ * The current resolution will be lost after adding a resource.
+ *
+ * @param resource the resource to add
+ */
void add(Resource resource);
+ /**
+ * Returns the list of resources that have been added to the resolution
+ * @return
+ */
+ Resource[] getAddedResources();
+
+ /**
+ * Add the following requirement to the resolution
+ *
+ * The current resolution will be lost after adding a requirement.
+ *
+ * @param requirement the requirement to add
+ */
+ void add(Requirement requirement);
+
+ /**
+ * Returns the list of requirements that have been added to the resolution
+ * @return
+ */
+ Requirement[] getAddedRequirements();
+
Requirement[] getUnsatisfiedRequirements();
Resource[] getOptionalResources();
@@ -36,8 +70,6 @@
Resource[] getRequiredResources();
- Resource[] getAddedResources();
-
boolean resolve();
void deploy(boolean start);