/* * 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.util.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; } }