felix-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From rickh...@apache.org
Subject svn commit: r835915 [1/2] - in /felix/sandbox/rickhall/resolver/src/main/java/org/apache/felix/resolver: ./ cs/ felix/ manifestparser/ prototype/
Date Fri, 13 Nov 2009 16:50:35 GMT
Author: rickhall
Date: Fri Nov 13 16:50:35 2009
New Revision: 835915

URL: http://svn.apache.org/viewvc?rev=835915&view=rev
Log:
Modified prototype resolver to use capability sets and updated the existing
felix resolver to the trunk version with indexing.

Added:
    felix/sandbox/rickhall/resolver/src/main/java/org/apache/felix/resolver/cs/
    felix/sandbox/rickhall/resolver/src/main/java/org/apache/felix/resolver/cs/Attribute.java
    felix/sandbox/rickhall/resolver/src/main/java/org/apache/felix/resolver/cs/Capability.java
    felix/sandbox/rickhall/resolver/src/main/java/org/apache/felix/resolver/cs/CapabilitySet.java
    felix/sandbox/rickhall/resolver/src/main/java/org/apache/felix/resolver/cs/SimpleFilter.java
Removed:
    felix/sandbox/rickhall/resolver/src/main/java/org/apache/felix/resolver/Attribute.java
    felix/sandbox/rickhall/resolver/src/main/java/org/apache/felix/resolver/felix/PackageSource.java
Modified:
    felix/sandbox/rickhall/resolver/src/main/java/org/apache/felix/resolver/ExportedPackage.java
    felix/sandbox/rickhall/resolver/src/main/java/org/apache/felix/resolver/ImportedPackage.java
    felix/sandbox/rickhall/resolver/src/main/java/org/apache/felix/resolver/Main.java
    felix/sandbox/rickhall/resolver/src/main/java/org/apache/felix/resolver/Resolver.java
    felix/sandbox/rickhall/resolver/src/main/java/org/apache/felix/resolver/ResolverConflictException.java
    felix/sandbox/rickhall/resolver/src/main/java/org/apache/felix/resolver/VersionRange.java
    felix/sandbox/rickhall/resolver/src/main/java/org/apache/felix/resolver/felix/CandidateSet.java
    felix/sandbox/rickhall/resolver/src/main/java/org/apache/felix/resolver/felix/FelixResolver.java
    felix/sandbox/rickhall/resolver/src/main/java/org/apache/felix/resolver/felix/FelixResolverImpl.java
    felix/sandbox/rickhall/resolver/src/main/java/org/apache/felix/resolver/felix/ResolvedPackage.java
    felix/sandbox/rickhall/resolver/src/main/java/org/apache/felix/resolver/manifestparser/Main.java
    felix/sandbox/rickhall/resolver/src/main/java/org/apache/felix/resolver/prototype/ProtoResolver.java

Modified: felix/sandbox/rickhall/resolver/src/main/java/org/apache/felix/resolver/ExportedPackage.java
URL: http://svn.apache.org/viewvc/felix/sandbox/rickhall/resolver/src/main/java/org/apache/felix/resolver/ExportedPackage.java?rev=835915&r1=835914&r2=835915&view=diff
==============================================================================
--- felix/sandbox/rickhall/resolver/src/main/java/org/apache/felix/resolver/ExportedPackage.java (original)
+++ felix/sandbox/rickhall/resolver/src/main/java/org/apache/felix/resolver/ExportedPackage.java Fri Nov 13 16:50:35 2009
@@ -18,26 +18,35 @@
  */
 package org.apache.felix.resolver;
 
+import org.apache.felix.resolver.cs.Attribute;
 import java.util.ArrayList;
 import java.util.HashMap;
-import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
-import java.util.Map.Entry;
 import java.util.StringTokenizer;
+import org.apache.felix.resolver.cs.Capability;
 import org.apache.felix.resolver.manifestparser.Constants;
 
-public class ExportedPackage
+public class ExportedPackage implements Capability
 {
+    private final Module m_module;
     private final String m_name;
     private final List m_uses;
     private final Map<String, Attribute> m_attrs;
 
-    public ExportedPackage(String name)
+    public ExportedPackage(Module module, String name)
     {
+        m_module = module;
         m_name = name;
         m_uses = new ArrayList<String>();
         m_attrs = new HashMap<String, Attribute>();
+        // Make package name an attribute too.
+        with("package=" + m_name);
+    }
+
+    public Module getModule()
+    {
+        return m_module;
     }
 
     public String getName()
@@ -99,7 +108,7 @@
     {
         return m_attrs.get(name);
     }
-
+/*
     public boolean satisfies(ImportedPackage ip)
     {
         boolean result = true;
@@ -119,7 +128,7 @@
 
         return result;
     }
-
+*/
     public List<String> getUses()
     {
         return m_uses;
@@ -127,6 +136,6 @@
 
     public String toString()
     {
-        return "export " + m_name;
+        return "export " + m_name + " (" + getModule() + ")";
     }
 }
\ No newline at end of file

Modified: felix/sandbox/rickhall/resolver/src/main/java/org/apache/felix/resolver/ImportedPackage.java
URL: http://svn.apache.org/viewvc/felix/sandbox/rickhall/resolver/src/main/java/org/apache/felix/resolver/ImportedPackage.java?rev=835915&r1=835914&r2=835915&view=diff
==============================================================================
--- felix/sandbox/rickhall/resolver/src/main/java/org/apache/felix/resolver/ImportedPackage.java (original)
+++ felix/sandbox/rickhall/resolver/src/main/java/org/apache/felix/resolver/ImportedPackage.java Fri Nov 13 16:50:35 2009
@@ -18,10 +18,12 @@
  */
 package org.apache.felix.resolver;
 
+import org.apache.felix.resolver.cs.Attribute;
 import java.util.HashMap;
 import java.util.Iterator;
 import java.util.Map;
 import java.util.Map.Entry;
+import org.apache.felix.resolver.cs.SimpleFilter;
 import org.apache.felix.resolver.manifestparser.Constants;
 
 public class ImportedPackage
@@ -29,11 +31,13 @@
     private final String m_name;
     private final Map<String, Attribute> m_attrs;
     private boolean m_optional = false;
+    private SimpleFilter m_filter;
 
     public ImportedPackage(String name)
     {
         m_name = name;
         m_attrs = new HashMap<String, Attribute>();
+        getFilter();
     }
 
     public ImportedPackage optional()
@@ -52,13 +56,16 @@
             if (n.equalsIgnoreCase(Constants.VERSION_ATTRIBUTE)
                 || n.equalsIgnoreCase(Constants.BUNDLE_VERSION_ATTRIBUTE))
             {
-                m_attrs.put(n, new Attribute(n, VersionRange.parse(v), false));
+//                m_attrs.put(n, new Attribute(n, VersionRange.parse(v), false));
+                m_attrs.put(n, new Attribute(n, Version.parseVersion(v), false));
             }
             else
             {
                 m_attrs.put(n, new Attribute(n, v, false));
             }
         }
+        m_filter = null;
+        getFilter();
         return this;
     }
 
@@ -67,11 +74,20 @@
         return m_name;
     }
 
+    public SimpleFilter getFilter()
+    {
+        if (m_filter == null)
+        {
+            m_filter = SimpleFilter.parse(convertToFilter());
+        }
+        return m_filter;
+    }
+/*
     public Attribute getAttribute(String name)
     {
         return m_attrs.get(name);
     }
-
+*/
     public boolean isSatistfiedBy(ExportedPackage ep)
     {
         boolean result = m_name.equals(ep.getName());
@@ -87,7 +103,7 @@
                 {
                     if (epAttr.getValue() instanceof Version)
                     {
-                        result = ((VersionRange) attr.getValue()).isInRange((Version) epAttr.getValue());
+                        result = ((Version) attr.getValue()).compareTo(epAttr.getValue()) <= 0;
                     }
                     else
                     {
@@ -104,10 +120,10 @@
         }
 
         // Check mandatory export attributes.
-        if (result)
-        {
-            result = ep.satisfies(this);
-        }
+//        if (result)
+//        {
+//            result = ep.satisfies(this);
+//        }
 
         return result;
     }
@@ -137,4 +153,79 @@
         }
         return sb.toString();
     }
+
+    private String convertToFilter()
+    {
+        StringBuffer sb = new StringBuffer();
+        if ((m_attrs != null) && (m_attrs.size() > 0))
+        {
+            sb.append("(&");
+        }
+
+        sb.append("(package=");
+        sb.append(m_name);
+        sb.append(")");
+
+        for (Iterator<Entry<String, Attribute>> it = m_attrs.entrySet().iterator(); it.hasNext(); )
+        {
+            Entry<String, Attribute> entry = it.next();
+/*
+            if (m_attrs.get(i).getValue() instanceof VersionRange)
+            {
+                VersionRange vr = (VersionRange) m_attributes[i].getValue();
+                if (vr.isLowInclusive())
+                {
+                    sb.append("(");
+                    sb.append(m_attributes[i].getName());
+                    sb.append(">=");
+                    sb.append(vr.getLow().toString());
+                    sb.append(")");
+                }
+                else
+                {
+                    sb.append("(!(");
+                    sb.append(m_attributes[i].getName());
+                    sb.append("<=");
+                    sb.append(vr.getLow().toString());
+                    sb.append("))");
+                }
+
+                if (vr.getHigh() != null)
+                {
+                    if (vr.isHighInclusive())
+                    {
+                        sb.append("(");
+                        sb.append(m_attributes[i].getName());
+                        sb.append("<=");
+                        sb.append(vr.getHigh().toString());
+                        sb.append(")");
+                    }
+                    else
+                    {
+                        sb.append("(!(");
+                        sb.append(m_attributes[i].getName());
+                        sb.append(">=");
+                        sb.append(vr.getHigh().toString());
+                        sb.append("))");
+                    }
+                }
+            }
+*/
+//            else
+//            {
+                sb.append("(");
+                sb.append(entry.getValue().getName());
+                sb.append("=");
+                sb.append(entry.getValue().getValue().toString());
+                sb.append(")");
+//            }
+        }
+
+        if ((m_attrs != null) && (m_attrs.size() > 0))
+        {
+            sb.append(")");
+        }
+
+        return sb.toString();
+    }
 }
\ No newline at end of file

Modified: felix/sandbox/rickhall/resolver/src/main/java/org/apache/felix/resolver/Main.java
URL: http://svn.apache.org/viewvc/felix/sandbox/rickhall/resolver/src/main/java/org/apache/felix/resolver/Main.java?rev=835915&r1=835914&r2=835915&view=diff
==============================================================================
--- felix/sandbox/rickhall/resolver/src/main/java/org/apache/felix/resolver/Main.java (original)
+++ felix/sandbox/rickhall/resolver/src/main/java/org/apache/felix/resolver/Main.java Fri Nov 13 16:50:35 2009
@@ -26,7 +26,6 @@
 import java.util.Map;
 import java.util.Map.Entry;
 import org.apache.felix.resolver.prototype.ProtoResolver;
-import org.apache.felix.resolver.felix.FelixResolver;
 
 public class Main
 {
@@ -40,15 +39,13 @@
             System.exit(0);
         }
 
-        List<Module> moduleList = new ArrayList<Module>();
         String scenario = "1";
-
-        Resolver resolver = new ProtoResolver(moduleList);
+        boolean legacy = false;
         for (int i = 0; i < args.length; i++)
         {
             if (args[i].equals("-legacy"))
             {
-                resolver = new FelixResolver(moduleList);
+                legacy = true;
             }
             else
             {
@@ -56,12 +53,16 @@
             }
         }
 
-        Module module = setupScenario(moduleList, scenario);
+        List<Module> moduleList = new ArrayList<Module>();
+        Module targetModule = setupScenario(moduleList, scenario);
+
+//        Resolver resolver = (legacy) ? new FelixResolver(moduleList) : new ProtoResolver(moduleList);
+        Resolver resolver = new ProtoResolver(moduleList);
 
         try
         {
             long starttime = System.currentTimeMillis();
-            Map<Module, List<Wire>> wireMap = resolver.resolve(module);
+            Map<Module, List<Wire>> wireMap = resolver.resolve(targetModule);
             long endtime = System.currentTimeMillis();
             System.out.println("Resolve time: " + (endtime - starttime));
             System.out.println("Wires:");
@@ -102,39 +103,39 @@
     // E: dit->F
     private static Module scenario1(List<Module> moduleList)
     {
-        Module target;
+        Module m, target;
 
         // Bundle A
         moduleList.add(
-            target = new Module("A")
+            target = (m = new Module("A"))
                 .importing(new ImportedPackage("bar"))
                 .importing(new ImportedPackage("baz")));
         // Bundle B
         moduleList.add(
-            new Module("B")
-                .exporting(new ExportedPackage("bar").using("woz"))
+            (m = new Module("B"))
+                .exporting(new ExportedPackage(m, "bar").using("woz"))
                 .importing(new ImportedPackage("woz")));
         // Bundle C
         moduleList.add(
-            new Module("C")
-                .exporting(new ExportedPackage("woz").using("foo"))
-                .exporting(new ExportedPackage("foo")));
+            (m = new Module("C"))
+                .exporting(new ExportedPackage(m, "woz").using("foo"))
+                .exporting(new ExportedPackage(m, "foo")));
         // Bundle D
         moduleList.add(
-            new Module("D")
-                .exporting(new ExportedPackage("woz"))
-                .exporting(new ExportedPackage("unused")));
+            (m = new Module("D"))
+                .exporting(new ExportedPackage(m, "woz"))
+                .exporting(new ExportedPackage(m, "unused")));
         // Bundle E
         moduleList.add(
-            new Module("E")
-                .exporting(new ExportedPackage("baz").using("dit"))
-                .exporting(new ExportedPackage("unused"))
+            (m = new Module("E"))
+                .exporting(new ExportedPackage(m, "baz").using("dit"))
+                .exporting(new ExportedPackage(m, "unused"))
                 .importing(new ImportedPackage("dit")));
         // Bundle F
         moduleList.add(
-            new Module("F")
-                .exporting(new ExportedPackage("dit").using("foo"))
-                .exporting(new ExportedPackage("foo")));
+            (m = new Module("F"))
+                .exporting(new ExportedPackage(m, "dit").using("foo"))
+                .exporting(new ExportedPackage(m, "foo")));
 
         return target;
     }
@@ -143,45 +144,45 @@
     // A: bar->B, woz->E
     private static Module scenario2(List<Module> moduleList)
     {
-        Module target;
+        Module m, target;
 
         // Bundle A
         moduleList.add(
-            target = new Module("A")
-                .exporting(new ExportedPackage("foo"))
+            target = (m = new Module("A"))
+                .exporting(new ExportedPackage(m, "foo"))
                 .importing(new ImportedPackage("bar"))
                 .importing(new ImportedPackage("woz")));
         // Bundle B
         moduleList.add(
-            new Module("B")
-                .exporting(new ExportedPackage("bar").using("baz,boo"))
-                .exporting(new ExportedPackage("baz"))
-                .exporting(new ExportedPackage("boo")));
+            (m = new Module("B"))
+                .exporting(new ExportedPackage(m, "bar").using("baz,boo"))
+                .exporting(new ExportedPackage(m, "baz"))
+                .exporting(new ExportedPackage(m, "boo")));
         // Bundle C
         moduleList.add(
-            new Module("C")
-                .exporting(new ExportedPackage("woz").using("bar,dir"))
+            (m = new Module("C"))
+                .exporting(new ExportedPackage(m, "woz").using("bar,dir"))
                 .importing(new ImportedPackage("bar"))
                 .importing(new ImportedPackage("dit")));
         // Bundle D
         moduleList.add(
-            new Module("D")
-                .exporting(new ExportedPackage("dit").using("dot"))
+            (m = new Module("D"))
+                .exporting(new ExportedPackage(m, "dit").using("dot"))
                 .importing(new ImportedPackage("dot")));
         // Bundle E
         moduleList.add(
-            new Module("E")
-                .exporting(new ExportedPackage("dot").using("woz"))
-                .exporting(new ExportedPackage("woz")));
+            (m = new Module("E"))
+                .exporting(new ExportedPackage(m, "dot").using("woz"))
+                .exporting(new ExportedPackage(m, "woz")));
         // Bundle F
         moduleList.add(
-            new Module("F")
-                .exporting(new ExportedPackage("woz").using("bar"))
+            (m = new Module("F"))
+                .exporting(new ExportedPackage(m, "woz").using("bar"))
                 .importing(new ImportedPackage("bar")));
         // Bundle G
         moduleList.add(
-            new Module("G")
-                .exporting(new ExportedPackage("dot")));
+            (m = new Module("G"))
+                .exporting(new ExportedPackage(m, "dot")));
 
         return target;
     }
@@ -190,29 +191,29 @@
     // A: bar->C, baz->D
     private static Module scenario3(List<Module> moduleList)
     {
-        Module target;
+        Module m, target;
 
         // Bundle A
         moduleList.add(
-            target = new Module("A")
-                .exporting(new ExportedPackage("foo"))
+            target = (m = new Module("A"))
+                .exporting(new ExportedPackage(m, "foo"))
                 .importing(new ImportedPackage("bar"))
                 .importing(new ImportedPackage("baz")));
         // Bundle B
         moduleList.add(
-            new Module("B")
-                .exporting(new ExportedPackage("bar").using("foo"))
-                .exporting(new ExportedPackage("baz").using("foo"))
-                .exporting(new ExportedPackage("foo")));
+            (m = new Module("B"))
+                .exporting(new ExportedPackage(m, "bar").using("foo"))
+                .exporting(new ExportedPackage(m, "baz").using("foo"))
+                .exporting(new ExportedPackage(m, "foo")));
         // Bundle C
         moduleList.add(
-            new Module("C")
-                .exporting(new ExportedPackage("bar").using("woz"))
-                .exporting(new ExportedPackage("woz")));
+            (m = new Module("C"))
+                .exporting(new ExportedPackage(m, "bar").using("woz"))
+                .exporting(new ExportedPackage(m, "woz")));
         // Bundle D
         moduleList.add(
-            new Module("D")
-                .exporting(new ExportedPackage("baz")));
+            (m = new Module("D"))
+                .exporting(new ExportedPackage(m, "baz")));
 
         return target;
     }
@@ -221,40 +222,40 @@
     // C: a->D, b->D, c->D, ..., foo->A, bar->A
     private static Module scenario4(List<Module> moduleList)
     {
-        Module target;
+        Module m, target;
 
         // Bundle A
         moduleList.add(
-            new Module("A")
-                .exporting(new ExportedPackage("bar").using("foo"))
-                .exporting(new ExportedPackage("foo")));
+            (m = new Module("A"))
+                .exporting(new ExportedPackage(m, "bar").using("foo"))
+                .exporting(new ExportedPackage(m, "foo")));
         // Bundle B
         moduleList.add(
-            new Module("B")
-                .exporting(new ExportedPackage("a").using("foo"))
-                .exporting(new ExportedPackage("b").using("foo"))
-                .exporting(new ExportedPackage("c").using("foo"))
-                .exporting(new ExportedPackage("d").using("foo"))
-                .exporting(new ExportedPackage("e").using("foo"))
-                .exporting(new ExportedPackage("f").using("foo"))
-                .exporting(new ExportedPackage("g").using("foo"))
-                .exporting(new ExportedPackage("h").using("foo"))
-                .exporting(new ExportedPackage("i").using("foo"))
-                .exporting(new ExportedPackage("j").using("foo"))
-                .exporting(new ExportedPackage("k").using("foo"))
-                .exporting(new ExportedPackage("l").using("foo"))
-                .exporting(new ExportedPackage("m").using("foo"))
-                .exporting(new ExportedPackage("n").using("foo"))
-                .exporting(new ExportedPackage("o").using("foo"))
-                .exporting(new ExportedPackage("p").using("foo"))
-                .exporting(new ExportedPackage("q").using("foo"))
-                .exporting(new ExportedPackage("r").using("foo"))
-                .exporting(new ExportedPackage("s").using("foo"))
-                .exporting(new ExportedPackage("t").using("foo"))
-                .exporting(new ExportedPackage("foo")));
+            (m = new Module("B"))
+                .exporting(new ExportedPackage(m, "a").using("foo"))
+                .exporting(new ExportedPackage(m, "b").using("foo"))
+                .exporting(new ExportedPackage(m, "c").using("foo"))
+                .exporting(new ExportedPackage(m, "d").using("foo"))
+                .exporting(new ExportedPackage(m, "e").using("foo"))
+                .exporting(new ExportedPackage(m, "f").using("foo"))
+                .exporting(new ExportedPackage(m, "g").using("foo"))
+                .exporting(new ExportedPackage(m, "h").using("foo"))
+                .exporting(new ExportedPackage(m, "i").using("foo"))
+                .exporting(new ExportedPackage(m, "j").using("foo"))
+                .exporting(new ExportedPackage(m, "k").using("foo"))
+                .exporting(new ExportedPackage(m, "l").using("foo"))
+                .exporting(new ExportedPackage(m, "m").using("foo"))
+                .exporting(new ExportedPackage(m, "n").using("foo"))
+                .exporting(new ExportedPackage(m, "o").using("foo"))
+                .exporting(new ExportedPackage(m, "p").using("foo"))
+                .exporting(new ExportedPackage(m, "q").using("foo"))
+                .exporting(new ExportedPackage(m, "r").using("foo"))
+                .exporting(new ExportedPackage(m, "s").using("foo"))
+                .exporting(new ExportedPackage(m, "t").using("foo"))
+                .exporting(new ExportedPackage(m, "foo")));
         // Bundle C
         moduleList.add(
-            target = new Module("C")
+            target = (m = new Module("C"))
                 .importing(new ImportedPackage("a"))
                 .importing(new ImportedPackage("b"))
                 .importing(new ImportedPackage("c"))
@@ -279,27 +280,27 @@
                 .importing(new ImportedPackage("bar")));
         // Bundle D
         moduleList.add(
-            new Module("D")
-                .exporting(new ExportedPackage("a"))
-                .exporting(new ExportedPackage("b"))
-                .exporting(new ExportedPackage("c"))
-                .exporting(new ExportedPackage("d"))
-                .exporting(new ExportedPackage("e"))
-                .exporting(new ExportedPackage("f"))
-                .exporting(new ExportedPackage("g"))
-                .exporting(new ExportedPackage("h"))
-                .exporting(new ExportedPackage("i"))
-                .exporting(new ExportedPackage("j"))
-                .exporting(new ExportedPackage("k"))
-                .exporting(new ExportedPackage("l"))
-                .exporting(new ExportedPackage("m"))
-                .exporting(new ExportedPackage("n"))
-                .exporting(new ExportedPackage("o"))
-                .exporting(new ExportedPackage("p"))
-                .exporting(new ExportedPackage("q"))
-                .exporting(new ExportedPackage("r"))
-                .exporting(new ExportedPackage("s"))
-                .exporting(new ExportedPackage("t")));
+            (m = new Module("D"))
+                .exporting(new ExportedPackage(m, "a"))
+                .exporting(new ExportedPackage(m, "b"))
+                .exporting(new ExportedPackage(m, "c"))
+                .exporting(new ExportedPackage(m, "d"))
+                .exporting(new ExportedPackage(m, "e"))
+                .exporting(new ExportedPackage(m, "f"))
+                .exporting(new ExportedPackage(m, "g"))
+                .exporting(new ExportedPackage(m, "h"))
+                .exporting(new ExportedPackage(m, "i"))
+                .exporting(new ExportedPackage(m, "j"))
+                .exporting(new ExportedPackage(m, "k"))
+                .exporting(new ExportedPackage(m, "l"))
+                .exporting(new ExportedPackage(m, "m"))
+                .exporting(new ExportedPackage(m, "n"))
+                .exporting(new ExportedPackage(m, "o"))
+                .exporting(new ExportedPackage(m, "p"))
+                .exporting(new ExportedPackage(m, "q"))
+                .exporting(new ExportedPackage(m, "r"))
+                .exporting(new ExportedPackage(m, "s"))
+                .exporting(new ExportedPackage(m, "t")));
 
         return target;
     }
@@ -308,40 +309,40 @@
     // C: a->D, b->D, c->E, d->E, e->F, f->F, ..., foo->A, bar->A
     private static Module scenario5(List<Module> moduleList)
     {
-        Module target;
+        Module m, target;
 
         // Bundle A
         moduleList.add(
-            new Module("A")
-                .exporting(new ExportedPackage("bar").using("foo"))
-                .exporting(new ExportedPackage("foo")));
+            (m = new Module("A"))
+                .exporting(new ExportedPackage(m, "bar").using("foo"))
+                .exporting(new ExportedPackage(m, "foo")));
         // Bundle B
         moduleList.add(
-            new Module("B")
-                .exporting(new ExportedPackage("a").using("foo"))
-                .exporting(new ExportedPackage("b").using("foo"))
-                .exporting(new ExportedPackage("c").using("foo"))
-                .exporting(new ExportedPackage("d").using("foo"))
-                .exporting(new ExportedPackage("e").using("foo"))
-                .exporting(new ExportedPackage("f").using("foo"))
-                .exporting(new ExportedPackage("g").using("foo"))
-                .exporting(new ExportedPackage("h").using("foo"))
-                .exporting(new ExportedPackage("i").using("foo"))
-                .exporting(new ExportedPackage("j").using("foo"))
-                .exporting(new ExportedPackage("k").using("foo"))
-                .exporting(new ExportedPackage("l").using("foo"))
-                .exporting(new ExportedPackage("m").using("foo"))
-                .exporting(new ExportedPackage("n").using("foo"))
-                .exporting(new ExportedPackage("o").using("foo"))
-                .exporting(new ExportedPackage("p").using("foo"))
-                .exporting(new ExportedPackage("q").using("foo"))
-                .exporting(new ExportedPackage("r").using("foo"))
-                .exporting(new ExportedPackage("s").using("foo"))
-                .exporting(new ExportedPackage("t").using("foo"))
-                .exporting(new ExportedPackage("foo")));
+            (m = new Module("B"))
+                .exporting(new ExportedPackage(m, "a").using("foo"))
+                .exporting(new ExportedPackage(m, "b").using("foo"))
+                .exporting(new ExportedPackage(m, "c").using("foo"))
+                .exporting(new ExportedPackage(m, "d").using("foo"))
+                .exporting(new ExportedPackage(m, "e").using("foo"))
+                .exporting(new ExportedPackage(m, "f").using("foo"))
+                .exporting(new ExportedPackage(m, "g").using("foo"))
+                .exporting(new ExportedPackage(m, "h").using("foo"))
+                .exporting(new ExportedPackage(m, "i").using("foo"))
+                .exporting(new ExportedPackage(m, "j").using("foo"))
+                .exporting(new ExportedPackage(m, "k").using("foo"))
+                .exporting(new ExportedPackage(m, "l").using("foo"))
+                .exporting(new ExportedPackage(m, "m").using("foo"))
+                .exporting(new ExportedPackage(m, "n").using("foo"))
+                .exporting(new ExportedPackage(m, "o").using("foo"))
+                .exporting(new ExportedPackage(m, "p").using("foo"))
+                .exporting(new ExportedPackage(m, "q").using("foo"))
+                .exporting(new ExportedPackage(m, "r").using("foo"))
+                .exporting(new ExportedPackage(m, "s").using("foo"))
+                .exporting(new ExportedPackage(m, "t").using("foo"))
+                .exporting(new ExportedPackage(m, "foo")));
         // Bundle C
         moduleList.add(
-            target = new Module("C")
+            target = (m = new Module("C"))
                 .importing(new ImportedPackage("a"))
                 .importing(new ImportedPackage("b"))
                 .importing(new ImportedPackage("c"))
@@ -366,54 +367,54 @@
                 .importing(new ImportedPackage("bar")));
         // Bundle D
         moduleList.add(
-            new Module("D")
-                .exporting(new ExportedPackage("a"))
-                .exporting(new ExportedPackage("b")));
+            (m = new Module("D"))
+                .exporting(new ExportedPackage(m, "a"))
+                .exporting(new ExportedPackage(m, "b")));
         // Bundle E
         moduleList.add(
-            new Module("E")
-                .exporting(new ExportedPackage("c"))
-                .exporting(new ExportedPackage("d")));
+            (m = new Module("E"))
+                .exporting(new ExportedPackage(m, "c"))
+                .exporting(new ExportedPackage(m, "d")));
         // Bundle F
         moduleList.add(
-            new Module("F")
-                .exporting(new ExportedPackage("e"))
-                .exporting(new ExportedPackage("f")));
+            (m = new Module("F"))
+                .exporting(new ExportedPackage(m, "e"))
+                .exporting(new ExportedPackage(m, "f")));
         // Bundle G
         moduleList.add(
-            new Module("G")
-                .exporting(new ExportedPackage("g"))
-                .exporting(new ExportedPackage("h")));
+            (m = new Module("G"))
+                .exporting(new ExportedPackage(m, "g"))
+                .exporting(new ExportedPackage(m, "h")));
         // Bundle H
         moduleList.add(
-            new Module("H")
-                .exporting(new ExportedPackage("i"))
-                .exporting(new ExportedPackage("j")));
+            (m = new Module("H"))
+                .exporting(new ExportedPackage(m, "i"))
+                .exporting(new ExportedPackage(m, "j")));
         // Bundle I
         moduleList.add(
-            new Module("I")
-                .exporting(new ExportedPackage("k"))
-                .exporting(new ExportedPackage("l")));
+            (m = new Module("I"))
+                .exporting(new ExportedPackage(m, "k"))
+                .exporting(new ExportedPackage(m, "l")));
         // Bundle J
         moduleList.add(
-            new Module("J")
-                .exporting(new ExportedPackage("m"))
-                .exporting(new ExportedPackage("n")));
+            (m = new Module("J"))
+                .exporting(new ExportedPackage(m, "m"))
+                .exporting(new ExportedPackage(m, "n")));
         // Bundle K
         moduleList.add(
-            new Module("K")
-                .exporting(new ExportedPackage("o"))
-                .exporting(new ExportedPackage("p")));
+            (m = new Module("K"))
+                .exporting(new ExportedPackage(m, "o"))
+                .exporting(new ExportedPackage(m, "p")));
         // Bundle L
         moduleList.add(
-            new Module("L")
-                .exporting(new ExportedPackage("q"))
-                .exporting(new ExportedPackage("r")));
+            (m = new Module("L"))
+                .exporting(new ExportedPackage(m, "q"))
+                .exporting(new ExportedPackage(m, "r")));
         // Bundle M
         moduleList.add(
-            new Module("M")
-                .exporting(new ExportedPackage("s"))
-                .exporting(new ExportedPackage("t")));
+            (m = new Module("M"))
+                .exporting(new ExportedPackage(m, "s"))
+                .exporting(new ExportedPackage(m, "t")));
 
         return target;
     }
@@ -422,11 +423,11 @@
     // A: baz cannot be resolved
     private static Module scenario6(List<Module> moduleList)
     {
-        Module target;
+        Module m, target;
 
         // Bundle A
         moduleList.add(
-            target = new Module("A")
+            target = (m = new Module("A"))
                 .importing(new ImportedPackage("foo"))
                 .importing(new ImportedPackage("bar"))
                 .importing(new ImportedPackage("baz")
@@ -434,15 +435,15 @@
 
         // Bundle B
         moduleList.add(
-            new Module("B")
-                .exporting(new ExportedPackage("foo").using("bar"))
-                .exporting(new ExportedPackage("bar").using("baz"))
-                .exporting(new ExportedPackage("baz")));
+            (m = new Module("B"))
+                .exporting(new ExportedPackage(m, "foo").using("bar"))
+                .exporting(new ExportedPackage(m, "bar").using("baz"))
+                .exporting(new ExportedPackage(m, "baz")));
 
         // Bundle C
         moduleList.add(
-            new Module("C")
-                .exporting(new ExportedPackage("baz")
+            (m = new Module("C"))
+                .exporting(new ExportedPackage(m, "baz")
                     .with("attr=blah")));
 
         return target;
@@ -454,22 +455,22 @@
     // C: foo->A
     private static Module scenario7(List<Module> moduleList)
     {
-        Module target;
+        Module m, target;
 
         // Bundle A
         moduleList.add(
-            target = new Module("A")
-                .exporting(new ExportedPackage("foo"))
+            target = (m = new Module("A"))
+                .exporting(new ExportedPackage(m, "foo"))
                 .importing(new ImportedPackage("bar")));
         // Bundle B
         moduleList.add(
-            new Module("B")
-                .exporting(new ExportedPackage("bar"))
+            (m = new Module("B"))
+                .exporting(new ExportedPackage(m, "bar"))
                 .importing(new ImportedPackage("woz")));
         // Bundle C
         moduleList.add(
-            new Module("C")
-                .exporting(new ExportedPackage("woz"))
+            (m = new Module("C"))
+                .exporting(new ExportedPackage(m, "woz"))
                 .importing(new ImportedPackage("foo")));
 
         return target;
@@ -479,24 +480,24 @@
     // A: bar->C, baz->B
     private static Module scenario8(List<Module> moduleList)
     {
-        Module target;
+        Module m, target;
 
         // Bundle A
         moduleList.add(
-            target = new Module("A")
-                .exporting(new ExportedPackage("foo"))
+            target = (m = new Module("A"))
+                .exporting(new ExportedPackage(m, "foo"))
                 .importing(new ImportedPackage("bar"))
                 .importing(new ImportedPackage("baz")));
         // Bundle B
         moduleList.add(
-            new Module("B")
-                .exporting(new ExportedPackage("foo"))
-                .exporting(new ExportedPackage("bar").using("foo"))
-                .exporting(new ExportedPackage("baz")));
+            (m = new Module("B"))
+                .exporting(new ExportedPackage(m, "foo"))
+                .exporting(new ExportedPackage(m, "bar").using("foo"))
+                .exporting(new ExportedPackage(m, "baz")));
         // Bundle C
         moduleList.add(
-            new Module("C")
-                .exporting(new ExportedPackage("bar")));
+            (m = new Module("C"))
+                .exporting(new ExportedPackage(m, "bar")));
 
         return target;
     }
@@ -505,31 +506,31 @@
     // B: foo->C, foobar->A, bar->C, baz->C
     private static Module scenario9(List<Module> moduleList)
     {
-        Module target;
+        Module m, target;
 
         // Bundle A
         moduleList.add(
-            new Module("A")
-                .exporting(new ExportedPackage("foo"))
-                .exporting(new ExportedPackage("foobar"))
-                .exporting(new ExportedPackage("bar").using("foo")));
+            (m = new Module("A"))
+                .exporting(new ExportedPackage(m, "foo"))
+                .exporting(new ExportedPackage(m, "foobar"))
+                .exporting(new ExportedPackage(m, "bar").using("foo")));
         // Bundle B
         moduleList.add(
-            target = new Module("B")
+            target = (m = new Module("B"))
                 .importing(new ImportedPackage("foo"))
                 .importing(new ImportedPackage("foobar"))
                 .importing(new ImportedPackage("bar"))
                 .importing(new ImportedPackage("baz")));
         // Bundle C
         moduleList.add(
-            new Module("C")
-                .exporting(new ExportedPackage("foo"))
-                .exporting(new ExportedPackage("bar").using("foo"))
-                .exporting(new ExportedPackage("baz").using("bar")));
+            (m = new Module("C"))
+                .exporting(new ExportedPackage(m, "foo"))
+                .exporting(new ExportedPackage(m, "bar").using("foo"))
+                .exporting(new ExportedPackage(m, "baz").using("bar")));
         // Bundle D
         moduleList.add(
-            new Module("D")
-                .exporting(new ExportedPackage("bar")));
+            (m = new Module("D"))
+                .exporting(new ExportedPackage(m, "bar")));
 
         return target;
     }
@@ -538,20 +539,20 @@
     // B: foo->C
     private static Module scenario10(List<Module> moduleList)
     {
-        Module target;
+        Module m, target;
 
         // Bundle A
         moduleList.add(
-            new Module("A")
-                .exporting(new ExportedPackage("foo").withMandatory("vendor=foo")));
+            (m = new Module("A"))
+                .exporting(new ExportedPackage(m, "foo").withMandatory("vendor=foo")));
         // Bundle B
         moduleList.add(
-            target = new Module("B")
+            target = (m = new Module("B"))
                 .importing(new ImportedPackage("foo")));
         // Bundle C
         moduleList.add(
-            new Module("C")
-                .exporting(new ExportedPackage("foo")));
+            (m = new Module("C"))
+                .exporting(new ExportedPackage(m, "foo")));
 
         return target;
     }

Modified: felix/sandbox/rickhall/resolver/src/main/java/org/apache/felix/resolver/Resolver.java
URL: http://svn.apache.org/viewvc/felix/sandbox/rickhall/resolver/src/main/java/org/apache/felix/resolver/Resolver.java?rev=835915&r1=835914&r2=835915&view=diff
==============================================================================
--- felix/sandbox/rickhall/resolver/src/main/java/org/apache/felix/resolver/Resolver.java (original)
+++ felix/sandbox/rickhall/resolver/src/main/java/org/apache/felix/resolver/Resolver.java Fri Nov 13 16:50:35 2009
@@ -23,7 +23,5 @@
 
 public interface Resolver
 {
-    Module getModule(String name);
-
     Map<Module, List<Wire>> resolve(Module module);
 }
\ No newline at end of file

Modified: felix/sandbox/rickhall/resolver/src/main/java/org/apache/felix/resolver/ResolverConflictException.java
URL: http://svn.apache.org/viewvc/felix/sandbox/rickhall/resolver/src/main/java/org/apache/felix/resolver/ResolverConflictException.java?rev=835915&r1=835914&r2=835915&view=diff
==============================================================================
--- felix/sandbox/rickhall/resolver/src/main/java/org/apache/felix/resolver/ResolverConflictException.java (original)
+++ felix/sandbox/rickhall/resolver/src/main/java/org/apache/felix/resolver/ResolverConflictException.java Fri Nov 13 16:50:35 2009
@@ -18,9 +18,6 @@
  */
 package org.apache.felix.resolver;
 
-import java.util.List;
-import java.util.Map;
-
 public class ResolverConflictException extends RuntimeException
 {
     /**

Modified: felix/sandbox/rickhall/resolver/src/main/java/org/apache/felix/resolver/VersionRange.java
URL: http://svn.apache.org/viewvc/felix/sandbox/rickhall/resolver/src/main/java/org/apache/felix/resolver/VersionRange.java?rev=835915&r1=835914&r2=835915&view=diff
==============================================================================
--- felix/sandbox/rickhall/resolver/src/main/java/org/apache/felix/resolver/VersionRange.java (original)
+++ felix/sandbox/rickhall/resolver/src/main/java/org/apache/felix/resolver/VersionRange.java Fri Nov 13 16:50:35 2009
@@ -18,8 +18,6 @@
  */
 package org.apache.felix.resolver;
 
-import org.apache.felix.resolver.Version;
-
 public class VersionRange
 {
     private Version m_low = null;

Added: felix/sandbox/rickhall/resolver/src/main/java/org/apache/felix/resolver/cs/Attribute.java
URL: http://svn.apache.org/viewvc/felix/sandbox/rickhall/resolver/src/main/java/org/apache/felix/resolver/cs/Attribute.java?rev=835915&view=auto
==============================================================================
--- felix/sandbox/rickhall/resolver/src/main/java/org/apache/felix/resolver/cs/Attribute.java (added)
+++ felix/sandbox/rickhall/resolver/src/main/java/org/apache/felix/resolver/cs/Attribute.java Fri Nov 13 16:50:35 2009
@@ -0,0 +1,53 @@
+/*
+ *  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.felix.resolver.cs;
+
+public class Attribute
+{
+    private final String m_name;
+    private final Comparable m_value;
+    private final boolean m_isMandatory;
+
+    public Attribute(String name, Comparable value, boolean isMandatory)
+    {
+        m_name = name;
+        m_value = value;
+        m_isMandatory = isMandatory;
+    }
+
+    public String getName()
+    {
+        return m_name;
+    }
+
+    public Comparable getValue()
+    {
+        return m_value;
+    }
+
+    public boolean isMandatory()
+    {
+        return m_isMandatory;
+    }
+
+    public String toString()
+    {
+        return m_name + "=" + m_value;
+    }
+}
\ No newline at end of file

Added: felix/sandbox/rickhall/resolver/src/main/java/org/apache/felix/resolver/cs/Capability.java
URL: http://svn.apache.org/viewvc/felix/sandbox/rickhall/resolver/src/main/java/org/apache/felix/resolver/cs/Capability.java?rev=835915&view=auto
==============================================================================
--- felix/sandbox/rickhall/resolver/src/main/java/org/apache/felix/resolver/cs/Capability.java (added)
+++ felix/sandbox/rickhall/resolver/src/main/java/org/apache/felix/resolver/cs/Capability.java Fri Nov 13 16:50:35 2009
@@ -0,0 +1,30 @@
+/*
+ *  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.felix.resolver.cs;
+
+import java.util.List;
+import org.apache.felix.resolver.Module;
+
+public interface Capability
+{
+    String getName();
+    Attribute getAttribute(String name);
+    List<String> getUses();
+    Module getModule();
+}
\ No newline at end of file

Added: felix/sandbox/rickhall/resolver/src/main/java/org/apache/felix/resolver/cs/CapabilitySet.java
URL: http://svn.apache.org/viewvc/felix/sandbox/rickhall/resolver/src/main/java/org/apache/felix/resolver/cs/CapabilitySet.java?rev=835915&view=auto
==============================================================================
--- felix/sandbox/rickhall/resolver/src/main/java/org/apache/felix/resolver/cs/CapabilitySet.java (added)
+++ felix/sandbox/rickhall/resolver/src/main/java/org/apache/felix/resolver/cs/CapabilitySet.java Fri Nov 13 16:50:35 2009
@@ -0,0 +1,325 @@
+/*
+ *  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.felix.resolver.cs;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import org.apache.felix.resolver.Version;
+
+public class CapabilitySet
+{
+    private final Map<String, Map<Comparable, Set<Capability>>> m_indices =
+        new HashMap<String, Map<Comparable, Set<Capability>>>();
+    private final Set<Capability> m_capList = new HashSet<Capability>();
+
+    public CapabilitySet(List<String> indexProps)
+    {
+        for (int i = 0; (indexProps != null) && (i < indexProps.size()); i++)
+        {
+            m_indices.put(indexProps.get(i), new HashMap<Comparable, Set<Capability>>());
+        }
+    }
+
+    public void addCapability(Capability cap)
+    {
+        m_capList.add(cap);
+
+        // Index capability.
+        for (Iterator<Map.Entry<String, Map<Comparable, Set<Capability>>>>
+            it = m_indices.entrySet().iterator(); it.hasNext(); )
+        {
+            Map.Entry<String, Map<Comparable, Set<Capability>>> entry = it.next();
+            if (cap.getAttribute(entry.getKey()) != null)
+            {
+                Map<Comparable, Set<Capability>> index = entry.getValue();
+                Set<Capability> caps = index.get(cap.getAttribute(entry.getKey()).getValue());
+                if (caps == null)
+                {
+                    caps = new HashSet<Capability>();
+                    index.put(cap.getAttribute(entry.getKey()).getValue(), caps);
+                }
+                caps.add(cap);
+            }
+        }
+
+//        System.out.println("+++ INDICES " + m_indices);
+    }
+
+    public void removeCapability(Capability cap)
+    {
+        if (m_capList.remove(cap))
+        {
+            for (Iterator<Map.Entry<String, Map<Comparable, Set<Capability>>>>
+                it = m_indices.entrySet().iterator(); it.hasNext(); )
+            {
+                Map.Entry<String, Map<Comparable, Set<Capability>>> entry = it.next();
+                if (cap.getAttribute(entry.getKey()) != null)
+                {
+                    Map<Comparable, Set<Capability>> index = entry.getValue();
+                    Set<Capability> caps = index.get(cap.getAttribute(entry.getKey()).getValue());
+                    caps.remove(cap);
+                    if (caps.size() == 0)
+                    {
+                        it.remove();
+                    }
+                }
+            }
+
+            System.out.println("+++ INDICES " + m_indices);
+        }
+    }
+
+    public Set<Capability> match(SimpleFilter sf)
+    {
+        return match(m_capList, sf);
+    }
+
+    private Set<Capability> match(Set<Capability> caps, SimpleFilter sf)
+    {
+//System.out.println("+++ SF " + sf);
+        Set<Capability> matches = new HashSet<Capability>();
+
+        if (sf.getOperation() == SimpleFilter.AND)
+        {
+            // Evaluate each subfilter against the remaining capabilities.
+            // For AND we calculate the intersection of each subfilter.
+            // We can short-circuit the AND operation if there are no
+            // remaining capabilities.
+            List<SimpleFilter> sfs = (List<SimpleFilter>) sf.getValue();
+            for (int i = 0; (caps.size() > 0) && (i < sfs.size()); i++)
+            {
+//System.out.println("+++ REMAINING " + caps);
+                matches = match(caps, sfs.get(i));
+//System.out.println("+++ CURRENT " + matches);
+                caps = matches;
+            }
+        }
+        else if (sf.getOperation() == SimpleFilter.OR)
+        {
+            // Evaluate each subfilter against the remaining capabilities.
+            // For OR we calculate the union of each subfilter.
+            List<SimpleFilter> sfs = (List<SimpleFilter>) sf.getValue();
+            for (int i = 0; i < sfs.size(); i++)
+            {
+                matches.addAll(match(caps, sfs.get(i)));
+            }
+        }
+        else if (sf.getOperation() == SimpleFilter.NOT)
+        {
+            // Evaluate each subfilter against the remaining capabilities.
+            // For OR we calculate the union of each subfilter.
+            matches.addAll(caps);
+            List<SimpleFilter> sfs = (List<SimpleFilter>) sf.getValue();
+            for (int i = 0; i < sfs.size(); i++)
+            {
+                matches.removeAll(match(caps, sfs.get(i)));
+            }
+        }
+        else
+        {
+            Map<Comparable, Set<Capability>> index = m_indices.get(sf.getName());
+            if ((sf.getOperation() == SimpleFilter.EQ) && (index != null))
+            {
+                Set<Capability> existingCaps = index.get((Comparable) sf.getValue());
+                if (existingCaps != null)
+                {
+                    matches.addAll(existingCaps);
+//System.out.println("NARROWED " + caps.size() + " TO " + existingCaps.size());
+                    matches.retainAll(caps);
+                }
+            }
+            else
+            {
+//                System.out.println("+++ SEARCHING " + caps.size() + " CAPABILITIES");
+                for (Iterator<Capability> it = caps.iterator(); it.hasNext(); )
+                {
+                    Capability cap = it.next();
+                    Attribute attr = cap.getAttribute(sf.getName());
+                    Comparable value = (attr == null) ? null : cap.getAttribute(sf.getName()).getValue();
+                    if (value != null)
+                    {
+                        switch (sf.getOperation())
+                        {
+                            case SimpleFilter.EQ:
+                                // Special hack, since a VersionRange is not a Comparable
+                                if (value instanceof Version)
+                                {
+                                    if (value.compareTo(coerceType(value, (String) sf.getValue())) >= 0)
+                                    {
+                                        matches.add(cap);
+                                    }
+                                }
+                                else
+                                {
+                                if (value.compareTo(coerceType(value, (String) sf.getValue())) == 0)
+                                {
+                                    matches.add(cap);
+                                }
+                                }
+                                break;
+                            case SimpleFilter.LTE:
+                                if (value.compareTo(coerceType(value, (String) sf.getValue())) <= 0)
+                                {
+                                    matches.add(cap);
+                                }
+                                break;
+                            case SimpleFilter.GTE:
+                                if (value.compareTo(coerceType(value, (String) sf.getValue())) >= 0)
+                                {
+                                    matches.add(cap);
+                                }
+                                break;
+                        }
+                    }
+                }
+            }
+        }
+
+        return matches;
+    }
+
+    private static final Class[] STRING_CLASS = new Class[] { String.class };
+
+    private Object coerceType(Comparable lhs, String rhs)
+    {
+        if (lhs instanceof String)
+        {
+            return rhs;
+        }
+
+        // Here we know that the LHS is a comparable object, so
+        // try to create an object for the RHS by using a constructor
+        // that will take the RHS string as a parameter.
+        Comparable rhsComparable = null;
+        try
+        {
+            // We are expecting to be able to construct a comparable
+            // instance from the RHS string by passing it into the
+            // constructor of the corresponing comparable class. The
+            // Character class is a special case, since its constructor
+            // does not take a string, so handle it separately.
+            if (lhs instanceof Character)
+            {
+                rhsComparable = new Character(rhs.charAt(0));
+            }
+            else
+            {
+                rhsComparable = (Comparable) lhs.getClass()
+                    .getConstructor(STRING_CLASS)
+                        .newInstance(new Object[] { rhs });
+            }
+        }
+        catch (Exception ex)
+        {
+            throw new RuntimeException(
+                "Could not instantiate class "
+                    + lhs.getClass().getName()
+                    + " with constructor String parameter "
+                    + rhs + " " + ex);
+        }
+
+        return rhsComparable;
+    }
+
+    public boolean matches(Capability cap, SimpleFilter sf)
+    {
+        boolean matched = true;
+
+        if (sf.getOperation() == SimpleFilter.AND)
+        {
+            // Evaluate each subfilter against the remaining capabilities.
+            // For AND we calculate the intersection of each subfilter.
+            // We can short-circuit the AND operation if there are no
+            // remaining capabilities.
+            List<SimpleFilter> sfs = (List<SimpleFilter>) sf.getValue();
+            for (int i = 0; matched && (i < sfs.size()); i++)
+            {
+                matched = matches(cap, sfs.get(i));
+            }
+        }
+        else if (sf.getOperation() == SimpleFilter.OR)
+        {
+            // Evaluate each subfilter against the remaining capabilities.
+            // For OR we calculate the union of each subfilter.
+            matched = false;
+            List<SimpleFilter> sfs = (List<SimpleFilter>) sf.getValue();
+            for (int i = 0; !matched && (i < sfs.size()); i++)
+            {
+                matched = matches(cap, sfs.get(i));
+            }
+        }
+        else if (sf.getOperation() == SimpleFilter.NOT)
+        {
+            // Evaluate each subfilter against the remaining capabilities.
+            // For OR we calculate the union of each subfilter.
+            List<SimpleFilter> sfs = (List<SimpleFilter>) sf.getValue();
+            for (int i = 0; i < sfs.size(); i++)
+            {
+                matched = !(matches(cap, sfs.get(i)));
+            }
+        }
+        else
+        {
+            matched = false;
+            Attribute attr = cap.getAttribute(sf.getName());
+            Comparable value = (attr == null) ? null : cap.getAttribute(sf.getName()).getValue();
+            if (value != null)
+            {
+                switch (sf.getOperation())
+                {
+                    case SimpleFilter.EQ:
+                        // Special hack, since a VersionRange is not a Comparable
+                        if (value instanceof Version)
+                        {
+                            if (value.compareTo(coerceType(value, (String) sf.getValue())) >= 0)
+                            {
+                                matched = true;
+                            }
+                        }
+                        else
+                        {
+                        if (value.compareTo(coerceType(value, (String) sf.getValue())) == 0)
+                        {
+                            matched = true;
+                        }
+                        }
+                        break;
+                    case SimpleFilter.LTE:
+                        if (value.compareTo(coerceType(value, (String) sf.getValue())) <= 0)
+                        {
+                            matched = true;
+                        }
+                        break;
+                    case SimpleFilter.GTE:
+                        if (value.compareTo(coerceType(value, (String) sf.getValue())) >= 0)
+                        {
+                            matched = true;
+                        }
+                        break;
+                }
+            }
+        }
+
+        return matched;
+    }
+}
\ No newline at end of file

Added: felix/sandbox/rickhall/resolver/src/main/java/org/apache/felix/resolver/cs/SimpleFilter.java
URL: http://svn.apache.org/viewvc/felix/sandbox/rickhall/resolver/src/main/java/org/apache/felix/resolver/cs/SimpleFilter.java?rev=835915&view=auto
==============================================================================
--- felix/sandbox/rickhall/resolver/src/main/java/org/apache/felix/resolver/cs/SimpleFilter.java (added)
+++ felix/sandbox/rickhall/resolver/src/main/java/org/apache/felix/resolver/cs/SimpleFilter.java Fri Nov 13 16:50:35 2009
@@ -0,0 +1,198 @@
+/*
+ *  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.felix.resolver.cs;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class SimpleFilter
+{
+    public static final int AND = 1;
+    public static final int OR = 2;
+    public static final int NOT = 3;
+    public static final int EQ = 4;
+    public static final int LTE = 5;
+    public static final int GTE = 6;
+
+    public final String m_name;
+    public final Object m_value;
+    public final int m_op;
+
+    public SimpleFilter(String attr, Object value, int op)
+    {
+        m_name = attr;
+        m_value = value;
+        m_op = op;
+    }
+
+    public String getName()
+    {
+        return m_name;
+    }
+
+    public Object getValue()
+    {
+        return m_value;
+    }
+
+    public int getOperation()
+    {
+        return m_op;
+    }
+
+    public String toString()
+    {
+        String s = null;
+        switch (m_op)
+        {
+            case AND:
+                s = "(&" + toString((List) m_value) + ")";
+                break;
+            case OR:
+                s = "(|" + toString((List) m_value) + ")";
+                break;
+            case NOT:
+                s = "(!" + toString((List) m_value) + ")";
+                break;
+            case EQ:
+                s = "(" + m_name + "=" + m_value + ")";
+                break;
+            case LTE:
+                s = "(" + m_name + "<=" + m_value + ")";
+                break;
+            case GTE:
+                s = "(" + m_name + ">=" + m_value + ")";
+                break;
+        }
+        return s;
+    }
+
+    private String toString(List list)
+    {
+        StringBuffer sb = new StringBuffer();
+        for (int i = 0; i < list.size(); i++)
+        {
+            sb.append(list.get(i).toString());
+        }
+        return sb.toString();
+    }
+
+    public static SimpleFilter parse(String filter)
+    {
+        filter = filter.trim();
+
+        // Assume we have a value that is something like:
+        // (&(n1=v1)(n2=v2)(|(n3=v3)(n4=v4)))
+
+        // Find the first ending ')' variable delimiter, which
+        // will correspond to the first deepest nested variable
+        // placeholder.
+
+        SimpleFilter sf = null;
+        List stack = new ArrayList();
+        for (int i = 0; i < filter.length(); i++)
+        {
+            if (sf != null)
+            {
+                throw new IllegalArgumentException(
+                    "Only one top-level operation allowed: " + filter);
+            }
+            if (filter.charAt(i) == '(')
+            {
+                if (filter.charAt(i+1) == '&')
+                {
+                    stack.add(0, new SimpleFilter(null, new ArrayList(), SimpleFilter.AND));
+                }
+                else if (filter.charAt(i+1) == '|')
+                {
+                    stack.add(0, new SimpleFilter(null, new ArrayList(), SimpleFilter.OR));
+                }
+                else if (filter.charAt(i+1) == '!')
+                {
+                    stack.add(0, new SimpleFilter(null, new ArrayList(), SimpleFilter.NOT));
+                }
+                else
+                {
+                    stack.add(0, new Integer(i));
+                }
+            }
+            else if (filter.charAt(i) == ')')
+            {
+                Object top = stack.remove(0);
+                if (top instanceof SimpleFilter)
+                {
+                    if (!stack.isEmpty() && (stack.get(0) instanceof SimpleFilter))
+                    {
+                        ((List) ((SimpleFilter) stack.get(0)).m_value).add(top);
+                    }
+                    else
+                    {
+                        sf = (SimpleFilter) top;
+                    }
+                }
+                else if (!stack.isEmpty() && (stack.get(0) instanceof SimpleFilter))
+                {
+                    ((List) ((SimpleFilter) stack.get(0)).m_value).add(
+                        SimpleFilter.subfilter(filter.substring(((Integer) top).intValue() + 1, i)));
+                }
+                else
+                {
+                    sf = SimpleFilter.subfilter(filter.substring(((Integer) top).intValue() + 1, i));
+                }
+            }
+        }
+        return sf;
+    }
+
+    private static SimpleFilter subfilter(String subfilter)
+    {
+        final String opChars = "=<>";
+        String attr = null, value = null;
+        int op = -1;
+        for (int i = 0; i < subfilter.length(); i++)
+        {
+            if (opChars.indexOf(subfilter.charAt(i)) >= 0)
+            {
+                switch (subfilter.charAt(i))
+                {
+                    case '=':
+                        attr = subfilter.substring(0, i);
+                        op = EQ;
+                        value = subfilter.substring(i + 1);
+                        break;
+                    case '<':
+                        attr = subfilter.substring(0, i);
+                        op = LTE;
+                        value = subfilter.substring(i + 2);
+                        break;
+                    case '>':
+                        attr = subfilter.substring(0, i);
+                        op = GTE;
+                        value = subfilter.substring(i + 2);
+                        break;
+                    default:
+                        throw new IllegalArgumentException("Unknown operator: " + subfilter);
+                }
+                break;
+            }
+        }
+
+        return new SimpleFilter(attr, value, op);
+    }
+}
\ No newline at end of file

Modified: felix/sandbox/rickhall/resolver/src/main/java/org/apache/felix/resolver/felix/CandidateSet.java
URL: http://svn.apache.org/viewvc/felix/sandbox/rickhall/resolver/src/main/java/org/apache/felix/resolver/felix/CandidateSet.java?rev=835915&r1=835914&r2=835915&view=diff
==============================================================================
--- felix/sandbox/rickhall/resolver/src/main/java/org/apache/felix/resolver/felix/CandidateSet.java (original)
+++ felix/sandbox/rickhall/resolver/src/main/java/org/apache/felix/resolver/felix/CandidateSet.java Fri Nov 13 16:50:35 2009
@@ -18,38 +18,24 @@
  */
 package org.apache.felix.resolver.felix;
 
-import org.apache.felix.resolver.*;
+import java.util.List;
+import org.apache.felix.resolver.ImportedPackage;
+import org.apache.felix.resolver.Module;
 
 class CandidateSet
 {
     public static final int NORMAL = 0;
-    public static final int FRAGMENT = 1;
-    public static final int HOST = 2;
-    public final int m_type;
     public final Module m_module;
     public final ImportedPackage m_requirement;
-    public final PackageSource[] m_candidates;
-    public final Module[] m_modules;
+    public final List m_candidates;
     public int m_idx = 0;
     public int m_rotated = 0;
 
-    public CandidateSet(int type, Module module, ImportedPackage requirement, PackageSource[] candidates)
+    public CandidateSet(Module module, ImportedPackage requirement, List candidates)
     {
         super();
-        m_type = type;
         m_module = module;
         m_requirement = requirement;
         m_candidates = candidates;
-        m_modules = null;
     }
-
-    public CandidateSet(int type, Module module, ImportedPackage requirement, Module[] fragments)
-    {
-        super();
-        m_type = type;
-        m_module = module;
-        m_requirement = requirement;
-        m_candidates = null;
-        m_modules = fragments;
-    }
-}
+}
\ No newline at end of file

Modified: felix/sandbox/rickhall/resolver/src/main/java/org/apache/felix/resolver/felix/FelixResolver.java
URL: http://svn.apache.org/viewvc/felix/sandbox/rickhall/resolver/src/main/java/org/apache/felix/resolver/felix/FelixResolver.java?rev=835915&r1=835914&r2=835915&view=diff
==============================================================================
--- felix/sandbox/rickhall/resolver/src/main/java/org/apache/felix/resolver/felix/FelixResolver.java (original)
+++ felix/sandbox/rickhall/resolver/src/main/java/org/apache/felix/resolver/felix/FelixResolver.java Fri Nov 13 16:50:35 2009
@@ -28,17 +28,87 @@
 import org.apache.felix.resolver.ImportedPackage;
 import org.apache.felix.resolver.Module;
 import org.apache.felix.resolver.Resolver;
+import org.apache.felix.resolver.Version;
 import org.apache.felix.resolver.Wire;
+import org.apache.felix.resolver.cs.Attribute;
+import org.apache.felix.resolver.cs.CapabilitySet;
 
 public class FelixResolver implements Resolver
 {
     private final List<Module> m_moduleList;
     private final FelixResolverImpl m_resolver = new FelixResolverImpl();
     private final ResolverStateImpl m_state = new ResolverStateImpl();
+    private final Map<String, List<ExportedPackage>> m_unresolvedPkgIndex =
+        new HashMap<String, List<ExportedPackage>>();
 
     public FelixResolver(List<Module> moduleList)
     {
         m_moduleList = moduleList;
+        for (int i = 0; i < m_moduleList.size(); i++)
+        {
+            addModule(m_moduleList.get(i));
+        }
+    }
+
+    private void addModule(Module module)
+    {
+        //
+        // Second, index module's capabilities.
+        //
+
+        List<ExportedPackage> eps = module.getExports();
+
+        // Add exports to unresolved package map.
+        for (int i = 0; (eps != null) && (i < eps.size()); i++)
+        {
+            indexPackageCapability(eps.get(i));
+        }
+    }
+
+    private void indexPackageCapability(ExportedPackage ep)
+    {
+        String pkgName = ep.getName();
+        List<ExportedPackage> epList = m_unresolvedPkgIndex.get(pkgName);
+
+        // We want to add the capability into the list of exporters
+        // in sorted order (descending version and ascending bundle
+        // identifier). Insert using a simple binary search algorithm.
+        if (epList == null)
+        {
+            epList = new ArrayList<ExportedPackage>();
+            epList.add(ep);
+        }
+        else
+        {
+            Attribute attr = ep.getAttribute("version");
+            Version version = (attr == null) ? Version.emptyVersion : (Version) attr.getValue();
+            Version middleVersion = null;
+            int top = 0, bottom = epList.size() - 1, middle = 0;
+            while (top <= bottom)
+            {
+                middle = (bottom - top) / 2 + top;
+                attr = epList.get(middle).getAttribute("version");
+                middleVersion = (attr == null) ? Version.emptyVersion : (Version) attr.getValue();
+                // Sort in reverse version order.
+                int cmp = middleVersion.compareTo(version);
+                if (cmp < 0)
+                {
+                    bottom = middle - 1;
+                }
+                else
+                {
+                    top = middle + 1;
+                }
+            }
+
+            // Ignore duplicates.
+            if ((top >= epList.size()) || (epList.get(top) != ep))
+            {
+                epList.add(top, ep);
+            }
+        }
+
+        m_unresolvedPkgIndex.put(pkgName, epList);
     }
 
     public Module getModule(String name)
@@ -70,31 +140,31 @@
 
     private class ResolverStateImpl implements FelixResolverImpl.ResolverState
     {
+        private final CapabilitySet m_cs = new CapabilitySet(null);
+
         public Module[] getModules()
         {
             return (Module[]) m_moduleList.toArray(new Module[m_moduleList.size()]);
         }
 
-        public PackageSource[] getResolvedCandidates(ImportedPackage req)
+        public List<ExportedPackage> getResolvedCandidates(ImportedPackage req)
         {
-            return new PackageSource[0];
+            return new ArrayList<ExportedPackage>();
         }
 
-        public PackageSource[] getUnresolvedCandidates(ImportedPackage req)
+        public List<ExportedPackage> getUnresolvedCandidates(ImportedPackage req)
         {
-            List<PackageSource> ps = new ArrayList<PackageSource>();
-            for (int modIdx = 0; modIdx < m_moduleList.size(); modIdx++)
+            List<ExportedPackage> matches = new ArrayList<ExportedPackage>();
+            List<ExportedPackage> candidates = m_unresolvedPkgIndex.get(req.getName());
+            for (int candIdx = 0; candIdx < candidates.size(); candIdx++)
             {
-                List<ExportedPackage> exports = m_moduleList.get(modIdx).getExports();
-                for (int expIdx = 0; expIdx < exports.size(); expIdx++)
+                ExportedPackage export = candidates.get(candIdx);
+                if (req.isSatistfiedBy(export))
                 {
-                    if (req.isSatistfiedBy(exports.get(expIdx)))
-                    {
-                        ps.add(new PackageSource(m_moduleList.get(modIdx), exports.get(expIdx)));
-                    }
+                    matches.add(export);
                 }
             }
-            return ps.toArray(new PackageSource[ps.size()]);
+            return matches;
         }
     }
 }
\ No newline at end of file



Mime
View raw message