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;
+ }
}