You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@aries.apache.org by zo...@apache.org on 2011/02/27 18:35:25 UTC

svn commit: r1075093 [4/7] - in /aries/tags/application-0.1-incubating: ./ application-api/ application-api/src/ application-api/src/main/ application-api/src/main/java/ application-api/src/main/java/org/ application-api/src/main/java/org/apache/ appli...

Added: aries/tags/application-0.1-incubating/application-management/src/test/resources/bundles/test.eba/foo.bar.widgets.jar/META-INF/MANIFEST.MF
URL: http://svn.apache.org/viewvc/aries/tags/application-0.1-incubating/application-management/src/test/resources/bundles/test.eba/foo.bar.widgets.jar/META-INF/MANIFEST.MF?rev=1075093&view=auto
==============================================================================
--- aries/tags/application-0.1-incubating/application-management/src/test/resources/bundles/test.eba/foo.bar.widgets.jar/META-INF/MANIFEST.MF (added)
+++ aries/tags/application-0.1-incubating/application-management/src/test/resources/bundles/test.eba/foo.bar.widgets.jar/META-INF/MANIFEST.MF Sun Feb 27 17:35:17 2011
@@ -0,0 +1,9 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: FooBarWidgets
+Bundle-SymbolicName: foo.bar.widgets
+Bundle-Version: 1.1
+Bundle-Vendor: Apache.org
+Export-Package: foo.bar.widgets
+
+

Added: aries/tags/application-0.1-incubating/application-management/src/test/resources/bundles/test.eba/my.business.logic.jar/META-INF/MANIFEST.MF
URL: http://svn.apache.org/viewvc/aries/tags/application-0.1-incubating/application-management/src/test/resources/bundles/test.eba/my.business.logic.jar/META-INF/MANIFEST.MF?rev=1075093&view=auto
==============================================================================
--- aries/tags/application-0.1-incubating/application-management/src/test/resources/bundles/test.eba/my.business.logic.jar/META-INF/MANIFEST.MF (added)
+++ aries/tags/application-0.1-incubating/application-management/src/test/resources/bundles/test.eba/my.business.logic.jar/META-INF/MANIFEST.MF Sun Feb 27 17:35:17 2011
@@ -0,0 +1,7 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: MyBusinessLogic
+Bundle-SymbolicName: my.business.logic
+Bundle-Version: 1.1
+Bundle-Vendor: Apache.org
+Export-Package: my.business.logic

Added: aries/tags/application-0.1-incubating/application-obr-resolver/pom.xml
URL: http://svn.apache.org/viewvc/aries/tags/application-0.1-incubating/application-obr-resolver/pom.xml?rev=1075093&view=auto
==============================================================================
--- aries/tags/application-0.1-incubating/application-obr-resolver/pom.xml (added)
+++ aries/tags/application-0.1-incubating/application-obr-resolver/pom.xml Sun Feb 27 17:35:17 2011
@@ -0,0 +1,64 @@
+<?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.
+-->
+<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/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <artifactId>application</artifactId>
+        <groupId>org.apache.aries.application</groupId>
+        <version>0.1-incubating</version>
+    </parent>
+    <artifactId>org.apache.aries.application.resolver.obr</artifactId>
+    <packaging>bundle</packaging>
+    <name>Apache Aries Application OBR Resolver</name>
+    <description>
+      Implementation of the AriesApplicationResolver using OBR
+    </description>
+    
+    <dependencies>
+        <dependency>
+            <groupId>org.osgi</groupId>
+            <artifactId>org.osgi.core</artifactId>
+            <scope>provided</scope>
+        </dependency>
+        <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.osgi.service.obr</artifactId>
+            <optional>true</optional>
+        </dependency>
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-api</artifactId>
+            <scope>provided</scope>
+        </dependency>
+    </dependencies>
+
+</project>

Added: aries/tags/application-0.1-incubating/application-obr-resolver/src/main/java/org/apache/aries/application/resolver/obr/OBRAriesResolver.java
URL: http://svn.apache.org/viewvc/aries/tags/application-0.1-incubating/application-obr-resolver/src/main/java/org/apache/aries/application/resolver/obr/OBRAriesResolver.java?rev=1075093&view=auto
==============================================================================
--- aries/tags/application-0.1-incubating/application-obr-resolver/src/main/java/org/apache/aries/application/resolver/obr/OBRAriesResolver.java (added)
+++ aries/tags/application-0.1-incubating/application-obr-resolver/src/main/java/org/apache/aries/application/resolver/obr/OBRAriesResolver.java Sun Feb 27 17:35:17 2011
@@ -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.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;
+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.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;
+import org.osgi.framework.Version;
+import org.osgi.service.obr.RepositoryAdmin;
+import org.osgi.service.obr.Requirement;
+import org.osgi.service.obr.Resolver;
+import org.osgi.service.obr.Resource;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.w3c.dom.Document;
+
+/**
+ * @version $Rev: 917781 $ $Date: 2010-03-01 23:00:12 +0000 (Mon, 01 Mar 2010) $
+ */
+public class OBRAriesResolver implements AriesApplicationResolver
+{
+  private static Logger log = LoggerFactory.getLogger(OBRAriesResolver.class);
+
+  private final RepositoryAdmin repositoryAdmin;
+
+  public OBRAriesResolver(RepositoryAdmin repositoryAdmin)
+  {
+    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 synchronized Set<BundleInfo> resolve(AriesApplication app, ResolveConstraint... constraints) throws ResolverException
+  {
+    log.trace("resolving {}", app);
+    Resolver obrResolver = repositoryAdmin.resolver();
+    
+    ApplicationMetadata appMeta = app.getApplicationMetadata();
+    
+    String appName = appMeta.getApplicationSymbolicName();
+    Version appVersion = appMeta.getApplicationVersion();
+    List<Content> appContent = appMeta.getApplicationContents();
+
+    // add a resource describing the requirements of the application metadata.
+    obrResolver.add(new ApplicationResourceImpl(appName, appVersion, appContent));
+
+    URL appRepoURL = null;
+    
+    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);
+    } 
+    
+    try {
+      if (obrResolver.resolve()) {
+        Set<BundleInfo> result = new HashSet<BundleInfo>();
+        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: " + getUnsatisfiedRequirements(obrResolver));
+      }
+    } finally {
+      if (appRepoURL != null) {
+        repositoryAdmin.removeRepository(appRepoURL);
+      }
+    }
+  }
+
+  public BundleInfo getBundleInfo(String bundleSymbolicName, Version bundleVersion)
+  {
+    Map<String, String> attribs = new HashMap<String, String>();
+    attribs.put(Resource.VERSION, bundleVersion.toString());
+    String filterString = ManifestHeaderProcessor.generateFilter(Resource.SYMBOLIC_NAME, bundleSymbolicName, attribs);
+    Resource[] resources = repositoryAdmin.discoverResources(filterString);
+    if (resources != null && resources.length > 0) {
+      return toBundleInfo(resources[0]);
+    } else {
+      return null;
+    }
+  }
+
+  private String getUnsatisfiedRequirements(Resolver resolver)
+  {
+    Requirement[] reqs = resolver.getUnsatisfiedRequirements();
+    if (reqs != null) {
+      StringBuilder sb = new StringBuilder();
+      for (int reqIdx = 0; reqIdx < reqs.length; reqIdx++) {
+        sb.append("   " + reqs[reqIdx].getFilter()).append("\n");
+        Resource[] resources = resolver.getResources(reqs[reqIdx]);
+        for (int resIdx = 0; resIdx < resources.length; resIdx++) {
+          sb.append("      " + resources[resIdx].getPresentationName()).append("\n");
+        }
+      }
+      return sb.toString();
+    }
+    return null;
+  }
+
+  private BundleInfo toBundleInfo(Resource resource)
+  {
+    String location = resource.getURL().toExternalForm();
+    return new OBRBundleInfo(resource.getSymbolicName(),
+            resource.getVersion(),
+            location,
+            null,
+            null,
+            null,
+            null,
+            null, 
+            null,
+            null,
+            null);
+  }
+}
\ No newline at end of file

Added: aries/tags/application-0.1-incubating/application-obr-resolver/src/main/java/org/apache/aries/application/resolver/obr/generator/RepositoryDescriptorGenerator.java
URL: http://svn.apache.org/viewvc/aries/tags/application-0.1-incubating/application-obr-resolver/src/main/java/org/apache/aries/application/resolver/obr/generator/RepositoryDescriptorGenerator.java?rev=1075093&view=auto
==============================================================================
--- aries/tags/application-0.1-incubating/application-obr-resolver/src/main/java/org/apache/aries/application/resolver/obr/generator/RepositoryDescriptorGenerator.java (added)
+++ aries/tags/application-0.1-incubating/application-obr-resolver/src/main/java/org/apache/aries/application/resolver/obr/generator/RepositoryDescriptorGenerator.java Sun Feb 27 17:35:17 2011
@@ -0,0 +1,149 @@
+/*
+ * 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("optional", "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.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);
+  }
+}
\ No newline at end of file

Added: aries/tags/application-0.1-incubating/application-obr-resolver/src/main/java/org/apache/aries/application/resolver/obr/impl/ApplicationResourceImpl.java
URL: http://svn.apache.org/viewvc/aries/tags/application-0.1-incubating/application-obr-resolver/src/main/java/org/apache/aries/application/resolver/obr/impl/ApplicationResourceImpl.java?rev=1075093&view=auto
==============================================================================
--- aries/tags/application-0.1-incubating/application-obr-resolver/src/main/java/org/apache/aries/application/resolver/obr/impl/ApplicationResourceImpl.java (added)
+++ aries/tags/application-0.1-incubating/application-obr-resolver/src/main/java/org/apache/aries/application/resolver/obr/impl/ApplicationResourceImpl.java Sun Feb 27 17:35:17 2011
@@ -0,0 +1,149 @@
+/*
+ * 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.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.osgi.service.obr.Capability;
+import org.osgi.service.obr.Repository;
+import org.osgi.service.obr.Requirement;
+import org.osgi.service.obr.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 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;
+  }
+}
\ No newline at end of file

Added: aries/tags/application-0.1-incubating/application-obr-resolver/src/main/java/org/apache/aries/application/resolver/obr/impl/CapabilityImpl.java
URL: http://svn.apache.org/viewvc/aries/tags/application-0.1-incubating/application-obr-resolver/src/main/java/org/apache/aries/application/resolver/obr/impl/CapabilityImpl.java?rev=1075093&view=auto
==============================================================================
--- aries/tags/application-0.1-incubating/application-obr-resolver/src/main/java/org/apache/aries/application/resolver/obr/impl/CapabilityImpl.java (added)
+++ aries/tags/application-0.1-incubating/application-obr-resolver/src/main/java/org/apache/aries/application/resolver/obr/impl/CapabilityImpl.java Sun Feb 27 17:35:17 2011
@@ -0,0 +1,52 @@
+/*
+ * 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.impl;
+
+import org.osgi.service.obr.Capability;
+
+import java.util.Map;
+
+/**
+ * @version $Rev: 910661 $ $Date: 2010-02-16 19:38:51 +0000 (Tue, 16 Feb 2010) $
+ */
+public class CapabilityImpl implements Capability
+{
+
+  private final String name;
+  private final Map properties;
+
+  public CapabilityImpl(String name, Map properties)
+  {
+    this.name = name;
+    this.properties = properties;
+  }
+
+  public String getName()
+  {
+    return name;
+  }
+
+  public Map getProperties()
+  {
+    return properties;
+  }
+  
+}

Added: aries/tags/application-0.1-incubating/application-obr-resolver/src/main/java/org/apache/aries/application/resolver/obr/impl/MapToDictionary.java
URL: http://svn.apache.org/viewvc/aries/tags/application-0.1-incubating/application-obr-resolver/src/main/java/org/apache/aries/application/resolver/obr/impl/MapToDictionary.java?rev=1075093&view=auto
==============================================================================
--- aries/tags/application-0.1-incubating/application-obr-resolver/src/main/java/org/apache/aries/application/resolver/obr/impl/MapToDictionary.java (added)
+++ aries/tags/application-0.1-incubating/application-obr-resolver/src/main/java/org/apache/aries/application/resolver/obr/impl/MapToDictionary.java Sun Feb 27 17:35:17 2011
@@ -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.aries.application.resolver.obr.impl;
+
+import java.util.Dictionary;
+import java.util.Enumeration;
+import java.util.Iterator;
+import java.util.Map;
+
+/**
+ * @version $Rev: 911397 $ $Date: 2010-02-18 13:41:27 +0000 (Thu, 18 Feb 2010) $
+ */
+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: aries/tags/application-0.1-incubating/application-obr-resolver/src/main/java/org/apache/aries/application/resolver/obr/impl/OBRBundleInfo.java
URL: http://svn.apache.org/viewvc/aries/tags/application-0.1-incubating/application-obr-resolver/src/main/java/org/apache/aries/application/resolver/obr/impl/OBRBundleInfo.java?rev=1075093&view=auto
==============================================================================
--- aries/tags/application-0.1-incubating/application-obr-resolver/src/main/java/org/apache/aries/application/resolver/obr/impl/OBRBundleInfo.java (added)
+++ aries/tags/application-0.1-incubating/application-obr-resolver/src/main/java/org/apache/aries/application/resolver/obr/impl/OBRBundleInfo.java Sun Feb 27 17:35:17 2011
@@ -0,0 +1,147 @@
+/*
+ * 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.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: 917780 $ $Date: 2010-03-01 22:58:35 +0000 (Mon, 01 Mar 2010) $
+ */
+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;
+  }
+  
+  /**
+   * Equality is just based on the location. If you install a bundle from the same location string
+   * you get the same Bundle, even if the underlying bundle had a different symbolic name/version.
+   * This seems reasonable and quick.
+   */
+  public boolean equals(Object other)
+  {
+    if (other == null) return false;
+    if (other == this) return true;
+    if (other instanceof OBRBundleInfo) {
+      return location.equals(((OBRBundleInfo)other).location);
+    }
+    
+    return false;
+  }
+  
+  public int hashCode()
+  {
+    return location.hashCode();
+  }
+  
+  public String toString()
+  {
+    return symbolicName + "_" + version;
+  }
+}
\ No newline at end of file

Added: aries/tags/application-0.1-incubating/application-obr-resolver/src/main/java/org/apache/aries/application/resolver/obr/impl/RequirementImpl.java
URL: http://svn.apache.org/viewvc/aries/tags/application-0.1-incubating/application-obr-resolver/src/main/java/org/apache/aries/application/resolver/obr/impl/RequirementImpl.java?rev=1075093&view=auto
==============================================================================
--- aries/tags/application-0.1-incubating/application-obr-resolver/src/main/java/org/apache/aries/application/resolver/obr/impl/RequirementImpl.java (added)
+++ aries/tags/application-0.1-incubating/application-obr-resolver/src/main/java/org/apache/aries/application/resolver/obr/impl/RequirementImpl.java Sun Feb 27 17:35:17 2011
@@ -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.aries.application.resolver.obr.impl;
+
+import org.osgi.framework.Filter;
+import org.osgi.service.obr.Capability;
+import org.osgi.service.obr.Requirement;
+
+/**
+ * @version $Rev: 911133 $ $Date: 2010-02-17 18:19:57 +0000 (Wed, 17 Feb 2010) $
+ */
+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 filter.match(new MapToDictionary(capability.getProperties()));
+  }
+}

Added: aries/tags/application-0.1-incubating/application-obr-resolver/src/main/java/org/apache/aries/application/resolver/obr/impl/ResourceImpl.java
URL: http://svn.apache.org/viewvc/aries/tags/application-0.1-incubating/application-obr-resolver/src/main/java/org/apache/aries/application/resolver/obr/impl/ResourceImpl.java?rev=1075093&view=auto
==============================================================================
--- aries/tags/application-0.1-incubating/application-obr-resolver/src/main/java/org/apache/aries/application/resolver/obr/impl/ResourceImpl.java (added)
+++ aries/tags/application-0.1-incubating/application-obr-resolver/src/main/java/org/apache/aries/application/resolver/obr/impl/ResourceImpl.java Sun Feb 27 17:35:17 2011
@@ -0,0 +1,113 @@
+/*
+ * 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.impl;
+
+import org.osgi.framework.Version;
+import org.osgi.service.obr.Capability;
+import org.osgi.service.obr.Repository;
+import org.osgi.service.obr.Requirement;
+import org.osgi.service.obr.Resource;
+
+import java.net.URL;
+import java.util.Map;
+
+/**
+ * @version $Rev: 910661 $ $Date: 2010-02-16 19:38:51 +0000 (Tue, 16 Feb 2010) $
+ */
+public class ResourceImpl implements Resource
+{
+
+  private final Map properties;
+  private final String symbolicName;
+  private final String presentationName;
+  private final Version version;
+  private final String id;
+  private final URL url;
+  private final Requirement[] requirements;
+  private final Capability[] capabilities;
+  private final String[] categories;
+  private final Repository repository;
+
+
+  public ResourceImpl(Map properties, String symbolicName, String presentationName, Version version, String id, URL url, Requirement[] requirements, Capability[] capabilities, String[] categories, Repository repository)
+  {
+    this.properties = properties;
+    this.symbolicName = symbolicName;
+    this.presentationName = presentationName;
+    this.version = version;
+    this.id = id;
+    this.url = url;
+    this.requirements = requirements;
+    this.capabilities = capabilities;
+    this.categories = categories;
+    this.repository = repository;
+  }
+
+  public Map getProperties()
+  {
+    return properties;
+  }
+
+  public String getSymbolicName()
+  {
+    return symbolicName;
+  }
+
+  public String getPresentationName()
+  {
+    return presentationName;
+  }
+
+  public Version getVersion()
+  {
+    return version;
+  }
+
+  public String getId()
+  {
+    return id;
+  }
+
+  public URL getURL()
+  {
+    return url;
+  }
+
+  public Requirement[] getRequirements()
+  {
+    return requirements;
+  }
+
+  public Capability[] getCapabilities()
+  {
+    return capabilities;
+  }
+
+  public String[] getCategories()
+  {
+    return categories;
+  }
+
+  public Repository getRepository()
+  {
+    return repository;
+  }
+}

Added: aries/tags/application-0.1-incubating/application-obr-resolver/src/main/resources/OSGI-INF/blueprint/obr-resolver.xml
URL: http://svn.apache.org/viewvc/aries/tags/application-0.1-incubating/application-obr-resolver/src/main/resources/OSGI-INF/blueprint/obr-resolver.xml?rev=1075093&view=auto
==============================================================================
--- aries/tags/application-0.1-incubating/application-obr-resolver/src/main/resources/OSGI-INF/blueprint/obr-resolver.xml (added)
+++ aries/tags/application-0.1-incubating/application-obr-resolver/src/main/resources/OSGI-INF/blueprint/obr-resolver.xml Sun Feb 27 17:35:17 2011
@@ -0,0 +1,31 @@
+<?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:xsi="http://www.w3.org/2001/XMLSchema-instance"
+           xsi:schemaLocation="http://www.osgi.org/xmlns/blueprint/v1.0.0">
+
+    <bean id="obr-resolver" class="org.apache.aries.application.resolver.obr.OBRAriesResolver" scope="singleton"
+          activation="eager">
+        <argument>
+            <reference interface="org.osgi.service.obr.RepositoryAdmin"/>
+        </argument>
+    </bean>
+
+    <service interface="org.apache.aries.application.management.AriesApplicationResolver" ref="obr-resolver"/>
+
+</blueprint>

Added: aries/tags/application-0.1-incubating/application-runtime/pom.xml
URL: http://svn.apache.org/viewvc/aries/tags/application-0.1-incubating/application-runtime/pom.xml?rev=1075093&view=auto
==============================================================================
--- aries/tags/application-0.1-incubating/application-runtime/pom.xml (added)
+++ aries/tags/application-0.1-incubating/application-runtime/pom.xml Sun Feb 27 17:35:17 2011
@@ -0,0 +1,72 @@
+<?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.
+-->
+<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">
+    <parent>
+        <artifactId>application</artifactId>
+        <groupId>org.apache.aries.application</groupId>
+        <version>0.1-incubating</version>
+    </parent>
+    
+    <modelVersion>4.0.0</modelVersion>
+    <artifactId>org.apache.aries.application.runtime</artifactId>
+    <packaging>bundle</packaging>
+    <name>Apache Aries Application Runtime</name>
+    <description>
+        A very basic runtime implementation
+    </description>
+
+    <dependencies>
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.aries.application</groupId>
+            <artifactId>org.apache.aries.application.utils</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.aries.testsupport</groupId>
+            <artifactId>org.apache.aries.testsupport.unit</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.osgi</groupId>
+            <artifactId>org.osgi.core</artifactId>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.osgi</groupId>
+            <artifactId>org.osgi.compendium</artifactId>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-api</artifactId>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-simple</artifactId>
+            <scope>test</scope>
+        </dependency>
+    </dependencies>
+
+</project>

Added: aries/tags/application-0.1-incubating/application-runtime/src/main/java/org/apache/aries/application/runtime/defaults/DefaultLocalPlatform.java
URL: http://svn.apache.org/viewvc/aries/tags/application-0.1-incubating/application-runtime/src/main/java/org/apache/aries/application/runtime/defaults/DefaultLocalPlatform.java?rev=1075093&view=auto
==============================================================================
--- aries/tags/application-0.1-incubating/application-runtime/src/main/java/org/apache/aries/application/runtime/defaults/DefaultLocalPlatform.java (added)
+++ aries/tags/application-0.1-incubating/application-runtime/src/main/java/org/apache/aries/application/runtime/defaults/DefaultLocalPlatform.java Sun Feb 27 17:35:17 2011
@@ -0,0 +1,37 @@
+/*
+ * 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.runtime.defaults;
+
+import java.io.File;
+import java.io.IOException;
+
+import org.apache.aries.application.management.LocalPlatform;
+
+public class DefaultLocalPlatform implements LocalPlatform {
+
+  public File getTemporaryDirectory() throws IOException {
+    File f = File.createTempFile("ebaTmp", null);
+    f.delete();
+    f.mkdir();
+    return f;
+  } 
+  public File getTemporaryFile () throws IOException { 
+    return File.createTempFile("ebaTmp", null);
+  }
+}

Added: aries/tags/application-0.1-incubating/application-runtime/src/main/java/org/apache/aries/application/runtime/defaults/NoOpResolver.java
URL: http://svn.apache.org/viewvc/aries/tags/application-0.1-incubating/application-runtime/src/main/java/org/apache/aries/application/runtime/defaults/NoOpResolver.java?rev=1075093&view=auto
==============================================================================
--- aries/tags/application-0.1-incubating/application-runtime/src/main/java/org/apache/aries/application/runtime/defaults/NoOpResolver.java (added)
+++ aries/tags/application-0.1-incubating/application-runtime/src/main/java/org/apache/aries/application/runtime/defaults/NoOpResolver.java Sun Feb 27 17:35:17 2011
@@ -0,0 +1,45 @@
+/*
+ * 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.runtime.defaults;
+
+import java.util.Set;
+
+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.osgi.framework.Version;
+
+/** AriesApplicationManager requires that there be at least one 
+ * AriesApplicationResolver service present. This class provides a null 
+ * implementation: it simply returns the bundles that it was provided with - 
+ * enough to permit the testing of Aries applications that have no external 
+ * dependencies.   
+ */
+public class NoOpResolver implements AriesApplicationResolver {
+
+  public Set<BundleInfo> resolve(AriesApplication app, ResolveConstraint... constraints) {
+    return app.getBundleInfo();
+  }
+
+  public BundleInfo getBundleInfo(String bundleSymbolicName, Version bundleVersion)
+  {
+    return null;
+  }
+}
\ No newline at end of file

Added: aries/tags/application-0.1-incubating/application-runtime/src/main/java/org/apache/aries/application/runtime/impl/ApplicationContextImpl.java
URL: http://svn.apache.org/viewvc/aries/tags/application-0.1-incubating/application-runtime/src/main/java/org/apache/aries/application/runtime/impl/ApplicationContextImpl.java?rev=1075093&view=auto
==============================================================================
--- aries/tags/application-0.1-incubating/application-runtime/src/main/java/org/apache/aries/application/runtime/impl/ApplicationContextImpl.java (added)
+++ aries/tags/application-0.1-incubating/application-runtime/src/main/java/org/apache/aries/application/runtime/impl/ApplicationContextImpl.java Sun Feb 27 17:35:17 2011
@@ -0,0 +1,171 @@
+/*
+ * 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.aries.application.runtime.impl;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.aries.application.DeploymentContent;
+import org.apache.aries.application.DeploymentMetadata;
+import org.apache.aries.application.management.AriesApplication;
+import org.apache.aries.application.management.AriesApplicationContext;
+import org.apache.aries.application.management.AriesApplicationResolver;
+import org.apache.aries.application.management.BundleInfo;
+import org.apache.aries.application.management.ManagementException;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.BundleException;
+import org.osgi.framework.ServiceException;
+import org.osgi.framework.ServiceReference;
+import org.osgi.framework.Version;
+
+public class ApplicationContextImpl implements AriesApplicationContext {
+  
+  private AriesApplication _application;
+  private Map<BundleInfo, Bundle> _bundles;
+  private ApplicationState _state;
+  private BundleContext _bundleContext;
+  
+  public ApplicationContextImpl (BundleContext b, AriesApplication app) throws BundleException, ManagementException { 
+    _bundleContext = b;
+    _application = app;
+    _bundles = new HashMap<BundleInfo, Bundle>();
+    
+    DeploymentMetadata meta = _application.getDeploymentMetadata();
+    
+    AriesApplicationResolver resolver = null;
+    
+    ServiceReference ref = b.getServiceReference(AriesApplicationResolver.class.getName());
+
+    if (ref != null) resolver = (AriesApplicationResolver) b.getService(ref);
+    
+    if (resolver == null) {
+      throw new ManagementException(new ServiceException(AriesApplicationResolver.class.getName(), ServiceException.UNREGISTERED));
+    }
+    
+    try {
+      List<DeploymentContent> bundlesToInstall = new ArrayList<DeploymentContent>(meta.getApplicationDeploymentContents());
+      bundlesToInstall.addAll(meta.getApplicationProvisionBundles());
+      
+      for (DeploymentContent content : bundlesToInstall) {
+        String bundleSymbolicName = content.getContentName();
+        Version bundleVersion = content.getExactVersion();
+        
+        BundleInfo bundleInfo = null;
+        
+        for (BundleInfo info : _application.getBundleInfo()) {
+          if (info.getSymbolicName().equals(bundleSymbolicName) &&
+              info.getVersion().equals(bundleVersion)) {
+            bundleInfo = info;
+            break;
+          }
+        }
+        
+        if (bundleInfo == null) {
+          // call out to the bundle repository.
+          bundleInfo = resolver.getBundleInfo(bundleSymbolicName, bundleVersion);
+        }
+        
+        if (bundleInfo == null) {
+          throw new ManagementException("Cound not find bundles: " + bundleSymbolicName + "_" + bundleVersion);
+        }
+        
+        Bundle bundle = _bundleContext.installBundle(bundleInfo.getLocation());
+        
+        _bundles.put(bundleInfo, bundle);
+      }
+    } catch (BundleException be) {
+      for (Bundle bundle : _bundles.values()) {
+        bundle.uninstall();
+      }
+      
+      _bundles.clear();
+      
+      throw be;
+    } finally {
+      if (resolver != null) b.ungetService(ref);
+    }
+    
+    _state = ApplicationState.INSTALLED;
+  }
+
+  public AriesApplication getApplication() {
+    return _application;
+  }
+  
+  public Set<Bundle> getApplicationContent() {
+    Set<Bundle> result = new HashSet<Bundle>();
+    for (Map.Entry<BundleInfo, Bundle> entry : _bundles.entrySet()) { 
+      result.add (entry.getValue());
+    }
+    return result;
+  } 
+
+  public ApplicationState getApplicationState() {
+    return _state;
+  }
+
+  public void start() throws BundleException 
+  {
+    _state = ApplicationState.STARTING;
+    
+    List<Bundle> bundlesWeStarted = new ArrayList<Bundle>();
+    
+    try {
+      for (Bundle b : _bundles.values()) { 
+        if (b.getState() != Bundle.ACTIVE) { 
+          b.start(Bundle.START_ACTIVATION_POLICY);
+          bundlesWeStarted.add(b);
+        }
+      }
+    } catch (BundleException be) {
+      for (Bundle b : bundlesWeStarted) {
+        try {
+          b.stop();
+        } catch (BundleException be2) {
+          // we are doing tidyup here, so we don't want to replace the bundle exception
+          // that occurred during start with one from stop. We also want to try to stop
+          // all the bundles we started even if some bundles wouldn't stop.
+        }
+      }
+      
+      _state = ApplicationState.INSTALLED;
+      throw be;
+    }
+    _state = ApplicationState.ACTIVE;
+  }
+
+  public void stop() throws BundleException {
+    for (Map.Entry<BundleInfo, Bundle> entry : _bundles.entrySet()) { 
+      Bundle b = entry.getValue();
+      b.stop();
+    }
+    _state = ApplicationState.RESOLVED;
+  }
+
+  public void setState(ApplicationState state)
+  {
+    _state = state;
+  }
+}

Added: aries/tags/application-0.1-incubating/application-runtime/src/main/java/org/apache/aries/application/runtime/impl/ApplicationContextManagerImpl.java
URL: http://svn.apache.org/viewvc/aries/tags/application-0.1-incubating/application-runtime/src/main/java/org/apache/aries/application/runtime/impl/ApplicationContextManagerImpl.java?rev=1075093&view=auto
==============================================================================
--- aries/tags/application-0.1-incubating/application-runtime/src/main/java/org/apache/aries/application/runtime/impl/ApplicationContextManagerImpl.java (added)
+++ aries/tags/application-0.1-incubating/application-runtime/src/main/java/org/apache/aries/application/runtime/impl/ApplicationContextManagerImpl.java Sun Feb 27 17:35:17 2011
@@ -0,0 +1,113 @@
+/*
+ * 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.aries.application.runtime.impl;
+
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+
+import org.apache.aries.application.management.AriesApplication;
+import org.apache.aries.application.management.AriesApplicationContext;
+import org.apache.aries.application.management.AriesApplicationContextManager;
+import org.apache.aries.application.management.ManagementException;
+import org.apache.aries.application.management.AriesApplicationContext.ApplicationState;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.BundleException;
+
+public class ApplicationContextManagerImpl implements AriesApplicationContextManager {
+
+  private ConcurrentMap<AriesApplication, ApplicationContextImpl> _appToContextMap;
+  private BundleContext _bundleContext;
+  
+  public ApplicationContextManagerImpl () { 
+    _appToContextMap = new ConcurrentHashMap<AriesApplication, ApplicationContextImpl>();
+  }
+  
+  public void setBundleContext (BundleContext b) { 
+    _bundleContext = b;
+  }
+  
+  public AriesApplicationContext getApplicationContext(AriesApplication app) throws BundleException, ManagementException {
+    ApplicationContextImpl result;
+    if (_appToContextMap.containsKey(app)) { 
+      result = _appToContextMap.get(app);
+    } else { 
+      result = new ApplicationContextImpl (_bundleContext, app);
+      ApplicationContextImpl previous = _appToContextMap.putIfAbsent(app, result);
+      if (previous != null) { 
+        result = previous;
+      }
+    }
+    return result;
+  }
+
+  public Set<AriesApplicationContext> getApplicationContexts() {
+    Set<AriesApplicationContext> result = new HashSet<AriesApplicationContext>();
+    for (Map.Entry<AriesApplication, ApplicationContextImpl> entry: _appToContextMap.entrySet()) {
+      result.add (entry.getValue());
+    }
+    return result;
+  }
+
+  public void remove(AriesApplicationContext app)
+  {
+    Iterator<Map.Entry<AriesApplication, ApplicationContextImpl>> it = _appToContextMap.entrySet().iterator();
+    
+    while (it.hasNext()) {
+      Map.Entry<AriesApplication, ApplicationContextImpl> entry = it.next();
+      
+      ApplicationContextImpl potentialMatch = entry.getValue();
+      
+      if (potentialMatch == app) {
+        it.remove();
+
+        uninstall(potentialMatch);
+
+        break;
+      }
+    }
+  }
+
+  private void uninstall(ApplicationContextImpl app)
+  {
+    Set<Bundle> bundles = app.getApplicationContent();
+    for (Bundle b : bundles) {
+      try {
+        b.uninstall();
+      } catch (BundleException be) {
+        // TODO ignoring this feels wrong, but I'm not sure how to communicate to the caller multiple failures. 
+      }
+    }
+    app.setState(ApplicationState.UNINSTALLED);
+  }
+  
+  public void close()
+  {
+    for (ApplicationContextImpl ctx : _appToContextMap.values()) {
+      uninstall(ctx);
+    }
+    
+    _appToContextMap.clear();
+  }
+}
\ No newline at end of file

Added: aries/tags/application-0.1-incubating/application-runtime/src/main/resources/OSGI-INF/blueprint/app-context-management.xml
URL: http://svn.apache.org/viewvc/aries/tags/application-0.1-incubating/application-runtime/src/main/resources/OSGI-INF/blueprint/app-context-management.xml?rev=1075093&view=auto
==============================================================================
--- aries/tags/application-0.1-incubating/application-runtime/src/main/resources/OSGI-INF/blueprint/app-context-management.xml (added)
+++ aries/tags/application-0.1-incubating/application-runtime/src/main/resources/OSGI-INF/blueprint/app-context-management.xml Sun Feb 27 17:35:17 2011
@@ -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:xsi="http://www.w3.org/2001/XMLSchema-instance"
+            xsi:schemaLocation="http://www.osgi.org/xmlns/blueprint/v1.0.0">
+  
+  <bean id="app-context-manager" class="org.apache.aries.application.runtime.impl.ApplicationContextManagerImpl" scope="singleton" activation="lazy" destroy-method="close">
+    <property name="bundleContext" ref="blueprintBundleContext"/>
+  </bean>
+
+  <service interface="org.apache.aries.application.management.AriesApplicationContextManager" ref="app-context-manager" />
+  
+  <!-- Default implementations of services that must be implemented against a 
+       particular application server environment follow -->
+
+  <bean id="default-local-platform" class="org.apache.aries.application.runtime.defaults.DefaultLocalPlatform"/>
+  <bean id="no-op-resolver" class="org.apache.aries.application.runtime.defaults.NoOpResolver"/>
+  
+  <service interface="org.apache.aries.application.management.LocalPlatform" 
+            ref="default-local-platform"
+            ranking="-1"/>
+  <service interface="org.apache.aries.application.management.AriesApplicationResolver" 
+            ref="no-op-resolver"
+            ranking="-1"/>
+  
+</blueprint>

Added: aries/tags/application-0.1-incubating/application-utils/pom.xml
URL: http://svn.apache.org/viewvc/aries/tags/application-0.1-incubating/application-utils/pom.xml?rev=1075093&view=auto
==============================================================================
--- aries/tags/application-0.1-incubating/application-utils/pom.xml (added)
+++ aries/tags/application-0.1-incubating/application-utils/pom.xml Sun Feb 27 17:35:17 2011
@@ -0,0 +1,85 @@
+<!--
+ 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.
+-->
+<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.aries.application</groupId>
+        <artifactId>application</artifactId>
+        <version>0.1-incubating</version>
+    </parent>
+
+    <artifactId>org.apache.aries.application.utils</artifactId>
+    <packaging>bundle</packaging>
+    <name>Apache Aries Application Utils</name>
+    <description>
+      Utilities for working with Aries Applications.
+    </description>
+
+    <properties>
+        <aries.osgi.export.pkg>
+            org.apache.aries.application.utils;
+            org.apache.aries.application.utils.filesystem;
+            org.apache.aries.application.utils.manifest;
+            org.apache.aries.application.utils.management
+        </aries.osgi.export.pkg>
+        <aries.osgi.private.pkg>
+            org.apache.aries.application.impl;
+            org.apache.aries.application.utils.internal;
+            org.apache.aries.application.utils.filesystem.impl
+        </aries.osgi.private.pkg>
+    </properties>
+
+    <dependencies>
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.aries.application</groupId>
+            <artifactId>org.apache.aries.application.api</artifactId>
+        </dependency>
+        <dependency>
+             <groupId>org.apache.aries</groupId>
+             <artifactId>org.apache.aries.util</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.aries.testsupport</groupId>
+            <artifactId>org.apache.aries.testsupport.unit</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.osgi</groupId>
+            <artifactId>org.osgi.core</artifactId>
+            <version>4.0.0</version>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-api</artifactId>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-simple</artifactId>
+            <scope>test</scope>
+        </dependency>
+    </dependencies>
+
+</project>

Added: aries/tags/application-0.1-incubating/application-utils/src/main/java/org/apache/aries/application/impl/ApplicationMetadataFactoryImpl.java
URL: http://svn.apache.org/viewvc/aries/tags/application-0.1-incubating/application-utils/src/main/java/org/apache/aries/application/impl/ApplicationMetadataFactoryImpl.java?rev=1075093&view=auto
==============================================================================
--- aries/tags/application-0.1-incubating/application-utils/src/main/java/org/apache/aries/application/impl/ApplicationMetadataFactoryImpl.java (added)
+++ aries/tags/application-0.1-incubating/application-utils/src/main/java/org/apache/aries/application/impl/ApplicationMetadataFactoryImpl.java Sun Feb 27 17:35:17 2011
@@ -0,0 +1,81 @@
+/*
+ * 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.aries.application.impl;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+import java.util.jar.Manifest;
+
+import org.apache.aries.application.ApplicationMetadata;
+import org.apache.aries.application.ApplicationMetadataFactory;
+import org.apache.aries.application.Content;
+import org.apache.aries.application.VersionRange;
+import org.apache.aries.application.utils.manifest.ManifestProcessor;
+import org.osgi.framework.Version;
+
+public class ApplicationMetadataFactoryImpl implements ApplicationMetadataFactory
+{
+  /** The applications managed, keyed based on the app symbolic name and version */
+  public ConcurrentMap<String, ApplicationMetadata> applications = new ConcurrentHashMap<String, ApplicationMetadata>();
+
+  public ApplicationMetadata getApplicationMetadata (String applicationSymbolicName, Version version)
+  {
+    ApplicationMetadata metadata = applications.get(applicationSymbolicName + "_" + version);
+    return metadata;
+  }
+
+  public ApplicationMetadata parseApplicationMetadata(InputStream in) throws IOException
+  {
+    Manifest man = ManifestProcessor.parseManifest(in);
+    
+    ApplicationMetadata metadata = new ApplicationMetadataImpl(man);
+    
+    return metadata;
+  }
+  
+  public boolean registerApplication(ApplicationMetadata app)
+  {
+    ApplicationMetadata existingApp = applications.putIfAbsent(app.getApplicationScope(), app);
+    
+    return existingApp == null;
+  }
+  
+  public ApplicationMetadata createApplicationMetadata(Manifest man)
+  {
+    return new ApplicationMetadataImpl(man);
+  }
+  
+  public boolean unregisterApplication(ApplicationMetadata app)
+  {
+    return applications.remove(app.getApplicationScope()) != null;
+  }
+
+  public Content parseContent(String content)
+  {
+    return new ContentImpl(content);
+  }
+
+  public VersionRange parseVersionRange(String versionRange)
+  {
+    return new VersionRangeImpl(versionRange);
+  }
+
+}
\ No newline at end of file

Added: aries/tags/application-0.1-incubating/application-utils/src/main/java/org/apache/aries/application/impl/ApplicationMetadataImpl.java
URL: http://svn.apache.org/viewvc/aries/tags/application-0.1-incubating/application-utils/src/main/java/org/apache/aries/application/impl/ApplicationMetadataImpl.java?rev=1075093&view=auto
==============================================================================
--- aries/tags/application-0.1-incubating/application-utils/src/main/java/org/apache/aries/application/impl/ApplicationMetadataImpl.java (added)
+++ aries/tags/application-0.1-incubating/application-utils/src/main/java/org/apache/aries/application/impl/ApplicationMetadataImpl.java Sun Feb 27 17:35:17 2011
@@ -0,0 +1,196 @@
+/*
+ * 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.aries.application.impl;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.Map.Entry;
+import java.util.jar.Attributes;
+import java.util.jar.Manifest;
+
+import org.apache.aries.application.ApplicationMetadata;
+import org.apache.aries.application.Content;
+import org.apache.aries.application.ServiceDeclaration;
+import org.apache.aries.application.utils.AppConstants;
+import org.apache.aries.application.utils.manifest.ManifestProcessor;
+import org.osgi.framework.Version;
+
+/**
+ * Implementation of ApplicationMetadata and DeploymentMetadata
+ *
+ */
+public final class ApplicationMetadataImpl implements ApplicationMetadata
+{
+  private String appSymbolicName;
+  private Version appVersion;
+  private String appName;
+  private String appScope;
+  private List<Content> appContents;
+  private List<ServiceDeclaration> importServices;
+  private List<ServiceDeclaration> exportServices;
+  private Manifest manifest;
+  
+  /**
+   * create the applicationMetadata from appManifest
+   * @param appManifest   the Application.mf manifest
+   */
+  public ApplicationMetadataImpl(Manifest appManifest) {
+
+    this.appContents = new ArrayList<Content>();
+    this.importServices = new ArrayList<ServiceDeclaration>();
+    this.exportServices = new ArrayList<ServiceDeclaration>();
+    setup(appManifest);
+    
+    // As of 7 Jan 2010 we have no setter methods. Hence it's currently 
+    // fine to keep a copy of appManifest, and to use it in the store()
+    // method.
+    manifest = appManifest;
+  }
+  
+  /**
+   * setup the application metadata from the appManifest
+   * @param appManifest     application.mf manifest
+   */
+  private void setup(Manifest appManifest) 
+  {
+    Map<String, String> appMap = readManifestIntoMap(appManifest);
+    
+    // configure the appSymbolicName and appVersion
+    this.appSymbolicName = appMap.get(AppConstants.APPLICATION_SYMBOLIC_NAME);
+    this.appVersion = new Version(appMap.get(AppConstants.APPLICATION_VERSION));
+    this.appName = appMap.get(AppConstants.APPLICATION_NAME);
+    this.appScope = this.appSymbolicName + "_" + this.appVersion.toString();
+    
+    if (this.appSymbolicName == null || this.appVersion == null) {
+      throw new IllegalArgumentException("Failed to create ApplicationMetadataImpl object from Manifest " + appManifest);
+    }
+    
+    // configure appContents
+    String applicationContents = appMap.get(AppConstants.APPLICATION_CONTENT);
+    List<String> appContentsArray = ManifestProcessor.split(applicationContents, ",");
+    for (String content : appContentsArray) {
+      this.appContents.add(new ContentImpl(content));
+    }
+    
+    // TODO: configure importServices + exportServices
+    
+  }
+  
+  /**
+   * Reads a manifest's main attributes into a String->String map.
+   * <p>
+   * Will always return a map, empty if the manifest had no attributes.
+   * 
+   * @param mf The manifest to read.
+   * @return Map of manifest main attributes.
+   */
+  private Map<String, String> readManifestIntoMap(Manifest mf){   
+    HashMap<String, String> props = new HashMap<String, String>();
+    
+    Attributes mainAttrs = mf.getMainAttributes();
+    if (mainAttrs!=null){
+      Set<Entry<Object, Object>> attributeSet =  mainAttrs.entrySet(); 
+      if (attributeSet != null){
+        // Copy all the manifest headers across. The entry set should be a set of
+        // Name to String mappings, by calling String.valueOf we do the conversion
+        // to a string and we do not NPE.
+        for (Map.Entry<Object, Object> entry : attributeSet) {
+          props.put(String.valueOf(entry.getKey()), String.valueOf(entry.getValue()));
+        }
+      }    
+    }
+       
+    return props;
+  }  
+    
+  public List<Content> getApplicationContents()
+  {
+    return Collections.unmodifiableList(this.appContents);
+  }
+
+  public List<ServiceDeclaration> getApplicationExportServices()
+  {
+    return Collections.unmodifiableList(this.exportServices);
+  }
+
+  public List<ServiceDeclaration> getApplicationImportServices()
+  {
+    return Collections.unmodifiableList(this.importServices);
+  }
+
+  public String getApplicationSymbolicName()
+  {
+    return this.appSymbolicName;
+  }
+
+  public Version getApplicationVersion()
+  {
+    return this.appVersion;
+  }
+
+  public String getApplicationName() 
+  {
+    return this.appName;
+  }
+  
+  public String getApplicationScope() 
+  {
+    return appScope;
+  }
+  
+  public boolean equals(Object other)
+  {
+    if (other == this) return true;
+    if (other == null) return false;
+    if (other instanceof ApplicationMetadataImpl) {
+      return appScope.equals(((ApplicationMetadataImpl)other).appScope);
+    }
+    
+    return false;
+  }
+  
+  public int hashCode()
+  {
+    return appScope.hashCode();
+  }
+
+  public void store(File f) throws IOException {
+    FileOutputStream fos = new FileOutputStream (f);
+    store(fos);
+    fos.close();
+  }
+
+  public void store(OutputStream out) throws IOException {
+    if (manifest != null) {
+      Attributes att = manifest.getMainAttributes();
+      if ((att.getValue(Attributes.Name.MANIFEST_VERSION.toString())) == null) {
+        att.putValue(Attributes.Name.MANIFEST_VERSION.toString(), AppConstants.MANIFEST_VERSION);
+      }
+      manifest.write(out);
+    }
+  }
+}
\ No newline at end of file

Added: aries/tags/application-0.1-incubating/application-utils/src/main/java/org/apache/aries/application/impl/ContentImpl.java
URL: http://svn.apache.org/viewvc/aries/tags/application-0.1-incubating/application-utils/src/main/java/org/apache/aries/application/impl/ContentImpl.java?rev=1075093&view=auto
==============================================================================
--- aries/tags/application-0.1-incubating/application-utils/src/main/java/org/apache/aries/application/impl/ContentImpl.java (added)
+++ aries/tags/application-0.1-incubating/application-utils/src/main/java/org/apache/aries/application/impl/ContentImpl.java Sun Feb 27 17:35:17 2011
@@ -0,0 +1,199 @@
+/*
+ * 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.aries.application.impl;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.aries.application.Content;
+import org.apache.aries.application.VersionRange;
+import org.apache.aries.application.utils.internal.MessageUtil;
+import org.apache.aries.application.utils.manifest.ManifestHeaderProcessor;
+import org.apache.aries.application.utils.manifest.ManifestHeaderProcessor.NameValueMap;
+import org.osgi.framework.Constants;
+import org.osgi.framework.Version;
+
+
+/**
+ * Implementation of Content 
+ *
+ */
+public final class ContentImpl implements Content
+{
+  private String contentName;
+  protected Map<String, String> attributes;
+  private Map<String, String> directives;
+  private NameValueMap<String, String> nameValueMap;
+  
+  /**
+   * 
+   * @param content  Application-Content, Import-Package content
+   */
+  public ContentImpl(String content) {
+    Map<String, NameValueMap<String, String>> appContentsMap = ManifestHeaderProcessor.parseImportString(content);
+    if (appContentsMap.size() != 1) {
+      throw new IllegalArgumentException(MessageUtil.getMessage("APPUTILS0004E",content));
+    }
+    for (Map.Entry<String, NameValueMap<String, String>> entry : appContentsMap.entrySet()) {
+      this.contentName = entry.getKey();
+      this.nameValueMap= entry.getValue();
+      setup();
+      break;
+    }
+  }
+  
+  public ContentImpl (String bundleSymbolicName, Version version) { 
+    this.contentName = bundleSymbolicName;
+    this.nameValueMap = new NameValueMap<String, String>();
+    nameValueMap.put("version", version.toString());
+    setup();
+  }
+  
+  /**
+   * 
+   * @param contentName  
+   * @param nameValueMap
+   */
+  public ContentImpl(String contentName, NameValueMap<String, String> nameValueMap) {
+    this.contentName = contentName;
+    this.nameValueMap= nameValueMap;
+    setup();
+  }
+  
+  public String getContentName() {
+    return this.contentName;
+  }
+  
+  public Map<String, String> getAttributes() {
+    return Collections.unmodifiableMap(this.attributes);
+  }
+  
+  public Map<String, String> getDirectives() {
+    return Collections.unmodifiableMap(this.directives);
+  }
+  
+  public String getAttribute(String key) {
+    String toReturn = this.attributes.get(key);
+    return toReturn;
+  }
+  
+  /**
+   * add key value to the attributes map
+   * @param key
+   * @param value
+   */
+  public void addAttribute(String key, String value) {
+    this.attributes.put(key, value);
+  }
+  
+  public String getDirective(String key) {
+    String toReturn = this.directives.get(key);
+    return toReturn;
+  }
+  
+  public NameValueMap<String, String> getNameValueMap() {
+    NameValueMap<String, String> nvm = new NameValueMap<String, String>();
+    for (String key : this.nameValueMap.keySet()) {
+      nvm.addToCollection(key, this.nameValueMap.get(key));
+    }
+    return nvm;
+  }
+  
+  /**
+   * add key value to the directives map
+   * @param key
+   * @param value
+   */
+  public void addDirective(String key, String value) {
+    this.directives.put(key, value);
+  }
+  
+  public VersionRange getVersion() {
+    VersionRange vi = null;
+    if (this.attributes.get(Constants.VERSION_ATTRIBUTE) != null 
+        && this.attributes.get(Constants.VERSION_ATTRIBUTE).length() > 0) {
+      vi = ManifestHeaderProcessor.parseVersionRange(this.attributes.get(Constants.VERSION_ATTRIBUTE));
+    } else {
+      // what if version is not specified?  let's interpret it as 0.0.0 
+      vi = ManifestHeaderProcessor.parseVersionRange("0.0.0");
+    }
+    return vi;
+  }
+  
+  @Override
+  public String toString()
+  {
+    return this.contentName + ";" + this.nameValueMap.toString();
+  }
+  
+  @Override
+  public boolean equals(Object other)
+  {
+    if (other == this) return true;
+    if (other == null) return false;
+    
+    if (other instanceof ContentImpl) {
+      ContentImpl otherContent = (ContentImpl)other;
+      
+      Map<String,String> attributesWithoutVersion = attributes;
+      
+      if (attributes.containsKey("version")) {
+        attributesWithoutVersion = new HashMap<String, String>(attributes);
+        attributesWithoutVersion.remove("version");
+      }
+      
+      Map<String, String> otherAttributesWithoutVersion = otherContent.attributes;
+      
+      if (otherContent.attributes.containsKey("version")) {
+        otherAttributesWithoutVersion = new HashMap<String, String>(otherContent.attributes);
+        otherAttributesWithoutVersion.remove("version");
+      }
+      
+      return contentName.equals(otherContent.contentName) && 
+             attributesWithoutVersion.equals(otherAttributesWithoutVersion) &&
+             directives.equals(otherContent.directives) &&
+             getVersion().equals(otherContent.getVersion());
+    }
+    
+    return false;
+  }
+  
+  @Override
+  public int hashCode()
+  {
+    return contentName.hashCode();
+  }
+  
+  /**
+   * set up directives and attributes
+   */
+  protected void setup() {
+    this.attributes = new HashMap<String, String>();
+    this.directives = new HashMap<String, String>();
+    
+    for (String key : this.nameValueMap.keySet()) {
+      if (key.endsWith(":")) {
+        this.directives.put(key.substring(0, key.length() - 1), this.nameValueMap.get(key));
+      } else {
+        this.attributes.put(key, this.nameValueMap.get(key));
+      }
+    }
+  }
+}