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 21:20:30 UTC
svn commit: r1075132 [9/18] - in /aries/tags/application-0.3: ./
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/ application-api...
Added: aries/tags/application-0.3/application-modeller/src/main/java/org/apache/aries/application/modelling/impl/DeployedBundlesImpl.java
URL: http://svn.apache.org/viewvc/aries/tags/application-0.3/application-modeller/src/main/java/org/apache/aries/application/modelling/impl/DeployedBundlesImpl.java?rev=1075132&view=auto
==============================================================================
--- aries/tags/application-0.3/application-modeller/src/main/java/org/apache/aries/application/modelling/impl/DeployedBundlesImpl.java (added)
+++ aries/tags/application-0.3/application-modeller/src/main/java/org/apache/aries/application/modelling/impl/DeployedBundlesImpl.java Sun Feb 27 20:20:13 2011
@@ -0,0 +1,477 @@
+/*
+ * 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.modelling.impl;
+
+import static org.apache.aries.application.utils.AppConstants.LOG_ENTRY;
+import static org.apache.aries.application.utils.AppConstants.LOG_EXIT;
+
+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 org.apache.aries.application.management.ResolverException;
+import org.apache.aries.application.modelling.DeployedBundles;
+import org.apache.aries.application.modelling.DeploymentMFElement;
+import org.apache.aries.application.modelling.ExportedBundle;
+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.ImportedService;
+import org.apache.aries.application.modelling.ModelledResource;
+import org.apache.aries.application.modelling.internal.MessageUtil;
+import org.apache.aries.application.modelling.internal.PackageRequirementMerger;
+import org.apache.aries.application.utils.AppConstants;
+import org.osgi.framework.Constants;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+/**
+ * Class to generate DEPLOYMENT.MF manifest entries for resolved bundles based on
+ * corresponding APPLICATION.MF entries.
+ */
+public final class DeployedBundlesImpl implements DeployedBundles
+{
+ private final Logger logger = LoggerFactory.getLogger(DeployedBundlesImpl.class);
+ private final String assetName;
+
+ /** Content from APPLICATION.MF */
+ private final Set<ImportedBundle> appContent = new HashSet<ImportedBundle>();
+ /** Use Bundle from APPLICATION.MF */
+ private final Set<ImportedBundle> appUseBundle = new HashSet<ImportedBundle>();
+ /** Content for deployment.mf deployed-content. */
+ private final Set<ModelledResource> deployedContent = new HashSet<ModelledResource>();
+ /** Content for deployment.mf use-bundle. */
+ private final Set<ModelledResource> deployedUseBundle = new HashSet<ModelledResource>();
+ /** Content for deployment.mf provision-bundle. */
+ private final Set<ModelledResource> deployedProvisionBundle = new HashSet<ModelledResource>();
+ /** Content for deployment.mf DeployedImport-Service. */
+ private final Collection<ImportedService> deployedImportService = new HashSet<ImportedService>();
+ private final Collection<ModelledResource> fakeDeployedBundles = new HashSet<ModelledResource>();
+
+ /**
+ * Constructor for cases when we have one or more '
+ * @param assetName the name of the asset being deployed.
+ * @param appContentNames the bundle names specified in Deployed-Content.
+ * @param appUseBundleNames the bundle names specified in Deployed-Use-Bundle.
+ * @param fakeServiceProvidingBundles bundles that we're pretending are part of the deployed content. Can be null.
+ * These bundles are proxies for bundles provided (for example by SCA) that export
+ * services matching Application-ImportService.
+ */
+ public DeployedBundlesImpl(String assetName, Collection<ImportedBundle> appContentNames,
+ Collection<ImportedBundle> appUseBundleNames, Collection<ModelledResource> fakeServiceProvidingBundles)
+ {
+ logger.debug(LOG_ENTRY, "DeployedBundles", new Object[]{appContentNames, appUseBundleNames, fakeServiceProvidingBundles});
+
+ this.assetName = assetName;
+
+ appContent.addAll(appContentNames);
+ appUseBundle.addAll(appUseBundleNames);
+ if (fakeServiceProvidingBundles != null) {
+ fakeDeployedBundles.addAll(fakeServiceProvidingBundles);
+ }
+ logger.debug(LOG_EXIT, "DeployedBundles");
+ }
+
+ /**
+ * Add provisioned version information for a specific bundle name. This will be added to the
+ * appropriate manifest header for the specified bundle.
+ * @param resolvedBundle the bundle that has been provisioned.
+ * @param resolvedVersion the specific version provisioned.
+ */
+ @Override
+ public void addBundle(ModelledResource modelledBundle)
+ {
+ logger.debug(LOG_ENTRY, "addBundle", new Object[]{modelledBundle});
+ // Identify the deployment.mf entries the bundle should be added to by matching
+ // both the bundle name and resolved version against the name and version range
+ // defined in application.mf.
+
+ ExportedBundle resolvedBundle = modelledBundle.getExportedBundle();
+
+ if (isBundleMatch(appContent, resolvedBundle))
+ {
+ logger.debug("Added to " + AppConstants.DEPLOYMENT_CONTENT + ": " + resolvedBundle);
+
+ deployedContent.add(modelledBundle);
+
+ // Add any service dependencies to the list
+ deployedImportService.addAll(modelledBundle.getImportedServices());
+ }
+ else if (isBundleMatch(appUseBundle, resolvedBundle))
+ {
+ logger.debug("Added to " + AppConstants.DEPLOYMENT_USE_BUNDLE + ": " + resolvedBundle);
+ deployedUseBundle.add(modelledBundle);
+ } else
+ {
+ logger.debug("Added to " + AppConstants.DEPLOYMENT_PROVISION_BUNDLE + ": " + resolvedBundle);
+ deployedProvisionBundle.add(modelledBundle);
+ }
+ logger.debug(LOG_EXIT, "addBundle");
+ }
+
+ /**
+ * Check if a match is found between the supplied map of application bundle name/version information,
+ * and the supplied bundle name and version.
+ * @param imports Imported bundles
+ * @param potentialMatch the exported bundle or composite we're interested in
+ * @return true if a match is found; otherwise false.
+ */
+ private boolean isBundleMatch(Set<ImportedBundle> imports, ExportedBundle potentialMatch)
+ {
+ boolean result = false;
+
+ for (ImportedBundle ib : imports)
+ {
+ if (ib.isSatisfied(potentialMatch))
+ {
+ result = true;
+ break;
+ }
+ }
+
+ return result;
+ }
+
+ /**
+ * Get the value corresponding to the Deployed-Content header in the deployment.mf.
+ * @return a manifest entry, or an empty string if there is no content.
+ */
+ @Override
+ public String getContent()
+ {
+ return createManifestString(deployedContent);
+ }
+
+ /**
+ * Get the value corresponding to the Deployed-Use-Bundle header in the deployment.mf.
+ * @return a manifest entry, or an empty string if there is no content.
+ */
+ @Override
+ public String getUseBundle()
+ {
+ return createManifestString(deployedUseBundle);
+ }
+
+ /**
+ * Get the value corresponding to the Provision-Bundle header in the deployment.mf.
+ * @return a manifest entry, or an empty string if there is no content.
+ */
+ @Override
+ public String getProvisionBundle()
+ {
+ return createManifestString(deployedProvisionBundle);
+ }
+
+ /**
+ * Get the value corresponding to the Import-Package header in the deployment.mf.
+ * @return a manifest entry, or an empty string if there is no content.
+ * @throws ResolverException if the requirements could not be resolved.
+ */
+ @Override
+ public String getImportPackage() throws ResolverException
+ {
+ logger.debug(LOG_ENTRY, "getImportPackage");
+ Collection<ImportedPackage> externalReqs = new ArrayList<ImportedPackage>(getExternalPackageRequirements());
+
+ //Validate that we don't have attributes that will break until RFC138 is used
+ validateOtherImports(externalReqs);
+
+ // Find the matching capabilities from bundles in use bundle, and prune
+ // matched requirements out of the external requirements collection.
+ Map<ImportedPackage,ExportedPackage> useBundlePkgs = new HashMap<ImportedPackage,ExportedPackage>();
+ for (Iterator<ImportedPackage> iter = externalReqs.iterator(); iter.hasNext(); )
+ {
+ ImportedPackage req = iter.next();
+ ExportedPackage match = getPackageMatch(req, deployedUseBundle);
+ if (match != null)
+ {
+ useBundlePkgs.put(req, match);
+ iter.remove();
+ }
+ }
+
+
+ StringBuilder useBundleImports = new StringBuilder();
+ for(Map.Entry<ImportedPackage, ExportedPackage> entry : useBundlePkgs.entrySet()) {
+ useBundleImports.append(entry.getValue().toDeploymentString());
+ ImportedPackage key = entry.getKey();
+ if(key.isOptional())
+ useBundleImports.append(";" + Constants.RESOLUTION_DIRECTIVE +":=" + Constants.RESOLUTION_OPTIONAL);
+ useBundleImports.append(",");
+ }
+
+ String result = useBundleImports.toString() + createManifestString(externalReqs);
+
+ if(result.endsWith(","))
+ result = result.substring(0, result.length() - 1);
+ logger.debug(LOG_EXIT, "getImportPackage", result);
+ return result;
+ }
+
+ /**
+ * Get the Deployed-ImportService header.
+ * this.deployedImportService contains all the service import filters for every
+ * blueprint component within the application. We will only write an entry
+ * to Deployed-ImportService if
+ * a) the reference isMultiple(), or
+ * b) the service was not available internally when the app was first deployed
+ *
+ */
+ @Override
+ public String getDeployedImportService() {
+ logger.debug(LOG_ENTRY,"getDeployedImportService");
+ Collection<ImportedService> deployedBundleServiceImports = new ArrayList<ImportedService>();
+ Collection<ExportedService> servicesExportedWithinIsolatedContent = new ArrayList<ExportedService>();
+ for (ModelledResource mRes : getDeployedContent()) {
+ servicesExportedWithinIsolatedContent.addAll(mRes.getExportedServices());
+ }
+ for (ModelledResource mRes : fakeDeployedBundles) {
+ servicesExportedWithinIsolatedContent.addAll(mRes.getExportedServices());
+ }
+ for (ImportedService impService : deployedImportService) {
+ if (impService.isMultiple()) {
+ deployedBundleServiceImports.add(impService);
+ } else {
+ boolean serviceProvidedWithinIsolatedContent = false;
+ Iterator<ExportedService> it = servicesExportedWithinIsolatedContent.iterator();
+ while (!serviceProvidedWithinIsolatedContent && it.hasNext()) {
+ ExportedService svc = it.next();
+ serviceProvidedWithinIsolatedContent |= impService.isSatisfied(svc);
+ }
+ if (!serviceProvidedWithinIsolatedContent) {
+ deployedBundleServiceImports.add(impService);
+ }
+ }
+ }
+
+ String result = createManifestString(deployedBundleServiceImports);
+ logger.debug(LOG_EXIT,"getDeployedImportService", result);
+
+ return result;
+ }
+ /**
+ * Get all the requirements of bundles in deployed content that are not satisfied
+ * by other bundles in deployed content.
+ * @return a collection of package requirements.
+ * @throws ResolverException if the requirements could not be resolved.
+ */
+ private Collection<ImportedPackage> getExternalPackageRequirements()
+ throws ResolverException
+ {
+ logger.debug(LOG_ENTRY,"getExternalPackageRequirements");
+
+ // Get all the internal requirements.
+ Collection<ImportedPackage> requirements = new ArrayList<ImportedPackage>();
+ for (ModelledResource bundle : deployedContent)
+ {
+ requirements.addAll(bundle.getImportedPackages());
+ }
+
+ // Filter out requirements satisfied by internal capabilities.
+ Collection<ImportedPackage> result = new ArrayList<ImportedPackage>();
+ for (ImportedPackage req : requirements)
+ {
+ ExportedPackage match = getPackageMatch(req, deployedContent);
+ //If we didn't find a match then it must come from outside
+ if (match == null)
+ {
+ result.add(req);
+ }
+ }
+
+ PackageRequirementMerger merger = new PackageRequirementMerger(result);
+ if (!merger.isMergeSuccessful())
+ {
+ List<String> pkgNames = new ArrayList<String>(merger.getInvalidRequirements());
+
+ StringBuilder buff = new StringBuilder();
+ for (String pkgName : merger.getInvalidRequirements())
+ {
+ buff.append(pkgName).append(", ");
+ }
+
+ int buffLen = buff.length();
+ String pkgString = (buffLen > 0 ? buff.substring(0, buffLen - 2) : "");
+
+ ResolverException re = new ResolverException(MessageUtil.getMessage(
+ "INCOMPATIBLE_PACKAGE_VERSION_REQUIREMENTS", new Object[] { assetName, pkgString }));
+ re.setUnsatisfiedRequirements(pkgNames);
+ logger.debug(LOG_EXIT,"getExternalPackageRequirements", re);
+
+ throw re;
+ }
+
+ result = merger.getMergedRequirements();
+ logger.debug(LOG_EXIT,"getExternalPackageRequirements", result);
+
+ return result;
+ }
+
+ /**
+ * Create entries for the Import-Package header corresponding to the supplied
+ * packages, referring to bundles not in Use-Bundle.
+ * @param requirements packages for which entries should be created.
+ * @return manifest header entries.
+ * @throws ResolverException if the imports are invalid.
+ */
+ private void validateOtherImports(Collection<ImportedPackage> requirements)
+ throws ResolverException
+ {
+ logger.debug(LOG_ENTRY, "validateOtherImports", requirements);
+ for (ImportedPackage req : requirements)
+ {
+ String pkgName = req.getPackageName();
+
+ for (String name : req.getAttributes().keySet())
+ {
+ if (Constants.BUNDLE_SYMBOLICNAME_ATTRIBUTE.equals(name)
+ || Constants.BUNDLE_VERSION_ATTRIBUTE.equals(name))
+ {
+ ResolverException re = new ResolverException(MessageUtil.getMessage(
+ "INVALID_PACKAGE_REQUIREMENT_ATTRIBUTES", new Object[] { assetName, name, pkgName }));
+ re.setUnsatisfiedRequirements(Arrays.asList(pkgName));
+ logger.debug(LOG_EXIT, "validateOtherImports", re);
+ throw re;
+ }
+ }
+ }
+ logger.debug(LOG_EXIT, "validateOtherImports");
+ }
+
+ /**
+ * Get a package match between the specified requirement and a capability of the supplied
+ * bundles. The resulting match object might not refer to any matching capability.
+ * @param requirement the {@link ImportedPackageImpl} to be matched.
+ * @param bundles the bundles to be searched for matching capabilities.
+ * @return an ExportedPackageImpl or null if no match is found.
+ */
+ private ExportedPackage getPackageMatch(ImportedPackage requirement, Collection<ModelledResource> bundles)
+ {
+ logger.debug(LOG_ENTRY, "getPackageMatch", new Object[]{requirement, bundles});
+ ExportedPackage result = null;
+
+ outer: for (ModelledResource bundle : bundles)
+ {
+ for (ExportedPackage pkg : bundle.getExportedPackages())
+ {
+ if(requirement.isSatisfied(pkg)) {
+ result = pkg;
+ break outer;
+ }
+ }
+ }
+ logger.debug(LOG_EXIT, "getPackageMatch", new Object[]{result});
+ return result;
+ }
+
+ private String createManifestString(Collection<? extends DeploymentMFElement> values)
+ {
+ logger.debug(LOG_ENTRY, "createManifestString", new Object[]{values});
+ StringBuilder builder = new StringBuilder();
+ for (DeploymentMFElement value : values)
+ {
+ builder.append(value.toDeploymentString()).append(",");
+ }
+
+ int length = builder.length();
+ String result = (length > 0 ? builder.substring(0, length - 1) : "");
+ logger.debug(LOG_EXIT, "createManifestString", new Object[]{result});
+ return result;
+ }
+
+
+ @Override
+ public String toString()
+ {
+ return AppConstants.DEPLOYMENT_CONTENT + '=' + deployedContent + ' ' +
+ AppConstants.DEPLOYMENT_USE_BUNDLE + '=' + deployedUseBundle + ' ' +
+ AppConstants.DEPLOYMENT_PROVISION_BUNDLE + '=' + deployedProvisionBundle;
+ }
+
+ /**
+ * Get the set of bundles that are going to be deployed into an isolated framework
+ * @return a set of bundle metadata
+ */
+ @Override
+ public Collection<ModelledResource> getDeployedContent()
+ {
+ logger.debug(LOG_ENTRY, "getDeployedContent");
+ logger.debug(LOG_EXIT,"getDeployedContent", deployedContent);
+ return Collections.unmodifiableCollection(deployedContent);
+ }
+
+ /**
+ * Get the set of bundles that map to Provision-Bundle: these plus
+ * getRequiredUseBundle combined give the bundles that will be provisioned
+ * into the shared bundle space
+ * 'getProvisionBundle' returns the manifest header string, so this method
+ * needs to be called something else.
+ *
+ */
+ @Override
+ public Collection<ModelledResource> getDeployedProvisionBundle ()
+ {
+ logger.debug(LOG_ENTRY,"getDeployedProvisionBundle");
+ logger.debug(LOG_EXIT, "getDeployedProvisionBundle", deployedContent);
+ return Collections.unmodifiableCollection(deployedProvisionBundle);
+ }
+
+ /**
+ * Get the subset of bundles specified in use-bundle that are actually required to
+ * satisfy direct requirements of deployed content.
+ * @return a set of bundle metadata.
+ * @throws ResolverException if the requirements could not be resolved.
+ */
+ @Override
+ public Collection<ModelledResource> getRequiredUseBundle() throws ResolverException
+ {
+ logger.debug(LOG_ENTRY, "getRequiredUseBundle");
+ Collection<ImportedPackage> externalReqs = getExternalPackageRequirements();
+ Collection<ModelledResource> usedUseBundles = new HashSet<ModelledResource>();
+ for (ImportedPackage req : externalReqs)
+ {
+ // Find a match from the supplied bundle capabilities.
+ ExportedPackage match = getPackageMatch(req, deployedUseBundle);
+ if (match != null)
+ {
+ usedUseBundles.add(match.getBundle());
+ }
+ }
+ logger.debug(LOG_EXIT, "getRequiredUseBundle", usedUseBundles);
+ return usedUseBundles;
+ }
+
+ /** This method will be overridden by a PostResolveTransformer returning an extended version of
+ * DeployedBundles
+ */
+ @Override
+ public Map<String, String> getExtraHeaders() {
+ logger.debug (LOG_ENTRY, "getExtraHeaders");
+ Map<String, String> result = Collections.emptyMap();
+ logger.debug (LOG_EXIT, "getExtraHeaders", result);
+ return result;
+ }
+}
Added: aries/tags/application-0.3/application-modeller/src/main/java/org/apache/aries/application/modelling/impl/ExportedBundleImpl.java
URL: http://svn.apache.org/viewvc/aries/tags/application-0.3/application-modeller/src/main/java/org/apache/aries/application/modelling/impl/ExportedBundleImpl.java?rev=1075132&view=auto
==============================================================================
--- aries/tags/application-0.3/application-modeller/src/main/java/org/apache/aries/application/modelling/impl/ExportedBundleImpl.java (added)
+++ aries/tags/application-0.3/application-modeller/src/main/java/org/apache/aries/application/modelling/impl/ExportedBundleImpl.java Sun Feb 27 20:20:13 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 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.modelling.impl;
+
+import static org.apache.aries.application.utils.AppConstants.LOG_ENTRY;
+import static org.apache.aries.application.utils.AppConstants.LOG_EXIT;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.jar.Attributes;
+
+import org.apache.aries.application.InvalidAttributeException;
+import org.apache.aries.application.modelling.ImportedBundle;
+import org.apache.aries.application.modelling.ModellingConstants;
+import org.apache.aries.application.modelling.internal.MessageUtil;
+import org.apache.aries.application.modelling.utils.impl.ModellingHelperImpl;
+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;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * An exported bundle: one that I have and make available.
+ */
+public class ExportedBundleImpl extends AbstractExportedBundle
+{
+ private static final Logger logger = LoggerFactory.getLogger(ExportedBundleImpl.class);
+ private final Map<String, Object> _attributes;
+ private final ImportedBundle _fragHost;
+
+ /**
+ * Construct an ExportedBundleImpl from a processed Manifest
+ * @param attrs
+ * @throws InvalidAttributeException
+ */
+ public ExportedBundleImpl (Attributes attrs) throws InvalidAttributeException {
+ logger.debug(LOG_ENTRY, "ExportedBundleImpl", attrs);
+ String symbolicName = attrs.getValue(Constants.BUNDLE_SYMBOLICNAME);
+
+ Map<String,NameValueMap<String, String>> map = ManifestHeaderProcessor.parseImportString(symbolicName);
+
+ //This should have one entry, which is keyed on the symbolicName
+
+ if(map.size() != 1) {
+ InvalidAttributeException iax = new InvalidAttributeException (MessageUtil.getMessage(
+ "TOO_MANY_SYM_NAMES", new Object[] {symbolicName}));
+ logger.debug(LOG_EXIT, "ExportedBundleImpl", iax);
+ throw iax;
+ }
+
+ Map.Entry<String, NameValueMap<String, String>> entry = map.entrySet().iterator().next();
+
+ symbolicName = entry.getKey();
+
+ Map<String, String> bundleAttrs = entry.getValue();
+
+ String displayName = attrs.getValue(Constants.BUNDLE_NAME);
+ String version = attrs.getValue(Constants.BUNDLE_VERSION);
+ if (version == null) {
+ version = Version.emptyVersion.toString();
+ }
+ String bmVersion = attrs.getValue(Constants.BUNDLE_MANIFESTVERSION);
+ if (symbolicName == null || bmVersion == null) {
+ InvalidAttributeException iax = new InvalidAttributeException(MessageUtil.getMessage("INCORRECT_MANDATORY_HEADERS",
+ new Object[] {symbolicName, bmVersion}));
+ logger.debug(LOG_EXIT, "ExportedBundleImpl", iax);
+ throw iax;
+ }
+
+ if(bundleAttrs != null)
+ _attributes = new HashMap<String, Object>(entry.getValue());
+ else
+ _attributes = new HashMap<String, Object>();
+
+ _attributes.put (Constants.BUNDLE_MANIFESTVERSION, bmVersion);
+ _attributes.put(ModellingConstants.OBR_SYMBOLIC_NAME, symbolicName);
+ _attributes.put (Constants.VERSION_ATTRIBUTE, version);
+
+ if(displayName != null)
+ _attributes.put(ModellingConstants.OBR_PRESENTATION_NAME, displayName);
+
+ String fragmentHost = attrs.getValue(Constants.FRAGMENT_HOST);
+ if (fragmentHost != null) {
+ _fragHost = ModellingHelperImpl.buildFragmentHost_(fragmentHost);
+ _attributes.put(Constants.FRAGMENT_HOST, fragmentHost);
+ } else {
+ _fragHost = null;
+ }
+ logger.debug(LOG_EXIT, "ExportedBundleImpl");
+ }
+
+ /**
+ * Construct a bundle from attributes and a fragment host
+ * @param attributes attributes describing the bundle
+ * @param fragHost may be null if this bundle is not a fragment
+ */
+ public ExportedBundleImpl(Map<String, String> attributes, ImportedBundle fragHost) {
+ logger.debug(LOG_ENTRY, "ExportedBundleImpl", new Object[]{attributes, fragHost});
+ _attributes = new HashMap<String, Object>(attributes);
+ _fragHost = fragHost;
+ logger.debug(LOG_EXIT, "ExportedBundleImpl", new Object[]{attributes, fragHost});
+ }
+
+
+ public Map<String, Object> getAttributes() {
+ logger.debug(LOG_ENTRY, "getAttributes");
+ logger.debug(LOG_EXIT, "getAttributes", new Object[]{_attributes});
+ return Collections.unmodifiableMap(_attributes);
+ }
+
+
+ public String toString() {
+ return _attributes.toString();
+ }
+
+
+ public ImportedBundle getFragmentHost() {
+ logger.debug(LOG_ENTRY, "getFragmentHost");
+ logger.debug(LOG_EXIT, "getFragmentHost", new Object[]{_fragHost});
+ return _fragHost;
+ }
+
+
+ public boolean isFragment() {
+ logger.debug(LOG_ENTRY, "isFragment");
+ boolean result = _fragHost != null;
+ logger.debug(LOG_EXIT, "isFragment", new Object[]{result});
+ return result;
+ }
+}
Added: aries/tags/application-0.3/application-modeller/src/main/java/org/apache/aries/application/modelling/impl/ExportedPackageImpl.java
URL: http://svn.apache.org/viewvc/aries/tags/application-0.3/application-modeller/src/main/java/org/apache/aries/application/modelling/impl/ExportedPackageImpl.java?rev=1075132&view=auto
==============================================================================
--- aries/tags/application-0.3/application-modeller/src/main/java/org/apache/aries/application/modelling/impl/ExportedPackageImpl.java (added)
+++ aries/tags/application-0.3/application-modeller/src/main/java/org/apache/aries/application/modelling/impl/ExportedPackageImpl.java Sun Feb 27 20:20:13 2011
@@ -0,0 +1,157 @@
+/*
+ * 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.modelling.impl;
+import static org.apache.aries.application.utils.AppConstants.LOG_ENTRY;
+import static org.apache.aries.application.utils.AppConstants.LOG_EXIT;
+import static org.apache.aries.application.modelling.ResourceType.PACKAGE;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.aries.application.modelling.ExportedPackage;
+import org.apache.aries.application.modelling.ModelledResource;
+import org.apache.aries.application.modelling.ResourceType;
+import org.osgi.framework.Constants;
+import org.osgi.framework.Version;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+
+
+public class ExportedPackageImpl implements ExportedPackage
+{
+
+ @SuppressWarnings("deprecation")
+ private static final String PACKAGE_SPECIFICATION_VERSION = Constants.PACKAGE_SPECIFICATION_VERSION;
+ private final Map<String, Object> _attributes;
+ private final String _packageName;
+ private final String _version;
+ private final ModelledResource _bundle;
+ private final Logger logger = LoggerFactory.getLogger(ExportedPackageImpl.class);
+ /**
+ *
+ * @param mr The {@link ModelledResource} exporting this package. Never null.
+ * @param pkg The fully qualified name of the package being exported
+ * @param attributes The package attributes. If no version is present, will be defaulted to 0.0.0.
+ *
+ */
+ public ExportedPackageImpl (ModelledResource mr, String pkg, Map<String, Object> attributes) {
+ logger.debug(LOG_ENTRY, "ExportedPackageImpl", new Object[]{mr, pkg, attributes});
+ _attributes = new HashMap<String, Object> (attributes);
+ _packageName = pkg;
+ _attributes.put (PACKAGE.toString(), _packageName);
+ String version = (String) attributes.get(Constants.VERSION_ATTRIBUTE);
+ if (version == null || "".equals(version)) {
+ _version = Version.emptyVersion.toString();
+ } else {
+ _version = version;
+ }
+ _attributes.put(Constants.VERSION_ATTRIBUTE, _version);
+ _attributes.put (Constants.BUNDLE_SYMBOLICNAME_ATTRIBUTE, mr.getSymbolicName());
+ _attributes.put (Constants.BUNDLE_VERSION_ATTRIBUTE, mr.getVersion());
+ _bundle = mr;
+ logger.debug(LOG_EXIT, "ExportedPackageImpl");
+ }
+
+
+ public Map<String, Object> getAttributes() {
+ logger.debug(LOG_ENTRY, "getAttributes");
+ logger.debug(LOG_EXIT, "getAttributes", _attributes);
+ return Collections.unmodifiableMap(_attributes);
+ }
+
+
+ public ResourceType getType() {
+ logger.debug(LOG_ENTRY, "getType");
+ logger.debug(LOG_EXIT, "getType", PACKAGE);
+ return PACKAGE;
+ }
+
+ /**
+ * Get the name of the exported package
+ * @return package name
+ */
+ public String getPackageName() {
+ logger.debug(LOG_ENTRY, "getPackageName");
+ logger.debug(LOG_EXIT, "getPackageName", _packageName);
+ return _packageName;
+ }
+
+ /**
+ * This will never be null.
+ * @return Version as String, or 0.0.0
+ */
+ public String getVersion() {
+ logger.debug(LOG_ENTRY, "getVersion");
+ logger.debug(LOG_EXIT, "getVersion", _version);
+ return _version;
+ }
+
+ /**
+ * This method turns an {@link ExportedPackageImpl} into a string suitable for a
+ * Use-Bundle style package import. We do NOT lock down package versions, only bundle versions.
+ */
+ public String toDeploymentString() {
+ logger.debug(LOG_ENTRY, "toDeploymentString");
+ StringBuilder sb = new StringBuilder(_packageName);
+ for (Map.Entry<String, Object> entry : _attributes.entrySet()) {
+ String key = entry.getKey();
+ Object objectValue = entry.getValue();
+ // While attributes can be arrays, especially for services, they should never be arrays for packages
+ // If the values are not arrays, they are Strings
+ if (!objectValue.getClass().isArray()) {
+ String value = String.valueOf(objectValue);
+ if (key != null && !key.equals(PACKAGE.toString())
+ && !key.equals(PACKAGE_SPECIFICATION_VERSION))
+ {
+ if (key.equals(Constants.BUNDLE_VERSION_ATTRIBUTE)) {
+ value = "[" + value + "," + value + "]";
+ }
+ // No Export-Package directives are valid on Import-Package, so strip out all
+ // directives. Never print out a null or empty key or value.
+ if (key.equals("") || key.endsWith(":") || value==null || value.equals("")) {
+
+ logger.debug("ExportedPackageImpl.toDeploymentString ignored " + key + "=" + value);
+ } else {
+ sb.append (";").append (key).append("=\"").append(value).append('"');
+ }
+ } else {
+ logger.debug("ExportedPackageImpl.toDeploymentString() ignoring attribute " + key + "->" + value);
+ }
+ }
+ }
+ String result = sb.toString();
+ logger.debug(LOG_EXIT, "toDeploymentString", result);
+ return result;
+ }
+
+ public ModelledResource getBundle() {
+ logger.debug(LOG_ENTRY, "getBundle");
+ logger.debug(LOG_EXIT, "getBundle", _bundle);
+ return _bundle;
+ }
+
+ @Override
+ public String toString() {
+ return toDeploymentString();
+ }
+
+}
Added: aries/tags/application-0.3/application-modeller/src/main/java/org/apache/aries/application/modelling/impl/ExportedServiceImpl.java
URL: http://svn.apache.org/viewvc/aries/tags/application-0.3/application-modeller/src/main/java/org/apache/aries/application/modelling/impl/ExportedServiceImpl.java?rev=1075132&view=auto
==============================================================================
--- aries/tags/application-0.3/application-modeller/src/main/java/org/apache/aries/application/modelling/impl/ExportedServiceImpl.java (added)
+++ aries/tags/application-0.3/application-modeller/src/main/java/org/apache/aries/application/modelling/impl/ExportedServiceImpl.java Sun Feb 27 20:20:13 2011
@@ -0,0 +1,281 @@
+/*
+ * 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.modelling.impl;
+
+import static org.apache.aries.application.utils.AppConstants.LOG_ENTRY;
+import static org.apache.aries.application.utils.AppConstants.LOG_EXIT;
+
+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.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeSet;
+
+import org.apache.aries.application.modelling.ExportedService;
+import org.apache.aries.application.modelling.ModellingConstants;
+import org.apache.aries.application.modelling.ResourceType;
+import org.apache.aries.application.modelling.WrappedServiceMetadata;
+import org.osgi.framework.Constants;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * A service exported by a bundle. Provides an entry to DEPLOYMENT.MF
+ */
+public class ExportedServiceImpl implements ExportedService
+{
+ private final Logger logger = LoggerFactory.getLogger(ExportedServiceImpl.class);
+ private final Map<String, Object> _attributes;
+ private final Collection<String> _interfaces;
+ private final Map<String, Object> _serviceProperties;
+ private final String _name;
+ private final int _ranking;
+ private String _toString = null;
+
+ /**
+ * Constructor.
+ * @param name "" will be changed to null
+ * @param ranking Service ranking
+ * @param ifaces Interfaces offered by the service
+ * @param serviceProperties Service properties.
+ * We expect that osgi.service.blueprint.compname has been set if possible
+ */
+ public ExportedServiceImpl (String name, int ranking, Collection<String> ifaces,
+ Map<String, Object> serviceProperties )
+ {
+
+ logger.debug(LOG_ENTRY,"ExportedServiceImpl", new Object[]{name, ranking, ifaces});
+ _interfaces = new TreeSet<String>(ifaces);
+ if (!"".equals(name)) {
+ _name = name;
+ } else {
+ _name = null;
+ }
+ _ranking = ranking;
+ if (serviceProperties == null) {
+ _serviceProperties = new HashMap<String, Object>();
+ } else {
+ _serviceProperties = new HashMap<String, Object>(serviceProperties);
+ }
+
+ // Construct _attributes
+ _attributes = new HashMap<String, Object>(_serviceProperties);
+
+ // Turn interfaces into a comma separated String
+ StringBuilder sb = new StringBuilder();
+ for (String i : _interfaces) {
+ sb.append(i + ",");
+ }
+ sb = sb.deleteCharAt(sb.length()-1);
+ _attributes.put(Constants.OBJECTCLASS, sb.toString());
+ _attributes.put (Constants.SERVICE_RANKING, String.valueOf(_ranking));
+ _attributes.put(ModellingConstants.OBR_SERVICE, ModellingConstants.OBR_SERVICE);
+ logger.debug(LOG_EXIT,"ExportedServiceImpl");
+ }
+
+ /**
+ * This constructor is for building ExportedServices from Export-Service manifest headers,
+ * which are deprecated in OSGi.
+ * @param ifaceName
+ * @param attrs
+ */
+ @Deprecated
+ public ExportedServiceImpl (String ifaceName, Map<String, String> attrs) {
+ logger.debug(LOG_ENTRY,"ExportedServiceImpl", new Object[]{ ifaceName, attrs});
+ _interfaces = new TreeSet<String> (Arrays.asList(ifaceName));
+ _ranking = 0;
+ _attributes = new HashMap<String, Object> (attrs);
+ _attributes.put(Constants.OBJECTCLASS, ifaceName);
+ _attributes.put (Constants.SERVICE_RANKING, String.valueOf(_ranking));
+ _attributes.put(ModellingConstants.OBR_SERVICE, ModellingConstants.OBR_SERVICE);
+ _serviceProperties = new HashMap<String, Object>();
+ _name = null;
+ logger.debug(LOG_EXIT,"ExportedServiceImpl");
+ }
+
+
+ public Map<String, Object> getAttributes() {
+ logger.debug(LOG_ENTRY,"getAttributes");
+ logger.debug(LOG_EXIT, "getAttributes", _attributes);
+ return Collections.unmodifiableMap(_attributes);
+ }
+
+
+ public ResourceType getType() {
+ logger.debug(LOG_ENTRY,"getType");
+ logger.debug(LOG_EXIT, "getType", ResourceType.SERVICE);
+ return ResourceType.SERVICE;
+ }
+
+
+ public Collection<String> getInterfaces() {
+ logger.debug(LOG_ENTRY,"getInterfaces");
+ logger.debug(LOG_EXIT, "getInterfaces", _interfaces);
+ return Collections.unmodifiableCollection(_interfaces);
+ }
+
+
+ public String getName() {
+ logger.debug(LOG_ENTRY,"getName");
+ logger.debug(LOG_EXIT, "getName", _name);
+ return _name;
+ }
+
+
+ public int getRanking() {
+ logger.debug(LOG_ENTRY,"getRanking");
+ logger.debug(LOG_EXIT, "getRanking", _ranking);
+ return _ranking;
+ }
+
+
+ public Map<String, Object> getServiceProperties() {
+ logger.debug(LOG_ENTRY,"getServiceProperties");
+ logger.debug(LOG_EXIT, "getServiceProperties", _serviceProperties);
+ return Collections.unmodifiableMap(_serviceProperties);
+ }
+
+
+ public int compareTo(WrappedServiceMetadata o) {
+ logger.debug(LOG_ENTRY, "compareTo", o);
+ if (o == null) {
+ logger.debug(LOG_EXIT, "compareTo", -1);
+ return -1; // shunt nulls to the end of any lists
+ }
+ int result = this.toString().compareTo(o.toString());
+ logger.debug(LOG_EXIT,"compareTo", result);
+ return result;
+ }
+
+ @Override
+ public boolean equals (Object o) {
+ logger.debug(LOG_ENTRY, "equals", o);
+ // Doubles as a null check
+ if (!(o instanceof WrappedServiceMetadata)) {
+ logger.debug(LOG_EXIT, "equals", false);
+ return false;
+ }
+
+ if (o==this) {
+ logger.debug(LOG_EXIT, "equals", true);
+ return true;
+ }
+
+ boolean eq = this.toString().equals(o.toString());
+ logger.debug(LOG_EXIT, "equals", eq);
+ return eq;
+ }
+
+
+ @Override
+ public int hashCode() {
+ logger.debug(LOG_ENTRY, "hashCode");
+ int result = toString().hashCode();
+ logger.debug(LOG_EXIT, "hashCode", result);
+ return result;
+ }
+
+ @Override
+ public String toString() {
+ if (_toString != null) {
+ return _toString;
+ }
+
+ List<String> interfaces = new ArrayList<String>(_interfaces);
+ Collections.sort(interfaces);
+
+ List<String> props = new ArrayList<String>();
+ for (Map.Entry<String, Object> entry : _serviceProperties.entrySet()) {
+ Object entryValue = entry.getValue();
+ String entryText;
+ if (entryValue.getClass().isArray()) {
+ // Turn arrays into comma separated Strings
+ Object [] entryArray = (Object[]) entryValue;
+ StringBuilder sb = new StringBuilder();
+ for (Object o: entryArray) {
+ sb.append(String.valueOf(o) + ",");
+ }
+ sb = sb.deleteCharAt(sb.length()-1);
+ entryText = sb.toString();
+ } else {
+ entryText = String.valueOf(entryValue);
+ }
+ props.add ("<entry> key=\"" + entry.getKey() + "\" value=\"" + entryText + "\"/>");
+ }
+ Collections.sort(props);
+
+ StringBuffer buf = new StringBuffer("<service>");
+ if(_name != null) {
+ buf.append("<name>" + _name + "</name>");
+ }
+ if (_interfaces.size() > 0) {
+ buf.append("<interfaces>");
+ }
+ for (String i : interfaces) {
+ buf.append("<value>" + i + "</value>");
+ }
+ if (_interfaces.size() > 0) {
+ buf.append("</interfaces>");
+ }
+ if (_serviceProperties.size() > 0) {
+ buf.append("<service-properties>");
+ }
+ for (String p : props) {
+ buf.append(p);
+ }
+ if (_serviceProperties.size() > 0) {
+ buf.append("</service-properties>");
+ }
+ buf.append("</service>");
+ _toString = buf.toString();
+ return _toString;
+ }
+
+
+ public boolean identicalOrDiffersOnlyByName(WrappedServiceMetadata wsmi) {
+ logger.debug(LOG_ENTRY,"identicalOrDiffersOnlyByName", wsmi);
+
+ if (this.equals(wsmi)) {
+ logger.debug(LOG_EXIT, "identicalOrDiffersOnlyByName", true);
+ return true;
+ }
+
+ Set<String> myInterfaces = new HashSet<String>(_interfaces);
+ Set<String> cmpInterfaces = new HashSet<String>(wsmi.getInterfaces());
+ if (!myInterfaces.equals(cmpInterfaces)) {
+ logger.debug(LOG_EXIT, "identicalOrDiffersOnlyByName", false);
+ return false;
+ }
+
+ boolean propertiesEqual = _serviceProperties.equals(wsmi.getServiceProperties());
+ if (!propertiesEqual) {
+ logger.debug(LOG_EXIT, "identicalOrDiffersOnlyByName", false);
+ return false;
+ }
+ logger.debug(LOG_EXIT, "identicalOrDiffersOnlyByName", true);
+ return true;
+ }
+
+
+}
Added: aries/tags/application-0.3/application-modeller/src/main/java/org/apache/aries/application/modelling/impl/ImportedBundleImpl.java
URL: http://svn.apache.org/viewvc/aries/tags/application-0.3/application-modeller/src/main/java/org/apache/aries/application/modelling/impl/ImportedBundleImpl.java?rev=1075132&view=auto
==============================================================================
--- aries/tags/application-0.3/application-modeller/src/main/java/org/apache/aries/application/modelling/impl/ImportedBundleImpl.java (added)
+++ aries/tags/application-0.3/application-modeller/src/main/java/org/apache/aries/application/modelling/impl/ImportedBundleImpl.java Sun Feb 27 20:20:13 2011
@@ -0,0 +1,222 @@
+/*
+ * 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.modelling.impl;
+
+
+
+import static org.apache.aries.application.utils.AppConstants.LOG_ENTRY;
+import static org.apache.aries.application.utils.AppConstants.LOG_EXIT;
+
+import java.util.Dictionary;
+import java.util.HashMap;
+import java.util.Hashtable;
+import java.util.Map;
+
+import org.apache.aries.application.InvalidAttributeException;
+import org.apache.aries.application.modelling.ImportedBundle;
+import org.apache.aries.application.modelling.ModellingConstants;
+import org.apache.aries.application.modelling.Provider;
+import org.apache.aries.application.modelling.ResourceType;
+import org.apache.aries.application.modelling.utils.impl.ModellingHelperImpl;
+import org.apache.aries.application.utils.FilterUtils;
+import org.apache.aries.application.utils.manifest.ManifestHeaderProcessor;
+import org.osgi.framework.Constants;
+import org.osgi.framework.Filter;
+import org.osgi.framework.FrameworkUtil;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.framework.Version;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+/**
+ * A model of a Bundle imported, or required, by something. For example, an entry in an APPLICATION.MF.
+ */
+public class ImportedBundleImpl implements ImportedBundle
+{
+
+ private final Map<String, String> _attributes;
+ private final String _filterString;
+ private final Filter _filter;
+ private final Logger logger = LoggerFactory.getLogger(ImportedBundleImpl.class);
+ /**
+ * Build an ImportedBundleImpl from filter string and a set of attributes. The filter string is
+ * most easily obtained ManifestHeaderProcessor.generateFilter() or Requirement.getFilter() -
+ * be careful if building your own.
+ * @param filterString For example as obtained from Requirement.getFilter()
+ * @param attributes
+ * @throws InvalidAttributeException
+ */
+ public ImportedBundleImpl(String filterString, Map<String, String> attributes) throws InvalidAttributeException
+ {
+ logger.debug(LOG_ENTRY, "ImportedBundleImpl", new Object[]{filterString, attributes});
+ _attributes = new HashMap<String, String> (attributes);
+ String versionRange = _attributes.remove(Constants.BUNDLE_VERSION_ATTRIBUTE);
+ if(versionRange == null) {
+ versionRange = Version.emptyVersion.toString();
+ }
+ if(_attributes.get(Constants.VERSION_ATTRIBUTE) == null) {
+ _attributes.put(Constants.VERSION_ATTRIBUTE, versionRange);
+ }
+ _filterString = filterString;
+ try {
+ _filter = FrameworkUtil.createFilter(FilterUtils.removeMandatoryFilterToken(_filterString));
+ } catch (InvalidSyntaxException isx) {
+ InvalidAttributeException iax = new InvalidAttributeException(isx);
+ logger.debug(LOG_EXIT, "ImportedBundleImpl", new Object[]{iax});
+ throw iax;
+ }
+ logger.debug(LOG_EXIT, "ImportedBundleImpl");
+ }
+
+ /**
+ * Build an ImportedBundleImpl from a bundle name and version range.
+ * @param bundleName Bundle symbolic name
+ * @param versionRange Bundle version range
+ * @throws InvalidAttributeException
+ */
+ public ImportedBundleImpl (String bundleName, String versionRange) throws InvalidAttributeException {
+ logger.debug(LOG_ENTRY, "ImportedBundleImpl", new Object[] {bundleName, versionRange});
+ _attributes = new HashMap<String, String> ();
+ _attributes.put (ModellingConstants.OBR_SYMBOLIC_NAME, bundleName);
+ _attributes.put (Constants.VERSION_ATTRIBUTE, versionRange);
+ _filterString = ManifestHeaderProcessor.generateFilter(_attributes);
+ try {
+ _filter = FrameworkUtil.createFilter(FilterUtils.removeMandatoryFilterToken(_filterString));
+ } catch (InvalidSyntaxException isx) {
+ InvalidAttributeException iax = new InvalidAttributeException(isx);
+ logger.debug(LOG_ENTRY, "ImportedBundleImpl", new Object[] {iax});
+ throw iax;
+ }
+ logger.debug(LOG_EXIT, "ImportedBundleImpl");
+ }
+
+
+ public String getAttributeFilter() {
+ logger.debug(LOG_ENTRY, "getAttributeFilter");
+ logger.debug(LOG_EXIT, "getAttributeFilter", new Object[] {_filterString});
+ return _filterString;
+ }
+
+
+ public ResourceType getType() {
+
+ logger.debug(LOG_ENTRY, "getType");
+ logger.debug(LOG_EXIT, "getType", new Object[] {ResourceType.BUNDLE});
+ return ResourceType.BUNDLE;
+ }
+
+
+ public boolean isMultiple() {
+ logger.debug(LOG_ENTRY, "isMultiple");
+ logger.debug(LOG_EXIT, "isMultiple", new Object[] {false});
+ return false;
+ }
+
+
+ public boolean isOptional() {
+ logger.debug(LOG_ENTRY, "isOptional");
+ boolean optional = false;
+ if (_attributes.containsKey(Constants.RESOLUTION_DIRECTIVE + ":")) {
+ if ((Constants.RESOLUTION_OPTIONAL).equals
+ (_attributes.get(Constants.RESOLUTION_DIRECTIVE + ":"))) {
+ optional = true;
+ }
+ }
+ logger.debug(LOG_EXIT, "isOptional", optional);
+ return optional;
+ }
+
+ public boolean isSatisfied(Provider capability) {
+ logger.debug(LOG_ENTRY, "isSatisfied", capability);
+ if (capability.getType() != ResourceType.BUNDLE
+ && capability.getType() != ResourceType.COMPOSITE) {
+ logger.debug(LOG_EXIT, "isSatisfied", false);
+ return false;
+ }
+ Dictionary<String, Object> dict = new Hashtable<String, Object> (capability.getAttributes());
+ String version = (String) dict.get(Constants.VERSION_ATTRIBUTE);
+ if (version != null) {
+ dict.put(Constants.VERSION_ATTRIBUTE, Version.parseVersion(version));
+ }
+ boolean allPresent = ModellingHelperImpl.areMandatoryAttributesPresent_(_attributes, capability);
+ boolean result = allPresent && _filter.match(dict);
+ logger.debug(LOG_EXIT, "isSatisfied", result);
+ return result;
+ }
+
+ /**
+ * Get the version range on this bundle import
+ * @return Imported version range, as a string
+ */
+ public String getVersionRange() {
+ logger.debug(LOG_ENTRY, "getVersionRange");
+ String range = _attributes.get(Constants.VERSION_ATTRIBUTE);
+ String result = (range == null) ? Version.emptyVersion.toString() : range;
+ logger.debug(LOG_EXIT, "getVersionRange", result);
+ return result;
+ }
+
+ /**
+ * Get the symbolic name of the imported bundle
+ * @return symbolic name
+ */
+ public String getSymbolicName() {
+ logger.debug(LOG_ENTRY, "getSymbolicName");
+ String result = _attributes.get(ModellingConstants.OBR_SYMBOLIC_NAME);
+ logger.debug(LOG_EXIT, "getSymbolicName", result);
+ return result;
+ }
+
+ /**
+ * Equal if symbolic names match and version strings match
+ */
+ @Override
+ public boolean equals(Object o)
+ {
+ logger.debug(LOG_ENTRY, "equals", o);
+ boolean result = false;
+ if (o == this)
+ {
+ result = true;
+ }
+ else if (o instanceof ImportedBundleImpl)
+ {
+ ImportedBundleImpl ib = (ImportedBundleImpl)o;
+ result = (getSymbolicName().equals(ib.getSymbolicName())
+ && getVersionRange().equals(ib.getVersionRange()));
+ }
+ logger.debug(LOG_EXIT, "equals", result);
+ return result;
+ }
+
+ @Override
+ public int hashCode()
+ {
+ logger.debug(LOG_ENTRY, "hashCode");
+ int hashCode = getSymbolicName().hashCode() + 31 * getVersionRange().hashCode();
+ logger.debug(LOG_ENTRY, "hashCode", hashCode);
+ return hashCode;
+ }
+
+ @Override
+ public String toString() {
+ return _filterString;
+ }
+}
Added: aries/tags/application-0.3/application-modeller/src/main/java/org/apache/aries/application/modelling/impl/ImportedPackageImpl.java
URL: http://svn.apache.org/viewvc/aries/tags/application-0.3/application-modeller/src/main/java/org/apache/aries/application/modelling/impl/ImportedPackageImpl.java?rev=1075132&view=auto
==============================================================================
--- aries/tags/application-0.3/application-modeller/src/main/java/org/apache/aries/application/modelling/impl/ImportedPackageImpl.java (added)
+++ aries/tags/application-0.3/application-modeller/src/main/java/org/apache/aries/application/modelling/impl/ImportedPackageImpl.java Sun Feb 27 20:20:13 2011
@@ -0,0 +1,209 @@
+/*
+ * 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.modelling.impl;
+
+import static org.apache.aries.application.modelling.ModellingConstants.OPTIONAL_KEY;
+import static org.apache.aries.application.modelling.ResourceType.PACKAGE;
+import static org.apache.aries.application.utils.AppConstants.LOG_ENTRY;
+import static org.apache.aries.application.utils.AppConstants.LOG_EXIT;
+
+import java.util.Collections;
+import java.util.Dictionary;
+import java.util.HashMap;
+import java.util.Hashtable;
+import java.util.Map;
+
+import org.apache.aries.application.InvalidAttributeException;
+import org.apache.aries.application.modelling.ImportedPackage;
+import org.apache.aries.application.modelling.Provider;
+import org.apache.aries.application.modelling.ResourceType;
+import org.apache.aries.application.modelling.utils.impl.ModellingHelperImpl;
+import org.apache.aries.application.utils.FilterUtils;
+import org.apache.aries.application.utils.manifest.ManifestHeaderProcessor;
+import org.osgi.framework.Constants;
+import org.osgi.framework.Filter;
+import org.osgi.framework.FrameworkUtil;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.framework.Version;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+/**
+ * An imported, or required package. Capable of generating an entry in DEPLOYMENT.MF's Import-Package header.
+ */
+public class ImportedPackageImpl implements ImportedPackage
+{
+
+
+ private final boolean _optional;
+ private final String _filterString;
+ private final Filter _filter;
+ private final String _package;
+ private final String _versionRange;
+ private final Map<String,String> _attributes;
+ private final Logger logger = LoggerFactory.getLogger(ImportedPackageImpl.class);
+ /**
+ * Construct a package requirement
+ * @param pkg The name of the required package
+ * @param attributes Other attributes - most commonly, version
+ * @throws InvalidAttributeException
+ */
+ public ImportedPackageImpl (String pkg, Map<String, String> attributes) throws InvalidAttributeException {
+ logger.debug(LOG_ENTRY, "ImportedPackageImpl", new Object[] {pkg, attributes});
+ _package = pkg;
+ String versionRange = null;
+ if (attributes != null) {
+ _optional = (Constants.RESOLUTION_OPTIONAL.equals(attributes.get(OPTIONAL_KEY)));
+ versionRange = attributes.get(Constants.VERSION_ATTRIBUTE);
+ _attributes = new HashMap<String, String>(attributes);
+ } else {
+ _optional = false;
+ _attributes = new HashMap<String, String>();
+ }
+ if (versionRange == null) {
+ _versionRange = Version.emptyVersion.toString();
+ } else {
+ _versionRange = versionRange;
+ }
+
+ _attributes.put(Constants.VERSION_ATTRIBUTE, _versionRange);
+ _filterString = ManifestHeaderProcessor.generateFilter(PACKAGE.toString(), _package, _attributes);
+ try {
+ _filter = FrameworkUtil.createFilter(FilterUtils.removeMandatoryFilterToken(_filterString));
+ } catch (InvalidSyntaxException isx) {
+ logger.debug(LOG_EXIT, "ImportedPackageImpl", new Object[] {isx});
+ throw new InvalidAttributeException(isx);
+ }
+ logger.debug(LOG_EXIT, "ImportedPackageImpl");
+ }
+
+ /**
+ * Get this ImportedPackageImpl's attributes
+ * @return attributes
+ */
+ public Map<String, String> getAttributes() {
+ logger.debug(LOG_ENTRY, "getAttributes");
+ logger.debug(LOG_EXIT, "getAttributes", new Object[] {_attributes});
+ return Collections.unmodifiableMap(_attributes);
+ }
+
+ /**
+ * Get the package name
+ * @return package name
+ */
+ public String getPackageName() {
+ logger.debug(LOG_ENTRY, "getPackageName");
+ logger.debug(LOG_EXIT, "getPackageName", new Object[] {_package});
+ return _package;
+ }
+
+ /**
+ * Get the imported package's version range
+ * @return version range
+ */
+ public String getVersionRange() {
+ logger.debug(LOG_ENTRY, "getVersionRange");
+ logger.debug(LOG_EXIT, "getVersionRange", new Object[] {_versionRange});
+ return _versionRange;
+ }
+
+
+ public String getAttributeFilter() {
+ logger.debug(LOG_ENTRY, "getAttributeFilter");
+ logger.debug(LOG_EXIT, "getAttributeFilter", new Object[] {_filterString});
+ return _filterString;
+ }
+
+
+ public ResourceType getType() {
+ logger.debug(LOG_ENTRY, "getType");
+ logger.debug(LOG_EXIT, "getType", new Object[] {PACKAGE});
+ return PACKAGE;
+ }
+
+
+ public boolean isMultiple() {
+ logger.debug(LOG_ENTRY, "isMultiple");
+ logger.debug(LOG_EXIT, "isMultiple", new Object[] {false});
+ return false; // cannot import a given package more than once
+ }
+
+
+ public boolean isOptional() {
+ logger.debug(LOG_ENTRY, "isOptional");
+ logger.debug(LOG_EXIT, "isOptional", new Object[] {_optional});
+ return _optional;
+ }
+
+
+ public boolean isSatisfied(Provider capability) {
+ logger.debug(LOG_ENTRY, "isSatisfied", new Object[]{capability});
+ if (capability.getType() != PACKAGE) {
+ logger.debug(LOG_EXIT, "isSatisfied", new Object[] {false});
+ return false;
+ }
+ Dictionary<String, Object> dict = new Hashtable<String, Object> (capability.getAttributes());
+ String version = (String) dict.get(Constants.VERSION_ATTRIBUTE);
+ if (version != null) {
+ dict.put(Constants.VERSION_ATTRIBUTE, Version.parseVersion(version));
+ }
+
+ boolean allPresent = ModellingHelperImpl.areMandatoryAttributesPresent_(_attributes, capability);
+ boolean result = allPresent && _filter.match(dict);
+ logger.debug(LOG_EXIT, "isSatisfied", new Object[] {result});
+ return result;
+ }
+
+
+
+ /**
+ * This method turns an {@link ImportedPackageImpl} into a string suitable for a
+ * Provision-Bundle style package import.
+ * It will not include ;bundle-symbolic-name=bundleName;bundle-version=version attribute pairs
+ * @return A String
+ */
+ @SuppressWarnings("deprecation")
+ public String toDeploymentString() {
+ logger.debug(LOG_ENTRY, "toDeploymentString");
+ StringBuilder sb = new StringBuilder(_package);
+ // Note that the RESOLUTION_DIRECTIVE is set in this map, so it will be
+ // output automatically. p41 of the OSGi Core Spec v4.2 includes an example
+ // Import-Package with a resolution:=mandatory directive on. We could choose to suppress
+ // resolution:=mandatory on packages however, since mandatory is the default.
+ for (Map.Entry<String, String> entry : _attributes.entrySet()) {
+ String key = entry.getKey();
+ String value = entry.getValue();
+ if (!key.equals(Constants.BUNDLE_SYMBOLICNAME_ATTRIBUTE)
+ && !key.equals(Constants.BUNDLE_VERSION_ATTRIBUTE)
+ && !key.equals(PACKAGE.toString())
+ && !key.equals(Constants.PACKAGE_SPECIFICATION_VERSION)) {
+ sb.append(";").append(key).append("=\"").append(value).append('"');
+ } else {
+ logger.debug("ignoring attribute {" + key + "=" + value + "} in ImportedPackageImpl.toDeploymentString()");
+ }
+ }
+ String result = sb.toString();
+ logger.debug(LOG_EXIT, "toDeploymentString", new Object[]{result});
+ return result;
+ }
+
+ @Override
+ public String toString() {
+ return toDeploymentString();
+ }
+}
Added: aries/tags/application-0.3/application-modeller/src/main/java/org/apache/aries/application/modelling/impl/ImportedServiceImpl.java
URL: http://svn.apache.org/viewvc/aries/tags/application-0.3/application-modeller/src/main/java/org/apache/aries/application/modelling/impl/ImportedServiceImpl.java?rev=1075132&view=auto
==============================================================================
--- aries/tags/application-0.3/application-modeller/src/main/java/org/apache/aries/application/modelling/impl/ImportedServiceImpl.java (added)
+++ aries/tags/application-0.3/application-modeller/src/main/java/org/apache/aries/application/modelling/impl/ImportedServiceImpl.java Sun Feb 27 20:20:13 2011
@@ -0,0 +1,305 @@
+/*
+ * 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.modelling.impl;
+
+import static org.apache.aries.application.modelling.ResourceType.SERVICE;
+import static org.apache.aries.application.utils.AppConstants.LOG_ENTRY;
+import static org.apache.aries.application.utils.AppConstants.LOG_EXIT;
+
+import java.util.Dictionary;
+import java.util.HashMap;
+import java.util.Hashtable;
+import java.util.Map;
+import java.util.regex.Pattern;
+
+import org.apache.aries.application.InvalidAttributeException;
+import org.apache.aries.application.modelling.ImportedService;
+import org.apache.aries.application.modelling.ModellingConstants;
+import org.apache.aries.application.modelling.Provider;
+import org.apache.aries.application.modelling.ResourceType;
+import org.apache.aries.application.modelling.WrappedReferenceMetadata;
+import org.apache.aries.application.modelling.utils.impl.ModellingHelperImpl;
+import org.apache.aries.application.utils.FilterUtils;
+import org.apache.aries.application.utils.manifest.ManifestHeaderProcessor;
+import org.osgi.framework.Constants;
+import org.osgi.framework.Filter;
+import org.osgi.framework.FrameworkUtil;
+import org.osgi.framework.InvalidSyntaxException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+/**
+ * an Import-Service entry
+ */
+public class ImportedServiceImpl implements ImportedService
+{
+ private final static String DEPRECATED_FILTER_ATTRIBUTE = "filter";
+ private final boolean _optional;
+ private final String _iface;
+ private final String _componentName;
+ private final String _blueprintFilter;
+ private final Filter _attributeFilter;
+ private final boolean _isMultiple;
+ private final String _id;
+ private final Map<String, String> _attributes;
+ private String _toString;
+ private String _attribFilterString; // The manner in which we set means it can't be final
+ private final static Pattern SERVICE_EQUALS_SERVICE = Pattern.compile("\\(" + ResourceType.SERVICE.toString()
+ + "=" + ResourceType.SERVICE.toString() + "\\)");
+ private final Logger logger = LoggerFactory.getLogger(ImportedServiceImpl.class);
+ /**
+ * Build an ImportedServiceImpl from its elements
+ * @param optional
+ * @param iface
+ * @param componentName
+ * @param blueprintFilter
+ * @param id
+ * @param isMultiple
+ * @throws InvalidAttributeException
+ */
+ public ImportedServiceImpl (boolean optional, String iface, String componentName,
+ String blueprintFilter, String id, boolean isMultiple)
+ throws InvalidAttributeException
+ {
+
+ _optional = optional;
+ _iface = iface;
+ _componentName = componentName;
+ _blueprintFilter = FilterUtils.removeMandatoryFilterToken(blueprintFilter);
+ _id = id;
+ _isMultiple = isMultiple;
+ _attributes = new HashMap<String, String>();
+ _attributeFilter = generateAttributeFilter (_attributes);
+
+
+ }
+
+ private Filter generateAttributeFilter (Map<String, String> attrsToPopulate) throws InvalidAttributeException {
+ logger.debug(LOG_ENTRY, "generateAttributeFilter", new Object[]{attrsToPopulate});
+ Filter result = null;
+
+ try {
+ attrsToPopulate.put(ModellingConstants.OBR_SERVICE, ModellingConstants.OBR_SERVICE);
+ if (_blueprintFilter != null) {
+ // We may get blueprint filters of the form (&(a=b)(c=d)). We can't put these in 'whole' because we'll
+ // end up generating a filter of the form (&(objectClass=foo)(&(a=b)(c=d)) which subsequent calls to
+ // parseFilter will choke on. So as an interim fix we'll strip off a leading &( and trailing ) if present.
+ String reducedBlueprintFilter;
+ if (_blueprintFilter.startsWith("(&")) {
+ reducedBlueprintFilter = _blueprintFilter.substring(2, _blueprintFilter.length() - 1);
+ } else {
+ reducedBlueprintFilter = _blueprintFilter;
+ }
+
+ attrsToPopulate.put(ManifestHeaderProcessor.NESTED_FILTER_ATTRIBUTE, reducedBlueprintFilter);
+ }
+ if (_componentName != null) {
+ attrsToPopulate.put ("osgi.service.blueprint.compname", _componentName);
+ }
+ if (_iface != null) {
+ attrsToPopulate.put (Constants.OBJECTCLASS, _iface);
+ }
+ _attribFilterString = ManifestHeaderProcessor.generateFilter(_attributes);
+ if (! "".equals(_attribFilterString)) {
+ result = FrameworkUtil.createFilter(FilterUtils.removeMandatoryFilterToken(_attribFilterString));
+ }
+ } catch (InvalidSyntaxException isx) {
+
+ InvalidAttributeException iax = new InvalidAttributeException(isx);
+ logger.debug(LOG_EXIT, "generateAttributeFilter", new Object[]{isx});
+ throw iax;
+ }
+ logger.debug(LOG_EXIT, "generateAttributeFilter", new Object[]{result});
+ return result;
+ }
+
+ /**
+ * Deprecated constructor for building these from deprecated Export-Service manifest headers. Do not use this
+ * constructor for any other purpose.
+ * @param ifaceName
+ * @param attributes
+ * @throws InvalidAttributeException
+ */
+ @Deprecated
+ public ImportedServiceImpl (String ifaceName, Map<String, String> attributes) throws InvalidAttributeException {
+
+ _optional = ("optional".equals(attributes.get("availability:")));
+ _iface = ifaceName;
+ _isMultiple = false;
+ _componentName = null;
+ _id = null;
+ _attributes = new HashMap<String, String>(attributes);
+
+ // The syntax for this deprecated header allows statements of the form,
+ // ImportService: myService;filter="(a=b")
+ _blueprintFilter = _attributes.remove(DEPRECATED_FILTER_ATTRIBUTE);
+ _attributeFilter = generateAttributeFilter (_attributes);
+
+
+ }
+
+ public String getFilter() {
+ logger.debug(LOG_ENTRY, "getFilter");
+ logger.debug(LOG_EXIT, "getFilter", _blueprintFilter);
+ return _blueprintFilter;
+ }
+
+
+ public ResourceType getType() {
+ logger.debug(LOG_ENTRY, "getType");
+ logger.debug(LOG_EXIT, "getType", ResourceType.SERVICE);
+ return ResourceType.SERVICE;
+ }
+
+
+ public boolean isMultiple() {
+ logger.debug(LOG_ENTRY, "isMultiple");
+ logger.debug(LOG_EXIT, "isMultiple", _isMultiple);
+ return _isMultiple;
+ }
+
+
+
+ public boolean isOptional() {
+ logger.debug(LOG_ENTRY, "isOptional");
+ logger.debug(LOG_EXIT, "isOptional", _optional);
+ return _optional;
+ }
+
+
+ public boolean isSatisfied(Provider capability) {
+ logger.debug(LOG_ENTRY, "isSatisfied", capability);
+
+ if (capability.getType() != SERVICE) {
+ logger.debug(LOG_EXIT, "isSatisfied", false);
+ return false;
+ }
+ Dictionary<String, Object> dict = new Hashtable<String, Object> (capability.getAttributes());
+
+ // If there's a value for ObjectClass, it may be a comma separated list.
+ String objectClass = (String) dict.get(Constants.OBJECTCLASS);
+ if (objectClass != null) {
+ String [] split = objectClass.split (",");
+ dict.put (Constants.OBJECTCLASS, split);
+ }
+
+ if (_attributeFilter == null) {
+ logger.debug(LOG_EXIT, "isSatisfied", true);
+ return true;
+ }
+ boolean allPresent = ModellingHelperImpl.areMandatoryAttributesPresent_(_attributes, capability);
+ boolean result = allPresent && _attributeFilter.match(dict);
+ logger.debug(LOG_EXIT, "isSatisfied", result);
+ return result;
+ }
+
+
+ public String getComponentName() {
+ logger.debug(LOG_ENTRY, "getComponentName");
+ logger.debug(LOG_EXIT, "getComponentName", _componentName);
+ return _componentName;
+ }
+
+
+ public String getId() {
+ logger.debug(LOG_ENTRY, "getId");
+ logger.debug(LOG_EXIT, "getId", _id);
+ return _id;
+ }
+
+
+ public String getInterface() {
+ logger.debug(LOG_ENTRY, "getInterface");
+ logger.debug(LOG_EXIT, "getInterface", _iface);
+ return _iface;
+ }
+
+ public boolean isList() {
+ logger.debug(LOG_ENTRY, "isList");
+ boolean result = isMultiple();
+ logger.debug(LOG_EXIT, "isList", result);
+ return result;
+ }
+
+
+ public String getAttributeFilter() {
+ logger.debug(LOG_ENTRY, "getAttributeFilter");
+ logger.debug(LOG_EXIT, "getAttributeFilter", _attribFilterString);
+ return _attribFilterString;
+ }
+
+ @Override
+ public boolean equals (Object o) {
+
+ boolean equal = false;
+ if (o==null) {
+ equal = false;
+ } else if (o==this) {
+ equal = true;
+ } else if (!(o instanceof WrappedReferenceMetadata)) {
+ equal = false;
+ } else {
+ equal = toString().equals(o.toString());
+ }
+
+ return equal;
+ }
+
+ @Override
+ public int hashCode() {
+
+ int result = toString().hashCode();
+
+ return result;
+ }
+
+ @Override
+ public String toString() {
+ logger.debug(LOG_ENTRY, "toString");
+
+ if (_toString != null) {
+ logger.debug(LOG_EXIT, "toString", _toString);
+ return _toString;
+ }
+ StringBuffer buf = new StringBuffer("<reference>");
+ buf.append("<componentName>" + _componentName + "</componentName>");
+ buf.append("<id>" + _id + "</id>");
+ buf.append("<interface>" + _iface + "</interface>");
+ buf.append("<isList>" + _isMultiple + "</isList>");
+ buf.append("<isOptional>" + _optional + "</isOptional>");
+ // We don't have a method for writing filters in a canonical form
+ buf.append("<filter>" + _blueprintFilter + "</filter>");
+ _toString = buf.toString();
+ logger.debug(LOG_EXIT, "toString", _toString);
+ return _toString;
+ }
+
+ /**
+ * A String suitable for use in DeployedImport-Service
+ */
+ public String toDeploymentString() {
+ logger.debug(LOG_ENTRY, "toDeploymentString");
+ String baseFilter = getAttributeFilter();
+ // We may have one or more (service=service) elements that must be removed.
+ String reducedFilter = SERVICE_EQUALS_SERVICE.matcher(baseFilter).replaceAll("");
+ // now trim off mandatory:<*service occurrences
+ String result = FilterUtils.removeMandatoryFilterToken(reducedFilter);
+ logger.debug(LOG_EXIT, "toDeploymentString", result);
+ return result;
+ }
+}
Added: aries/tags/application-0.3/application-modeller/src/main/java/org/apache/aries/application/modelling/impl/ModelledResourceImpl.java
URL: http://svn.apache.org/viewvc/aries/tags/application-0.3/application-modeller/src/main/java/org/apache/aries/application/modelling/impl/ModelledResourceImpl.java?rev=1075132&view=auto
==============================================================================
--- aries/tags/application-0.3/application-modeller/src/main/java/org/apache/aries/application/modelling/impl/ModelledResourceImpl.java (added)
+++ aries/tags/application-0.3/application-modeller/src/main/java/org/apache/aries/application/modelling/impl/ModelledResourceImpl.java Sun Feb 27 20:20:13 2011
@@ -0,0 +1,342 @@
+/*
+ * 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.modelling.impl;
+
+import static org.apache.aries.application.utils.AppConstants.LOG_ENTRY;
+import static org.apache.aries.application.utils.AppConstants.LOG_EXIT;
+import static org.osgi.framework.Constants.BUNDLE_VERSION_ATTRIBUTE;
+import static org.osgi.framework.Constants.DYNAMICIMPORT_PACKAGE;
+import static org.osgi.framework.Constants.EXPORT_PACKAGE;
+import static org.osgi.framework.Constants.EXPORT_SERVICE;
+import static org.osgi.framework.Constants.IMPORT_PACKAGE;
+import static org.osgi.framework.Constants.IMPORT_SERVICE;
+import static org.osgi.framework.Constants.REQUIRE_BUNDLE;
+import static org.osgi.framework.Constants.RESOLUTION_DIRECTIVE;
+import static org.osgi.framework.Constants.RESOLUTION_OPTIONAL;
+import static org.osgi.framework.Constants.VERSION_ATTRIBUTE;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.jar.Attributes;
+
+import org.apache.aries.application.InvalidAttributeException;
+import org.apache.aries.application.management.BundleInfo;
+import org.apache.aries.application.modelling.ExportedBundle;
+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.ImportedService;
+import org.apache.aries.application.modelling.ModelledResource;
+import org.apache.aries.application.modelling.ModellingConstants;
+import org.apache.aries.application.modelling.ResourceType;
+import org.apache.aries.application.utils.manifest.ManifestHeaderProcessor;
+import org.apache.aries.application.utils.manifest.ManifestHeaderProcessor.NameValueMap;
+import org.apache.aries.application.utils.manifest.ManifestHeaderProcessor.NameValuePair;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+/**
+ * A model of a bundle or composite. Used for example to supply information to
+ * RepositoryGenerator.generateRepository()
+ *
+ */
+public class ModelledResourceImpl implements ModelledResource
+{
+ private final Logger logger = LoggerFactory.getLogger(ModelledResourceImpl.class);
+ private final String _fileURI;
+ private final Collection<ImportedService> _importedServices;
+ private final Collection<ExportedService> _exportedServices;
+ private final Collection<ExportedPackage> _exportedPackages;
+ private final Collection<ImportedPackage> _importedPackages;
+ private final Collection<ImportedBundle> _requiredBundles;
+ private final ExportedBundle _exportedBundle;
+ private final ResourceType _resourceType;
+
+ /**
+ * Construct a new {@link ModelledResourceImpl} for the following manifest and services
+ * @param fileURI The location of the bundle, may be null, which indicates a by value bundle
+ * @param bundleInfo The bundle info object
+ * @param importedServices The blueprint references defined by the bundle. May be null
+ * @param exportedServices The blueprint services exported by the bundle. May be null
+ * @throws InvalidAttributeException
+ */
+ public ModelledResourceImpl (String fileURI, BundleInfo bundleInfo,
+ Collection<ImportedService> importedServices,
+ Collection<ExportedService> exportedServices) throws InvalidAttributeException
+ {
+ this(fileURI, bundleInfo.getRawAttributes(), importedServices, exportedServices);
+ }
+ /**
+ * Construct a new {@link ModelledResourceImpl} for the following manifest and services
+ * @param fileURI The location of the bundle, may be null, which indicates a by value bundle
+ * @param bundleAttributes The bundle manifest, must not be null
+ * @param importedServices The blueprint references defined by the bundle. May be null
+ * @param exportedServices The blueprint services exported by the bundle. May be null
+ * @throws InvalidAttributeException
+ */
+ @SuppressWarnings("deprecation")
+ public ModelledResourceImpl (String fileURI, Attributes bundleAttributes, ExportedBundle exportedBundle, ResourceType resourceType,
+ Collection<ImportedService> importedServices,
+ Collection<ExportedService> exportedServices) throws InvalidAttributeException
+ {
+ this (fileURI, bundleAttributes, resourceType, exportedBundle, importedServices, exportedServices);
+ logger.debug(LOG_ENTRY, "ModelledResourceImpl", new Object[]{fileURI, bundleAttributes, importedServices, exportedServices});
+ logger.debug(LOG_EXIT, "ModelledResourceImpl");
+ }
+
+ /**
+ * Construct a new {@link ModelledResourceImpl} for the following manifest and services
+ * @param fileURI The location of the bundle, may be null, which indicates a by value bundle
+ * @param bundleAttributes The bundle manifest, must not be null
+ * @param importedServices The blueprint references defined by the bundle. May be null
+ * @param exportedServices The blueprint services exported by the bundle. May be null
+ * @throws InvalidAttributeException
+ */
+ @SuppressWarnings("deprecation")
+ public ModelledResourceImpl (String fileURI, Attributes bundleAttributes,
+ Collection<ImportedService> importedServices,
+ Collection<ExportedService> exportedServices) throws InvalidAttributeException
+ {
+ this (fileURI, bundleAttributes, ResourceType.BUNDLE, null, importedServices, exportedServices );
+ logger.debug(LOG_ENTRY, "ModelledResourceImpl", new Object[]{fileURI, bundleAttributes, importedServices, exportedServices});
+ logger.debug(LOG_EXIT, "ModelledResourceImpl");
+ }
+
+ public ModelledResourceImpl (String fileURI, Attributes bundleAttributes,
+ ResourceType resourceType, ExportedBundle exportedBundle,
+ Collection<ImportedService> importedServices,
+ Collection<ExportedService> exportedServices
+ ) throws InvalidAttributeException
+ {
+ logger.debug(LOG_ENTRY, "ModelledResourceImpl", new Object[]{fileURI, bundleAttributes, importedServices, exportedServices,
+ resourceType});
+
+ if (exportedBundle == null) {
+ _exportedBundle = new ExportedBundleImpl (bundleAttributes);
+ } else {
+ _exportedBundle = exportedBundle;
+ }
+ _resourceType = resourceType;
+ _fileURI = fileURI;
+ if(importedServices != null)
+ _importedServices = new ArrayList<ImportedService> (importedServices);
+ else
+ _importedServices = new ArrayList<ImportedService>();
+
+ if(exportedServices != null)
+ _exportedServices = new ArrayList<ExportedService> (exportedServices);
+ else
+ _exportedServices = new ArrayList<ExportedService>();
+
+ _exportedPackages = new ArrayList<ExportedPackage>();
+ String packageExports = bundleAttributes.getValue(EXPORT_PACKAGE);
+ if (packageExports != null) {
+ List<NameValuePair<String, NameValueMap<String, String>>> exportedPackages = ManifestHeaderProcessor
+ .parseExportString(packageExports);
+ for (NameValuePair<String, NameValueMap<String, String>> exportedPackage : exportedPackages) {
+ _exportedPackages.add(new ExportedPackageImpl(this, exportedPackage.getName(),
+ new HashMap<String, Object>(exportedPackage.getValue())));
+
+ }
+ }
+
+ _importedPackages = new ArrayList<ImportedPackage>();
+ String packageImports = bundleAttributes.getValue(IMPORT_PACKAGE);
+ if (packageImports != null) {
+ Map<String, NameValueMap<String, String>> importedPackages = ManifestHeaderProcessor
+ .parseImportString(packageImports);
+ for (Map.Entry<String, NameValueMap<String, String>> importedPackage : importedPackages.entrySet()) {
+ Map<String, String> atts = importedPackage.getValue();
+ _importedPackages.add(new ImportedPackageImpl(importedPackage.getKey(), atts));
+ }
+ }
+
+ // Use of Import-Service and Export-Service is deprecated in OSGi. We like Blueprint.
+ // Blueprint is good.
+
+ String serviceExports = null;
+ if (_resourceType == ResourceType.BUNDLE) {
+ serviceExports = bundleAttributes.getValue(EXPORT_SERVICE);
+ }
+ if (serviceExports != null) {
+ List<NameValuePair<String, NameValueMap<String, String>>> expServices = ManifestHeaderProcessor
+ .parseExportString(serviceExports);
+ for (NameValuePair<String, NameValueMap<String, String>> exportedService : expServices) {
+ _exportedServices.add(new ExportedServiceImpl(exportedService.getName(), exportedService.getValue()));
+ }
+ }
+
+ String serviceImports =null;
+ if (_resourceType == ResourceType.BUNDLE) {
+ serviceImports = bundleAttributes.getValue(IMPORT_SERVICE);
+ }
+ if (serviceImports != null) {
+ Map<String, NameValueMap<String, String>> svcImports = ManifestHeaderProcessor
+ .parseImportString(serviceImports);
+ for (Map.Entry<String, NameValueMap<String, String>> importedService : svcImports.entrySet()) {
+ _importedServices.add(new ImportedServiceImpl(importedService.getKey(), importedService.getValue()));
+ }
+ }
+
+ _requiredBundles = new ArrayList<ImportedBundle>();
+ // Require-Bundle and DynamicImport-Package relevant to Bundles but not Composites
+ if (_resourceType == ResourceType.BUNDLE) {
+ String requireBundleHeader = bundleAttributes.getValue(REQUIRE_BUNDLE);
+ if (requireBundleHeader != null) {
+ Map<String, NameValueMap<String, String>> requiredBundles = ManifestHeaderProcessor
+ .parseImportString(requireBundleHeader);
+ for (Map.Entry<String, NameValueMap<String, String>> bundle : requiredBundles.entrySet()) {
+ String type = bundle.getKey();
+ Map<String, String> attribs = bundle.getValue();
+ // We may parse a manifest with a header like Require-Bundle: bundle.a;bundle-version=3.0.0
+ // The filter that we generate is intended for OBR in which case we need (version>=3.0.0) and not (bundle-version>=3.0.0)
+ String bundleVersion = attribs.remove(BUNDLE_VERSION_ATTRIBUTE);
+ if (bundleVersion != null && attribs.get(VERSION_ATTRIBUTE) == null) {
+ attribs.put (VERSION_ATTRIBUTE, bundleVersion);
+ }
+ String filter = ManifestHeaderProcessor.generateFilter(ModellingConstants.OBR_SYMBOLIC_NAME, type, attribs);
+ Map<String, String> atts = new HashMap<String, String>(bundle.getValue());
+ atts.put(ModellingConstants.OBR_SYMBOLIC_NAME, bundle.getKey());
+ _requiredBundles.add(new ImportedBundleImpl(filter, atts));
+ }
+ }
+
+ String dynamicImports = bundleAttributes.getValue(DYNAMICIMPORT_PACKAGE);
+ if (dynamicImports != null) {
+ Map<String, NameValueMap<String, String>> dynamicImportPackages = ManifestHeaderProcessor
+ .parseImportString(dynamicImports);
+ for (Map.Entry<String, NameValueMap<String, String>> dynImportPkg : dynamicImportPackages.entrySet()) {
+ if (dynImportPkg.getKey().indexOf("*") == -1) {
+ dynImportPkg.getValue().put(RESOLUTION_DIRECTIVE + ":", RESOLUTION_OPTIONAL);
+ _importedPackages.add(new ImportedPackageImpl(dynImportPkg.getKey(), dynImportPkg.getValue()));
+ }
+ }
+ }
+ }
+ logger.debug(LOG_EXIT, "ModelledResourceImpl");
+ }
+
+
+ public String getLocation() {
+ logger.debug(LOG_ENTRY, "getLocation");
+ logger.debug(LOG_EXIT, "getLocation", _fileURI);
+ return _fileURI;
+ }
+
+
+ public ExportedBundle getExportedBundle() {
+ logger.debug(LOG_ENTRY, "getExportedBundle");
+ logger.debug(LOG_EXIT, "getExportedBundle", _exportedBundle);
+ return _exportedBundle;
+ }
+
+
+ public Collection<ExportedPackage> getExportedPackages() {
+ logger.debug(LOG_ENTRY, "getExportedPackages");
+ logger.debug(LOG_EXIT, "getExportedPackages", _exportedPackages);
+ return Collections.unmodifiableCollection(_exportedPackages);
+ }
+
+
+
+ public Collection<ImportedPackage> getImportedPackages() {
+ logger.debug(LOG_ENTRY, "getImportedPackages");
+ logger.debug(LOG_EXIT, "getImportedPackages", _importedPackages);
+ return Collections.unmodifiableCollection(_importedPackages);
+ }
+
+ public Collection<ExportedService> getExportedServices() {
+ logger.debug(LOG_ENTRY, "getExportedServices");
+ logger.debug(LOG_EXIT, "getExportedServices", _exportedServices);
+ return Collections.unmodifiableCollection(_exportedServices);
+ }
+
+
+
+ public Collection<ImportedService> getImportedServices() {
+ logger.debug(LOG_ENTRY, "getImportedServices");
+ logger.debug(LOG_EXIT, "getImportedServices", _exportedServices);
+ return Collections.unmodifiableCollection(_importedServices);
+ }
+
+
+ public String getSymbolicName() {
+ logger.debug(LOG_ENTRY, "getSymbolicName");
+ String result = _exportedBundle.getSymbolicName();
+ logger.debug(LOG_EXIT, "getSymbolicName", result);
+ return result;
+ }
+
+
+ public String getVersion() {
+ logger.debug(LOG_ENTRY, "getVersion");
+ String result = _exportedBundle.getVersion();
+ logger.debug(LOG_EXIT, "getVersion", result);
+ return result;
+ }
+
+
+ public String toDeploymentString() {
+ logger.debug(LOG_ENTRY, "toDeploymentString");
+ String result = _exportedBundle.toDeploymentString();
+ logger.debug(LOG_EXIT, "toDeploymentString", result);
+ return result;
+ }
+
+
+ public ResourceType getType() {
+ logger.debug(LOG_ENTRY, "getType");
+ logger.debug(LOG_EXIT, "getType", ResourceType.BUNDLE);
+ return _resourceType;
+ }
+
+ @Override
+ public String toString() {
+ return toDeploymentString();
+ }
+
+
+ public Collection<ImportedBundle> getRequiredBundles() {
+ logger.debug(LOG_ENTRY, "getRequiredBundles");
+ logger.debug(LOG_EXIT, "getRequiredBundles", _requiredBundles);
+ return Collections.unmodifiableCollection(_requiredBundles);
+ }
+
+
+ public ImportedBundle getFragmentHost() {
+ logger.debug(LOG_ENTRY, "getFragmentHost");
+ ImportedBundle result = _exportedBundle.getFragmentHost();
+ logger.debug(LOG_EXIT, "getFragmentHost", result);
+ return result;
+ }
+
+
+ public boolean isFragment() {
+ logger.debug(LOG_ENTRY, "isFragment");
+ boolean result = _exportedBundle.isFragment();
+ logger.debug(LOG_EXIT, "isFragment", result);
+ return result;
+ }
+}