blob: 20ec8b78e6469394c42f2efa176ed9dcc3c1101b [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2008, 2009 Martin Lippert 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:
* David Knibb initial implementation
* Martin Lippert supplementing mechanism reworked
* Martin Lippert fragment handling fixed
*******************************************************************************/
package org.eclipse.equinox.service.weaving;
import java.util.HashSet;
import java.util.Set;
import org.eclipse.osgi.util.ManifestElement;
import org.osgi.framework.Bundle;
/**
* A supplementer object is created for every bundle that contains one or many
* of the supplementer headers in its header.
*
* The corresponding supplementer object contains the information which headers
* the bundle defines and which bundles it supplements in the running system.
*
* @author Martin Lippert
*/
public class Supplementer {
private final ManifestElement[] supplementBundle;
private final Set<Bundle> supplementedBundles; // elements of type Bundle
private final Bundle supplementer;
private final Bundle supplementerHost;
private final ManifestElement[] supplementExporter;
private final ManifestElement[] supplementImporter;
/**
* Creates a supplementer object for the given bundle.
*
* @param bundle The bundle that defines the supplementer headers
* @param bundleHost The host bundle of the supplementer bundle, if the
* bundle is a fragment, otherwise null
* @param supplementBundle The parsed manifest headers defined for
* Eclipse-SupplementBundle
* @param supplementImporter The parsed manifest headers defined for
* Eclipse-SupplementImporter
* @param supplementExporter The parsed manifest headers defined for
* Eclipse-SupplementExporter
*/
public Supplementer(final Bundle bundle, final Bundle bundleHost,
final ManifestElement[] supplementBundle,
final ManifestElement[] supplementImporter,
final ManifestElement[] supplementExporter) {
this.supplementer = bundle;
this.supplementerHost = bundleHost != null ? bundleHost : bundle;
this.supplementBundle = supplementBundle;
this.supplementImporter = supplementImporter;
this.supplementExporter = supplementExporter;
this.supplementedBundles = new HashSet<Bundle>();
}
/**
* Add a bundle to the list of supplemented bundles
*
* @param supplementedBundle The bundle that is supplemented by this
* supplementer
*/
public void addSupplementedBundle(final Bundle supplementedBundle) {
this.supplementedBundles.add(supplementedBundle);
}
/**
* Gives information about which bundles are currently supplemented by this
* supplementer
*
* @return The currently supplemented bundles
*/
public Bundle[] getSupplementedBundles() {
return supplementedBundles.toArray(new Bundle[supplementedBundles
.size()]);
}
/**
* Returns the bundle that defines the supplementer headers (this
* supplementer object belongs to)
*
* @return The bundle object this supplementer belongs to
*/
public Bundle getSupplementerBundle() {
return supplementer;
}
/**
* Returns the host of the supplementer bundle, if it is a fragment,
* otherwise this returns the same as getSupplementerBundle()
*
* @return The host bundle this supplementer belongs to
*/
public Bundle getSupplementerHost() {
return supplementerHost;
}
/**
* The symbolic name of the supplementer bundle
*
* @return The symbolic name of the supplementer bundle
*/
public String getSymbolicName() {
return supplementer.getSymbolicName();
}
/**
* Provides information about whether a given bundle is supplemented by this
* supplementer or not
*
* @param bundle The bundle that might be supplemented by this supplementer
* @return true, if the bundle is supplemented by this supplementer,
* otherwise false
*/
public boolean isSupplemented(final Bundle bundle) {
return supplementedBundles.contains(bundle);
}
/**
* Checks if the given export-package header definitions matches the
* supplement-exporter definitions of this supplementer
*
* @param exports The headers to check for matching against this
* supplementer
* @return true, if this supplementer matches against the given
* export-package headers
*/
public boolean matchesSupplementExporter(final ManifestElement[] exports) {
boolean matches = false;
if (supplementExporter != null)
for (int i = 0; !matches && i < supplementExporter.length; i++) {
final ManifestElement supplementExport = supplementExporter[i];
for (int j = 0; !matches && j < exports.length; j++) {
final ManifestElement exportPackage = exports[j];
if (supplementExport.getValue().equals(
exportPackage.getValue())) matches = true;
}
}
return matches;
}
/**
* Checks if the given import-package header definitions matches the
* supplement-importer definitions of this supplementer
*
* @param imports The headers to check for matching against this
* supplementer
* @return true, if this supplementer matches against the given
* import-package headers
*/
public boolean matchesSupplementImporter(final ManifestElement[] imports) {
boolean matches = false;
if (supplementImporter != null)
for (int i = 0; !matches && i < supplementImporter.length; i++) {
final ManifestElement supplementImport = supplementImporter[i];
for (int j = 0; !matches && j < imports.length; j++) {
final ManifestElement importPackage = imports[j];
if (supplementImport.getValue().equals(
importPackage.getValue())) matches = true;
}
}
return matches;
}
/**
* Checks if the given bundle symbolic name definition matches the
* supplement-bundle definition of this supplementer
*
* @param symbolicName The symbolic name of the bundle that shoudl be
* checked
* @return true, if this supplementer matches against the given bundle
* symbolic name
*/
public boolean matchSupplementer(final String symbolicName) {
boolean matches = false;
if (supplementBundle != null)
for (int i = 0; !matches && i < supplementBundle.length; i++) {
final ManifestElement bundle = supplementBundle[i];
if (equals_wild(bundle.getValue(), symbolicName))
matches = true;
}
return matches;
}
/**
* Removes the given bundle from the set of supplemented bundles (that are
* supplemented by this supplementer)
*
* @param supplementedBundle The bundle that is no longer supplemented by
* this supplementer
*/
public void removeSupplementedBundle(final Bundle supplementedBundle) {
this.supplementedBundles.remove(supplementedBundle);
}
//knibb
//test if two Strings are equal
//with wild card support - only supports strings ending in *
private boolean equals_wild(final String input, final String match) {
if (input.equals(match)) {
//its a match so just return true
return true;
}
if (input.endsWith("*") == false) {
//no wildcards are being used here
return false;
}
final String wild_in = input.substring(0, input.length() - 1);
if (match.startsWith(wild_in)) return true;
return false;
}
}