/******************************************************************************* * Copyright (c) 2008, 2013 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); } //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) { //$NON-NLS-1$ //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; } /** * 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); } }