You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@aries.apache.org by mn...@apache.org on 2012/10/09 10:47:01 UTC
svn commit: r1395912 [2/2] - in /aries/trunk: subsystem/subsystem-core/
subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/
subsystem/subsystem-itests/
subsystem/subsystem-itests/src/test/java/org/apache/aries/subsystem/ite...
Modified: aries/trunk/subsystem/subsystem-itests/src/test/java/org/apache/aries/subsystem/itests/SubsystemTest.java
URL: http://svn.apache.org/viewvc/aries/trunk/subsystem/subsystem-itests/src/test/java/org/apache/aries/subsystem/itests/SubsystemTest.java?rev=1395912&r1=1395911&r2=1395912&view=diff
==============================================================================
--- aries/trunk/subsystem/subsystem-itests/src/test/java/org/apache/aries/subsystem/itests/SubsystemTest.java (original)
+++ aries/trunk/subsystem/subsystem-itests/src/test/java/org/apache/aries/subsystem/itests/SubsystemTest.java Tue Oct 9 08:47:01 2012
@@ -1,837 +1,837 @@
-/*
- * Licensed 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 WARRANTIES OR 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.subsystem.itests;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-import static org.ops4j.pax.exam.CoreOptions.equinox;
-import static org.ops4j.pax.exam.CoreOptions.options;
-import static org.ops4j.pax.exam.CoreOptions.systemProperty;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.lang.reflect.Field;
-import java.net.URL;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.EnumSet;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-
-import org.apache.aries.subsystem.core.archive.ProvisionPolicyDirective;
-import org.apache.aries.subsystem.core.archive.SubsystemTypeHeader;
-import org.apache.aries.subsystem.core.internal.BundleResource;
-import org.apache.aries.subsystem.core.internal.ResourceHelper;
-import org.apache.aries.subsystem.core.internal.SubsystemIdentifier;
-import org.apache.aries.subsystem.itests.util.TestRepository;
-import org.apache.aries.subsystem.itests.util.Utils;
-import org.apache.aries.unittest.fixture.ArchiveFixture;
-import org.apache.aries.unittest.fixture.ArchiveFixture.JarFixture;
-import org.apache.aries.unittest.fixture.ArchiveFixture.ManifestFixture;
-import org.apache.aries.unittest.fixture.ArchiveFixture.ZipFixture;
-import org.ops4j.pax.exam.Option;
-import org.ops4j.pax.exam.container.def.PaxRunnerOptions;
-import org.osgi.framework.Bundle;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.BundleException;
-import org.osgi.framework.Constants;
-import org.osgi.framework.InvalidSyntaxException;
-import org.osgi.framework.ServiceEvent;
-import org.osgi.framework.ServiceListener;
-import org.osgi.framework.ServiceRegistration;
-import org.osgi.framework.Version;
-import org.osgi.framework.namespace.IdentityNamespace;
-import org.osgi.framework.wiring.BundleRevision;
-import org.osgi.resource.Resource;
-import org.osgi.service.repository.Repository;
-import org.osgi.service.repository.RepositoryContent;
-import org.osgi.service.subsystem.Subsystem;
-import org.osgi.service.subsystem.Subsystem.State;
-import org.osgi.service.subsystem.SubsystemConstants;
-
-public abstract class SubsystemTest extends IntegrationTest {
- protected static class SubsystemEventHandler implements ServiceListener {
- private static class ServiceEventInfo {
- private final ServiceEvent event;
- private final long id;
- private final State state;
- private final String symbolicName;
- private final String type;
- private final Version version;
-
- public ServiceEventInfo(ServiceEvent event) {
- id = (Long)event.getServiceReference().getProperty(SubsystemConstants.SUBSYSTEM_ID_PROPERTY);
- state = (State)event.getServiceReference().getProperty(SubsystemConstants.SUBSYSTEM_STATE_PROPERTY);
- symbolicName = (String)event.getServiceReference().getProperty(SubsystemConstants.SUBSYSTEM_SYMBOLICNAME_PROPERTY);
- type = (String)event.getServiceReference().getProperty(SubsystemConstants.SUBSYSTEM_TYPE_PROPERTY);
- version = (Version)event.getServiceReference().getProperty(SubsystemConstants.SUBSYSTEM_VERSION_PROPERTY);
- this.event = event;
- }
-
- public int getEventType() {
- return event.getType();
- }
-
- public long getId() {
- return id;
- }
-
- public State getState() {
- return state;
- }
-
- public String getSymbolicName() {
- return symbolicName;
- }
-
- public String getType() {
- return type;
- }
-
- public Version getVersion() {
- return version;
- }
- }
-
- private final Map<Long, List<ServiceEventInfo>> subsystemIdToEvents = new HashMap<Long, List<ServiceEventInfo>>();
-
- public void clear() {
- synchronized (subsystemIdToEvents) {
- subsystemIdToEvents.clear();
- }
- }
-
- public ServiceEventInfo poll(long subsystemId) throws InterruptedException {
- return poll(subsystemId, 0);
- }
-
- public ServiceEventInfo poll(long subsystemId, long timeout) throws InterruptedException {
- List<ServiceEventInfo> events;
- synchronized (subsystemIdToEvents) {
- events = subsystemIdToEvents.get(subsystemId);
- if (events == null) {
- events = new ArrayList<ServiceEventInfo>();
- subsystemIdToEvents.put(subsystemId, events);
- }
- }
- synchronized (events) {
- if (events.isEmpty()) {
- events.wait(timeout);
- if (events.isEmpty()) {
- return null;
- }
- }
- return events.remove(0);
- }
- }
-
- public void serviceChanged(ServiceEvent event) {
- Long subsystemId = (Long)event.getServiceReference().getProperty(SubsystemConstants.SUBSYSTEM_ID_PROPERTY);
- synchronized (subsystemIdToEvents) {
- List<ServiceEventInfo> events = subsystemIdToEvents.get(subsystemId);
- if (events == null) {
- events = new ArrayList<ServiceEventInfo>();
- subsystemIdToEvents.put(subsystemId, events);
- }
- synchronized (events) {
- events.add(new ServiceEventInfo(event));
- events.notify();
- }
- }
- }
-
- public int size() {
- synchronized (subsystemIdToEvents) {
- return subsystemIdToEvents.size();
- }
- }
- }
-
- @org.ops4j.pax.exam.junit.Configuration
- public static Option[] configuration() {
- Option[] options = options(
- // this is how you set the default log level when using pax
- // logging (logProfile)
- systemProperty("org.ops4j.pax.logging.DefaultServiceLog.level").value("INFO"),
- systemProperty("org.osgi.framework.bsnversion").value("multiple"),
- // Log
- mavenBundle("org.ops4j.pax.logging", "pax-logging-api"),
- mavenBundle("org.ops4j.pax.logging", "pax-logging-service"),
- // Felix mvn url handler
- mavenBundle("org.ops4j.pax.url", "pax-url-mvn"),
- // Bundles
- mavenBundle("org.apache.aries", "org.apache.aries.util").version("1.0.0"),
- mavenBundle("org.apache.aries.application", "org.apache.aries.application.api"),
- mavenBundle("org.apache.aries.application", "org.apache.aries.application.modeller").version("1.0.0"),
- mavenBundle("org.apache.aries.application", "org.apache.aries.application.utils"),
- mavenBundle("org.apache.aries.blueprint", "org.apache.aries.blueprint").version("1.0.0"),
- mavenBundle("org.apache.aries.proxy", "org.apache.aries.proxy").version("1.0.1-SNAPSHOT"),
- mavenBundle("org.apache.aries.subsystem", "org.apache.aries.subsystem.api"),
- mavenBundle("org.apache.aries.subsystem", "org.apache.aries.subsystem.core"),
- mavenBundle("org.apache.aries.subsystem", "org.apache.aries.subsystem.itest.interfaces"),
- mavenBundle("org.apache.aries.testsupport", "org.apache.aries.testsupport.unit"),
- mavenBundle("org.apache.felix", "org.apache.felix.resolver"),
- mavenBundle("org.eclipse.equinox", "org.eclipse.equinox.coordinator").version("1.1.0.v20120522-1841"),
- mavenBundle("org.eclipse.equinox", "org.eclipse.equinox.event").version("1.2.200.v20120522-2049"),
- mavenBundle("org.eclipse.equinox", "org.eclipse.equinox.region").version("1.1.0.v20120522-1841"),
- mavenBundle("org.osgi", "org.osgi.enterprise").version("5.0.0"),
-// org.ops4j.pax.exam.container.def.PaxRunnerOptions.vmOption("-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=5005"),
- PaxRunnerOptions.rawPaxRunnerOption("config", "classpath:ss-runner.properties"),
- equinox().version("3.8.0.V20120529-1548"));
- options = updateOptions(options);
- return options;
- }
-
- protected final SubsystemEventHandler subsystemEvents = new SubsystemEventHandler();
-
- protected Collection<ServiceRegistration<?>> serviceRegistrations = new ArrayList<ServiceRegistration<?>>();
-
- public void setUp() throws Exception {
- super.setUp();
- try {
- bundleContext.getBundle(0).getBundleContext().addServiceListener(subsystemEvents, '(' + Constants.OBJECTCLASS + '=' + Subsystem.class.getName() + ')');
- }
- catch (InvalidSyntaxException e) {
- fail("Invalid filter: " + e.getMessage());
- }
- assertSubsystemNotNull(getRootSubsystem());
- }
-
- public void tearDown() throws Exception
- {
- bundleContext.removeServiceListener(subsystemEvents);
- for (ServiceRegistration<?> registration : serviceRegistrations)
- Utils.unregisterQuietly(registration);
- serviceRegistrations.clear();
- super.tearDown();
- }
-
- protected void assertEmptySubsystem(Subsystem subsystem) {
- assertSymbolicName("org.apache.aries.subsystem.itests.subsystem.empty", subsystem);
- assertVersion("0", subsystem);
- assertType(SubsystemConstants.SUBSYSTEM_TYPE_APPLICATION, subsystem);
- }
-
- protected void assertBundleState(int state, String symbolicName, Subsystem subsystem) {
- Bundle bundle = getBundle(subsystem, symbolicName);
- assertBundleState(bundle, state);
- }
-
- protected void assertBundleState(Bundle bundle, int state) {
- assertNotNull("Bundle not found: " + bundle, bundle);
- assertTrue("Wrong state: " + bundle + " [expected " + state + " but was " + bundle.getState() + "]", (bundle.getState() & state) != 0);
- }
-
- protected void assertChild(Subsystem parent, Subsystem child) {
- Collection<Subsystem> children = new ArrayList<Subsystem>(1);
- children.add(child);
- assertChildren(parent, children);
- }
-
- protected void assertChildren(int size, Subsystem subsystem) {
- assertEquals("Wrong number of children", size, subsystem.getChildren().size());
- }
-
- protected void assertChildren(Subsystem parent, Collection<Subsystem> children) {
- assertTrue("Parent did not contain all children", parent.getChildren().containsAll(children));
- }
-
- protected void assertConstituent(Subsystem subsystem, String symbolicName) {
- assertConstituent(subsystem, symbolicName, Version.emptyVersion);
- }
-
- protected void assertConstituent(Subsystem subsystem, String symbolicName, Version version) {
- assertConstituent(subsystem, symbolicName, version, IdentityNamespace.TYPE_BUNDLE);
- }
-
- protected void assertContituent(Subsystem subsystem, String symbolicName, String type) {
- assertConstituent(subsystem, symbolicName, Version.emptyVersion, type);
- }
-
- protected Resource assertConstituent(Subsystem subsystem, String symbolicName, Version version, String type) {
- Resource constituent = getConstituent(subsystem, symbolicName, version, type);
- assertNotNull("Constituent not found: " + symbolicName + ';' + version + ';' + type, constituent);
- return constituent;
- }
-
- protected void assertConstituents(int size, Subsystem subsystem) {
- assertEquals("Wrong number of constituents", size, subsystem.getConstituents().size());
- }
-
- protected void assertDirectory(Subsystem subsystem) {
- Bundle bundle = getSubsystemCoreBundle();
- File file = bundle.getDataFile("subsystem" + subsystem.getSubsystemId());
- assertNotNull("Subsystem data file was null", file);
- assertTrue("Subsystem data file does not exist", file.exists());
- }
-
- protected void assertNotDirectory(Subsystem subsystem) {
- Bundle bundle = getSubsystemCoreBundle();
- File file = bundle.getDataFile("subsystem" + subsystem.getSubsystemId());
- assertNotNull("Subsystem data file was null", file);
- assertFalse("Subsystem data file exists", file.exists());
- }
-
- protected void assertEvent(Subsystem subsystem, Subsystem.State state) throws InterruptedException {
- assertEvent(subsystem, state, 0);
- }
-
- protected void assertEvent(Subsystem subsystem, Subsystem.State state, long timeout) throws InterruptedException {
- assertEvent(subsystem, state, subsystemEvents.poll(subsystem.getSubsystemId(), timeout));
- }
- protected void assertEvent(Subsystem subsystem, Subsystem.State state, SubsystemEventHandler.ServiceEventInfo event) {
- if (State.INSTALLING.equals(state))
- assertEvent(subsystem, state, event, ServiceEvent.REGISTERED);
- else
- assertEvent(subsystem, state, event, ServiceEvent.MODIFIED);
- }
-
- protected void assertEvent(Subsystem subsystem, Subsystem.State state, SubsystemEventHandler.ServiceEventInfo event, int type) {
- // TODO Could accept a ServiceRegistration as an argument and verify it against the one in the event.
- assertNotNull("No event", event);
- assertEquals("Wrong ID", subsystem.getSubsystemId(), event.getId());
- assertEquals("Wrong symbolic name", subsystem.getSymbolicName(), event.getSymbolicName());
- assertEquals("Wrong version", subsystem.getVersion(), event.getVersion());
- assertEquals("Wrong type", subsystem.getType(), event.getType());
- assertEquals("Wrong state", state, event.getState());
- assertEquals("Wrong event type", type, event.getEventType());
- }
-
- protected String assertHeaderExists(Subsystem subsystem, String name) {
- String header = subsystem.getSubsystemHeaders(null).get(name);
- assertNotNull("Missing header: " + name, header);
- return header;
- }
-
- protected void assertId(Subsystem subsystem) {
- assertId(subsystem.getSubsystemId());
- }
-
- protected void assertId(Long id) {
- assertTrue("Subsystem ID was not a positive integer: " + id, id > 0);
- }
-
- protected void assertLastId(long id) throws SecurityException, NoSuchFieldException, IllegalArgumentException, IllegalAccessException {
- Subsystem root = getRootSubsystem();
- Field lastId = SubsystemIdentifier.class.getDeclaredField("lastId");
- lastId.setAccessible(true);
- assertEquals("Wrong lastId", id, lastId.getLong(root));
- }
-
- protected void assertLocation(String expected, String actual) {
- assertTrue("Wrong location: " + actual, actual.indexOf(expected) != -1);
- }
-
- protected void assertLocation(String expected, Subsystem subsystem) {
- assertLocation(expected, subsystem.getLocation());
- }
-
- protected void assertNotChild(Subsystem parent, Subsystem child) {
- assertFalse("Parent contained child", parent.getChildren().contains(child));
- }
-
- protected void assertNotConstituent(Subsystem subsystem, String symbolicName) {
- assertNotConstituent(subsystem, symbolicName, Version.emptyVersion, IdentityNamespace.TYPE_BUNDLE);
- }
-
- protected void assertNotConstituent(Subsystem subsystem, String symbolicName, Version version, String type) {
- Resource constituent = getConstituent(subsystem, symbolicName, version, type);
- assertNull("Constituent found: " + symbolicName + ';' + version + ';' + type, constituent);
- }
-
- protected void assertParent(Subsystem expected, Subsystem subsystem) {
- for (Subsystem parent : subsystem.getParents()) {
- if (parent.equals(expected))
- return;
-
- }
- fail("Parent did not exist: " + expected.getSymbolicName());
- }
-
- protected void assertProvisionPolicy(Subsystem subsystem, boolean acceptsDependencies) {
- String headerStr = subsystem.getSubsystemHeaders(null).get(SubsystemConstants.SUBSYSTEM_TYPE);
- assertNotNull("Missing subsystem type header", headerStr);
- SubsystemTypeHeader header = new SubsystemTypeHeader(headerStr);
- ProvisionPolicyDirective directive = header.getProvisionPolicyDirective();
- if (acceptsDependencies)
- assertTrue("Subsystem does not accept dependencies", directive.isAcceptDependencies());
- else
- assertTrue("Subsystem accepts dependencies", directive.isRejectDependencies());
- }
-
- protected void assertRegionContextBundle(Subsystem s) {
- Bundle b = getRegionContextBundle(s);
- assertEquals("Not active", Bundle.ACTIVE, b.getState());
- assertEquals("Wrong location", s.getLocation() + '/' + s.getSubsystemId(), b.getLocation());
- assertEquals("Wrong symbolic name", "org.osgi.service.subsystem.region.context." + s.getSubsystemId(), b.getSymbolicName());
- assertEquals("Wrong version", Version.parseVersion("1.0.0"), b.getVersion());
- assertConstituent(s, "org.osgi.service.subsystem.region.context." + s.getSubsystemId(), Version.parseVersion("1.0.0"), IdentityNamespace.TYPE_BUNDLE);
- }
-
- protected void assertServiceEventsInstall(Subsystem subsystem) throws InterruptedException {
- assertEvent(subsystem, Subsystem.State.INSTALLING, subsystemEvents.poll(subsystem.getSubsystemId(), 5000));
- assertEvent(subsystem, Subsystem.State.INSTALLED, subsystemEvents.poll(subsystem.getSubsystemId(), 5000));
- }
-
- protected void assertServiceEventsResolve(Subsystem subsystem) throws InterruptedException {
- assertEvent(subsystem, Subsystem.State.RESOLVING, subsystemEvents.poll(subsystem.getSubsystemId(), 5000));
- assertServiceEventResolved(subsystem, ServiceEvent.MODIFIED);
- }
-
- protected void assertServiceEventsStart(Subsystem subsystem) throws InterruptedException {
- assertEvent(subsystem, Subsystem.State.STARTING, subsystemEvents.poll(subsystem.getSubsystemId(), 5000));
- assertEvent(subsystem, Subsystem.State.ACTIVE, subsystemEvents.poll(subsystem.getSubsystemId(), 5000));
- }
-
- protected void assertServiceEventsStop(Subsystem subsystem) throws InterruptedException {
- assertEvent(subsystem, Subsystem.State.STOPPING, subsystemEvents.poll(subsystem.getSubsystemId(), 5000));
- assertServiceEventResolved(subsystem, ServiceEvent.MODIFIED);
- // Don't forget about the unregistering event, which will have the same state as before.
- assertServiceEventResolved(subsystem, ServiceEvent.UNREGISTERING);
- }
-
- protected void assertServiceEventResolved(Subsystem subsystem, int type) throws InterruptedException {
- assertEvent(subsystem, Subsystem.State.RESOLVED, subsystemEvents.poll(subsystem.getSubsystemId(), 5000), type);
- }
-
- protected void assertState(State expected, State actual) {
- assertState(EnumSet.of(expected), actual);
- }
-
- protected void assertState(EnumSet<State> expected, State actual) {
- assertTrue("Wrong state: expected=" + expected + ", actual=" + actual, expected.contains(actual));
- }
-
- protected void assertState(State expected, Subsystem subsystem) {
- assertState(expected, subsystem.getState());
- }
-
- protected void assertState(EnumSet<State> expected, Subsystem subsystem) {
- assertState(expected, subsystem.getState());
- }
-
- protected Subsystem assertSubsystemLifeCycle(File file) throws Exception {
- Subsystem rootSubsystem = getOsgiService(Subsystem.class);
- assertNotNull("Root subsystem was null", rootSubsystem);
- Subsystem subsystem = rootSubsystem.install(file.toURI().toURL().toExternalForm());
- assertNotNull("The subsystem was null", subsystem);
- assertState(EnumSet.of(State.INSTALLING, State.INSTALLED), subsystem.getState());
- assertEvent(subsystem, Subsystem.State.INSTALLING, subsystemEvents.poll(subsystem.getSubsystemId(), 5000));
- assertEvent(subsystem, Subsystem.State.INSTALLED, subsystemEvents.poll(subsystem.getSubsystemId(), 5000));
- assertChild(rootSubsystem, subsystem);
- subsystem.start();
- assertState(EnumSet.of(State.RESOLVING, State.RESOLVED, State.STARTING, State.ACTIVE), subsystem.getState());
- assertEvent(subsystem, Subsystem.State.RESOLVING, subsystemEvents.poll(subsystem.getSubsystemId(), 5000));
- assertEvent(subsystem, Subsystem.State.RESOLVED, subsystemEvents.poll(subsystem.getSubsystemId(), 5000));
- assertEvent(subsystem, Subsystem.State.STARTING, subsystemEvents.poll(subsystem.getSubsystemId(), 5000));
- assertEvent(subsystem, Subsystem.State.ACTIVE, subsystemEvents.poll(subsystem.getSubsystemId(), 5000));
- subsystem.stop();
- assertState(EnumSet.of(State.STOPPING, State.RESOLVED), subsystem.getState());
- assertEvent(subsystem, Subsystem.State.STOPPING, subsystemEvents.poll(subsystem.getSubsystemId(), 5000));
- assertEvent(subsystem, Subsystem.State.RESOLVED, subsystemEvents.poll(subsystem.getSubsystemId(), 5000));
- subsystem.uninstall();
- assertState(EnumSet.of(State.UNINSTALLING, State.UNINSTALLED), subsystem.getState());
- assertEvent(subsystem, Subsystem.State.UNINSTALLING, subsystemEvents.poll(subsystem.getSubsystemId(), 5000));
- assertEvent(subsystem, Subsystem.State.UNINSTALLED, subsystemEvents.poll(subsystem.getSubsystemId(), 5000));
- assertNotChild(rootSubsystem, subsystem);
- return subsystem;
- }
-
- protected void assertSubsystemNotNull(Subsystem subsystem) {
- assertNotNull("Subsystem was null", subsystem);
- }
-
- protected void assertSymbolicName(String expected, Subsystem subsystem) {
- assertEquals("Wrong symbolic name: " + subsystem.getSymbolicName(), expected, subsystem.getSymbolicName());
- }
-
- protected void assertType(String expected, Subsystem subsystem) {
- assertEquals("Wrong type", expected, subsystem.getType());
- }
-
- protected void assertVersion(String expected, Subsystem subsystem) {
- assertVersion(Version.parseVersion(expected), subsystem);
- }
-
- protected void assertVersion(Version expected, Subsystem subsystem) {
- assertVersion(expected, subsystem.getVersion());
- }
-
- protected void assertVersion(Version expected, Version actual) {
- assertEquals("Wrong version", expected, actual);
- }
-
- protected static void createBundle(String symbolicName) throws IOException {
- createBundle(symbolicName, null);
- }
-
- protected static void createBundle(String symbolicName, Map<String, String> headers) throws IOException {
- createBundle(symbolicName, null, headers);
- }
-
- protected static void createBundle(String symbolicName, String version, Map<String, String> headers) throws IOException {
- if (headers == null)
- headers = new HashMap<String, String>();
- headers.put(Constants.BUNDLE_SYMBOLICNAME, symbolicName);
- if (version != null)
- headers.put(Constants.BUNDLE_VERSION, version);
- createBundle(headers);
- }
-
- protected static void createBundle(Map<String, String> headers) throws IOException
- {
- String symbolicName = headers.get(Constants.BUNDLE_SYMBOLICNAME);
- JarFixture bundle = ArchiveFixture.newJar();
- ManifestFixture manifest = bundle.manifest();
- for (Entry<String, String> header : headers.entrySet()) {
- manifest.attribute(header.getKey(), header.getValue());
- }
- write(symbolicName, bundle);
- }
-
- protected RepositoryContent createBundleRepositoryContent(String file) throws Exception {
- return createBundleRepositoryContent(new File(file));
- }
-
- protected RepositoryContent createBundleRepositoryContent(File file) throws Exception {
- return new BundleResource(file.toURI().toURL());
- }
-
- protected static void createManifest(String name, Map<String, String> headers) throws IOException {
- ManifestFixture manifest = ArchiveFixture.newJar().manifest();
- for (Entry<String, String> header : headers.entrySet()) {
- manifest.attribute(header.getKey(), header.getValue());
- }
- write(name, manifest);
- }
-
- protected static void createSubsystem(String name) throws IOException {
- createSubsystem(name, new String[0]);
- }
-
- protected static void createSubsystem(String name, String...contents) throws IOException {
- // The following input stream is closed by ArchiveFixture.copy.
- ZipFixture fixture = ArchiveFixture.newZip().binary("OSGI-INF/SUBSYSTEM.MF", new FileInputStream(name + ".mf"));
- if (contents != null) {
- for (String content : contents) {
- // The following input stream is closed by ArchiveFixture.copy.
- fixture.binary(content, new FileInputStream(content));
- }
- }
- write(name, fixture);
- }
-
- protected Subsystem findSubsystemService(long id) throws InvalidSyntaxException {
- String filter = "(" + SubsystemConstants.SUBSYSTEM_ID_PROPERTY + "=" + id + ")";
- return getOsgiService(Subsystem.class, filter, 5000);
- }
-
- protected Bundle getBundle(Subsystem subsystem, String symbolicName) {
- for (Bundle bundle : subsystem.getBundleContext().getBundles()) {
- if (symbolicName.equals(bundle.getSymbolicName())) {
- return bundle;
- }
- }
- return null;
- }
-
- protected Resource getConstituent(Subsystem subsystem, String symbolicName, Version version, String type) {
- for (Resource resource : subsystem.getConstituents()) {
- if (symbolicName.equals(ResourceHelper.getSymbolicNameAttribute(resource))) {
- if (version == null)
- version = Version.emptyVersion;
- if (version.equals(ResourceHelper.getVersionAttribute(resource))) {
- if (type == null)
- type = IdentityNamespace.TYPE_BUNDLE;
- if (type.equals(ResourceHelper.getTypeAttribute(resource))) {
- return resource;
- }
- }
- }
- }
- return null;
- }
-
- protected Bundle getConstituentAsBundle(Subsystem subsystem, String symbolicName, Version version, String type) {
- return getConstituentAsBundleRevision(subsystem, symbolicName, version, type).getBundle();
- }
-
- protected BundleRevision getConstituentAsBundleRevision(Subsystem subsystem, String symbolicName, Version version, String type) {
- Resource resource = getConstituent(subsystem, symbolicName, version, type);
- return (BundleRevision)resource;
- }
-
- protected Bundle getRegionContextBundle(Subsystem subsystem) {
- BundleContext bc = subsystem.getBundleContext();
- assertNotNull("No region context bundle", bc);
- return bc.getBundle();
- }
-
- protected Subsystem getRootSubsystem() {
- return getOsgiService(Subsystem.class);
- }
-
- protected Bundle getSubsystemCoreBundle() {
- return findBundleBySymbolicName("org.apache.aries.subsystem.core");
- }
-
- protected Bundle installBundleFromFile(String fileName) throws FileNotFoundException, BundleException {
- return installBundleFromFile(new File(fileName));
- }
-
- protected Bundle installBundleFromFile(File file) throws FileNotFoundException, BundleException {
- return installBundleFromFile(file, getRootSubsystem());
- }
-
- protected Bundle installBundleFromFile(String file, Subsystem subsystem) throws FileNotFoundException, BundleException {
- return installBundleFromFile(new File(file), subsystem);
- }
-
- protected Bundle installBundleFromFile(File file, Subsystem subsystem) throws FileNotFoundException, BundleException {
- Bundle bundle = installBundleFromFile(file, subsystem.getBundleContext());
- assertBundleState(Bundle.INSTALLED|Bundle.RESOLVED, bundle.getSymbolicName(), subsystem);
- return bundle;
- }
-
- protected Bundle installBundleFromFile(File file, BundleContext bundleContext) throws FileNotFoundException, BundleException {
- // The following input stream is closed by the bundle context.
- return bundleContext.installBundle(file.toURI().toString(), new FileInputStream(file));
- }
-
- protected Subsystem installSubsystemFromFile(Subsystem parent, String fileName) throws Exception {
- return installSubsystemFromFile(parent, new File(fileName));
- }
-
- protected Subsystem installSubsystemFromFile(String fileName) throws Exception {
- return installSubsystemFromFile(new File(fileName));
- }
-
- protected Subsystem installSubsystemFromFile(Subsystem parent, File file) throws Exception {
- return installSubsystem(parent, file.toURI().toURL().toExternalForm());
- }
-
- protected Subsystem installSubsystemFromFile(File file) throws Exception {
- return installSubsystem(getRootSubsystem(), file.toURI().toURL().toExternalForm());
- }
-
- protected Subsystem installSubsystem(String location) throws Exception {
- return installSubsystem(getRootSubsystem(), location);
- }
-
- protected Subsystem installSubsystem(String location, InputStream content) throws Exception {
- return installSubsystem(getRootSubsystem(), location, content);
- }
-
- protected Subsystem installSubsystem(Subsystem parent, String location) throws Exception {
- // The following input stream is closed by Subsystem.install.
- return installSubsystem(parent, location, new URL(location).openStream());
- }
-
- protected Subsystem installSubsystem(Subsystem parent, String location, InputStream content) throws Exception {
- subsystemEvents.clear();
- Subsystem subsystem = parent.install(location, content);
- assertSubsystemNotNull(subsystem);
- assertEvent(subsystem, State.INSTALLING, 5000);
- assertEvent(subsystem, State.INSTALLED, 5000);
- assertChild(parent, subsystem);
- assertLocation(location, subsystem);
- assertParent(parent, subsystem);
- assertState(State.INSTALLED, subsystem);
- assertLocation(location, subsystem);
- assertId(subsystem);
- // TODO This does not take into account nested directories.
-// assertDirectory(subsystem);
- return subsystem;
- }
-
- protected void registerRepositoryService(Repository repository) {
- serviceRegistrations.add(bundleContext.registerService(
- Repository.class, repository, null));
- }
-
- protected void registerRepositoryService(Resource...resources) {
- TestRepository.Builder builder = new TestRepository.Builder();
- for (Resource resource : resources) {
- builder.resource(resource);
- }
- registerRepositoryService(builder.build());
- }
-
- protected void registerRepositoryService(String...files) throws Exception {
- Resource[] resources = new Resource[files.length];
- int i = 0;
- for (String file : files) {
- resources[i++] = (Resource)createBundleRepositoryContent(file);
- }
- registerRepositoryService(resources);
- }
-
- protected void restartSubsystemsImplBundle() throws BundleException {
- Bundle b = getSubsystemCoreBundle();
- b.stop();
- b.start();
- }
-
- protected void startBundle(Bundle bundle) throws BundleException {
- startBundle(bundle, getRootSubsystem());
- }
-
- protected void startBundle(Bundle bundle, Subsystem subsystem) throws BundleException {
- bundle.start();
- assertBundleState(Bundle.ACTIVE, bundle.getSymbolicName(), subsystem);
- }
-
- protected void startSubsystem(Subsystem subsystem) throws Exception {
- startSubsystemFromInstalled(subsystem);
- }
-
- protected void startSubsystemFromInstalled(Subsystem subsystem) throws InterruptedException {
- assertState(State.INSTALLED, subsystem);
- subsystemEvents.clear();
- subsystem.start();
- assertEvent(subsystem, State.RESOLVING, 5000);
- assertEvent(subsystem, State.RESOLVED, 5000);
- assertEvent(subsystem, State.STARTING, 5000);
- assertEvent(subsystem, State.ACTIVE, 5000);
- assertState(State.ACTIVE, subsystem);
- }
-
- protected void startSubsystemFromResolved(Subsystem subsystem) throws InterruptedException {
- assertState(State.RESOLVED, subsystem);
- subsystemEvents.clear();
- subsystem.start();
- assertEvent(subsystem, State.STARTING, 5000);
- assertEvent(subsystem, State.ACTIVE, 5000);
- assertState(State.ACTIVE, subsystem);
- }
-
- protected void stopAndUninstallSubsystemSilently(Subsystem subsystem) {
- stopSubsystemSilently(subsystem);
- uninstallSubsystemSilently(subsystem);
- }
-
- protected void stopSubsystem(Subsystem subsystem) throws Exception {
- assertState(State.ACTIVE, subsystem);
- subsystemEvents.clear();
- subsystem.stop();
- assertEvent(subsystem, State.STOPPING, 5000);
- assertEvent(subsystem, State.RESOLVED, 5000);
- assertState(State.RESOLVED, subsystem);
- }
-
- protected void stopSubsystemSilently(Subsystem subsystem) {
- try {
- stopSubsystem(subsystem);
- }
- catch (Throwable t) {
- t.printStackTrace();
- }
- }
-
- protected void uninstallSilently(Bundle bundle) {
- if (bundle == null)
- return;
- try {
- bundle.uninstall();
- }
- catch (Exception e) {}
- }
-
- protected void uninstallSubsystem(Subsystem subsystem) throws Exception {
- assertState(EnumSet.of(State.INSTALLED, State.RESOLVED), subsystem);
- subsystemEvents.clear();
- Collection<Subsystem> parents = subsystem.getParents();
- Bundle b = null;
- if (subsystem.getType().equals(SubsystemConstants.SUBSYSTEM_TYPE_APPLICATION)
- || subsystem.getType().equals(SubsystemConstants.SUBSYSTEM_TYPE_COMPOSITE))
- b = getRegionContextBundle(subsystem);
- State state = subsystem.getState();
- subsystem.uninstall();
- if (!EnumSet.of(State.INSTALL_FAILED, State.INSTALLED, State.INSTALLING).contains(state))
- assertEvent(subsystem, State.INSTALLED, 5000);
- assertEvent(subsystem, State.UNINSTALLING, 5000);
- assertEvent(subsystem, State.UNINSTALLED, 5000);
- assertState(State.UNINSTALLED, subsystem);
- for (Subsystem parent : parents)
- assertNotChild(parent, subsystem);
-// assertNotDirectory(subsystem);
- if (b != null)
- assertEquals("Region context bundle not uninstalled", Bundle.UNINSTALLED, b.getState());
- }
-
- protected void uninstallSubsystemSilently(Subsystem subsystem) {
- if (subsystem == null)
- return;
- try {
- uninstallSubsystem(subsystem);
- }
- catch (Throwable t) {
- t.printStackTrace();
- }
- }
-
- protected static void write(String file, ArchiveFixture.AbstractFixture fixture) throws IOException
- {
- write(new File(file), fixture);
- }
-
- protected static void write(File file, ArchiveFixture.AbstractFixture fixture) throws IOException {
- FileOutputStream fos = new FileOutputStream(file);
- try {
- fixture.writeOut(fos);
- }
- finally {
- fos.close();
- }
- }
-
- static void createApplication(String name, String[] content) throws Exception
- {
- ZipFixture feature = ArchiveFixture
- .newZip()
- .binary("OSGI-INF/SUBSYSTEM.MF",
- // The following input stream is closed by ArchiveFixture.copy.
- SubsystemTest.class.getClassLoader().getResourceAsStream(
- name + "/OSGI-INF/SUBSYSTEM.MF"));
- for (String s : content) {
- try {
- feature.binary(s,
- // The following input stream is closed by ArchiveFixture.copy.
- SubsystemTest.class.getClassLoader().getResourceAsStream(
- name + '/' + s));
- }
- catch (Exception e) {
- // The following input stream is closed by ArchiveFixture.copy.
- feature.binary(s, new FileInputStream(new File(s)));
- }
- }
- feature.end();
- FileOutputStream fos = new FileOutputStream(name + ".esa");
- try {
- feature.writeOut(fos);
- } finally {
- Utils.closeQuietly(fos);
- }
- }
-}
+/*
+ * Licensed 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 WARRANTIES OR 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.subsystem.itests;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+import static org.ops4j.pax.exam.CoreOptions.equinox;
+import static org.ops4j.pax.exam.CoreOptions.options;
+import static org.ops4j.pax.exam.CoreOptions.systemProperty;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.lang.reflect.Field;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.EnumSet;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import org.apache.aries.subsystem.core.archive.ProvisionPolicyDirective;
+import org.apache.aries.subsystem.core.archive.SubsystemTypeHeader;
+import org.apache.aries.subsystem.core.internal.BundleResource;
+import org.apache.aries.subsystem.core.internal.ResourceHelper;
+import org.apache.aries.subsystem.core.internal.SubsystemIdentifier;
+import org.apache.aries.subsystem.itests.util.TestRepository;
+import org.apache.aries.subsystem.itests.util.Utils;
+import org.apache.aries.unittest.fixture.ArchiveFixture;
+import org.apache.aries.unittest.fixture.ArchiveFixture.JarFixture;
+import org.apache.aries.unittest.fixture.ArchiveFixture.ManifestFixture;
+import org.apache.aries.unittest.fixture.ArchiveFixture.ZipFixture;
+import org.ops4j.pax.exam.Option;
+import org.ops4j.pax.exam.container.def.PaxRunnerOptions;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.BundleException;
+import org.osgi.framework.Constants;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.framework.ServiceEvent;
+import org.osgi.framework.ServiceListener;
+import org.osgi.framework.ServiceRegistration;
+import org.osgi.framework.Version;
+import org.osgi.framework.namespace.IdentityNamespace;
+import org.osgi.framework.wiring.BundleRevision;
+import org.osgi.resource.Resource;
+import org.osgi.service.repository.Repository;
+import org.osgi.service.repository.RepositoryContent;
+import org.osgi.service.subsystem.Subsystem;
+import org.osgi.service.subsystem.Subsystem.State;
+import org.osgi.service.subsystem.SubsystemConstants;
+
+public abstract class SubsystemTest extends IntegrationTest {
+ protected static class SubsystemEventHandler implements ServiceListener {
+ private static class ServiceEventInfo {
+ private final ServiceEvent event;
+ private final long id;
+ private final State state;
+ private final String symbolicName;
+ private final String type;
+ private final Version version;
+
+ public ServiceEventInfo(ServiceEvent event) {
+ id = (Long)event.getServiceReference().getProperty(SubsystemConstants.SUBSYSTEM_ID_PROPERTY);
+ state = (State)event.getServiceReference().getProperty(SubsystemConstants.SUBSYSTEM_STATE_PROPERTY);
+ symbolicName = (String)event.getServiceReference().getProperty(SubsystemConstants.SUBSYSTEM_SYMBOLICNAME_PROPERTY);
+ type = (String)event.getServiceReference().getProperty(SubsystemConstants.SUBSYSTEM_TYPE_PROPERTY);
+ version = (Version)event.getServiceReference().getProperty(SubsystemConstants.SUBSYSTEM_VERSION_PROPERTY);
+ this.event = event;
+ }
+
+ public int getEventType() {
+ return event.getType();
+ }
+
+ public long getId() {
+ return id;
+ }
+
+ public State getState() {
+ return state;
+ }
+
+ public String getSymbolicName() {
+ return symbolicName;
+ }
+
+ public String getType() {
+ return type;
+ }
+
+ public Version getVersion() {
+ return version;
+ }
+ }
+
+ private final Map<Long, List<ServiceEventInfo>> subsystemIdToEvents = new HashMap<Long, List<ServiceEventInfo>>();
+
+ public void clear() {
+ synchronized (subsystemIdToEvents) {
+ subsystemIdToEvents.clear();
+ }
+ }
+
+ public ServiceEventInfo poll(long subsystemId) throws InterruptedException {
+ return poll(subsystemId, 0);
+ }
+
+ public ServiceEventInfo poll(long subsystemId, long timeout) throws InterruptedException {
+ List<ServiceEventInfo> events;
+ synchronized (subsystemIdToEvents) {
+ events = subsystemIdToEvents.get(subsystemId);
+ if (events == null) {
+ events = new ArrayList<ServiceEventInfo>();
+ subsystemIdToEvents.put(subsystemId, events);
+ }
+ }
+ synchronized (events) {
+ if (events.isEmpty()) {
+ events.wait(timeout);
+ if (events.isEmpty()) {
+ return null;
+ }
+ }
+ return events.remove(0);
+ }
+ }
+
+ public void serviceChanged(ServiceEvent event) {
+ Long subsystemId = (Long)event.getServiceReference().getProperty(SubsystemConstants.SUBSYSTEM_ID_PROPERTY);
+ synchronized (subsystemIdToEvents) {
+ List<ServiceEventInfo> events = subsystemIdToEvents.get(subsystemId);
+ if (events == null) {
+ events = new ArrayList<ServiceEventInfo>();
+ subsystemIdToEvents.put(subsystemId, events);
+ }
+ synchronized (events) {
+ events.add(new ServiceEventInfo(event));
+ events.notify();
+ }
+ }
+ }
+
+ public int size() {
+ synchronized (subsystemIdToEvents) {
+ return subsystemIdToEvents.size();
+ }
+ }
+ }
+
+ @org.ops4j.pax.exam.junit.Configuration
+ public static Option[] configuration() {
+ Option[] options = options(
+ // this is how you set the default log level when using pax
+ // logging (logProfile)
+ systemProperty("org.ops4j.pax.logging.DefaultServiceLog.level").value("INFO"),
+ systemProperty("org.osgi.framework.bsnversion").value("multiple"),
+ // Log
+ mavenBundle("org.ops4j.pax.logging", "pax-logging-api"),
+ mavenBundle("org.ops4j.pax.logging", "pax-logging-service"),
+ // Felix mvn url handler
+ mavenBundle("org.ops4j.pax.url", "pax-url-mvn"),
+ // Bundles
+ mavenBundle("org.apache.aries", "org.apache.aries.util"),
+ mavenBundle("org.apache.aries.application", "org.apache.aries.application.api"),
+ mavenBundle("org.apache.aries.application", "org.apache.aries.application.modeller").version("1.0.0"),
+ mavenBundle("org.apache.aries.application", "org.apache.aries.application.utils"),
+ mavenBundle("org.apache.aries.blueprint", "org.apache.aries.blueprint").version("1.0.0"),
+ mavenBundle("org.apache.aries.proxy", "org.apache.aries.proxy").version("1.0.1-SNAPSHOT"),
+ mavenBundle("org.apache.aries.subsystem", "org.apache.aries.subsystem.api"),
+ mavenBundle("org.apache.aries.subsystem", "org.apache.aries.subsystem.core"),
+ mavenBundle("org.apache.aries.subsystem", "org.apache.aries.subsystem.itest.interfaces"),
+ mavenBundle("org.apache.aries.testsupport", "org.apache.aries.testsupport.unit"),
+ mavenBundle("org.apache.felix", "org.apache.felix.resolver"),
+ mavenBundle("org.eclipse.equinox", "org.eclipse.equinox.coordinator").version("1.1.0.v20120522-1841"),
+ mavenBundle("org.eclipse.equinox", "org.eclipse.equinox.event").version("1.2.200.v20120522-2049"),
+ mavenBundle("org.eclipse.equinox", "org.eclipse.equinox.region").version("1.1.0.v20120522-1841"),
+ mavenBundle("org.osgi", "org.osgi.enterprise").version("5.0.0"),
+ //org.ops4j.pax.exam.container.def.PaxRunnerOptions.vmOption("-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=7777"),
+ PaxRunnerOptions.rawPaxRunnerOption("config", "classpath:ss-runner.properties"),
+ equinox().version("3.8.0.V20120529-1548"));
+ options = updateOptions(options);
+ return options;
+ }
+
+ protected final SubsystemEventHandler subsystemEvents = new SubsystemEventHandler();
+
+ protected Collection<ServiceRegistration<?>> serviceRegistrations = new ArrayList<ServiceRegistration<?>>();
+
+ public void setUp() throws Exception {
+ super.setUp();
+ try {
+ bundleContext.getBundle(0).getBundleContext().addServiceListener(subsystemEvents, '(' + Constants.OBJECTCLASS + '=' + Subsystem.class.getName() + ')');
+ }
+ catch (InvalidSyntaxException e) {
+ fail("Invalid filter: " + e.getMessage());
+ }
+ assertSubsystemNotNull(getRootSubsystem());
+ }
+
+ public void tearDown() throws Exception
+ {
+ bundleContext.removeServiceListener(subsystemEvents);
+ for (ServiceRegistration<?> registration : serviceRegistrations)
+ Utils.unregisterQuietly(registration);
+ serviceRegistrations.clear();
+ super.tearDown();
+ }
+
+ protected void assertEmptySubsystem(Subsystem subsystem) {
+ assertSymbolicName("org.apache.aries.subsystem.itests.subsystem.empty", subsystem);
+ assertVersion("0", subsystem);
+ assertType(SubsystemConstants.SUBSYSTEM_TYPE_APPLICATION, subsystem);
+ }
+
+ protected void assertBundleState(int state, String symbolicName, Subsystem subsystem) {
+ Bundle bundle = getBundle(subsystem, symbolicName);
+ assertBundleState(bundle, state);
+ }
+
+ protected void assertBundleState(Bundle bundle, int state) {
+ assertNotNull("Bundle not found: " + bundle, bundle);
+ assertTrue("Wrong state: " + bundle + " [expected " + state + " but was " + bundle.getState() + "]", (bundle.getState() & state) != 0);
+ }
+
+ protected void assertChild(Subsystem parent, Subsystem child) {
+ Collection<Subsystem> children = new ArrayList<Subsystem>(1);
+ children.add(child);
+ assertChildren(parent, children);
+ }
+
+ protected void assertChildren(int size, Subsystem subsystem) {
+ assertEquals("Wrong number of children", size, subsystem.getChildren().size());
+ }
+
+ protected void assertChildren(Subsystem parent, Collection<Subsystem> children) {
+ assertTrue("Parent did not contain all children", parent.getChildren().containsAll(children));
+ }
+
+ protected void assertConstituent(Subsystem subsystem, String symbolicName) {
+ assertConstituent(subsystem, symbolicName, Version.emptyVersion);
+ }
+
+ protected void assertConstituent(Subsystem subsystem, String symbolicName, Version version) {
+ assertConstituent(subsystem, symbolicName, version, IdentityNamespace.TYPE_BUNDLE);
+ }
+
+ protected void assertContituent(Subsystem subsystem, String symbolicName, String type) {
+ assertConstituent(subsystem, symbolicName, Version.emptyVersion, type);
+ }
+
+ protected Resource assertConstituent(Subsystem subsystem, String symbolicName, Version version, String type) {
+ Resource constituent = getConstituent(subsystem, symbolicName, version, type);
+ assertNotNull("Constituent not found: " + symbolicName + ';' + version + ';' + type, constituent);
+ return constituent;
+ }
+
+ protected void assertConstituents(int size, Subsystem subsystem) {
+ assertEquals("Wrong number of constituents", size, subsystem.getConstituents().size());
+ }
+
+ protected void assertDirectory(Subsystem subsystem) {
+ Bundle bundle = getSubsystemCoreBundle();
+ File file = bundle.getDataFile("subsystem" + subsystem.getSubsystemId());
+ assertNotNull("Subsystem data file was null", file);
+ assertTrue("Subsystem data file does not exist", file.exists());
+ }
+
+ protected void assertNotDirectory(Subsystem subsystem) {
+ Bundle bundle = getSubsystemCoreBundle();
+ File file = bundle.getDataFile("subsystem" + subsystem.getSubsystemId());
+ assertNotNull("Subsystem data file was null", file);
+ assertFalse("Subsystem data file exists", file.exists());
+ }
+
+ protected void assertEvent(Subsystem subsystem, Subsystem.State state) throws InterruptedException {
+ assertEvent(subsystem, state, 0);
+ }
+
+ protected void assertEvent(Subsystem subsystem, Subsystem.State state, long timeout) throws InterruptedException {
+ assertEvent(subsystem, state, subsystemEvents.poll(subsystem.getSubsystemId(), timeout));
+ }
+ protected void assertEvent(Subsystem subsystem, Subsystem.State state, SubsystemEventHandler.ServiceEventInfo event) {
+ if (State.INSTALLING.equals(state))
+ assertEvent(subsystem, state, event, ServiceEvent.REGISTERED);
+ else
+ assertEvent(subsystem, state, event, ServiceEvent.MODIFIED);
+ }
+
+ protected void assertEvent(Subsystem subsystem, Subsystem.State state, SubsystemEventHandler.ServiceEventInfo event, int type) {
+ // TODO Could accept a ServiceRegistration as an argument and verify it against the one in the event.
+ assertNotNull("No event", event);
+ assertEquals("Wrong ID", subsystem.getSubsystemId(), event.getId());
+ assertEquals("Wrong symbolic name", subsystem.getSymbolicName(), event.getSymbolicName());
+ assertEquals("Wrong version", subsystem.getVersion(), event.getVersion());
+ assertEquals("Wrong type", subsystem.getType(), event.getType());
+ assertEquals("Wrong state", state, event.getState());
+ assertEquals("Wrong event type", type, event.getEventType());
+ }
+
+ protected String assertHeaderExists(Subsystem subsystem, String name) {
+ String header = subsystem.getSubsystemHeaders(null).get(name);
+ assertNotNull("Missing header: " + name, header);
+ return header;
+ }
+
+ protected void assertId(Subsystem subsystem) {
+ assertId(subsystem.getSubsystemId());
+ }
+
+ protected void assertId(Long id) {
+ assertTrue("Subsystem ID was not a positive integer: " + id, id > 0);
+ }
+
+ protected void assertLastId(long id) throws SecurityException, NoSuchFieldException, IllegalArgumentException, IllegalAccessException {
+ Subsystem root = getRootSubsystem();
+ Field lastId = SubsystemIdentifier.class.getDeclaredField("lastId");
+ lastId.setAccessible(true);
+ assertEquals("Wrong lastId", id, lastId.getLong(root));
+ }
+
+ protected void assertLocation(String expected, String actual) {
+ assertTrue("Wrong location: " + actual, actual.indexOf(expected) != -1);
+ }
+
+ protected void assertLocation(String expected, Subsystem subsystem) {
+ assertLocation(expected, subsystem.getLocation());
+ }
+
+ protected void assertNotChild(Subsystem parent, Subsystem child) {
+ assertFalse("Parent contained child", parent.getChildren().contains(child));
+ }
+
+ protected void assertNotConstituent(Subsystem subsystem, String symbolicName) {
+ assertNotConstituent(subsystem, symbolicName, Version.emptyVersion, IdentityNamespace.TYPE_BUNDLE);
+ }
+
+ protected void assertNotConstituent(Subsystem subsystem, String symbolicName, Version version, String type) {
+ Resource constituent = getConstituent(subsystem, symbolicName, version, type);
+ assertNull("Constituent found: " + symbolicName + ';' + version + ';' + type, constituent);
+ }
+
+ protected void assertParent(Subsystem expected, Subsystem subsystem) {
+ for (Subsystem parent : subsystem.getParents()) {
+ if (parent.equals(expected))
+ return;
+
+ }
+ fail("Parent did not exist: " + expected.getSymbolicName());
+ }
+
+ protected void assertProvisionPolicy(Subsystem subsystem, boolean acceptsDependencies) {
+ String headerStr = subsystem.getSubsystemHeaders(null).get(SubsystemConstants.SUBSYSTEM_TYPE);
+ assertNotNull("Missing subsystem type header", headerStr);
+ SubsystemTypeHeader header = new SubsystemTypeHeader(headerStr);
+ ProvisionPolicyDirective directive = header.getProvisionPolicyDirective();
+ if (acceptsDependencies)
+ assertTrue("Subsystem does not accept dependencies", directive.isAcceptDependencies());
+ else
+ assertTrue("Subsystem accepts dependencies", directive.isRejectDependencies());
+ }
+
+ protected void assertRegionContextBundle(Subsystem s) {
+ Bundle b = getRegionContextBundle(s);
+ assertEquals("Not active", Bundle.ACTIVE, b.getState());
+ assertEquals("Wrong location", s.getLocation() + '/' + s.getSubsystemId(), b.getLocation());
+ assertEquals("Wrong symbolic name", "org.osgi.service.subsystem.region.context." + s.getSubsystemId(), b.getSymbolicName());
+ assertEquals("Wrong version", Version.parseVersion("1.0.0"), b.getVersion());
+ assertConstituent(s, "org.osgi.service.subsystem.region.context." + s.getSubsystemId(), Version.parseVersion("1.0.0"), IdentityNamespace.TYPE_BUNDLE);
+ }
+
+ protected void assertServiceEventsInstall(Subsystem subsystem) throws InterruptedException {
+ assertEvent(subsystem, Subsystem.State.INSTALLING, subsystemEvents.poll(subsystem.getSubsystemId(), 5000));
+ assertEvent(subsystem, Subsystem.State.INSTALLED, subsystemEvents.poll(subsystem.getSubsystemId(), 5000));
+ }
+
+ protected void assertServiceEventsResolve(Subsystem subsystem) throws InterruptedException {
+ assertEvent(subsystem, Subsystem.State.RESOLVING, subsystemEvents.poll(subsystem.getSubsystemId(), 5000));
+ assertServiceEventResolved(subsystem, ServiceEvent.MODIFIED);
+ }
+
+ protected void assertServiceEventsStart(Subsystem subsystem) throws InterruptedException {
+ assertEvent(subsystem, Subsystem.State.STARTING, subsystemEvents.poll(subsystem.getSubsystemId(), 5000));
+ assertEvent(subsystem, Subsystem.State.ACTIVE, subsystemEvents.poll(subsystem.getSubsystemId(), 5000));
+ }
+
+ protected void assertServiceEventsStop(Subsystem subsystem) throws InterruptedException {
+ assertEvent(subsystem, Subsystem.State.STOPPING, subsystemEvents.poll(subsystem.getSubsystemId(), 5000));
+ assertServiceEventResolved(subsystem, ServiceEvent.MODIFIED);
+ // Don't forget about the unregistering event, which will have the same state as before.
+ assertServiceEventResolved(subsystem, ServiceEvent.UNREGISTERING);
+ }
+
+ protected void assertServiceEventResolved(Subsystem subsystem, int type) throws InterruptedException {
+ assertEvent(subsystem, Subsystem.State.RESOLVED, subsystemEvents.poll(subsystem.getSubsystemId(), 5000), type);
+ }
+
+ protected void assertState(State expected, State actual) {
+ assertState(EnumSet.of(expected), actual);
+ }
+
+ protected void assertState(EnumSet<State> expected, State actual) {
+ assertTrue("Wrong state: expected=" + expected + ", actual=" + actual, expected.contains(actual));
+ }
+
+ protected void assertState(State expected, Subsystem subsystem) {
+ assertState(expected, subsystem.getState());
+ }
+
+ protected void assertState(EnumSet<State> expected, Subsystem subsystem) {
+ assertState(expected, subsystem.getState());
+ }
+
+ protected Subsystem assertSubsystemLifeCycle(File file) throws Exception {
+ Subsystem rootSubsystem = getOsgiService(Subsystem.class);
+ assertNotNull("Root subsystem was null", rootSubsystem);
+ Subsystem subsystem = rootSubsystem.install(file.toURI().toURL().toExternalForm());
+ assertNotNull("The subsystem was null", subsystem);
+ assertState(EnumSet.of(State.INSTALLING, State.INSTALLED), subsystem.getState());
+ assertEvent(subsystem, Subsystem.State.INSTALLING, subsystemEvents.poll(subsystem.getSubsystemId(), 5000));
+ assertEvent(subsystem, Subsystem.State.INSTALLED, subsystemEvents.poll(subsystem.getSubsystemId(), 5000));
+ assertChild(rootSubsystem, subsystem);
+ subsystem.start();
+ assertState(EnumSet.of(State.RESOLVING, State.RESOLVED, State.STARTING, State.ACTIVE), subsystem.getState());
+ assertEvent(subsystem, Subsystem.State.RESOLVING, subsystemEvents.poll(subsystem.getSubsystemId(), 5000));
+ assertEvent(subsystem, Subsystem.State.RESOLVED, subsystemEvents.poll(subsystem.getSubsystemId(), 5000));
+ assertEvent(subsystem, Subsystem.State.STARTING, subsystemEvents.poll(subsystem.getSubsystemId(), 5000));
+ assertEvent(subsystem, Subsystem.State.ACTIVE, subsystemEvents.poll(subsystem.getSubsystemId(), 5000));
+ subsystem.stop();
+ assertState(EnumSet.of(State.STOPPING, State.RESOLVED), subsystem.getState());
+ assertEvent(subsystem, Subsystem.State.STOPPING, subsystemEvents.poll(subsystem.getSubsystemId(), 5000));
+ assertEvent(subsystem, Subsystem.State.RESOLVED, subsystemEvents.poll(subsystem.getSubsystemId(), 5000));
+ subsystem.uninstall();
+ assertState(EnumSet.of(State.UNINSTALLING, State.UNINSTALLED), subsystem.getState());
+ assertEvent(subsystem, Subsystem.State.UNINSTALLING, subsystemEvents.poll(subsystem.getSubsystemId(), 5000));
+ assertEvent(subsystem, Subsystem.State.UNINSTALLED, subsystemEvents.poll(subsystem.getSubsystemId(), 5000));
+ assertNotChild(rootSubsystem, subsystem);
+ return subsystem;
+ }
+
+ protected void assertSubsystemNotNull(Subsystem subsystem) {
+ assertNotNull("Subsystem was null", subsystem);
+ }
+
+ protected void assertSymbolicName(String expected, Subsystem subsystem) {
+ assertEquals("Wrong symbolic name: " + subsystem.getSymbolicName(), expected, subsystem.getSymbolicName());
+ }
+
+ protected void assertType(String expected, Subsystem subsystem) {
+ assertEquals("Wrong type", expected, subsystem.getType());
+ }
+
+ protected void assertVersion(String expected, Subsystem subsystem) {
+ assertVersion(Version.parseVersion(expected), subsystem);
+ }
+
+ protected void assertVersion(Version expected, Subsystem subsystem) {
+ assertVersion(expected, subsystem.getVersion());
+ }
+
+ protected void assertVersion(Version expected, Version actual) {
+ assertEquals("Wrong version", expected, actual);
+ }
+
+ protected static void createBundle(String symbolicName) throws IOException {
+ createBundle(symbolicName, null);
+ }
+
+ protected static void createBundle(String symbolicName, Map<String, String> headers) throws IOException {
+ createBundle(symbolicName, null, headers);
+ }
+
+ protected static void createBundle(String symbolicName, String version, Map<String, String> headers) throws IOException {
+ if (headers == null)
+ headers = new HashMap<String, String>();
+ headers.put(Constants.BUNDLE_SYMBOLICNAME, symbolicName);
+ if (version != null)
+ headers.put(Constants.BUNDLE_VERSION, version);
+ createBundle(headers);
+ }
+
+ protected static void createBundle(Map<String, String> headers) throws IOException
+ {
+ String symbolicName = headers.get(Constants.BUNDLE_SYMBOLICNAME);
+ JarFixture bundle = ArchiveFixture.newJar();
+ ManifestFixture manifest = bundle.manifest();
+ for (Entry<String, String> header : headers.entrySet()) {
+ manifest.attribute(header.getKey(), header.getValue());
+ }
+ write(symbolicName, bundle);
+ }
+
+ protected RepositoryContent createBundleRepositoryContent(String file) throws Exception {
+ return createBundleRepositoryContent(new File(file));
+ }
+
+ protected RepositoryContent createBundleRepositoryContent(File file) throws Exception {
+ return new BundleResource(file.toURI().toURL());
+ }
+
+ protected static void createManifest(String name, Map<String, String> headers) throws IOException {
+ ManifestFixture manifest = ArchiveFixture.newJar().manifest();
+ for (Entry<String, String> header : headers.entrySet()) {
+ manifest.attribute(header.getKey(), header.getValue());
+ }
+ write(name, manifest);
+ }
+
+ protected static void createSubsystem(String name) throws IOException {
+ createSubsystem(name, new String[0]);
+ }
+
+ protected static void createSubsystem(String name, String...contents) throws IOException {
+ // The following input stream is closed by ArchiveFixture.copy.
+ ZipFixture fixture = ArchiveFixture.newZip().binary("OSGI-INF/SUBSYSTEM.MF", new FileInputStream(name + ".mf"));
+ if (contents != null) {
+ for (String content : contents) {
+ // The following input stream is closed by ArchiveFixture.copy.
+ fixture.binary(content, new FileInputStream(content));
+ }
+ }
+ write(name, fixture);
+ }
+
+ protected Subsystem findSubsystemService(long id) throws InvalidSyntaxException {
+ String filter = "(" + SubsystemConstants.SUBSYSTEM_ID_PROPERTY + "=" + id + ")";
+ return getOsgiService(Subsystem.class, filter, 5000);
+ }
+
+ protected Bundle getBundle(Subsystem subsystem, String symbolicName) {
+ for (Bundle bundle : subsystem.getBundleContext().getBundles()) {
+ if (symbolicName.equals(bundle.getSymbolicName())) {
+ return bundle;
+ }
+ }
+ return null;
+ }
+
+ protected Resource getConstituent(Subsystem subsystem, String symbolicName, Version version, String type) {
+ for (Resource resource : subsystem.getConstituents()) {
+ if (symbolicName.equals(ResourceHelper.getSymbolicNameAttribute(resource))) {
+ if (version == null)
+ version = Version.emptyVersion;
+ if (version.equals(ResourceHelper.getVersionAttribute(resource))) {
+ if (type == null)
+ type = IdentityNamespace.TYPE_BUNDLE;
+ if (type.equals(ResourceHelper.getTypeAttribute(resource))) {
+ return resource;
+ }
+ }
+ }
+ }
+ return null;
+ }
+
+ protected Bundle getConstituentAsBundle(Subsystem subsystem, String symbolicName, Version version, String type) {
+ return getConstituentAsBundleRevision(subsystem, symbolicName, version, type).getBundle();
+ }
+
+ protected BundleRevision getConstituentAsBundleRevision(Subsystem subsystem, String symbolicName, Version version, String type) {
+ Resource resource = getConstituent(subsystem, symbolicName, version, type);
+ return (BundleRevision)resource;
+ }
+
+ protected Bundle getRegionContextBundle(Subsystem subsystem) {
+ BundleContext bc = subsystem.getBundleContext();
+ assertNotNull("No region context bundle", bc);
+ return bc.getBundle();
+ }
+
+ protected Subsystem getRootSubsystem() {
+ return getOsgiService(Subsystem.class);
+ }
+
+ protected Bundle getSubsystemCoreBundle() {
+ return findBundleBySymbolicName("org.apache.aries.subsystem.core");
+ }
+
+ protected Bundle installBundleFromFile(String fileName) throws FileNotFoundException, BundleException {
+ return installBundleFromFile(new File(fileName));
+ }
+
+ protected Bundle installBundleFromFile(File file) throws FileNotFoundException, BundleException {
+ return installBundleFromFile(file, getRootSubsystem());
+ }
+
+ protected Bundle installBundleFromFile(String file, Subsystem subsystem) throws FileNotFoundException, BundleException {
+ return installBundleFromFile(new File(file), subsystem);
+ }
+
+ protected Bundle installBundleFromFile(File file, Subsystem subsystem) throws FileNotFoundException, BundleException {
+ Bundle bundle = installBundleFromFile(file, subsystem.getBundleContext());
+ assertBundleState(Bundle.INSTALLED|Bundle.RESOLVED, bundle.getSymbolicName(), subsystem);
+ return bundle;
+ }
+
+ protected Bundle installBundleFromFile(File file, BundleContext bundleContext) throws FileNotFoundException, BundleException {
+ // The following input stream is closed by the bundle context.
+ return bundleContext.installBundle(file.toURI().toString(), new FileInputStream(file));
+ }
+
+ protected Subsystem installSubsystemFromFile(Subsystem parent, String fileName) throws Exception {
+ return installSubsystemFromFile(parent, new File(fileName));
+ }
+
+ protected Subsystem installSubsystemFromFile(String fileName) throws Exception {
+ return installSubsystemFromFile(new File(fileName));
+ }
+
+ protected Subsystem installSubsystemFromFile(Subsystem parent, File file) throws Exception {
+ return installSubsystem(parent, file.toURI().toURL().toExternalForm());
+ }
+
+ protected Subsystem installSubsystemFromFile(File file) throws Exception {
+ return installSubsystem(getRootSubsystem(), file.toURI().toURL().toExternalForm());
+ }
+
+ protected Subsystem installSubsystem(String location) throws Exception {
+ return installSubsystem(getRootSubsystem(), location);
+ }
+
+ protected Subsystem installSubsystem(String location, InputStream content) throws Exception {
+ return installSubsystem(getRootSubsystem(), location, content);
+ }
+
+ protected Subsystem installSubsystem(Subsystem parent, String location) throws Exception {
+ // The following input stream is closed by Subsystem.install.
+ return installSubsystem(parent, location, new URL(location).openStream());
+ }
+
+ protected Subsystem installSubsystem(Subsystem parent, String location, InputStream content) throws Exception {
+ subsystemEvents.clear();
+ Subsystem subsystem = parent.install(location, content);
+ assertSubsystemNotNull(subsystem);
+ assertEvent(subsystem, State.INSTALLING, 5000);
+ assertEvent(subsystem, State.INSTALLED, 5000);
+ assertChild(parent, subsystem);
+ assertLocation(location, subsystem);
+ assertParent(parent, subsystem);
+ assertState(State.INSTALLED, subsystem);
+ assertLocation(location, subsystem);
+ assertId(subsystem);
+ // TODO This does not take into account nested directories.
+// assertDirectory(subsystem);
+ return subsystem;
+ }
+
+ protected void registerRepositoryService(Repository repository) {
+ serviceRegistrations.add(bundleContext.registerService(
+ Repository.class, repository, null));
+ }
+
+ protected void registerRepositoryService(Resource...resources) {
+ TestRepository.Builder builder = new TestRepository.Builder();
+ for (Resource resource : resources) {
+ builder.resource(resource);
+ }
+ registerRepositoryService(builder.build());
+ }
+
+ protected void registerRepositoryService(String...files) throws Exception {
+ Resource[] resources = new Resource[files.length];
+ int i = 0;
+ for (String file : files) {
+ resources[i++] = (Resource)createBundleRepositoryContent(file);
+ }
+ registerRepositoryService(resources);
+ }
+
+ protected void restartSubsystemsImplBundle() throws BundleException {
+ Bundle b = getSubsystemCoreBundle();
+ b.stop();
+ b.start();
+ }
+
+ protected void startBundle(Bundle bundle) throws BundleException {
+ startBundle(bundle, getRootSubsystem());
+ }
+
+ protected void startBundle(Bundle bundle, Subsystem subsystem) throws BundleException {
+ bundle.start();
+ assertBundleState(Bundle.ACTIVE, bundle.getSymbolicName(), subsystem);
+ }
+
+ protected void startSubsystem(Subsystem subsystem) throws Exception {
+ startSubsystemFromInstalled(subsystem);
+ }
+
+ protected void startSubsystemFromInstalled(Subsystem subsystem) throws InterruptedException {
+ assertState(State.INSTALLED, subsystem);
+ subsystemEvents.clear();
+ subsystem.start();
+ assertEvent(subsystem, State.RESOLVING, 5000);
+ assertEvent(subsystem, State.RESOLVED, 5000);
+ assertEvent(subsystem, State.STARTING, 5000);
+ assertEvent(subsystem, State.ACTIVE, 5000);
+ assertState(State.ACTIVE, subsystem);
+ }
+
+ protected void startSubsystemFromResolved(Subsystem subsystem) throws InterruptedException {
+ assertState(State.RESOLVED, subsystem);
+ subsystemEvents.clear();
+ subsystem.start();
+ assertEvent(subsystem, State.STARTING, 5000);
+ assertEvent(subsystem, State.ACTIVE, 5000);
+ assertState(State.ACTIVE, subsystem);
+ }
+
+ protected void stopAndUninstallSubsystemSilently(Subsystem subsystem) {
+ stopSubsystemSilently(subsystem);
+ uninstallSubsystemSilently(subsystem);
+ }
+
+ protected void stopSubsystem(Subsystem subsystem) throws Exception {
+ assertState(State.ACTIVE, subsystem);
+ subsystemEvents.clear();
+ subsystem.stop();
+ assertEvent(subsystem, State.STOPPING, 5000);
+ assertEvent(subsystem, State.RESOLVED, 5000);
+ assertState(State.RESOLVED, subsystem);
+ }
+
+ protected void stopSubsystemSilently(Subsystem subsystem) {
+ try {
+ stopSubsystem(subsystem);
+ }
+ catch (Throwable t) {
+ t.printStackTrace();
+ }
+ }
+
+ protected void uninstallSilently(Bundle bundle) {
+ if (bundle == null)
+ return;
+ try {
+ bundle.uninstall();
+ }
+ catch (Exception e) {}
+ }
+
+ protected void uninstallSubsystem(Subsystem subsystem) throws Exception {
+ assertState(EnumSet.of(State.INSTALLED, State.RESOLVED), subsystem);
+ subsystemEvents.clear();
+ Collection<Subsystem> parents = subsystem.getParents();
+ Bundle b = null;
+ if (subsystem.getType().equals(SubsystemConstants.SUBSYSTEM_TYPE_APPLICATION)
+ || subsystem.getType().equals(SubsystemConstants.SUBSYSTEM_TYPE_COMPOSITE))
+ b = getRegionContextBundle(subsystem);
+ State state = subsystem.getState();
+ subsystem.uninstall();
+ if (!EnumSet.of(State.INSTALL_FAILED, State.INSTALLED, State.INSTALLING).contains(state))
+ assertEvent(subsystem, State.INSTALLED, 5000);
+ assertEvent(subsystem, State.UNINSTALLING, 5000);
+ assertEvent(subsystem, State.UNINSTALLED, 5000);
+ assertState(State.UNINSTALLED, subsystem);
+ for (Subsystem parent : parents)
+ assertNotChild(parent, subsystem);
+// assertNotDirectory(subsystem);
+ if (b != null)
+ assertEquals("Region context bundle not uninstalled", Bundle.UNINSTALLED, b.getState());
+ }
+
+ protected void uninstallSubsystemSilently(Subsystem subsystem) {
+ if (subsystem == null)
+ return;
+ try {
+ uninstallSubsystem(subsystem);
+ }
+ catch (Throwable t) {
+ t.printStackTrace();
+ }
+ }
+
+ protected static void write(String file, ArchiveFixture.AbstractFixture fixture) throws IOException
+ {
+ write(new File(file), fixture);
+ }
+
+ protected static void write(File file, ArchiveFixture.AbstractFixture fixture) throws IOException {
+ FileOutputStream fos = new FileOutputStream(file);
+ try {
+ fixture.writeOut(fos);
+ }
+ finally {
+ fos.close();
+ }
+ }
+
+ static void createApplication(String name, String[] content) throws Exception
+ {
+ ZipFixture feature = ArchiveFixture
+ .newZip()
+ .binary("OSGI-INF/SUBSYSTEM.MF",
+ // The following input stream is closed by ArchiveFixture.copy.
+ SubsystemTest.class.getClassLoader().getResourceAsStream(
+ name + "/OSGI-INF/SUBSYSTEM.MF"));
+ for (String s : content) {
+ try {
+ feature.binary(s,
+ // The following input stream is closed by ArchiveFixture.copy.
+ SubsystemTest.class.getClassLoader().getResourceAsStream(
+ name + '/' + s));
+ }
+ catch (Exception e) {
+ // The following input stream is closed by ArchiveFixture.copy.
+ feature.binary(s, new FileInputStream(new File(s)));
+ }
+ }
+ feature.end();
+ FileOutputStream fos = new FileOutputStream(name + ".esa");
+ try {
+ feature.writeOut(fos);
+ } finally {
+ Utils.closeQuietly(fos);
+ }
+ }
+}
Added: aries/trunk/util/util-r42/src/main/java/org/apache/aries/util/filesystem/IDirectoryFinder.java
URL: http://svn.apache.org/viewvc/aries/trunk/util/util-r42/src/main/java/org/apache/aries/util/filesystem/IDirectoryFinder.java?rev=1395912&view=auto
==============================================================================
--- aries/trunk/util/util-r42/src/main/java/org/apache/aries/util/filesystem/IDirectoryFinder.java (added)
+++ aries/trunk/util/util-r42/src/main/java/org/apache/aries/util/filesystem/IDirectoryFinder.java Tue Oct 9 08:47:01 2012
@@ -0,0 +1,83 @@
+/*
+ * 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.util.filesystem;
+
+import java.net.URI;
+
+/**
+ * Provides a means by which a virtual directory can be cached and returned on
+ * demand.
+ * <p>
+ *
+ * A typical scenario for this interface is to implement it as a service which
+ * is used to hold virtual directories containing application installation
+ * artifacts, with this directory being retrieved when required during
+ * application installation (a URI identifying the virtual directory having been
+ * passed to the installation code).
+ * <p>
+ *
+ * Implementing classes should use URIs of the form
+ * <code>idirfinder://?finderID=xxx&directoryID=yyy</code> where the finder ID
+ * within the query part of the URI may be used to assist in determining the
+ * directory finder instance that can retrieve the virtual directory identified
+ * by the directory ID part (or alternatively, the URI as a whole). When
+ * implemented as a service, a directory finder should configure a corresponding
+ * service property of "finderID=xxx".
+ * <p>
+ */
+public interface IDirectoryFinder
+{
+ /**
+ * The scheme for directory finder URI ids. Using this scheme enables code
+ * receiving such a URI to infer that it is intended for use with a
+ * IDirectoryFinder instance.
+ * <p>
+ */
+ final static String IDIR_SCHEME = "idirfinder";
+
+ /**
+ * The key used in the query part of the URI whose corresponding value
+ * assists in identifying the directory finder to be used.
+ * <p>
+ */
+ final static String IDIR_FINDERID_KEY = "finderID";
+
+ /**
+ * The key used in the query part of the URI whose corresponding value
+ * identifies the directory to be returned.
+ * <p>
+ */
+ final static String IDIR_DIRECTORYID_KEY = "directoryID";
+
+ /**
+ * Get the directory that corresponds to the given identifier, and remove it
+ * from the cache, or return null if no corresponding directory is found.
+ * <p>
+ *
+ * As the found directory is removed, it is not subsequently retrievable by
+ * re-issuing the request.
+ * <p>
+ *
+ * @param id a URI that identifies the desired directory.
+ * @return IDirectory instance that corresponds to the given id URI, or null
+ * if unknown.
+ */
+ IDirectory retrieveIDirectory(URI id);
+}