blob: 55092c8b820b89c39eb051368cefa30f1d065704 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2003, 2008 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
* Danail Nachev - ProSyst - bug 218625
* Rob Harrop - SpringSource Inc. (bug 247522)
*******************************************************************************/
package org.eclipse.osgi.internal.resolver;
import java.util.*;
import org.eclipse.osgi.framework.internal.core.Constants;
import org.eclipse.osgi.service.resolver.*;
public class ImportPackageSpecificationImpl extends VersionConstraintImpl implements ImportPackageSpecification {
private String resolution = ImportPackageSpecification.RESOLUTION_STATIC; // the default is static
private String symbolicName;
private VersionRange bundleVersionRange;
private Map attributes;
public Map getDirectives() {
synchronized (this.monitor) {
Map result = new HashMap(5);
if (resolution != null)
result.put(Constants.RESOLUTION_DIRECTIVE, resolution);
return result;
}
}
public Object getDirective(String key) {
synchronized (this.monitor) {
if (key.equals(Constants.RESOLUTION_DIRECTIVE))
return resolution;
return null;
}
}
public Object setDirective(String key, Object value) {
synchronized (this.monitor) {
if (key.equals(Constants.RESOLUTION_DIRECTIVE))
return resolution = (String) value;
return null;
}
}
public void setDirectives(Map directives) {
synchronized (this.monitor) {
if (directives == null)
return;
resolution = (String) directives.get(Constants.RESOLUTION_DIRECTIVE);
}
}
public String getBundleSymbolicName() {
synchronized (this.monitor) {
if (Constants.SYSTEM_BUNDLE_SYMBOLICNAME.equals(symbolicName)) {
StateImpl state = (StateImpl) getBundle().getContainingState();
return state == null ? Constants.getInternalSymbolicName() : state.getSystemBundle();
}
return symbolicName;
}
}
public VersionRange getBundleVersionRange() {
synchronized (this.monitor) {
if (bundleVersionRange == null)
return VersionRange.emptyRange;
return bundleVersionRange;
}
}
public Map getAttributes() {
synchronized (this.monitor) {
return attributes;
}
}
public boolean isSatisfiedBy(BaseDescription supplier) {
if (!(supplier instanceof ExportPackageDescription))
return false;
ExportPackageDescriptionImpl pkgDes = (ExportPackageDescriptionImpl) supplier;
// If we are in strict mode, check to see if the export specifies friends.
// If it does, are we one of the friends
String[] friends = (String[]) pkgDes.getDirective(Constants.FRIENDS_DIRECTIVE);
Boolean internal = (Boolean) pkgDes.getDirective(Constants.INTERNAL_DIRECTIVE);
if (internal.booleanValue() || friends != null) {
StateImpl state = (StateImpl) getBundle().getContainingState();
boolean strict = state == null ? false : state.inStrictMode();
if (strict) {
if (internal.booleanValue())
return false;
boolean found = false;
if (friends != null && getBundle().getSymbolicName() != null)
for (int i = 0; i < friends.length; i++)
if (getBundle().getSymbolicName().equals(friends[i]))
found = true;
if (!found)
return false;
}
}
String exporterSymbolicName = getBundleSymbolicName();
if (exporterSymbolicName != null) {
BundleDescription exporter = pkgDes.getExporter();
if (!exporterSymbolicName.equals(exporter.getSymbolicName()))
return false;
if (getBundleVersionRange() != null && !getBundleVersionRange().isIncluded(exporter.getVersion()))
return false;
}
String name = getName();
// shortcut '*'
// NOTE: wildcards are supported only in cases where this is a dynamic import
if (!"*".equals(name) && !(name.endsWith(".*") && pkgDes.getName().startsWith(name.substring(0, name.length() - 1))) && !pkgDes.getName().equals(name)) //$NON-NLS-1$ //$NON-NLS-2$
return false;
if (getVersionRange() != null && !getVersionRange().isIncluded(pkgDes.getVersion()))
return false;
Map importAttrs = getAttributes();
if (importAttrs != null) {
Map exportAttrs = pkgDes.getAttributes();
if (exportAttrs == null)
return false;
for (Iterator i = importAttrs.keySet().iterator(); i.hasNext();) {
String importKey = (String) i.next();
Object importValue = importAttrs.get(importKey);
Object exportValue = exportAttrs.get(importKey);
if (exportValue == null || !importValue.equals(exportValue))
return false;
}
}
String[] mandatory = (String[]) pkgDes.getDirective(Constants.MANDATORY_DIRECTIVE);
if (mandatory != null) {
for (int i = 0; i < mandatory.length; i++) {
if (Constants.BUNDLE_SYMBOLICNAME_ATTRIBUTE.equals(mandatory[i])) {
if (exporterSymbolicName == null)
return false;
} else if (Constants.BUNDLE_VERSION_ATTRIBUTE.equals(mandatory[i])) {
if (bundleVersionRange == null)
return false;
} else if (Constants.PACKAGE_SPECIFICATION_VERSION.equals(mandatory[i]) || Constants.VERSION_ATTRIBUTE.equals(mandatory[i])) {
if (getVersionRange() == null)
return false;
} else { // arbitrary attribute
if (importAttrs == null)
return false;
if (importAttrs.get(mandatory[i]) == null)
return false;
}
}
}
// finally check the ee index
if (((BundleDescriptionImpl) getBundle()).getEquinoxEE() < 0)
return true;
int eeIndex = ((Integer) pkgDes.getDirective(ExportPackageDescriptionImpl.EQUINOX_EE)).intValue();
return eeIndex < 0 || eeIndex == ((BundleDescriptionImpl) getBundle()).getEquinoxEE();
}
protected void setBundleSymbolicName(String symbolicName) {
synchronized (this.monitor) {
this.symbolicName = symbolicName;
}
}
protected void setBundleVersionRange(VersionRange bundleVersionRange) {
synchronized (this.monitor) {
this.bundleVersionRange = bundleVersionRange;
}
}
protected void setAttributes(Map attributes) {
synchronized (this.monitor) {
this.attributes = attributes;
}
}
public String toString() {
return "Import-Package: " + getName() + "; version=\"" + getVersionRange() + "\""; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
}
}