All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.eclipse.equinox.internal.region.BundleIdBasedRegion Maven / Gradle / Ivy

Go to download

Provides the concept of a region used to isolate bundles according to the configured sharing policy, which is applied across the framework using the OSGi hook APIs.

The newest version!
/*******************************************************************************
 * Copyright (c) 2011, 2013 VMware Inc.
 * 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:
 *   VMware Inc. - initial contribution
 *******************************************************************************/

package org.eclipse.equinox.internal.region;

import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Set;
import java.util.regex.Pattern;
import org.eclipse.equinox.region.*;
import org.eclipse.equinox.region.RegionDigraph.FilteredRegion;
import org.osgi.framework.*;

/**
 * {@link BundleIdBasedRegion} is an implementation of {@link Region} which keeps a track of the bundles in the region
 * by recording their bundle identifiers.
 * 

* * Concurrent Semantics
* Thread safe. */ public final class BundleIdBasedRegion implements Region { private static final Pattern invalidName = Pattern.compile("[:=\\n*?,\"\\\\]"); //$NON-NLS-1$ private static final String REGION_LOCATION_DELIMITER = "#"; //$NON-NLS-1$ private static final String FILE_SCHEME = "file:"; //$NON-NLS-1$ private final String regionName; private final RegionDigraph regionDigraph; private final BundleIdToRegionMapping bundleIdToRegionMapping; private final BundleContext bundleContext; private final ThreadLocal threadLocal; public BundleIdBasedRegion(String regionName, RegionDigraph regionDigraph, BundleIdToRegionMapping bundleIdToRegionMapping, BundleContext bundleContext, ThreadLocal threadLocal) { BundleIdBasedRegion.validateName(regionName); if (regionDigraph == null) throw new IllegalArgumentException("The region digraph must not be null"); //$NON-NLS-1$ if (bundleIdToRegionMapping == null) throw new IllegalArgumentException("The bundle id to region mapping must not be null"); //$NON-NLS-1$ this.regionName = regionName; this.regionDigraph = regionDigraph; this.bundleIdToRegionMapping = bundleIdToRegionMapping; this.bundleContext = bundleContext; this.threadLocal = threadLocal; } private static void validateName(String name) { if (name == null) throw new IllegalArgumentException("The region name must not be null"); //$NON-NLS-1$ if (invalidName.matcher(name).find()) throw new IllegalArgumentException("The region name has invalid characters: " + name); //$NON-NLS-1$ } /** * {@inheritDoc} */ @Override public String getName() { return this.regionName; } /** * {@inheritDoc} */ @Override public void addBundle(Bundle bundle) throws BundleException { addBundle(bundle.getBundleId()); } /** * {@inheritDoc} */ @Override public void addBundle(long bundleId) throws BundleException { this.bundleIdToRegionMapping.associateBundleWithRegion(bundleId, this); } /** * {@inheritDoc} */ @Override public Bundle installBundleAtLocation(String location, InputStream input) throws BundleException { return installBundle0(location, input, false); } /** * {@inheritDoc} */ @Override public Bundle installBundle(String location, InputStream input) throws BundleException { return installBundle0(location, input, true); } private Bundle installBundle0(String location, InputStream input, boolean appendRegionName) throws BundleException { if (this.bundleContext == null) throw new BundleException("This region is not connected to an OSGi Framework.", BundleException.INVALID_OPERATION); //$NON-NLS-1$ setRegionThreadLocal(); try { input = checkFileProtocol(location, input); if (appendRegionName) { location = location + REGION_LOCATION_DELIMITER + this.regionName; } return this.bundleContext.installBundle(location, input); } finally { removeRegionThreadLocal(); } } private InputStream checkFileProtocol(String location, InputStream input) throws BundleException { if (input != null || location.startsWith(FILE_SCHEME)) return input; try { return new URL(location).openStream(); } catch (MalformedURLException e) { throw new BundleException("The location resulted in an invalid bundle URI: " + location, e); //$NON-NLS-1$ } catch (IOException e) { throw new BundleException("The location referred to an invalid bundle at URI: " + location, e); //$NON-NLS-1$ } } /** * {@inheritDoc} */ @Override public Bundle installBundle(String location) throws BundleException { return installBundle(location, null); } private void setRegionThreadLocal() { if (this.threadLocal != null) this.threadLocal.set(this); } private void removeRegionThreadLocal() { if (this.threadLocal != null) this.threadLocal.remove(); } /** * {@inheritDoc} */ @Override public Bundle getBundle(String symbolicName, Version version) { if (bundleContext == null) return null; // this region is not connected to an OSGi framework Set bundleIds = getBundleIds(); for (long bundleId : bundleIds) { Bundle bundle = bundleContext.getBundle(bundleId); if (bundle != null && symbolicName.equals(bundle.getSymbolicName()) && version.equals(bundle.getVersion())) { return bundle; } } return null; } /** * {@inheritDoc} */ @Override public void connectRegion(Region headRegion, RegionFilter filter) throws BundleException { this.regionDigraph.connect(this, filter, headRegion); } /** * {@inheritDoc} */ @Override public boolean contains(long bundleId) { return this.bundleIdToRegionMapping.isBundleAssociatedWithRegion(bundleId, this); } /** * {@inheritDoc} */ @Override public boolean contains(Bundle bundle) { return contains(bundle.getBundleId()); } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + this.regionName.hashCode(); return result; } @Override public boolean equals(Object obj) { if (this == obj) { return true; } if (obj == null) { return false; } if (!(obj instanceof BundleIdBasedRegion)) { return false; } BundleIdBasedRegion other = (BundleIdBasedRegion) obj; return this.regionName.equals(other.regionName); } /** * {@inheritDoc} */ @Override public void removeBundle(Bundle bundle) { removeBundle(bundle.getBundleId()); } /** * {@inheritDoc} */ @Override public void removeBundle(long bundleId) { this.bundleIdToRegionMapping.dissociateBundleFromRegion(bundleId, this); } /** * {@inheritDoc} */ @Override public String toString() { return getName(); } /** * {@inheritDoc} */ @Override public Set getBundleIds() { return this.bundleIdToRegionMapping.getBundleIds(this); } /** * {@inheritDoc} */ @Override public Set getEdges() { return this.regionDigraph.getEdges(this); } /** * {@inheritDoc} */ @Override public void visitSubgraph(RegionDigraphVisitor visitor) { this.regionDigraph.visitSubgraph(this, visitor); } /** * {@inheritDoc} */ @Override public RegionDigraph getRegionDigraph() { return this.regionDigraph; } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy