You are viewing a plain text version of this content. The canonical link for it is here.
Posted to scm@geronimo.apache.org by ga...@apache.org on 2012/04/03 21:17:01 UTC

svn commit: r1309100 [1/2] - in /geronimo/server/branches/3.0-beta/plugins/aries: ./ aries-deployer/ aries-deployer/src/main/history/ aries/ aries/src/main/history/ geronimo-aries-resolver/ geronimo-aries-resolver/src/ geronimo-aries-resolver/src/main/...

Author: gawor
Date: Tue Apr  3 19:16:59 2012
New Revision: 1309100

URL: http://svn.apache.org/viewvc?rev=1309100&view=rev
Log:
GERONIMO-6319: Discover and provision fragment bundles for OSGi apps

Added:
    geronimo/server/branches/3.0-beta/plugins/aries/geronimo-aries-resolver/
    geronimo/server/branches/3.0-beta/plugins/aries/geronimo-aries-resolver/pom.xml
    geronimo/server/branches/3.0-beta/plugins/aries/geronimo-aries-resolver/src/
    geronimo/server/branches/3.0-beta/plugins/aries/geronimo-aries-resolver/src/main/
    geronimo/server/branches/3.0-beta/plugins/aries/geronimo-aries-resolver/src/main/java/
    geronimo/server/branches/3.0-beta/plugins/aries/geronimo-aries-resolver/src/main/java/org/
    geronimo/server/branches/3.0-beta/plugins/aries/geronimo-aries-resolver/src/main/java/org/apache/
    geronimo/server/branches/3.0-beta/plugins/aries/geronimo-aries-resolver/src/main/java/org/apache/geronimo/
    geronimo/server/branches/3.0-beta/plugins/aries/geronimo-aries-resolver/src/main/java/org/apache/geronimo/aries/
    geronimo/server/branches/3.0-beta/plugins/aries/geronimo-aries-resolver/src/main/java/org/apache/geronimo/aries/resolver/
    geronimo/server/branches/3.0-beta/plugins/aries/geronimo-aries-resolver/src/main/java/org/apache/geronimo/aries/resolver/internal/
    geronimo/server/branches/3.0-beta/plugins/aries/geronimo-aries-resolver/src/main/java/org/apache/geronimo/aries/resolver/internal/MessageUtil.java
    geronimo/server/branches/3.0-beta/plugins/aries/geronimo-aries-resolver/src/main/java/org/apache/geronimo/aries/resolver/internal/ModellingConstants.java
    geronimo/server/branches/3.0-beta/plugins/aries/geronimo-aries-resolver/src/main/java/org/apache/geronimo/aries/resolver/obr/
    geronimo/server/branches/3.0-beta/plugins/aries/geronimo-aries-resolver/src/main/java/org/apache/geronimo/aries/resolver/obr/OBRAriesResolver.java
    geronimo/server/branches/3.0-beta/plugins/aries/geronimo-aries-resolver/src/main/java/org/apache/geronimo/aries/resolver/obr/generator/
    geronimo/server/branches/3.0-beta/plugins/aries/geronimo-aries-resolver/src/main/java/org/apache/geronimo/aries/resolver/obr/generator/RepositoryDescriptorGenerator.java
    geronimo/server/branches/3.0-beta/plugins/aries/geronimo-aries-resolver/src/main/java/org/apache/geronimo/aries/resolver/obr/impl/
    geronimo/server/branches/3.0-beta/plugins/aries/geronimo-aries-resolver/src/main/java/org/apache/geronimo/aries/resolver/obr/impl/ApplicationResourceImpl.java
    geronimo/server/branches/3.0-beta/plugins/aries/geronimo-aries-resolver/src/main/java/org/apache/geronimo/aries/resolver/obr/impl/MapToDictionary.java
    geronimo/server/branches/3.0-beta/plugins/aries/geronimo-aries-resolver/src/main/java/org/apache/geronimo/aries/resolver/obr/impl/OBRBundleInfo.java
    geronimo/server/branches/3.0-beta/plugins/aries/geronimo-aries-resolver/src/main/java/org/apache/geronimo/aries/resolver/obr/impl/RequirementImpl.java
    geronimo/server/branches/3.0-beta/plugins/aries/geronimo-aries-resolver/src/main/java/org/apache/geronimo/aries/resolver/obr/impl/ResourceWrapper.java
    geronimo/server/branches/3.0-beta/plugins/aries/geronimo-aries-resolver/src/main/resources/
    geronimo/server/branches/3.0-beta/plugins/aries/geronimo-aries-resolver/src/main/resources/OSGI-INF/
    geronimo/server/branches/3.0-beta/plugins/aries/geronimo-aries-resolver/src/main/resources/OSGI-INF/blueprint/
    geronimo/server/branches/3.0-beta/plugins/aries/geronimo-aries-resolver/src/main/resources/OSGI-INF/blueprint/obr-resolver.xml
    geronimo/server/branches/3.0-beta/plugins/aries/geronimo-aries-resolver/src/main/resources/org/
    geronimo/server/branches/3.0-beta/plugins/aries/geronimo-aries-resolver/src/main/resources/org/apache/
    geronimo/server/branches/3.0-beta/plugins/aries/geronimo-aries-resolver/src/main/resources/org/apache/geronimo/
    geronimo/server/branches/3.0-beta/plugins/aries/geronimo-aries-resolver/src/main/resources/org/apache/geronimo/aries/
    geronimo/server/branches/3.0-beta/plugins/aries/geronimo-aries-resolver/src/main/resources/org/apache/geronimo/aries/resolver/
    geronimo/server/branches/3.0-beta/plugins/aries/geronimo-aries-resolver/src/main/resources/org/apache/geronimo/aries/resolver/messages/
    geronimo/server/branches/3.0-beta/plugins/aries/geronimo-aries-resolver/src/main/resources/org/apache/geronimo/aries/resolver/messages/ResolverMessages.properties
Removed:
    geronimo/server/branches/3.0-beta/plugins/aries/geronimo-aries/src/main/resources/OSGI-INF/blueprint/obr-resolver.xml
Modified:
    geronimo/server/branches/3.0-beta/plugins/aries/aries-deployer/pom.xml
    geronimo/server/branches/3.0-beta/plugins/aries/aries-deployer/src/main/history/dependencies.xml
    geronimo/server/branches/3.0-beta/plugins/aries/aries/pom.xml
    geronimo/server/branches/3.0-beta/plugins/aries/aries/src/main/history/dependencies.xml
    geronimo/server/branches/3.0-beta/plugins/aries/pom.xml

Modified: geronimo/server/branches/3.0-beta/plugins/aries/aries-deployer/pom.xml
URL: http://svn.apache.org/viewvc/geronimo/server/branches/3.0-beta/plugins/aries/aries-deployer/pom.xml?rev=1309100&r1=1309099&r2=1309100&view=diff
==============================================================================
--- geronimo/server/branches/3.0-beta/plugins/aries/aries-deployer/pom.xml (original)
+++ geronimo/server/branches/3.0-beta/plugins/aries/aries-deployer/pom.xml Tue Apr  3 19:16:59 2012
@@ -61,11 +61,6 @@
         
         <dependency>
             <groupId>org.apache.aries.application</groupId>
-            <artifactId>org.apache.aries.application.resolver.obr</artifactId>
-        </dependency>
-
-        <dependency>
-            <groupId>org.apache.aries.application</groupId>
             <artifactId>org.apache.aries.application.api</artifactId>
         </dependency>
 

Modified: geronimo/server/branches/3.0-beta/plugins/aries/aries-deployer/src/main/history/dependencies.xml
URL: http://svn.apache.org/viewvc/geronimo/server/branches/3.0-beta/plugins/aries/aries-deployer/src/main/history/dependencies.xml?rev=1309100&r1=1309099&r2=1309100&view=diff
==============================================================================
--- geronimo/server/branches/3.0-beta/plugins/aries/aries-deployer/src/main/history/dependencies.xml (original)
+++ geronimo/server/branches/3.0-beta/plugins/aries/aries-deployer/src/main/history/dependencies.xml Tue Apr  3 19:16:59 2012
@@ -38,11 +38,6 @@
     </dependency>
     <dependency>
         <groupId>org.apache.felix</groupId>
-        <artifactId>org.apache.felix.bundlerepository</artifactId>
-        <type>jar</type>
-    </dependency>
-    <dependency>
-        <groupId>org.apache.felix</groupId>
         <artifactId>org.apache.felix.configadmin</artifactId>
         <type>jar</type>
     </dependency>

Modified: geronimo/server/branches/3.0-beta/plugins/aries/aries/pom.xml
URL: http://svn.apache.org/viewvc/geronimo/server/branches/3.0-beta/plugins/aries/aries/pom.xml?rev=1309100&r1=1309099&r2=1309100&view=diff
==============================================================================
--- geronimo/server/branches/3.0-beta/plugins/aries/aries/pom.xml (original)
+++ geronimo/server/branches/3.0-beta/plugins/aries/aries/pom.xml Tue Apr  3 19:16:59 2012
@@ -40,6 +40,12 @@
             <artifactId>geronimo-aries</artifactId>
             <version>${project.version}</version>
         </dependency>
+
+        <dependency>
+            <groupId>org.apache.geronimo.modules</groupId>
+            <artifactId>geronimo-aries-resolver</artifactId>
+            <version>${project.version}</version>
+        </dependency>
         
         <dependency>
             <groupId>org.apache.geronimo.ext.aries.blueprint</groupId>
@@ -48,11 +54,6 @@
                 
         <dependency>
             <groupId>org.apache.aries.application</groupId>
-            <artifactId>org.apache.aries.application.resolver.obr</artifactId>
-        </dependency>
-        
-        <dependency>
-            <groupId>org.apache.aries.application</groupId>
             <artifactId>org.apache.aries.application.api</artifactId>
         </dependency>
 

Modified: geronimo/server/branches/3.0-beta/plugins/aries/aries/src/main/history/dependencies.xml
URL: http://svn.apache.org/viewvc/geronimo/server/branches/3.0-beta/plugins/aries/aries/src/main/history/dependencies.xml?rev=1309100&r1=1309099&r2=1309100&view=diff
==============================================================================
--- geronimo/server/branches/3.0-beta/plugins/aries/aries/src/main/history/dependencies.xml (original)
+++ geronimo/server/branches/3.0-beta/plugins/aries/aries/src/main/history/dependencies.xml Tue Apr  3 19:16:59 2012
@@ -38,11 +38,6 @@
     </dependency>
     <dependency>
         <groupId>org.apache.aries.application</groupId>
-        <artifactId>org.apache.aries.application.resolver.obr</artifactId>
-        <type>jar</type>
-    </dependency>
-    <dependency>
-        <groupId>org.apache.aries.application</groupId>
         <artifactId>org.apache.aries.application.utils</artifactId>
         <type>jar</type>
     </dependency>
@@ -168,6 +163,11 @@
     </dependency>
     <dependency>
         <groupId>org.apache.geronimo.modules</groupId>
+        <artifactId>geronimo-aries-resolver</artifactId>
+        <type>jar</type>
+    </dependency>
+    <dependency>
+        <groupId>org.apache.geronimo.modules</groupId>
         <artifactId>geronimo-j2ee</artifactId>
         <type>jar</type>
     </dependency>

Added: geronimo/server/branches/3.0-beta/plugins/aries/geronimo-aries-resolver/pom.xml
URL: http://svn.apache.org/viewvc/geronimo/server/branches/3.0-beta/plugins/aries/geronimo-aries-resolver/pom.xml?rev=1309100&view=auto
==============================================================================
--- geronimo/server/branches/3.0-beta/plugins/aries/geronimo-aries-resolver/pom.xml (added)
+++ geronimo/server/branches/3.0-beta/plugins/aries/geronimo-aries-resolver/pom.xml Tue Apr  3 19:16:59 2012
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!--
+    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.
+-->
+
+<!-- $Rev: 23025 $ $Date: 2011-12-20 13:26:50 -0500 (Tue, 20 Dec 2011) $ -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>org.apache.geronimo.plugins</groupId>
+        <artifactId>aries</artifactId>
+        <version>3.0-beta-2-SNAPSHOT</version>
+    </parent>
+
+    <groupId>org.apache.geronimo.modules</groupId>
+    <artifactId>geronimo-aries-resolver</artifactId>
+    <packaging>bundle</packaging>
+    <name>Geronimo Plugins, Aries :: OBR Resolver</name>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.aries.application</groupId>
+            <artifactId>org.apache.aries.application.api</artifactId>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.aries.application</groupId>
+            <artifactId>org.apache.aries.application.management</artifactId>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.aries.application</groupId>
+            <artifactId>org.apache.aries.application.utils</artifactId>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+          <groupId>org.apache.felix</groupId>
+          <artifactId>org.apache.felix.bundlerepository</artifactId>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.felix</groupId>
+                <artifactId>maven-bundle-plugin</artifactId>
+                <configuration>
+                    <instructions>
+                        <Export-Package>
+                          org.apache.geronimo.aries.resolver
+                        </Export-Package>
+                    </instructions>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+
+</project>
+

Added: geronimo/server/branches/3.0-beta/plugins/aries/geronimo-aries-resolver/src/main/java/org/apache/geronimo/aries/resolver/internal/MessageUtil.java
URL: http://svn.apache.org/viewvc/geronimo/server/branches/3.0-beta/plugins/aries/geronimo-aries-resolver/src/main/java/org/apache/geronimo/aries/resolver/internal/MessageUtil.java?rev=1309100&view=auto
==============================================================================
--- geronimo/server/branches/3.0-beta/plugins/aries/geronimo-aries-resolver/src/main/java/org/apache/geronimo/aries/resolver/internal/MessageUtil.java (added)
+++ geronimo/server/branches/3.0-beta/plugins/aries/geronimo-aries-resolver/src/main/java/org/apache/geronimo/aries/resolver/internal/MessageUtil.java Tue Apr  3 19:16:59 2012
@@ -0,0 +1,46 @@
+/*
+ * 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 WARRANTIESOR 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.geronimo.aries.resolver.internal;
+
+import java.text.MessageFormat;
+import java.util.ResourceBundle;
+
+public class MessageUtil
+{
+  /** The resource bundle for blueprint messages */
+  private final static ResourceBundle messages = ResourceBundle.getBundle("org.apache.geronimo.aries.resolver.messages.ResolverMessages");
+  
+  /**
+   * Resolve a message from the bundle, including any necessary formatting.
+   * 
+   * @param key     the message key.
+   * @param inserts any required message inserts.
+   * @return        the message translated into the server local.
+   */
+  public static final String getMessage(String key, Object ... inserts)
+  {
+    String msg = messages.getString(key);
+    
+    if (inserts.length > 0)
+      msg = MessageFormat.format(msg, inserts);
+    
+    return msg;
+  }
+}

Added: geronimo/server/branches/3.0-beta/plugins/aries/geronimo-aries-resolver/src/main/java/org/apache/geronimo/aries/resolver/internal/ModellingConstants.java
URL: http://svn.apache.org/viewvc/geronimo/server/branches/3.0-beta/plugins/aries/geronimo-aries-resolver/src/main/java/org/apache/geronimo/aries/resolver/internal/ModellingConstants.java?rev=1309100&view=auto
==============================================================================
--- geronimo/server/branches/3.0-beta/plugins/aries/geronimo-aries-resolver/src/main/java/org/apache/geronimo/aries/resolver/internal/ModellingConstants.java (added)
+++ geronimo/server/branches/3.0-beta/plugins/aries/geronimo-aries-resolver/src/main/java/org/apache/geronimo/aries/resolver/internal/ModellingConstants.java Tue Apr  3 19:16:59 2012
@@ -0,0 +1,34 @@
+/*
+ * 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 WARRANTIESOR 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.geronimo.aries.resolver.internal;
+
+import org.osgi.framework.Constants;
+
+public class ModellingConstants
+{
+  public static final String OBR_SYMBOLIC_NAME = "symbolicname";
+  public static final String OBR_PRESENTATION_NAME = "presentationname";
+  public static final String OBR_MANIFEST_VERSION = "manifestversion";
+  public static final String OBR_BUNDLE = "bundle";
+  public static final String OBR_PACKAGE = "package";
+  public static final String OBR_SERVICE = "service";
+  public static final String OBR_COMPOSITE_BUNDLE = "composite-bundle";
+  public static final String OBR_UNKNOWN = "unknown";
+  public static final String OPTIONAL_KEY = Constants.RESOLUTION_DIRECTIVE + ":";
+}

Added: geronimo/server/branches/3.0-beta/plugins/aries/geronimo-aries-resolver/src/main/java/org/apache/geronimo/aries/resolver/obr/OBRAriesResolver.java
URL: http://svn.apache.org/viewvc/geronimo/server/branches/3.0-beta/plugins/aries/geronimo-aries-resolver/src/main/java/org/apache/geronimo/aries/resolver/obr/OBRAriesResolver.java?rev=1309100&view=auto
==============================================================================
--- geronimo/server/branches/3.0-beta/plugins/aries/geronimo-aries-resolver/src/main/java/org/apache/geronimo/aries/resolver/obr/OBRAriesResolver.java (added)
+++ geronimo/server/branches/3.0-beta/plugins/aries/geronimo-aries-resolver/src/main/java/org/apache/geronimo/aries/resolver/obr/OBRAriesResolver.java Tue Apr  3 19:16:59 2012
@@ -0,0 +1,531 @@
+/*
+ * 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.geronimo.aries.resolver.obr;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.InputStreamReader;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Comparator;
+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 javax.xml.transform.TransformerFactory;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamResult;
+
+import org.apache.aries.application.ApplicationMetadata;
+import org.apache.aries.application.Content;
+import org.apache.aries.application.VersionRange;
+import org.apache.aries.application.management.AriesApplication;
+import org.apache.aries.application.management.AriesApplicationResolver;
+import org.apache.aries.application.management.BundleInfo;
+import org.apache.aries.application.management.ResolveConstraint;
+import org.apache.aries.application.management.ResolverException;
+import org.apache.aries.application.utils.manifest.ManifestHeaderProcessor;
+import org.apache.felix.bundlerepository.Capability;
+import org.apache.felix.bundlerepository.DataModelHelper;
+import org.apache.felix.bundlerepository.Reason;
+import org.apache.felix.bundlerepository.Repository;
+import org.apache.felix.bundlerepository.RepositoryAdmin;
+import org.apache.felix.bundlerepository.Requirement;
+import org.apache.felix.bundlerepository.Resolver;
+import org.apache.felix.bundlerepository.Resource;
+import org.apache.geronimo.aries.resolver.internal.MessageUtil;
+import org.apache.geronimo.aries.resolver.internal.ModellingConstants;
+import org.apache.geronimo.aries.resolver.obr.generator.RepositoryDescriptorGenerator;
+import org.apache.geronimo.aries.resolver.obr.impl.ApplicationResourceImpl;
+import org.apache.geronimo.aries.resolver.obr.impl.OBRBundleInfo;
+import org.apache.geronimo.aries.resolver.obr.impl.ResourceWrapper;
+import org.osgi.framework.Constants;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.framework.Version;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.w3c.dom.Document;
+
+/**
+ * @version $Rev: 23025 $ $Date: 2011-08-23 15:04:55 -0400 (Tue, 23 Aug 2011)
+ *          $
+ */
+public class OBRAriesResolver implements AriesApplicationResolver {
+    private static Logger log = LoggerFactory.getLogger(OBRAriesResolver.class);
+
+    private final static String LOG_ENTRY = "Method entry: {}, args {}";
+    private final static String LOG_EXIT = "Method exit: {}, returning {}";
+
+    private final RepositoryAdmin repositoryAdmin;
+    private boolean returnOptionalResources = true;
+    private boolean resolveFragments = false;
+
+    public OBRAriesResolver(RepositoryAdmin repositoryAdmin) {
+        this.repositoryAdmin = repositoryAdmin;
+    }
+
+    public void setReturnOptionalResources(boolean optional) {
+        this.returnOptionalResources = optional;
+    }
+
+    public boolean getReturnOptionalResources() {
+        return returnOptionalResources;
+    }
+
+    public void setResolveFragments(boolean resolveFragments) {
+        this.resolveFragments = resolveFragments;
+    }
+
+    public boolean getResolveFragments() {
+        return resolveFragments;
+    }
+
+    public Set<BundleInfo> resolve(AriesApplication app, ResolveConstraint... constraints) throws ResolverException {
+        log.trace("resolving {}", app);
+        DataModelHelper helper = repositoryAdmin.getHelper();
+
+        ApplicationMetadata appMeta = app.getApplicationMetadata();
+
+        String appName = appMeta.getApplicationSymbolicName();
+        Version appVersion = appMeta.getApplicationVersion();
+        List<Content> appContent = appMeta.getApplicationContents();
+
+        Repository appRepo;
+
+        try {
+            Document doc = RepositoryDescriptorGenerator.generateRepositoryDescriptor(appName + "_" + appVersion, app
+                    .getBundleInfo());
+
+            ByteArrayOutputStream bytesOut = new ByteArrayOutputStream();
+
+            TransformerFactory.newInstance().newTransformer().transform(new DOMSource(doc), new StreamResult(bytesOut));
+
+            appRepo = helper.readRepository(new InputStreamReader(new ByteArrayInputStream(bytesOut.toByteArray())));
+        } catch (Exception e) {
+            throw new ResolverException(e);
+        }
+
+        List<Repository> resolveRepos = new ArrayList<Repository>();
+
+        // add system repository
+        resolveRepos.add(repositoryAdmin.getSystemRepository());
+
+        // add local repository
+        resolveRepos.add(getLocalRepository(repositoryAdmin));
+
+        // add application repository
+        resolveRepos.add(appRepo);
+
+        // add user-defined repositories
+        Repository[] repos = repositoryAdmin.listRepositories();
+        for (Repository r : repos) {
+            resolveRepos.add(r);
+        }
+
+        Resolver obrResolver = repositoryAdmin.resolver(resolveRepos.toArray(new Repository[resolveRepos.size()]));
+        // add a resource describing the requirements of the application
+        // metadata.
+        obrResolver.add(createApplicationResource(helper, appName, appVersion, appContent));
+        
+        boolean resolved = obrResolver.resolve();
+        Set<BundleInfo> fragments = new HashSet<BundleInfo>();
+        
+        if (resolved && resolveFragments) {
+            for (Resource resource : obrResolver.getRequiredResources()) {
+                Resource fragmentResource = findFragmentResource(resource);
+                if (fragmentResource != null) {
+                    obrResolver.add(fragmentResource);
+                    fragments.add(toBundleInfo(fragmentResource, false));
+                }
+            }
+            if (returnOptionalResources) {
+                for (Resource resource : obrResolver.getOptionalResources()) {
+                    Resource fragmentResource = findFragmentResource(resource);
+                    if (fragmentResource != null) {
+                        obrResolver.add(fragmentResource);
+                        fragments.add(toBundleInfo(fragmentResource, true));
+                    }
+                }
+            }
+            
+            if (!fragments.isEmpty()) {
+                resolved = obrResolver.resolve();
+            }
+        }
+
+        if (resolved) {
+            Set<BundleInfo> result = new HashSet<BundleInfo>();
+            for (Resource resource : obrResolver.getRequiredResources()) {
+                BundleInfo bundleInfo = toBundleInfo(resource, false);
+                result.add(bundleInfo);
+            }
+            if (returnOptionalResources) {
+                for (Resource resource : obrResolver.getOptionalResources()) {
+                    BundleInfo bundleInfo = toBundleInfo(resource, true);
+                    result.add(bundleInfo);
+                }
+            }
+            result.addAll(fragments);
+            return result;
+        } else {
+            Reason[] reasons = obrResolver.getUnsatisfiedRequirements();
+            // let's refine the list by removing the indirect unsatisfied
+            // bundles that are caused by unsatisfied packages or other bundles
+            Map<String, Set<String>> refinedReqs = refineUnsatisfiedRequirements(obrResolver, reasons);
+
+            StringBuffer reqList = new StringBuffer();
+            Map<String, String> unsatisfiedRequirements = extractConsumableMessageInfo(refinedReqs);
+            for (String reason : unsatisfiedRequirements.keySet()) {
+                reqList.append('\n');
+                reqList.append(reason);
+            }
+
+            ResolverException re = new ResolverException(MessageUtil.getMessage("RESOLVER_UNABLE_TO_RESOLVE",
+                    new Object[] { appName, reqList }));
+            List<String> list = new ArrayList<String>();
+            list.addAll(unsatisfiedRequirements.keySet());
+            re.setUnsatisfiedRequirements(list);
+
+            throw re;
+        }
+    }
+
+    private Repository getLocalRepository(RepositoryAdmin admin) {
+        Repository localRepository = repositoryAdmin.getLocalRepository();
+
+        Resource[] resources = localRepository.getResources();
+
+        Resource[] newResources = new Resource[resources.length];
+        for (int i = 0; i < resources.length; i++) {
+            newResources[i] = new ResourceWrapper(resources[i]);
+        }
+
+        return repositoryAdmin.getHelper().repository(newResources);
+    }
+
+    private Resource createApplicationResource(DataModelHelper helper, String appName, Version appVersion,
+            List<Content> appContent) {
+        return new ApplicationResourceImpl(appName, appVersion, appContent);
+    }
+
+    public BundleInfo getBundleInfo(String bundleSymbolicName, Version bundleVersion) {
+        Map<String, String> attribs = new HashMap<String, String>();
+        // bundleVersion is an exact version - so ensure right version filter is
+        // generated
+        VersionRange range = ManifestHeaderProcessor.parseVersionRange(bundleVersion.toString(), true);
+        attribs.put(Resource.VERSION, range.toString());
+        String filterString = ManifestHeaderProcessor.generateFilter(Resource.SYMBOLIC_NAME, bundleSymbolicName,
+                attribs);
+        Resource[] resources;
+        try {
+            resources = repositoryAdmin.discoverResources(filterString);
+            if (resources != null && resources.length > 0) {
+                return toBundleInfo(resources[0], false);
+            } else {
+                return null;
+            }
+        } catch (InvalidSyntaxException e) {
+            log.error("Invalid filter", e);
+            return null;
+        }
+    }
+
+    private BundleInfo toBundleInfo(Resource resource, boolean optional) {
+        Map<String, String> directives = null;
+        if (optional) {
+            directives = new HashMap<String, String>();
+            directives.put(Constants.RESOLUTION_DIRECTIVE, Constants.RESOLUTION_OPTIONAL);
+        }
+        String location = resource.getURI();
+        return new OBRBundleInfo(resource.getSymbolicName(), resource.getVersion(), location, null, null, null, null,
+                null, null, directives, null);
+    }
+
+    /**
+     * Refine the unsatisfied requirements ready for later human comsumption
+     * 
+     * @param resolver
+     *            The resolver to be used to refine the requirements
+     * @param reasons
+     *            The reasons
+     * @return A map of the unsatifiedRequirement to the set of bundles that
+     *         have that requirement unsatisfied (values associated with the
+     *         keys can be null)
+     */
+    private Map<String, Set<String>> refineUnsatisfiedRequirements(Resolver resolver, Reason[] reasons) {
+        log.debug(LOG_ENTRY, "refineUnsatisfiedRequirements", new Object[] { resolver, Arrays.toString(reasons) });
+
+        Map<Requirement, Set<String>> req_resources = new HashMap<Requirement, Set<String>>();
+        // add the reasons to the map, use the requirement as the key, the
+        // resources required the requirement as the values
+        Set<Resource> resources = new HashSet<Resource>();
+        for (Reason reason : reasons) {
+            resources.add(reason.getResource());
+            Requirement key = reason.getRequirement();
+            String value = reason.getResource().getSymbolicName() + "_" + reason.getResource().getVersion().toString();
+            Set<String> values = req_resources.get(key);
+            if (values == null) {
+                values = new HashSet<String>();
+            }
+            values.add(value);
+            req_resources.put(key, values);
+        }
+
+        // remove the requirements that can be satisifed by the resources. It is
+        // listed because the resources are not satisfied by other requirements.
+        // For an instance, the unsatisfied reasons are [package a, required by
+        // bundle aa], [package b, required by bundle bb] and [package c,
+        // required by bundle cc],
+        // If the bundle aa exports the package a and c. In our error message,
+        // we only want to display package a is needed by bundle aa.
+        // Go through each requirement and find out whether the requirement can
+        // be satisfied by the reasons.
+        Set<Capability> caps = new HashSet<Capability>();
+        for (Resource res : resources) {
+            if ((res != null) && (res.getCapabilities() != null)) {
+                List<Capability> capList = Arrays.asList(res.getCapabilities());
+                if (capList != null) {
+                    caps.addAll(capList);
+                }
+            }
+        }
+
+        Iterator<Map.Entry<Requirement, Set<String>>> iterator = req_resources.entrySet().iterator();
+        while (iterator.hasNext()) {
+            Map.Entry<Requirement, Set<String>> entry = iterator.next();
+            Requirement req = entry.getKey();
+            for (Capability cap : caps) {
+                if (req.isSatisfied(cap)) { // remove the key from the map
+                    iterator.remove();
+                    break;
+                }
+            }
+        }
+        // Now the map only contains the necessary missing requirements
+
+        Map<String, Set<String>> result = new HashMap<String, Set<String>>();
+        for (Map.Entry<Requirement, Set<String>> req_res : req_resources.entrySet()) {
+            result.put(req_res.getKey().getFilter(), req_res.getValue());
+        }
+
+        log.debug(LOG_EXIT, "refineUnsatisfiedRequirements", new Object[] { result });
+
+        return result;
+    }
+
+    private static final Set<String> SPECIAL_FILTER_ATTRS = Collections.unmodifiableSet(new HashSet<String>(Arrays
+            .asList(ModellingConstants.OBR_PACKAGE, ModellingConstants.OBR_SYMBOLIC_NAME,
+                    ModellingConstants.OBR_SERVICE, Constants.VERSION_ATTRIBUTE)));
+
+    /**
+     * Turn a requirement into a human readable String for debug.
+     * 
+     * @param filter
+     *            The filter that is failing
+     * @param bundlesFailing
+     *            For problems with a bundle, the set of bundles that have a
+     *            problem
+     * @return human readable form
+     */
+    private Map<String, String> extractConsumableMessageInfo(Map<String, Set<String>> refinedReqs) {
+        log.debug(LOG_ENTRY, "extractConsumableMessageInfo", refinedReqs);
+
+        Map<String, String> unsatisfiedRequirements = new HashMap<String, String>();
+
+        for (Map.Entry<String, Set<String>> filterEntry : refinedReqs.entrySet()) {
+
+            String filter = filterEntry.getKey();
+            Set<String> bundlesFailing = filterEntry.getValue();
+
+            log.debug("unable to satisfy the filter , filter = " + filter + "required by "
+                    + Arrays.toString(bundlesFailing.toArray()));
+
+            Map<String, String> attrs = ManifestHeaderProcessor.parseFilter(filter);
+            Map<String, String> customAttrs = new HashMap<String, String>();
+            for (Map.Entry<String, String> e : attrs.entrySet()) {
+                if (!SPECIAL_FILTER_ATTRS.contains(e.getKey())) {
+                    customAttrs.put(e.getKey(), e.getValue());
+                }
+            }
+
+            StringBuilder msgKey = new StringBuilder();
+            List<Object> inserts = new ArrayList<Object>();
+
+            final String type;
+            boolean unknownType = false;
+            if (attrs.containsKey(ModellingConstants.OBR_PACKAGE)) {
+                type = ModellingConstants.OBR_PACKAGE;
+                msgKey.append("RESOLVER_UNABLE_TO_RESOLVE_PACKAGE");
+                inserts.add(attrs.get(ModellingConstants.OBR_PACKAGE));
+            } else if (attrs.containsKey(ModellingConstants.OBR_SYMBOLIC_NAME)) {
+                type = ModellingConstants.OBR_SYMBOLIC_NAME;
+                msgKey.append("RESOLVER_UNABLE_TO_RESOLVE_BUNDLE");
+                inserts.add(attrs.get(ModellingConstants.OBR_SYMBOLIC_NAME));
+            } else if (attrs.containsKey(ModellingConstants.OBR_SERVICE)) {
+                type = ModellingConstants.OBR_SERVICE;
+                msgKey.append("RESOLVER_UNABLE_TO_RESOLVE_SERVICE");
+                // No insert for service name as the name must be "*" to match
+                // any
+                // Service capability
+            } else {
+                type = ModellingConstants.OBR_UNKNOWN;
+                unknownType = true;
+                msgKey.append("RESOLVER_UNABLE_TO_RESOLVE_FILTER");
+                inserts.add(filter);
+            }
+
+            if (bundlesFailing != null && bundlesFailing.size() != 0) {
+                msgKey.append("_REQUIRED_BY_BUNDLE");
+                if (bundlesFailing.size() == 1)
+                    inserts.add(bundlesFailing.iterator().next()); // Just take
+                // the string
+                // if there's only one
+                // of them
+                else
+                    inserts.add(bundlesFailing.toString()); // Add the whole set
+                // if there
+                // isn't exactly one
+            }
+            if (!unknownType && !customAttrs.isEmpty()) {
+                msgKey.append("_WITH_ATTRS");
+                inserts.add(customAttrs);
+            }
+
+            if (!unknownType && attrs.containsKey(Constants.VERSION_ATTRIBUTE)) {
+                msgKey.append("_WITH_VERSION");
+                VersionRange vr = ManifestHeaderProcessor.parseVersionRange(attrs.get(Constants.VERSION_ATTRIBUTE));
+                inserts.add(vr.getMinimumVersion());
+
+                if (!!!vr.isExactVersion()) {
+                    msgKey.append(vr.isMinimumExclusive() ? "_LOWEX" : "_LOW");
+                    if (vr.getMaximumVersion() != null) {
+                        msgKey.append(vr.isMaximumExclusive() ? "_UPEX" : "_UP");
+                        inserts.add(vr.getMaximumVersion());
+                    }
+                }
+            }
+
+            String msgKeyStr = msgKey.toString();
+
+            String msg = MessageUtil.getMessage(msgKeyStr, inserts.toArray());
+            unsatisfiedRequirements.put(msg, type);
+        }
+
+        log.debug(LOG_EXIT, "extractConsumableMessageInfo", unsatisfiedRequirements);
+
+        return unsatisfiedRequirements;
+    }
+    
+    
+    private Resource findFragmentResource(Resource hostResource) {
+        Capability hostCapability = getHostCapability(hostResource.getCapabilities());       
+        if (hostCapability == null || Capability.FRAGMENT.equals(hostCapability.getName())) {
+            // no capabilities or it's a fragment
+            return null;
+        }
+        
+        log.debug("Searching for fragments for {}", hostResource);
+        
+        DataModelHelper helper = repositoryAdmin.getHelper();
+        
+        String filter = "(&(host=" + hostResource.getSymbolicName() + "))";
+        Requirement fragmentRequirement = helper.requirement(Capability.FRAGMENT, filter);
+        Resource[] fragmentResources = repositoryAdmin.discoverResources(new Requirement[] { fragmentRequirement });
+        if (fragmentResources != null && fragmentResources.length > 0) {
+
+            if (log.isDebugEnabled()) {
+                log.debug("Fragments found for {}: {}", new Object[] { hostResource, Arrays.asList(fragmentResources) } );                
+            }
+            
+            List<Resource> candidateFragments = new ArrayList<Resource>();
+
+            // trim out fragments that do not match the host
+            for (Resource fragmentResource : fragmentResources) {
+                Requirement fragmentHostRequirement = getFragmentHostRequirement(fragmentResource.getRequirements());
+                if (fragmentHostRequirement == null) {
+                    log.debug("Ignoring {} fragment. No host requirement found.", fragmentResource);
+                    continue;
+                }
+                if (fragmentHostRequirement.isSatisfied(hostCapability)) {
+                    candidateFragments.add(fragmentResource);
+                }
+            }
+
+            int candiates = candidateFragments.size();
+            if (candiates == 0) {
+                log.debug("No matching fragments found for {}", hostResource);
+                return null;
+            } else if (candiates == 1) {
+                Resource fragmentResource = candidateFragments.get(0);
+                log.debug("Single matching fragment found for {}: {}", new Object[] { hostResource, fragmentResource }); 
+                return fragmentResource;
+            } else {
+                Collections.sort(candidateFragments, new Comparator<Resource>() {
+                    @Override
+                    public int compare(Resource object1, Resource object2) {
+                        Version version1 = object1.getVersion();
+                        Version version2 = object2.getVersion();
+                        return version2.compareTo(version1);
+                    }
+                });
+                Resource fragmentResource = candidateFragments.get(0);
+                log.debug("Multiple matching fragments found for {}. Fragment selected: {}", new Object[] { hostResource, fragmentResource }); 
+                return fragmentResource;
+            }
+
+        } else {
+            log.debug("No fragments found for {}", hostResource);
+        }
+
+        return null;
+    }
+    
+    /*
+     * Returns "fragment" or "bundle" capability. 
+     */
+    private Capability getHostCapability(Capability[] capabilities) {
+        Capability bundleCapability = null;
+        if (capabilities != null) {
+            for (Capability capability : capabilities) {
+                if (Capability.BUNDLE.equals(capability.getName()) && bundleCapability == null) {
+                    bundleCapability = capability;
+                } else if (Capability.FRAGMENT.equals(capability.getName())) {
+                    return capability;
+                }
+            }
+        }
+        return bundleCapability;
+    }
+    
+    private Requirement getFragmentHostRequirement(Requirement[] requirements) {
+        if (requirements != null) {
+            for (Requirement requirement : requirements) {
+                if (Capability.BUNDLE.equals(requirement.getName()) && requirement.isExtend()) {
+                    return requirement;
+                }
+            }
+        }
+        return null;
+    }
+}

Added: geronimo/server/branches/3.0-beta/plugins/aries/geronimo-aries-resolver/src/main/java/org/apache/geronimo/aries/resolver/obr/generator/RepositoryDescriptorGenerator.java
URL: http://svn.apache.org/viewvc/geronimo/server/branches/3.0-beta/plugins/aries/geronimo-aries-resolver/src/main/java/org/apache/geronimo/aries/resolver/obr/generator/RepositoryDescriptorGenerator.java?rev=1309100&view=auto
==============================================================================
--- geronimo/server/branches/3.0-beta/plugins/aries/geronimo-aries-resolver/src/main/java/org/apache/geronimo/aries/resolver/obr/generator/RepositoryDescriptorGenerator.java (added)
+++ geronimo/server/branches/3.0-beta/plugins/aries/geronimo-aries-resolver/src/main/java/org/apache/geronimo/aries/resolver/obr/generator/RepositoryDescriptorGenerator.java Tue Apr  3 19:16:59 2012
@@ -0,0 +1,154 @@
+/*
+ * 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.geronimo.aries.resolver.obr.generator;
+
+import java.util.Map;
+import java.util.Set;
+
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.apache.aries.application.Content;
+import org.apache.aries.application.management.BundleInfo;
+import org.apache.aries.application.utils.manifest.ManifestHeaderProcessor;
+import org.apache.felix.bundlerepository.Resource;
+import org.osgi.framework.Constants;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+public final class RepositoryDescriptorGenerator
+{
+  public static Document generateRepositoryDescriptor(String name, Set<BundleInfo> bundles) throws ParserConfigurationException
+  {
+    Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
+    Element root = doc.createElement("repository");
+    
+    root.setAttribute("name", name);
+    doc.appendChild(root);
+    
+    for (BundleInfo info : bundles) {
+      Element resource = doc.createElement("resource");
+      resource.setAttribute(Resource.VERSION, info.getVersion().toString());
+      resource.setAttribute("uri", info.getLocation());
+      resource.setAttribute(Resource.SYMBOLIC_NAME, info.getSymbolicName());
+      resource.setAttribute(Resource.PRESENTATION_NAME, info.getHeaders().get(Constants.BUNDLE_NAME));
+      resource.setAttribute(Resource.ID, info.getSymbolicName() + "/" + info.getVersion());
+      root.appendChild(resource);
+      
+      addBundleCapability(doc, resource, info);
+      
+      for (Content p : info.getExportPackage()) {
+        addPackageCapability(doc, resource, info, p);
+      }
+      
+      for (Content p : info.getImportPackage()) {
+        addPackageRequirement(doc, resource, info, p);
+      }
+      
+      for (Content p : info.getRequireBundle()) {
+        addBundleRequirement(doc, resource, info, p);
+      }
+    }
+    
+    return doc;
+  }
+
+  private static void addBundleRequirement(Document doc, Element resource, BundleInfo info, Content p)
+  {
+    Element requirement = doc.createElement("require");
+    requirement.setAttribute("name", "bundle");
+    
+    requirement.setAttribute("extend", "false");
+    requirement.setAttribute("multiple", "false");
+    requirement.setAttribute("optional", getOptional(p));
+    
+    requirement.setAttribute("filter", ManifestHeaderProcessor.generateFilter("symbolicname", p.getContentName(), p.getAttributes()));
+    
+    resource.appendChild(requirement);
+  }
+
+  private static void addPackageRequirement(Document doc, Element resource, BundleInfo info, Content p)
+  {
+    Element requirement = doc.createElement("require");
+    requirement.setAttribute("name", "package");
+    
+    requirement.setAttribute("extend", "false");
+    requirement.setAttribute("multiple", "false");
+    requirement.setAttribute("optional", getOptional(p));
+        
+    requirement.setAttribute("filter", ManifestHeaderProcessor.generateFilter("package", p.getContentName(), p.getAttributes()));
+    
+    resource.appendChild(requirement);
+  }
+
+  private static void addPackageCapability(Document doc, Element resource, BundleInfo info, Content p)
+  {
+    Element capability = doc.createElement("capability");
+    capability.setAttribute("name", "package");
+    resource.appendChild(capability);
+    
+    addProperty(doc, capability, "package", p.getContentName(), null);
+    addProperty(doc, capability, Constants.VERSION_ATTRIBUTE, p.getVersion().toString(), "version");
+    addProperty(doc, capability, Constants.BUNDLE_SYMBOLICNAME_ATTRIBUTE, info.getSymbolicName(), null);
+    addProperty(doc, capability, Constants.BUNDLE_VERSION_ATTRIBUTE, info.getVersion().toString(), "version");
+    
+    for (Map.Entry<String, String> entry : p.getAttributes().entrySet()) {
+      if (!!!Constants.VERSION_ATTRIBUTE.equals(entry.getKey())) {
+        addProperty(doc, capability, entry.getKey(), entry.getValue(), null);
+      }
+    }
+    
+    String mandatory = p.getDirective(Constants.MANDATORY_DIRECTIVE);
+    if (mandatory == null) mandatory = "";
+    addProperty(doc, capability, Constants.MANDATORY_DIRECTIVE, mandatory, "set");
+  }
+
+  private static void addBundleCapability(Document doc, Element resource, BundleInfo info)
+  {
+    Element capability = doc.createElement("capability");
+    capability.setAttribute("name", "bundle");
+    resource.appendChild(capability);
+    
+    addProperty(doc, capability, Resource.SYMBOLIC_NAME, info.getSymbolicName(), null);
+    addProperty(doc, capability, Constants.VERSION_ATTRIBUTE, info.getVersion().toString(), "version");
+    addProperty(doc, capability, Resource.PRESENTATION_NAME, info.getHeaders().get(Constants.BUNDLE_NAME), null);
+    addProperty(doc, capability, Constants.BUNDLE_MANIFESTVERSION, "2", "version");
+    addProperty(doc, capability, Constants.FRAGMENT_ATTACHMENT_DIRECTIVE, info.getBundleDirectives().get(Constants.FRAGMENT_ATTACHMENT_DIRECTIVE), null);
+    addProperty(doc, capability, Constants.SINGLETON_DIRECTIVE, info.getBundleDirectives().get(Constants.SINGLETON_DIRECTIVE), null);
+  }
+
+  private static void addProperty(Document doc, Element capability, String name,
+      String value, String type)
+  {
+    Element p = doc.createElement("p");
+    p.setAttribute("n", name);
+    p.setAttribute("v", value);
+    if (type != null) p.setAttribute("t", type);
+    capability.appendChild(p);
+  }
+
+  private static String getOptional(Content p) {
+    String resolution = p.getDirective(Constants.RESOLUTION_DIRECTIVE);
+    if (Constants.RESOLUTION_OPTIONAL.equals(resolution)) {
+        return "true";
+    } else {
+        return "false";
+    }
+  }
+}

Added: geronimo/server/branches/3.0-beta/plugins/aries/geronimo-aries-resolver/src/main/java/org/apache/geronimo/aries/resolver/obr/impl/ApplicationResourceImpl.java
URL: http://svn.apache.org/viewvc/geronimo/server/branches/3.0-beta/plugins/aries/geronimo-aries-resolver/src/main/java/org/apache/geronimo/aries/resolver/obr/impl/ApplicationResourceImpl.java?rev=1309100&view=auto
==============================================================================
--- geronimo/server/branches/3.0-beta/plugins/aries/geronimo-aries-resolver/src/main/java/org/apache/geronimo/aries/resolver/obr/impl/ApplicationResourceImpl.java (added)
+++ geronimo/server/branches/3.0-beta/plugins/aries/geronimo-aries-resolver/src/main/java/org/apache/geronimo/aries/resolver/obr/impl/ApplicationResourceImpl.java Tue Apr  3 19:16:59 2012
@@ -0,0 +1,170 @@
+/*
+ * 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.geronimo.aries.resolver.obr.impl;
+
+import java.util.Dictionary;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.aries.application.Content;
+import org.apache.aries.application.utils.manifest.ManifestHeaderProcessor;
+import org.osgi.framework.Filter;
+import org.osgi.framework.FrameworkUtil;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.framework.ServiceReference;
+import org.osgi.framework.Version;
+import org.apache.felix.bundlerepository.Capability;
+import org.apache.felix.bundlerepository.Repository;
+import org.apache.felix.bundlerepository.Requirement;
+import org.apache.felix.bundlerepository.Resource;
+
+public class ApplicationResourceImpl implements Resource
+{
+  private String _symbolicName;
+  private Version _version;
+  private Requirement[] _requirements;
+  
+  private static class FilterWrapper implements Filter
+  {
+    private Filter delgate;
+    
+    public FilterWrapper(Filter f)
+    {
+      delgate = f;
+    }
+    
+    public boolean match(ServiceReference reference)
+    {
+      return delgate.match(reference);
+    }
+
+    public boolean match(Dictionary dictionary)
+    {
+      boolean result = delgate.match(dictionary);
+      return result;
+    }
+
+    public boolean matchCase(Dictionary dictionary)
+    {
+      return delgate.matchCase(dictionary);
+    }
+
+    public boolean matches(Map map)
+    {
+      return delgate.matches(map);
+    }
+    
+    public String toString()
+    {
+      return delgate.toString();
+    }
+  }
+  
+  public ApplicationResourceImpl(String appName, Version appVersion, List<Content> appContent)
+  {
+    _symbolicName = appName;
+    _version = appVersion;
+    
+    _requirements = new Requirement[appContent.size()];
+    for (int i = 0; i < _requirements.length; i++) {
+      Content c = appContent.get(i);
+      
+      String comment = "Requires " + Resource.SYMBOLIC_NAME + " " + c.getContentName() + " with attributes " + c.getAttributes();
+      
+      String resolution = c.getDirective("resolution");
+
+      boolean optional = Boolean.valueOf(resolution);
+      
+      String f = ManifestHeaderProcessor.generateFilter(Resource.SYMBOLIC_NAME, c.getContentName(), c.getAttributes());
+      Filter filter;
+      try {
+        filter = FrameworkUtil.createFilter(f);
+        _requirements[i] = new RequirementImpl("bundle", new FilterWrapper(filter), false, optional, false, comment);
+      } catch (InvalidSyntaxException e) {
+        // TODO work out what to do if his happens. If it does our filter generation code is bust.
+      }
+    }
+  }
+  
+  public Capability[] getCapabilities()
+  {
+    return null;
+  }
+
+  public String[] getCategories()
+  {
+    return null;
+  }
+
+  public String getId()
+  {
+    return _symbolicName;
+  }
+
+  public String getPresentationName()
+  {
+    return _symbolicName;
+  }
+
+  public Map getProperties()
+  {
+    return null;
+  }
+
+  public Repository getRepository()
+  {
+    return null;
+  }
+
+  public Requirement[] getRequirements()
+  {
+    return _requirements;
+  }
+
+  public String getSymbolicName()
+  {
+    return _symbolicName;
+  }
+
+  public java.net.URL getURL()
+  {
+    return null;
+  }
+
+  public Version getVersion()
+  {
+    return _version;
+  }
+
+  public Long getSize()
+  {
+    return 0l;
+  }
+
+  public String getURI()
+  {
+    // TODO Auto-generated method stub
+    return null;
+  }
+
+  public boolean isLocal()
+  {
+    return false;
+  }
+}
\ No newline at end of file

Added: geronimo/server/branches/3.0-beta/plugins/aries/geronimo-aries-resolver/src/main/java/org/apache/geronimo/aries/resolver/obr/impl/MapToDictionary.java
URL: http://svn.apache.org/viewvc/geronimo/server/branches/3.0-beta/plugins/aries/geronimo-aries-resolver/src/main/java/org/apache/geronimo/aries/resolver/obr/impl/MapToDictionary.java?rev=1309100&view=auto
==============================================================================
--- geronimo/server/branches/3.0-beta/plugins/aries/geronimo-aries-resolver/src/main/java/org/apache/geronimo/aries/resolver/obr/impl/MapToDictionary.java (added)
+++ geronimo/server/branches/3.0-beta/plugins/aries/geronimo-aries-resolver/src/main/java/org/apache/geronimo/aries/resolver/obr/impl/MapToDictionary.java Tue Apr  3 19:16:59 2012
@@ -0,0 +1,123 @@
+/*
+ * 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.geronimo.aries.resolver.obr.impl;
+
+import java.util.Dictionary;
+import java.util.Enumeration;
+import java.util.Iterator;
+import java.util.Map;
+
+/**
+ * @version $Rev: 23025 $ $Date: 2011-12-20 13:26:50 -0500 (Tue, 20 Dec 2011) $
+ */
+public class MapToDictionary extends Dictionary
+{
+  /**
+   * Map source.
+   */
+  private final Map m_map;
+
+  public MapToDictionary(Map map)
+  {
+    m_map = map;
+  }
+
+  public Enumeration elements()
+  {
+    if (m_map == null) {
+      return null;
+    }
+    return new IteratorToEnumeration(m_map.values().iterator());
+  }
+
+  public Object get(Object key)
+  {
+    if (m_map == null) {
+      return null;
+    }
+    return m_map.get(key);
+  }
+
+  public boolean isEmpty()
+  {
+    if (m_map == null) {
+      return true;
+    }
+    return m_map.isEmpty();
+  }
+
+  public Enumeration keys()
+  {
+    if (m_map == null) {
+      return null;
+    }
+    return new IteratorToEnumeration(m_map.keySet().iterator());
+  }
+
+  public Object put(Object key, Object value)
+  {
+    throw new UnsupportedOperationException();
+  }
+
+  public Object remove(Object key)
+  {
+    throw new UnsupportedOperationException();
+  }
+
+  public int size()
+  {
+    if (m_map == null) {
+      return 0;
+    }
+    return m_map.size();
+  }
+
+  @Override
+  public String toString()
+  {
+    return m_map != null ? m_map.toString() : "null";
+  }
+
+  private static class IteratorToEnumeration implements Enumeration
+  {
+    private final Iterator m_iter;
+
+    public IteratorToEnumeration(Iterator iter)
+    {
+      m_iter = iter;
+    }
+
+    public boolean hasMoreElements()
+    {
+      if (m_iter == null)
+        return false;
+      return m_iter.hasNext();
+    }
+
+    public Object nextElement()
+    {
+      if (m_iter == null)
+        return null;
+      return m_iter.next();
+    }
+  }
+
+}

Added: geronimo/server/branches/3.0-beta/plugins/aries/geronimo-aries-resolver/src/main/java/org/apache/geronimo/aries/resolver/obr/impl/OBRBundleInfo.java
URL: http://svn.apache.org/viewvc/geronimo/server/branches/3.0-beta/plugins/aries/geronimo-aries-resolver/src/main/java/org/apache/geronimo/aries/resolver/obr/impl/OBRBundleInfo.java?rev=1309100&view=auto
==============================================================================
--- geronimo/server/branches/3.0-beta/plugins/aries/geronimo-aries-resolver/src/main/java/org/apache/geronimo/aries/resolver/obr/impl/OBRBundleInfo.java (added)
+++ geronimo/server/branches/3.0-beta/plugins/aries/geronimo-aries-resolver/src/main/java/org/apache/geronimo/aries/resolver/obr/impl/OBRBundleInfo.java Tue Apr  3 19:16:59 2012
@@ -0,0 +1,146 @@
+/*
+ * 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.geronimo.aries.resolver.obr.impl;
+
+import org.apache.aries.application.Content;
+import org.apache.aries.application.management.BundleInfo;
+import org.osgi.framework.Version;
+
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * @version $Rev: 23025 $ $Date: 2011-12-20 13:26:50 -0500 (Tue, 20 Dec 2011) $
+ */
+public class OBRBundleInfo implements BundleInfo
+{
+
+  private final String symbolicName;
+  private final Version version;
+  private final String location;
+  private final Set<Content> importPackage;
+  private final Set<Content> exportPackage;
+  private final Set<Content> importService;
+  private final Set<Content> exportService;
+  private final Map<String, String> headers;
+  private final Set<Content> requireBundle;
+  private final Map<String, String> attributes;
+  private final Map<String, String> directives;
+
+  public OBRBundleInfo(String symbolicName, Version version, String location,
+                       Set<Content> importPackage, Set<Content> exportPackage,
+                       Set<Content> importService, Set<Content> exportService,
+                       Set<Content> requireBundle, Map<String, String> attributes,
+                       Map<String, String> directives, Map<String, String> headers)
+  {
+    this.symbolicName = symbolicName;
+    this.version = version;
+    this.location = location;
+    this.importPackage = importPackage;
+    this.exportPackage = exportPackage;
+    this.importService = importService;
+    this.exportService = exportService;
+    this.headers = headers;
+    this.requireBundle = requireBundle;
+    this.attributes = attributes;
+    this.directives = directives;
+  }
+
+  public String getSymbolicName()
+  {
+    return symbolicName;
+  }
+
+  public Version getVersion()
+  {
+    return version;
+  }
+
+  public String getLocation()
+  {
+    return location;
+  }
+
+  public Set<Content> getImportPackage()
+  {
+    return importPackage;
+  }
+
+  public Set<Content> getExportPackage()
+  {
+    return exportPackage;
+  }
+
+  public Set<Content> getImportService()
+  {
+    return importService;
+  }
+
+  public Set<Content> getExportService()
+  {
+    return exportService;
+  }
+
+  public Map<String, String> getHeaders()
+  {
+    return headers;
+  }
+
+  public Map<String, String> getBundleAttributes()
+  {
+    return attributes;
+  }
+
+  public Map<String, String> getBundleDirectives()
+  {
+    return directives;
+  }
+
+  public Set<Content> getRequireBundle()
+  {
+    return requireBundle;
+  }
+    
+  public String toString()
+  {
+    return symbolicName + "_" + version;
+  }
+
+  public int hashCode() 
+  {
+    final int prime = 31;
+    int result = 1;
+    result = prime * result + symbolicName.hashCode();
+    result = prime * result + version.hashCode();
+    return result;
+  }
+
+  public boolean equals(Object obj) {
+    if (this == obj) return true;
+    if (obj == null) return false;
+    if (getClass() != obj.getClass()) {
+        return false;
+    }
+    OBRBundleInfo other = (OBRBundleInfo) obj;
+    return (symbolicName.equals(other.symbolicName)
+            && version.equals(other.version));
+  }
+  
+}

Added: geronimo/server/branches/3.0-beta/plugins/aries/geronimo-aries-resolver/src/main/java/org/apache/geronimo/aries/resolver/obr/impl/RequirementImpl.java
URL: http://svn.apache.org/viewvc/geronimo/server/branches/3.0-beta/plugins/aries/geronimo-aries-resolver/src/main/java/org/apache/geronimo/aries/resolver/obr/impl/RequirementImpl.java?rev=1309100&view=auto
==============================================================================
--- geronimo/server/branches/3.0-beta/plugins/aries/geronimo-aries-resolver/src/main/java/org/apache/geronimo/aries/resolver/obr/impl/RequirementImpl.java (added)
+++ geronimo/server/branches/3.0-beta/plugins/aries/geronimo-aries-resolver/src/main/java/org/apache/geronimo/aries/resolver/obr/impl/RequirementImpl.java Tue Apr  3 19:16:59 2012
@@ -0,0 +1,83 @@
+/*
+ * 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.geronimo.aries.resolver.obr.impl;
+
+import org.osgi.framework.Filter;
+import org.apache.felix.bundlerepository.Capability;
+import org.apache.felix.bundlerepository.Requirement;
+
+/**
+ * @version $Rev: 23025 $ $Date: 2011-12-20 13:26:50 -0500 (Tue, 20 Dec 2011) $
+ */
+public class RequirementImpl implements Requirement
+{
+  private final String name;
+  private final Filter filter;
+  private final boolean multiple;
+  private final boolean optional;
+  private final boolean extend;
+  private final String comment;
+
+  public RequirementImpl(String name, Filter filter, boolean multiple, boolean optional, boolean extend, String comment)
+  {
+    this.name = name;
+    this.filter = filter;
+    this.multiple = multiple;
+    this.optional = optional;
+    this.extend = extend;
+    this.comment = comment;
+  }
+
+  public String getName()
+  {
+    return name;
+  }
+
+  public String getFilter()
+  {
+    return filter.toString();
+  }
+
+  public boolean isMultiple()
+  {
+    return multiple;
+  }
+
+  public boolean isOptional()
+  {
+    return optional;
+  }
+
+  public boolean isExtend()
+  {
+    return extend;
+  }
+
+  public String getComment()
+  {
+    return comment;
+  }
+
+  public boolean isSatisfied(Capability capability)
+  {
+    return name.equals(capability.getName()) && filter.match(new MapToDictionary(capability.getPropertiesAsMap()));
+  }
+}

Added: geronimo/server/branches/3.0-beta/plugins/aries/geronimo-aries-resolver/src/main/java/org/apache/geronimo/aries/resolver/obr/impl/ResourceWrapper.java
URL: http://svn.apache.org/viewvc/geronimo/server/branches/3.0-beta/plugins/aries/geronimo-aries-resolver/src/main/java/org/apache/geronimo/aries/resolver/obr/impl/ResourceWrapper.java?rev=1309100&view=auto
==============================================================================
--- geronimo/server/branches/3.0-beta/plugins/aries/geronimo-aries-resolver/src/main/java/org/apache/geronimo/aries/resolver/obr/impl/ResourceWrapper.java (added)
+++ geronimo/server/branches/3.0-beta/plugins/aries/geronimo-aries-resolver/src/main/java/org/apache/geronimo/aries/resolver/obr/impl/ResourceWrapper.java Tue Apr  3 19:16:59 2012
@@ -0,0 +1,87 @@
+/*
+ * 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.geronimo.aries.resolver.obr.impl;
+
+import java.util.Map;
+
+import org.apache.felix.bundlerepository.Capability;
+import org.apache.felix.bundlerepository.Requirement;
+import org.apache.felix.bundlerepository.Resource;
+import org.osgi.framework.Version;
+
+/**
+ * @version $Rev: 23025 $ $Date: 2011-12-20 13:26:50 -0500 (Tue, 20 Dec 2011) $
+ */
+public class ResourceWrapper implements Resource {
+
+    private final Resource resource;
+    
+    public ResourceWrapper(Resource resource) {
+        this.resource = resource;
+    }
+    
+    public Capability[] getCapabilities() {
+        return resource.getCapabilities();
+    }
+
+    public String[] getCategories() {
+        return resource.getCategories();
+    }
+
+    public String getId() {
+        return resource.getId();
+    }
+
+    public String getPresentationName() {
+        return resource.getPresentationName();
+    }
+
+    public Map getProperties() {
+        return resource.getProperties();
+    }
+
+    public Requirement[] getRequirements() {
+        return resource.getRequirements();
+    }
+
+    public Long getSize() {
+        return resource.getSize();
+    }
+
+    public String getSymbolicName() {
+        return resource.getSymbolicName();
+    }
+
+    public String getURI() {
+        return resource.getURI();
+    }
+
+    public Version getVersion() {
+        return resource.getVersion();
+    }
+
+    public boolean isLocal() {
+        return false;
+    }
+
+    public String toString() {
+        return resource.toString();
+    }
+}

Added: geronimo/server/branches/3.0-beta/plugins/aries/geronimo-aries-resolver/src/main/resources/OSGI-INF/blueprint/obr-resolver.xml
URL: http://svn.apache.org/viewvc/geronimo/server/branches/3.0-beta/plugins/aries/geronimo-aries-resolver/src/main/resources/OSGI-INF/blueprint/obr-resolver.xml?rev=1309100&view=auto
==============================================================================
--- geronimo/server/branches/3.0-beta/plugins/aries/geronimo-aries-resolver/src/main/resources/OSGI-INF/blueprint/obr-resolver.xml (added)
+++ geronimo/server/branches/3.0-beta/plugins/aries/geronimo-aries-resolver/src/main/resources/OSGI-INF/blueprint/obr-resolver.xml Tue Apr  3 19:16:59 2012
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+    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.
+-->
+<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
+           xmlns:ext="http://aries.apache.org/blueprint/xmlns/blueprint-ext/v1.0.0"
+           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+           xsi:schemaLocation="http://www.osgi.org/xmlns/blueprint/v1.0.0">
+
+    <ext:property-placeholder placeholder-prefix="$[" placeholder-suffix="]">
+        <ext:default-properties>
+            <ext:property name="ariesApplicationResolver.returnOptionalResources" value="false" />
+            <ext:property name="ariesApplicationResolver.resolveFragments" value="false" />
+        </ext:default-properties>
+    </ext:property-placeholder>
+    
+    <bean id="obr-resolver" class="org.apache.geronimo.aries.resolver.obr.OBRAriesResolver" scope="singleton"
+          activation="eager">
+        <argument>
+            <reference interface="org.apache.felix.bundlerepository.RepositoryAdmin"/>
+        </argument>
+        <property name="returnOptionalResources" value="$[ariesApplicationResolver.returnOptionalResources]"/>
+        <property name="resolveFragments" value="$[ariesApplicationResolver.resolveFragments]"/>
+    </bean>
+
+    <service interface="org.apache.aries.application.management.AriesApplicationResolver" ref="obr-resolver"/>
+
+</blueprint>