Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'org.eclipse.virgo.kernel.osgi/src')
-rw-r--r--org.eclipse.virgo.kernel.osgi/src/main/java/org/eclipse/virgo/kernel/osgi/common/Version.java126
-rw-r--r--org.eclipse.virgo.kernel.osgi/src/main/java/org/eclipse/virgo/kernel/osgi/framework/BundleClassLoaderUnavailableException.java45
-rw-r--r--org.eclipse.virgo.kernel.osgi/src/main/java/org/eclipse/virgo/kernel/osgi/framework/ExtendedClassNotFoundException.java37
-rw-r--r--org.eclipse.virgo.kernel.osgi/src/main/java/org/eclipse/virgo/kernel/osgi/framework/ExtendedNoClassDefFoundError.java38
-rw-r--r--org.eclipse.virgo.kernel.osgi/src/main/java/org/eclipse/virgo/kernel/osgi/framework/ImportExpander.java45
-rw-r--r--org.eclipse.virgo.kernel.osgi/src/main/java/org/eclipse/virgo/kernel/osgi/framework/ImportMergeException.java62
-rw-r--r--org.eclipse.virgo.kernel.osgi/src/main/java/org/eclipse/virgo/kernel/osgi/framework/InstrumentableClassLoader.java58
-rw-r--r--org.eclipse.virgo.kernel.osgi/src/main/java/org/eclipse/virgo/kernel/osgi/framework/ManifestTransformer.java35
-rw-r--r--org.eclipse.virgo.kernel.osgi/src/main/java/org/eclipse/virgo/kernel/osgi/framework/OsgiConfiguration.java38
-rw-r--r--org.eclipse.virgo.kernel.osgi/src/main/java/org/eclipse/virgo/kernel/osgi/framework/OsgiFramework.java100
-rw-r--r--org.eclipse.virgo.kernel.osgi/src/main/java/org/eclipse/virgo/kernel/osgi/framework/OsgiFrameworkException.java61
-rw-r--r--org.eclipse.virgo.kernel.osgi/src/main/java/org/eclipse/virgo/kernel/osgi/framework/OsgiFrameworkLogEvents.java57
-rw-r--r--org.eclipse.virgo.kernel.osgi/src/main/java/org/eclipse/virgo/kernel/osgi/framework/OsgiFrameworkUtils.java200
-rw-r--r--org.eclipse.virgo.kernel.osgi/src/main/java/org/eclipse/virgo/kernel/osgi/framework/OsgiServiceHolder.java34
-rw-r--r--org.eclipse.virgo.kernel.osgi/src/main/java/org/eclipse/virgo/kernel/osgi/framework/PackageAdminUtil.java32
-rw-r--r--org.eclipse.virgo.kernel.osgi/src/main/java/org/eclipse/virgo/kernel/osgi/framework/UnableToSatisfyBundleDependenciesException.java77
-rw-r--r--org.eclipse.virgo.kernel.osgi/src/main/java/org/eclipse/virgo/kernel/osgi/framework/UnableToSatisfyDependenciesException.java94
-rw-r--r--org.eclipse.virgo.kernel.osgi/src/main/java/org/eclipse/virgo/kernel/osgi/framework/UnableToSatisfyLibraryDependenciesException.java40
-rw-r--r--org.eclipse.virgo.kernel.osgi/src/main/java/org/eclipse/virgo/kernel/osgi/framework/UnableToSatisfyPlanDependenciesException.java35
-rw-r--r--org.eclipse.virgo.kernel.osgi/src/main/java/org/eclipse/virgo/kernel/osgi/framework/support/AbstractOsgiFramework.java76
-rw-r--r--org.eclipse.virgo.kernel.osgi/src/main/java/org/eclipse/virgo/kernel/osgi/framework/support/ImmutableOsgiConfiguration.java53
-rw-r--r--org.eclipse.virgo.kernel.osgi/src/main/java/org/eclipse/virgo/kernel/osgi/quasi/QuasiBundle.java129
-rw-r--r--org.eclipse.virgo.kernel.osgi/src/main/java/org/eclipse/virgo/kernel/osgi/quasi/QuasiExportPackage.java53
-rw-r--r--org.eclipse.virgo.kernel.osgi/src/main/java/org/eclipse/virgo/kernel/osgi/quasi/QuasiFramework.java106
-rw-r--r--org.eclipse.virgo.kernel.osgi/src/main/java/org/eclipse/virgo/kernel/osgi/quasi/QuasiFrameworkFactory.java42
-rw-r--r--org.eclipse.virgo.kernel.osgi/src/main/java/org/eclipse/virgo/kernel/osgi/quasi/QuasiImportPackage.java64
-rw-r--r--org.eclipse.virgo.kernel.osgi/src/main/java/org/eclipse/virgo/kernel/osgi/quasi/QuasiPackageResolutionFailure.java36
-rw-r--r--org.eclipse.virgo.kernel.osgi/src/main/java/org/eclipse/virgo/kernel/osgi/quasi/QuasiPackageUsesResolutionFailure.java26
-rw-r--r--org.eclipse.virgo.kernel.osgi/src/main/java/org/eclipse/virgo/kernel/osgi/quasi/QuasiParameterised.java41
-rw-r--r--org.eclipse.virgo.kernel.osgi/src/main/java/org/eclipse/virgo/kernel/osgi/quasi/QuasiRequiredBundle.java62
-rw-r--r--org.eclipse.virgo.kernel.osgi/src/main/java/org/eclipse/virgo/kernel/osgi/quasi/QuasiResolutionFailure.java40
-rw-r--r--org.eclipse.virgo.kernel.osgi/src/main/java/org/eclipse/virgo/kernel/osgi/region/PackageImportWildcardExpander.java141
-rw-r--r--org.eclipse.virgo.kernel.osgi/src/main/java/org/eclipse/virgo/kernel/osgi/region/Region.java40
-rw-r--r--org.eclipse.virgo.kernel.osgi/src/main/java/org/eclipse/virgo/kernel/osgi/region/RegionManager.java361
-rw-r--r--org.eclipse.virgo.kernel.osgi/src/main/java/org/eclipse/virgo/kernel/osgi/region/RegionManagerParserLogger.java42
-rw-r--r--org.eclipse.virgo.kernel.osgi/src/main/java/org/eclipse/virgo/kernel/osgi/region/eventlog/RegionAwareEventLoggerServiceFactory.java55
-rw-r--r--org.eclipse.virgo.kernel.osgi/src/main/resources/EventLogMessages.properties7
-rw-r--r--org.eclipse.virgo.kernel.osgi/src/main/resources/META-INF/spring/configuration-context.xml16
-rw-r--r--org.eclipse.virgo.kernel.osgi/src/main/resources/META-INF/spring/internal-osgi-context.xml33
-rw-r--r--org.eclipse.virgo.kernel.osgi/src/main/resources/META-INF/spring/osgi-framework-context.xml18
-rw-r--r--org.eclipse.virgo.kernel.osgi/src/test/java/.gitignore0
-rw-r--r--org.eclipse.virgo.kernel.osgi/src/test/java/org/eclipse/virgo/kernel/osgi/common/VersionTests.java66
-rw-r--r--org.eclipse.virgo.kernel.osgi/src/test/java/org/eclipse/virgo/kernel/osgi/region/PackageImportWildcardExpanderTests.java76
-rw-r--r--org.eclipse.virgo.kernel.osgi/src/test/java/org/eclipse/virgo/kernel/osgi/region/RegionManagerTests.java86
-rw-r--r--org.eclipse.virgo.kernel.osgi/src/test/resources/.gitignore0
-rw-r--r--org.eclipse.virgo.kernel.osgi/src/test/resources/com/springsource/kernel/osgi/provisioning/tools/IMPORTBUNDLE.MF3
-rw-r--r--org.eclipse.virgo.kernel.osgi/src/test/resources/com/springsource/kernel/osgi/provisioning/tools/IMPORTLIBRARY.MF1
-rw-r--r--org.eclipse.virgo.kernel.osgi/src/test/resources/com/springsource/kernel/osgi/provisioning/tools/IMPORTPACKAGE.MF1
-rw-r--r--org.eclipse.virgo.kernel.osgi/src/test/resources/com/springsource/kernel/osgi/provisioning/tools/IMPORTSYSTEMPACKAGES.MF4
-rw-r--r--org.eclipse.virgo.kernel.osgi/src/test/resources/com/springsource/kernel/osgi/provisioning/tools/IMPORTSYSTEMPACKAGESJAVA6.MF1
-rw-r--r--org.eclipse.virgo.kernel.osgi/src/test/resources/com/springsource/kernel/osgi/provisioning/tools/REQUIREBUNDLE.MF2
-rw-r--r--org.eclipse.virgo.kernel.osgi/src/test/resources/com/springsource/kernel/osgi/provisioning/tools/SATISFIABLEANDUNSATISFIABLE.MF2
-rw-r--r--org.eclipse.virgo.kernel.osgi/src/test/resources/com/springsource/kernel/osgi/provisioning/tools/UNSATISFIABLEIMPORTBUNDLE.MF1
-rw-r--r--org.eclipse.virgo.kernel.osgi/src/test/resources/com/springsource/kernel/osgi/provisioning/tools/UNSATISFIABLEIMPORTLIBRARY.MF1
-rw-r--r--org.eclipse.virgo.kernel.osgi/src/test/resources/com/springsource/kernel/osgi/provisioning/tools/UNSATISFIABLEIMPORTPACKAGE.MF1
-rw-r--r--org.eclipse.virgo.kernel.osgi/src/test/resources/com/springsource/kernel/osgi/provisioning/tools/UNSATISFIABLEREQUIREBUNDLE.MF1
-rw-r--r--org.eclipse.virgo.kernel.osgi/src/test/resources/com/springsource/kernel/osgi/provisioning/tools/org.springframework_spring_2.5.3.libd5
57 files changed, 2906 insertions, 0 deletions
diff --git a/org.eclipse.virgo.kernel.osgi/src/main/java/org/eclipse/virgo/kernel/osgi/common/Version.java b/org.eclipse.virgo.kernel.osgi/src/main/java/org/eclipse/virgo/kernel/osgi/common/Version.java
new file mode 100644
index 00000000..300aac9e
--- /dev/null
+++ b/org.eclipse.virgo.kernel.osgi/src/main/java/org/eclipse/virgo/kernel/osgi/common/Version.java
@@ -0,0 +1,126 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2010 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.virgo.kernel.osgi.common;
+
+import java.util.Arrays;
+import java.util.List;
+
+import org.eclipse.virgo.util.math.Range;
+
+/**
+ * This class is thread safe.
+ *
+ */
+public final class Version implements Comparable<Version> {
+
+ private static final int DEFAULT_VERSION_COMPONENT = 0;
+
+ private static final String MINIMUM_VERSION_STRING = "0";
+
+ public static final Version MINIMUM_VERSION = new Version(MINIMUM_VERSION_STRING);
+
+ public static final Version MAXIMUM_VERSION = new Version(Arrays.asList(Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE));
+
+ private final org.osgi.framework.Version version;
+
+ public Version(String v) {
+ this.version = org.osgi.framework.Version.parseVersion(v);
+ }
+
+ public Version(org.osgi.framework.Version version) {
+ this.version = version;
+ }
+
+ public Version(List<Integer> comp) {
+ if (comp.size() > 3) {
+ throw new NumberFormatException("Versions may have at most three numeric components");
+ }
+ int major = comp.size() >= 1 ? comp.get(0) : DEFAULT_VERSION_COMPONENT;
+ int minor = comp.size() >= 2 ? comp.get(1) : DEFAULT_VERSION_COMPONENT;
+ int micro = comp.size() == 3 ? comp.get(2) : DEFAULT_VERSION_COMPONENT;
+ this.version = new org.osgi.framework.Version(major, minor, micro);
+ }
+
+ /**
+ * @see Integer#compareTo
+ *
+ * @param v2
+ * @return -1 if this < v2, 0 if this equals v2, 1 if this > v2
+ */
+ public int compareTo(Version v2) {
+ return this.version.compareTo(v2.version);
+ }
+
+ /**
+ * Convert a version range string following OSGi conventions into a Range<Version>.
+ *
+ * OSGi conventions are that ranges are specified using standard mathematical interval notation except for the
+ * special case of a version, v, on its own which denotes the range [v, MAXIMUM_VERSION).
+ *
+ * @param stringRange a version range string
+ * @return the Range<String> corresponding to the given version range string
+ */
+ public static Range<Version> stringToVersionRange(String stringRange) {
+ if (stringRange == null) {
+ return stringToVersionRange(MINIMUM_VERSION_STRING);
+ }
+ boolean floorInc = stringRange.startsWith(Range.FLOOR_INCLUSIVE_DELIMITER);
+ boolean floorExc = stringRange.startsWith(Range.FLOOR_EXCLUSIVE_DELIMITER);
+ boolean ceilingInc = stringRange.endsWith(Range.CEILING_INCLUSIVE_DELIMITER);
+ boolean ceilingExc = stringRange.endsWith(Range.CEILING_EXCLUSIVE_DELIMITER);
+ int separatorIndex = stringRange.indexOf(Range.SEPARATOR);
+ boolean delimitedRange = (floorInc || floorExc) && (ceilingInc || ceilingExc) && separatorIndex != -1;
+
+ if (delimitedRange) {
+ String floor = stringRange.substring(1, separatorIndex);
+ String ceiling = stringRange.substring(separatorIndex + 1, stringRange.length() - 1);
+ return new Range<Version>(new Version(floor), floorInc, new Version(ceiling), ceilingInc);
+ } else {
+ return new Range<Version>(new Version(stringRange), true, MAXIMUM_VERSION, false);
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override public int hashCode() {
+ return this.version.hashCode();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj == null) {
+ return false;
+ }
+ if (getClass() != obj.getClass()) {
+ return false;
+ }
+ final Version other = (Version) obj;
+ return this.version.equals(other.version);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override public String toString() {
+ String result = this.version.toString();
+ while (result.endsWith(".0")) {
+ result = result.substring(0, result.length() - 2);
+ }
+ return result;
+ }
+}
diff --git a/org.eclipse.virgo.kernel.osgi/src/main/java/org/eclipse/virgo/kernel/osgi/framework/BundleClassLoaderUnavailableException.java b/org.eclipse.virgo.kernel.osgi/src/main/java/org/eclipse/virgo/kernel/osgi/framework/BundleClassLoaderUnavailableException.java
new file mode 100644
index 00000000..26811e14
--- /dev/null
+++ b/org.eclipse.virgo.kernel.osgi/src/main/java/org/eclipse/virgo/kernel/osgi/framework/BundleClassLoaderUnavailableException.java
@@ -0,0 +1,45 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2010 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.virgo.kernel.osgi.framework;
+
+import org.osgi.framework.Bundle;
+
+/**
+ * Exception signalling that the <code>ClassLoader</code> for a {@link Bundle} is not available.
+ * <p />
+ *
+ * <strong>Concurrent Semantics</strong><br />
+ *
+ * Threadsafe.
+ *
+ */
+public final class BundleClassLoaderUnavailableException extends RuntimeException {
+
+ private static final long serialVersionUID = 4014635817682252026L;
+
+ public BundleClassLoaderUnavailableException() {
+ super();
+ }
+
+ public BundleClassLoaderUnavailableException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ public BundleClassLoaderUnavailableException(String message) {
+ super(message);
+ }
+
+ public BundleClassLoaderUnavailableException(Throwable cause) {
+ super(cause);
+ }
+
+}
diff --git a/org.eclipse.virgo.kernel.osgi/src/main/java/org/eclipse/virgo/kernel/osgi/framework/ExtendedClassNotFoundException.java b/org.eclipse.virgo.kernel.osgi/src/main/java/org/eclipse/virgo/kernel/osgi/framework/ExtendedClassNotFoundException.java
new file mode 100644
index 00000000..91118903
--- /dev/null
+++ b/org.eclipse.virgo.kernel.osgi/src/main/java/org/eclipse/virgo/kernel/osgi/framework/ExtendedClassNotFoundException.java
@@ -0,0 +1,37 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2010 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.virgo.kernel.osgi.framework;
+
+/**
+ * An extension to {@link ClassNotFoundException} that provides access to the ClassLoader that
+ * attempted the class load.
+ * <p />
+ *
+ * <strong>Concurrent Semantics</strong><br />
+ * <strong>Thread-safe</strong>
+ *
+ */
+public class ExtendedClassNotFoundException extends ClassNotFoundException {
+
+ private static final long serialVersionUID = 6045566593339869456L;
+
+ private final ClassLoader classLoader;
+
+ public ExtendedClassNotFoundException(ClassLoader classLoader, ClassNotFoundException cause) {
+ super(cause.getMessage() + " in " + classLoader, cause);
+ this.classLoader = classLoader;
+ }
+
+ public ClassLoader getClassLoader() {
+ return this.classLoader;
+ }
+}
diff --git a/org.eclipse.virgo.kernel.osgi/src/main/java/org/eclipse/virgo/kernel/osgi/framework/ExtendedNoClassDefFoundError.java b/org.eclipse.virgo.kernel.osgi/src/main/java/org/eclipse/virgo/kernel/osgi/framework/ExtendedNoClassDefFoundError.java
new file mode 100644
index 00000000..1620b3de
--- /dev/null
+++ b/org.eclipse.virgo.kernel.osgi/src/main/java/org/eclipse/virgo/kernel/osgi/framework/ExtendedNoClassDefFoundError.java
@@ -0,0 +1,38 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2010 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.virgo.kernel.osgi.framework;
+
+/**
+ * An extension to {@link NoClassDefFoundError} that provides access to the ClassLoader that attempted
+ * the class load.
+ * <p />
+ *
+ * <strong>Concurrent Semantics</strong><br />
+ * <strong>Thread-safe</strong>
+ *
+ */
+public class ExtendedNoClassDefFoundError extends NoClassDefFoundError {
+
+ private static final long serialVersionUID = 4573722090207901849L;
+
+ private final ClassLoader classLoader;
+
+ public ExtendedNoClassDefFoundError(ClassLoader classLoader, NoClassDefFoundError cause) {
+ super(cause.getMessage() + " in " + classLoader);
+ this.classLoader = classLoader;
+ initCause(cause);
+ }
+
+ public ClassLoader getClassLoader() {
+ return this.classLoader;
+ }
+}
diff --git a/org.eclipse.virgo.kernel.osgi/src/main/java/org/eclipse/virgo/kernel/osgi/framework/ImportExpander.java b/org.eclipse.virgo.kernel.osgi/src/main/java/org/eclipse/virgo/kernel/osgi/framework/ImportExpander.java
new file mode 100644
index 00000000..7ab10333
--- /dev/null
+++ b/org.eclipse.virgo.kernel.osgi/src/main/java/org/eclipse/virgo/kernel/osgi/framework/ImportExpander.java
@@ -0,0 +1,45 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2010 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.virgo.kernel.osgi.framework;
+
+import java.util.List;
+
+import org.eclipse.virgo.util.osgi.manifest.BundleManifest;
+
+/**
+ * {@link ImportExpander} is an interface for expanding library and bundle imports into package imports and propagating
+ * promoted imports across a collection of bundles. <p />
+ *
+ * <strong>Concurrent Semantics</strong><br />
+ *
+ * Implementations of this interface should be thread safe.
+ *
+ */
+public interface ImportExpander {
+
+ public interface ImportPromotionVector {
+ }
+
+ /**
+ * Modifies the supplied {@link BundleManifest bundle manifests} by replacing all of the <code>Import-Library</code>
+ * and <code>Import-Bundle</code> header entries with the equivalent <code>Import-Package</code> header entries and
+ * propagating promoted imports across the supplied bundle manifests.
+ *
+ * @param bundleManifests the manifests to perform <code>Import-Library</code> and <code>Import-Bundle</code>
+ * expansion upon.
+ * @return vector of imports promoted
+ * @throws UnableToSatisfyDependenciesException if a manifest's dependencies cannot be satisfied
+ * @throws ImportMergeException if there was a clash between some of the imports being merged
+ */
+ ImportPromotionVector expandImports(List<BundleManifest> bundleManifests) throws UnableToSatisfyDependenciesException, ImportMergeException;
+
+}
diff --git a/org.eclipse.virgo.kernel.osgi/src/main/java/org/eclipse/virgo/kernel/osgi/framework/ImportMergeException.java b/org.eclipse.virgo.kernel.osgi/src/main/java/org/eclipse/virgo/kernel/osgi/framework/ImportMergeException.java
new file mode 100644
index 00000000..fa037700
--- /dev/null
+++ b/org.eclipse.virgo.kernel.osgi/src/main/java/org/eclipse/virgo/kernel/osgi/framework/ImportMergeException.java
@@ -0,0 +1,62 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2010 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.virgo.kernel.osgi.framework;
+
+
+/**
+ * {@link ImportMergeException} is thrown when conflicting imports are detected.
+ * <p />
+ *
+ * <strong>Concurrent Semantics</strong><br />
+ *
+ * This class is immutable and therefore thread safe.
+ *
+ */
+public class ImportMergeException extends OsgiFrameworkException {
+
+ private static final long serialVersionUID = 56985682345987L;
+
+ private final String conflictingPackageName;
+
+ private final String sources;
+
+ /**
+ * Creates a new <code>ImportMergeException</code> with the supplied error message.
+ * @param conflictingPackageName of package where conflicting merges meet
+ * @param sources conflicting imports
+ * @param message The reason (String) for merge failure
+ */
+ public ImportMergeException(String conflictingPackageName, String sources, String message) {
+ super("cannot merge imports of package '" + conflictingPackageName + "' from sources '" + sources + "' because of " + message);
+ this.conflictingPackageName = conflictingPackageName;
+ this.sources = sources;
+ }
+
+ /**
+ * Get the name of the package that failed to merge.
+ *
+ * @return the name of the package that failed to merge
+ */
+ public final String getConflictingPackageName() {
+ return this.conflictingPackageName;
+ }
+
+ /**
+ * Get the sources of the package that failed to merge.
+ *
+ * @return the sources of the package that failed to merge
+ */
+ public final String getSources() {
+ return this.sources;
+ }
+
+}
diff --git a/org.eclipse.virgo.kernel.osgi/src/main/java/org/eclipse/virgo/kernel/osgi/framework/InstrumentableClassLoader.java b/org.eclipse.virgo.kernel.osgi/src/main/java/org/eclipse/virgo/kernel/osgi/framework/InstrumentableClassLoader.java
new file mode 100644
index 00000000..49001c1c
--- /dev/null
+++ b/org.eclipse.virgo.kernel.osgi/src/main/java/org/eclipse/virgo/kernel/osgi/framework/InstrumentableClassLoader.java
@@ -0,0 +1,58 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2010 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.virgo.kernel.osgi.framework;
+
+import java.lang.instrument.ClassFileTransformer;
+
+/**
+ * Provides an interface onto <code>ClassLoaders</code> that support the use of {@link ClassFileTransformer
+ * ClassFileTransformers} for load-time weaving.<p/>
+ *
+ * <strong>Concurrent Semantics</strong><br />
+ *
+ * Implementations <strong>must</strong> be threadsafe.
+ *
+ */
+public interface InstrumentableClassLoader {
+
+ /**
+ * Adds the supplied {@link ClassFileTransformer} to the {@link ClassLoader}. All subsequent class loads will pass
+ * through the newly added <code>ClassFileTransformer</code>.
+ *
+ * @param transformer the <code>ClassFileTransformer</code>.
+ */
+ void addClassFileTransformer(ClassFileTransformer transformer);
+
+ /**
+ * Creates a throw away {@link ClassLoader} that can be used to explore and introspect on types that will be loaded
+ * by this <code>ClassLoader</code>.
+ *
+ * @return the throw away <code>ClassLoader</code>.
+ */
+ ClassLoader createThrowAway();
+
+ /**
+ * Queries whether this <code>ClassLoader</code> has been {@link #addClassFileTransformer(ClassFileTransformer)
+ * instrumented}.
+ *
+ * @return <code>true</code> if instrumented, otherwise <code>false</code>.
+ */
+ boolean isInstrumented();
+
+ /**
+ * Gets the number of {@link ClassFileTransformer ClassFileTransformers} that have been added to this
+ * <code>ClassLoader</code>.
+ *
+ * @return the number of <code>ClassFileTransformers</code>.
+ */
+ int getClassFileTransformerCount();
+}
diff --git a/org.eclipse.virgo.kernel.osgi/src/main/java/org/eclipse/virgo/kernel/osgi/framework/ManifestTransformer.java b/org.eclipse.virgo.kernel.osgi/src/main/java/org/eclipse/virgo/kernel/osgi/framework/ManifestTransformer.java
new file mode 100644
index 00000000..e20c4dbb
--- /dev/null
+++ b/org.eclipse.virgo.kernel.osgi/src/main/java/org/eclipse/virgo/kernel/osgi/framework/ManifestTransformer.java
@@ -0,0 +1,35 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2010 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.virgo.kernel.osgi.framework;
+
+import org.osgi.framework.Bundle;
+
+import org.eclipse.virgo.util.osgi.manifest.BundleManifest;
+
+/**
+ * A ManifestTransformer can be used to return a transformed {@link BundleManifest} for a {@link Bundle}. <p />
+ *
+ * <strong>Concurrent Semantics</strong><br />
+ *
+ * Implementations <strong>must</strong> be thread-safe.
+ *
+ */
+public interface ManifestTransformer {
+
+ /**
+ * Transform the supplied manifest, e.g. by expanding any Import-Library and Import-Bundle headers.
+ *
+ * @param bundleManifest the manifest to transform
+ * @return The transformed manifest, or the original manifest if no transformation is required.
+ */
+ public BundleManifest transform(BundleManifest bundleManifest);
+}
diff --git a/org.eclipse.virgo.kernel.osgi/src/main/java/org/eclipse/virgo/kernel/osgi/framework/OsgiConfiguration.java b/org.eclipse.virgo.kernel.osgi/src/main/java/org/eclipse/virgo/kernel/osgi/framework/OsgiConfiguration.java
new file mode 100644
index 00000000..ad7e5284
--- /dev/null
+++ b/org.eclipse.virgo.kernel.osgi/src/main/java/org/eclipse/virgo/kernel/osgi/framework/OsgiConfiguration.java
@@ -0,0 +1,38 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2010 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.virgo.kernel.osgi.framework;
+
+/**
+ * Configuration data for an {@link OsgiFramework}.
+ * <p/>
+ *
+ * <strong>Concurrent Semantics</strong><br/>
+ *
+ * Implementations <strong>must</strong> be threadsafe.
+ *
+ */
+public interface OsgiConfiguration {
+
+ /**
+ * Whether or not the console is enabled
+ *
+ * @return <code>true</code> if the console is enabled, otherwise <code>false</code>.
+ */
+ boolean isConsoleEnabled();
+
+ /**
+ * Returns the port upon which the console should listen
+ *
+ * @return the console's port
+ */
+ int getConsolePort();
+}
diff --git a/org.eclipse.virgo.kernel.osgi/src/main/java/org/eclipse/virgo/kernel/osgi/framework/OsgiFramework.java b/org.eclipse.virgo.kernel.osgi/src/main/java/org/eclipse/virgo/kernel/osgi/framework/OsgiFramework.java
new file mode 100644
index 00000000..fd7aea0f
--- /dev/null
+++ b/org.eclipse.virgo.kernel.osgi/src/main/java/org/eclipse/virgo/kernel/osgi/framework/OsgiFramework.java
@@ -0,0 +1,100 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2010 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.virgo.kernel.osgi.framework;
+
+import java.util.jar.Manifest;
+
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.BundleException;
+import org.osgi.service.packageadmin.PackageAdmin;
+
+/**
+ * <code>OsgiFramework</code> defines a basic abstraction for interacting with various OSGi implementations in a
+ * server-independent manner. <p/>
+ *
+ * Implementations <strong>must</strong> make themselves available in the OSGi service registry under the
+ * <code>OsgiFramework</code> class names.
+ *
+ */
+public interface OsgiFramework {
+
+ /**
+ * Name of the {@link Manifest} entry defining the scope of a bundle.
+ */
+ public static String HEADER_MODULE_SCOPE = "Module-Scope";
+
+ /**
+ * Gets the {@link BundleContext} of the system {@link Bundle}.
+ *
+ * @return the system <code>BundleContext</code>.
+ */
+ BundleContext getBundleContext();
+
+ /**
+ * Gets the {@link ClassLoader} for the supplied {@link Bundle}.
+ *
+ * @param bundle the <code>Bundle</code>.
+ * @return the <code>ClassLoader</code>.
+ */
+ ClassLoader getBundleClassLoader(Bundle bundle);
+
+ /**
+ * Returns true if the class with the given name will be loaded via boot delegation by the underlying OSGi framework
+ *
+ * @param className The class name
+ * @return Whether the underlying framework considers the class to be boot delegated.
+ */
+ boolean isBootDelegated(String className);
+
+ /**
+ * Returns all of the supplied bundle's direct dependencies. A bundle's direct dependencies are the bundles to which
+ * its package imports have been wired. Equivalent to calling <code>getDirectDependencies(bundle, false)</code>.
+ *
+ * @param bundle The bundle for which the direct dependencies are required
+ * @return the supplied bundle's direct dependencies
+ */
+ Bundle[] getDirectDependencies(Bundle bundle);
+
+ /**
+ * Returns all of the supplied bundle's direct dependencies, optionally including the fragments, if any, of each
+ * direct dependency in the returned array. A bundle's direct dependencies are the bundles to which its package
+ * imports have been wired.
+ *
+ * @param bundle The bundle for which the direct dependencies are required
+ * @param includeFragments <code>true</code> if fragments of bundles to which package imports have been wired
+ * should be included in the returned array
+ * @return the supplied bundle's direct dependencies
+ */
+ Bundle[] getDirectDependencies(Bundle bundle, boolean includeFragments);
+
+ /**
+ * Refreshes the supplied {@link Bundle}. Reloads all contents, and refreshes the packages.
+ *
+ * @param bundle the <code>Bundle</code> to refresh.
+ * @throws BundleException if there is an error during refresh.
+ * @see PackageAdmin#refreshPackages(Bundle[])
+ */
+ void refresh(Bundle bundle) throws BundleException;
+
+ /**
+ * Updates the supplied <code>Bundle</code> using the supplied <code>ManifestTransformer</code>
+ * to transformer the <code>Bundle</code>'s manifest as it is updated.
+ *
+ * @param bundle the bundle to update
+ * @param manifestTransformer the manifest transformer to apply to the bundle's manifest
+ *
+ * @throws BundleException if the bundle fails to update
+ */
+ void update(Bundle bundle, ManifestTransformer manifestTransformer) throws BundleException;
+
+}
diff --git a/org.eclipse.virgo.kernel.osgi/src/main/java/org/eclipse/virgo/kernel/osgi/framework/OsgiFrameworkException.java b/org.eclipse.virgo.kernel.osgi/src/main/java/org/eclipse/virgo/kernel/osgi/framework/OsgiFrameworkException.java
new file mode 100644
index 00000000..9c0cb2b3
--- /dev/null
+++ b/org.eclipse.virgo.kernel.osgi/src/main/java/org/eclipse/virgo/kernel/osgi/framework/OsgiFrameworkException.java
@@ -0,0 +1,61 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2010 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.virgo.kernel.osgi.framework;
+
+/**
+ * Signals a generic error in the OSGi Framework subsystem.<p/>
+ *
+ * <strong>Concurrent Semantics</strong><br />
+ *
+ * Threadsafe.
+ *
+ */
+public class OsgiFrameworkException extends RuntimeException {
+
+ private static final long serialVersionUID = -2615790102302563284L;
+
+ /**
+ * Creates a new <code>OsgiFrameworkException</code>.
+ */
+ public OsgiFrameworkException() {
+ super();
+ }
+
+ /**
+ * Creates a new <code>OsgiFrameworkException</code>.
+ *
+ * @param message the error message.
+ * @param cause the root cause.
+ */
+ public OsgiFrameworkException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ /**
+ * Creates a new <code>OsgiFrameworkException</code>.
+ *
+ * @param message the error message.
+ */
+ public OsgiFrameworkException(String message) {
+ super(message);
+ }
+
+ /**
+ * Creates a new <code>OsgiFrameworkException</code>.
+ *
+ * @param cause the root cause.
+ */
+ public OsgiFrameworkException(Throwable cause) {
+ super(cause);
+ }
+
+}
diff --git a/org.eclipse.virgo.kernel.osgi/src/main/java/org/eclipse/virgo/kernel/osgi/framework/OsgiFrameworkLogEvents.java b/org.eclipse.virgo.kernel.osgi/src/main/java/org/eclipse/virgo/kernel/osgi/framework/OsgiFrameworkLogEvents.java
new file mode 100644
index 00000000..12ebc0e1
--- /dev/null
+++ b/org.eclipse.virgo.kernel.osgi/src/main/java/org/eclipse/virgo/kernel/osgi/framework/OsgiFrameworkLogEvents.java
@@ -0,0 +1,57 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2010 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.virgo.kernel.osgi.framework;
+
+import org.eclipse.virgo.kernel.serviceability.LogEventDelegate;
+import org.eclipse.virgo.medic.eventlog.Level;
+import org.eclipse.virgo.medic.eventlog.LogEvent;
+
+/**
+ * {@link LogEvent} for the OSGi provisioning bundle.
+ * <p/>
+ *
+ * <strong>Concurrent Semantics</strong><br />
+ *
+ * Threadsafe.
+ *
+ */
+public enum OsgiFrameworkLogEvents implements LogEvent {
+
+ REGION_IMPORTS_PARSE_FAILED(1, Level.ERROR), //
+ REGION_IMPORT_NO_MATCH(2, Level.WARNING), //
+ // 3 has been moved to the user region bundle and is unused here.
+ // 4 has been moved to the user region bundle and is unused here.
+ OSGI_CONSOLE_PORT(100, Level.INFO), //
+ OSGI_CONSOLE_PORT_IN_USE(101, Level.ERROR);
+
+ private static final String PREFIX = "OF";
+
+ private final LogEventDelegate delegate;
+
+ private OsgiFrameworkLogEvents(int code, Level level) {
+ this.delegate = new LogEventDelegate(PREFIX, code, level);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public String getEventCode() {
+ return this.delegate.getEventCode();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public Level getLevel() {
+ return this.delegate.getLevel();
+ }
+}
diff --git a/org.eclipse.virgo.kernel.osgi/src/main/java/org/eclipse/virgo/kernel/osgi/framework/OsgiFrameworkUtils.java b/org.eclipse.virgo.kernel.osgi/src/main/java/org/eclipse/virgo/kernel/osgi/framework/OsgiFrameworkUtils.java
new file mode 100644
index 00000000..c8e3a76a
--- /dev/null
+++ b/org.eclipse.virgo.kernel.osgi/src/main/java/org/eclipse/virgo/kernel/osgi/framework/OsgiFrameworkUtils.java
@@ -0,0 +1,200 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2010 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.virgo.kernel.osgi.framework;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.framework.ServiceReference;
+
+/**
+ * Utility methods for working the OSGi framework and {@link Bundle Bundles}.
+ * <p/>
+ *
+ * <strong>Concurrent Semantics</strong><br />
+ *
+ * Threadsafe.
+ *
+ */
+public final class OsgiFrameworkUtils {
+
+ private static final String HEADER_MODULE_SCOPE = "Module-Scope";
+
+ /**
+ * Gets the scope for the supplied {@link Bundle}.
+ *
+ * @param bundle the <code>Bundle</code>.
+ * @return the scope, or <code>null</code> if no scope is specified.
+ */
+ public static String getScopeName(Bundle bundle) {
+ return (String) bundle.getHeaders().get(HEADER_MODULE_SCOPE);
+ }
+
+ /**
+ * Queries whether the supplied {@link Bundle} is scoped.
+ *
+ * @param bundle the <code>Bundle</code>.
+ * @return <code>true</code> if the <code>Bundle</code> is scoped, otherwise <code>false</code>.
+ */
+ public static boolean isScoped(Bundle bundle) {
+ String scope = getScopeName(bundle);
+ return scope != null && scope.length() > 0;
+ }
+
+ /**
+ * Queries whether both supplied {@link Bundle Bundles} are in the same scope.
+ *
+ * @param a the first <code>Bundle</code>.
+ * @param b the second <code>Bundle</code>.
+ * @return <code>true</code> if both <code>Bundles</code> are in the same scope.
+ */
+ public static boolean sameScope(Bundle a, Bundle b) {
+ String scopeA = getScopeName(a);
+ if (scopeA == null || scopeA.length() == 0) {
+ return false;
+ } else {
+ return scopeA.equals(getScopeName(b));
+ }
+ }
+
+ /**
+ * Indicates whether or not the supplied {@link Bundle} is active.
+ *
+ * @param bundle The bundle to query
+ * @return <code>true</code> if the supplied bundle is active, otherwise <code>false</code>.
+ * @see Bundle#getState()
+ * @see Bundle#ACTIVE
+ */
+ public static boolean isBundleActive(Bundle bundle) {
+ return bundle.getState() == Bundle.ACTIVE;
+ }
+
+ @SuppressWarnings("unchecked")
+ public static <T> OsgiServiceHolder<T> getService(BundleContext bundleContext, Class<T> clazz) {
+ final ServiceReference reference = bundleContext.getServiceReference(clazz.getName());
+ if (reference != null) {
+ final T service = (T) bundleContext.getService(reference);
+ return new StandardOsgiServiceHolder<T>(service, reference);
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * Returns an ordered list of {@link OsgiServiceHolder OsgiServiceHolders}, one for each service in the service
+ * registry which was published under the supplied <code>serviceType</code>. The service lookup is performed using
+ * the supplied <code>bundleContext</code>.
+ * <p/>
+ * The ordering of the <code>OsgiServiceHolder</code>s is determined by the
+ * {@link ServiceReference#compareTo(Object) ordering} of the encapsulated {@link ServiceReference
+ * ServiceReferences}.
+ * <p/>
+ * @param bundleContext in which to lookup services
+ * @param serviceType of service to look for
+ * @param <T> of service
+ * @return list of {@link OsgiServiceHolder}s
+ */
+ @SuppressWarnings("unchecked")
+ public static <T> List<OsgiServiceHolder<T>> getServices(BundleContext bundleContext, Class<T> serviceType) {
+ List<OsgiServiceHolder<T>> serviceHolders = new ArrayList<OsgiServiceHolder<T>>();
+ try {
+ ServiceReference[] serviceReferences = bundleContext.getServiceReferences(serviceType.getName(), null);
+ if (serviceReferences != null) {
+ for (ServiceReference serviceReference : serviceReferences) {
+ T service = (T) bundleContext.getService(serviceReference);
+ if (service != null) {
+ serviceHolders.add(new StandardOsgiServiceHolder<T>(service, serviceReference));
+ }
+ }
+ Collections.sort(serviceHolders);
+ }
+ } catch (InvalidSyntaxException ise) {
+ throw new OsgiFrameworkException(ise);
+ }
+
+ return serviceHolders;
+ }
+
+ private static class StandardOsgiServiceHolder<T> implements OsgiServiceHolder<T>, Comparable<OsgiServiceHolder<?>> {
+
+ private final T service;
+
+ private final ServiceReference serviceReference;
+
+ private StandardOsgiServiceHolder(T service, ServiceReference serviceReference) {
+ this.service = service;
+ this.serviceReference = serviceReference;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public T getService() {
+ return this.service;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public ServiceReference getServiceReference() {
+ return this.serviceReference;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public int compareTo(OsgiServiceHolder<?> o) {
+ return this.serviceReference.compareTo(o.getServiceReference());
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + (this.serviceReference == null ? 0 : this.serviceReference.hashCode());
+ return result;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj == null) {
+ return false;
+ }
+ if (getClass() != obj.getClass()) {
+ return false;
+ }
+ StandardOsgiServiceHolder<?> other = (StandardOsgiServiceHolder<?>) obj;
+ if (this.serviceReference == null) {
+ if (other.serviceReference != null) {
+ return false;
+ }
+ } else if (!this.serviceReference.equals(other.serviceReference)) {
+ return false;
+ }
+ return true;
+ }
+
+ }
+}
diff --git a/org.eclipse.virgo.kernel.osgi/src/main/java/org/eclipse/virgo/kernel/osgi/framework/OsgiServiceHolder.java b/org.eclipse.virgo.kernel.osgi/src/main/java/org/eclipse/virgo/kernel/osgi/framework/OsgiServiceHolder.java
new file mode 100644
index 00000000..7c7d8c27
--- /dev/null
+++ b/org.eclipse.virgo.kernel.osgi/src/main/java/org/eclipse/virgo/kernel/osgi/framework/OsgiServiceHolder.java
@@ -0,0 +1,34 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2010 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.virgo.kernel.osgi.framework;
+
+import org.osgi.framework.ServiceReference;
+
+/**
+ * An <code>OsgiServiceHolder</code> holds a service retrieved from the OSGi service registry and a
+ * <code>ServiceReference</code> for the held service.
+ * <p />
+ * An <code>OsgiServiceHolder</code> is {@link Comparable} and uses the encapsulated {@link ServiceReference}. to
+ * determine its ordering.
+ *
+ * <strong>Concurrent Semantics</strong><br />
+ *
+ * Implementations must be thread-safe.
+ *
+ * @param <T> Type of service to hold
+ */
+public interface OsgiServiceHolder<T> extends Comparable<OsgiServiceHolder<?>> {
+
+ T getService();
+
+ ServiceReference getServiceReference();
+}
diff --git a/org.eclipse.virgo.kernel.osgi/src/main/java/org/eclipse/virgo/kernel/osgi/framework/PackageAdminUtil.java b/org.eclipse.virgo.kernel.osgi/src/main/java/org/eclipse/virgo/kernel/osgi/framework/PackageAdminUtil.java
new file mode 100644
index 00000000..8f550502
--- /dev/null
+++ b/org.eclipse.virgo.kernel.osgi/src/main/java/org/eclipse/virgo/kernel/osgi/framework/PackageAdminUtil.java
@@ -0,0 +1,32 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2010 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.virgo.kernel.osgi.framework;
+
+import org.osgi.framework.Bundle;
+
+/**
+ * {@link PackageAdminUtil} provides utilities relating to {@link org.osgi.service.packageadmin.PackageAdmin PackageAdmin}.
+ * <p />
+ *
+ * <strong>Concurrent Semantics</strong><br />
+ *
+ * Implementations of this class must be thread safe.
+ *
+ */
+public interface PackageAdminUtil {
+ /**
+ * Synchronously drives refresh packages for the given bundles.
+ *
+ * @param bundles The bundles to refresh.
+ */
+ void synchronouslyRefreshPackages(Bundle[] bundles);
+}
diff --git a/org.eclipse.virgo.kernel.osgi/src/main/java/org/eclipse/virgo/kernel/osgi/framework/UnableToSatisfyBundleDependenciesException.java b/org.eclipse.virgo.kernel.osgi/src/main/java/org/eclipse/virgo/kernel/osgi/framework/UnableToSatisfyBundleDependenciesException.java
new file mode 100644
index 00000000..a28aa63c
--- /dev/null
+++ b/org.eclipse.virgo.kernel.osgi/src/main/java/org/eclipse/virgo/kernel/osgi/framework/UnableToSatisfyBundleDependenciesException.java
@@ -0,0 +1,77 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2010 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.virgo.kernel.osgi.framework;
+
+import org.eclipse.osgi.service.resolver.ResolverError;
+import org.eclipse.osgi.service.resolver.State;
+import org.osgi.framework.Version;
+
+/**
+ * Signals an error resolving the dependencies of a bundle during installation.<p/>
+ *
+ * <strong>Concurrent Semantics</strong><br />
+ *
+ * Threadsafe.
+ *
+ */
+public class UnableToSatisfyBundleDependenciesException extends UnableToSatisfyDependenciesException {
+
+ private static final long serialVersionUID = -4291846255969729124L;
+
+ private static final String BUNDLE_ENTITY = "bundle";
+
+ private final State state;
+
+ private final ResolverError[] resolverErrors;
+
+ /**
+ * Creates a new <code>UnableToSatisfyBundleDependenciesException</code>.
+ *
+ * @param symbolicName the symbolic name of the bundle.
+ * @param version the bundle version.
+ * @param failureDescription a description of the failure.
+ */
+ public UnableToSatisfyBundleDependenciesException(String symbolicName, Version version, String failureDescription) {
+ super(BUNDLE_ENTITY, symbolicName, version, failureDescription);
+ this.state = null;
+ this.resolverErrors = null;
+ }
+
+ /**
+ * Creates a new <code>UnableToSatisfyBundleDependenciesException</code>.
+ *
+ * @param symbolicName the symbolic name of the bundle.
+ * @param version the bundle version.
+ * @param failureDescription a description of the failure.
+ * @param state of bundle
+ * @param resolverErrors a possibly empty array of {@linkplain ResolverError}s.
+ */
+ public UnableToSatisfyBundleDependenciesException(String symbolicName, Version version, String failureDescription, State state, ResolverError[] resolverErrors) {
+ super(BUNDLE_ENTITY, symbolicName, version, failureDescription);
+ this.state = state;
+ this.resolverErrors = resolverErrors.clone();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public final State getState() {
+ return this.state;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public final ResolverError[] getResolverErrors() {
+ return this.resolverErrors.clone();
+ }
+}
diff --git a/org.eclipse.virgo.kernel.osgi/src/main/java/org/eclipse/virgo/kernel/osgi/framework/UnableToSatisfyDependenciesException.java b/org.eclipse.virgo.kernel.osgi/src/main/java/org/eclipse/virgo/kernel/osgi/framework/UnableToSatisfyDependenciesException.java
new file mode 100644
index 00000000..cbd21f2b
--- /dev/null
+++ b/org.eclipse.virgo.kernel.osgi/src/main/java/org/eclipse/virgo/kernel/osgi/framework/UnableToSatisfyDependenciesException.java
@@ -0,0 +1,94 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2010 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.virgo.kernel.osgi.framework;
+
+import org.eclipse.osgi.service.resolver.ResolverError;
+import org.eclipse.osgi.service.resolver.State;
+import org.osgi.framework.Version;
+
+/**
+ * Signals an error resolving the dependencies of a bundle or library during installation.<p/>
+ *
+ * <strong>Concurrent Semantics</strong><br />
+ *
+ * Thread-safe.
+ *
+ */
+@SuppressWarnings("serial")
+public abstract class UnableToSatisfyDependenciesException extends Exception {
+
+ private final String symbolicName;
+
+ private final Version version;
+
+ private final String failureDescription;
+
+ /**
+ * Creates a new <code>UnableToSatisfyDependenciesException</code>.
+ *
+ * @param symbolicName the symbolic name of the entity that failed to install.
+ * @param version the version of the entity that failed to install.
+ * @param failureDescription the description of the dependency satisfaction problem.
+ */
+ protected UnableToSatisfyDependenciesException(String entity, String symbolicName, Version version, String failureDescription) {
+ super(formatMessage(entity, symbolicName, version, failureDescription));
+ this.symbolicName = symbolicName;
+ this.version = version;
+ this.failureDescription = failureDescription;
+ }
+
+ /**
+ * @return the symbolic name of the entity that failed to install.
+ */
+ public String getSymbolicName() {
+ return this.symbolicName;
+ }
+
+ /**
+ * @return the version of the entity that failed to install.
+ */
+ public Version getVersion() {
+ return this.version;
+ }
+
+ /**
+ * @return the full description of the dependencies that could not be satisfied.
+ */
+ public String getFailureDescription() {
+ return this.failureDescription;
+ }
+
+ /**
+ * Creates a formatted message to describe the dependency failure.
+ */
+ private static String formatMessage(String entity, String symbolicName, Version version, String failureDescription) {
+ return "Unable to satisfy dependencies of " + entity + " '" + symbolicName + "' at version '" + version + "': " + failureDescription;
+ }
+
+ /**
+ * Get any {@link State} associated with this exception.
+ *
+ * @return either <code>null</code> or a <code>State</code>
+ */
+ public State getState() {
+ return null;
+ }
+
+ /**
+ * Get any {@link ResolverError}s associated with this exception.
+ *
+ * @return either <code>null</code> or a possibly empty array of <code>ResolverError</code>s
+ */
+ public ResolverError[] getResolverErrors() {
+ return null;
+ }
+}
diff --git a/org.eclipse.virgo.kernel.osgi/src/main/java/org/eclipse/virgo/kernel/osgi/framework/UnableToSatisfyLibraryDependenciesException.java b/org.eclipse.virgo.kernel.osgi/src/main/java/org/eclipse/virgo/kernel/osgi/framework/UnableToSatisfyLibraryDependenciesException.java
new file mode 100644
index 00000000..669a4434
--- /dev/null
+++ b/org.eclipse.virgo.kernel.osgi/src/main/java/org/eclipse/virgo/kernel/osgi/framework/UnableToSatisfyLibraryDependenciesException.java
@@ -0,0 +1,40 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2010 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.virgo.kernel.osgi.framework;
+
+import org.osgi.framework.Version;
+
+/**
+ * Signals an error resolving the dependencies of a library during installation.<p/>
+ *
+ * <strong>Concurrent Semantics</strong><br />
+ *
+ * Threadsafe.
+ *
+ */
+public class UnableToSatisfyLibraryDependenciesException extends UnableToSatisfyDependenciesException {
+
+ private static final long serialVersionUID = -2705837902792185894L;
+
+ private static final String LIBRARY_ENTITY = "library";
+
+ /**
+ * Creates a new <code>UnableToSatisfyLibraryDependenciesException</code>.
+ *
+ * @param symbolicName the library symbolic name.
+ * @param version the library version.
+ * @param failureDescription a description of the failure.
+ */
+ public UnableToSatisfyLibraryDependenciesException(String symbolicName, Version version, String failureDescription) {
+ super(LIBRARY_ENTITY, symbolicName, version, failureDescription);
+ }
+}
diff --git a/org.eclipse.virgo.kernel.osgi/src/main/java/org/eclipse/virgo/kernel/osgi/framework/UnableToSatisfyPlanDependenciesException.java b/org.eclipse.virgo.kernel.osgi/src/main/java/org/eclipse/virgo/kernel/osgi/framework/UnableToSatisfyPlanDependenciesException.java
new file mode 100644
index 00000000..781df446
--- /dev/null
+++ b/org.eclipse.virgo.kernel.osgi/src/main/java/org/eclipse/virgo/kernel/osgi/framework/UnableToSatisfyPlanDependenciesException.java
@@ -0,0 +1,35 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2010 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.virgo.kernel.osgi.framework;
+
+import org.osgi.framework.Version;
+
+/**
+ * Signals an error resolving the dependencies of a plan during installation.
+ * <p/>
+ *
+ * <strong>Concurrent Semantics</strong><br />
+ *
+ * Threadsafe.
+ *
+ */
+public class UnableToSatisfyPlanDependenciesException extends UnableToSatisfyDependenciesException {
+
+ private static final long serialVersionUID = 903287709449316407L;
+
+ private static final String PLAN_ENTITY = "plan";
+
+ public UnableToSatisfyPlanDependenciesException(String symbolicName, Version version, String failureDescription) {
+ super(PLAN_ENTITY, symbolicName, version, failureDescription);
+ }
+
+}
diff --git a/org.eclipse.virgo.kernel.osgi/src/main/java/org/eclipse/virgo/kernel/osgi/framework/support/AbstractOsgiFramework.java b/org.eclipse.virgo.kernel.osgi/src/main/java/org/eclipse/virgo/kernel/osgi/framework/support/AbstractOsgiFramework.java
new file mode 100644
index 00000000..d174b962
--- /dev/null
+++ b/org.eclipse.virgo.kernel.osgi/src/main/java/org/eclipse/virgo/kernel/osgi/framework/support/AbstractOsgiFramework.java
@@ -0,0 +1,76 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2010 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.virgo.kernel.osgi.framework.support;
+
+import org.eclipse.virgo.kernel.osgi.framework.OsgiFramework;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.service.packageadmin.PackageAdmin;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+/**
+ * Base implementation of {@link OsgiFramework}.
+ * <p/>
+ *
+ * Core start and stop logic is handled by this base implementation. In particular, the requirement to self publish as
+ * services in the service registration under <code>BundleInstaller</code> and <code>OsgiFramework</code> is handled.
+ * <p/>
+ *
+ * <strong>Concurrent Semantics</strong><br/>
+ *
+ * Implementation is thread safe.
+ *
+ */
+public abstract class AbstractOsgiFramework implements OsgiFramework {
+
+ public static final String DIRECTIVE_SEPARATOR = ";";
+
+ public static final boolean DIRECTIVE_PUBLISH_CONTEXT_DEFAULT = true;
+
+ protected final Logger logger = LoggerFactory.getLogger(this.getClass());
+
+ private final PackageAdmin packageAdmin;
+
+ private final BundleContext bundleContext;
+
+
+ protected AbstractOsgiFramework(BundleContext context, PackageAdmin packageAdmin) {
+ this.bundleContext = context;
+ this.packageAdmin = packageAdmin;
+ }
+
+ public Bundle getClassBundle(Class<?> cls) {
+ if (this.packageAdmin != null) {
+ return this.packageAdmin.getBundle(cls);
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * Gets the {@link PackageAdmin} service.
+ *
+ * @return the <code>PackageAdmin</code> service.
+ */
+ protected final PackageAdmin getPackageAdmin() {
+ return this.packageAdmin;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public BundleContext getBundleContext() {
+ return this.bundleContext;
+ }
+}
diff --git a/org.eclipse.virgo.kernel.osgi/src/main/java/org/eclipse/virgo/kernel/osgi/framework/support/ImmutableOsgiConfiguration.java b/org.eclipse.virgo.kernel.osgi/src/main/java/org/eclipse/virgo/kernel/osgi/framework/support/ImmutableOsgiConfiguration.java
new file mode 100644
index 00000000..3b349f2e
--- /dev/null
+++ b/org.eclipse.virgo.kernel.osgi/src/main/java/org/eclipse/virgo/kernel/osgi/framework/support/ImmutableOsgiConfiguration.java
@@ -0,0 +1,53 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2010 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.virgo.kernel.osgi.framework.support;
+
+import org.eclipse.virgo.kernel.osgi.framework.OsgiConfiguration;
+
+/**
+ * Abstract implementation of {@link OsgiConfiguration}.
+ *
+ * <strong>Concurrent Semantics</strong><br/>
+ *
+ * Thread-safe.
+ *
+ */
+public final class ImmutableOsgiConfiguration implements OsgiConfiguration {
+
+ private final boolean consoleEnabled;
+
+ private final int consolePort;
+
+ /**
+ * Creates a new <code>OsgiConfiguration</code> with the repository search paths.
+ * @param consoleEnabled whether console is enabled
+ * @param consolePort port number for console
+ */
+ public ImmutableOsgiConfiguration(boolean consoleEnabled, int consolePort) {
+ this.consoleEnabled = consoleEnabled;
+ this.consolePort = consolePort;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean isConsoleEnabled() {
+ return this.consoleEnabled;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public int getConsolePort() {
+ return this.consolePort;
+ }
+}
diff --git a/org.eclipse.virgo.kernel.osgi/src/main/java/org/eclipse/virgo/kernel/osgi/quasi/QuasiBundle.java b/org.eclipse.virgo.kernel.osgi/src/main/java/org/eclipse/virgo/kernel/osgi/quasi/QuasiBundle.java
new file mode 100644
index 00000000..f3399005
--- /dev/null
+++ b/org.eclipse.virgo.kernel.osgi/src/main/java/org/eclipse/virgo/kernel/osgi/quasi/QuasiBundle.java
@@ -0,0 +1,129 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2010 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.virgo.kernel.osgi.quasi;
+
+import java.io.File;
+import java.util.List;
+
+import org.osgi.framework.Bundle;
+import org.osgi.framework.Version;
+
+/**
+ * {@link QuasiBundle} is a representation of a bundle in a {@link QuasiFramework}.
+ * <p />
+ *
+ * <strong>Concurrent Semantics</strong><br />
+ *
+ * Implementations of this class must be thread safe.
+ *
+ */
+public interface QuasiBundle {
+
+ /**
+ * Returns this {@link QuasiBundle}'s symbolic name. If this <code>QuasiBundle</code> does not have a symbolic name,
+ * returns <code>null</code>.
+ *
+ * @return a bundle symbolic name String or <code>null</code> if this <code>QuasiBundle</code> does not have a
+ * symbolic name
+ */
+ String getSymbolicName();
+
+ /**
+ * Returns this {@link QuasiBundle}'s bundle version.
+ *
+ * @return a {@link Version}, which is never <code>null</code>
+ */
+ Version getVersion();
+
+ /**
+ * Returns whether this {@link QuasiBundle} was resolved in its {@link QuasiFramework}.
+ *
+ * @return <code>true</code> if and only if this <code>QuasiBundle</code> is resolved
+ */
+ boolean isResolved();
+
+ /**
+ * Uninstalls this {@link QuasiBundle} from its {@link QuasiFramework}. This does not modify any committed
+ * {@link Bundle} in the OSGi framework.
+ */
+ void uninstall();
+
+ /**
+ * If this {@link QuasiBundle} has been successfully committed, returns the corresponding {@link Bundle} in the OSGi
+ * framework. If this {@link QuasiBundle} has not been successfully committed, returns <code>null</code>.
+ *
+ * @return a <code>Bundle</code> or <code>null</code>
+ */
+ Bundle getBundle();
+
+ /**
+ * Returns the numeric id of this QuasiBundle. Typically a QuasiBundle will only have a numeric id if it represents
+ * a bundle that is present in a QuasiFramework as the framework assigns the ids. -1 is returned if the id is not
+ * known.
+ *
+ * @return the numeric id of this QuasiBundle
+ */
+ long getBundleId();
+
+ /**
+ * Returns all fragments known to this QuasiBundle (regardless resolution status).
+ *
+ * @return an array of QuasiBundle containing all known fragments
+ */
+ List<QuasiBundle> getFragments();
+
+ /**
+ * Returns the potential hosts for this QuasiBundle. null is returned if this QuasiBundle is not a fragment.
+ *
+ * @return the host QuasiBundles for this QuasiBundle or null.
+ */
+ List<QuasiBundle> getHosts();
+
+ /**
+ * Returns an array of QuasiExportPackage defined by the Export-Package clauses. All QuasiExportPackage are returned
+ * even if they have not been selected by the resolver as an exporter of the package.
+ *
+ * @return an array of QuasiExportPackage
+ */
+ List<QuasiExportPackage> getExportPackages();
+
+ /**
+ * Returns an array of {@link QuasiImportPackage} defined by the Import-Package clause of this QuasiBundle.
+ *
+ * @return an array of QuasiImportPackage
+ */
+ List<QuasiImportPackage> getImportPackages();
+
+ /**
+ * Returns an array of {@link QuasiRequiredBundle} defined by the Require-Bundle clause of this QuasiBundle.
+ *
+ * @return an array of QuasiRequiredBundle
+ */
+ List<QuasiRequiredBundle> getRequiredBundles();
+
+ /**
+ * A utility method that returns all QuasiBundle which depend on this bundle. A bundle depends on another bundle if
+ * it requires the bundle, imports a package which is exported by that bundle, is a fragment to the bundle or is the
+ * host of the bundle.
+ *
+ * @return all QuasiBundle(s) which depend on this bundle.
+ */
+ List<QuasiBundle> getDependents();
+
+ /**
+ * Returns the actual filesystem location of this QuasiBundle
+ *
+ * @return The file that is represented by this QuasiBundle
+ */
+ File getBundleFile();
+
+}
diff --git a/org.eclipse.virgo.kernel.osgi/src/main/java/org/eclipse/virgo/kernel/osgi/quasi/QuasiExportPackage.java b/org.eclipse.virgo.kernel.osgi/src/main/java/org/eclipse/virgo/kernel/osgi/quasi/QuasiExportPackage.java
new file mode 100644
index 00000000..dc3e3669
--- /dev/null
+++ b/org.eclipse.virgo.kernel.osgi/src/main/java/org/eclipse/virgo/kernel/osgi/quasi/QuasiExportPackage.java
@@ -0,0 +1,53 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2010 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.virgo.kernel.osgi.quasi;
+
+import java.util.List;
+
+import org.osgi.framework.Version;
+
+/**
+ * {@link QuasiExportPackage} is a representation of an exported package
+ * from a {@link QuasiBundle}.
+ * <p />
+ *
+ * <strong>Concurrent Semantics</strong><br />
+ *
+ * Implementations of this interface must be thread safe.
+ *
+ */
+public interface QuasiExportPackage extends QuasiParameterised {
+
+ /**
+ *
+ * @return the name of the package being exported
+ */
+ public String getPackageName();
+
+ /**
+ *
+ * @return the <code>Version</code> that the package is exported at.
+ */
+ public Version getVersion();
+
+ /**
+ *
+ * @return the {@link QuasiBundle} that provides this <code>QuasiExportPackage</code>
+ */
+ public QuasiBundle getExportingBundle();
+
+ /**
+ *
+ * @return The a list {@link QuasiImportPackage}s that are consuming this export
+ */
+ public List<QuasiImportPackage> getConsumers();
+}
diff --git a/org.eclipse.virgo.kernel.osgi/src/main/java/org/eclipse/virgo/kernel/osgi/quasi/QuasiFramework.java b/org.eclipse.virgo.kernel.osgi/src/main/java/org/eclipse/virgo/kernel/osgi/quasi/QuasiFramework.java
new file mode 100644
index 00000000..2f12f68a
--- /dev/null
+++ b/org.eclipse.virgo.kernel.osgi/src/main/java/org/eclipse/virgo/kernel/osgi/quasi/QuasiFramework.java
@@ -0,0 +1,106 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2010 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.virgo.kernel.osgi.quasi;
+
+import java.net.URI;
+import java.util.List;
+
+import org.eclipse.osgi.service.resolver.State;
+import org.osgi.framework.BundleException;
+import org.osgi.framework.Version;
+
+import org.eclipse.virgo.util.osgi.manifest.BundleManifest;
+
+/**
+ * {@link QuasiFramework} is a snapshot of the OSGi framework state into which bundles can be installed and resolved
+ * and, in the normal case, committed into the OSGi framework.
+ * <p />
+ *
+ * <strong>Concurrent Semantics</strong><br />
+ *
+ * Implementations of this class must be thread safe.
+ *
+ */
+public interface QuasiFramework {
+
+ /**
+ * Installs a bundle into this {@link QuasiFramework} using the given {@link URI} and {@link BundleManifest} and
+ * returns a {@link QuasiBundle}.
+ *
+ * @param location a <code>URI</code> to the bundle's contents
+ * @param bundleManifest the <code>BundleManifest</code> to be used for the bundle, regardless of any manifest at
+ * the location
+ * @return a <code>QuasiBundle</code>
+ * @throws BundleException if the bundle could not be installed
+ */
+ QuasiBundle install(URI location, BundleManifest bundleManifest) throws BundleException;
+
+ /**
+ * Returns a list of {@link QuasiBundle} that represent all the bundles currently installed in this {@link QuasiFramework}.
+ *
+ * @return a non<code>null</code> list of <code>QuasiBundle</code>
+ */
+ List<QuasiBundle> getBundles();
+
+ /**
+ * Returns a {@link QuasiBundle} with the given bundle id.
+ *
+ * @param bundleId
+ * @return <code>QuasiBundle</code> or <code>null</code> if the id is not known.
+ */
+ QuasiBundle getBundle(long bundleId);
+
+ /**
+ * Returns a {@link QuasiBundle} with the given bundle name and version.
+ *
+ * @param name
+ * @param version
+ * @return <code>QuasiBundle</code> or <code>null</code> if the name/version is not found.
+ */
+ QuasiBundle getBundle(String name, Version version);
+
+ /**
+ * Attempts to resolve the {@link QuasiBundle QuasiBundles} that have been installed in this {@link QuasiFramework}.
+ * <p/>
+ * If all the bundles can be resolved, returns an empty list. If some of the bundles cannot be resolved, returns a
+ * list of {@link QuasiResolutionFailure QuasiResolutionFailures}.
+ *
+ * @return a non<code>null</code> list of <code>QuasiResolutionFailure</code>, which is empty if resolution succeeded
+ */
+ List<QuasiResolutionFailure> resolve();
+
+ /**
+ * Diagnoses failures to resolve of the {@link QuasiBundle} given.
+ * <p/>
+ * If the bundle can be resolved, returns null otherwise a {@link QuasiResolutionFailure} is returned.
+ * @param bundleId identifier (in the {@link State}) of bundle to diagnose
+ *
+ * @return a non<code>null</code> list of <code>QuasiResolutionFailure</code>, which is empty if resolution succeeded
+ */
+ List<QuasiResolutionFailure> diagnose(long bundleId);
+
+ /**
+ * Attempts to resolve any unresolved {@link QuasiBundle QuasiBundles} in this {@link QuasiFramework} and then
+ * commits the contents of this {@link QuasiFramework} by installing each of its <code>QuasiBundles</code> into the
+ * OSGi framework.
+ * <p/>
+ * If any unresolved <code>QuasiBundles</code> cannot be resolved, {@link BundleException} is thrown.
+ * <p/>
+ * If a <code>QuasiBundle</code> fails to install, any <code>QuasiBundles</code> which have been installed are
+ * uninstalled and <code>BundleException</code> is thrown.
+ * <p/>
+ *
+ * @throws BundleException if the contents could not be resolved and installed
+ */
+ void commit() throws BundleException;
+
+}
diff --git a/org.eclipse.virgo.kernel.osgi/src/main/java/org/eclipse/virgo/kernel/osgi/quasi/QuasiFrameworkFactory.java b/org.eclipse.virgo.kernel.osgi/src/main/java/org/eclipse/virgo/kernel/osgi/quasi/QuasiFrameworkFactory.java
new file mode 100644
index 00000000..5bea9b9e
--- /dev/null
+++ b/org.eclipse.virgo.kernel.osgi/src/main/java/org/eclipse/virgo/kernel/osgi/quasi/QuasiFrameworkFactory.java
@@ -0,0 +1,42 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2010 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.virgo.kernel.osgi.quasi;
+
+import java.io.File;
+
+/**
+ * {@link QuasiFrameworkFactory} is used to create {@link QuasiFramework QuasiFrameworks}.
+ * <p />
+ *
+ * <strong>Concurrent Semantics</strong><br />
+ *
+ * Implementations of this class must be thread safe.
+ *
+ */
+public interface QuasiFrameworkFactory {
+
+ /**
+ * Creates a {@link QuasiFramework} from the current OSGi framework state.
+ *
+ * @return the <code>QuasiFramework</code>, which is never <code>null</code>
+ */
+ QuasiFramework create();
+
+ /**
+ * Creates a {@link QuasiFramework} from a state dump in the given directory.
+ *
+ * @param stateDump a {@link File} containing the state dump directory
+ * @return the <code>QuasiFramework</code>, which is never <code>null</code>
+ */
+ QuasiFramework create(File stateDump);
+
+}
diff --git a/org.eclipse.virgo.kernel.osgi/src/main/java/org/eclipse/virgo/kernel/osgi/quasi/QuasiImportPackage.java b/org.eclipse.virgo.kernel.osgi/src/main/java/org/eclipse/virgo/kernel/osgi/quasi/QuasiImportPackage.java
new file mode 100644
index 00000000..33080d3b
--- /dev/null
+++ b/org.eclipse.virgo.kernel.osgi/src/main/java/org/eclipse/virgo/kernel/osgi/quasi/QuasiImportPackage.java
@@ -0,0 +1,64 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2010 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.virgo.kernel.osgi.quasi;
+
+import org.eclipse.virgo.util.osgi.VersionRange;
+
+/**
+ * <p>
+ * {@link QuasiImportPackage} is a representation of a imported package from a {@link QuasiBundle}.
+ * </p>
+ *
+ * <strong>Concurrent Semantics</strong><br />
+ *
+ * Implementations of this interface must be thread safe.
+ *
+ */
+public interface QuasiImportPackage extends QuasiParameterised {
+
+ /**
+ * The name of the package being imported.
+ *
+ * @return The package name
+ */
+ public String getPackageName();
+
+ /**
+ * The version range that the exporting package must be within to satisfy this <code>QuasiImportPackage</code>.
+ *
+ * @return The {@link VersionRange} constraint
+ */
+ public VersionRange getVersionConstraint();
+
+ /**
+ * Returns whether or not this import is resolved.
+ *
+ * @return true if this import is resolved
+ */
+ public boolean isResolved();
+
+ /**
+ * If this import is resolved, return the {@link QuasiExportPackage} that satisfies it. If this import is not
+ * resolved or if it is resolved but is an optional import that was not satisfied, return null.
+ *
+ * @return any <code>QuasiExportPackage</code> that satisfies this import.
+ */
+ public QuasiExportPackage getProvider();
+
+ /**
+ * The {@link QuasiBundle} that specifies this import package.
+ *
+ * @return The specifying <code>QuasiBundle</code>.
+ */
+ public QuasiBundle getImportingBundle();
+
+}
diff --git a/org.eclipse.virgo.kernel.osgi/src/main/java/org/eclipse/virgo/kernel/osgi/quasi/QuasiPackageResolutionFailure.java b/org.eclipse.virgo.kernel.osgi/src/main/java/org/eclipse/virgo/kernel/osgi/quasi/QuasiPackageResolutionFailure.java
new file mode 100644
index 00000000..9fbb421a
--- /dev/null
+++ b/org.eclipse.virgo.kernel.osgi/src/main/java/org/eclipse/virgo/kernel/osgi/quasi/QuasiPackageResolutionFailure.java
@@ -0,0 +1,36 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2010 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.virgo.kernel.osgi.quasi;
+
+import org.eclipse.virgo.util.osgi.VersionRange;
+
+/**
+ * {@link QuasiPackageResolutionFailure} describes a failure to resolve a package import of a {@link QuasiBundle} in a
+ * {@link QuasiFramework}.
+ * <p />
+ *
+ * <strong>Concurrent Semantics</strong><br />
+ *
+ * Implementations of this class are thread safe.
+ *
+ */
+public interface QuasiPackageResolutionFailure extends QuasiResolutionFailure {
+
+ String getPackage();
+
+ VersionRange getPackageVersionRange();
+
+ String getPackageBundleSymbolicName();
+
+ VersionRange getPackageBundleVersionRange();
+
+}
diff --git a/org.eclipse.virgo.kernel.osgi/src/main/java/org/eclipse/virgo/kernel/osgi/quasi/QuasiPackageUsesResolutionFailure.java b/org.eclipse.virgo.kernel.osgi/src/main/java/org/eclipse/virgo/kernel/osgi/quasi/QuasiPackageUsesResolutionFailure.java
new file mode 100644
index 00000000..7f1e45d0
--- /dev/null
+++ b/org.eclipse.virgo.kernel.osgi/src/main/java/org/eclipse/virgo/kernel/osgi/quasi/QuasiPackageUsesResolutionFailure.java
@@ -0,0 +1,26 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2010 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.virgo.kernel.osgi.quasi;
+
+/**
+ * {@link QuasiPackageUsesResolutionFailure} describes a failure to resolve a package import of a {@link QuasiBundle} in
+ * a {@link QuasiFramework} because of a user constraint.
+ * <p />
+ *
+ * <strong>Concurrent Semantics</strong><br />
+ *
+ * Implementations of this class are thread safe.
+ *
+ */
+public interface QuasiPackageUsesResolutionFailure extends QuasiPackageResolutionFailure {
+
+}
diff --git a/org.eclipse.virgo.kernel.osgi/src/main/java/org/eclipse/virgo/kernel/osgi/quasi/QuasiParameterised.java b/org.eclipse.virgo.kernel.osgi/src/main/java/org/eclipse/virgo/kernel/osgi/quasi/QuasiParameterised.java
new file mode 100644
index 00000000..34d7bdbb
--- /dev/null
+++ b/org.eclipse.virgo.kernel.osgi/src/main/java/org/eclipse/virgo/kernel/osgi/quasi/QuasiParameterised.java
@@ -0,0 +1,41 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2010 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.virgo.kernel.osgi.quasi;
+
+import java.util.Map;
+
+/**
+ * {@link QuasiParameterised} provides access to the attributes and directives of a header.
+ * <p />
+ *
+ * <strong>Concurrent Semantics</strong><br />
+ *
+ * Implementations of this class must be thread safe.
+ *
+ */
+public interface QuasiParameterised {
+
+ /**
+ * Returns the directives for a header.
+ *
+ * @return a map containing the directives
+ */
+ Map<String, Object> getDirectives();
+
+ /**
+ * Returns the attributes for a header.
+ *
+ * @return a map containing the attributes
+ */
+ Map<String, Object> getAttributes();
+
+}
diff --git a/org.eclipse.virgo.kernel.osgi/src/main/java/org/eclipse/virgo/kernel/osgi/quasi/QuasiRequiredBundle.java b/org.eclipse.virgo.kernel.osgi/src/main/java/org/eclipse/virgo/kernel/osgi/quasi/QuasiRequiredBundle.java
new file mode 100644
index 00000000..ff53af81
--- /dev/null
+++ b/org.eclipse.virgo.kernel.osgi/src/main/java/org/eclipse/virgo/kernel/osgi/quasi/QuasiRequiredBundle.java
@@ -0,0 +1,62 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2010 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.virgo.kernel.osgi.quasi;
+
+import org.eclipse.virgo.util.osgi.VersionRange;
+
+/**
+ * <p>
+ * {@link QuasiRequiredBundle} is a representation of a bundle required from another bundle in a {@link QuasiFramework}.
+ * </p>
+ *
+ * <strong>Concurrent Semantics</strong><br />
+ *
+ * Implementations of this class must be thread safe.
+ *
+ */
+public interface QuasiRequiredBundle extends QuasiParameterised {
+
+ /**
+ * @return The symbolic name of the Bundle required.
+ */
+ public String getRequiredBundleName();
+
+ /**
+ * The version range that must be satisfied by any matching bundles.
+ *
+ * @return the <code>VersionRange</code> constraint
+ */
+ public VersionRange getVersionConstraint();
+
+ /**
+ * Returns whether this require bundle is resolved.
+ *
+ * @return true if this require bundle is resolved
+ */
+ public boolean isResolved();
+
+ /**
+ * If this require bundle is resolved, return any specific {@link QuasiBundle} that satisfies it. If this require
+ * bundle is not resolved or if it is resolved but is optional and was not satisfied, return null.
+ *
+ * @return any <code>QuasiBundle</code> that satisfies this <code>QuasiRequiredBundle</code>.
+ */
+ public QuasiBundle getProvider();
+
+ /**
+ * The {@link QuasiBundle} that specifies this <code>QuasiRequiredBundle</code> clause.
+ *
+ * @return The requiring QuasiBundle.
+ */
+ public QuasiBundle getRequiringBundle();
+
+}
diff --git a/org.eclipse.virgo.kernel.osgi/src/main/java/org/eclipse/virgo/kernel/osgi/quasi/QuasiResolutionFailure.java b/org.eclipse.virgo.kernel.osgi/src/main/java/org/eclipse/virgo/kernel/osgi/quasi/QuasiResolutionFailure.java
new file mode 100644
index 00000000..20841c5c
--- /dev/null
+++ b/org.eclipse.virgo.kernel.osgi/src/main/java/org/eclipse/virgo/kernel/osgi/quasi/QuasiResolutionFailure.java
@@ -0,0 +1,40 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2010 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.virgo.kernel.osgi.quasi;
+
+
+/**
+ * {@link QuasiResolutionFailure} describes a failure to resolve a {@link QuasiBundle} in a {@link QuasiFramework}.
+ * <p />
+ *
+ * <strong>Concurrent Semantics</strong><br />
+ *
+ * Implementations of this class are thread safe.
+ *
+ */
+public interface QuasiResolutionFailure {
+
+ /**
+ * Gets a human readable description of the failure.
+ *
+ * @return a human readable String
+ */
+ String getDescription();
+
+ /**
+ * Gets the unresolved {@link QuasiBundle}.
+ *
+ * @return the unresolved <code>QuasiBundle</code>
+ */
+ QuasiBundle getUnresolvedQuasiBundle();
+
+}
diff --git a/org.eclipse.virgo.kernel.osgi/src/main/java/org/eclipse/virgo/kernel/osgi/region/PackageImportWildcardExpander.java b/org.eclipse.virgo.kernel.osgi/src/main/java/org/eclipse/virgo/kernel/osgi/region/PackageImportWildcardExpander.java
new file mode 100644
index 00000000..1467b3fd
--- /dev/null
+++ b/org.eclipse.virgo.kernel.osgi/src/main/java/org/eclipse/virgo/kernel/osgi/region/PackageImportWildcardExpander.java
@@ -0,0 +1,141 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2010 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.virgo.kernel.osgi.region;
+
+import java.util.ArrayList;
+import java.util.Dictionary;
+import java.util.HashSet;
+import java.util.Hashtable;
+import java.util.List;
+import java.util.Set;
+
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceReference;
+import org.osgi.service.packageadmin.ExportedPackage;
+import org.osgi.service.packageadmin.PackageAdmin;
+
+
+import org.eclipse.virgo.kernel.osgi.framework.OsgiFrameworkLogEvents;
+import org.eclipse.virgo.kernel.serviceability.Assert;
+import org.eclipse.virgo.medic.eventlog.EventLogger;
+import org.eclipse.virgo.util.osgi.manifest.BundleManifest;
+import org.eclipse.virgo.util.osgi.manifest.BundleManifestFactory;
+import org.eclipse.virgo.util.osgi.manifest.DynamicImportPackage;
+import org.eclipse.virgo.util.osgi.manifest.DynamicallyImportedPackage;
+
+/**
+ * {@link PackageImportWildcardExpander} expands the wildcards in a string containing the body of an import package
+ * header.
+ * <p />
+ *
+ * <strong>Concurrent Semantics</strong><br />
+ *
+ * Thread safe.
+ *
+ */
+final class PackageImportWildcardExpander {
+
+ private static final String wildcard = "*";
+
+ static String expandPackageImportsWildcards(String userRegionImportsProperty, BundleContext bundleContext) {
+ ServiceReference eventLoggerServiceReference = bundleContext.getServiceReference(EventLogger.class.getName());
+ EventLogger eventLogger = (EventLogger) bundleContext.getService(eventLoggerServiceReference);
+
+ String[] exportedPackageNames = getExportedPackageNames(bundleContext);
+
+ String expandedUserRegionImportsProperty = expandWildcards(userRegionImportsProperty, exportedPackageNames, eventLogger);
+
+ bundleContext.ungetService(eventLoggerServiceReference);
+
+ return expandedUserRegionImportsProperty;
+ }
+
+ private static String[] getExportedPackageNames(BundleContext bundleContext) {
+ Set<String> exportedPackageNames = new HashSet<String>();
+ for (ExportedPackage exportedPackage : getExportedPackages(bundleContext)) {
+ exportedPackageNames.add(exportedPackage.getName());
+ }
+ return exportedPackageNames.toArray(new String[] {});
+ }
+
+ private static ExportedPackage[] getExportedPackages(BundleContext bundleContext) {
+ ServiceReference paServiceReference = bundleContext.getServiceReference(PackageAdmin.class.getName());
+ PackageAdmin pa = (PackageAdmin) bundleContext.getService(paServiceReference);
+
+ ExportedPackage[] exportedPackages = pa.getExportedPackages((Bundle) null);
+ Assert.notNull(exportedPackages, "Expected at least one exported package");
+
+ bundleContext.ungetService(paServiceReference);
+
+ return exportedPackages;
+ }
+
+ private static String expandWildcards(String userRegionImportsProperty, String[] exportedPackageNamess, EventLogger eventLogger) {
+ DynamicImportPackage dynamicImportPackage = representImportsAsDynamicImports(userRegionImportsProperty, eventLogger);
+ return expandWildcards(dynamicImportPackage, exportedPackageNamess, eventLogger);
+ }
+
+ private static DynamicImportPackage representImportsAsDynamicImports(String userRegionImportsProperty, EventLogger eventLogger) {
+ Dictionary<String, String> headers = new Hashtable<String, String>();
+ headers.put("DynamicImport-Package", userRegionImportsProperty);
+
+ BundleManifest manifest = BundleManifestFactory.createBundleManifest(headers, new RegionManagerParserLogger(eventLogger));
+ return manifest.getDynamicImportPackage();
+ }
+
+ private static String expandWildcards(DynamicImportPackage dynamicImportPackage, String[] exportedPackageNames, EventLogger eventLogger) {
+ StringBuffer expandedPackages = new StringBuffer();
+ boolean first = true;
+ List<DynamicallyImportedPackage> dynamicallyImportedPackages = dynamicImportPackage.getDynamicallyImportedPackages();
+ for (DynamicallyImportedPackage dynamicallyImportedPackage : dynamicallyImportedPackages) {
+ String possiblyWildcardedPackageName = dynamicallyImportedPackage.getPackageName();
+ if (possiblyWildcardedPackageName.endsWith(wildcard)) {
+ List<String> expansions = expandWildcard(possiblyWildcardedPackageName, exportedPackageNames, eventLogger);
+ for (String expansion : expansions) {
+ dynamicallyImportedPackage.setPackageName(expansion);
+ if (first) {
+ first = false;
+ } else {
+ expandedPackages.append(",");
+ }
+ expandedPackages.append(dynamicallyImportedPackage.toParseString());
+ }
+ } else {
+ if (first) {
+ first = false;
+ } else {
+ expandedPackages.append(",");
+ }
+ expandedPackages.append(dynamicallyImportedPackage.toParseString());
+ }
+
+ }
+ return expandedPackages.toString();
+ }
+
+ private static List<String> expandWildcard(String wildcardedPackageName, String[] exportedPackageNames, EventLogger eventLogger) {
+ List<String> expansions = new ArrayList<String>();
+
+ String prefix = wildcardedPackageName.substring(0, wildcardedPackageName.length() - 1);
+ for (String exportedPackage : exportedPackageNames) {
+ if (exportedPackage.startsWith(prefix)) {
+ expansions.add(exportedPackage);
+ }
+ }
+ if (expansions.isEmpty()) {
+ eventLogger.log(OsgiFrameworkLogEvents.REGION_IMPORT_NO_MATCH, wildcardedPackageName);
+ }
+ return expansions;
+ }
+
+}
diff --git a/org.eclipse.virgo.kernel.osgi/src/main/java/org/eclipse/virgo/kernel/osgi/region/Region.java b/org.eclipse.virgo.kernel.osgi/src/main/java/org/eclipse/virgo/kernel/osgi/region/Region.java
new file mode 100644
index 00000000..e737cd2c
--- /dev/null
+++ b/org.eclipse.virgo.kernel.osgi/src/main/java/org/eclipse/virgo/kernel/osgi/region/Region.java
@@ -0,0 +1,40 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2010 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.virgo.kernel.osgi.region;
+
+import org.osgi.framework.BundleContext;
+
+/**
+ * A region is an encapsulated OSGi framework. Regions are isolated from each other except by explicitly shared packages
+ * and services that are defined when the region is created.
+ * <p />
+ *
+ * <strong>Concurrent Semantics</strong><br />
+ *
+ * Implementations must be threadsafe.
+ *
+ */
+public interface Region {
+
+ /**
+ * @return the name of the region
+ */
+ String getName();
+
+ /**
+ * Returns a {@link BundleContext} that can be used to access the encapsulated OSGi framework.
+ *
+ * @return a <code>BundleContext</code>
+ */
+ BundleContext getBundleContext();
+
+}
diff --git a/org.eclipse.virgo.kernel.osgi/src/main/java/org/eclipse/virgo/kernel/osgi/region/RegionManager.java b/org.eclipse.virgo.kernel.osgi/src/main/java/org/eclipse/virgo/kernel/osgi/region/RegionManager.java
new file mode 100644
index 00000000..cec58b32
--- /dev/null
+++ b/org.eclipse.virgo.kernel.osgi/src/main/java/org/eclipse/virgo/kernel/osgi/region/RegionManager.java
@@ -0,0 +1,361 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2010 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.virgo.kernel.osgi.region;
+
+import java.io.IOException;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Dictionary;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.BundleException;
+import org.osgi.framework.Constants;
+import org.osgi.framework.ServiceFactory;
+import org.osgi.framework.launch.Framework;
+import org.osgi.service.cm.Configuration;
+import org.osgi.service.cm.ConfigurationAdmin;
+import org.osgi.service.event.Event;
+import org.osgi.service.event.EventAdmin;
+import org.osgi.service.framework.CompositeBundle;
+import org.osgi.service.framework.CompositeBundleFactory;
+import org.osgi.service.framework.SurrogateBundle;
+
+import org.eclipse.virgo.osgi.launcher.parser.ArgumentParser;
+import org.eclipse.virgo.osgi.launcher.parser.BundleEntry;
+import org.eclipse.virgo.medic.eventlog.EventLogger;
+import org.eclipse.virgo.util.osgi.ServiceRegistrationTracker;
+
+/**
+ * Creates and manages the user {@link Region regions}.
+ * <p />
+ *
+ * <strong>Concurrent Semantics</strong><br />
+ *
+ * Threadsafe.
+ *
+ */
+@SuppressWarnings("deprecation")
+final class RegionManager {
+
+ private static final String USER_REGION_CONFIGURATION_PID = "org.eclipse.virgo.kernel.userregion";
+
+ private static final String PLUGGABLE_CLASS_LOADING_HOOK_CLASS_NAME = "org.eclipse.virgo.osgi.extensions.equinox.hooks.PluggableClassLoadingHook";
+
+ private static final String USER_REGION_BASE_BUNDLES_PROPERTY = "baseBundles";
+
+ private static final String USER_REGION_PACKAGE_IMPORTS_PROPERTY = "packageImports";
+
+ private static final String USER_REGION_SERVICE_IMPORTS_PROPERTY = "serviceImports";
+
+ private static final String USER_REGION_SERVICE_EXPORTS_PROPERTY = "serviceExports";
+
+ private static final String USER_REGION_PROPERTIES_PROPERTY = "inheritedFrameworkProperties";
+
+ private static final String REGION_USER = "org.eclipse.virgo.region.user";
+
+ private static final String EVENT_REGION_STARTING = "org/eclipse/virgo/kernel/region/STARTING";
+
+ private static final Object EVENT_PROPERTY_REGION_BUNDLECONTEXT = "region.bundleContext";
+
+ private final ServiceRegistrationTracker tracker = new ServiceRegistrationTracker();
+
+ private final BundleContext bundleContext;
+
+ private final CompositeBundleFactory compositeBundleFactory;
+
+ private final ArgumentParser parser = new ArgumentParser();
+
+ private final EventAdmin eventAdmin;
+
+ private final ServiceFactory eventLoggerServiceFactory;
+
+ private volatile Framework childFramework;
+
+ private Dictionary<String, String> userRegionProperties;
+
+ private String regionBundles;
+
+ private String regionImports;
+
+ private String regionServiceImports;
+
+ private String regionServiceExports;
+
+ private String regionInheritedProperties;
+
+ public RegionManager(BundleContext bundleContext, CompositeBundleFactory compositeBundleFactory, EventAdmin eventAdmin,
+ ServiceFactory eventLoggerServiceFactory, ConfigurationAdmin configAdmin) {
+ this.bundleContext = bundleContext;
+ this.compositeBundleFactory = compositeBundleFactory;
+ this.eventAdmin = eventAdmin;
+ this.eventLoggerServiceFactory = eventLoggerServiceFactory;
+ getRegionConfiguration(configAdmin);
+ }
+
+ @SuppressWarnings("unchecked")
+ private void getRegionConfiguration(ConfigurationAdmin configAdmin) {
+ try {
+ Configuration config = configAdmin.getConfiguration(USER_REGION_CONFIGURATION_PID);
+ Dictionary<String, String> properties = (Dictionary<String, String>) config.getProperties();
+ if (properties != null) {
+ this.userRegionProperties = properties;
+ this.regionBundles = properties.get(USER_REGION_BASE_BUNDLES_PROPERTY);
+ this.regionImports = properties.get(USER_REGION_PACKAGE_IMPORTS_PROPERTY);
+ this.regionServiceImports = properties.get(USER_REGION_SERVICE_IMPORTS_PROPERTY);
+ this.regionServiceExports = properties.get(USER_REGION_SERVICE_EXPORTS_PROPERTY);
+ this.regionInheritedProperties = properties.get(USER_REGION_PROPERTIES_PROPERTY);
+ }
+ } catch (IOException _) {
+ }
+ }
+
+ public void start() throws BundleException {
+ createAndPublishUserRegion();
+ }
+
+ private void createAndPublishUserRegion() throws BundleException {
+
+ CompositeBundle compositeBundle = this.compositeBundleFactory.installCompositeBundle(createChildFrameworkConfig(), REGION_USER,
+ createCompositeBundleManifest());
+
+ childFramework = compositeBundle.getCompositeFramework();
+ compositeBundle.start();
+ childFramework.start();
+
+ SurrogateBundle surrogateBundle = compositeBundle.getSurrogateBundle();
+ BundleContext surrogateBundleContext = surrogateBundle.getBundleContext();
+
+ Properties properties = new Properties();
+ properties.put(EVENT_PROPERTY_REGION_BUNDLECONTEXT, surrogateBundleContext);
+ this.eventAdmin.sendEvent(new Event(EVENT_REGION_STARTING, properties));
+
+ setUserRegionBundleParentClassLoader(surrogateBundleContext);
+
+ registerEventLoggerServiceFactory(surrogateBundleContext);
+
+ initialiseUserRegionBundles(surrogateBundleContext);
+
+ registerRegionService(new ImmutableRegion(REGION_USER, surrogateBundleContext));
+ publishUserRegionsBundleContext(surrogateBundleContext);
+ }
+
+ private void registerEventLoggerServiceFactory(BundleContext surrogateBundleContext) {
+ surrogateBundleContext.registerService(EventLogger.class.getName(), this.eventLoggerServiceFactory, null);
+ }
+
+ /**
+ * @param surrogateBundleContext
+ */
+ private void publishUserRegionsBundleContext(BundleContext surrogateBundleContext) {
+ Properties properties = new Properties();
+ properties.put("org.eclipse.virgo.kernel.regionContext", "true");
+ this.bundleContext.registerService(BundleContext.class.getName(), surrogateBundleContext, properties);
+ }
+
+ private void setUserRegionBundleParentClassLoader(BundleContext surrogateBundleContext) throws BundleException {
+ ClassLoader surrogateClassLoader = surrogateBundleContext.getClass().getClassLoader();
+ try {
+ setUserRegionHookBundleParentClassLoader(surrogateClassLoader);
+ } catch (Exception e) {
+ throw new BundleException("Error setting user region hook bundle parent class loader", e);
+ }
+ }
+
+ private void setUserRegionHookBundleParentClassLoader(ClassLoader parentClassLoader) throws ClassNotFoundException, SecurityException,
+ NoSuchMethodException, IllegalArgumentException, IllegalAccessException, InvocationTargetException {
+ Class<?> pluggableClassLoadingHookClass = parentClassLoader.loadClass(PLUGGABLE_CLASS_LOADING_HOOK_CLASS_NAME);
+
+ Object pluggableClassLoadingHookInstance = invokeGetInstance(pluggableClassLoadingHookClass);
+
+ invokeSetParent(pluggableClassLoadingHookClass, pluggableClassLoadingHookInstance, parentClassLoader);
+ }
+
+ private Object invokeGetInstance(Class<?> pluggableClassLoadingHookClass) throws SecurityException, NoSuchMethodException,
+ IllegalArgumentException, IllegalAccessException, InvocationTargetException {
+ Class<?>[] parmTypes = {};
+ Method getInstanceMethod = pluggableClassLoadingHookClass.getDeclaredMethod("getInstance", parmTypes);
+ Object[] args = {};
+ return getInstanceMethod.invoke(null, args);
+ }
+
+ private void invokeSetParent(Class<?> pluggableClassLoadingHookClass, Object pluggableClassLoadingHookInstance, ClassLoader parentClassLoader)
+ throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
+ Class<?>[] parmTypes = { ClassLoader.class };
+ Method setParentMethod = pluggableClassLoadingHookClass.getDeclaredMethod("setBundleClassLoaderParent", parmTypes);
+ Object[] args = { parentClassLoader };
+ setParentMethod.invoke(pluggableClassLoadingHookInstance, args);
+ }
+
+ private Map<String, String> createChildFrameworkConfig() {
+ HashMap<String, String> frameworkConfig = new HashMap<String, String>();
+ // debug frameworkConfig.put(CONFIG_PROPERTY_OSGI_CONSOLE, "2403");
+
+ setUserConfiguredUserRegionProperties(frameworkConfig);
+
+ if (this.regionInheritedProperties != null) {
+ String[] inheritedProperties = this.regionInheritedProperties.split(",");
+ for (String property : inheritedProperties) {
+ propagatePropertyToUserRegion(frameworkConfig, property);
+ }
+ }
+
+ String userRegionImportsProperty = this.bundleContext.getProperty(USER_REGION_PROPERTIES_PROPERTY);
+ if (userRegionImportsProperty != null) {
+ for (String property : userRegionImportsProperty.split(",")) {
+ propagatePropertyToUserRegion(frameworkConfig, property);
+ }
+ }
+
+ return frameworkConfig;
+ }
+
+ private void setUserConfiguredUserRegionProperties(HashMap<String, String> frameworkConfig) {
+ if (this.userRegionProperties != null) {
+ Enumeration<String> keys = this.userRegionProperties.keys();
+ while (keys.hasMoreElements()) {
+ String propertyName = keys.nextElement();
+ String propertyValue = this.userRegionProperties.get(propertyName);
+ frameworkConfig.put(propertyName, propertyValue);
+ }
+ }
+ }
+
+ private void propagatePropertyToUserRegion(HashMap<String, String> frameworkConfig, String propertyName) {
+ String propertyValue = this.bundleContext.getProperty(propertyName);
+ if (propertyValue != null) {
+ frameworkConfig.put(propertyName, propertyValue);
+ }
+ }
+
+ private Map<String, String> createCompositeBundleManifest() {
+ Map<String, String> compositeManifest = new HashMap<String, String>();
+
+ compositeManifest.put(Constants.BUNDLE_SYMBOLICNAME, REGION_USER);
+
+ String userRegionImportsProperty = this.regionImports != null ? this.regionImports
+ : this.bundleContext.getProperty(USER_REGION_PACKAGE_IMPORTS_PROPERTY);
+ if (userRegionImportsProperty != null) {
+ String expandedUserRegionImportsProperty = PackageImportWildcardExpander.expandPackageImportsWildcards(userRegionImportsProperty,
+ this.bundleContext);
+ compositeManifest.put(Constants.IMPORT_PACKAGE, expandedUserRegionImportsProperty);
+ }
+
+ configureServiceImportFilter(compositeManifest);
+ configureServiceExportFilter(compositeManifest);
+
+ return compositeManifest;
+ }
+
+ private void configureServiceImportFilter(Map<String, String> compositeManifest) {
+ String[] serviceImports = splitServices(this.regionServiceImports);
+ if (serviceImports != null) {
+ compositeManifest.put(CompositeBundleFactory.COMPOSITE_SERVICE_FILTER_IMPORT, createObjectClassesServiceFilter(serviceImports));
+ }
+ }
+
+ private void configureServiceExportFilter(Map<String, String> compositeManifest) {
+ String[] serviceExports = splitServices(this.regionServiceExports);
+ if (serviceExports != null) {
+ compositeManifest.put(CompositeBundleFactory.COMPOSITE_SERVICE_FILTER_EXPORT, createObjectClassesServiceFilter(serviceExports));
+ }
+ }
+
+ private String[] splitServices(String serviceString) {
+ String[] services = null;
+ if (serviceString != null) {
+ services = serviceString.split(",");
+ }
+ return services;
+ }
+
+ private String createObjectClassesServiceFilter(String[] serviceClassNames) {
+ StringBuffer importFilter = new StringBuffer();
+ importFilter.append("(|");
+ for (String className : serviceClassNames) {
+ importFilter.append(createObjectClassFilter(className));
+ }
+ importFilter.append(")");
+ return importFilter.toString();
+ }
+
+ private String createObjectClassFilter(String className) {
+ return "(objectClass=" + className + ")";
+ }
+
+ private void initialiseUserRegionBundles(BundleContext surrogateBundleContext) throws BundleException {
+ String userRegionBundlesProperty = this.regionBundles != null ? this.regionBundles
+ : this.bundleContext.getProperty(USER_REGION_BASE_BUNDLES_PROPERTY);
+
+ if (userRegionBundlesProperty != null) {
+ List<Bundle> bundlesToStart = new ArrayList<Bundle>();
+
+ for (BundleEntry entry : this.parser.parseBundleEntries(userRegionBundlesProperty)) {
+ Bundle bundle = surrogateBundleContext.installBundle(entry.getURI().toString());
+
+ if (entry.isAutoStart()) {
+ bundlesToStart.add(bundle);
+ }
+ }
+
+ for (Bundle bundle : bundlesToStart) {
+ try {
+ bundle.start();
+ } catch (BundleException e) {
+ throw new BundleException("Failed to start bundle " + bundle.getSymbolicName() + " " + bundle.getVersion(), e);
+ }
+ }
+
+ }
+ }
+
+ private void registerRegionService(Region region) {
+ Properties props = new Properties();
+ props.setProperty("org.eclipse.virgo.kernel.region.name", region.getName());
+ this.tracker.track(this.bundleContext.registerService(Region.class.getName(), region, props));
+ }
+
+ /**
+ * @throws BundleException
+ * @throws InterruptedException
+ */
+ public void stop() throws BundleException, InterruptedException {
+ this.tracker.unregisterAll();
+ }
+
+ private static class ImmutableRegion implements Region {
+
+ private final String name;
+
+ private final BundleContext bundleContext;
+
+ public ImmutableRegion(String name, BundleContext bundleContext) {
+ this.name = name;
+ this.bundleContext = bundleContext;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public BundleContext getBundleContext() {
+ return this.bundleContext;
+ }
+
+ }
+}
diff --git a/org.eclipse.virgo.kernel.osgi/src/main/java/org/eclipse/virgo/kernel/osgi/region/RegionManagerParserLogger.java b/org.eclipse.virgo.kernel.osgi/src/main/java/org/eclipse/virgo/kernel/osgi/region/RegionManagerParserLogger.java
new file mode 100644
index 00000000..bb25f6a6
--- /dev/null
+++ b/org.eclipse.virgo.kernel.osgi/src/main/java/org/eclipse/virgo/kernel/osgi/region/RegionManagerParserLogger.java
@@ -0,0 +1,42 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2010 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.virgo.kernel.osgi.region;
+
+import org.eclipse.virgo.kernel.osgi.framework.OsgiFrameworkLogEvents;
+import org.eclipse.virgo.medic.eventlog.EventLogger;
+import org.eclipse.virgo.util.osgi.manifest.parse.ParserLogger;
+
+/**
+ * {@link RegionManagerParserLogger} maps OSGi bundle manifest parsing errors to a log message.
+ * <p />
+ *
+ * <strong>Concurrent Semantics</strong><br />
+ *
+ * This class is thread safe.
+ *
+ */
+final class RegionManagerParserLogger implements ParserLogger {
+
+ private final EventLogger eventLogger;
+
+ public RegionManagerParserLogger(EventLogger eventLogger) {
+ this.eventLogger = eventLogger;
+ }
+
+ public String[] errorReports() {
+ return new String[0];
+ }
+
+ public void outputErrorMsg(Exception re, String item) {
+ this.eventLogger.log(OsgiFrameworkLogEvents.REGION_IMPORTS_PARSE_FAILED, re, item);
+ }
+}
diff --git a/org.eclipse.virgo.kernel.osgi/src/main/java/org/eclipse/virgo/kernel/osgi/region/eventlog/RegionAwareEventLoggerServiceFactory.java b/org.eclipse.virgo.kernel.osgi/src/main/java/org/eclipse/virgo/kernel/osgi/region/eventlog/RegionAwareEventLoggerServiceFactory.java
new file mode 100644
index 00000000..e2d291d5
--- /dev/null
+++ b/org.eclipse.virgo.kernel.osgi/src/main/java/org/eclipse/virgo/kernel/osgi/region/eventlog/RegionAwareEventLoggerServiceFactory.java
@@ -0,0 +1,55 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2010 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.virgo.kernel.osgi.region.eventlog;
+
+import org.osgi.framework.Bundle;
+import org.osgi.framework.ServiceFactory;
+import org.osgi.framework.ServiceRegistration;
+
+import org.eclipse.virgo.medic.eventlog.EventLoggerFactory;
+
+/**
+ * RegionAwareEventLoggerServiceFactory is a {@link ServiceFactory} for
+ * {@link EventLogger} instances in the user region. Medic's default ServiceFactory
+ * cannot be used due to the nested framework service-sharing mechnism which
+ * causes the wrong {@link Bundle} to be passed to {@link #getService(Bundle, ServiceRegistration)}
+ * <p />
+ *
+ * <strong>Concurrent Semantics</strong><br />
+ *
+ * Thread-safe.
+ *
+ */
+final class RegionAwareEventLoggerServiceFactory implements ServiceFactory {
+
+ private final EventLoggerFactory eventLoggerFactory;
+
+ /**
+ * @param eventLoggerFactory
+ */
+ public RegionAwareEventLoggerServiceFactory(EventLoggerFactory eventLoggerFactory) {
+ this.eventLoggerFactory = eventLoggerFactory;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public Object getService(Bundle bundle, ServiceRegistration registration) {
+ return this.eventLoggerFactory.createEventLogger(bundle);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void ungetService(Bundle bundle, ServiceRegistration registration, Object service) {
+ }
+}
diff --git a/org.eclipse.virgo.kernel.osgi/src/main/resources/EventLogMessages.properties b/org.eclipse.virgo.kernel.osgi/src/main/resources/EventLogMessages.properties
new file mode 100644
index 00000000..2f83e146
--- /dev/null
+++ b/org.eclipse.virgo.kernel.osgi/src/main/resources/EventLogMessages.properties
@@ -0,0 +1,7 @@
+#OSGI
+OF0001E=Region imports parsing failed: {}.
+OF0002W=No match found for region import: {}.
+#OF0003W Moved to the userregion bundle
+#OF0004W Moved to the userregion bundle
+OF0100I=OSGi telnet console available on port {}.
+OF0101E=Unable to start OSGi telnet console. Port {} is in use.
diff --git a/org.eclipse.virgo.kernel.osgi/src/main/resources/META-INF/spring/configuration-context.xml b/org.eclipse.virgo.kernel.osgi/src/main/resources/META-INF/spring/configuration-context.xml
new file mode 100644
index 00000000..17e5153a
--- /dev/null
+++ b/org.eclipse.virgo.kernel.osgi/src/main/resources/META-INF/spring/configuration-context.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<beans xmlns="http://www.springframework.org/schema/beans"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns:osgi="http://www.springframework.org/schema/osgi"
+ xmlns:context="http://www.springframework.org/schema/context"
+ xmlns:osgi-compendium="http://www.springframework.org/schema/osgi-compendium"
+ xsi:schemaLocation="http://www.springframework.org/schema/osgi http://www.springframework.org/schema/osgi/spring-osgi-1.2.xsd
+ http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
+ http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
+ http://www.springframework.org/schema/osgi-compendium http://www.springframework.org/schema/osgi-compendium/spring-osgi-compendium-1.2.xsd">
+
+ <osgi-compendium:cm-properties id="kernelConfig" persistent-id="org.eclipse.virgo.kernel"/>
+
+ <context:property-placeholder properties-ref="kernelConfig"/>
+
+</beans>
diff --git a/org.eclipse.virgo.kernel.osgi/src/main/resources/META-INF/spring/internal-osgi-context.xml b/org.eclipse.virgo.kernel.osgi/src/main/resources/META-INF/spring/internal-osgi-context.xml
new file mode 100644
index 00000000..994bc253
--- /dev/null
+++ b/org.eclipse.virgo.kernel.osgi/src/main/resources/META-INF/spring/internal-osgi-context.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<beans xmlns="http://www.springframework.org/schema/beans"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:osgi="http://www.springframework.org/schema/osgi"
+ xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
+ http://www.springframework.org/schema/osgi http://www.springframework.org/schema/osgi/spring-osgi-1.2.xsd">
+
+ <!--
+ Configuration for OSGi services that the kernel depends on and
+ provides to the framework. These services are not considered part of
+ the kernel API.
+ -->
+
+ <osgi:reference id="eventLogger"
+ interface="org.eclipse.virgo.medic.eventlog.EventLogger" />
+
+ <osgi:reference id="packageAdmin"
+ interface="org.osgi.service.packageadmin.PackageAdmin" />
+
+ <osgi:reference id="repository"
+ interface="org.eclipse.virgo.repository.Repository" />
+
+ <osgi:reference id="compositeBundleFactory"
+ interface="org.osgi.service.framework.CompositeBundleFactory" />
+
+ <osgi:reference id="eventAdmin" interface="org.osgi.service.event.EventAdmin" />
+
+ <osgi:reference id="configAdmin"
+ interface="org.osgi.service.cm.ConfigurationAdmin" />
+
+ <osgi:reference id="eventLoggerFactory"
+ interface="org.eclipse.virgo.medic.eventlog.EventLoggerFactory" />
+
+</beans>
diff --git a/org.eclipse.virgo.kernel.osgi/src/main/resources/META-INF/spring/osgi-framework-context.xml b/org.eclipse.virgo.kernel.osgi/src/main/resources/META-INF/spring/osgi-framework-context.xml
new file mode 100644
index 00000000..2eb7c867
--- /dev/null
+++ b/org.eclipse.virgo.kernel.osgi/src/main/resources/META-INF/spring/osgi-framework-context.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<beans xmlns="http://www.springframework.org/schema/beans"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
+
+ <bean class="org.eclipse.virgo.kernel.osgi.region.RegionManager" init-method="start" destroy-method="stop">
+ <constructor-arg ref="bundleContext"/>
+ <constructor-arg ref="compositeBundleFactory"/>
+ <constructor-arg ref="eventAdmin"/>
+ <constructor-arg>
+ <bean class="org.eclipse.virgo.kernel.osgi.region.eventlog.RegionAwareEventLoggerServiceFactory">
+ <constructor-arg ref="eventLoggerFactory"/>
+ </bean>
+ </constructor-arg>
+ <constructor-arg ref="configAdmin"/>
+ </bean>
+
+</beans>
diff --git a/org.eclipse.virgo.kernel.osgi/src/test/java/.gitignore b/org.eclipse.virgo.kernel.osgi/src/test/java/.gitignore
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/org.eclipse.virgo.kernel.osgi/src/test/java/.gitignore
diff --git a/org.eclipse.virgo.kernel.osgi/src/test/java/org/eclipse/virgo/kernel/osgi/common/VersionTests.java b/org.eclipse.virgo.kernel.osgi/src/test/java/org/eclipse/virgo/kernel/osgi/common/VersionTests.java
new file mode 100644
index 00000000..d496ff89
--- /dev/null
+++ b/org.eclipse.virgo.kernel.osgi/src/test/java/org/eclipse/virgo/kernel/osgi/common/VersionTests.java
@@ -0,0 +1,66 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2010 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.virgo.kernel.osgi.common;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.virgo.kernel.osgi.common.Version;
+import org.junit.Assert;
+import org.junit.Test;
+
+public class VersionTests {
+
+ @Test public void normal() {
+ Version v1 = new Version("1");
+ Version v10 = new Version("1.0");
+ Assert.assertEquals(v1, v10);
+ Version v101 = new Version("1.0.1");
+ Assert.assertEquals(0, v1.compareTo(v10));
+ Assert.assertEquals(-1, v1.compareTo(v101));
+ Assert.assertEquals(1, v101.compareTo(v10));
+ }
+
+ @Test public void edgeCases() {
+
+ Assert.assertEquals(0, (new Version("0")).compareTo(new Version("")));
+ Assert.assertEquals(0, (new Version("0")).compareTo(new Version((String) null)));
+
+ try {
+ @SuppressWarnings("unused") Version v2 = new Version(".");
+ Assert.assertTrue(false);
+ } catch (NumberFormatException e) {
+ }
+ try {
+ @SuppressWarnings("unused") Version v3 = new Version("0-0");
+ Assert.assertTrue(false);
+ } catch (NumberFormatException e) {
+ }
+
+ try {
+ @SuppressWarnings("unused") Version v4 = new Version("1.-3.5");
+ Assert.assertTrue(false);
+ } catch (IllegalArgumentException e) {
+ }
+ }
+
+ @Test public void listConstructor() {
+ Version v102 = new Version("1.0.2");
+ List<Integer> comps = new ArrayList<Integer>();
+ comps.add(1);
+ comps.add(0);
+ comps.add(2);
+ Version v102a = new Version(comps);
+ Assert.assertEquals(0, v102.compareTo(v102a));
+ }
+
+}
diff --git a/org.eclipse.virgo.kernel.osgi/src/test/java/org/eclipse/virgo/kernel/osgi/region/PackageImportWildcardExpanderTests.java b/org.eclipse.virgo.kernel.osgi/src/test/java/org/eclipse/virgo/kernel/osgi/region/PackageImportWildcardExpanderTests.java
new file mode 100644
index 00000000..9e3105b3
--- /dev/null
+++ b/org.eclipse.virgo.kernel.osgi/src/test/java/org/eclipse/virgo/kernel/osgi/region/PackageImportWildcardExpanderTests.java
@@ -0,0 +1,76 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2010 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.virgo.kernel.osgi.region;
+
+import static org.easymock.EasyMock.createMock;
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.replay;
+import static org.junit.Assert.assertEquals;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.osgi.framework.Bundle;
+import org.osgi.service.packageadmin.ExportedPackage;
+import org.osgi.service.packageadmin.PackageAdmin;
+
+import org.eclipse.virgo.kernel.osgi.region.PackageImportWildcardExpander;
+import org.eclipse.virgo.medic.eventlog.EventLogger;
+import org.eclipse.virgo.teststubs.osgi.framework.StubBundleContext;
+
+/**
+ */
+public class PackageImportWildcardExpanderTests {
+
+ private StubBundleContext stubBundleContext;
+
+ private EventLogger mockEventLogger;
+
+ private PackageAdmin mockPackageAdmin;
+
+ private ExportedPackage[] exportedPackages;
+
+ @Before
+ public void setUp() throws Exception {
+ this.stubBundleContext = new StubBundleContext();
+
+ this.mockEventLogger = createMock(EventLogger.class);
+ replay(this.mockEventLogger);
+ this.stubBundleContext.registerService(EventLogger.class.getName(), this.mockEventLogger, null);
+
+ this.mockPackageAdmin = createMock(PackageAdmin.class);
+ this.exportedPackages = new ExportedPackage[] { createdMockExportedPackage("q"), createdMockExportedPackage("r.a"),
+ createdMockExportedPackage("r.b.c") };
+ expect(this.mockPackageAdmin.getExportedPackages((Bundle) null)).andReturn(this.exportedPackages);
+ replay(this.mockPackageAdmin);
+ this.stubBundleContext.registerService(PackageAdmin.class.getName(), this.mockPackageAdmin, null);
+ }
+
+ private ExportedPackage createdMockExportedPackage(String packageName) {
+ ExportedPackage pkg = createMock(ExportedPackage.class);
+ expect(pkg.getName()).andReturn(packageName);
+ replay(pkg);
+ return pkg;
+ }
+
+ @Test
+ public void testNoWildcards() {
+ String expansion = PackageImportWildcardExpander.expandPackageImportsWildcards("p,r", this.stubBundleContext);
+ assertEquals("Incorrect expansion", "p,r", expansion);
+ }
+
+ @Test
+ public void testWildcards() {
+ String expansion = PackageImportWildcardExpander.expandPackageImportsWildcards("r.*", this.stubBundleContext);
+ assertEquals("Incorrect expansion", "r.a,r.b.c", expansion);
+ }
+
+}
diff --git a/org.eclipse.virgo.kernel.osgi/src/test/java/org/eclipse/virgo/kernel/osgi/region/RegionManagerTests.java b/org.eclipse.virgo.kernel.osgi/src/test/java/org/eclipse/virgo/kernel/osgi/region/RegionManagerTests.java
new file mode 100644
index 00000000..c6ec9bde
--- /dev/null
+++ b/org.eclipse.virgo.kernel.osgi/src/test/java/org/eclipse/virgo/kernel/osgi/region/RegionManagerTests.java
@@ -0,0 +1,86 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2010 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.virgo.kernel.osgi.region;
+
+import static org.easymock.EasyMock.createMock;
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.isA;
+import static org.easymock.EasyMock.replay;
+import static org.easymock.EasyMock.verify;
+import static org.junit.Assert.assertEquals;
+
+import java.util.Dictionary;
+import java.util.Hashtable;
+import java.util.List;
+import java.util.Map;
+
+import org.junit.Test;
+import org.osgi.framework.ServiceFactory;
+import org.osgi.framework.launch.Framework;
+import org.osgi.service.cm.Configuration;
+import org.osgi.service.cm.ConfigurationAdmin;
+import org.osgi.service.event.Event;
+import org.osgi.service.event.EventAdmin;
+import org.osgi.service.framework.CompositeBundle;
+import org.osgi.service.framework.CompositeBundleFactory;
+import org.osgi.service.framework.SurrogateBundle;
+
+import org.eclipse.virgo.kernel.osgi.region.RegionManager;
+import org.eclipse.virgo.teststubs.osgi.framework.StubBundleContext;
+import org.eclipse.virgo.teststubs.osgi.framework.StubServiceRegistration;
+
+/**
+ */
+@SuppressWarnings("deprecation")
+public class RegionManagerTests {
+
+ @Test
+ public void testStartAndStop() throws Exception {
+ StubBundleContext bundleContext = new StubBundleContext();
+ StubBundleContext surrogateBundleContext = new StubBundleContext();
+
+ Framework user = createMock(Framework.class);
+ SurrogateBundle surrogate = createMock(SurrogateBundle.class);
+ ServiceFactory serviceFactory = createMock(ServiceFactory.class);
+
+ CompositeBundleFactory factory = createMock(CompositeBundleFactory.class);
+ CompositeBundle bundle = createMock(CompositeBundle.class);
+
+ expect(factory.installCompositeBundle(isA(Map.class), isA(String.class), isA(Map.class))).andReturn(bundle);
+ expect(bundle.getCompositeFramework()).andReturn(user);
+ bundle.start();
+ expect(bundle.getSurrogateBundle()).andReturn(surrogate);
+
+ expect(surrogate.getBundleContext()).andReturn(surrogateBundleContext);
+
+ EventAdmin eventAdmin = createMock(EventAdmin.class);
+ eventAdmin.sendEvent(isA(Event.class));
+
+ Dictionary<String, String> properties = new Hashtable<String, String>();
+ Configuration config = createMock(Configuration.class);
+ expect(config.getProperties()).andReturn(properties);
+
+ ConfigurationAdmin configAdmin = createMock(ConfigurationAdmin.class);
+ expect(configAdmin.getConfiguration(isA(String.class))).andReturn(config);
+
+ replay(factory, bundle, surrogate, eventAdmin, configAdmin, config);
+ RegionManager manager = new RegionManager(bundleContext, factory, eventAdmin, serviceFactory, configAdmin);
+ manager.start();
+
+ List<StubServiceRegistration> serviceRegistrations = bundleContext.getServiceRegistrations();
+ assertEquals("Regions not registered", 2, serviceRegistrations.size());
+
+ manager.stop();
+ verify(factory, bundle, surrogate, eventAdmin, configAdmin, config);
+
+ }
+}
diff --git a/org.eclipse.virgo.kernel.osgi/src/test/resources/.gitignore b/org.eclipse.virgo.kernel.osgi/src/test/resources/.gitignore
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/org.eclipse.virgo.kernel.osgi/src/test/resources/.gitignore
diff --git a/org.eclipse.virgo.kernel.osgi/src/test/resources/com/springsource/kernel/osgi/provisioning/tools/IMPORTBUNDLE.MF b/org.eclipse.virgo.kernel.osgi/src/test/resources/com/springsource/kernel/osgi/provisioning/tools/IMPORTBUNDLE.MF
new file mode 100644
index 00000000..0d4f08c4
--- /dev/null
+++ b/org.eclipse.virgo.kernel.osgi/src/test/resources/com/springsource/kernel/osgi/provisioning/tools/IMPORTBUNDLE.MF
@@ -0,0 +1,3 @@
+Import-Bundle: org.springframework.core;version="2.5.3",
+ org.springframework.beans;version="2.5.3",
+ org.springframework.context;version="2.5.3"
diff --git a/org.eclipse.virgo.kernel.osgi/src/test/resources/com/springsource/kernel/osgi/provisioning/tools/IMPORTLIBRARY.MF b/org.eclipse.virgo.kernel.osgi/src/test/resources/com/springsource/kernel/osgi/provisioning/tools/IMPORTLIBRARY.MF
new file mode 100644
index 00000000..b7541d03
--- /dev/null
+++ b/org.eclipse.virgo.kernel.osgi/src/test/resources/com/springsource/kernel/osgi/provisioning/tools/IMPORTLIBRARY.MF
@@ -0,0 +1 @@
+Import-Library: org.springframework_spring;version="2.5.3"
diff --git a/org.eclipse.virgo.kernel.osgi/src/test/resources/com/springsource/kernel/osgi/provisioning/tools/IMPORTPACKAGE.MF b/org.eclipse.virgo.kernel.osgi/src/test/resources/com/springsource/kernel/osgi/provisioning/tools/IMPORTPACKAGE.MF
new file mode 100644
index 00000000..0479f8c8
--- /dev/null
+++ b/org.eclipse.virgo.kernel.osgi/src/test/resources/com/springsource/kernel/osgi/provisioning/tools/IMPORTPACKAGE.MF
@@ -0,0 +1 @@
+Import-Package: org.springframework.beans;version=2.5.4,org.springframework.context;version=2.5.4,org.springframework.beans.factory;version=2.5.4
diff --git a/org.eclipse.virgo.kernel.osgi/src/test/resources/com/springsource/kernel/osgi/provisioning/tools/IMPORTSYSTEMPACKAGES.MF b/org.eclipse.virgo.kernel.osgi/src/test/resources/com/springsource/kernel/osgi/provisioning/tools/IMPORTSYSTEMPACKAGES.MF
new file mode 100644
index 00000000..3c12faf0
--- /dev/null
+++ b/org.eclipse.virgo.kernel.osgi/src/test/resources/com/springsource/kernel/osgi/provisioning/tools/IMPORTSYSTEMPACKAGES.MF
@@ -0,0 +1,4 @@
+Import-Package: javax.sql,
+ javax.transaction,
+ org.apache.commons.logging;version="[1.1.1,1.1.1]";resolution:=optional,
+ org.osgi.framework
diff --git a/org.eclipse.virgo.kernel.osgi/src/test/resources/com/springsource/kernel/osgi/provisioning/tools/IMPORTSYSTEMPACKAGESJAVA6.MF b/org.eclipse.virgo.kernel.osgi/src/test/resources/com/springsource/kernel/osgi/provisioning/tools/IMPORTSYSTEMPACKAGESJAVA6.MF
new file mode 100644
index 00000000..c25826a5
--- /dev/null
+++ b/org.eclipse.virgo.kernel.osgi/src/test/resources/com/springsource/kernel/osgi/provisioning/tools/IMPORTSYSTEMPACKAGESJAVA6.MF
@@ -0,0 +1 @@
+Import-Package: javax.xml.soap
diff --git a/org.eclipse.virgo.kernel.osgi/src/test/resources/com/springsource/kernel/osgi/provisioning/tools/REQUIREBUNDLE.MF b/org.eclipse.virgo.kernel.osgi/src/test/resources/com/springsource/kernel/osgi/provisioning/tools/REQUIREBUNDLE.MF
new file mode 100644
index 00000000..b8048c05
--- /dev/null
+++ b/org.eclipse.virgo.kernel.osgi/src/test/resources/com/springsource/kernel/osgi/provisioning/tools/REQUIREBUNDLE.MF
@@ -0,0 +1,2 @@
+Require-Bundle: org.springframework.core;version="[2.5.4, 2.6.0)"
+Import-Package: org.springframework.core;version="2.5.4"
diff --git a/org.eclipse.virgo.kernel.osgi/src/test/resources/com/springsource/kernel/osgi/provisioning/tools/SATISFIABLEANDUNSATISFIABLE.MF b/org.eclipse.virgo.kernel.osgi/src/test/resources/com/springsource/kernel/osgi/provisioning/tools/SATISFIABLEANDUNSATISFIABLE.MF
new file mode 100644
index 00000000..d804f6dc
--- /dev/null
+++ b/org.eclipse.virgo.kernel.osgi/src/test/resources/com/springsource/kernel/osgi/provisioning/tools/SATISFIABLEANDUNSATISFIABLE.MF
@@ -0,0 +1,2 @@
+Import-Library: org.springframework_spring;version="[2.5.3,2.5.3]"
+Require-Bundle: com.foo
diff --git a/org.eclipse.virgo.kernel.osgi/src/test/resources/com/springsource/kernel/osgi/provisioning/tools/UNSATISFIABLEIMPORTBUNDLE.MF b/org.eclipse.virgo.kernel.osgi/src/test/resources/com/springsource/kernel/osgi/provisioning/tools/UNSATISFIABLEIMPORTBUNDLE.MF
new file mode 100644
index 00000000..4f6ab98e
--- /dev/null
+++ b/org.eclipse.virgo.kernel.osgi/src/test/resources/com/springsource/kernel/osgi/provisioning/tools/UNSATISFIABLEIMPORTBUNDLE.MF
@@ -0,0 +1 @@
+Import-Bundle: com.foo, com.bar
diff --git a/org.eclipse.virgo.kernel.osgi/src/test/resources/com/springsource/kernel/osgi/provisioning/tools/UNSATISFIABLEIMPORTLIBRARY.MF b/org.eclipse.virgo.kernel.osgi/src/test/resources/com/springsource/kernel/osgi/provisioning/tools/UNSATISFIABLEIMPORTLIBRARY.MF
new file mode 100644
index 00000000..645a4a84
--- /dev/null
+++ b/org.eclipse.virgo.kernel.osgi/src/test/resources/com/springsource/kernel/osgi/provisioning/tools/UNSATISFIABLEIMPORTLIBRARY.MF
@@ -0,0 +1 @@
+Import-Library: com.foo.bar
diff --git a/org.eclipse.virgo.kernel.osgi/src/test/resources/com/springsource/kernel/osgi/provisioning/tools/UNSATISFIABLEIMPORTPACKAGE.MF b/org.eclipse.virgo.kernel.osgi/src/test/resources/com/springsource/kernel/osgi/provisioning/tools/UNSATISFIABLEIMPORTPACKAGE.MF
new file mode 100644
index 00000000..4bd54a5c
--- /dev/null
+++ b/org.eclipse.virgo.kernel.osgi/src/test/resources/com/springsource/kernel/osgi/provisioning/tools/UNSATISFIABLEIMPORTPACKAGE.MF
@@ -0,0 +1 @@
+Import-Package: com.foo.bar
diff --git a/org.eclipse.virgo.kernel.osgi/src/test/resources/com/springsource/kernel/osgi/provisioning/tools/UNSATISFIABLEREQUIREBUNDLE.MF b/org.eclipse.virgo.kernel.osgi/src/test/resources/com/springsource/kernel/osgi/provisioning/tools/UNSATISFIABLEREQUIREBUNDLE.MF
new file mode 100644
index 00000000..07dc36e5
--- /dev/null
+++ b/org.eclipse.virgo.kernel.osgi/src/test/resources/com/springsource/kernel/osgi/provisioning/tools/UNSATISFIABLEREQUIREBUNDLE.MF
@@ -0,0 +1 @@
+Require-Bundle: com.foo.bar
diff --git a/org.eclipse.virgo.kernel.osgi/src/test/resources/com/springsource/kernel/osgi/provisioning/tools/org.springframework_spring_2.5.3.libd b/org.eclipse.virgo.kernel.osgi/src/test/resources/com/springsource/kernel/osgi/provisioning/tools/org.springframework_spring_2.5.3.libd
new file mode 100644
index 00000000..dd7f6776
--- /dev/null
+++ b/org.eclipse.virgo.kernel.osgi/src/test/resources/com/springsource/kernel/osgi/provisioning/tools/org.springframework_spring_2.5.3.libd
@@ -0,0 +1,5 @@
+Library-SymbolicName: org.springframework_spring
+Library-Version: 2.5.3
+Import-Bundle: org.springframework.core;version="2.5.3",
+ org.springframework.beans;version="2.5.3",
+ org.springframework.context;version="2.5.3" \ No newline at end of file

Back to the top