You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@aries.apache.org by no...@apache.org on 2010/02/18 17:11:29 UTC

svn commit: r911468 - in /incubator/aries/trunk/application: application-api/src/main/java/org/apache/aries/application/management/ application-management/src/main/java/org/apache/aries/application/management/impl/ application-obr-resolver/src/main/jav...

Author: not
Date: Thu Feb 18 16:11:29 2010
New Revision: 911468

URL: http://svn.apache.org/viewvc?rev=911468&view=rev
Log:
ARIES-174 resolve against the application content.

Added:
    incubator/aries/trunk/application/application-obr-resolver/src/main/java/org/apache/aries/application/resolver/obr/generator/
    incubator/aries/trunk/application/application-obr-resolver/src/main/java/org/apache/aries/application/resolver/obr/generator/RepositoryDescriptorGenerator.java
Modified:
    incubator/aries/trunk/application/application-api/src/main/java/org/apache/aries/application/management/AriesApplicationResolver.java
    incubator/aries/trunk/application/application-api/src/main/java/org/apache/aries/application/management/BundleInfo.java
    incubator/aries/trunk/application/application-management/src/main/java/org/apache/aries/application/management/impl/BundleInfoImpl.java
    incubator/aries/trunk/application/application-obr-resolver/src/main/java/org/apache/aries/application/resolver/obr/OBRAriesResolver.java
    incubator/aries/trunk/application/application-obr-resolver/src/main/java/org/apache/aries/application/resolver/obr/impl/OBRBundleInfo.java

Modified: incubator/aries/trunk/application/application-api/src/main/java/org/apache/aries/application/management/AriesApplicationResolver.java
URL: http://svn.apache.org/viewvc/incubator/aries/trunk/application/application-api/src/main/java/org/apache/aries/application/management/AriesApplicationResolver.java?rev=911468&r1=911467&r2=911468&view=diff
==============================================================================
--- incubator/aries/trunk/application/application-api/src/main/java/org/apache/aries/application/management/AriesApplicationResolver.java (original)
+++ incubator/aries/trunk/application/application-api/src/main/java/org/apache/aries/application/management/AriesApplicationResolver.java Thu Feb 18 16:11:29 2010
@@ -21,11 +21,35 @@
 
 import java.util.Set;
 
+import org.apache.aries.application.ApplicationMetadata;
 import org.osgi.framework.Version;
 
+/**
+ * An {@code AriesApplicationResolver} is a service used by the {@link AriesApplicationManager} when one of the
+ * {@code createApplication} methods are called. It is used to "deploy" the application. The "deploy" process
+ * generates an Aries Deployment manifest <a href="http://incubator.apache.org/aries/applications.html"/>See
+ * the design documentation</a>.
+ * 
+ * <p>The {@code AriesApplicationManager} calls the resolve method in order to determine which bundles are required.
+ * </p>
+ */
 public interface AriesApplicationResolver {
 
-  /** Resolve an AriesApplication 
+  /** 
+   * Resolve an AriesApplication. The implementation of this method is expected to do the following:
+   * 
+   * <ol>
+   *   <li>Extract from the {@link AriesApplication}'s the application's content. This is performed
+   *     using the {@link AriesApplication#getApplicationMetadata()} method following by calling 
+   *     {@link ApplicationMetadata#getApplicationContents()}.
+   *   </li>
+   *   <li>Resolve the application content using any configured repositories for bundles, and the
+   *     bundles that are contained by value inside the application. These bundles can be obtained
+   *     by calling {@link AriesApplication#getBundleInfo()}.
+   *   </li>
+   * </ol>
+   * 
+   * The method returns the set of bundle info objects that should be used.
    * 
    * @param app The application to resolve
    * @return The additional bundles required to ensure that the application resolves. This
@@ -35,8 +59,10 @@
   Set<BundleInfo> resolve (AriesApplication app, ResolveConstraint... constraints) throws ResolverException ;
 
   /** 
-   * Return the info for the requested bundle. If no matching bundle exists in the
-   * resolver runtime then null is returned.
+   * Return the info for the requested bundle. This method is called when installing
+   * an application to determine where the bundle is located in order to install it.
+   * 
+   * <p>If no matching bundle exists in the resolver runtime then null is returned.</p>
    * 
    * @param bundleSymbolicName the bundle symbolic name.
    * @param bundleVersion      the version of the bundle

Modified: incubator/aries/trunk/application/application-api/src/main/java/org/apache/aries/application/management/BundleInfo.java
URL: http://svn.apache.org/viewvc/incubator/aries/trunk/application/application-api/src/main/java/org/apache/aries/application/management/BundleInfo.java?rev=911468&r1=911467&r2=911468&view=diff
==============================================================================
--- incubator/aries/trunk/application/application-api/src/main/java/org/apache/aries/application/management/BundleInfo.java (original)
+++ incubator/aries/trunk/application/application-api/src/main/java/org/apache/aries/application/management/BundleInfo.java Thu Feb 18 16:11:29 2010
@@ -32,6 +32,12 @@
   /** Bundle-SymbolicName */
   public String getSymbolicName();
   
+  /** Returns the directives specified on the symbolic name */
+  public Map<String, String> getBundleDirectives();
+  
+  /** Returns the attributes specified on the symbolic name */
+  public Map<String, String> getBundleAttributes();
+  
   /** Bundle-Version: */
   public Version getVersion();
   
@@ -41,6 +47,9 @@
   /** Import-Package */
   public Set<Content> getImportPackage();
   
+  /** Require-Bundle */
+  public Set<Content> getRequireBundle();
+  
   /** Export-Package */
   public Set<Content> getExportPackage();
 

Modified: incubator/aries/trunk/application/application-management/src/main/java/org/apache/aries/application/management/impl/BundleInfoImpl.java
URL: http://svn.apache.org/viewvc/incubator/aries/trunk/application/application-management/src/main/java/org/apache/aries/application/management/impl/BundleInfoImpl.java?rev=911468&r1=911467&r2=911468&view=diff
==============================================================================
--- incubator/aries/trunk/application/application-management/src/main/java/org/apache/aries/application/management/impl/BundleInfoImpl.java (original)
+++ incubator/aries/trunk/application/application-management/src/main/java/org/apache/aries/application/management/impl/BundleInfoImpl.java Thu Feb 18 16:11:29 2010
@@ -36,18 +36,20 @@
 import org.osgi.framework.Version;
 
 public class BundleInfoImpl implements BundleInfo {
-  private String _symbolicName;
+  private Content _symbolicName;
   private Version _version;
   private Attributes _attributes;
   private Set<Content> _exportPackages = null;
   private Set<Content> _importPackages = null;
   private Set<Content> _exportServices = null;
   private Set<Content> _importServices = null;
+  private Set<Content> _requireBundle = null;
+  
   private String _location;
   private ApplicationMetadataFactory _applicationMetadataFactory;
   
   public BundleInfoImpl (ApplicationMetadataFactory amf, BundleManifest bm, String location) { 
-    _symbolicName = bm.getSymbolicName();
+    _symbolicName = amf.parseContent(bm.getSymbolicName());
     _version = bm.getVersion();
     _attributes = bm.getRawAttributes();
     _location = location;
@@ -97,7 +99,7 @@
   }
 
   public String getSymbolicName() {
-    return _symbolicName;
+    return _symbolicName.getContentName();
   }
 
   public Version getVersion() {
@@ -114,4 +116,23 @@
     }
     return result;
   }
+
+  public Map<String, String> getBundleAttributes()
+  {
+    return _symbolicName.getAttributes();
+  }
+
+  public Map<String, String> getBundleDirectives()
+  {
+    return _symbolicName.getDirectives();
+  }
+
+  public Set<Content> getRequireBundle()
+  {
+    if (_requireBundle == null) {
+      _requireBundle = getContentSetFromHeader(_attributes, Constants.REQUIRE_BUNDLE);
+    }
+    
+    return _requireBundle;
+  }
 }

Modified: incubator/aries/trunk/application/application-obr-resolver/src/main/java/org/apache/aries/application/resolver/obr/OBRAriesResolver.java
URL: http://svn.apache.org/viewvc/incubator/aries/trunk/application/application-obr-resolver/src/main/java/org/apache/aries/application/resolver/obr/OBRAriesResolver.java?rev=911468&r1=911467&r2=911468&view=diff
==============================================================================
--- incubator/aries/trunk/application/application-obr-resolver/src/main/java/org/apache/aries/application/resolver/obr/OBRAriesResolver.java (original)
+++ incubator/aries/trunk/application/application-obr-resolver/src/main/java/org/apache/aries/application/resolver/obr/OBRAriesResolver.java Thu Feb 18 16:11:29 2010
@@ -20,12 +20,18 @@
 
 package org.apache.aries.application.resolver.obr;
 
+import java.io.File;
+import java.net.URL;
 import java.util.HashMap;
 import java.util.HashSet;
 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.management.AriesApplication;
@@ -33,6 +39,7 @@
 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.resolver.obr.generator.RepositoryDescriptorGenerator;
 import org.apache.aries.application.resolver.obr.impl.ApplicationResourceImpl;
 import org.apache.aries.application.resolver.obr.impl.OBRBundleInfo;
 import org.apache.aries.application.utils.manifest.ManifestHeaderProcessor;
@@ -43,6 +50,7 @@
 import org.osgi.service.obr.Resource;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
+import org.w3c.dom.Document;
 
 /**
  * @version $Rev$ $Date$
@@ -58,6 +66,10 @@
     this.repositoryAdmin = repositoryAdmin;
   }
 
+  /**
+   * This method is synchronized because it changes the repositories understood by OBR, and we don't
+   * want one apps by value content being used to resolve another. I'll ask for an OBR enhancement.
+   */
   public Set<BundleInfo> resolve(AriesApplication app, ResolveConstraint... constraints) throws ResolverException
   {
     log.trace("resolving {}", app);
@@ -71,22 +83,42 @@
 
     // add a resource describing the requirements of the application metadata.
     obrResolver.add(new ApplicationResourceImpl(appName, appVersion, appContent));
+
+    URL appRepoURL = null;
     
-    // TODO we need to resolve against the app content so we need to generate an OBR.xml for the content
+    try {
+      Document doc = RepositoryDescriptorGenerator.generateRepositoryDescriptor(appName + "_" + appVersion, app.getBundleInfo());
+      
+      File f = File.createTempFile(appName + "_" + appVersion, "repository.xml");
+      TransformerFactory.newInstance().newTransformer().transform(new DOMSource(doc), new StreamResult(f));
+      
+      appRepoURL = f.toURI().toURL();
+      
+      repositoryAdmin.addRepository(appRepoURL);
+      f.delete();
+    } catch (Exception e) {
+      throw new ResolverException(e);
+    } 
     
-    if (obrResolver.resolve()) {
-      Set<BundleInfo> result = new HashSet<BundleInfo>(app.getBundleInfo());
-      for (Resource resource: obrResolver.getRequiredResources()) {
-        BundleInfo bundleInfo = toBundleInfo(resource);
-        result.add(bundleInfo);
+    try {
+      if (obrResolver.resolve()) {
+        Set<BundleInfo> result = new HashSet<BundleInfo>(app.getBundleInfo());
+        for (Resource resource: obrResolver.getRequiredResources()) {
+          BundleInfo bundleInfo = toBundleInfo(resource);
+          result.add(bundleInfo);
+        }
+        for (Resource resource: obrResolver.getOptionalResources()) {
+          BundleInfo bundleInfo = toBundleInfo(resource);
+          result.add(bundleInfo);
+        }
+        return result;
+      } else {
+        throw new ResolverException("Could not resolve requirements: " + getUnsatifiedRequirements(obrResolver));
       }
-      for (Resource resource: obrResolver.getOptionalResources()) {
-        BundleInfo bundleInfo = toBundleInfo(resource);
-        result.add(bundleInfo);
+    } finally {
+      if (appRepoURL != null) {
+        repositoryAdmin.removeRepository(appRepoURL);
       }
-      return result;
-    } else {
-      throw new ResolverException("Could not resolve requirements: " + getUnsatifiedRequirements(obrResolver));
     }
   }
 
@@ -130,6 +162,9 @@
             null,
             null,
             null,
+            null, 
+            null,
+            null,
             null);
   }
 }
\ No newline at end of file

Added: incubator/aries/trunk/application/application-obr-resolver/src/main/java/org/apache/aries/application/resolver/obr/generator/RepositoryDescriptorGenerator.java
URL: http://svn.apache.org/viewvc/incubator/aries/trunk/application/application-obr-resolver/src/main/java/org/apache/aries/application/resolver/obr/generator/RepositoryDescriptorGenerator.java?rev=911468&view=auto
==============================================================================
--- incubator/aries/trunk/application/application-obr-resolver/src/main/java/org/apache/aries/application/resolver/obr/generator/RepositoryDescriptorGenerator.java (added)
+++ incubator/aries/trunk/application/application-obr-resolver/src/main/java/org/apache/aries/application/resolver/obr/generator/RepositoryDescriptorGenerator.java Thu Feb 18 16:11:29 2010
@@ -0,0 +1,148 @@
+/*
+ * 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.aries.application.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.osgi.framework.Constants;
+import org.osgi.service.obr.Resource;
+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("filter", ManifestHeaderProcessor.generateFilter("bundle", 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");
+    
+    String optional = p.getDirective("optional");
+    if (optional == null) optional = "false";
+    
+    requirement.setAttribute("optional", optional);
+    
+    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.getAttribute("version"), "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);
+  }
+}
\ No newline at end of file

Modified: incubator/aries/trunk/application/application-obr-resolver/src/main/java/org/apache/aries/application/resolver/obr/impl/OBRBundleInfo.java
URL: http://svn.apache.org/viewvc/incubator/aries/trunk/application/application-obr-resolver/src/main/java/org/apache/aries/application/resolver/obr/impl/OBRBundleInfo.java?rev=911468&r1=911467&r2=911468&view=diff
==============================================================================
--- incubator/aries/trunk/application/application-obr-resolver/src/main/java/org/apache/aries/application/resolver/obr/impl/OBRBundleInfo.java (original)
+++ incubator/aries/trunk/application/application-obr-resolver/src/main/java/org/apache/aries/application/resolver/obr/impl/OBRBundleInfo.java Thu Feb 18 16:11:29 2010
@@ -41,11 +41,15 @@
   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,
-                       Map<String, String> headers)
+                       Set<Content> requireBundle, Map<String, String> attributes,
+                       Map<String, String> directives, Map<String, String> headers)
   {
     this.symbolicName = symbolicName;
     this.version = version;
@@ -55,6 +59,9 @@
     this.importService = importService;
     this.exportService = exportService;
     this.headers = headers;
+    this.requireBundle = requireBundle;
+    this.attributes = attributes;
+    this.directives = directives;
   }
 
   public String getSymbolicName()
@@ -96,4 +103,19 @@
   {
     return headers;
   }
+
+  public Map<String, String> getBundleAttributes()
+  {
+    return attributes;
+  }
+
+  public Map<String, String> getBundleDirectives()
+  {
+    return directives;
+  }
+
+  public Set<Content> getRequireBundle()
+  {
+    return requireBundle;
+  }
 }