incubator-aries-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From mnutt...@apache.org
Subject svn commit: r989594 [1/2] - in /incubator/aries/trunk/application/application-deployment-management: ./ src/ src/main/ src/main/java/ src/main/java/org/ src/main/java/org/apache/ src/main/java/org/apache/aries/ src/main/java/org/apache/aries/applicatio...
Date Thu, 26 Aug 2010 10:31:46 GMT
Author: mnuttall
Date: Thu Aug 26 10:31:45 2010
New Revision: 989594

URL: http://svn.apache.org/viewvc?rev=989594&view=rev
Log:
ARIES-361: Provisioning changes required to support application isolation. From a patch submitted by Emily Jiang.

Added:
    incubator/aries/trunk/application/application-deployment-management/pom.xml
    incubator/aries/trunk/application/application-deployment-management/src/
    incubator/aries/trunk/application/application-deployment-management/src/main/
    incubator/aries/trunk/application/application-deployment-management/src/main/java/
    incubator/aries/trunk/application/application-deployment-management/src/main/java/org/
    incubator/aries/trunk/application/application-deployment-management/src/main/java/org/apache/
    incubator/aries/trunk/application/application-deployment-management/src/main/java/org/apache/aries/
    incubator/aries/trunk/application/application-deployment-management/src/main/java/org/apache/aries/application/
    incubator/aries/trunk/application/application-deployment-management/src/main/java/org/apache/aries/application/deployment/
    incubator/aries/trunk/application/application-deployment-management/src/main/java/org/apache/aries/application/deployment/management/
    incubator/aries/trunk/application/application-deployment-management/src/main/java/org/apache/aries/application/deployment/management/impl/
    incubator/aries/trunk/application/application-deployment-management/src/main/java/org/apache/aries/application/deployment/management/impl/DeploymentManifestManagerImpl.java
    incubator/aries/trunk/application/application-deployment-management/src/main/java/org/apache/aries/application/deployment/management/impl/ModelledResourceManagerImpl.java
    incubator/aries/trunk/application/application-deployment-management/src/main/java/org/apache/aries/application/deployment/management/impl/ParserProxyImpl.java
    incubator/aries/trunk/application/application-deployment-management/src/main/java/org/apache/aries/application/deployment/management/internal/
    incubator/aries/trunk/application/application-deployment-management/src/main/java/org/apache/aries/application/deployment/management/internal/BundleBlueprintParser.java
    incubator/aries/trunk/application/application-deployment-management/src/main/java/org/apache/aries/application/deployment/management/internal/MessageUtil.java
    incubator/aries/trunk/application/application-deployment-management/src/main/resources/
    incubator/aries/trunk/application/application-deployment-management/src/main/resources/OSGI-INF/
    incubator/aries/trunk/application/application-deployment-management/src/main/resources/OSGI-INF/blueprint/
    incubator/aries/trunk/application/application-deployment-management/src/main/resources/OSGI-INF/blueprint/deployment-manager.xml
    incubator/aries/trunk/application/application-deployment-management/src/main/resources/org/
    incubator/aries/trunk/application/application-deployment-management/src/main/resources/org/apache/
    incubator/aries/trunk/application/application-deployment-management/src/main/resources/org/apache/aries/
    incubator/aries/trunk/application/application-deployment-management/src/main/resources/org/apache/aries/application/
    incubator/aries/trunk/application/application-deployment-management/src/main/resources/org/apache/aries/application/deployment/
    incubator/aries/trunk/application/application-deployment-management/src/main/resources/org/apache/aries/application/deployment/management/
    incubator/aries/trunk/application/application-deployment-management/src/main/resources/org/apache/aries/application/deployment/management/messages/
    incubator/aries/trunk/application/application-deployment-management/src/main/resources/org/apache/aries/application/deployment/management/messages/DeploymentManagementMessages.properties
    incubator/aries/trunk/application/application-deployment-management/src/test/
    incubator/aries/trunk/application/application-deployment-management/src/test/java/
    incubator/aries/trunk/application/application-deployment-management/src/test/java/org/
    incubator/aries/trunk/application/application-deployment-management/src/test/java/org/apache/
    incubator/aries/trunk/application/application-deployment-management/src/test/java/org/apache/aries/
    incubator/aries/trunk/application/application-deployment-management/src/test/java/org/apache/aries/application/
    incubator/aries/trunk/application/application-deployment-management/src/test/java/org/apache/aries/application/deployment/
    incubator/aries/trunk/application/application-deployment-management/src/test/java/org/apache/aries/application/deployment/management/
    incubator/aries/trunk/application/application-deployment-management/src/test/java/org/apache/aries/application/deployment/management/DeploymentGeneratorTest.java
Modified:
    incubator/aries/trunk/application/application-deployment-management/   (props changed)

Propchange: incubator/aries/trunk/application/application-deployment-management/
------------------------------------------------------------------------------
--- svn:ignore (added)
+++ svn:ignore Thu Aug 26 10:31:45 2010
@@ -0,0 +1,4 @@
+.settings
+target
+.classpath
+.project

Added: incubator/aries/trunk/application/application-deployment-management/pom.xml
URL: http://svn.apache.org/viewvc/incubator/aries/trunk/application/application-deployment-management/pom.xml?rev=989594&view=auto
==============================================================================
--- incubator/aries/trunk/application/application-deployment-management/pom.xml (added)
+++ incubator/aries/trunk/application/application-deployment-management/pom.xml Thu Aug 26 10:31:45 2010
@@ -0,0 +1,98 @@
+<!--
+ 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>
+        <artifactId>application</artifactId>
+        <groupId>org.apache.aries.application</groupId>
+        <version>0.3-incubating-SNAPSHOT</version>
+    </parent>
+    <artifactId>org.apache.aries.application.deployment.management</artifactId>
+    <packaging>bundle</packaging>
+    <name>Apache Aries Application Deployment Management</name>
+    <description>
+      Deployment Manager for resolving an Aries Applications.
+    </description>
+
+    <properties>
+        <aries.osgi.export.pkg>
+        </aries.osgi.export.pkg>
+        <aries.osgi.private.pkg>
+            org.apache.aries.application.deployment.management.impl;
+            org.apache.aries.application.deployment.management.internal
+        </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.2.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>
+        <dependency>
+        	<groupId>org.apache.aries.application</groupId>
+        	<artifactId>org.apache.aries.application.utils</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.aries.application</groupId>
+            <artifactId>org.apache.aries.application.modeller</artifactId>
+        </dependency>
+        <dependency>
+        	<groupId>org.apache.aries.blueprint</groupId>
+        	<artifactId>org.apache.aries.blueprint.api</artifactId>
+        	<version>0.3-incubating-SNAPSHOT</version> 
+        </dependency>
+        <dependency>
+            <groupId>org.apache.aries.blueprint</groupId>
+            <artifactId>org.apache.aries.blueprint.core</artifactId>
+            <version>0.3-incubating-SNAPSHOT</version> 
+        </dependency>
+        
+    </dependencies>
+
+</project>

Added: incubator/aries/trunk/application/application-deployment-management/src/main/java/org/apache/aries/application/deployment/management/impl/DeploymentManifestManagerImpl.java
URL: http://svn.apache.org/viewvc/incubator/aries/trunk/application/application-deployment-management/src/main/java/org/apache/aries/application/deployment/management/impl/DeploymentManifestManagerImpl.java?rev=989594&view=auto
==============================================================================
--- incubator/aries/trunk/application/application-deployment-management/src/main/java/org/apache/aries/application/deployment/management/impl/DeploymentManifestManagerImpl.java (added)
+++ incubator/aries/trunk/application/application-deployment-management/src/main/java/org/apache/aries/application/deployment/management/impl/DeploymentManifestManagerImpl.java Thu Aug 26 10:31:45 2010
@@ -0,0 +1,581 @@
+/*
+ * 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.deployment.management.impl;
+
+import static org.apache.aries.application.utils.AppConstants.LOG_ENTRY;
+import static org.apache.aries.application.utils.AppConstants.LOG_EXIT;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.URL;
+import java.net.URLConnection;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import 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.PostResolveTransformer;
+import org.apache.aries.application.ServiceDeclaration;
+import org.apache.aries.application.deployment.management.internal.MessageUtil;
+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.DeploymentManifestManager;
+import org.apache.aries.application.management.InvalidAttributeException;
+import org.apache.aries.application.management.LocalPlatform;
+import org.apache.aries.application.management.ResolveConstraint;
+import org.apache.aries.application.management.ResolverException;
+import org.apache.aries.application.modelling.ExportedPackage;
+import org.apache.aries.application.modelling.ExportedService;
+import org.apache.aries.application.modelling.ImportedBundle;
+import org.apache.aries.application.modelling.ImportedPackage;
+import org.apache.aries.application.modelling.ModelledResource;
+import org.apache.aries.application.modelling.ModelledResourceManager;
+import org.apache.aries.application.modelling.ModellerException;
+import org.apache.aries.application.modelling.utils.DeployedBundles;
+import org.apache.aries.application.modelling.utils.ModellingManager;
+import org.apache.aries.application.utils.AppConstants;
+import org.apache.aries.application.utils.filesystem.FileSystem;
+import org.apache.aries.application.utils.filesystem.IOUtils;
+import org.apache.aries.application.utils.manifest.ManifestHeaderProcessor;
+import org.osgi.framework.Constants;
+import org.osgi.framework.Filter;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class DeploymentManifestManagerImpl implements DeploymentManifestManager
+{
+
+  private Logger _logger = LoggerFactory.getLogger(DeploymentManifestManagerImpl.class);
+  private AriesApplicationResolver resolver;
+  private List<PostResolveTransformer> postResolveTransformers;
+
+  private ModelledResourceManager modelledResourceManager;
+  private LocalPlatform localPlatform;
+
+
+  public LocalPlatform getLocalPlatform()
+  {
+    return localPlatform;
+  }
+
+  public void setLocalPlatform(LocalPlatform localPlatform)
+  {
+    this.localPlatform = localPlatform;
+  }
+
+  public ModelledResourceManager getModelledResourceManager()
+  {
+    return modelledResourceManager;
+  }
+
+  public void setModelledResourceManager(ModelledResourceManager modelledResourceManager)
+  {
+    this.modelledResourceManager = modelledResourceManager;
+  }
+
+  public AriesApplicationResolver getResolver()
+  {
+    return resolver;
+  }
+
+  public void setPostResolveTransformers(List<PostResolveTransformer> transformers) {
+    postResolveTransformers = transformers;
+  }
+  public void setResolver(AriesApplicationResolver resolver)
+  {
+    this.resolver = resolver;
+  }
+
+  /* Mutable state */
+  private DeployedBundles deployedBundles;
+  private Collection<ModelledResource> bundlesToBeProvisioned;
+  private String importPackages;
+  private Collection<ModelledResource> requiredUseBundle;
+
+
+
+  public DeployedBundles getDeployedBundles() {
+    return deployedBundles;
+  }
+
+
+  /**
+   * Perform provisioning to work out the 'freeze dried list' of the eba
+   * @param app - Aries application
+   * @param ResolveConstraint - resolver constraint for limiting the resolving results
+   * @return manifest the generated deployment manifest
+   * @throws ResolverException
+   */
+  public Manifest generateDeploymentManifest( AriesApplication app,  ResolveConstraint... constraints ) throws ResolverException
+  {
+
+    _logger.debug(LOG_ENTRY, "generateDeploymentManifest", new Object[]{app, constraints});
+    ApplicationMetadata appMetadata = app.getApplicationMetadata();
+    Collection<ModelledResource> byValueBundles = null;
+    try {
+      // find out blueprint information
+      byValueBundles = getByValueBundles(app);
+      // find out by value bundles and then by reference bundles
+    } catch (Exception e) {
+      throw new ResolverException (e);
+    }
+    Collection<Content> useBundles = app.getApplicationMetadata().getUseBundles();
+
+    Collection<Content> bundlesToResolve = new ArrayList<Content>();
+    bundlesToResolve.addAll(appMetadata.getApplicationContents());    
+    bundlesToResolve.addAll(useBundles);
+
+    //If we pass in provision bundles (e.g. import deployment manifest sanity check), we add them into our bundlesToResolve set.
+    // This is because we want to make sure all bundles we passed into resolver the same as what we are going to get from resolver. 
+    List<Content> restrictedReqs = new ArrayList<Content>();
+    for (ResolveConstraint constraint : constraints ) {
+      Content content = ManifestHeaderProcessor.parseContent(constraint.getBundleName(), constraint.getVersionRange().toString());
+      restrictedReqs.add(content);
+    }
+    Manifest man = generateDeploymentManifest(app, byValueBundles, useBundles, restrictedReqs);
+    _logger.debug(LOG_EXIT, "generateDeploymentManifest", new Object[] {man});
+    return man;
+  }
+
+  /**
+   * Perform provisioning to work out the 'freeze dried list' of the eba
+   * @param appContent - the application content in the application.mf
+   * @param useBundleContent - use bundle entry in the application.mf
+   * @param providedByValueBundles - bundles contained in the eba  
+   * @return
+   * @throws ResolverException
+   */
+  public Manifest generateDeploymentManifest( 
+      AriesApplication app, Collection<ModelledResource> provideByValueBundles, Collection<Content> useBundleSet, Collection<Content> otherBundles) throws ResolverException {
+    _logger.debug(LOG_ENTRY, "generateDeploymentManifest", new Object[]{app, provideByValueBundles,useBundleSet,otherBundles });
+    Map<String, String> deploymentManifestMap = Collections.EMPTY_MAP;
+
+    ApplicationMetadata appMetadata = app.getApplicationMetadata();
+    Collection<Content> bundlesToResolve = new ArrayList<Content>();
+    Set<ImportedBundle> appContentIB = null;
+    Collection<Content> appContent = appMetadata.getApplicationContents();
+    Set<ImportedBundle> useBundleIB = null;
+    useBundleIB = new HashSet<ImportedBundle> (toImportedBundle(useBundleSet));
+    appContentIB = new HashSet<ImportedBundle>(toImportedBundle(appMetadata.getApplicationContents()));
+
+    bundlesToResolve.addAll(useBundleSet);
+
+    bundlesToResolve.addAll(appMetadata.getApplicationContents());
+    bundlesToResolve.addAll(otherBundles);
+    Collection<ModelledResource> byValueBundles = new ArrayList<ModelledResource>(provideByValueBundles);
+    ModelledResource fakeBundleResource;
+    try { 
+      fakeBundleResource = createFakeBundle(appMetadata);
+    } catch (InvalidAttributeException iax) { 
+      ResolverException rx = new ResolverException (iax);
+      _logger.debug(LOG_EXIT, "generateDeploymentManifest", new Object[] {rx});
+
+      throw rx;
+    }
+    byValueBundles.add(fakeBundleResource);
+    String appSymbolicName = appMetadata.getApplicationSymbolicName();
+    String appVersion = appMetadata.getApplicationVersion().toString();
+    String uniqueName = appSymbolicName + "_" + appVersion;
+    deployedBundles = new DeployedBundles(appMetadata.getApplicationName(), appContentIB, useBundleIB, Arrays.asList(fakeBundleResource));
+    bundlesToBeProvisioned = resolver.resolve(
+        appSymbolicName, appVersion, byValueBundles, bundlesToResolve);
+    pruneFakeBundleFromResults (bundlesToBeProvisioned);
+
+    if (bundlesToBeProvisioned.isEmpty()) {
+      throw new ResolverException(MessageUtil.getMessage("EMPTY_DEPLOYMENT_CONTENT",uniqueName));
+    } else {
+      for (ModelledResource rbm : bundlesToBeProvisioned)
+      {
+        deployedBundles.addBundle(rbm);
+      }
+      requiredUseBundle = deployedBundles.getRequiredUseBundle();
+
+      if (requiredUseBundle.size() < useBundleSet.size())
+      {
+        // Some of the use-bundle entries were redundant so resolve again with just the good ones.
+        deployedBundles = new DeployedBundles(appMetadata.getApplicationName(), appContentIB, useBundleIB, Arrays.asList(fakeBundleResource));
+        bundlesToResolve.clear();
+        bundlesToResolve.addAll(appContent);
+        Collection<ImportedBundle> slimmedDownUseBundle = narrowUseBundles(useBundleIB, requiredUseBundle);
+        bundlesToResolve.addAll(toContent(slimmedDownUseBundle));
+        bundlesToBeProvisioned = resolver.resolve(appSymbolicName, appVersion, byValueBundles, bundlesToResolve);
+        pruneFakeBundleFromResults (bundlesToBeProvisioned);
+        for (ModelledResource rbm : bundlesToBeProvisioned)
+        {
+          deployedBundles.addBundle(rbm);
+        }
+      }
+
+      // Check for circular dependencies. No shared bundle can depend on any 
+      // isolated bundle. 
+      Collection<ModelledResource> sharedBundles = new HashSet<ModelledResource>();
+      sharedBundles.addAll (deployedBundles.getDeployedProvisionBundle());
+      sharedBundles.addAll (deployedBundles.getRequiredUseBundle()); 
+
+      Collection<Content> requiredSharedBundles = new ArrayList<Content>();
+      for (ModelledResource mr : sharedBundles) { 
+        String version = mr.getExportedBundle().getVersion();
+        String exactVersion = "[" + version + "," + version + "]";
+
+        Content ib = ManifestHeaderProcessor.parseContent(mr.getExportedBundle().getSymbolicName(), 
+            exactVersion);
+        requiredSharedBundles.add(ib);
+
+      }
+      // This will throw a ResolverException if the shared content does not resolve
+      Collection<ModelledResource> resolvedSharedBundles = resolver.resolve(appSymbolicName, appVersion
+          , byValueBundles, requiredSharedBundles);
+
+      List<String> differences = findDifferences (resolvedSharedBundles, sharedBundles);
+      // If we have differences, it means that we have shared bundles trying to import packages
+      // from isolated bundles. We need to build up the error message and throw a ResolverException
+      if (!differences.isEmpty()) { 
+        StringBuilder msgs = new StringBuilder();
+        List<String> unsatisfiedRequirements = new ArrayList<String>();
+
+        Map<String, List<String>> isolatedBundles = new HashMap<String, List<String>>();
+        // Find the isolated bundles and store all the packages that they export in a map.
+        for (ModelledResource mr : resolvedSharedBundles) {
+          String mrName = mr.getSymbolicName() + "_" + mr.getExportedBundle().getVersion();
+          if (differences.contains(mrName)) {
+            List<String> exportedPackages = new ArrayList<String>();
+            isolatedBundles.put(mrName, exportedPackages);
+            for (ExportedPackage ep : mr.getExportedPackages()) {
+              exportedPackages.add(ep.getPackageName());
+            }
+          }
+        }
+        // Now loop through the shared bundles, reading the imported packages, and find which ones 
+        // are exported from the isolated bundles.
+        for (ModelledResource mr : resolvedSharedBundles) {
+          String mrName = mr.getSymbolicName() + "_" + mr.getExportedBundle().getVersion();
+          // if current reource isn't an isolated bundle check it's requirements
+          if (!!! differences.contains(mrName)) {
+            // Iterate through the imported packages of the current shared bundle.
+            for (ImportedPackage ip : mr.getImportedPackages()) {
+              String packageName = ip.getPackageName();
+              List<String> bundlesExportingPackage = new ArrayList<String>();
+              // Loop through each exported package of each isolated bundle, and if we
+              // get a match store the info away.
+              for (Map.Entry<String, List<String>> currBundle : isolatedBundles.entrySet()) {
+
+                List<String> exportedPackages = currBundle.getValue();
+                if (exportedPackages != null && exportedPackages.contains(packageName)) {
+                  bundlesExportingPackage.add(currBundle.getKey());
+                }
+              }
+              // If we have found at least one matching entry, we construct the sub message for the
+              // exception.
+              if (!!! bundlesExportingPackage.isEmpty()) {
+                String newMsg;
+                if (bundlesExportingPackage.size() > 1) {
+                  newMsg = MessageUtil.getMessage("SHARED_BUNDLE_IMPORTING_FROM_ISOLATED_BUNDLES", 
+                      new Object[] {mrName, packageName, bundlesExportingPackage}); 
+                } else {
+                  newMsg = MessageUtil.getMessage("SHARED_BUNDLE_IMPORTING_FROM_ISOLATED_BUNDLE", 
+                      new Object[] {mrName, packageName, bundlesExportingPackage});
+                }
+                msgs.append("\n");
+                msgs.append(newMsg);
+                unsatisfiedRequirements.add(newMsg);
+              }
+            }
+          }
+        }
+        // Once we have iterated over all bundles and have got our translated submessages, 
+        // throw the exception.
+        // Well! if the msgs is empty, no need to throw an exception
+        if (msgs.length() !=0) {
+          String message = MessageUtil.getMessage(
+              "SUSPECTED_CIRCULAR_DEPENDENCIES", new Object[] {appMetadata.getApplicationSymbolicName(), msgs});
+          ResolverException rx = new ResolverException (message);
+          rx.setUnsatisfiedRequirements(unsatisfiedRequirements);
+          _logger.debug(LOG_EXIT, "generateDeploymentManifest", new Object[] {rx});
+          throw (rx);
+        }
+      }
+
+      requiredUseBundle = deployedBundles.getRequiredUseBundle();
+      importPackages = deployedBundles.getImportPackage();
+      Collection<ModelledResource> requriedBundles = new HashSet<ModelledResource>();
+      requriedBundles.addAll(deployedBundles.getDeployedContent());
+      requriedBundles.addAll(deployedBundles.getRequiredUseBundle());
+      requriedBundles.addAll(deployedBundles.getDeployedProvisionBundle());
+      deploymentManifestMap = generateDeploymentAttributes(appMetadata);
+      // Perform some post process if there are any.
+      if ((postResolveTransformers != null) && (!postResolveTransformers.isEmpty())) {
+        // validate the contents
+        for (PostResolveTransformer prt : postResolveTransformers) {
+          prt.postResolveProcess(app, requriedBundles, deploymentManifestMap);
+        }
+      }
+    }
+    Manifest man = convertMapToManifest(deploymentManifestMap);
+    _logger.debug(LOG_EXIT, "generateDeploymentManifest", new Object[] {man});
+    return man;
+  }
+
+  /**
+   * Returns a Collection of the {@link ImportedBundle} objects that are
+   * satisfied by the contents of the Collection of requiredUseBundles.
+   * 
+   * @param useBundleSet
+   * @param requiredUseBundle
+   * @return the collection of ImportedBundle objects
+   */
+  private Collection<ImportedBundle> narrowUseBundles(
+      Collection<ImportedBundle> useBundleSet,
+      Collection<ModelledResource> requiredUseBundle) {
+    _logger.debug(LOG_ENTRY, "narrowUseBundles", new Object[] {useBundleSet,requiredUseBundle});
+    Collection<ImportedBundle> result = new HashSet<ImportedBundle>();
+
+    outer : for(ImportedBundle ib : useBundleSet) {
+      for(ModelledResource mb : requiredUseBundle) {
+        if(ib.isSatisfied(mb.getExportedBundle())) {
+          result.add(ib);
+          continue outer;
+        }
+      }
+    }
+    _logger.debug(LOG_EXIT, "narrowUseBundles", result);
+    return result;
+  }
+
+
+
+  private Map<String,String> generateDeploymentAttributes(ApplicationMetadata appMetadata) throws ResolverException
+  {
+    _logger.debug(LOG_ENTRY, "generateDeploymentAttributes", new Object[] {appMetadata});
+    Map<String,String> result = new HashMap<String, String>();
+    String content = deployedBundles.getContent();
+    if (!content.isEmpty()) {
+      result.put(AppConstants.DEPLOYMENT_CONTENT, content);
+    } else {
+      throw new ResolverException(MessageUtil.getMessage("EMPTY_DEPLOYMENT_CONTENT", appMetadata.getApplicationSymbolicName()));
+    }
+
+    String useBundle = deployedBundles.getUseBundle();
+    if (!useBundle.isEmpty()) {
+      result.put(AppConstants.DEPLOYMENT_USE_BUNDLE, useBundle);
+    }
+
+    String provisionBundle = deployedBundles.getProvisionBundle();
+    if (!provisionBundle.isEmpty()) {
+      result.put(AppConstants.DEPLOYMENT_PROVISION_BUNDLE, provisionBundle);
+    }
+
+
+    String importServices = deployedBundles.getDeployedImportService();
+    if (!importServices.isEmpty()) { 
+      result.put(AppConstants.DEPLOYMENTSERVICE_IMPORT, importServices);
+    }
+
+
+    if (!importPackages.isEmpty()) {
+      result.put(Constants.IMPORT_PACKAGE, importPackages);
+    }
+
+    result.put(AppConstants.APPLICATION_VERSION, appMetadata.getApplicationVersion().toString());
+    result.put(AppConstants.APPLICATION_SYMBOLIC_NAME, appMetadata.getApplicationSymbolicName());
+
+    _logger.debug(LOG_ENTRY, "generateDeploymentAttributes", new Object[] {result});
+    return result;
+  }
+
+  private Manifest convertMapToManifest(Map<String,String> attributes)
+  {
+    _logger.debug(LOG_ENTRY, "convertMapToManifest", new Object[]{attributes});
+    Manifest man = new Manifest();
+    Attributes att = man.getMainAttributes();
+    att.putValue(Attributes.Name.MANIFEST_VERSION.toString(), AppConstants.MANIFEST_VERSION);
+    for (Map.Entry<String, String> entry : attributes.entrySet()) {
+      att.putValue(entry.getKey(),  entry.getValue());
+    }
+    _logger.debug(LOG_EXIT, "convertMapToManifest", new Object[]{man});
+    return man;
+  }
+
+
+
+
+  private static final String FAKE_BUNDLE_NAME = "aries.internal.fake.service.bundle";
+
+  // create a 'mock' bundle that does nothing but export services required by 
+  // Application-ImportService
+  private ModelledResource createFakeBundle (ApplicationMetadata appMetadata) throws InvalidAttributeException 
+  {
+    _logger.debug(LOG_ENTRY, "createFakeBundle", new Object[]{appMetadata});
+    Attributes attrs = new Attributes();
+    attrs.putValue(Constants.BUNDLE_SYMBOLICNAME, FAKE_BUNDLE_NAME);
+    attrs.putValue(Constants.BUNDLE_VERSION_ATTRIBUTE, "1.0");
+    attrs.putValue(Constants.BUNDLE_MANIFESTVERSION, "2");
+
+    // Build an ExportedService for every Application-ImportService entry
+    List<ServiceDeclaration> appImportServices = appMetadata.getApplicationImportServices();
+    Collection<ExportedService> exportedServices = new ArrayList<ExportedService>();
+    for (ServiceDeclaration sDec : appImportServices) { 
+      Collection<String> ifaces = Arrays.asList(sDec.getInterfaceName());
+      Filter filter = sDec.getFilter();
+      Map<String, String> serviceProperties;
+      if (filter != null) { 
+        serviceProperties = ManifestHeaderProcessor.parseFilter(filter.toString());
+      } else { 
+        serviceProperties = new HashMap<String, String>();
+      }
+      serviceProperties.put("service.imported", "");
+      exportedServices.add (ModellingManager.getExportedService("", 0, ifaces, new HashMap<String, Object>(serviceProperties)));
+    }
+    ModelledResource fakeBundle = ModellingManager.getModelledResource(null, attrs, null, exportedServices);
+
+    _logger.debug(LOG_EXIT, "createFakeBundle", new Object[]{fakeBundle});
+    return fakeBundle;
+  }
+
+  private void pruneFakeBundleFromResults (Collection<ModelledResource> results) { 
+    _logger.debug(LOG_ENTRY, "pruneFakeBundleFromResults", new Object[]{results});
+    boolean fakeBundleRemoved = false;
+    Iterator<ModelledResource> it = results.iterator();
+    while (!fakeBundleRemoved && it.hasNext()) { 
+      ModelledResource mr = it.next();
+      if (mr.getExportedBundle().getSymbolicName().equals(FAKE_BUNDLE_NAME)) { 
+        it.remove();
+        fakeBundleRemoved = true;
+      }
+    }
+    _logger.debug(LOG_EXIT, "pruneFakeBundleFromResults");
+
+  }
+
+  /**
+   * We've done a sanity check resolve on our sharedBundles and received back 
+   * resolvedSharedBundles. These two collections should be equal in size and 
+   * contain the same elements. If this is not true, we've found a circular dependency. 
+   * This method extracts the name_versions of those bundles in resolvedSharedBundles
+   * that do not appear in sharedBundles. 
+   * @param resolvedSharedBundles What we got back from the resolver
+   * @param sharedBundles         What we expected to get back from the resolver
+   * @return                      The difference
+   */
+  private List<String> findDifferences (Collection<ModelledResource> resolvedSharedBundles, 
+      Collection<ModelledResource> sharedBundles){
+    _logger.debug(LOG_ENTRY, "findDifferences", new Object[]{resolvedSharedBundles,sharedBundles });
+    Set<String> expectedBundles = new HashSet<String>();
+    for (ModelledResource sb : sharedBundles) { 
+      expectedBundles.add(sb.getExportedBundle().getSymbolicName() + "_" + 
+          sb.getExportedBundle().getVersion());
+    }
+    List<String> suspects = new ArrayList<String>();
+    for (ModelledResource mr : resolvedSharedBundles) {
+      String thisBundle = mr.getExportedBundle().getSymbolicName() + "_" + 
+      mr.getExportedBundle().getVersion();
+      if (!expectedBundles.contains(thisBundle)) { 
+        suspects.add(thisBundle);   
+      }
+    }
+    _logger.debug(LOG_EXIT, "pruneFakeBundleFromResults", new Object[]{suspects});
+
+    return suspects;
+  }
+
+  /**
+   * Covert a collection of contents to a collection of ImportedBundle objects
+   * @param content a collection of content
+   * @return a collection of ImportedBundle objects
+   * @throws ResolverException
+   */
+  private Collection<ImportedBundle> toImportedBundle(Collection<Content> content) throws ResolverException
+  {
+
+    _logger.debug(LOG_ENTRY, "toImportedBundle", new Object[]{content});
+
+    List<ImportedBundle> result = new ArrayList<ImportedBundle>();
+    for (Content c : content) {
+      try {
+        result.add(ModellingManager.getImportedBundle(c.getContentName(), c.getVersion().toString()));
+      } catch (InvalidAttributeException iax) { 
+        ResolverException rx = new ResolverException (iax);
+        _logger.debug(LOG_EXIT, "toImportedBundle", new Object[]{rx});
+        throw rx;
+      }
+    }
+
+    _logger.debug(LOG_EXIT, "toImportedBundle", new Object[]{result});
+
+    return result;
+  }
+
+  private Collection<Content> toContent(Collection<ImportedBundle> ibs)
+  {
+    Collection<Content> contents = new ArrayList<Content>();
+    for (ImportedBundle ib : ibs) {
+      contents.add(ManifestHeaderProcessor.parseContent(ib.getSymbolicName(), ib.getVersionRange()));
+    }
+    return contents;
+  }
+  /**
+   * Get a list of bundles included by value in this application.
+   * @param app The Aries Application
+   * @return a list of by value bundles
+   * @throws IOException
+   * @throws InvalidAttributeException
+   * @throws ModellerException
+   */
+  private Collection<ModelledResource> getByValueBundles(AriesApplication app) throws IOException, InvalidAttributeException, ModellerException {
+
+    _logger.debug(LOG_ENTRY, "getByValueBundles", new Object[]{app});
+
+    Collection<BundleInfo> bundles = app.getBundleInfo();
+    Collection<ModelledResource> result = new ArrayList<ModelledResource>();
+
+    for (BundleInfo bundleInfo: bundles) {      
+      // find out the eba directory
+      String bundleLocation = bundleInfo.getLocation();
+      String bundleFileName = bundleLocation.substring(bundleLocation.lastIndexOf('/') + 1);
+      // just the portion of root directory excluding !      
+      URL jarUrl = new URL(bundleLocation);
+      URLConnection jarCon = jarUrl.openConnection();
+      jarCon.connect();
+      InputStream in = jarCon.getInputStream();
+      File temp = new File(getLocalPlatform().getTemporaryDirectory() + bundleFileName);
+      OutputStream out = new FileOutputStream(temp);
+      IOUtils.copy(in, out);
+      IOUtils.close(out);
+      result.add(modelledResourceManager.getModelledResource(null, FileSystem.getFSRoot(temp)));
+      // delete the temp file
+      temp.delete();
+    }
+    _logger.debug(LOG_EXIT, "getByValueBundles", new Object[]{result});
+    return result;
+  }
+
+}

Added: incubator/aries/trunk/application/application-deployment-management/src/main/java/org/apache/aries/application/deployment/management/impl/ModelledResourceManagerImpl.java
URL: http://svn.apache.org/viewvc/incubator/aries/trunk/application/application-deployment-management/src/main/java/org/apache/aries/application/deployment/management/impl/ModelledResourceManagerImpl.java?rev=989594&view=auto
==============================================================================
--- incubator/aries/trunk/application/application-deployment-management/src/main/java/org/apache/aries/application/deployment/management/impl/ModelledResourceManagerImpl.java (added)
+++ incubator/aries/trunk/application/application-deployment-management/src/main/java/org/apache/aries/application/deployment/management/impl/ModelledResourceManagerImpl.java Thu Aug 26 10:31:45 2010
@@ -0,0 +1,217 @@
+/*
+ * 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.deployment.management.impl;
+
+import static org.apache.aries.application.utils.AppConstants.LOG_ENTRY;
+import static org.apache.aries.application.utils.AppConstants.LOG_EXIT;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.net.URLConnection;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Enumeration;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+import java.util.jar.Attributes;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipFile;
+
+import org.apache.aries.application.deployment.management.internal.BundleBlueprintParser;
+import org.apache.aries.application.filesystem.IDirectory;
+import org.apache.aries.application.filesystem.IFile;
+import org.apache.aries.application.management.InvalidAttributeException;
+import org.apache.aries.application.modelling.ExportedService;
+import org.apache.aries.application.modelling.ImportedService;
+import org.apache.aries.application.modelling.ModelledResource;
+import org.apache.aries.application.modelling.ModelledResourceManager;
+import org.apache.aries.application.modelling.ModellerException;
+import org.apache.aries.application.modelling.ParsedServiceElements;
+import org.apache.aries.application.modelling.ParserProxy;
+import org.apache.aries.application.modelling.utils.ModellingManager;
+import org.apache.aries.application.utils.manifest.BundleManifest;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+public class ModelledResourceManagerImpl implements ModelledResourceManager
+{
+  private Logger _logger = LoggerFactory.getLogger(ModelledResourceManagerImpl.class);
+
+  private ParserProxy parserProxy;
+
+  public ParserProxy getParserProxy()
+  {
+    return parserProxy;
+  }
+  public void setParserProxy(ParserProxy parserProxy)
+  {
+    this.parserProxy = parserProxy;
+  }
+
+
+  /**
+   * For a given file, which we know to be a bundle, parse out all the
+   * service, reference and reference-list elements. This method will return
+   * all such services, including anonymous ones, 
+   * but should not return indistinguishable duplicates. 
+   * @param archive CommonArchive. The caller is responsible for closing this afterwards. 
+   * @return ParsedServiceElementsImpl 
+   * @throws OpenFailureException 
+   */
+  public ParsedServiceElements getServiceElements (IDirectory archive) throws ModellerException { 
+
+    _logger.debug(LOG_ENTRY,"getServiceElements", archive );
+
+    Set<ExportedService> services = new HashSet<ExportedService>();
+    Set<ImportedService> references = new HashSet<ImportedService>();
+    try { 
+      Collection<IFile> blueprints = findBlueprints(archive);
+      InputStream is = null;
+      for (IFile bpFile : blueprints) {
+        URL url = bpFile.toURL();
+        URLConnection conn = url.openConnection();
+        is = conn.getInputStream();
+        //is = this.getClass().getResourceAsStream(bpFile.getName());
+        try {
+          ParsedServiceElements pse = parserProxy.parseAllServiceElements(is);
+          services.addAll(pse.getServices());
+          references.addAll(pse.getReferences());
+
+        } finally {
+          if (is != null) {
+            is.close();
+          }
+        }
+      }
+    } catch (URISyntaxException e) {
+      ModellerException m = new ModellerException(e);
+      _logger.debug(LOG_EXIT, "getServiceElements", m);
+      throw m;
+    } catch (IOException e) {
+      ModellerException m = new ModellerException(e);
+      _logger.debug(LOG_EXIT, "getServiceElements", m);
+      throw m;
+    } catch (Exception e) {
+      ModellerException m = new ModellerException(e);
+      _logger.debug(LOG_EXIT, "getServiceElements", m);
+      throw m;
+    } 
+    ParsedServiceElements result = ModellingManager.getParsedServiceElements(services, references);
+    _logger.debug(LOG_EXIT, "getServiceElements", result);
+    return result;
+  }
+
+
+  /**
+   * Helper method to pass a single bundle into findBlueprints 
+   * @param oneBundle a single bundle
+   * @return Files for all the blueprint files within the bundle
+   * @throws URISyntaxException
+   * @throws IOException
+   * @throws OpenFailureException
+   */
+  private Collection<IFile> findBlueprints (IDirectory oneBundle) 
+  throws  IOException
+  {
+    _logger.debug(LOG_ENTRY, "findBlueprints", oneBundle);
+    Set<IDirectory> archiveSet = new HashSet<IDirectory>();
+    archiveSet.add(oneBundle);
+    Collection<IFile> result = findBlueprints (archiveSet);
+    _logger.debug(LOG_EXIT, "findBlueprints", result);
+    return result;
+  }
+
+  /**
+   * Locate all blueprint xml files located within a set of bundles. Typically, call findApplicationBundles()
+   * first to determine which bundles within an EBA fall within the range of the Application-Content header. 
+   * (See the comment on that method). 
+   * @param applicationBundles
+   * @return A Collection of blue print files
+   * @throws URISyntaxException
+   * @throws IOException
+   * @throws OpenFailureException
+   */
+  private Collection<IFile> findBlueprints(Collection<IDirectory> applicationBundles)
+  throws IOException
+  {
+    _logger.debug(LOG_ENTRY, "findBlueprints", applicationBundles);
+    Collection<IFile> blueprints = new ArrayList<IFile>();
+    for (IDirectory appBundle : applicationBundles) {
+      if (appBundle != null) {
+        File bundleFile = new File(appBundle.toString());
+        BundleManifest bundleMf = BundleManifest.fromBundle(bundleFile);
+        BundleBlueprintParser bpParser = new BundleBlueprintParser(bundleMf);
+        ZipFile zipFile = new ZipFile(bundleFile);
+        Enumeration<? extends ZipEntry> entries = zipFile.entries();
+        while (entries.hasMoreElements()) {
+          ZipEntry ze = entries.nextElement();
+
+          System.out.println(ze.getName());
+        }
+        List<IFile> files = appBundle.listAllFiles();
+        Iterator<IFile> it = files.iterator();
+        while (it.hasNext()) {
+          IFile file = (IFile) it.next();         
+          String directoryFullPath = file.getName(); 
+          String directoryName = "";
+          String fileName = "";
+          if (directoryFullPath.lastIndexOf("/") != -1) {
+            directoryName = directoryFullPath.substring(0, directoryFullPath.lastIndexOf("/"));
+            fileName = directoryFullPath.substring(directoryFullPath.lastIndexOf("/") + 1);
+          } else {
+            if (file.isFile()) {
+              directoryName="";
+              fileName = directoryFullPath;
+            } 
+
+          }
+          if (bpParser.isBPFile(directoryName, fileName)) {
+            blueprints.add(file);
+          }
+        }
+      }
+    }
+    _logger.debug(LOG_EXIT, "findBlueprints", blueprints);
+    return blueprints;
+  }
+
+  public ModelledResource getModelledResource(String uri, IDirectory bundle) throws ModellerException{
+    _logger.debug(LOG_ENTRY, "getModelledResource", new Object[]{uri, bundle});
+    ParsedServiceElements pse = getServiceElements(bundle);
+
+    BundleManifest bm = BundleManifest.fromBundle(new File(bundle.toString()));
+    Attributes attributes = bm.getRawAttributes();
+    ModelledResource mbi;
+    try {
+      mbi = ModellingManager.getModelledResource(uri, attributes, pse.getReferences(), pse.getServices());
+    } catch (InvalidAttributeException iae) {
+      throw new ModellerException(iae);
+    }
+    _logger.debug(LOG_EXIT, "getModelledResource", mbi);
+    return mbi;
+  }
+
+}

Added: incubator/aries/trunk/application/application-deployment-management/src/main/java/org/apache/aries/application/deployment/management/impl/ParserProxyImpl.java
URL: http://svn.apache.org/viewvc/incubator/aries/trunk/application/application-deployment-management/src/main/java/org/apache/aries/application/deployment/management/impl/ParserProxyImpl.java?rev=989594&view=auto
==============================================================================
--- incubator/aries/trunk/application/application-deployment-management/src/main/java/org/apache/aries/application/deployment/management/impl/ParserProxyImpl.java (added)
+++ incubator/aries/trunk/application/application-deployment-management/src/main/java/org/apache/aries/application/deployment/management/impl/ParserProxyImpl.java Thu Aug 26 10:31:45 2010
@@ -0,0 +1,263 @@
+/*
+ * 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.deployment.management.impl;
+import static org.apache.aries.application.utils.AppConstants.LOG_ENTRY;
+import static org.apache.aries.application.utils.AppConstants.LOG_EXIT;
+import java.io.InputStream;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.aries.application.management.InvalidAttributeException;
+import org.apache.aries.application.modelling.ExportedService;
+import org.apache.aries.application.modelling.ImportedService;
+import org.apache.aries.application.modelling.ParsedServiceElements;
+import org.apache.aries.application.modelling.ParserProxy;
+import org.apache.aries.application.modelling.WrappedServiceMetadata;
+import org.apache.aries.application.modelling.utils.ModellingManager;
+import org.apache.aries.blueprint.ComponentDefinitionRegistry;
+import org.apache.aries.blueprint.ParserService;
+import org.osgi.framework.BundleContext;
+import org.osgi.service.blueprint.reflect.BeanMetadata;
+import org.osgi.service.blueprint.reflect.CollectionMetadata;
+import org.osgi.service.blueprint.reflect.ComponentMetadata;
+import org.osgi.service.blueprint.reflect.MapEntry;
+import org.osgi.service.blueprint.reflect.Metadata;
+import org.osgi.service.blueprint.reflect.RefMetadata;
+import org.osgi.service.blueprint.reflect.ReferenceListMetadata;
+import org.osgi.service.blueprint.reflect.ServiceMetadata;
+import org.osgi.service.blueprint.reflect.ServiceReferenceMetadata;
+import org.osgi.service.blueprint.reflect.Target;
+import org.osgi.service.blueprint.reflect.ValueMetadata;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+
+public class ParserProxyImpl implements ParserProxy {
+  private Logger _logger = LoggerFactory.getLogger(ParserProxyImpl.class);
+  private ParserService _parserService;
+  private BundleContext _bundleContext;
+  
+  public void setParserService (ParserService p) { 
+    _parserService = p;
+  }
+  
+  public void setBundleContext (BundleContext b) { 
+    _bundleContext = b;
+  }
+  
+
+  public List<? extends WrappedServiceMetadata> parse(List<URL> blueprintsToParse) throws Exception {
+    _logger.debug(LOG_ENTRY, "parse", new Object[]{blueprintsToParse});
+    ComponentDefinitionRegistry cdr = _parserService.parse (blueprintsToParse, _bundleContext.getBundle());
+    List<? extends WrappedServiceMetadata> result = parseCDRForServices (cdr, true);
+    _logger.debug(LOG_EXIT, "parse", new Object[]{result});
+    return result;
+  }
+   
+  public List<? extends WrappedServiceMetadata> parse(URL blueprintToParse)
+      throws Exception {
+    _logger.debug(LOG_ENTRY, "parse", new Object[]{blueprintToParse});
+    List<URL> list = new ArrayList<URL>();
+    list.add(blueprintToParse);
+   
+    List<? extends WrappedServiceMetadata> result = parse (list);
+    _logger.debug(LOG_EXIT, "parse", new Object[]{result});
+    return result;
+  }
+
+
+  public List<? extends WrappedServiceMetadata> parse(InputStream blueprintToParse)
+      throws Exception {
+    _logger.debug(LOG_ENTRY, "parse", new Object[]{blueprintToParse});
+    ComponentDefinitionRegistry cdr = _parserService.parse (blueprintToParse, _bundleContext.getBundle());
+    List<? extends WrappedServiceMetadata> result = parseCDRForServices (cdr, true);
+    _logger.debug(LOG_EXIT, "parse", new Object[]{result});
+    return result;
+  }
+ 
+
+  public ParsedServiceElements parseAllServiceElements(InputStream blueprintToParse) throws Exception {
+    _logger.debug(LOG_ENTRY, "parseAllServiceElements", new Object[]{blueprintToParse});
+    ComponentDefinitionRegistry cdr = _parserService.parse (blueprintToParse, _bundleContext.getBundle());
+    Collection<ExportedService> services = parseCDRForServices(cdr, false);
+    Collection<ImportedService> references = parseCDRForReferences (cdr);
+    ParsedServiceElements result = ModellingManager.getParsedServiceElements(services, references);
+    _logger.debug(LOG_EXIT, "parseAllServiceElements", new Object[]{result});
+    return result;
+  }
+  
+  /**
+   * Extract Service metadata from a ComponentDefinitionRegistry. When doing SCA modelling, we
+   * need to suppress anonymous services. We don't want to do that when we're modelling for 
+   * provisioning dependencies. 
+   * @param cdr                       ComponentDefinitionRegistry
+   * @param suppressAnonymousServices Unnamed services will not be returned if this is true
+   * @return List<WrappedServiceMetadata>
+   */
+  private List<ExportedService> parseCDRForServices (ComponentDefinitionRegistry cdr, 
+      boolean suppressAnonymousServices) { 
+    _logger.debug(LOG_ENTRY, "parseCDRForServices", new Object[]{cdr, suppressAnonymousServices});
+    List<ExportedService> result = new ArrayList<ExportedService>();
+    Set<String> names = cdr.getComponentDefinitionNames();
+    for (String name: names) { 
+      ComponentMetadata compMetadata = cdr.getComponentDefinition(name);
+      if (compMetadata instanceof ServiceMetadata) { 
+        ServiceMetadata serviceMetadata = (ServiceMetadata)compMetadata;
+        String serviceName;
+        int ranking;
+        Collection<String> interfaces = new ArrayList<String>(); 
+        Map<String, Object> serviceProps = new HashMap<String, Object>();
+
+        ranking = serviceMetadata.getRanking();
+        for (Object i : serviceMetadata.getInterfaces()) {
+          interfaces.add((String)i);
+        }
+        
+        // get the service properties
+        List<MapEntry> props = serviceMetadata.getServiceProperties();
+        for (MapEntry entry : props) { 
+          String key = ((ValueMetadata)entry.getKey()).getStringValue();
+          
+          Metadata value = entry.getValue();
+          if (value instanceof CollectionMetadata) { 
+            List<Metadata> values = ((CollectionMetadata)value).getValues();
+            String[] theseValues = new String[values.size()];
+            for (int i=0; i < values.size(); i++) { 
+              Metadata m = values.get(i); 
+              theseValues[i] = ((ValueMetadata)m).getStringValue();
+            }
+            serviceProps.put(key, theseValues);
+          } else { 
+            serviceProps.put(key, ((ValueMetadata)entry.getValue()).getStringValue());
+          }
+        }
+
+        // serviceName: use the service id unless that's not set, 
+        // in which case we use the bean id. 
+        serviceName = serviceMetadata.getId();
+        
+        // If the Service references a Bean, export the bean id as a service property
+        // as per 121.6.5 p669 of the blueprint 1.0 specification
+        Target t = serviceMetadata.getServiceComponent();
+        String targetId = null;
+        if (t instanceof RefMetadata) { 
+          targetId = ((RefMetadata)t).getComponentId();
+        } else if (t instanceof BeanMetadata) { 
+          targetId = ((BeanMetadata)t).getId();
+        }
+        
+        // Our OBR code MUST have access to targetId if it's available (i.e. not null 
+        // or auto-generated for an anonymous service. This must ALWAYS be set. 
+        if (targetId != null && !targetId.startsWith(".")) { // Don't set this for anonymous inner components
+            serviceProps.put("osgi.service.blueprint.compname", targetId);
+          if (serviceName == null || serviceName.equals("") || serviceName.startsWith(".")) { 
+            serviceName = targetId;
+          }
+        }
+        
+        if(serviceName != null && serviceName.startsWith("."))
+          serviceName = null;
+        
+        // If suppressAnonymous services, do not expose services that have no name
+        if (!suppressAnonymousServices || (serviceName != null)) { 
+          ExportedService wsm = ModellingManager.getExportedService(serviceName, ranking, interfaces, serviceProps);
+          result.add(wsm);
+        }
+      }
+    }
+    _logger.debug(LOG_EXIT, "parseAllServiceElements", new Object[]{result});
+    return result; 
+  }
+
+  /**
+   * Extract References metadata from a ComponentDefinitionRegistry. 
+   * @param cdr                       ComponentDefinitionRegistry
+   * @return List<WrappedReferenceMetadata>
+   * @throws InvalidAttributeException 
+   */
+  private List<ImportedService> parseCDRForReferences (ComponentDefinitionRegistry cdr) throws InvalidAttributeException { 
+    _logger.debug(LOG_ENTRY, "parseCDRForReferences", new Object[]{cdr});
+    List<ImportedService> result = new ArrayList<ImportedService>();
+    Set<String> names = cdr.getComponentDefinitionNames();
+    for (String name: names) { 
+      ComponentMetadata compMetadata = cdr.getComponentDefinition(name);
+      if (compMetadata instanceof ServiceReferenceMetadata) { 
+        ServiceReferenceMetadata referenceMetadata = (ServiceReferenceMetadata)compMetadata;
+
+        boolean optional = referenceMetadata.getAvailability() == ServiceReferenceMetadata.AVAILABILITY_OPTIONAL;
+        String iface = referenceMetadata.getInterface();
+        String compName = referenceMetadata.getComponentName();
+        String blueprintFilter = referenceMetadata.getFilter();
+        String id = referenceMetadata.getId();
+        boolean isMultiple = (referenceMetadata instanceof ReferenceListMetadata);
+        
+        //The blueprint parser teams up with JPA and blueprint resource ref
+        // namespace handlers to give us service imports of the form, 
+        // objectClass=javax.persistence.EntityManagerFactory, org.apache.aries.jpa.proxy.factory=*, osgi.unit.name=blabber
+        //
+        // There will be no matching service for this reference. 
+        // For now we blacklist certain objectClasses and filters - this is a pretty dreadful thing to do. 
+        if (isNotBlacklisted (iface, blueprintFilter)) { 
+          ImportedService ref = ModellingManager.getImportedService (optional, iface, compName, blueprintFilter, 
+              id, isMultiple);
+          result.add (ref);  
+        }
+      }
+    }
+    _logger.debug(LOG_EXIT, "parseCDRForReferences", new Object[]{result});
+    return result; 
+  }
+  
+  /**
+   * Some services are injected directly into isolated frameworks by default. We do 
+   * not need to model these services. They are not represented as ExportedServices 
+   * (Capabilities) in the various OBR registries, and so cannot be resolved against. 
+   * Since they are injected directly into each isolated framework, we do not need
+   * an entry in DEPLOYMENT.MF's Deployed-ImportService header for any of these 
+   * services. 
+   * 
+   * @param iface           The interface declared on a blueprint reference
+   * @param blueprintFilter The filter on the blueprint reference
+   * @return                True if the service is not 'blacklisted' and so may be exposed
+   *                        in the model being generated. 
+   */
+  private boolean isNotBlacklisted (String iface, String blueprintFilter) { 
+    _logger.debug(LOG_ENTRY, "isNotBlacklisted", new Object[]{iface, blueprintFilter});
+    boolean blacklisted = false;
+    if (iface != null) {
+      // JPA - detect interface;
+      blacklisted |= iface.equals("javax.persistence.EntityManagerFactory");
+      blacklisted |= iface.equals("javax.persistence.EntityManager");
+    
+      // JTA - detect interface
+      blacklisted |= iface.equals("javax.transaction.UserTransaction");
+      blacklisted |= iface.equals("javax.transaction.TransactionSynchronizationRegistry");
+    }
+    _logger.debug(LOG_EXIT, "isNotBlacklisted", new Object[]{!blacklisted});
+    return !blacklisted;
+  }
+
+ 
+}

Added: incubator/aries/trunk/application/application-deployment-management/src/main/java/org/apache/aries/application/deployment/management/internal/BundleBlueprintParser.java
URL: http://svn.apache.org/viewvc/incubator/aries/trunk/application/application-deployment-management/src/main/java/org/apache/aries/application/deployment/management/internal/BundleBlueprintParser.java?rev=989594&view=auto
==============================================================================
--- incubator/aries/trunk/application/application-deployment-management/src/main/java/org/apache/aries/application/deployment/management/internal/BundleBlueprintParser.java (added)
+++ incubator/aries/trunk/application/application-deployment-management/src/main/java/org/apache/aries/application/deployment/management/internal/BundleBlueprintParser.java Thu Aug 26 10:31:45 2010
@@ -0,0 +1,161 @@
+/*
+ * 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.deployment.management.internal;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.regex.Pattern;
+
+import org.apache.aries.application.utils.manifest.BundleManifest;
+import org.apache.aries.application.utils.manifest.ManifestHeaderProcessor;
+
+/**
+ * A bundle may contain a Bundle-Blueprint: header as per p649 of the v4 spec. If present, 
+ * this denotes where to look for blueprint xml files. We could use Bundle.findEntries() 
+ * to deal with the wildcards that the last entry in the list may contain, but our caller
+ * is introspecting .jar files within an EBA and does not have  access to Bundle objects, 
+ * so we need this extra support. Our caller needs to iterate over the files 
+ * within a jar in each case asking this class, 'is this a blueprint file'?
+ *
+ */
+public class BundleBlueprintParser {
+  
+  public static final String DEFAULT_HEADER = "OSGI-INF/blueprint/*.xml";
+  
+  String _mfHeader = null;
+  List<Path> _paths;
+  
+  static class Path { 
+    String directory;
+    String filename;  // This will either be a simple filename or 'null', in which case filenamePattern will be set
+    Pattern filenamePattern;
+    public Path (String d, String f) { 
+      directory = d;
+      if (f.contains("*")) { 
+        filename = null;
+        String pattern = f.replace(".", "\\.");
+        pattern = pattern.replace("*", ".*");
+        filenamePattern = Pattern.compile(pattern);
+      } else { 
+        filename = f;
+        filenamePattern = null;
+      }
+    }
+    
+    /**
+     * Match this Path object against a specific directory, file pair. Case sensitive. 
+     * @param dir Directory
+     * @param fil Filename - may not contain a wildcard
+     * @return true these match
+     */
+    public boolean matches (String dir, String fil) {
+      boolean match = false;
+      if (!directory.equals(dir)) { 
+        match = false;
+      } else if (filename != null) { 
+        match = (filename.equals(fil));
+      } else { 
+        match = filenamePattern.matcher(fil).matches();
+      }
+      return match;
+    }
+  }
+  
+  /**
+   * BundleBlueprintParser constructor
+   * @param bundleMf BundleManifest to construct the parser from
+   */
+  public BundleBlueprintParser (BundleManifest bundleMf) {
+    String bundleBPHeader = (String) bundleMf.getRawAttributes().getValue("Bundle-Blueprint");
+    setup (bundleBPHeader);
+  }
+
+  /**
+   * BundleBlueprintParser alternative constructor
+   * @param bundleBPHeader Bundle-Blueprint header to construct the parser from
+   */
+  public BundleBlueprintParser (String bundleBPHeader) {
+    setup (bundleBPHeader);
+  }
+  
+  /**
+   * Default constructor
+   */
+  public BundleBlueprintParser () { 
+    setup(null);
+  }
+  
+  private void setup (String bundleBPHeader) { 
+    _paths = new LinkedList <Path>();
+    if (bundleBPHeader == null) { 
+      _mfHeader = DEFAULT_HEADER;
+    } else { 
+      _mfHeader = bundleBPHeader;
+    }
+    
+    // Break this comma separated list up
+    List<String> files = ManifestHeaderProcessor.split(_mfHeader, ",");
+    clauses: for (String fileClause : files) {
+
+      // we could be doing directives, so we split again, the clause can
+      // have multiple paths with directives at the end.
+        
+      List<String> yetMoreFiles = ManifestHeaderProcessor.split(fileClause, ";");
+      for (String f : yetMoreFiles) {
+          
+        // if f has an = in it then we have hit the directive, which must
+        // be at the end, we do not have any directives so we just continue
+        // onto the next clause.
+        if (f.contains("=")) continue clauses;
+          
+        // we need to make sure we have zero spaces here, otherwise stuff may
+        // not be found.
+        f = f.trim();
+        if (f.startsWith("\"") && f.endsWith("\"")) {
+          f = f.substring(1,f.length()-1);
+        }
+          
+        int index = f.lastIndexOf('/');
+        String path = "";
+        String file = f;
+        if (index != -1) {
+          path = f.substring(0, index);
+          file = f.substring(index + 1);
+        }
+        _paths.add(new Path(path, file));
+      }
+    }
+  }  
+ 
+  /**
+   * Iterate through the list of valid file patterns. Return true if this matches against
+   * the header provided to the constructor. We're going to have to be case sensitive. 
+   *  @param directory Directory name
+   *  @param filename File name 
+   *  @return true if this is a blueprint file according to the Bundle-Blueprint header
+   */
+  public boolean isBPFile (String directory, String filename) { 
+    for (Path path: _paths) { 
+      if (path.matches(directory, filename)) { 
+        return true;
+      }
+    }
+    return false;
+  }
+       
+}

Added: incubator/aries/trunk/application/application-deployment-management/src/main/java/org/apache/aries/application/deployment/management/internal/MessageUtil.java
URL: http://svn.apache.org/viewvc/incubator/aries/trunk/application/application-deployment-management/src/main/java/org/apache/aries/application/deployment/management/internal/MessageUtil.java?rev=989594&view=auto
==============================================================================
--- incubator/aries/trunk/application/application-deployment-management/src/main/java/org/apache/aries/application/deployment/management/internal/MessageUtil.java (added)
+++ incubator/aries/trunk/application/application-deployment-management/src/main/java/org/apache/aries/application/deployment/management/internal/MessageUtil.java Thu Aug 26 10:31:45 2010
@@ -0,0 +1,139 @@
+/*
+ * 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.deployment.management.internal;
+
+import java.text.MessageFormat;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.ResourceBundle;
+
+public class MessageUtil
+{
+  /** The resource bundle for blueprint messages */
+  private final static ResourceBundle messages = ResourceBundle.getBundle("org.apache.aries.application.deployment.management.messages.DeploymentManagementMessages");
+  private static class Message {
+    public String msgKey;
+    public Object[] inserts;
+    public Exception cause;
+    
+    public Message(String msgKey, Exception cause, Object[] inserts) {
+      this.msgKey = msgKey;
+      this.cause = cause;
+      this.inserts = inserts;
+    }
+  }
+  
+  private List<Message> errors = new ArrayList<Message>();
+  private List<Message> warnings = new ArrayList<Message>();
+  private final String fileName;
+  
+  public MessageUtil(String fileName) {
+    this.fileName = fileName;
+  }
+  
+  public String getFileName() {
+    return fileName;
+  }
+  
+  public void processMessages()
+  {
+    
+      for (Message m : errors) {
+        //Tr.error(tc, m.msgKey, m.inserts);
+        // use logger
+      }
+    
+
+    
+      for (Message m : warnings) {
+        //Tr.warning(tc, m.msgKey, m.inserts);
+        // use logger
+      }        
+          
+  }
+  
+  public List<String> getErrors()
+  {
+    List<String> result = new ArrayList<String>(warnings.size());
+    for (Message m : warnings) {
+      result.add(MessageFormat.format(messages.getString(m.msgKey), m.inserts));
+    }
+    
+    return result;    
+  }
+  
+  public List<String> getWarnings()
+  {
+    List<String> result = new ArrayList<String>(warnings.size());
+    for (Message m : warnings) {
+      result.add(MessageFormat.format(messages.getString(m.msgKey), m.inserts));
+    }
+    
+    return result;
+  }
+  
+  
+  public void clear() 
+  {
+    errors.clear();
+    warnings.clear();
+  }
+  
+  public boolean hasErrors() 
+  {
+    return !!!errors.isEmpty();
+  }
+  
+  public void error(String msgKey, Object ... inserts) 
+  {
+    errors.add(new Message(msgKey, null, inserts));
+  }
+  
+  public void error(String msgKey, Exception e, Object ... inserts)
+  {
+    errors.add(new Message(msgKey, e, inserts));
+  }
+  
+  public void warning(String msgKey, Object ... inserts)
+  {
+    warnings.add(new Message(msgKey, null, inserts));
+  }
+  
+  public void warning(String msgKey, Exception e, Object ... inserts)
+  {
+    warnings.add(new Message(msgKey, e, inserts));
+  }
+  /**
+   * Resolve a message from the bundle, including any necessary formatting.
+   * 
+   * @param key     the message key.
+   * @param inserts any required message inserts.
+   * @return        the message translated into the server local.
+   */
+  public static final String getMessage(String key, Object ... inserts)
+  {
+    String msg = messages.getString(key);
+    
+    if (inserts.length > 0)
+      msg = MessageFormat.format(msg, inserts);
+    
+    return msg;
+  }
+}

Added: incubator/aries/trunk/application/application-deployment-management/src/main/resources/OSGI-INF/blueprint/deployment-manager.xml
URL: http://svn.apache.org/viewvc/incubator/aries/trunk/application/application-deployment-management/src/main/resources/OSGI-INF/blueprint/deployment-manager.xml?rev=989594&view=auto
==============================================================================
--- incubator/aries/trunk/application/application-deployment-management/src/main/resources/OSGI-INF/blueprint/deployment-manager.xml (added)
+++ incubator/aries/trunk/application/application-deployment-management/src/main/resources/OSGI-INF/blueprint/deployment-manager.xml Thu Aug 26 10:31:45 2010
@@ -0,0 +1,54 @@
+<?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="bluePrintParserProxy" class="org.apache.aries.application.deployment.management.impl.ParserProxyImpl">
+    <property name= "parserService" ref="parser-service"/>
+    <property name="bundleContext" ref="blueprintBundleContext"/>
+  </bean>
+  <reference id="parser-service" interface="org.apache.aries.blueprint.ParserService"/>
+  
+  
+  <bean id="modelledResourceManager" class="org.apache.aries.application.deployment.management.impl.ModelledResourceManagerImpl">
+    <property name ="parserProxy" ref="bluePrintParserProxy"/>
+  </bean>
+  
+  <service id = "modelledResourceManagerService" ref="modelledResourceManager" interface="org.apache.aries.application.modelling.ModelledResourceManager"/>
+  
+  <bean id="deploymentManifestManager" class="org.apache.aries.application.deployment.management.impl.DeploymentManifestManagerImpl">
+    <property name="resolver" ref="resolver"/>
+    <property name="postResolveTransformers" ref="post-resolver-transformers"/>
+    <property name="modelledResourceManager" ref = "modelledResourceManager"/>
+    <property name="localPlatform" ref="localPlatform"/>
+  </bean>
+  
+  
+  <reference id="localPlatform" interface="org.apache.aries.application.management.LocalPlatform"/>
+  <reference id="resolver" interface="org.apache.aries.application.management.AriesApplicationResolver"/>
+  <reference-list id="post-resolver-transformers" interface="org.apache.aries.application.PostResolveTransformer" availability="optional"/>
+  
+  <service id ="deploymentManifestManager-Service" ref="deploymentManifestManager" interface="org.apache.aries.application.management.DeploymentManifestManager"/>
+  
+  <service id="parserProxyService" ref="bluePrintParserProxy">
+    <interfaces>
+      <value>org.apache.aries.application.modelling.ParserProxy</value>
+    </interfaces>
+  </service>
+</blueprint>
\ No newline at end of file

Added: incubator/aries/trunk/application/application-deployment-management/src/main/resources/org/apache/aries/application/deployment/management/messages/DeploymentManagementMessages.properties
URL: http://svn.apache.org/viewvc/incubator/aries/trunk/application/application-deployment-management/src/main/resources/org/apache/aries/application/deployment/management/messages/DeploymentManagementMessages.properties?rev=989594&view=auto
==============================================================================
--- incubator/aries/trunk/application/application-deployment-management/src/main/resources/org/apache/aries/application/deployment/management/messages/DeploymentManagementMessages.properties (added)
+++ incubator/aries/trunk/application/application-deployment-management/src/main/resources/org/apache/aries/application/deployment/management/messages/DeploymentManagementMessages.properties Thu Aug 26 10:31:45 2010
@@ -0,0 +1,46 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+SHARED_BUNDLE_IMPORTING_FROM_ISOLATED_BUNDLE=Shared bundle {0} has a dependency for package {1} which is exported from isolated bundle {2}
+SHARED_BUNDLE_IMPORTING_FROM_ISOLATED_BUNDLES=Shared bundle {0} has a dependency for package {1} which is exported from isolated bundles {2} 
+
+
+SUSPECTED_CIRCULAR_DEPENDENCIES=Resolution of asset {0} indicates invalid dependencies of shared content on isolated content: {1} 
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+SHARED_BUNDLE_IMPORTING_FROM_ISOLATED_BUNDLE=Shared bundle {0} has a dependency for package {1} which is exported from isolated bundle {2}
+SHARED_BUNDLE_IMPORTING_FROM_ISOLATED_BUNDLES=Shared bundle {0} has a dependency for package {1} which is exported from isolated bundles {2} 
+
+
+SUSPECTED_CIRCULAR_DEPENDENCIES=Resolution of asset {0} indicates invalid dependencies of shared content on isolated content: {1} 



Mime
View raw message