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 [12/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-ap...
Added: aries/tags/application-0.3/application-obr-resolver/src/main/java/org/apache/aries/application/resolver/obr/OBRAriesResolver.java
URL: http://svn.apache.org/viewvc/aries/tags/application-0.3/application-obr-resolver/src/main/java/org/apache/aries/application/resolver/obr/OBRAriesResolver.java?rev=1075132&view=auto
==============================================================================
--- aries/tags/application-0.3/application-obr-resolver/src/main/java/org/apache/aries/application/resolver/obr/OBRAriesResolver.java (added)
+++ aries/tags/application-0.3/application-obr-resolver/src/main/java/org/apache/aries/application/resolver/obr/OBRAriesResolver.java Sun Feb 27 20:20:13 2011
@@ -0,0 +1,712 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.aries.application.resolver.obr;
+
+import static org.apache.aries.application.utils.AppConstants.LOG_ENTRY;
+import static org.apache.aries.application.utils.AppConstants.LOG_EXIT;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.net.URI;
+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.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.aries.application.ApplicationMetadata;
+import org.apache.aries.application.Content;
+import org.apache.aries.application.InvalidAttributeException;
+import org.apache.aries.application.VersionRange;
+import org.apache.aries.application.management.AriesApplication;
+import org.apache.aries.application.management.BundleInfo;
+import org.apache.aries.application.management.ResolveConstraint;
+import org.apache.aries.application.management.ResolverException;
+import org.apache.aries.application.management.spi.repository.PlatformRepository;
+import org.apache.aries.application.management.spi.resolve.AriesApplicationResolver;
+import org.apache.aries.application.modelling.ImportedBundle;
+import org.apache.aries.application.modelling.ModelledResource;
+import org.apache.aries.application.modelling.ModellingConstants;
+import org.apache.aries.application.modelling.ModellingManager;
+import org.apache.aries.application.modelling.utils.ModellingHelper;
+import org.apache.aries.application.resolver.internal.MessageUtil;
+import org.apache.aries.application.resolver.obr.impl.ApplicationResourceImpl;
+import org.apache.aries.application.resolver.obr.impl.ModelledBundleResource;
+import org.apache.aries.application.resolver.obr.impl.OBRBundleInfo;
+import org.apache.aries.application.resolver.obr.impl.RepositoryGeneratorImpl;
+import org.apache.aries.application.resolver.obr.impl.ResourceWrapper;
+import org.apache.aries.application.utils.AppConstants;
+import org.apache.aries.application.utils.filesystem.IOUtils;
+import org.apache.aries.application.utils.manifest.ManifestHeaderProcessor;
+import org.apache.aries.application.utils.manifest.ManifestHeaderProcessor.NameValueMap;
+import org.apache.felix.bundlerepository.Capability;
+import org.apache.felix.bundlerepository.DataModelHelper;
+import org.apache.felix.bundlerepository.Reason;
+import org.apache.felix.bundlerepository.Repository;
+import org.apache.felix.bundlerepository.RepositoryAdmin;
+import org.apache.felix.bundlerepository.Requirement;
+import org.apache.felix.bundlerepository.Resolver;
+import org.apache.felix.bundlerepository.Resource;
+import org.osgi.framework.Constants;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.framework.Version;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * @version $Rev: 1059320 $ $Date: 2011-01-15 12:58:13 +0000 (Sat, 15 Jan 2011) $
+ */
+public class OBRAriesResolver implements AriesApplicationResolver
+{
+ private static Logger log = LoggerFactory.getLogger(OBRAriesResolver.class);
+
+ private final RepositoryAdmin repositoryAdmin;
+ private boolean returnOptionalResources = true;
+ private PlatformRepository platformRepository;
+ private ModellingManager modellingManager;
+ private ModellingHelper modellingHelper;
+
+ public void setModellingManager (ModellingManager m) {
+ modellingManager = m;
+ }
+
+ public void setModellingHelper (ModellingHelper mh) {
+ modellingHelper = mh;
+ }
+
+ public PlatformRepository getPlatformRepository()
+ {
+ return platformRepository;
+ }
+
+
+
+ public RepositoryAdmin getRepositoryAdmin() {
+ return this.repositoryAdmin;
+ }
+ public void setPlatformRepository(PlatformRepository platformRepository)
+ {
+ this.platformRepository = platformRepository;
+ }
+
+ public OBRAriesResolver(RepositoryAdmin repositoryAdmin)
+ {
+ this.repositoryAdmin = repositoryAdmin;
+ }
+
+ public void setReturnOptionalResources(boolean optional)
+ {
+ this.returnOptionalResources = optional;
+ }
+
+ public boolean getReturnOptionalResources()
+ {
+ return returnOptionalResources;
+ }
+
+ public Collection<ModelledResource> resolve(String appName,
+ String appVersion, Collection<ModelledResource> byValueBundles,
+ Collection<Content> inputs) throws ResolverException {
+ return resolve(appName, appVersion, byValueBundles,
+ inputs, this.platformRepository);
+ }
+
+/**
+ * Resolve a list of resources from the OBR bundle repositories by OBR
+ * resolver.
+ *
+ * @param appName - application name
+ * @param appVersion - application version
+ * @param byValueBundles - by value bundles
+ * @param inputs - other constraints
+ * @param platformRepository - a platform repository to use instead of the one provided as a service
+ * @return a collection of modelled resources required by this application
+ * @throws ResolverException
+ */
+ @Override
+ public Collection<ModelledResource> resolve(String appName, String appVersion,
+ Collection<ModelledResource> byValueBundles, Collection<Content> inputs, PlatformRepository platformRepository)
+ throws ResolverException {
+ log.debug(LOG_ENTRY, "resolve", new Object[]{appName, appVersion,byValueBundles, inputs});
+ Collection<ImportedBundle> importedBundles = toImportedBundle(inputs);
+ Collection<ModelledResource> toReturn = new ArrayList<ModelledResource>();
+
+ Resolver obrResolver = getConfiguredObrResolver(appName, appVersion, byValueBundles, platformRepository);
+ // add a resource describing the requirements of the application metadata.
+ obrResolver.add(createApplicationResource( appName, appVersion, importedBundles));
+
+ if (obrResolver.resolve()) {
+
+ List<Resource> requiredResources = retrieveRequiredResources(obrResolver);
+
+ if (requiredResources == null) {
+ log.debug("resolver.getRequiredResources() returned null");
+ } else {
+
+ for (Resource r : requiredResources) {
+ NameValueMap<String, String> attribs = new NameValueMap<String, String>();
+ attribs.put(Constants.VERSION_ATTRIBUTE, "[" + r.getVersion() + ',' + r.getVersion()
+ + "]");
+ ModelledResource modelledResourceForThisMatch = null;
+ // OBR may give us back the global capabilities. Typically these do not have a bundle symbolic name - they're a
+ // list of packages available in the target runtime environment. If the resource has no symbolic name, we can ignore it
+ if (r.getSymbolicName() != null) {
+ try {
+ modelledResourceForThisMatch = new ModelledBundleResource (r, modellingManager, modellingHelper);
+ } catch (InvalidAttributeException iax) {
+
+ ResolverException re = new ResolverException("Internal error occurred: " + iax.toString());
+ log.debug(LOG_EXIT, "resolve", re);
+
+ throw re;
+ }
+ toReturn.add(modelledResourceForThisMatch);
+ }
+ }
+ }
+ log.debug(LOG_EXIT, "resolve", toReturn);
+ return toReturn;
+ } else {
+ Reason[] reasons = obrResolver.getUnsatisfiedRequirements();
+ // let's refine the list by removing the indirect unsatisfied bundles that are caused by unsatisfied packages or other bundles
+ Map<String,Set<String>> refinedReqs = refineUnsatisfiedRequirements(obrResolver, reasons);
+ StringBuffer reqList = new StringBuffer();
+ List<String> unsatisfiedRequirements = new LinkedList<String>();
+
+ for (Map.Entry<String, Set<String>> filterEntry : refinedReqs.entrySet()) {
+ log.debug("unable to satisfy the filter , filter = " + filterEntry.getKey() + "required by "+filterEntry.getValue());
+
+ String reason = extractConsumableMessageInfo(filterEntry.getKey(),filterEntry.getValue());
+
+ reqList.append('\n');
+ reqList.append(reason);
+ unsatisfiedRequirements.add(reason);
+ }
+
+ ResolverException re = new ResolverException(MessageUtil.getMessage("RESOLVER_UNABLE_TO_RESOLVE",
+ new Object[] { appName, reqList }));
+ re.setUnsatisfiedRequirements(unsatisfiedRequirements);
+ log.debug(LOG_EXIT, "resolve", re);
+
+ throw re;
+ }
+
+ }
+
+ private Resolver getConfiguredObrResolver(String appName, String appVersion,
+ Collection<ModelledResource> byValueBundles) throws ResolverException
+ {
+
+ return getConfiguredObrResolver(appName, appVersion, byValueBundles, platformRepository);
+ }
+
+ private Resolver getConfiguredObrResolver(String appName, String appVersion,
+ Collection<ModelledResource> byValueBundles, PlatformRepository platformRepository) throws ResolverException
+ {
+ log.debug(LOG_ENTRY, "getConfiguredObrResolver", new Object[]{appName, appVersion,byValueBundles });
+ DataModelHelper helper = repositoryAdmin.getHelper();
+ Repository appRepo;
+ try {
+ ByteArrayOutputStream bytesOut = new ByteArrayOutputStream();
+ RepositoryGeneratorImpl.generateRepository(repositoryAdmin, appName + "_" + appVersion, byValueBundles, bytesOut);
+ appRepo = helper.readRepository(new InputStreamReader(new ByteArrayInputStream(bytesOut.toByteArray())));
+ } catch (Exception e) {
+ throw new ResolverException(e);
+ }
+
+ List<Repository> resolveRepos = new ArrayList<Repository>();
+ // add system repository
+ resolveRepos.add(repositoryAdmin.getSystemRepository());
+ // add local repository if configured
+ if (!(excludeLocalRuntime())) {
+ resolveRepos.add(getLocalRepository(repositoryAdmin));
+ }
+ // add application repository
+ resolveRepos.add(appRepo);
+ // Need to refresh the repositories added to repository admin
+ // add user-defined repositories
+ Repository[] repos = repositoryAdmin.listRepositories();
+ for (Repository r : repos) {
+ resolveRepos.add(r);
+ }
+ Resolver obrResolver = repositoryAdmin.resolver(resolveRepos.toArray(new Repository[resolveRepos.size()]));
+ addPlatformRepositories (obrResolver, appName, platformRepository);
+ log.debug(LOG_EXIT, "getConfiguredObrResolver", obrResolver);
+ return obrResolver;
+ }
+
+
+ @Deprecated
+ @Override
+ public Set<BundleInfo> resolve(AriesApplication app, ResolveConstraint... constraints) throws ResolverException
+ {
+ log.trace("resolving {}", app);
+ ApplicationMetadata appMeta = app.getApplicationMetadata();
+
+ String appName = appMeta.getApplicationSymbolicName();
+ Version appVersion = appMeta.getApplicationVersion();
+ List<Content> appContent = appMeta.getApplicationContents();
+
+ Collection<Content> useBundleContent = appMeta.getUseBundles();
+ List<Content> contents = new ArrayList<Content>();
+ contents.addAll(appContent);
+ contents.addAll(useBundleContent);
+ if ((constraints != null ) && (constraints.length > 0 )) {
+ for (ResolveConstraint con: constraints) {
+ contents.add(ManifestHeaderProcessor.parseContent(con.getBundleName(), con.getVersionRange().toString()));
+ }
+ }
+
+ Resolver obrResolver = getConfiguredObrResolver(appName, appVersion.toString(), toModelledResource(app.getBundleInfo()));
+ // add a resource describing the requirements of the application metadata.
+ obrResolver.add(createApplicationResource( appName, appVersion, contents));
+ if (obrResolver.resolve()) {
+ Set<BundleInfo> result = new HashSet<BundleInfo>();
+ List<Resource> requiredResources = retrieveRequiredResources(obrResolver);
+
+ for (Resource resource: requiredResources) {
+ BundleInfo bundleInfo = toBundleInfo(resource, false);
+ result.add(bundleInfo);
+ }
+ if (returnOptionalResources) {
+ for (Resource resource: obrResolver.getOptionalResources()) {
+ BundleInfo bundleInfo = toBundleInfo(resource, true);
+ result.add(bundleInfo);
+ }
+ }
+
+ return result;
+ } else {
+ Reason[] reasons = obrResolver.getUnsatisfiedRequirements();
+ //refine the list by removing the indirect unsatisfied bundles that are caused by unsatisfied packages or other bundles
+ Map<String,Set<String>> refinedReqs = refineUnsatisfiedRequirements(obrResolver, reasons);
+ StringBuffer reqList = new StringBuffer();
+ List<String> unsatisfiedRequirements = new LinkedList<String>();
+
+ for (Map.Entry<String, Set<String>> filterEntry : refinedReqs.entrySet()) {
+ log.debug("unable to satisfied the filter , filter = " + filterEntry.getKey() + "required by "+filterEntry.getValue());
+
+ String reason = extractConsumableMessageInfo(filterEntry.getKey(),filterEntry.getValue());
+
+ reqList.append('\n');
+ reqList.append(reason);
+ unsatisfiedRequirements.add(reason);
+ }
+
+ ResolverException re = new ResolverException(MessageUtil.getMessage("RESOLVER_UNABLE_TO_RESOLVE",
+ new Object[] { app.getApplicationMetadata().getApplicationName(), reqList }));
+ re.setUnsatisfiedRequirements(unsatisfiedRequirements);
+ log.debug(LOG_EXIT, "resolve", re);
+
+ throw re;
+ }
+ }
+
+
+
+ @Override
+ public BundleInfo getBundleInfo(String bundleSymbolicName, Version bundleVersion)
+ {
+ Map<String, String> attribs = new HashMap<String, String>();
+ attribs.put(Resource.VERSION, bundleVersion.toString());
+ String filterString = ManifestHeaderProcessor.generateFilter(Resource.SYMBOLIC_NAME, bundleSymbolicName, attribs);
+ Resource[] resources;
+ try {
+ resources = repositoryAdmin.discoverResources(filterString);
+ if (resources != null && resources.length > 0) {
+ return toBundleInfo(resources[0], false);
+ } else {
+ return null;
+ }
+ } catch (InvalidSyntaxException e) {
+ log.error("Invalid filter", e);
+ return null;
+ }
+ }
+
+ /* A 'platform repository' describes capabilities of the target runtime environment
+ * These should be added to the resolver without being listed as coming from a particular
+ * repository or bundle.
+ */
+ private void addPlatformRepositories (Resolver obrResolver, String appName, PlatformRepository platformRepository)
+ {
+ log.debug(LOG_ENTRY, "addPlatformRepositories", new Object[]{obrResolver, appName});
+ DataModelHelper helper = repositoryAdmin.getHelper();
+ if (platformRepository != null) {
+ Collection<URI> uris = platformRepository.getPlatformRepositoryURLs();
+ if ((uris != null) && (!uris.isEmpty())) {
+ for (URI uri : uris) {
+ InputStream is = null;
+ try {
+ is = uri.toURL().openStream();
+ Reader repoReader = new InputStreamReader(is);
+ Repository aPlatformRepo = helper.readRepository(repoReader);
+ Resource resources[] = aPlatformRepo.getResources();
+ for (Resource r : resources) {
+ Capability[] caps = r.getCapabilities();
+ for (Capability c : caps) {
+ obrResolver.addGlobalCapability(c);
+ }
+ }
+ } catch (Exception e) {
+ // not a big problem
+ log.error(MessageUtil.getMessage("RESOLVER_UNABLE_TO_READ_REPOSITORY_EXCEPTION", new Object[]{appName, uri}) );
+ } finally {
+ IOUtils.close(is);
+ }
+ }
+ }
+ }
+ log.debug(LOG_EXIT, "addPlatformRepositories");
+ }
+
+ private Resource createApplicationResource( String appName, Version appVersion,
+ List<Content> appContent)
+ {
+ return new ApplicationResourceImpl(appName, appVersion, appContent);
+ }
+
+ private Resource createApplicationResource( String appName, String appVersion,
+ Collection<ImportedBundle> inputs)
+ {
+ return new ApplicationResourceImpl(appName, Version.parseVersion(appVersion), inputs);
+ }
+
+ private BundleInfo toBundleInfo(Resource resource, boolean optional)
+ {
+ Map<String, String> directives = null;
+ if (optional) {
+ directives = new HashMap<String, String>();
+ directives.put(Constants.RESOLUTION_DIRECTIVE, Constants.RESOLUTION_OPTIONAL);
+ }
+
+
+ return new OBRBundleInfo(resource.getSymbolicName(),
+ resource.getVersion(),
+ resource.getURI(),
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ directives,
+ null);
+
+ }
+
+ /**
+ * Get the list of resources returned by the resolver
+ * @param resolver OBR resolver
+ * @return a list of required resources
+ */
+ protected List<Resource> retrieveRequiredResources(Resolver resolver)
+ {
+ log.debug(LOG_ENTRY,"retrieveRequiredResources", resolver);
+ Map<String, List<Resource>> resourcesByName = new HashMap<String, List<Resource>>();
+
+ for (Resource r : resolver.getRequiredResources()) {
+ resourcesByName.put(r.getSymbolicName(), mergeResource(resolver, r, resourcesByName.get(r
+ .getSymbolicName())));
+ }
+
+ List<Resource> result = new ArrayList<Resource>();
+ for (List<Resource> res : resourcesByName.values()) {
+ result.addAll(res);
+ }
+
+ log.debug(LOG_EXIT, "retrieveRequiredResources", result);
+ return result;
+ }
+
+
+/**
+ * Get rid of the redundant resources
+ * @param resolver OBR resolver
+ * @param r a resource
+ * @param list similar resources
+ * @return the list of minimum resources
+ */
+ protected List<Resource> mergeResource(Resolver resolver, Resource r,
+ List<Resource> list)
+ {
+ log.debug(LOG_ENTRY, "mergeResource", new Object[]{resolver, r, list});
+
+ if (list == null) {
+ log.debug(LOG_EXIT, "mergeResource", Arrays.asList(r));
+ return Arrays.asList(r);
+ } else {
+ List<Resource> result = new ArrayList<Resource>();
+
+ for (Resource old : list) {
+ boolean oldRedundant = satisfiesAll(r, resolver.getReason(old));
+ boolean newRedundant = satisfiesAll(old, resolver.getReason(r));
+ if (oldRedundant && newRedundant) {
+ int comp = old.getVersion().compareTo(r.getVersion());
+ oldRedundant = comp < 0;
+ newRedundant = comp >= 0;
+ }
+
+ if (newRedundant) {
+ log.debug(LOG_EXIT, "mergeResource", list);
+ return list;
+ } else if (oldRedundant) {
+ // do nothing -> so don't add the old resource to the new list
+ } else {
+ result.add(old);
+ }
+ }
+
+ result.add(r);
+
+ log.debug(LOG_EXIT, "mergeResource", result);
+
+ return result;
+ }
+ }
+ protected boolean satisfiesAll(Resource res, Reason[] reasons)
+ {
+ log.debug(LOG_ENTRY,"satisfiesAll", new Object[] {res, Arrays.toString(reasons)});
+ //Let's convert the reason to requirement
+ List<Requirement> reqs = new ArrayList<Requirement>();
+ for (Reason reason : reasons) {
+ reqs.add(reason.getRequirement());
+ }
+ boolean result = true;
+
+ outer: for (Requirement r : reqs) {
+ boolean found = false;
+ inner: for (Capability c : res.getCapabilities()) {
+ if (r.isSatisfied(c)) {
+ found = true;
+ break inner;
+ }
+ }
+
+ if (!!!found && !!!r.isOptional()) {
+ result = false;
+ break outer;
+ }
+ }
+ log.debug(LOG_EXIT, "satisfiesAll", result);
+ return result;
+ }
+
+ private static final Set<String> SPECIAL_FILTER_ATTRS = Collections
+ .unmodifiableSet(new HashSet<String>(Arrays.asList(ModellingConstants.OBR_PACKAGE,
+ ModellingConstants.OBR_SYMBOLIC_NAME, ModellingConstants.OBR_SERVICE, Constants.VERSION_ATTRIBUTE)));
+
+ /**
+ * Turn a requirement into a human readable String for debug.
+ * @param filter The filter that is failing
+ * @param bundlesFailing For problems with a bundle, the set of bundles that have a problem
+ * @return human readable form
+ */
+ private String extractConsumableMessageInfo(String filter, Set<String> bundlesFailing)
+ {
+ log.debug(LOG_ENTRY, "extractConsumableMessageInfo", new Object[] {filter, bundlesFailing});
+
+ Map<String, String> attrs = ManifestHeaderProcessor.parseFilter(filter);
+ Map<String, String> customAttrs = new HashMap<String, String>();
+ for (Map.Entry<String, String> e : attrs.entrySet()) {
+ if (!SPECIAL_FILTER_ATTRS.contains(e.getKey())) {
+ customAttrs.put(e.getKey(), e.getValue());
+ }
+ }
+
+ StringBuilder msgKey = new StringBuilder();
+ List<Object> inserts = new ArrayList<Object>();
+
+ boolean unknownType = false;
+ if (attrs.containsKey(ModellingConstants.OBR_PACKAGE)) {
+ msgKey.append("RESOLVER_UNABLE_TO_RESOLVE_PACKAGE");
+ inserts.add(attrs.get(ModellingConstants.OBR_PACKAGE));
+ } else if (attrs.containsKey(ModellingConstants.OBR_SYMBOLIC_NAME)) {
+ msgKey.append("RESOLVER_UNABLE_TO_RESOLVE_BUNDLE");
+ inserts.add(attrs.get(ModellingConstants.OBR_SYMBOLIC_NAME));
+ } else if (attrs.containsKey(ModellingConstants.OBR_SERVICE)) {
+ msgKey.append("RESOLVER_UNABLE_TO_RESOLVE_SERVICE");
+ //No insert for service name as the name must be "*" to match any Service capability
+ } else {
+ unknownType = true;
+ msgKey.append("RESOLVER_UNABLE_TO_RESOLVE_FILTER");
+ inserts.add(filter);
+ }
+
+ if (bundlesFailing != null && bundlesFailing.size() != 0) {
+ msgKey.append("_REQUIRED_BY_BUNDLE");
+ if (bundlesFailing.size() == 1)
+ inserts.add(bundlesFailing.iterator().next()); // Just take the string if there's only one of them
+ else
+ inserts.add(bundlesFailing.toString()); // Add the whole set if there isn't exactly one
+ }
+ if (!unknownType && !customAttrs.isEmpty()) {
+ msgKey.append("_WITH_ATTRS");
+ inserts.add(customAttrs);
+ }
+
+ if (!unknownType && attrs.containsKey(Constants.VERSION_ATTRIBUTE)) {
+ msgKey.append("_WITH_VERSION");
+ VersionRange vr = ManifestHeaderProcessor.parseVersionRange(attrs
+ .get(Constants.VERSION_ATTRIBUTE));
+ inserts.add(vr.getMinimumVersion());
+
+ if (!!!vr.isExactVersion()) {
+ msgKey.append(vr.isMinimumExclusive() ? "_LOWEX" : "_LOW");
+ if (vr.getMaximumVersion() != null) {
+ msgKey.append(vr.isMaximumExclusive() ? "_UPEX" : "_UP");
+ inserts.add(vr.getMaximumVersion());
+ }
+ }
+ }
+
+ String msgKeyStr = msgKey.toString();
+
+ String msg = MessageUtil.getMessage(msgKeyStr, inserts.toArray());
+
+ log.debug(LOG_EXIT, "extractConsumableMessageInfo", msg);
+
+ return msg;
+ }
+
+ /**
+ * Refine the unsatisfied requirements ready for later human comsumption
+ *
+ * @param resolver The resolver to be used to refine the requirements
+ * @param reasons The reasons
+ * @return A map of the unsatifiedRequirement to the set of bundles that have that requirement unsatisfied (values associated with the keys can be null)
+ */
+ private Map<String,Set<String>> refineUnsatisfiedRequirements(Resolver resolver, Reason[] reasons) {
+ log.debug(LOG_ENTRY, "refineUnsatisfiedRequirements", new Object[]{resolver, Arrays.toString(reasons)});
+
+ Map<Requirement,Set<String>> req_resources = new HashMap<Requirement,Set<String>>();
+ // add the reasons to the map, use the requirement as the key, the resources required the requirement as the values
+ Set<Resource> resources = new HashSet<Resource>();
+ for (Reason reason: reasons) {
+ resources.add(reason.getResource());
+ Requirement key = reason.getRequirement();
+ String value = reason.getResource().getSymbolicName()+"_" + reason.getResource().getVersion().toString();
+ Set<String> values = req_resources.get(key);
+ if (values == null) {
+ values = new HashSet<String>();
+ }
+ values.add(value);
+ req_resources.put(key, values);
+ }
+
+ // remove the requirements that can be satisifed by the resources. It is listed because the resources are not satisfied by other requirements.
+ // For an instance, the unsatisfied reasons are [package a, required by bundle aa], [package b, required by bundle bb] and [package c, required by bundle cc],
+ // If the bundle aa exports the package a and c. In our error message, we only want to display package a is needed by bundle aa.
+ // Go through each requirement and find out whether the requirement can be satisfied by the reasons.
+ Set<Capability> caps = new HashSet<Capability>();
+ for (Resource res : resources) {
+ if ((res !=null) && (res.getCapabilities() != null)) {
+
+ List<Capability> capList = Arrays.asList(res.getCapabilities());
+ if (capList != null) {
+ caps.addAll(capList);
+ }
+ }
+ }
+ Iterator<Map.Entry<Requirement, Set<String>>> iterator = req_resources.entrySet().iterator();
+ while (iterator.hasNext()) {
+ Map.Entry<Requirement, Set<String>> entry = iterator.next();
+ Requirement req = entry.getKey();
+ for (Capability cap :caps) {
+ if (req.isSatisfied(cap)){ // remove the key from the map
+ iterator.remove();
+ break;
+ }
+ }
+ }
+ //Now the map only contains the necessary missing requirements
+
+ Map<String,Set<String>> result = new HashMap<String, Set<String>>();
+ for (Map.Entry<Requirement, Set<String>> req_res : req_resources.entrySet()) {
+ result.put(req_res.getKey().getFilter(), req_res.getValue());
+ }
+ log.debug(LOG_EXIT, "refineUnsatisfiedRequirements", new Object[]{result});
+
+ return result;
+ }
+
+
+
+ private Collection<ImportedBundle> toImportedBundle(Collection<Content> content) throws ResolverException
+ {
+ log.debug(LOG_ENTRY, "toImportedBundle", content);
+
+ List<ImportedBundle> result = new ArrayList<ImportedBundle>();
+ for (Content c : content) {
+ try {
+ result.add(modellingManager.getImportedBundle(c.getContentName(), c.getVersion().toString()));
+ } catch (InvalidAttributeException iae) {
+ throw new ResolverException(iae);
+ }
+ }
+ log.debug(LOG_EXIT, "toImportedBundle", result);
+ return result;
+ }
+
+ private Collection<ModelledResource> toModelledResource(Collection<BundleInfo> bundleInfos) throws ResolverException{
+
+ Collection<ModelledResource> result = new ArrayList<ModelledResource>();
+
+ if ((bundleInfos != null) && (!!!bundleInfos.isEmpty())) {
+ for (BundleInfo bi : bundleInfos) {
+ try {
+ result.add(modellingManager.getModelledResource(null, bi, null, null));
+ } catch (InvalidAttributeException iae) {
+ throw new ResolverException(iae);
+ }
+ }
+ }
+ return result;
+ }
+
+ private Repository getLocalRepository(RepositoryAdmin admin)
+ {
+ Repository localRepository = repositoryAdmin.getLocalRepository();
+
+ Resource[] resources = localRepository.getResources();
+
+ Resource[] newResources = new Resource[resources.length];
+ for (int i = 0; i < resources.length; i++) {
+ newResources[i] = new ResourceWrapper(resources[i]);
+ }
+
+ return repositoryAdmin.getHelper().repository(newResources);
+ }
+
+
+ private boolean excludeLocalRuntime() {
+ return Boolean.parseBoolean(System.getProperty(AppConstants.PROVISON_EXCLUDE_LOCAL_REPO_SYSPROP));
+ }
+
+}
Added: aries/tags/application-0.3/application-obr-resolver/src/main/java/org/apache/aries/application/resolver/obr/ext/BundleResource.java
URL: http://svn.apache.org/viewvc/aries/tags/application-0.3/application-obr-resolver/src/main/java/org/apache/aries/application/resolver/obr/ext/BundleResource.java?rev=1075132&view=auto
==============================================================================
--- aries/tags/application-0.3/application-obr-resolver/src/main/java/org/apache/aries/application/resolver/obr/ext/BundleResource.java (added)
+++ aries/tags/application-0.3/application-obr-resolver/src/main/java/org/apache/aries/application/resolver/obr/ext/BundleResource.java Sun Feb 27 20:20:13 2011
@@ -0,0 +1,228 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.aries.application.resolver.obr.ext;
+
+import static org.apache.aries.application.utils.AppConstants.LOG_ENTRY;
+import static org.apache.aries.application.utils.AppConstants.LOG_EXIT;
+
+import java.net.MalformedURLException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Map;
+
+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.resolver.obr.impl.OBRCapability;
+import org.apache.aries.application.resolver.obr.impl.RequirementImpl;
+import org.apache.felix.bundlerepository.Capability;
+import org.apache.felix.bundlerepository.RepositoryAdmin;
+import org.apache.felix.bundlerepository.Requirement;
+import org.apache.felix.bundlerepository.Resource;
+import org.osgi.framework.Version;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class BundleResource implements Resource
+{
+
+ private final ModelledResource _modelledBundle;
+ private final Collection<Capability> _capabilities;
+ private final Collection<Requirement> _requirements;
+ private final String _displayName;
+ private Logger logger = LoggerFactory.getLogger(BundleResource.class);
+
+ /**
+ * Build a BundleResource from another BundleResource and some optional extra capabilities and requirements
+ * @param br
+ * @param extraCapabilities can be null
+ * @param extraRequirements can be null
+ */
+ public BundleResource (BundleResource br, Collection<Capability> extraCapabilities, Collection<Requirement> extraRequirements) {
+ _modelledBundle = br._modelledBundle;
+ _capabilities = new ArrayList<Capability> (br._capabilities);
+ _requirements = new ArrayList<Requirement> (br._requirements);
+ _displayName = new String (br._displayName);
+ if (extraCapabilities != null) _capabilities.addAll(extraCapabilities);
+ if (extraRequirements != null) _requirements.addAll(extraRequirements);
+ }
+
+ public BundleResource (ModelledResource mb, RepositoryAdmin repositoryAdmin) {
+ logger.debug(LOG_ENTRY,"BundleResource", mb);
+ _modelledBundle = mb;
+
+ _capabilities = new ArrayList<Capability>();
+ _capabilities.add(new OBRCapability(_modelledBundle.getExportedBundle(), repositoryAdmin));
+
+ for (ExportedPackage pkg : _modelledBundle.getExportedPackages()) {
+ _capabilities.add(new OBRCapability(pkg, repositoryAdmin));
+ }
+
+ for (ExportedService svc : _modelledBundle.getExportedServices()) {
+ _capabilities.add(new OBRCapability(svc, repositoryAdmin));
+ }
+
+ _requirements = new ArrayList<Requirement>();
+ for (ImportedPackage pkg : _modelledBundle.getImportedPackages()) {
+ _requirements.add(new RequirementImpl(pkg));
+ }
+
+ for (ImportedService svc : _modelledBundle.getImportedServices()) {
+ _requirements.add(new RequirementImpl(svc));
+ }
+
+ for (ImportedBundle requiredBundle : _modelledBundle.getRequiredBundles()) {
+ _requirements.add(new RequirementImpl(requiredBundle));
+ }
+
+ if(mb.isFragment())
+ _requirements.add(new RequirementImpl(mb.getFragmentHost()));
+
+ String possibleDisplayName = (String) mb.getExportedBundle().getAttributes().get(
+ ModellingConstants.OBR_PRESENTATION_NAME);
+ if (possibleDisplayName == null) {
+ _displayName = mb.getSymbolicName();
+ } else {
+ _displayName = possibleDisplayName;
+ }
+
+
+
+ logger.debug(LOG_EXIT,"BundleResource");
+
+ }
+
+ public ModelledResource getModelledResource() {
+ return _modelledBundle;
+ }
+
+ public Capability[] getCapabilities() {
+
+ logger.debug(LOG_ENTRY,"getCapabilities");
+ Capability [] result = _capabilities.toArray(new Capability[_capabilities.size()]);
+ logger.debug(LOG_EXIT,"getCapabilities", result);
+ return result;
+ }
+
+
+ public String[] getCategories() {
+ logger.debug(LOG_ENTRY,"getCategories");
+ logger.debug(LOG_EXIT,"getCategories", null);
+ return null;
+ }
+
+
+ public String getId() {
+ logger.debug(LOG_ENTRY,"getId");
+ String id = _modelledBundle.getSymbolicName() + '/' + _modelledBundle.getVersion();
+ logger.debug(LOG_EXIT,"getId", id);
+ return id;
+ }
+
+
+ public String getPresentationName() {
+
+ logger.debug(LOG_ENTRY,"getPresentationName");
+ logger.debug(LOG_EXIT,"getPresentationName", _displayName);
+ return _displayName;
+ }
+
+
+ @SuppressWarnings("unchecked")
+ public Map getProperties() {
+ logger.debug(LOG_ENTRY,"getProperties");
+ logger.debug(LOG_EXIT,"getProperties", null);
+
+ return null;
+ }
+
+
+
+
+ public Requirement[] getRequirements() {
+ logger.debug(LOG_ENTRY,"getRequirements");
+ Requirement [] result = _requirements.toArray(new Requirement[_requirements.size()]);
+ logger.debug(LOG_EXIT,"getRequirements", result);
+ return result;
+ }
+
+
+ public String getSymbolicName() {
+ logger.debug(LOG_ENTRY,"getSymbolicName");
+ String result = _modelledBundle.getSymbolicName();
+ logger.debug(LOG_EXIT,"getSymbolicName", result);
+ return result;
+ }
+
+
+ public URL getURL() {
+
+ logger.debug(LOG_ENTRY,"getURL");
+ URL url = null;
+ try {
+ URI uri = new URI(_modelledBundle.getLocation());
+ url = uri.toURL();
+ } catch (URISyntaxException e) {
+ logger.error(e.getMessage());
+ } catch (MalformedURLException e) {
+ logger.error(e.getMessage());
+ }
+ logger.debug(LOG_EXIT,"getURL", url);
+ return url;
+ }
+
+
+ public Version getVersion() {
+ logger.debug(LOG_ENTRY,"getVersion");
+ Version v = new Version(_modelledBundle.getVersion());
+ logger.debug(LOG_EXIT,"getVersion", v);
+ return v;
+ }
+
+ public Long getSize()
+ {
+ logger.debug(LOG_ENTRY,"getSize");
+ logger.debug(LOG_EXIT,"getSize", 5l);
+ return 5l;
+ }
+
+ public String getURI()
+ {
+ logger.debug(LOG_ENTRY,"getURI");
+ String uri = _modelledBundle.getLocation();
+ logger.debug(LOG_EXIT,"getURI", uri);
+ return uri;
+ }
+
+ public boolean isLocal()
+ {
+ logger.debug(LOG_ENTRY,"isLocal");
+ logger.debug(LOG_EXIT,"isLocal", false);
+ return false;
+ }
+
+}
Added: aries/tags/application-0.3/application-obr-resolver/src/main/java/org/apache/aries/application/resolver/obr/ext/BundleResourceTransformer.java
URL: http://svn.apache.org/viewvc/aries/tags/application-0.3/application-obr-resolver/src/main/java/org/apache/aries/application/resolver/obr/ext/BundleResourceTransformer.java?rev=1075132&view=auto
==============================================================================
--- aries/tags/application-0.3/application-obr-resolver/src/main/java/org/apache/aries/application/resolver/obr/ext/BundleResourceTransformer.java (added)
+++ aries/tags/application-0.3/application-obr-resolver/src/main/java/org/apache/aries/application/resolver/obr/ext/BundleResourceTransformer.java Sun Feb 27 20:20:13 2011
@@ -0,0 +1,27 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.aries.application.resolver.obr.ext;
+
+
+public interface BundleResourceTransformer {
+
+ BundleResource transform (BundleResource b);
+}
+
+
Added: aries/tags/application-0.3/application-obr-resolver/src/main/java/org/apache/aries/application/resolver/obr/impl/ApplicationResourceImpl.java
URL: http://svn.apache.org/viewvc/aries/tags/application-0.3/application-obr-resolver/src/main/java/org/apache/aries/application/resolver/obr/impl/ApplicationResourceImpl.java?rev=1075132&view=auto
==============================================================================
--- aries/tags/application-0.3/application-obr-resolver/src/main/java/org/apache/aries/application/resolver/obr/impl/ApplicationResourceImpl.java (added)
+++ aries/tags/application-0.3/application-obr-resolver/src/main/java/org/apache/aries/application/resolver/obr/impl/ApplicationResourceImpl.java Sun Feb 27 20:20:13 2011
@@ -0,0 +1,180 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.aries.application.resolver.obr.impl;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Dictionary;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.aries.application.Content;
+import org.apache.aries.application.modelling.ImportedBundle;
+import org.apache.aries.application.utils.manifest.ManifestHeaderProcessor;
+import org.apache.felix.bundlerepository.Capability;
+import org.apache.felix.bundlerepository.Requirement;
+import org.apache.felix.bundlerepository.Resource;
+import org.osgi.framework.Filter;
+import org.osgi.framework.FrameworkUtil;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.framework.ServiceReference;
+import org.osgi.framework.Version;
+
+public class ApplicationResourceImpl implements Resource
+{
+ private String _symbolicName;
+ private Version _version;
+ private List<Requirement> _requirements = new ArrayList<Requirement>();
+
+ private static class FilterWrapper implements Filter
+ {
+ private Filter delgate;
+
+ public FilterWrapper(Filter f)
+ {
+ delgate = f;
+ }
+
+ public boolean match(ServiceReference reference)
+ {
+ return delgate.match(reference);
+ }
+
+ public boolean match(Dictionary dictionary)
+ {
+ boolean result = delgate.match(dictionary);
+ return result;
+ }
+
+ public boolean matchCase(Dictionary dictionary)
+ {
+ return delgate.matchCase(dictionary);
+ }
+
+ public String toString()
+ {
+ return delgate.toString();
+ }
+ }
+
+ public ApplicationResourceImpl(String appName, Version appVersion, List<Content> appContent)
+ {
+ _symbolicName = appName;
+ _version = appVersion;
+
+
+ for (int i = 0; i < appContent.size(); i++) {
+ Content c = appContent.get(i);
+
+ String comment = "Requires " + Resource.SYMBOLIC_NAME + " " + c.getContentName() + " with attributes " + c.getAttributes();
+
+ String resolution = c.getDirective("resolution");
+
+ boolean optional = Boolean.valueOf(resolution);
+
+ String f = ManifestHeaderProcessor.generateFilter(Resource.SYMBOLIC_NAME, c.getContentName(), c.getAttributes());
+ Filter filter;
+ try {
+ filter = FrameworkUtil.createFilter(f);
+ _requirements.add(new RequirementImpl("bundle", new FilterWrapper(filter), false, optional, false, comment));
+ } catch (InvalidSyntaxException e) {
+ // TODO work out what to do if this happens. If it does our filter generation code is bust.
+ }
+ }
+ }
+
+ public ApplicationResourceImpl(String appName, Version appVersion, Collection<ImportedBundle> inputs)
+ {
+ _symbolicName = appName;
+ _version = appVersion;
+
+ for (ImportedBundle match : inputs) {
+ _requirements.add(new RequirementImpl(match));
+ }
+ }
+ public Capability[] getCapabilities()
+ {
+ return null;
+ }
+
+ public String[] getCategories()
+ {
+ return null;
+ }
+
+ public String getId()
+ {
+ return _symbolicName;
+ }
+
+ public String getPresentationName()
+ {
+ return _symbolicName;
+ }
+
+ public Map getProperties()
+ {
+ return null;
+ }
+
+ public Requirement[] getRequirements()
+ {
+ if (_requirements!= null) {
+ Requirement[] reqs = new Requirement[_requirements.size()];
+ int index =0;
+ for (Requirement req: _requirements) {
+ reqs[index++] = req;
+ }
+ return reqs;
+ } else {
+ return null;
+ }
+
+ }
+
+ public String getSymbolicName()
+ {
+ return _symbolicName;
+ }
+
+ public java.net.URL getURL()
+ {
+ return null;
+ }
+
+ public Version getVersion()
+ {
+ return _version;
+ }
+
+ public Long getSize()
+ {
+ return 0l;
+ }
+
+ public String getURI()
+ {
+ return null;
+ }
+
+ public boolean isLocal()
+ {
+ return false;
+ }
+}
\ No newline at end of file
Added: aries/tags/application-0.3/application-obr-resolver/src/main/java/org/apache/aries/application/resolver/obr/impl/MapToDictionary.java
URL: http://svn.apache.org/viewvc/aries/tags/application-0.3/application-obr-resolver/src/main/java/org/apache/aries/application/resolver/obr/impl/MapToDictionary.java?rev=1075132&view=auto
==============================================================================
--- aries/tags/application-0.3/application-obr-resolver/src/main/java/org/apache/aries/application/resolver/obr/impl/MapToDictionary.java (added)
+++ aries/tags/application-0.3/application-obr-resolver/src/main/java/org/apache/aries/application/resolver/obr/impl/MapToDictionary.java Sun Feb 27 20:20:13 2011
@@ -0,0 +1,123 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+
+package org.apache.aries.application.resolver.obr.impl;
+
+import java.util.Dictionary;
+import java.util.Enumeration;
+import java.util.Iterator;
+import java.util.Map;
+
+/**
+ * @version $Rev: 911397 $ $Date: 2010-02-18 13:41:27 +0000 (Thu, 18 Feb 2010) $
+ */
+public class MapToDictionary extends Dictionary
+{
+ /**
+ * Map source.
+ */
+ private final Map m_map;
+
+ public MapToDictionary(Map map)
+ {
+ m_map = map;
+ }
+
+ public Enumeration elements()
+ {
+ if (m_map == null) {
+ return null;
+ }
+ return new IteratorToEnumeration(m_map.values().iterator());
+ }
+
+ public Object get(Object key)
+ {
+ if (m_map == null) {
+ return null;
+ }
+ return m_map.get(key);
+ }
+
+ public boolean isEmpty()
+ {
+ if (m_map == null) {
+ return true;
+ }
+ return m_map.isEmpty();
+ }
+
+ public Enumeration keys()
+ {
+ if (m_map == null) {
+ return null;
+ }
+ return new IteratorToEnumeration(m_map.keySet().iterator());
+ }
+
+ public Object put(Object key, Object value)
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ public Object remove(Object key)
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ public int size()
+ {
+ if (m_map == null) {
+ return 0;
+ }
+ return m_map.size();
+ }
+
+ @Override
+ public String toString()
+ {
+ return m_map != null ? m_map.toString() : "null";
+ }
+
+ private static class IteratorToEnumeration implements Enumeration
+ {
+ private final Iterator m_iter;
+
+ public IteratorToEnumeration(Iterator iter)
+ {
+ m_iter = iter;
+ }
+
+ public boolean hasMoreElements()
+ {
+ if (m_iter == null)
+ return false;
+ return m_iter.hasNext();
+ }
+
+ public Object nextElement()
+ {
+ if (m_iter == null)
+ return null;
+ return m_iter.next();
+ }
+ }
+
+}
Added: aries/tags/application-0.3/application-obr-resolver/src/main/java/org/apache/aries/application/resolver/obr/impl/ModelledBundleResource.java
URL: http://svn.apache.org/viewvc/aries/tags/application-0.3/application-obr-resolver/src/main/java/org/apache/aries/application/resolver/obr/impl/ModelledBundleResource.java?rev=1075132&view=auto
==============================================================================
--- aries/tags/application-0.3/application-obr-resolver/src/main/java/org/apache/aries/application/resolver/obr/impl/ModelledBundleResource.java (added)
+++ aries/tags/application-0.3/application-obr-resolver/src/main/java/org/apache/aries/application/resolver/obr/impl/ModelledBundleResource.java Sun Feb 27 20:20:13 2011
@@ -0,0 +1,313 @@
+/*
+ * 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.resolver.obr.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 org.apache.aries.application.InvalidAttributeException;
+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.ModellingManager;
+import org.apache.aries.application.modelling.ResourceType;
+import org.apache.aries.application.modelling.utils.ModellingHelper;
+import org.apache.aries.application.resolver.internal.MessageUtil;
+import org.apache.aries.application.utils.AppConstants;
+import org.apache.aries.application.utils.manifest.ManifestHeaderProcessor;
+import org.apache.felix.bundlerepository.Capability;
+import org.apache.felix.bundlerepository.Property;
+import org.apache.felix.bundlerepository.Requirement;
+import org.apache.felix.bundlerepository.Resource;
+import org.osgi.framework.Constants;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class ModelledBundleResource implements ModelledResource {
+ private final Resource resource;
+ private final ExportedBundle exportedBundle;
+ private final Collection<ImportedPackage> packageRequirements;
+ private final Collection<ImportedService> serviceRequirements;
+ private final Collection<ExportedPackage> packageCapabilities;
+ private final Collection<ExportedService> serviceCapabilties;
+ private final Collection<ImportedBundle> bundleRequirements;
+ private final ResourceType type;
+ private final ModellingManager modellingManager;
+ private final ModellingHelper modellingHelper;
+ private final Logger logger = LoggerFactory.getLogger(ModelledBundleResource.class);
+
+ public ModelledBundleResource (Resource r, ModellingManager mm, ModellingHelper mh) throws InvalidAttributeException {
+
+ logger.debug(LOG_ENTRY, "ModelledBundleResource", new Object[]{r, mm, mh});
+ resource = r;
+ modellingManager = mm;
+ modellingHelper = mh;
+ List<ExportedBundle> exportedBundles = new ArrayList<ExportedBundle>();
+ ResourceType thisResourceType = ResourceType.BUNDLE;
+
+ // We'll iterate through our Capabilities a second time below. We do this since we later
+ // build an ExportedPackageImpl for which 'this' is the ModelledResource.
+ for (Capability cap : r.getCapabilities()) {
+ String capName = cap.getName();
+ if (capName.equals(ResourceType.BUNDLE.toString())) {
+ @SuppressWarnings("unchecked")
+ Property[] props = cap.getProperties();
+
+ Map<String,String> sanitizedMap = new HashMap<String, String>();
+ for(Property entry : props) {
+ sanitizedMap.put(entry.getName(), entry.getValue());
+ }
+ exportedBundles.add (modellingManager.getExportedBundle(sanitizedMap, modellingHelper.buildFragmentHost(
+ sanitizedMap.get(Constants.FRAGMENT_HOST))));
+ } else if (cap.getName().equals(ResourceType.COMPOSITE.toString())) {
+ thisResourceType = ResourceType.COMPOSITE;
+ }
+ }
+ type = thisResourceType;
+
+
+ if (exportedBundles.size() == 0) {
+ throw new InvalidAttributeException(MessageUtil.getMessage("NO_EXPORTED_BUNDLE", new Object[0]));
+ } else if (exportedBundles.size() == 1) {
+ exportedBundle = exportedBundles.get(0);
+ } else {
+ throw new InvalidAttributeException(MessageUtil.getMessage("TOO_MANY_EXPORTED_BUNDLES",
+ new Object[0]));
+ }
+
+ packageCapabilities = new HashSet<ExportedPackage>();
+ packageRequirements = new HashSet<ImportedPackage>();
+ serviceCapabilties = new HashSet<ExportedService>();
+ serviceRequirements = new HashSet<ImportedService>();
+ bundleRequirements = new HashSet<ImportedBundle>();
+
+ for (Requirement requirement : r.getRequirements())
+ {
+ String reqName = requirement.getName();
+ // Build ImportedPackageImpl, ImportedServiceImpl objects from the Resource's requirments.
+ // Parse the Requirement's filter and remove from the parsed Map all the entries
+ // that we will pass in as explicit parameters to the ImportedServiceImpl or ImportedPackageImpl
+ // constructor.
+ // (This does mean that we remove 'package=package.name' entries but not 'service=service' -
+ // the latter is not very useful :)
+ if (ResourceType.PACKAGE.toString().equals(reqName))
+ {
+ Map<String, String> filter = ManifestHeaderProcessor.parseFilter(requirement.getFilter());
+ // Grab and remove the package name, leaving only additional attributes.
+ String name = filter.remove(ResourceType.PACKAGE.toString());
+ if (requirement.isOptional()) {
+ filter.put(Constants.RESOLUTION_DIRECTIVE + ":", Constants.RESOLUTION_OPTIONAL);
+ }
+ ImportedPackage info = modellingManager.getImportedPackage(name, filter);
+ packageRequirements.add(info);
+ } else if (ResourceType.SERVICE.toString().equals(requirement.getName())) {
+ boolean optional = requirement.isOptional();
+ String iface;
+ String componentName;
+ String blueprintFilter;
+ String id = null;
+ boolean isMultiple = requirement.isMultiple();
+
+ /* It would be much better to pull these keys out of ImportedServiceImpl,
+ * or even values via static methods
+ */
+ Map<String, String> attrs = ManifestHeaderProcessor.parseFilter(requirement.getFilter());
+ iface = attrs.get(Constants.OBJECTCLASS);
+ componentName = attrs.get ("osgi.service.blueprint.compname");
+ blueprintFilter = requirement.getFilter();
+
+ ImportedService svc = modellingManager.getImportedService(optional, iface, componentName,
+ blueprintFilter, id, isMultiple);
+ serviceRequirements.add(svc);
+ } else if (ResourceType.BUNDLE.toString().equals(requirement.getName())) {
+ String filter =requirement.getFilter();
+ Map<String,String> atts = ManifestHeaderProcessor.parseFilter(filter);
+ if (requirement.isOptional()) {
+ atts.put(Constants.RESOLUTION_DIRECTIVE + ":", Constants.RESOLUTION_OPTIONAL);
+ }
+ bundleRequirements.add(modellingManager.getImportedBundle(filter, atts));
+ }
+ }
+
+ for (Capability capability : r.getCapabilities())
+ {
+ Map<String, Object> props = new HashMap<String, Object>();
+ Property[] properties = capability.getProperties();
+ for (Property prop : properties) {
+ props.put(prop.getName(), prop.getValue());
+ }
+ if (ResourceType.PACKAGE.toString().equals(capability.getName()))
+ {
+ // Grab and remove the package name, leaving only additional attributes.
+ Object pkg = props.remove(ResourceType.PACKAGE.toString());
+ // bundle symbolic name and version will be in additionalProps, so do not
+ // need to be passed in separately.
+ ExportedPackage info = modellingManager.getExportedPackage(this, pkg.toString(), props);
+ packageCapabilities.add(info);
+ } else if (ResourceType.SERVICE.toString().equals(capability.getName())) {
+ String name = null; // we've lost this irretrievably
+ int ranking = 0;
+ Collection<String> ifaces;
+ String rankingText = (String) props.remove(Constants.SERVICE_RANKING);
+ if (rankingText != null) ranking = Integer.parseInt(rankingText);
+ // objectClass may come out as a String or String[]
+ Object rawObjectClass = props.remove (Constants.OBJECTCLASS);
+ if (rawObjectClass == null) {
+ // get it from service
+ ifaces = Arrays.asList((String)props.get(ModellingConstants.OBR_SERVICE));
+ } else {
+ if (rawObjectClass.getClass().isArray()) {
+ ifaces = Arrays.asList((String[])rawObjectClass);
+ } else {
+ ifaces = Arrays.asList((String)rawObjectClass);
+ }
+ }
+
+ ExportedService svc = modellingManager.getExportedService(name, ranking, ifaces, props);
+ serviceCapabilties.add(svc);
+
+ }
+ }
+ logger.debug(LOG_EXIT, "ModelledBundleResource");
+
+ }
+
+
+ public ExportedBundle getExportedBundle() {
+ logger.debug(LOG_ENTRY, "AbstractExportedBundle");
+ logger.debug(LOG_EXIT, "AbstractExportedBundle",exportedBundle );
+ return exportedBundle;
+ }
+
+
+ public Collection<? extends ExportedPackage> getExportedPackages() {
+ logger.debug(LOG_ENTRY, "getExportedPackages");
+ logger.debug(LOG_EXIT, "getExportedPackages", packageCapabilities );
+ return Collections.unmodifiableCollection(packageCapabilities);
+ }
+
+
+ public Collection<? extends ExportedService> getExportedServices() {
+ logger.debug(LOG_ENTRY, "getExportedServices");
+ logger.debug(LOG_EXIT, "getExportedServices", serviceCapabilties );
+
+ return Collections.unmodifiableCollection(serviceCapabilties);
+ }
+
+
+ public Collection<? extends ImportedPackage> getImportedPackages() {
+ logger.debug(LOG_ENTRY, "getImportedPackages");
+ logger.debug(LOG_EXIT, "getImportedPackages", packageRequirements );
+ return Collections.unmodifiableCollection(packageRequirements);
+ }
+
+
+ public Collection<? extends ImportedService> getImportedServices() {
+ logger.debug(LOG_ENTRY, "getImportedServices");
+ logger.debug(LOG_EXIT, "getImportedServices", serviceRequirements );
+ return Collections.unmodifiableCollection(serviceRequirements);
+ }
+
+
+ public Collection<? extends ImportedBundle> getRequiredBundles() {
+ logger.debug(LOG_ENTRY, "getRequiredBundles");
+ logger.debug(LOG_EXIT, "getRequiredBundles", bundleRequirements );
+ return Collections.unmodifiableCollection(bundleRequirements);
+ }
+
+
+ public String getSymbolicName() {
+ logger.debug(LOG_ENTRY, "getSymbolicName");
+ String result = resource.getSymbolicName();
+ logger.debug(LOG_EXIT, "getSymbolicName", result );
+
+ return result;
+ }
+
+
+ public String getLocation() {
+ logger.debug(LOG_ENTRY, "getLocation");
+ logger.debug(LOG_EXIT, "getLocation", resource.getURI());
+ return resource.getURI();
+
+ }
+
+
+ public String getVersion() {
+ logger.debug(LOG_ENTRY, "getVersion");
+ String result = resource.getVersion().toString();
+ logger.debug(LOG_EXIT, "getVersion", result);
+ return result;
+ }
+
+
+ public String toDeploymentString() {
+ logger.debug(LOG_ENTRY, "toDeploymentString");
+ String result = getSymbolicName() + ";" + AppConstants.DEPLOYMENT_BUNDLE_VERSION + "=" + getVersion();
+ logger.debug(LOG_EXIT, "toDeploymentString", result);
+ return result;
+ }
+
+
+ public String toString() {
+ logger.debug(LOG_ENTRY, "toString");
+ String result = toDeploymentString() + " uri=" + getLocation();
+ logger.debug(LOG_EXIT, "toString", result);
+ return result;
+ }
+
+
+ public ResourceType getType() {
+ logger.debug(LOG_ENTRY, "getType");
+ logger.debug(LOG_EXIT, "getType", type);
+ return type;
+ }
+
+
+ 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;
+ }
+
+
+}
\ No newline at end of file
Added: aries/tags/application-0.3/application-obr-resolver/src/main/java/org/apache/aries/application/resolver/obr/impl/OBRBundleInfo.java
URL: http://svn.apache.org/viewvc/aries/tags/application-0.3/application-obr-resolver/src/main/java/org/apache/aries/application/resolver/obr/impl/OBRBundleInfo.java?rev=1075132&view=auto
==============================================================================
--- aries/tags/application-0.3/application-obr-resolver/src/main/java/org/apache/aries/application/resolver/obr/impl/OBRBundleInfo.java (added)
+++ aries/tags/application-0.3/application-obr-resolver/src/main/java/org/apache/aries/application/resolver/obr/impl/OBRBundleInfo.java Sun Feb 27 20:20:13 2011
@@ -0,0 +1,152 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.aries.application.resolver.obr.impl;
+
+import java.util.Map;
+import java.util.Set;
+import java.util.jar.Attributes;
+
+import org.apache.aries.application.Content;
+import org.apache.aries.application.management.BundleInfo;
+import org.osgi.framework.Version;
+
+public class OBRBundleInfo implements BundleInfo
+{
+
+ private final String symbolicName;
+ private final Version version;
+ private final String location;
+ private final Set<Content> importPackage;
+ private final Set<Content> exportPackage;
+ private final Set<Content> importService;
+ private final Set<Content> exportService;
+ private final Map<String, String> headers;
+ private final Set<Content> requireBundle;
+ private final Map<String, String> attributes;
+ private final Map<String, String> directives;
+
+ public OBRBundleInfo(String symbolicName, Version version, String location,
+ Set<Content> importPackage, Set<Content> exportPackage,
+ Set<Content> importService, Set<Content> exportService,
+ Set<Content> requireBundle, Map<String, String> attributes,
+ Map<String, String> directives, Map<String, String> headers)
+ {
+ this.symbolicName = symbolicName;
+ this.version = version;
+ this.location = location;
+ this.importPackage = importPackage;
+ this.exportPackage = exportPackage;
+ this.importService = importService;
+ this.exportService = exportService;
+ this.headers = headers;
+ this.requireBundle = requireBundle;
+ this.attributes = attributes;
+ this.directives = directives;
+ }
+
+ public String getSymbolicName()
+ {
+ return symbolicName;
+ }
+
+ public Version getVersion()
+ {
+ return version;
+ }
+
+ public String getLocation()
+ {
+ return location;
+ }
+
+ public Set<Content> getImportPackage()
+ {
+ return importPackage;
+ }
+
+ public Set<Content> getExportPackage()
+ {
+ return exportPackage;
+ }
+
+ public Set<Content> getImportService()
+ {
+ return importService;
+ }
+
+ public Set<Content> getExportService()
+ {
+ return exportService;
+ }
+
+ public Map<String, String> getHeaders()
+ {
+ return headers;
+ }
+
+ public Map<String, String> getBundleAttributes()
+ {
+ return attributes;
+ }
+
+ public Map<String, String> getBundleDirectives()
+ {
+ return directives;
+ }
+
+ public Set<Content> getRequireBundle()
+ {
+ return requireBundle;
+ }
+
+ public String toString()
+ {
+ return symbolicName + "_" + version;
+ }
+
+ public int hashCode()
+ {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + symbolicName.hashCode();
+ result = prime * result + version.hashCode();
+ return result;
+ }
+
+ public boolean equals(Object obj) {
+ if (this == obj) return true;
+ if (obj == null) return false;
+ if (getClass() != obj.getClass()) {
+ return false;
+ }
+ OBRBundleInfo other = (OBRBundleInfo) obj;
+ return (symbolicName.equals(other.symbolicName)
+ && version.equals(other.version));
+ }
+
+ public Attributes getRawAttributes()
+ {
+
+ Attributes _attributes = new Attributes();
+ _attributes.putAll(attributes);
+ _attributes.putAll(directives);
+ return _attributes;
+ }
+}
Added: aries/tags/application-0.3/application-obr-resolver/src/main/java/org/apache/aries/application/resolver/obr/impl/OBRCapability.java
URL: http://svn.apache.org/viewvc/aries/tags/application-0.3/application-obr-resolver/src/main/java/org/apache/aries/application/resolver/obr/impl/OBRCapability.java?rev=1075132&view=auto
==============================================================================
--- aries/tags/application-0.3/application-obr-resolver/src/main/java/org/apache/aries/application/resolver/obr/impl/OBRCapability.java (added)
+++ aries/tags/application-0.3/application-obr-resolver/src/main/java/org/apache/aries/application/resolver/obr/impl/OBRCapability.java Sun Feb 27 20:20:13 2011
@@ -0,0 +1,90 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.aries.application.resolver.obr.impl;
+
+
+import static org.apache.aries.application.utils.AppConstants.LOG_ENTRY;
+import static org.apache.aries.application.utils.AppConstants.LOG_EXIT;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.aries.application.modelling.Provider;
+import org.apache.felix.bundlerepository.Capability;
+import org.apache.felix.bundlerepository.Property;
+import org.apache.felix.bundlerepository.RepositoryAdmin;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Common code for handling OBR Capabilities.
+ */
+public class OBRCapability implements Capability
+{
+
+ private Logger logger = LoggerFactory.getLogger(OBRCapability.class);
+ private final Provider _provider;
+
+ private final RepositoryAdmin repositoryAdmin;
+ /**
+ * Property map for this Capability.
+ */
+ private final Map<String, Object> _props;
+
+ /**
+ * Construct a Capability specifying the OBR name to use.
+ * @param type the value to be used for the Capability name in OBR.
+ */
+ public OBRCapability(Provider provider, RepositoryAdmin repositoryAdmin){
+
+ logger.debug(LOG_ENTRY, "OBRCapability", provider);
+ _provider = provider;
+ _props = new HashMap<String, Object>(provider.getAttributes());
+ this.repositoryAdmin = repositoryAdmin;
+ logger.debug(LOG_EXIT, "OBRCapability");
+
+ }
+
+
+ public String getName()
+ {
+ logger.debug(LOG_ENTRY, "getName");
+ String name = _provider.getType().toString();
+ logger.debug(LOG_EXIT, "getName", name);
+ return name;
+ }
+
+
+ public Property[] getProperties()
+ {
+ logger.debug(LOG_ENTRY, "getProperties");
+ Property[] props = repositoryAdmin.getHelper().capability(getName(), _props).getProperties();
+ logger.debug(LOG_EXIT, "getProperties", props);
+ return props;
+ }
+
+ public Map getPropertiesAsMap()
+ {
+ logger.debug(LOG_ENTRY, "getPropertiesAsMap");
+ logger.debug(LOG_ENTRY, "getPropertiesAsMap", new Object[]{_props});
+ return _props;
+ }
+
+}
Added: aries/tags/application-0.3/application-obr-resolver/src/main/java/org/apache/aries/application/resolver/obr/impl/RepositoryGeneratorImpl.java
URL: http://svn.apache.org/viewvc/aries/tags/application-0.3/application-obr-resolver/src/main/java/org/apache/aries/application/resolver/obr/impl/RepositoryGeneratorImpl.java?rev=1075132&view=auto
==============================================================================
--- aries/tags/application-0.3/application-obr-resolver/src/main/java/org/apache/aries/application/resolver/obr/impl/RepositoryGeneratorImpl.java (added)
+++ aries/tags/application-0.3/application-obr-resolver/src/main/java/org/apache/aries/application/resolver/obr/impl/RepositoryGeneratorImpl.java Sun Feb 27 20:20:13 2011
@@ -0,0 +1,226 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.aries.application.resolver.obr.impl;
+
+import static org.apache.aries.application.utils.AppConstants.LOG_ENTRY;
+import static org.apache.aries.application.utils.AppConstants.LOG_EXIT;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.transform.OutputKeys;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamResult;
+
+import org.apache.aries.application.management.ResolverException;
+import org.apache.aries.application.management.spi.repository.RepositoryGenerator;
+import org.apache.aries.application.modelling.ModelledResource;
+import org.apache.aries.application.resolver.obr.ext.BundleResource;
+import org.apache.aries.application.resolver.obr.ext.BundleResourceTransformer;
+import org.apache.felix.bundlerepository.Capability;
+import org.apache.felix.bundlerepository.Property;
+import org.apache.felix.bundlerepository.RepositoryAdmin;
+import org.apache.felix.bundlerepository.Requirement;
+import org.apache.felix.bundlerepository.Resource;
+import org.osgi.framework.Constants;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+public final class RepositoryGeneratorImpl implements RepositoryGenerator
+{
+ private RepositoryAdmin repositoryAdmin;
+ private static Logger logger = LoggerFactory.getLogger(RepositoryGeneratorImpl.class);
+ private static Collection<BundleResourceTransformer> bundleResourceTransformers = new ArrayList<BundleResourceTransformer>();
+ private static final String MANDATORY_DIRECTIVE = Constants.MANDATORY_DIRECTIVE + ":";
+
+
+ public void setBundleResourceTransformers (List<BundleResourceTransformer> brts) {
+ bundleResourceTransformers = brts;
+ }
+
+ public RepositoryGeneratorImpl(RepositoryAdmin repositoryAdmin) {
+ this.repositoryAdmin = repositoryAdmin;
+ }
+ private static void addProperty(Document doc, Element capability, String name,
+ String value, String type)
+ {
+ logger.debug(LOG_ENTRY, "addProperty", new Object[]{doc, capability, name, value, type});
+ Element p = doc.createElement("p");
+ p.setAttribute("n", name);
+ p.setAttribute("v", value);
+ if (type != null) p.setAttribute("t", type);
+ capability.appendChild(p);
+ logger.debug(LOG_ENTRY, "addProperty", new Object[]{});
+ }
+
+
+
+ /**
+ * Write out the resource element
+ *
+ * @param r
+ * resource
+ * @param writer
+ * buffer writer
+ * @throws IOException
+ */
+ private static void writeResource(Resource r, String uri, Document doc, Element root) throws IOException
+ {
+ logger.debug(LOG_ENTRY, "writeResource", new Object[]{r, uri, doc, root});
+ Element resource = doc.createElement("resource");
+ resource.setAttribute(Resource.VERSION, r.getVersion().toString());
+ resource.setAttribute("uri", r.getURI());
+ resource.setAttribute(Resource.SYMBOLIC_NAME, r.getSymbolicName());
+ resource.setAttribute(Resource.ID, r.getSymbolicName() + "/" + r.getVersion());
+ resource.setAttribute(Resource.PRESENTATION_NAME, r.getPresentationName());
+ root.appendChild(resource);
+
+
+ for (Capability c : r.getCapabilities())
+ writeCapability(c, doc, resource);
+
+ for (Requirement req : r.getRequirements()) {
+ writeRequirement(req, doc, resource);
+
+ }
+ logger.debug(LOG_EXIT, "writeResource");
+
+ }
+
+ /**
+ * Write out the capability
+ *
+ * @param c capability
+ * @param writer buffer writer
+ * @throws IOException
+ */
+ private static void writeCapability(Capability c, Document doc, Element resource) throws IOException
+ {
+ logger.debug(LOG_ENTRY, "writeCapability", new Object[]{c, doc, resource});
+ Element capability = doc.createElement("capability");
+ capability.setAttribute("name", c.getName());
+ resource.appendChild(capability);
+
+ Property[] props = c.getProperties();
+
+ for (Property entry : props) {
+
+ String name = (String) entry.getName();
+ String objectAttrs = entry.getValue();
+
+ String type = getType(name);
+
+ // remove the beginning " and tailing "
+ if (objectAttrs.startsWith("\"") && objectAttrs.endsWith("\""))
+ objectAttrs = objectAttrs.substring(1, objectAttrs.length() - 1);
+ addProperty(doc, capability, name, objectAttrs, type);
+ }
+
+ logger.debug(LOG_EXIT, "writeCapability");
+ }
+
+ /**
+ * write the requirement
+ *
+ * @param req
+ * requirement
+ * @param writer
+ * buffer writer
+ * @throws IOException
+ */
+ private static void writeRequirement(Requirement req, Document doc, Element resource) throws IOException
+ {
+ logger.debug(LOG_ENTRY, "writeRequirement", new Object[]{req, doc, resource});
+ Element requirement = doc.createElement("require");
+ requirement.setAttribute("name", req.getName());
+ requirement.setAttribute("extend", String.valueOf(req.isExtend()));
+ requirement.setAttribute("multiple", String.valueOf(req.isMultiple()));
+ requirement.setAttribute("optional", String.valueOf(req.isOptional()));
+ requirement.setAttribute("filter", req.getFilter());
+ requirement.setTextContent(req.getComment());
+ resource.appendChild(requirement);
+ logger.debug(LOG_EXIT, "writeRequirement");
+ }
+
+
+ public void generateRepository(String repositoryName,
+ Collection<? extends ModelledResource> byValueBundles, OutputStream os)
+ throws ResolverException, IOException
+ {
+ logger.debug(LOG_ENTRY, "generateRepository", new Object[]{repositoryName, byValueBundles, os});
+ generateRepository(repositoryAdmin, repositoryName, byValueBundles, os);
+ logger.debug(LOG_EXIT, "generateRepository");
+ }
+
+ public static void generateRepository (RepositoryAdmin repositoryAdmin, String repositoryName,
+ Collection<? extends ModelledResource> byValueBundles, OutputStream os)
+ throws ResolverException, IOException {
+ logger.debug(LOG_ENTRY, "generateRepository", new Object[]{repositoryAdmin, repositoryName, byValueBundles, os});
+ Document doc;
+ try {
+ doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
+
+ } catch (ParserConfigurationException pce) {
+ throw new ResolverException(pce);
+ }
+ Element root = doc.createElement("repository");
+
+ root.setAttribute("name", repositoryName);
+ doc.appendChild(root);
+ for (ModelledResource mr : byValueBundles) {
+ BundleResource bundleResource = new BundleResource(mr, repositoryAdmin);
+ if (bundleResourceTransformers.size() > 0) {
+ for (BundleResourceTransformer brt : bundleResourceTransformers) {
+ bundleResource = brt.transform (bundleResource);
+ }
+ }
+ writeResource (bundleResource, mr.getLocation(), doc, root);
+ }
+
+ try {
+ Transformer trans = TransformerFactory.newInstance().newTransformer();
+ trans.setOutputProperty(OutputKeys.INDENT, "yes");
+ trans.transform(new DOMSource(doc), new StreamResult(os));
+ } catch (TransformerException te) {
+ logger.debug(LOG_EXIT, "generateRepository", te);
+ throw new ResolverException(te);
+ }
+ logger.debug(LOG_EXIT, "generateRepository");
+ }
+ private static String getType(String name) {
+ logger.debug(LOG_ENTRY, "getType", new Object[]{name});
+ String type = null;
+ if (Constants.VERSION_ATTRIBUTE.equals(name) || (Constants.BUNDLE_VERSION_ATTRIBUTE.equals(name))) {
+ type = "version";
+ } else if (Constants.OBJECTCLASS.equals(name) || MANDATORY_DIRECTIVE.equals(name))
+ type = "set";
+ logger.debug(LOG_EXIT, "getType", new Object[]{type});
+ return type;
+ }
+
+}
\ No newline at end of file
Added: aries/tags/application-0.3/application-obr-resolver/src/main/java/org/apache/aries/application/resolver/obr/impl/RequirementImpl.java
URL: http://svn.apache.org/viewvc/aries/tags/application-0.3/application-obr-resolver/src/main/java/org/apache/aries/application/resolver/obr/impl/RequirementImpl.java?rev=1075132&view=auto
==============================================================================
--- aries/tags/application-0.3/application-obr-resolver/src/main/java/org/apache/aries/application/resolver/obr/impl/RequirementImpl.java (added)
+++ aries/tags/application-0.3/application-obr-resolver/src/main/java/org/apache/aries/application/resolver/obr/impl/RequirementImpl.java Sun Feb 27 20:20:13 2011
@@ -0,0 +1,178 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+
+package org.apache.aries.application.resolver.obr.impl;
+
+import static org.apache.aries.application.utils.AppConstants.LOG_ENTRY;
+import static org.apache.aries.application.utils.AppConstants.LOG_EXIT;
+
+import java.util.Hashtable;
+import java.util.Map;
+
+import org.apache.aries.application.modelling.Consumer;
+import org.apache.aries.application.utils.FilterUtils;
+import org.apache.aries.application.utils.manifest.ManifestHeaderProcessor;
+import org.apache.felix.bundlerepository.Capability;
+import org.apache.felix.bundlerepository.Requirement;
+import org.osgi.framework.Filter;
+import org.osgi.framework.FrameworkUtil;
+import org.osgi.framework.InvalidSyntaxException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class RequirementImpl implements Requirement
+{
+
+
+ private final Logger logger = LoggerFactory.getLogger(RequirementImpl.class);
+ private final Consumer consumer;
+
+ private final String name;
+ private final String filter;
+ private final boolean multiple;
+ private final boolean optional;
+ private final boolean extend;
+ private final String comment;
+
+ public RequirementImpl(String name, Filter filter, boolean multiple, boolean optional, boolean extend, String comment)
+ {
+ this.name = name;
+ this.filter = filter.toString();
+ this.multiple = multiple;
+ this.optional = optional;
+ this.extend = extend;
+ this.comment = comment;
+ this.consumer = null;
+ }
+
+ public RequirementImpl(Consumer consumer) {
+ this.consumer = consumer;
+ this.name = getName();
+ this.filter= getFilter();
+ this.multiple= isMultiple();
+ this.optional= isOptional();
+ this.extend = false;
+ this.comment = getComment();
+
+ }
+
+
+
+ public String getComment()
+ {
+
+ logger.debug(LOG_ENTRY,"getComment" );
+ if (consumer!= null) {
+ String cleanFilter = FilterUtils.removeMandatoryFilterToken(consumer.getAttributeFilter());
+ Map<String, String> atts = ManifestHeaderProcessor.parseFilter(cleanFilter);
+ String comment = "Requires " + consumer.getType().toString() + " with attributes " + atts;
+ logger.debug(LOG_EXIT,"getComment", comment );
+ return comment;
+ } else {
+ logger.debug(LOG_EXIT,"getComment", this.comment );
+ return this.comment;
+ }
+ }
+
+
+ public String getFilter()
+ {
+ String result;
+ if (consumer != null) {
+ result = consumer.getAttributeFilter();
+ } else {
+ result = this.filter;
+ }
+ return result;
+ }
+
+
+ public String getName()
+ {
+
+ String result;
+ if (consumer != null) {
+ result = consumer.getType().toString();
+ } else {
+ result = this.name;
+ }
+ return result;
+ }
+
+
+ public boolean isExtend()
+ {
+ return this.extend;
+ }
+
+
+ public boolean isMultiple()
+ {
+ boolean result;
+ if (consumer != null ) {
+ result = consumer.isMultiple();
+ } else {
+ result = this.multiple;
+ }
+ return result;
+ }
+
+
+ public boolean isOptional()
+ {
+ boolean result;
+ if (consumer != null) {
+ result = consumer.isOptional();
+ } else {
+ result = this.optional;
+ }
+ return result;
+ }
+
+ @SuppressWarnings("unchecked")
+
+ public boolean isSatisfied(Capability cap)
+ {
+
+ logger.debug(LOG_ENTRY,"isSatisfied", cap );
+ boolean result = false;
+
+ String name = getName();
+ if (name.equals(cap.getName())) {
+ String filterToCreate = getFilter();
+ try {
+ Filter f = FrameworkUtil.createFilter(FilterUtils.removeMandatoryFilterToken(filterToCreate));
+ Hashtable<String, Object> hash = new Hashtable<String, Object>();
+ Map<String, String> props = cap.getPropertiesAsMap();
+ if ((props != null) && (!!!props.isEmpty())) {
+ for (Map.Entry<String, String> propertyPair : props.entrySet()) {
+ hash.put(propertyPair.getKey(), propertyPair.getValue());
+ }
+ }
+
+ result = f.match(hash);
+ } catch (InvalidSyntaxException e) {
+ logger.error(e.getMessage());
+ }
+ }
+ logger.debug(LOG_EXIT,"isSatisfied", result );
+ return result;
+ }
+}
Added: aries/tags/application-0.3/application-obr-resolver/src/main/java/org/apache/aries/application/resolver/obr/impl/ResourceWrapper.java
URL: http://svn.apache.org/viewvc/aries/tags/application-0.3/application-obr-resolver/src/main/java/org/apache/aries/application/resolver/obr/impl/ResourceWrapper.java?rev=1075132&view=auto
==============================================================================
--- aries/tags/application-0.3/application-obr-resolver/src/main/java/org/apache/aries/application/resolver/obr/impl/ResourceWrapper.java (added)
+++ aries/tags/application-0.3/application-obr-resolver/src/main/java/org/apache/aries/application/resolver/obr/impl/ResourceWrapper.java Sun Feb 27 20:20:13 2011
@@ -0,0 +1,84 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.aries.application.resolver.obr.impl;
+
+import java.util.Map;
+
+import org.apache.felix.bundlerepository.Capability;
+import org.apache.felix.bundlerepository.Requirement;
+import org.apache.felix.bundlerepository.Resource;
+import org.osgi.framework.Version;
+
+/**
+ * @version $Rev: 964138 $ $Date: 2010-07-14 20:03:40 +0100 (Wed, 14 Jul 2010) $
+ */
+public class ResourceWrapper implements Resource {
+
+ private final Resource resource;
+
+ public ResourceWrapper(Resource resource) {
+ this.resource = resource;
+ }
+
+ public Capability[] getCapabilities() {
+ return resource.getCapabilities();
+ }
+
+ public String[] getCategories() {
+ return resource.getCategories();
+ }
+
+ public String getId() {
+ return resource.getId();
+ }
+
+ public String getPresentationName() {
+ return resource.getPresentationName();
+ }
+
+ public Map getProperties() {
+ return resource.getProperties();
+ }
+
+ public Requirement[] getRequirements() {
+ return resource.getRequirements();
+ }
+
+ public Long getSize() {
+ return resource.getSize();
+ }
+
+ public String getSymbolicName() {
+ return resource.getSymbolicName();
+ }
+
+ public String getURI() {
+ return resource.getURI();
+ }
+
+ public Version getVersion() {
+ return resource.getVersion();
+ }
+
+ public boolean isLocal() {
+ return false;
+ }
+
+}