Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'org.eclipse.virgo.kernel.model')
-rw-r--r--org.eclipse.virgo.kernel.model/.classpath46
-rw-r--r--org.eclipse.virgo.kernel.model/.project42
-rw-r--r--org.eclipse.virgo.kernel.model/.settings/com.cenqua.clover.core.prefs21
-rw-r--r--org.eclipse.virgo.kernel.model/.settings/com.springsource.server.ide.bundlor.core.prefs3
-rw-r--r--org.eclipse.virgo.kernel.model/.settings/org.eclipse.jdt.core.prefs70
-rw-r--r--org.eclipse.virgo.kernel.model/.settings/org.eclipse.wst.common.project.facet.core.xml4
-rw-r--r--org.eclipse.virgo.kernel.model/.settings/org.springframework.ide.eclipse.beans.core.prefs3
-rw-r--r--org.eclipse.virgo.kernel.model/.springBeans13
-rw-r--r--org.eclipse.virgo.kernel.model/build.xml8
-rw-r--r--org.eclipse.virgo.kernel.model/ivy.xml37
-rw-r--r--org.eclipse.virgo.kernel.model/src/main/java/org/eclipse/virgo/kernel/model/Artifact.java96
-rw-r--r--org.eclipse.virgo.kernel.model/src/main/java/org/eclipse/virgo/kernel/model/ArtifactState.java35
-rw-r--r--org.eclipse.virgo.kernel.model/src/main/java/org/eclipse/virgo/kernel/model/BundleArtifact.java42
-rw-r--r--org.eclipse.virgo.kernel.model/src/main/java/org/eclipse/virgo/kernel/model/CompositeArtifact.java41
-rw-r--r--org.eclipse.virgo.kernel.model/src/main/java/org/eclipse/virgo/kernel/model/RuntimeArtifactRepository.java68
-rw-r--r--org.eclipse.virgo.kernel.model/src/main/java/org/eclipse/virgo/kernel/model/internal/AbstractArtifact.java158
-rw-r--r--org.eclipse.virgo.kernel.model/src/main/java/org/eclipse/virgo/kernel/model/internal/ArtifactRepositoryListener.java41
-rw-r--r--org.eclipse.virgo.kernel.model/src/main/java/org/eclipse/virgo/kernel/model/internal/DependencyDeterminer.java42
-rw-r--r--org.eclipse.virgo.kernel.model/src/main/java/org/eclipse/virgo/kernel/model/internal/NotifyingRuntimeArtifactRepository.java113
-rw-r--r--org.eclipse.virgo.kernel.model/src/main/java/org/eclipse/virgo/kernel/model/internal/bundle/BundleArtifact.java130
-rw-r--r--org.eclipse.virgo.kernel.model/src/main/java/org/eclipse/virgo/kernel/model/internal/bundle/BundleDependencyDeterminer.java81
-rw-r--r--org.eclipse.virgo.kernel.model/src/main/java/org/eclipse/virgo/kernel/model/internal/bundle/ModelBundleListener.java77
-rw-r--r--org.eclipse.virgo.kernel.model/src/main/java/org/eclipse/virgo/kernel/model/internal/bundle/ModelBundleListenerInitializer.java85
-rw-r--r--org.eclipse.virgo.kernel.model/src/main/java/org/eclipse/virgo/kernel/model/internal/configurationadmin/ConfigurationArtifact.java92
-rw-r--r--org.eclipse.virgo.kernel.model/src/main/java/org/eclipse/virgo/kernel/model/internal/configurationadmin/ModelConfigurationListener.java83
-rw-r--r--org.eclipse.virgo.kernel.model/src/main/java/org/eclipse/virgo/kernel/model/internal/configurationadmin/ModelConfigurationListenerInitializer.java92
-rw-r--r--org.eclipse.virgo.kernel.model/src/main/java/org/eclipse/virgo/kernel/model/internal/deployer/DeployerArtifact.java148
-rw-r--r--org.eclipse.virgo.kernel.model/src/main/java/org/eclipse/virgo/kernel/model/internal/deployer/DeployerBundleArtifact.java40
-rw-r--r--org.eclipse.virgo.kernel.model/src/main/java/org/eclipse/virgo/kernel/model/internal/deployer/DeployerCompositeArtifact.java60
-rw-r--r--org.eclipse.virgo.kernel.model/src/main/java/org/eclipse/virgo/kernel/model/internal/deployer/DeployerCompositeArtifactDependencyDeterminer.java63
-rw-r--r--org.eclipse.virgo.kernel.model/src/main/java/org/eclipse/virgo/kernel/model/internal/deployer/ModelInstallArtifactLifecycleListener.java117
-rw-r--r--org.eclipse.virgo.kernel.model/src/main/java/org/eclipse/virgo/kernel/model/internal/deployer/ModelInstallArtifactLifecycleListenerInitializer.java94
-rw-r--r--org.eclipse.virgo.kernel.model/src/main/java/org/eclipse/virgo/kernel/model/management/InstallException.java35
-rw-r--r--org.eclipse.virgo.kernel.model/src/main/java/org/eclipse/virgo/kernel/model/management/Installer.java38
-rw-r--r--org.eclipse.virgo.kernel.model/src/main/java/org/eclipse/virgo/kernel/model/management/ManageableArtifact.java98
-rw-r--r--org.eclipse.virgo.kernel.model/src/main/java/org/eclipse/virgo/kernel/model/management/ManageableBundleArtifact.java45
-rw-r--r--org.eclipse.virgo.kernel.model/src/main/java/org/eclipse/virgo/kernel/model/management/ManageableCompositeArtifact.java44
-rw-r--r--org.eclipse.virgo.kernel.model/src/main/java/org/eclipse/virgo/kernel/model/management/RuntimeArtifactModelObjectNameCreator.java102
-rw-r--r--org.eclipse.virgo.kernel.model/src/main/java/org/eclipse/virgo/kernel/model/management/internal/DefaultRuntimeArtifactModelObjectNameCreator.java121
-rw-r--r--org.eclipse.virgo.kernel.model/src/main/java/org/eclipse/virgo/kernel/model/management/internal/DelegatingInstaller.java58
-rw-r--r--org.eclipse.virgo.kernel.model/src/main/java/org/eclipse/virgo/kernel/model/management/internal/DelegatingManageableArtifact.java131
-rw-r--r--org.eclipse.virgo.kernel.model/src/main/java/org/eclipse/virgo/kernel/model/management/internal/DelegatingManageableBundleArtifact.java49
-rw-r--r--org.eclipse.virgo.kernel.model/src/main/java/org/eclipse/virgo/kernel/model/management/internal/DelegatingManageableCompositeArtifact.java54
-rw-r--r--org.eclipse.virgo.kernel.model/src/main/java/org/eclipse/virgo/kernel/model/management/internal/JmxArtifactRepositoryListener.java108
-rw-r--r--org.eclipse.virgo.kernel.model/src/main/resources/META-INF/spring/module-context.xml75
-rw-r--r--org.eclipse.virgo.kernel.model/src/main/resources/META-INF/spring/osgi-context.xml48
-rw-r--r--org.eclipse.virgo.kernel.model/src/test/java/org/eclipse/virgo/kernel/model/StubArtifactRepository.java45
-rw-r--r--org.eclipse.virgo.kernel.model/src/test/java/org/eclipse/virgo/kernel/model/StubCompositeArtifact.java72
-rw-r--r--org.eclipse.virgo.kernel.model/src/test/java/org/eclipse/virgo/kernel/model/internal/AbztractArtifactTests.java151
-rw-r--r--org.eclipse.virgo.kernel.model/src/test/java/org/eclipse/virgo/kernel/model/internal/NotifyingArtifactRepositoryTests.java104
-rw-r--r--org.eclipse.virgo.kernel.model/src/test/java/org/eclipse/virgo/kernel/model/internal/bundle/BundleArtifactTests.java117
-rw-r--r--org.eclipse.virgo.kernel.model/src/test/java/org/eclipse/virgo/kernel/model/internal/bundle/BundleDependencyDeterminerTests.java66
-rw-r--r--org.eclipse.virgo.kernel.model/src/test/java/org/eclipse/virgo/kernel/model/internal/bundle/ModelBundleListenerInitializerTests.java84
-rw-r--r--org.eclipse.virgo.kernel.model/src/test/java/org/eclipse/virgo/kernel/model/internal/bundle/ModelBundleListenerTests.java89
-rw-r--r--org.eclipse.virgo.kernel.model/src/test/java/org/eclipse/virgo/kernel/model/internal/configurationadmin/ConfgurationArtifactTests.java86
-rw-r--r--org.eclipse.virgo.kernel.model/src/test/java/org/eclipse/virgo/kernel/model/internal/configurationadmin/ModelConfigurationListenerInitializerTests.java76
-rw-r--r--org.eclipse.virgo.kernel.model/src/test/java/org/eclipse/virgo/kernel/model/internal/configurationadmin/ModelConfigurationListenerTests.java100
-rw-r--r--org.eclipse.virgo.kernel.model/src/test/java/org/eclipse/virgo/kernel/model/internal/deployer/DeployerArtifactTests.java117
-rw-r--r--org.eclipse.virgo.kernel.model/src/test/java/org/eclipse/virgo/kernel/model/internal/deployer/DeployerCompositeArtifactDependencyDeterminerTests.java65
-rw-r--r--org.eclipse.virgo.kernel.model/src/test/java/org/eclipse/virgo/kernel/model/internal/deployer/DeployerCompositeArtifactTests.java62
-rw-r--r--org.eclipse.virgo.kernel.model/src/test/java/org/eclipse/virgo/kernel/model/internal/deployer/ModelInstallArtifactLifecycleListenerInitializerTests.java115
-rw-r--r--org.eclipse.virgo.kernel.model/src/test/java/org/eclipse/virgo/kernel/model/internal/deployer/ModelInstallArtifactLifecycleListenerTests.java103
-rw-r--r--org.eclipse.virgo.kernel.model/src/test/java/org/eclipse/virgo/kernel/model/management/internal/DefaultArtifactObjectNameCreatorTests.java40
-rw-r--r--org.eclipse.virgo.kernel.model/src/test/java/org/eclipse/virgo/kernel/model/management/internal/DelegatingManageableArtifactTests.java94
-rw-r--r--org.eclipse.virgo.kernel.model/src/test/java/org/eclipse/virgo/kernel/model/management/internal/DelegatingManageableCompositeArtifactTests.java59
-rw-r--r--org.eclipse.virgo.kernel.model/src/test/java/org/eclipse/virgo/kernel/model/management/internal/JmxArtifactRepositoryListenerTests.java71
-rw-r--r--org.eclipse.virgo.kernel.model/src/test/resources/.gitignore0
-rw-r--r--org.eclipse.virgo.kernel.model/template.mf19
68 files changed, 4786 insertions, 0 deletions
diff --git a/org.eclipse.virgo.kernel.model/.classpath b/org.eclipse.virgo.kernel.model/.classpath
new file mode 100644
index 00000000..42ed3046
--- /dev/null
+++ b/org.eclipse.virgo.kernel.model/.classpath
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="src" path="src/main/java">
+ <attributes>
+ <attribute name="com.springsource.server.ide.jdt.core.test.classpathentry" value="false"/>
+ </attributes>
+ </classpathentry>
+ <classpathentry kind="src" path="src/main/resources">
+ <attributes>
+ <attribute name="com.springsource.server.ide.jdt.core.test.classpathentry" value="false"/>
+ </attributes>
+ </classpathentry>
+ <classpathentry kind="src" output="target/test-classes" path="src/test/java">
+ <attributes>
+ <attribute name="com.springsource.server.ide.jdt.core.test.classpathentry" value="true"/>
+ </attributes>
+ </classpathentry>
+ <classpathentry excluding="ConfigBundleTests/config_tests_badprops/|ConfigBundleTests/|customConfigDir/" kind="src" output="target/test-classes" path="src/test/resources">
+ <attributes>
+ <attribute name="com.springsource.server.ide.jdt.core.test.classpathentry" value="true"/>
+ </attributes>
+ </classpathentry>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
+ <classpathentry kind="con" path="org.eclipse.ajdt.core.ASPECTJRT_CONTAINER"/>
+ <classpathentry kind="var" path="KERNEL_IVY_CACHE/org.slf4j/com.springsource.slf4j.api/1.5.10/com.springsource.slf4j.api-1.5.10.jar" sourcepath="/KERNEL_IVY_CACHE/org.slf4j/com.springsource.slf4j.api/1.5.10/com.springsource.slf4j.api-sources-1.5.10.jar"/>
+ <classpathentry kind="var" path="KERNEL_IVY_CACHE/org.slf4j/com.springsource.slf4j.nop/1.5.10/com.springsource.slf4j.nop-1.5.10.jar" sourcepath="/KERNEL_IVY_CACHE/org.slf4j/com.springsource.slf4j.nop/1.5.10/com.springsource.slf4j.nop-sources-1.5.10.jar"/>
+ <classpathentry kind="var" path="KERNEL_IVY_CACHE/org.junit/com.springsource.org.junit/4.7.0/com.springsource.org.junit-4.7.0.jar" sourcepath="/KERNEL_IVY_CACHE/org.junit/com.springsource.org.junit/4.7.0/com.springsource.org.junit-sources-4.7.0.jar"/>
+ <classpathentry kind="var" path="KERNEL_IVY_CACHE/org.eclipse.virgo.medic/org.eclipse.virgo.medic/1.0.1.D-20100420092100/org.eclipse.virgo.medic-1.0.1.D-20100420092100.jar" sourcepath="/KERNEL_IVY_CACHE/org.eclipse.virgo.medic/org.eclipse.virgo.medic/1.0.0.CI-B20/org.eclipse.virgo.medic-sources-1.0.0.CI-B20.jar">
+ <attributes>
+ <attribute name="org.eclipse.ajdt.aspectpath" value="org.eclipse.ajdt.aspectpath"/>
+ </attributes>
+ </classpathentry>
+ <classpathentry kind="var" path="KERNEL_IVY_CACHE/org.eclipse.osgi/org.eclipse.osgi/3.5.1.R35x_v20091005/org.eclipse.osgi-3.5.1.R35x_v20091005.jar" sourcepath="/KERNEL_IVY_CACHE/org.eclipse.osgi/org.eclipse.osgi/3.5.1.R35x_v20091005/org.eclipse.osgi-sources-3.5.1.R35x_v20091005.jar"/>
+ <classpathentry kind="var" path="KERNEL_IVY_CACHE/org.easymock/com.springsource.org.easymock/2.3.0/com.springsource.org.easymock-2.3.0.jar" sourcepath="/KERNEL_IVY_CACHE/org.easymock/com.springsource.org.easymock/2.3.0/com.springsource.org.easymock-sources-2.3.0.jar"/>
+ <classpathentry kind="var" path="KERNEL_IVY_CACHE/org.eclipse.virgo.teststubs/org.eclipse.virgo.teststubs.osgi/1.0.0.D-20100420091314/org.eclipse.virgo.teststubs.osgi-1.0.0.D-20100420091314.jar" sourcepath="/KERNEL_IVY_CACHE/org.eclipse.virgo.test/org.eclipse.virgo.teststubs.osgi/1.0.0.D-20100420091314/org.eclipse.virgo.teststubs.osgi-sources-1.0.0.D-20100420091314.jar"/>
+ <classpathentry kind="var" path="KERNEL_IVY_CACHE/org.apache.felix/org.apache.felix.configadmin/1.2.4/org.apache.felix.configadmin-1.2.4.jar" sourcepath="/KERNEL_IVY_CACHE/org.apache.felix/org.apache.felix.configadmin/1.2.4/org.apache.felix.configadmin-sources-1.2.4.jar"/>
+ <classpathentry kind="var" path="KERNEL_IVY_CACHE/org.eclipse.virgo.util/org.eclipse.virgo.util.osgi/2.1.0.D-20100420091708/org.eclipse.virgo.util.osgi-2.1.0.D-20100420091708.jar" sourcepath="/KERNEL_IVY_CACHE/org.eclipse.virgo.util/org.eclipse.virgo.util.osgi/2.1.0.D-20100420091708/org.eclipse.virgo.util.osgi-sources-2.1.0.D-20100420091708.jar"/>
+ <classpathentry kind="var" path="KERNEL_IVY_CACHE/org.eclipse.virgo.util/org.eclipse.virgo.util.common/2.1.0.D-20100420091708/org.eclipse.virgo.util.common-2.1.0.D-20100420091708.jar" sourcepath="/KERNEL_IVY_CACHE/org.eclipse.virgo.util/org.eclipse.virgo.util.common/2.1.0.D-20100420091708/org.eclipse.virgo.util.common-sources-2.1.0.D-20100420091708.jar"/>
+ <classpathentry combineaccessrules="false" kind="src" path="/org.eclipse.virgo.kernel.osgi"/>
+ <classpathentry combineaccessrules="false" kind="src" path="/org.eclipse.virgo.kernel.artifact"/>
+ <classpathentry combineaccessrules="false" kind="src" path="/org.eclipse.virgo.kernel.deployer"/>
+ <classpathentry kind="src" path="/org.eclipse.virgo.kernel.core"/>
+ <classpathentry combineaccessrules="false" kind="src" path="/org.eclipse.virgo.kernel.stubs"/>
+ <classpathentry kind="var" path="KERNEL_IVY_CACHE/org.springframework/org.springframework.context/3.0.0.RELEASE/org.springframework.context-3.0.0.RELEASE.jar" sourcepath="/KERNEL_IVY_CACHE/org.springframework/org.springframework.context/3.0.0.RELEASE/org.springframework.context-sources-3.0.0.RELEASE.jar"/>
+ <classpathentry kind="output" path="target/classes"/>
+</classpath>
diff --git a/org.eclipse.virgo.kernel.model/.project b/org.eclipse.virgo.kernel.model/.project
new file mode 100644
index 00000000..f09b0be2
--- /dev/null
+++ b/org.eclipse.virgo.kernel.model/.project
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>org.eclipse.virgo.kernel.model</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.wst.common.project.facet.core.builder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.ajdt.core.ajbuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>com.springsource.server.dev.eclipse.serverdevelopmentbuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.springframework.ide.eclipse.core.springbuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>com.springsource.server.ide.bundlor.core.builder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.ajdt.ui.ajnature</nature>
+ <nature>com.springsource.server.ide.facet.core.bundlenature</nature>
+ <nature>org.springframework.ide.eclipse.core.springnature</nature>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ <nature>com.springsource.server.dev.eclipse.serverdevelopmentnature</nature>
+ <nature>org.eclipse.wst.common.project.facet.core.nature</nature>
+ </natures>
+</projectDescription>
diff --git a/org.eclipse.virgo.kernel.model/.settings/com.cenqua.clover.core.prefs b/org.eclipse.virgo.kernel.model/.settings/com.cenqua.clover.core.prefs
new file mode 100644
index 00000000..86ce0323
--- /dev/null
+++ b/org.eclipse.virgo.kernel.model/.settings/com.cenqua.clover.core.prefs
@@ -0,0 +1,21 @@
+#Fri Sep 04 12:39:32 BST 2009
+block_filters=SourceDirective
+eclipse.preferences.version=1
+flush_interval=1000
+flush_policy=2
+include_filter=**/*.java
+init_string=target/clover/db/coverage.db
+init_string_default=false
+init_string_project_relative=true
+instrument_selected_source_folders=true
+instrumented_source_folder_patterns[0]=src/main/java\n**/*.java\n\nenabled
+instrumented_source_folder_patterns[1]=src/main/resources\n**/*.java\n\nenabled
+instrumented_source_folder_patterns[2]=src/test/java\n**/*.java\n\ndisabled
+instrumented_source_folder_patterns[3]=src/test/resources\n**/*.java\n\ndisabled
+output_root=.clover/bin
+output_root_same_as_project=true
+selected_test_source_folders[0]=src/test/java
+selected_test_source_folders[1]=src/test/resources
+should_qualify_java_lang=true
+test_include_filter=**/*Test.java,**/Test*.java
+test_source_folders=1
diff --git a/org.eclipse.virgo.kernel.model/.settings/com.springsource.server.ide.bundlor.core.prefs b/org.eclipse.virgo.kernel.model/.settings/com.springsource.server.ide.bundlor.core.prefs
new file mode 100644
index 00000000..ecb7aefe
--- /dev/null
+++ b/org.eclipse.virgo.kernel.model/.settings/com.springsource.server.ide.bundlor.core.prefs
@@ -0,0 +1,3 @@
+#Mon Jul 06 09:08:03 BST 2009
+com.springsource.server.ide.bundlor.core.template.properties.files=../build.versions
+eclipse.preferences.version=1
diff --git a/org.eclipse.virgo.kernel.model/.settings/org.eclipse.jdt.core.prefs b/org.eclipse.virgo.kernel.model/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 00000000..aff8ee71
--- /dev/null
+++ b/org.eclipse.virgo.kernel.model/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,70 @@
+#Tue Feb 17 09:27:55 GMT 2009
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
+org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
+org.eclipse.jdt.core.compiler.compliance=1.5
+org.eclipse.jdt.core.compiler.debug.lineNumber=generate
+org.eclipse.jdt.core.compiler.debug.localVariable=generate
+org.eclipse.jdt.core.compiler.debug.sourceFile=generate
+org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.autoboxing=ignore
+org.eclipse.jdt.core.compiler.problem.deprecation=warning
+org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled
+org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=disabled
+org.eclipse.jdt.core.compiler.problem.discouragedReference=warning
+org.eclipse.jdt.core.compiler.problem.emptyStatement=ignore
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.problem.fallthroughCase=ignore
+org.eclipse.jdt.core.compiler.problem.fatalOptionalError=enabled
+org.eclipse.jdt.core.compiler.problem.fieldHiding=ignore
+org.eclipse.jdt.core.compiler.problem.finalParameterBound=warning
+org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning
+org.eclipse.jdt.core.compiler.problem.forbiddenReference=error
+org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=warning
+org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning
+org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=ignore
+org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=ignore
+org.eclipse.jdt.core.compiler.problem.localVariableHiding=ignore
+org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=warning
+org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=ignore
+org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=ignore
+org.eclipse.jdt.core.compiler.problem.missingSerialVersion=warning
+org.eclipse.jdt.core.compiler.problem.noEffectAssignment=warning
+org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning
+org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=ignore
+org.eclipse.jdt.core.compiler.problem.nullReference=warning
+org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning
+org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore
+org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=ignore
+org.eclipse.jdt.core.compiler.problem.potentialNullReference=ignore
+org.eclipse.jdt.core.compiler.problem.rawTypeReference=ignore
+org.eclipse.jdt.core.compiler.problem.redundantNullCheck=ignore
+org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=ignore
+org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled
+org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning
+org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled
+org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore
+org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning
+org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning
+org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=ignore
+org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning
+org.eclipse.jdt.core.compiler.problem.unnecessaryElse=ignore
+org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=ignore
+org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=ignore
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionExemptExceptionAndThrowable=enabled
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionIncludeDocCommentReference=enabled
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled
+org.eclipse.jdt.core.compiler.problem.unusedImport=warning
+org.eclipse.jdt.core.compiler.problem.unusedLabel=warning
+org.eclipse.jdt.core.compiler.problem.unusedLocal=ignore
+org.eclipse.jdt.core.compiler.problem.unusedParameter=ignore
+org.eclipse.jdt.core.compiler.problem.unusedParameterIncludeDocCommentReference=enabled
+org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled
+org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled
+org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning
+org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning
+org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning
+org.eclipse.jdt.core.compiler.source=1.5
diff --git a/org.eclipse.virgo.kernel.model/.settings/org.eclipse.wst.common.project.facet.core.xml b/org.eclipse.virgo.kernel.model/.settings/org.eclipse.wst.common.project.facet.core.xml
new file mode 100644
index 00000000..801f856c
--- /dev/null
+++ b/org.eclipse.virgo.kernel.model/.settings/org.eclipse.wst.common.project.facet.core.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<faceted-project>
+ <installed facet="com.springsource.server.bundle" version="1.0"/>
+</faceted-project>
diff --git a/org.eclipse.virgo.kernel.model/.settings/org.springframework.ide.eclipse.beans.core.prefs b/org.eclipse.virgo.kernel.model/.settings/org.springframework.ide.eclipse.beans.core.prefs
new file mode 100644
index 00000000..39218d3d
--- /dev/null
+++ b/org.eclipse.virgo.kernel.model/.settings/org.springframework.ide.eclipse.beans.core.prefs
@@ -0,0 +1,3 @@
+#Tue Sep 08 09:58:14 BST 2009
+eclipse.preferences.version=1
+org.springframework.ide.eclipse.beans.core.ignoreMissingNamespaceHandler=false
diff --git a/org.eclipse.virgo.kernel.model/.springBeans b/org.eclipse.virgo.kernel.model/.springBeans
new file mode 100644
index 00000000..34b281cf
--- /dev/null
+++ b/org.eclipse.virgo.kernel.model/.springBeans
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<beansProjectDescription>
+ <version>1</version>
+ <pluginVersion><![CDATA[2.3.0.200912170948-RELEASE]]></pluginVersion>
+ <configSuffixes>
+ <configSuffix><![CDATA[xml]]></configSuffix>
+ </configSuffixes>
+ <enableImports><![CDATA[false]]></enableImports>
+ <configs>
+ </configs>
+ <configSets>
+ </configSets>
+</beansProjectDescription>
diff --git a/org.eclipse.virgo.kernel.model/build.xml b/org.eclipse.virgo.kernel.model/build.xml
new file mode 100644
index 00000000..87bb7b50
--- /dev/null
+++ b/org.eclipse.virgo.kernel.model/build.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project name="org.eclipse.virgo.kernel.model">
+
+ <property file="${basedir}/../build.properties"/>
+ <property file="${basedir}/../build.versions"/>
+ <import file="${basedir}/../virgo-build/weaving/default.xml"/>
+
+</project>
diff --git a/org.eclipse.virgo.kernel.model/ivy.xml b/org.eclipse.virgo.kernel.model/ivy.xml
new file mode 100644
index 00000000..1b411ff3
--- /dev/null
+++ b/org.eclipse.virgo.kernel.model/ivy.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?xml-stylesheet type="text/xsl" href="http://ivyrep.jayasoft.org/ivy-doc.xsl"?>
+<ivy-module xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://incubator.apache.org/ivy/schemas/ivy.xsd" version="1.3">
+
+ <info module="${ant.project.name}" organisation="org.eclipse.virgo.kernel"/>
+
+ <configurations>
+ <include file="${virgo.build.dir}/common/default-ivy-configurations.xml"/>
+ </configurations>
+
+ <publications>
+ <artifact name="${ant.project.name}"/>
+ <artifact name="${ant.project.name}-sources" ext="jar" type="src"/>
+ </publications>
+
+ <dependencies>
+ <dependency org="org.junit" name="com.springsource.org.junit" rev="${org.junit}" conf="test->runtime"/>
+ <dependency org="org.easymock" name="com.springsource.org.easymock" rev="${org.easymock}" conf="test->runtime"/>
+ <dependency org="org.eclipse.virgo.teststubs" name="org.eclipse.virgo.teststubs.osgi" rev="${org.eclipse.virgo.teststubs}" conf="test->runtime"/>
+ <dependency org="org.slf4j" name="com.springsource.slf4j.api" rev="${org.slf4j}" conf="compile->runtime"/>
+ <dependency org="org.slf4j" name="com.springsource.slf4j.nop" rev="${org.slf4j}" conf="test->runtime"/>
+ <dependency org="org.springframework" name="org.springframework.context" rev="${org.springframework}" conf="compile->runtime"/>
+ <dependency org="org.eclipse.virgo.medic" name="org.eclipse.virgo.medic" rev="${org.eclipse.virgo.medic}" conf="aspects, compile->runtime"/>
+ <dependency org="org.eclipse.virgo.kernel" name="org.eclipse.virgo.kernel.osgi" rev="latest.integration" conf="compile->runtime"/>
+ <dependency org="org.eclipse.virgo.kernel" name="org.eclipse.virgo.kernel.artifact" rev="latest.integration" conf="compile->runtime"/>
+ <dependency org="org.eclipse.virgo.kernel" name="org.eclipse.virgo.kernel.stubs" rev="latest.integration" conf="test->runtime"/>
+ <dependency org="org.eclipse.virgo.kernel" name="org.eclipse.virgo.kernel.deployer" rev="latest.integration" conf="aspects->runtime"/>
+ <dependency org="org.eclipse.virgo.util" name="org.eclipse.virgo.util.common" rev="${org.eclipse.virgo.util}" conf="compile->compile"/>
+ <dependency org="org.eclipse.virgo.util" name="org.eclipse.virgo.util.osgi" rev="${org.eclipse.virgo.util}" conf="compile->compile"/>
+ <dependency org="org.eclipse.virgo.util" name="org.eclipse.virgo.util.jmx" rev="${org.eclipse.virgo.util}" conf="aspects->runtime"/>
+ <dependency org="org.eclipse.osgi" name="org.eclipse.osgi" rev="${org.eclipse.osgi}" conf="compile->runtime"/>
+ <dependency org="org.apache.felix" name="org.apache.felix.configadmin" rev="${org.apache.felix}" conf="compile->runtime"/>
+
+ <override org="org.eclipse.virgo.util" rev="${org.eclipse.virgo.util}"/>
+ </dependencies>
+
+</ivy-module>
diff --git a/org.eclipse.virgo.kernel.model/src/main/java/org/eclipse/virgo/kernel/model/Artifact.java b/org.eclipse.virgo.kernel.model/src/main/java/org/eclipse/virgo/kernel/model/Artifact.java
new file mode 100644
index 00000000..9f2d202f
--- /dev/null
+++ b/org.eclipse.virgo.kernel.model/src/main/java/org/eclipse/virgo/kernel/model/Artifact.java
@@ -0,0 +1,96 @@
+/*******************************************************************************
+ * 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.model;
+
+import java.util.Map;
+import java.util.Set;
+
+import org.osgi.framework.Version;
+
+/**
+ * Represents an artifact in the runtime model of this system. Acts as a generic interface that delegates to more
+ * specific functionality in the running system. In all likelihood, there should be very few sub-interfaces of this
+ * interface but quite a few implementations of this interface.
+ * <p />
+ *
+ * <strong>Concurrent Semantics</strong><br />
+ *
+ * Implementations must be threadsafe
+ *
+ */
+public interface Artifact {
+
+ /**
+ * Start this {@link Artifact}
+ */
+ void start();
+
+ /**
+ * Stop this {@link Artifact}
+ */
+ void stop();
+
+ /**
+ * Update and refresh the contents of this {@link Artifact}
+ * @return true if the refresh is successful, false if refresh is not performed
+ */
+ boolean refresh();
+
+ /**
+ * Uninstall this {@link Artifact}
+ */
+ void uninstall();
+
+ /**
+ * Get the type of this {@link Artifact}
+ *
+ * @return The type of this {@link Artifact}
+ */
+ String getType();
+
+ /**
+ * Get the name of this {@link Artifact}
+ *
+ * @return The name of this {@link Artifact}
+ */
+ String getName();
+
+ /**
+ * Get the {@link Version} of this {@link Artifact}
+ *
+ * @return The {@link Version} of this {@link Artifact}
+ */
+ Version getVersion();
+
+ /**
+ * Get the state of this {@link Artifact}
+ *
+ * @return The state of this {@link Artifact}
+ */
+ ArtifactState getState();
+
+ /**
+ * Get the {@link Artifact}s that this {@link Artifact} depends on. The dependency can be of any kind and will be
+ * determined by the type of {@link Artifact} represented.
+ *
+ * @return This {@link Artifact}'s dependents
+ */
+ Set<Artifact> getDependents();
+
+ /**
+ * Get this {@link Artifact}'s properties. This map is free to hold any properties contributed by any collaborator.
+ *
+ * @return This {@link Artifact}'s properties
+ */
+ Map<String, String> getProperties();
+
+}
diff --git a/org.eclipse.virgo.kernel.model/src/main/java/org/eclipse/virgo/kernel/model/ArtifactState.java b/org.eclipse.virgo.kernel.model/src/main/java/org/eclipse/virgo/kernel/model/ArtifactState.java
new file mode 100644
index 00000000..ab2443f5
--- /dev/null
+++ b/org.eclipse.virgo.kernel.model/src/main/java/org/eclipse/virgo/kernel/model/ArtifactState.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.model;
+
+/**
+ * The states that an {@link Artifact} can be in
+ * <p />
+ *
+ * <strong>Concurrent Semantics</strong><br />
+ *
+ * Threadsafe
+ *
+ */
+public enum ArtifactState {
+
+ INITIAL, //
+ INSTALLING, //
+ INSTALLED, //
+ RESOLVING, //
+ RESOLVED, //
+ STARTING, //
+ ACTIVE, //
+ STOPPING, //
+ UNINSTALLING, //
+ UNINSTALLED
+}
diff --git a/org.eclipse.virgo.kernel.model/src/main/java/org/eclipse/virgo/kernel/model/BundleArtifact.java b/org.eclipse.virgo.kernel.model/src/main/java/org/eclipse/virgo/kernel/model/BundleArtifact.java
new file mode 100644
index 00000000..c32f3f34
--- /dev/null
+++ b/org.eclipse.virgo.kernel.model/src/main/java/org/eclipse/virgo/kernel/model/BundleArtifact.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.model;
+
+/**
+ * Represents a bundle artifact (an artifact that is an OSGi Bundle) in the runtime model of this system. Acts as a
+ * generic interface that delegates to more specific functionality in the running system. In all likelihood, there
+ * should be very few sub-interfaces of this interface but quite a few implementations of this interface.
+ * <p />
+ *
+ * <strong>Concurrent Semantics</strong><br />
+ *
+ * Implementations must be threadsafe
+ *
+ */
+public interface BundleArtifact extends Artifact {
+
+ /**
+ * Update an entry within this bundle. If the target path does not already exist, creates a new entry at that
+ * location.
+ *
+ * @param inputPath The path to read update from
+ * @param targetPath The bundle relative path to write the update to
+ */
+ void updateEntry(String inputPath, String targetPath);
+
+ /**
+ * Delete an entry in a bundle
+ *
+ * @param targetPath The bundle relative path to delete
+ */
+ void deleteEntry(String targetPath);
+}
diff --git a/org.eclipse.virgo.kernel.model/src/main/java/org/eclipse/virgo/kernel/model/CompositeArtifact.java b/org.eclipse.virgo.kernel.model/src/main/java/org/eclipse/virgo/kernel/model/CompositeArtifact.java
new file mode 100644
index 00000000..1140d36c
--- /dev/null
+++ b/org.eclipse.virgo.kernel.model/src/main/java/org/eclipse/virgo/kernel/model/CompositeArtifact.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.model;
+
+/**
+ * Represents a composite artifact (an artifact that contains other artifacts) in the runtime model of this system. Acts
+ * as a generic interface that delegates to more specific functionality in the running system. In all likelihood, there
+ * should be very few sub-interfaces of this interface but quite a few implementations of this interface.
+ * <p />
+ *
+ * <strong>Concurrent Semantics</strong><br />
+ *
+ * Implementations must be threadsafe
+ *
+ */
+public interface CompositeArtifact extends Artifact {
+
+ /**
+ * Get whether this @{link CompositeArtifact} is scoped or not
+ *
+ * @return Whether this {@link CompositeArtifact} is scoped or not
+ */
+ boolean isScoped();
+
+ /**
+ * Get whether this @{link CompositeArtifact} is atomic or not
+ *
+ * @return Whether this {@link CompositeArtifact} is atomic or not
+ */
+ boolean isAtomic();
+
+}
diff --git a/org.eclipse.virgo.kernel.model/src/main/java/org/eclipse/virgo/kernel/model/RuntimeArtifactRepository.java b/org.eclipse.virgo.kernel.model/src/main/java/org/eclipse/virgo/kernel/model/RuntimeArtifactRepository.java
new file mode 100644
index 00000000..bb45d094
--- /dev/null
+++ b/org.eclipse.virgo.kernel.model/src/main/java/org/eclipse/virgo/kernel/model/RuntimeArtifactRepository.java
@@ -0,0 +1,68 @@
+/*******************************************************************************
+ * 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.model;
+
+import java.util.Set;
+
+import org.osgi.framework.Version;
+
+/**
+ * A single in-memory repository with representations of all artifacts in the running system. Operations are generally
+ * executed against the artifacts themselves rather than the repository.
+ * <p />
+ *
+ * <strong>Concurrent Semantics</strong><br />
+ *
+ * Implementations must be threadsafe
+ *
+ */
+public interface RuntimeArtifactRepository {
+
+ /**
+ * Add an {@link Artifact} to this repository
+ *
+ * @param artifact The {@link Artifact} to add
+ * @return <code>true</code> if this repository did not already contain the specified {@link Artifact}
+ * @see Set
+ */
+ boolean add(Artifact artifact);
+
+ /**
+ * Remove an {@link Artifact} from this repository
+ *
+ * @param type The type of the {@link Artifact} to remove
+ * @param name The name of the {@link Artifact} to remove
+ * @param version The {@link Version} of the {@link Artifact} to remove
+ * @return <code>true</code> if this repository contained the specified {@link Artifact}
+ */
+ boolean remove(String type, String name, Version version);
+
+ /**
+ * Returns the entire collection of {@link Artifact}s contained within this repository. The returned collection
+ * should not be mutated by this repository when it changes. Only a subsequent call to this method will show changes
+ * to the contents of the repository.
+ *
+ * @return The entire collection of artifacts contained within this repository
+ */
+ Set<Artifact> getArtifacts();
+
+ /**
+ * Gets a specific {@link Artifact} from this repository
+ *
+ * @param type The type of the {@link Artifact} to get
+ * @param name The name of the {@link Artifact} to get
+ * @param version The {@link Version} of the {@link Artifact} to get
+ * @return The {@link Artifact} represented by this type, name, and version if it is in the repository, otherwise
+ * <code>null</code>
+ */
+ Artifact getArtifact(String type, String name, Version version);
+}
diff --git a/org.eclipse.virgo.kernel.model/src/main/java/org/eclipse/virgo/kernel/model/internal/AbstractArtifact.java b/org.eclipse.virgo.kernel.model/src/main/java/org/eclipse/virgo/kernel/model/internal/AbstractArtifact.java
new file mode 100644
index 00000000..aa484136
--- /dev/null
+++ b/org.eclipse.virgo.kernel.model/src/main/java/org/eclipse/virgo/kernel/model/internal/AbstractArtifact.java
@@ -0,0 +1,158 @@
+/*******************************************************************************
+ * 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.model.internal;
+
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import org.eclipse.virgo.kernel.model.Artifact;
+import org.eclipse.virgo.kernel.serviceability.NonNull;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Filter;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.framework.Version;
+import org.osgi.util.tracker.ServiceTracker;
+
+
+/**
+ * An abstract implementation of {@link Artifact} that all implementations should extend.
+ * <p/>
+ * Implements {@link #getDependents()} by delegating to {@link DependencyDeterminer} found in the service registry. The
+ * appropriate {@link DependencyDeterminer} is located by finding a a service with the property
+ * <code>artifactType</code> with the a value equal to the value of {@link #getType()}.
+ * <p />
+ * {@link #equals(Object)} and {@link #hashCode()} are also implemented to guarantee that equality is based on the type,
+ * name, and version of the artifact.
+ * <p/>
+ *
+ * <strong>Concurrent Semantics</strong><br />
+ *
+ * Threadsafe and all subclasses should be threadsafe
+ *
+ * @see DependencyDeterminer
+ */
+public abstract class AbstractArtifact implements Artifact {
+
+ private static final String FILTER_FORMAT = "(&(objectClass=%s)(artifactType=%s))";
+
+ private final String type;
+
+ private final String name;
+
+ private final Version version;
+
+ private final ServiceTracker dependencyDeterminerTracker;
+
+ public AbstractArtifact(@NonNull BundleContext bundleContext, @NonNull String type, @NonNull String name, @NonNull Version version) {
+ this.type = type;
+ this.name = name;
+ this.version = version;
+
+ Filter filter;
+ try {
+ filter = bundleContext.createFilter(String.format(FILTER_FORMAT, DependencyDeterminer.class.getCanonicalName(), type));
+ } catch (InvalidSyntaxException e) {
+ throw new RuntimeException(String.format("Cannot create Service Registry filter for a DependencyDeterminer of type '%s'", type), e);
+ }
+ this.dependencyDeterminerTracker = new ServiceTracker(bundleContext, filter, null);
+ this.dependencyDeterminerTracker.open();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public final String getType() {
+ return this.type;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public final String getName() {
+ return this.name;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public final Version getVersion() {
+ return this.version;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public final Set<Artifact> getDependents() {
+ Set<Artifact> dependents = new HashSet<Artifact>();
+
+ Object[] dependencyDeterminers = this.dependencyDeterminerTracker.getServices();
+ if (dependencyDeterminers != null) {
+ for (Object dependencyDeterminer : dependencyDeterminers) {
+ dependents.addAll(((DependencyDeterminer) dependencyDeterminer).getDependents(this));
+ }
+ }
+
+ return Collections.unmodifiableSet(dependents);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public Map<String, String> getProperties() {
+ return Collections.<String, String> emptyMap();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public final int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + name.hashCode();
+ result = prime * result + type.hashCode();
+ result = prime * result + version.hashCode();
+ return result;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public final boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj == null) {
+ return false;
+ }
+ if (!(obj instanceof Artifact)) {
+ return false;
+ }
+ Artifact other = (Artifact) obj;
+ if (!name.equals(other.getName())) {
+ return false;
+ }
+ if (!type.equals(other.getType())) {
+ return false;
+ }
+ if (!version.equals(other.getVersion())) {
+ return false;
+ }
+ return true;
+ }
+
+ @Override
+ public String toString() {
+ return String.format("type: %s, name: %s, version: %s", this.type, this.name, this.version.toString());
+ }
+}
diff --git a/org.eclipse.virgo.kernel.model/src/main/java/org/eclipse/virgo/kernel/model/internal/ArtifactRepositoryListener.java b/org.eclipse.virgo.kernel.model/src/main/java/org/eclipse/virgo/kernel/model/internal/ArtifactRepositoryListener.java
new file mode 100644
index 00000000..0d59444c
--- /dev/null
+++ b/org.eclipse.virgo.kernel.model/src/main/java/org/eclipse/virgo/kernel/model/internal/ArtifactRepositoryListener.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.model.internal;
+
+import org.eclipse.virgo.kernel.model.Artifact;
+
+/**
+ * A listener for changes in the {@link NotifyingRuntimeArtifactRepository}
+ * <p />
+ *
+ * <strong>Concurrent Semantics</strong><br />
+ *
+ * Implementations must be threadsafe
+ *
+ * @see NotifyingRuntimeArtifactRepository
+ */
+public interface ArtifactRepositoryListener {
+
+ /**
+ * Called when an {@link Artifact} is added to the repository
+ *
+ * @param artifact The {@link Artifact} that was added to the repository
+ */
+ void added(Artifact artifact);
+
+ /**
+ * Called when an {@link Artifact} is removed from the repository
+ *
+ * @param artifact The {@link Artifact} that was removed from the repository
+ */
+ void removed(Artifact artifact);
+}
diff --git a/org.eclipse.virgo.kernel.model/src/main/java/org/eclipse/virgo/kernel/model/internal/DependencyDeterminer.java b/org.eclipse.virgo.kernel.model/src/main/java/org/eclipse/virgo/kernel/model/internal/DependencyDeterminer.java
new file mode 100644
index 00000000..8a3ee57a
--- /dev/null
+++ b/org.eclipse.virgo.kernel.model/src/main/java/org/eclipse/virgo/kernel/model/internal/DependencyDeterminer.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.model.internal;
+
+import java.util.Set;
+
+import org.eclipse.virgo.kernel.model.Artifact;
+
+
+/**
+ * Interface used to provide the values of the dependents of a given {@link Artifact}. Implementations of this interface
+ * should be registered in the OSGi Service Registry with a service property of <code>artifactType</code>. The value of
+ * this property should indicate which type of artifact this {@link DependencyDeterminer} can be used for.
+ * <p />
+ *
+ * <strong>Concurrent Semantics</strong><br />
+ *
+ * Implementations should be threadsafe
+ *
+ * @see AbstractArtifact
+ */
+public interface DependencyDeterminer {
+
+ /**
+ * Returns the collection of dependent {@link Artifact}s for a given root {@link Artifact}. Note that the artifacts
+ * that are returned from this determiner should already be contained in the {@link org.eclipse.virgo.kernel.model.RuntimeArtifactRepository RuntimeArtifactRepository}. The
+ * single instance of this may need to be injected into the {@link DependencyDeterminer} implementation.
+ *
+ * @param rootArtifact The {@link Artifact} to find dependents for
+ * @return The collection of dependent {@link Artifact}s
+ */
+ Set<Artifact> getDependents(Artifact rootArtifact);
+}
diff --git a/org.eclipse.virgo.kernel.model/src/main/java/org/eclipse/virgo/kernel/model/internal/NotifyingRuntimeArtifactRepository.java b/org.eclipse.virgo.kernel.model/src/main/java/org/eclipse/virgo/kernel/model/internal/NotifyingRuntimeArtifactRepository.java
new file mode 100644
index 00000000..eacd17b8
--- /dev/null
+++ b/org.eclipse.virgo.kernel.model/src/main/java/org/eclipse/virgo/kernel/model/internal/NotifyingRuntimeArtifactRepository.java
@@ -0,0 +1,113 @@
+/*******************************************************************************
+ * 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.model.internal;
+
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.eclipse.virgo.kernel.model.Artifact;
+import org.eclipse.virgo.kernel.model.RuntimeArtifactRepository;
+import org.osgi.framework.Version;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+/**
+ * Implementation of {@link RuntimeArtifactRepository} that notifies a collection of listeners that a change has
+ * happened to this repository.
+ * <p />
+ *
+ * <strong>Concurrent Semantics</strong><br />
+ *
+ * Threadsafe
+ *
+ * @see ArtifactRepositoryListener
+ */
+public final class NotifyingRuntimeArtifactRepository implements RuntimeArtifactRepository {
+
+ private final Logger logger = LoggerFactory.getLogger(this.getClass());
+
+ private final Object monitor = new Object();
+
+ private final Set<Artifact> artifacts = new HashSet<Artifact>();
+
+ private final List<ArtifactRepositoryListener> listeners;
+
+ public NotifyingRuntimeArtifactRepository(ArtifactRepositoryListener... listeners) {
+ this.listeners = Arrays.asList(listeners);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean add(Artifact artifact) {
+ synchronized (this.monitor) {
+ boolean result = this.artifacts.add(artifact);
+ if (result) {
+ for (ArtifactRepositoryListener listener : listeners) {
+ try {
+ listener.added(artifact);
+ } catch (Exception e) {
+ logger.error(String.format("Exception calling added() on listener '%s'", listener.toString()), e);
+ }
+ }
+ }
+ return result;
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean remove(String type, String name, Version version) {
+ synchronized (this.monitor) {
+ Artifact artifact = getArtifact(type, name, version);
+ boolean result = this.artifacts.remove(artifact);
+ if (result) {
+ for (ArtifactRepositoryListener listener : listeners) {
+ try {
+ listener.removed(artifact);
+ } catch (Exception e) {
+ logger.error(String.format("Exception calling removed() on listener '%s'", listener.toString()), e);
+ }
+ }
+ }
+ return result;
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public Set<Artifact> getArtifacts() {
+ synchronized (this.monitor) {
+ return new HashSet<Artifact>(this.artifacts);
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public Artifact getArtifact(String type, String name, Version version) {
+ synchronized (this.monitor) {
+ for (Artifact artifact : this.artifacts) {
+ if (artifact.getType().equals(type) && artifact.getName().equals(name) && artifact.getVersion().equals(version)) {
+ return artifact;
+ }
+ }
+ return null;
+ }
+ }
+
+}
diff --git a/org.eclipse.virgo.kernel.model/src/main/java/org/eclipse/virgo/kernel/model/internal/bundle/BundleArtifact.java b/org.eclipse.virgo.kernel.model/src/main/java/org/eclipse/virgo/kernel/model/internal/bundle/BundleArtifact.java
new file mode 100644
index 00000000..82951797
--- /dev/null
+++ b/org.eclipse.virgo.kernel.model/src/main/java/org/eclipse/virgo/kernel/model/internal/bundle/BundleArtifact.java
@@ -0,0 +1,130 @@
+/*******************************************************************************
+ * 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.model.internal.bundle;
+
+import org.eclipse.virgo.kernel.model.Artifact;
+import org.eclipse.virgo.kernel.model.ArtifactState;
+import org.eclipse.virgo.kernel.model.internal.AbstractArtifact;
+import org.eclipse.virgo.kernel.serviceability.NonNull;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.BundleException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.eclipse.virgo.kernel.osgi.framework.PackageAdminUtil;
+
+/**
+ * Implementation of {@link Artifact} that delegates to an OSGi native bundle
+ * <p />
+ *
+ * <strong>Concurrent Semantics</strong><br />
+ *
+ * Threadsafe
+ *
+ */
+final class BundleArtifact extends AbstractArtifact {
+
+ static final String TYPE = "bundle";
+
+ private final Logger logger = LoggerFactory.getLogger(this.getClass());
+
+ private final PackageAdminUtil packageAdminUtil;
+
+ private final Bundle bundle;
+
+ public BundleArtifact(@NonNull BundleContext bundleContext, @NonNull PackageAdminUtil packageAdminUtil, @NonNull Bundle bundle) {
+ super(bundleContext, TYPE, bundle.getSymbolicName(), bundle.getVersion());
+ this.packageAdminUtil = packageAdminUtil;
+ this.bundle = bundle;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public ArtifactState getState() {
+ return mapBundleState(this.bundle.getState());
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean refresh() {
+ try {
+ this.bundle.update();
+ this.packageAdminUtil.synchronouslyRefreshPackages(new Bundle[] { this.bundle });
+ return true;
+ } catch (BundleException e) {
+ logger.error("Unable to update bundle '{}:{}'", this.bundle.getSymbolicName(), this.bundle.getVersion());
+ throw new RuntimeException(String.format("Unable to update bundle '%s:%s'", this.bundle.getSymbolicName(), this.bundle.getVersion()), e);
+
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void start() {
+ try {
+ this.bundle.start();
+ } catch (BundleException e) {
+ logger.error("Unable to start bundle '{}:{}'", this.bundle.getSymbolicName(), this.bundle.getVersion());
+ throw new RuntimeException(String.format("Unable to start bundle '%s:%s'", this.bundle.getSymbolicName(), this.bundle.getVersion()), e);
+
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void stop() {
+ try {
+ this.bundle.stop();
+ } catch (BundleException e) {
+ logger.error("Unable to stop bundle '{}:{}'", this.bundle.getSymbolicName(), this.bundle.getVersion());
+ throw new RuntimeException(String.format("Unable to stop bundle '%s:%s'", this.bundle.getSymbolicName(), this.bundle.getVersion()), e);
+
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void uninstall() {
+ try {
+ this.bundle.uninstall();
+ } catch (BundleException e) {
+ logger.error("Unable to uninstall bundle '{}:{}'", this.bundle.getSymbolicName(), this.bundle.getVersion());
+ throw new RuntimeException(String.format("Unable to uninstall bundle '%s:%s'", this.bundle.getSymbolicName(), this.bundle.getVersion()),
+ e);
+ }
+ }
+
+ private ArtifactState mapBundleState(int state) {
+ if (Bundle.UNINSTALLED == state) {
+ return ArtifactState.UNINSTALLED;
+ } else if (Bundle.INSTALLED == state) {
+ return ArtifactState.INSTALLED;
+ } else if (Bundle.RESOLVED == state) {
+ return ArtifactState.RESOLVED;
+ } else if (Bundle.STARTING == state) {
+ return ArtifactState.STARTING;
+ } else if (Bundle.STOPPING == state) {
+ return ArtifactState.STOPPING;
+ } else if (Bundle.ACTIVE == state) {
+ return ArtifactState.ACTIVE;
+ } else {
+ throw new IllegalArgumentException(String.format("Unknown bundle state '%d'", state));
+ }
+ }
+
+}
diff --git a/org.eclipse.virgo.kernel.model/src/main/java/org/eclipse/virgo/kernel/model/internal/bundle/BundleDependencyDeterminer.java b/org.eclipse.virgo.kernel.model/src/main/java/org/eclipse/virgo/kernel/model/internal/bundle/BundleDependencyDeterminer.java
new file mode 100644
index 00000000..74bc65e1
--- /dev/null
+++ b/org.eclipse.virgo.kernel.model/src/main/java/org/eclipse/virgo/kernel/model/internal/bundle/BundleDependencyDeterminer.java
@@ -0,0 +1,81 @@
+/*******************************************************************************
+ * 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.model.internal.bundle;
+
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+
+import org.eclipse.virgo.kernel.model.Artifact;
+import org.eclipse.virgo.kernel.model.RuntimeArtifactRepository;
+import org.eclipse.virgo.kernel.model.internal.DependencyDeterminer;
+import org.eclipse.virgo.kernel.serviceability.NonNull;
+
+import org.eclipse.virgo.kernel.osgi.quasi.QuasiBundle;
+import org.eclipse.virgo.kernel.osgi.quasi.QuasiExportPackage;
+import org.eclipse.virgo.kernel.osgi.quasi.QuasiFramework;
+import org.eclipse.virgo.kernel.osgi.quasi.QuasiFrameworkFactory;
+import org.eclipse.virgo.kernel.osgi.quasi.QuasiImportPackage;
+
+/**
+ * Implementation of {@link DependencyDeterminer} that returns the dependents of a {@link org.osgi.framework.Bundle
+ * Bundle}. The dependents consist of any bundle that has been wired to as a result of <code>Import-Package</code>.
+ * <p />
+ *
+ * <strong>Concurrent Semantics</strong><br />
+ *
+ * Threadsafe
+ *
+ */
+public final class BundleDependencyDeterminer implements DependencyDeterminer {
+
+ private final QuasiFrameworkFactory quasiFrameworkFactory;
+
+ private final RuntimeArtifactRepository artifactRepository;
+
+ public BundleDependencyDeterminer(@NonNull QuasiFrameworkFactory quasiFrameworkFactory, @NonNull RuntimeArtifactRepository artifactRepository) {
+ this.quasiFrameworkFactory = quasiFrameworkFactory;
+ this.artifactRepository = artifactRepository;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public Set<Artifact> getDependents(Artifact rootArtifact) {
+ Set<Artifact> artifacts = new HashSet<Artifact>();
+ QuasiBundle rootBundle = getBundle(rootArtifact);
+
+ if (rootBundle == null) {
+ return Collections.<Artifact> emptySet();
+ }
+
+ for (QuasiImportPackage importPackage : rootBundle.getImportPackages()) {
+ QuasiExportPackage provider = importPackage.getProvider();
+ if (provider != null) {
+ QuasiBundle bundle = provider.getExportingBundle();
+ artifacts.add(artifactRepository.getArtifact(BundleArtifact.TYPE, bundle.getSymbolicName(), bundle.getVersion()));
+ }
+ }
+
+ return artifacts;
+ }
+
+ private QuasiBundle getBundle(Artifact artifact) {
+ QuasiFramework framework = quasiFrameworkFactory.create();
+ for (QuasiBundle bundle : framework.getBundles()) {
+ if (artifact.getName().equals(bundle.getSymbolicName()) && artifact.getVersion().equals(bundle.getVersion())) {
+ return bundle;
+ }
+ }
+ return null;
+ }
+}
diff --git a/org.eclipse.virgo.kernel.model/src/main/java/org/eclipse/virgo/kernel/model/internal/bundle/ModelBundleListener.java b/org.eclipse.virgo.kernel.model/src/main/java/org/eclipse/virgo/kernel/model/internal/bundle/ModelBundleListener.java
new file mode 100644
index 00000000..58e7de1c
--- /dev/null
+++ b/org.eclipse.virgo.kernel.model/src/main/java/org/eclipse/virgo/kernel/model/internal/bundle/ModelBundleListener.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.model.internal.bundle;
+
+import org.eclipse.virgo.kernel.model.Artifact;
+import org.eclipse.virgo.kernel.model.RuntimeArtifactRepository;
+import org.eclipse.virgo.kernel.serviceability.NonNull;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.BundleEvent;
+import org.osgi.framework.SynchronousBundleListener;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.eclipse.virgo.kernel.osgi.framework.PackageAdminUtil;
+
+/**
+ * Implementation of {@link BundleListener} that notices {@link BundleEvent#INSTALLED} and
+ * {@link BundleEvent#UNINSTALLED} events to add and remove respectively {@link Artifact}s from the
+ * {@link RuntimeArtifactRepository}
+ * <p />
+ *
+ * <strong>Concurrent Semantics</strong><br />
+ *
+ * Threadsafe
+ *
+ */
+final class ModelBundleListener implements SynchronousBundleListener {
+
+ private final Logger logger = LoggerFactory.getLogger(this.getClass());
+
+ private final BundleContext bundleContext;
+
+ private final RuntimeArtifactRepository artifactRepository;
+
+ private final PackageAdminUtil packageAdminUtil;
+
+ public ModelBundleListener(@NonNull BundleContext bundleContext, @NonNull RuntimeArtifactRepository artifactRepository,
+ @NonNull PackageAdminUtil packageAdminUtil) {
+ this.bundleContext = bundleContext;
+ this.artifactRepository = artifactRepository;
+ this.packageAdminUtil = packageAdminUtil;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void bundleChanged(BundleEvent event) {
+ if (BundleEvent.INSTALLED == event.getType()) {
+ processInstalled(event);
+ } else if (BundleEvent.UNINSTALLED == event.getType()) {
+ processUninstalled(event);
+ }
+ }
+
+ private void processInstalled(BundleEvent event) {
+ Bundle bundle = event.getBundle();
+ logger.info("Processing installed event for '{}:{}'", bundle.getSymbolicName(), bundle.getVersion().toString());
+ this.artifactRepository.add(new BundleArtifact(bundleContext, packageAdminUtil, bundle));
+ }
+
+ private void processUninstalled(BundleEvent event) {
+ Bundle bundle = event.getBundle();
+ logger.info("Processing uninstalled event for '{}:{}'", bundle.getSymbolicName(), bundle.getVersion().toString());
+ this.artifactRepository.remove(BundleArtifact.TYPE, bundle.getSymbolicName(), bundle.getVersion());
+ }
+
+}
diff --git a/org.eclipse.virgo.kernel.model/src/main/java/org/eclipse/virgo/kernel/model/internal/bundle/ModelBundleListenerInitializer.java b/org.eclipse.virgo.kernel.model/src/main/java/org/eclipse/virgo/kernel/model/internal/bundle/ModelBundleListenerInitializer.java
new file mode 100644
index 00000000..7805fbba
--- /dev/null
+++ b/org.eclipse.virgo.kernel.model/src/main/java/org/eclipse/virgo/kernel/model/internal/bundle/ModelBundleListenerInitializer.java
@@ -0,0 +1,85 @@
+/*******************************************************************************
+ * 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.model.internal.bundle;
+
+import javax.annotation.PostConstruct;
+import javax.annotation.PreDestroy;
+
+import org.eclipse.virgo.kernel.model.RuntimeArtifactRepository;
+import org.eclipse.virgo.kernel.serviceability.NonNull;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.BundleListener;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.eclipse.virgo.kernel.osgi.framework.PackageAdminUtil;
+
+/**
+ * An intializer responsible for registering a {@link ModelBundleListener} and enumerating any existing {@link Bundle}
+ * objects from the OSGi Framework.
+ * <p />
+ *
+ * <strong>Concurrent Semantics</strong><br />
+ *
+ * Threadsafe
+ *
+ * @see ModelBundleListener
+ */
+public final class ModelBundleListenerInitializer {
+
+ private final Logger logger = LoggerFactory.getLogger(this.getClass());
+
+ private final RuntimeArtifactRepository artifactRepository;
+
+ private final PackageAdminUtil packageAdminUtil;
+
+ private final BundleContext kernelBundleContext;
+
+ private final BundleContext userRegionBundleContext;
+
+ private final BundleListener bundleListener;
+
+ public ModelBundleListenerInitializer(@NonNull RuntimeArtifactRepository artifactRepository, @NonNull PackageAdminUtil packageAdminUtil,
+ @NonNull BundleContext kernelBundleContext, @NonNull BundleContext userRegionBundleContext) {
+ this.artifactRepository = artifactRepository;
+ this.packageAdminUtil = packageAdminUtil;
+ this.kernelBundleContext = kernelBundleContext;
+ this.userRegionBundleContext = userRegionBundleContext;
+ this.bundleListener = new ModelBundleListener(kernelBundleContext, artifactRepository, packageAdminUtil);
+ }
+
+ /**
+ * Registers a {@link BundleListener} with the OSGi framework. Enumerates any existing {@link Bundle}s that exist
+ * from the OSGi framework.
+ */
+ @PostConstruct
+ public void initialize() {
+ this.userRegionBundleContext.addBundleListener(bundleListener);
+ for (Bundle bundle : userRegionBundleContext.getBundles()) {
+ try {
+ this.artifactRepository.add(new BundleArtifact(kernelBundleContext, packageAdminUtil, bundle));
+ } catch (Exception e) {
+ logger.error(String.format("Exception adding bundle '%s:%s' to the repository", bundle.getSymbolicName(),
+ bundle.getVersion().toString()), e);
+ }
+ }
+ }
+
+ /**
+ * Unregisters the listener from the OSGi framework
+ */
+ @PreDestroy
+ public void destroy() {
+ this.userRegionBundleContext.removeBundleListener(bundleListener);
+ }
+}
diff --git a/org.eclipse.virgo.kernel.model/src/main/java/org/eclipse/virgo/kernel/model/internal/configurationadmin/ConfigurationArtifact.java b/org.eclipse.virgo.kernel.model/src/main/java/org/eclipse/virgo/kernel/model/internal/configurationadmin/ConfigurationArtifact.java
new file mode 100644
index 00000000..98a9bfb5
--- /dev/null
+++ b/org.eclipse.virgo.kernel.model/src/main/java/org/eclipse/virgo/kernel/model/internal/configurationadmin/ConfigurationArtifact.java
@@ -0,0 +1,92 @@
+/*******************************************************************************
+ * 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.model.internal.configurationadmin;
+
+import java.io.IOException;
+
+import org.eclipse.virgo.kernel.model.ArtifactState;
+import org.eclipse.virgo.kernel.model.internal.AbstractArtifact;
+import org.eclipse.virgo.kernel.serviceability.NonNull;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Version;
+import org.osgi.service.cm.ConfigurationAdmin;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+/**
+ * Implementation of {@link Artifact} that delegates to a Configuration Admin {@link Configuration}
+ * <p />
+ *
+ * <strong>Concurrent Semantics</strong><br />
+ *
+ * Threadsafe
+ *
+ */
+final class ConfigurationArtifact extends AbstractArtifact {
+
+ private final Logger logger = LoggerFactory.getLogger(this.getClass());
+
+ static final String TYPE = "configuration";
+
+ private final ConfigurationAdmin configurationAdmin;
+
+ private final String pid;
+
+ public ConfigurationArtifact(@NonNull BundleContext bundleContext, @NonNull ConfigurationAdmin configurationAdmin, @NonNull String pid) {
+ super(bundleContext, TYPE, pid, Version.emptyVersion);
+ this.configurationAdmin = configurationAdmin;
+ this.pid = pid;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public ArtifactState getState() {
+ return ArtifactState.ACTIVE;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean refresh() {
+ return false;
+ // Do nothing for a Configuration
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void start() {
+ // Do nothing for a Configuration
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void stop() {
+ // Do nothing for a Configuration
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void uninstall() {
+ try {
+ this.configurationAdmin.getConfiguration(this.pid).delete();
+ } catch (IOException e) {
+ logger.error("Unable to delete configuration for '{}'", this.pid);
+ throw new RuntimeException(String.format("Unable to delete configuration for '%s'", this.pid), e);
+ }
+ }
+
+}
diff --git a/org.eclipse.virgo.kernel.model/src/main/java/org/eclipse/virgo/kernel/model/internal/configurationadmin/ModelConfigurationListener.java b/org.eclipse.virgo.kernel.model/src/main/java/org/eclipse/virgo/kernel/model/internal/configurationadmin/ModelConfigurationListener.java
new file mode 100644
index 00000000..58ceb547
--- /dev/null
+++ b/org.eclipse.virgo.kernel.model/src/main/java/org/eclipse/virgo/kernel/model/internal/configurationadmin/ModelConfigurationListener.java
@@ -0,0 +1,83 @@
+/*******************************************************************************
+ * 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.model.internal.configurationadmin;
+
+import org.eclipse.virgo.kernel.model.Artifact;
+import org.eclipse.virgo.kernel.model.RuntimeArtifactRepository;
+import org.eclipse.virgo.kernel.serviceability.NonNull;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Version;
+import org.osgi.service.cm.ConfigurationAdmin;
+import org.osgi.service.cm.ConfigurationEvent;
+import org.osgi.service.cm.ConfigurationListener;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+/**
+ * Implementation of {@link ConfigurationListener} that notices {@link ConfigurationEvent#CM_UPDATED} and
+ * {@link ConfigurationEvent#CM_DELETED} events to add and remove respectively {@link Artifact}s from the
+ * {@link RuntimeArtifactRepository}
+ * <p />
+ *
+ * <strong>Concurrent Semantics</strong><br />
+ *
+ * Threadsafe
+ *
+ */
+final class ModelConfigurationListener implements ConfigurationListener {
+
+ private final Logger logger = LoggerFactory.getLogger(this.getClass());
+
+ private final RuntimeArtifactRepository artifactRepository;
+
+ private final BundleContext bundleContext;
+
+ private final ConfigurationAdmin configurationAdmin;
+
+ public ModelConfigurationListener(@NonNull RuntimeArtifactRepository artifactRepository, @NonNull BundleContext bundleContext,
+ @NonNull ConfigurationAdmin configurationAdmin) {
+ this.artifactRepository = artifactRepository;
+ this.bundleContext = bundleContext;
+ this.configurationAdmin = configurationAdmin;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void configurationEvent(ConfigurationEvent event) {
+ if (ConfigurationEvent.CM_UPDATED == event.getType()) {
+ processUpdate(event);
+ } else if (ConfigurationEvent.CM_DELETED == event.getType()) {
+ processDelete(event);
+ }
+ }
+
+ private void processUpdate(ConfigurationEvent event) {
+ logger.info("Processing update event for '{}'", event.getPid());
+ this.artifactRepository.add(createArtifact(event));
+ }
+
+ private void processDelete(ConfigurationEvent event) {
+ logger.info("Processing delete event for '{}'", event.getPid());
+
+ Artifact artifact = this.artifactRepository.getArtifact(ConfigurationArtifact.TYPE, event.getPid(), Version.emptyVersion);
+ if (artifact instanceof ConfigurationArtifact) {
+ this.artifactRepository.remove(ConfigurationArtifact.TYPE, event.getPid(), Version.emptyVersion);
+ }
+ }
+
+ private ConfigurationArtifact createArtifact(ConfigurationEvent event) {
+ return new ConfigurationArtifact(this.bundleContext, this.configurationAdmin, event.getPid());
+ }
+
+}
diff --git a/org.eclipse.virgo.kernel.model/src/main/java/org/eclipse/virgo/kernel/model/internal/configurationadmin/ModelConfigurationListenerInitializer.java b/org.eclipse.virgo.kernel.model/src/main/java/org/eclipse/virgo/kernel/model/internal/configurationadmin/ModelConfigurationListenerInitializer.java
new file mode 100644
index 00000000..0ae30b23
--- /dev/null
+++ b/org.eclipse.virgo.kernel.model/src/main/java/org/eclipse/virgo/kernel/model/internal/configurationadmin/ModelConfigurationListenerInitializer.java
@@ -0,0 +1,92 @@
+/*******************************************************************************
+ * 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.model.internal.configurationadmin;
+
+import java.io.IOException;
+
+import javax.annotation.PostConstruct;
+import javax.annotation.PreDestroy;
+
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.service.cm.Configuration;
+import org.osgi.service.cm.ConfigurationAdmin;
+import org.osgi.service.cm.ConfigurationListener;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+import org.eclipse.virgo.kernel.model.RuntimeArtifactRepository;
+import org.eclipse.virgo.kernel.serviceability.NonNull;
+import org.eclipse.virgo.util.osgi.ServiceRegistrationTracker;
+
+/**
+ * An initializer responsible for registering a {@link ModelConfigurationListener} and enumerating any existing
+ * {@link Configuration} objects from {@link ConfigurationAdmin}
+ * <p />
+ *
+ * <strong>Concurrent Semantics</strong><br />
+ *
+ * Threadsafe
+ *
+ * @see ModelConfigurationListener
+ */
+public final class ModelConfigurationListenerInitializer {
+
+ private final Logger logger = LoggerFactory.getLogger(this.getClass());
+
+ private final ServiceRegistrationTracker registrationTracker = new ServiceRegistrationTracker();
+
+ private final RuntimeArtifactRepository artifactRepository;
+
+ private final BundleContext bundleContext;
+
+ private final ConfigurationAdmin configurationAdmin;
+
+ public ModelConfigurationListenerInitializer(@NonNull RuntimeArtifactRepository artifactRepository, @NonNull BundleContext bundleContext,
+ @NonNull ConfigurationAdmin configurationAdmin) {
+ this.artifactRepository = artifactRepository;
+ this.bundleContext = bundleContext;
+ this.configurationAdmin = configurationAdmin;
+ }
+
+ /**
+ * Registers a {@link ModelConfigurationListener} with the service registry. Enumerates any existing
+ * {@link Configuration} objects that exist from {@link ConfigurationAdmin}.
+ *
+ * @throws IOException
+ * @throws InvalidSyntaxException
+ */
+ @PostConstruct
+ public void initialize() throws IOException, InvalidSyntaxException {
+ ModelConfigurationListener configurationListener = new ModelConfigurationListener(artifactRepository, bundleContext, configurationAdmin);
+ this.registrationTracker.track(this.bundleContext.registerService(ConfigurationListener.class.getCanonicalName(), configurationListener, null));
+ Configuration[] configurations = this.configurationAdmin.listConfigurations(null);
+ if (configurations != null) {
+ for (Configuration configuration : configurations) {
+ try {
+ this.artifactRepository.add(new ConfigurationArtifact(bundleContext, configurationAdmin, configuration.getPid()));
+ } catch (Exception e) {
+ logger.error(String.format("Exception adding configuration '%s' to the repository", configuration.getPid()), e);
+ }
+ }
+ }
+ }
+
+ /**
+ * Unregisters the listener from the service registry
+ */
+ @PreDestroy
+ public void destroy() {
+ this.registrationTracker.unregisterAll();
+ }
+}
diff --git a/org.eclipse.virgo.kernel.model/src/main/java/org/eclipse/virgo/kernel/model/internal/deployer/DeployerArtifact.java b/org.eclipse.virgo.kernel.model/src/main/java/org/eclipse/virgo/kernel/model/internal/deployer/DeployerArtifact.java
new file mode 100644
index 00000000..2a880e68
--- /dev/null
+++ b/org.eclipse.virgo.kernel.model/src/main/java/org/eclipse/virgo/kernel/model/internal/deployer/DeployerArtifact.java
@@ -0,0 +1,148 @@
+/*******************************************************************************
+ * 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.model.internal.deployer;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.TimeUnit;
+
+import org.eclipse.virgo.kernel.core.BlockingSignal;
+import org.eclipse.virgo.kernel.core.FailureSignalledException;
+import org.eclipse.virgo.kernel.deployer.core.DeploymentException;
+import org.eclipse.virgo.kernel.serviceability.NonNull;
+import org.osgi.framework.BundleContext;
+
+import org.eclipse.virgo.kernel.install.artifact.InstallArtifact;
+import org.eclipse.virgo.kernel.install.artifact.InstallArtifact.State;
+import org.eclipse.virgo.kernel.model.Artifact;
+import org.eclipse.virgo.kernel.model.ArtifactState;
+import org.eclipse.virgo.kernel.model.internal.AbstractArtifact;
+
+/**
+ * Implementation of {@link Artifact} that delegates to a Kernel {@link InstallArtifact}
+ * <p />
+ *
+ * <strong>Concurrent Semantics</strong><br />
+ *
+ * Threadsafe
+ *
+ */
+class DeployerArtifact extends AbstractArtifact {
+
+ private final InstallArtifact installArtifact;
+
+ public DeployerArtifact(@NonNull BundleContext bundleContext, @NonNull InstallArtifact installArtifact) {
+ super(bundleContext, installArtifact.getType(), installArtifact.getName(), installArtifact.getVersion());
+ this.installArtifact = installArtifact;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public final ArtifactState getState() {
+ return mapInstallArtifactState(this.installArtifact.getState());
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public final void start() {
+ try {
+ BlockingSignal signal = new BlockingSignal();
+ this.installArtifact.start(signal);
+ try {
+ if (!signal.awaitCompletion(5, TimeUnit.MINUTES)) {
+ throw new RuntimeException("Started failed");
+ }
+ } catch (FailureSignalledException fse) {
+ throw new RuntimeException(fse.getCause());
+ }
+ } catch (DeploymentException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public final void stop() {
+ try {
+ this.installArtifact.stop();
+ } catch (DeploymentException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public final void uninstall() {
+ try {
+ this.installArtifact.uninstall();
+ } catch (DeploymentException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public final boolean refresh() {
+ try {
+ return this.installArtifact.refresh();
+ } catch (DeploymentException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public final Map<String, String> getProperties() {
+ Set<String> propertyNames = this.installArtifact.getPropertyNames();
+ Map<String, String> result = new HashMap<String, String>(propertyNames.size());
+ for (String propertyName : propertyNames) {
+ String propertyValue = this.installArtifact.getProperty(propertyName);
+ // The property may have been deleted concurrently.
+ if (propertyValue != null) {
+ result.put(propertyName, propertyValue);
+ }
+ }
+ return Collections.unmodifiableMap(result);
+ }
+
+ private ArtifactState mapInstallArtifactState(State state) {
+ if (State.INITIAL == state) {
+ return ArtifactState.INITIAL;
+ } else if (State.INSTALLING == state) {
+ return ArtifactState.INSTALLING;
+ } else if (State.INSTALLED == state) {
+ return ArtifactState.INSTALLED;
+ } else if (State.RESOLVING == state) {
+ return ArtifactState.RESOLVING;
+ } else if (State.RESOLVED == state) {
+ return ArtifactState.RESOLVED;
+ } else if (State.STARTING == state) {
+ return ArtifactState.STARTING;
+ } else if (State.ACTIVE == state) {
+ return ArtifactState.ACTIVE;
+ } else if (State.STOPPING == state) {
+ return ArtifactState.STOPPING;
+ } else if (State.UNINSTALLING == state) {
+ return ArtifactState.UNINSTALLING;
+ } else {
+ return ArtifactState.UNINSTALLED;
+ }
+ }
+}
diff --git a/org.eclipse.virgo.kernel.model/src/main/java/org/eclipse/virgo/kernel/model/internal/deployer/DeployerBundleArtifact.java b/org.eclipse.virgo.kernel.model/src/main/java/org/eclipse/virgo/kernel/model/internal/deployer/DeployerBundleArtifact.java
new file mode 100644
index 00000000..3b99f6ea
--- /dev/null
+++ b/org.eclipse.virgo.kernel.model/src/main/java/org/eclipse/virgo/kernel/model/internal/deployer/DeployerBundleArtifact.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.model.internal.deployer;
+
+import java.net.URI;
+
+import org.eclipse.virgo.kernel.serviceability.NonNull;
+import org.osgi.framework.BundleContext;
+
+import org.eclipse.virgo.kernel.install.artifact.BundleInstallArtifact;
+import org.eclipse.virgo.kernel.model.BundleArtifact;
+
+final class DeployerBundleArtifact extends DeployerArtifact implements BundleArtifact {
+
+ private final BundleInstallArtifact installArtifact;
+
+ public DeployerBundleArtifact(@NonNull BundleContext bundleContext, @NonNull BundleInstallArtifact installArtifact) {
+ super(bundleContext, installArtifact);
+ this.installArtifact = installArtifact;
+ }
+
+ public void deleteEntry(String targetPath) {
+ this.installArtifact.deleteEntry(targetPath);
+
+ }
+
+ public void updateEntry(String inputPath, String targetPath) {
+ this.installArtifact.updateEntry(URI.create(inputPath), targetPath);
+ }
+
+}
diff --git a/org.eclipse.virgo.kernel.model/src/main/java/org/eclipse/virgo/kernel/model/internal/deployer/DeployerCompositeArtifact.java b/org.eclipse.virgo.kernel.model/src/main/java/org/eclipse/virgo/kernel/model/internal/deployer/DeployerCompositeArtifact.java
new file mode 100644
index 00000000..c424b585
--- /dev/null
+++ b/org.eclipse.virgo.kernel.model/src/main/java/org/eclipse/virgo/kernel/model/internal/deployer/DeployerCompositeArtifact.java
@@ -0,0 +1,60 @@
+/*******************************************************************************
+ * 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.model.internal.deployer;
+
+import org.eclipse.virgo.kernel.serviceability.NonNull;
+import org.osgi.framework.BundleContext;
+
+import org.eclipse.virgo.kernel.install.artifact.PlanInstallArtifact;
+import org.eclipse.virgo.kernel.model.CompositeArtifact;
+
+/**
+ * Implementation of {@link CompositeArtifact} that delegates to a Kernel {@link PlanInstallArtifact}
+ * <p />
+ *
+ * <strong>Concurrent Semantics</strong><br />
+ *
+ * Threadsafe
+ *
+ */
+final class DeployerCompositeArtifact extends DeployerArtifact implements CompositeArtifact {
+
+ private final PlanInstallArtifact installArtifact;
+
+ public DeployerCompositeArtifact(@NonNull BundleContext bundleContext, @NonNull PlanInstallArtifact installArtifact) {
+ super(bundleContext, installArtifact);
+ this.installArtifact = installArtifact;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean isAtomic() {
+ return this.installArtifact.isAtomic();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean isScoped() {
+ return this.installArtifact.isScoped();
+ }
+
+ /**
+ * Gets the underlying {@link PlanInstallArtifact} encapsulated by this {@link DeployerCompositeArtifact}
+ *
+ * @return The underlying {@link PlanInstallArtifact}
+ */
+ PlanInstallArtifact getInstallArtifact() {
+ return this.installArtifact;
+ }
+}
diff --git a/org.eclipse.virgo.kernel.model/src/main/java/org/eclipse/virgo/kernel/model/internal/deployer/DeployerCompositeArtifactDependencyDeterminer.java b/org.eclipse.virgo.kernel.model/src/main/java/org/eclipse/virgo/kernel/model/internal/deployer/DeployerCompositeArtifactDependencyDeterminer.java
new file mode 100644
index 00000000..fab5009c
--- /dev/null
+++ b/org.eclipse.virgo.kernel.model/src/main/java/org/eclipse/virgo/kernel/model/internal/deployer/DeployerCompositeArtifactDependencyDeterminer.java
@@ -0,0 +1,63 @@
+/*******************************************************************************
+ * 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.model.internal.deployer;
+
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.eclipse.virgo.kernel.install.artifact.InstallArtifact;
+import org.eclipse.virgo.kernel.model.Artifact;
+import org.eclipse.virgo.kernel.model.RuntimeArtifactRepository;
+import org.eclipse.virgo.kernel.model.internal.DependencyDeterminer;
+
+import org.eclipse.virgo.kernel.serviceability.NonNull;
+import org.eclipse.virgo.util.common.Tree;
+
+/**
+ * Implementation of {@link DependencyDeterminer} that reutns the dependent of a <code>Plan</code>. The dependents
+ * consist of the artifacts specified in the plan.
+ * <p />
+ *
+ * <strong>Concurrent Semantics</strong><br />
+ *
+ * Threadsafe
+ *
+ */
+public final class DeployerCompositeArtifactDependencyDeterminer implements DependencyDeterminer {
+
+ private final RuntimeArtifactRepository artifactRepository;
+
+ public DeployerCompositeArtifactDependencyDeterminer(@NonNull RuntimeArtifactRepository artifactRepository) {
+ this.artifactRepository = artifactRepository;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public Set<Artifact> getDependents(Artifact rootArtifact) {
+ if (!(rootArtifact instanceof DeployerCompositeArtifact)) {
+ return Collections.<Artifact> emptySet();
+ }
+
+ final Set<Artifact> dependents = new HashSet<Artifact>();
+ List<Tree<InstallArtifact>> children = ((DeployerCompositeArtifact) rootArtifact).getInstallArtifact().getTree().getChildren();
+ for (Tree<InstallArtifact> child : children) {
+ InstallArtifact artifact = child.getValue();
+ dependents.add(artifactRepository.getArtifact(artifact.getType(), artifact.getName(), artifact.getVersion()));
+ }
+
+ return dependents;
+ }
+
+}
diff --git a/org.eclipse.virgo.kernel.model/src/main/java/org/eclipse/virgo/kernel/model/internal/deployer/ModelInstallArtifactLifecycleListener.java b/org.eclipse.virgo.kernel.model/src/main/java/org/eclipse/virgo/kernel/model/internal/deployer/ModelInstallArtifactLifecycleListener.java
new file mode 100644
index 00000000..af480931
--- /dev/null
+++ b/org.eclipse.virgo.kernel.model/src/main/java/org/eclipse/virgo/kernel/model/internal/deployer/ModelInstallArtifactLifecycleListener.java
@@ -0,0 +1,117 @@
+/*******************************************************************************
+ * 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.model.internal.deployer;
+
+import org.eclipse.virgo.kernel.deployer.core.DeploymentException;
+import org.eclipse.virgo.kernel.serviceability.NonNull;
+import org.osgi.framework.BundleContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.eclipse.virgo.kernel.install.artifact.BundleInstallArtifact;
+import org.eclipse.virgo.kernel.install.artifact.InstallArtifact;
+import org.eclipse.virgo.kernel.install.artifact.InstallArtifactLifecycleListener;
+import org.eclipse.virgo.kernel.install.artifact.InstallArtifactLifecycleListenerSupport;
+import org.eclipse.virgo.kernel.install.artifact.PlanInstallArtifact;
+import org.eclipse.virgo.kernel.model.Artifact;
+import org.eclipse.virgo.kernel.model.RuntimeArtifactRepository;
+
+/**
+ * Implementation of {@link InstallArtifactLifecycleListener} that notices
+ * {@link InstallArtifactLifecycleListener#onInstalling(InstallArtifact)} and
+ * {@link InstallArtifactLifecycleListener#onUninstalled(InstallArtifact)} calls to add and remove respectively
+ * {@link Artifact}s from the {@link RuntimeArtifactRepository}
+ * <p />
+ * An existing artifact with the same type, name, and version as the incoming artifact is not replaced except in the
+ * case of a bundle. An existing {@link BundleArtifact} is replaced by an incoming {@link DeployerBundleArtifact}. This
+ * prevents the RAM being corrupted if an attempt it made to install an artifact which belongs to an existing install
+ * tree. See {@link TreeRestrictingInstallArtifactLifecycleListener}.
+ * <p />
+ *
+ * <strong>Concurrent Semantics</strong><br />
+ *
+ * Threadsafe
+ *
+ */
+class ModelInstallArtifactLifecycleListener extends InstallArtifactLifecycleListenerSupport {
+
+ private final Logger logger = LoggerFactory.getLogger(this.getClass());
+
+ private final RuntimeArtifactRepository artifactRepository;
+
+ private final BundleContext bundleContext;
+
+ public ModelInstallArtifactLifecycleListener(@NonNull BundleContext bundleContext, @NonNull RuntimeArtifactRepository artifactRepository) {
+ this.bundleContext = bundleContext;
+ this.artifactRepository = artifactRepository;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void onInstalling(InstallArtifact installArtifact) throws DeploymentException {
+ logEvent("installing", installArtifact);
+ if (installArtifact instanceof PlanInstallArtifact) {
+ addPlan((PlanInstallArtifact) installArtifact);
+ } else if (installArtifact instanceof BundleInstallArtifact) {
+ addOrReplaceBundle((BundleInstallArtifact) installArtifact);
+ } else {
+ addArtifact(installArtifact);
+ }
+ }
+
+ private void addPlan(PlanInstallArtifact planInstallArtifact) {
+ this.artifactRepository.add(new DeployerCompositeArtifact(this.bundleContext, planInstallArtifact));
+ }
+
+ private void addOrReplaceBundle(BundleInstallArtifact bundleInstallArtifact) {
+ Artifact existingBundleArtifact = this.artifactRepository.getArtifact(bundleInstallArtifact.getType(), bundleInstallArtifact.getName(),
+ bundleInstallArtifact.getVersion());
+ if (!(existingBundleArtifact instanceof DeployerBundleArtifact)) {
+ remove(bundleInstallArtifact);
+ this.artifactRepository.add(new DeployerBundleArtifact(this.bundleContext, bundleInstallArtifact));
+ }
+ }
+
+ private void addArtifact(InstallArtifact installArtifact) {
+ this.artifactRepository.add(new DeployerArtifact(this.bundleContext, installArtifact));
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void onInstallFailed(InstallArtifact installArtifact) throws DeploymentException {
+ logEvent("install failed", installArtifact);
+ remove(installArtifact);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void onUninstalled(InstallArtifact installArtifact) throws DeploymentException {
+ logEvent("uninstalled", installArtifact);
+ remove(installArtifact);
+ }
+
+ private void logEvent(String event, InstallArtifact installArtifact) {
+ this.logger.info("Processing " + event + " event for {} '{}' version '{}'", new String[] { installArtifact.getType(),
+ installArtifact.getName(), installArtifact.getVersion().toString() });
+ }
+
+ private void remove(InstallArtifact installArtifact) {
+ this.artifactRepository.remove(installArtifact.getType(), installArtifact.getName(), installArtifact.getVersion());
+ }
+
+}
diff --git a/org.eclipse.virgo.kernel.model/src/main/java/org/eclipse/virgo/kernel/model/internal/deployer/ModelInstallArtifactLifecycleListenerInitializer.java b/org.eclipse.virgo.kernel.model/src/main/java/org/eclipse/virgo/kernel/model/internal/deployer/ModelInstallArtifactLifecycleListenerInitializer.java
new file mode 100644
index 00000000..493a380d
--- /dev/null
+++ b/org.eclipse.virgo.kernel.model/src/main/java/org/eclipse/virgo/kernel/model/internal/deployer/ModelInstallArtifactLifecycleListenerInitializer.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.model.internal.deployer;
+
+import javax.annotation.PostConstruct;
+
+import org.osgi.framework.BundleContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.eclipse.virgo.kernel.install.artifact.BundleInstallArtifact;
+import org.eclipse.virgo.kernel.install.artifact.InstallArtifact;
+import org.eclipse.virgo.kernel.install.artifact.InstallArtifactLifecycleListener;
+import org.eclipse.virgo.kernel.install.artifact.PlanInstallArtifact;
+import org.eclipse.virgo.kernel.model.RuntimeArtifactRepository;
+
+import org.eclipse.virgo.kernel.deployer.core.DeploymentIdentity;
+import org.eclipse.virgo.kernel.deployer.model.RuntimeArtifactModel;
+import org.eclipse.virgo.kernel.serviceability.NonNull;
+import org.eclipse.virgo.util.osgi.ServiceRegistrationTracker;
+
+/**
+ * An initializer responsible for registering a {@link ModelInstallArtifactLifecycleListener} and enumerating any
+ * existing {@link InstallArtifact} objects from the Kernel deployer
+ * <p />
+ *
+ * <strong>Concurrent Semantics</strong><br />
+ *
+ * TODO Document concurrent semantics of ModelInstallArtifactLifecycleListenerInitializer
+ *
+ * @see ModelInstallArtifactLifecycleListener
+ */
+public final class ModelInstallArtifactLifecycleListenerInitializer {
+
+ private final Logger logger = LoggerFactory.getLogger(this.getClass());
+
+ private final RuntimeArtifactRepository artifactRepository;
+
+ private final BundleContext bundleContext;
+
+ private final RuntimeArtifactModel runtimeArtifactModel;
+
+ private final ServiceRegistrationTracker registrationTracker = new ServiceRegistrationTracker();
+
+ public ModelInstallArtifactLifecycleListenerInitializer(@NonNull RuntimeArtifactRepository artifactRepository,
+ @NonNull BundleContext bundleContext, @NonNull RuntimeArtifactModel runtimeArtifactModel) {
+ this.artifactRepository = artifactRepository;
+ this.bundleContext = bundleContext;
+ this.runtimeArtifactModel = runtimeArtifactModel;
+ }
+
+ /**
+ * Registers a {@link ModelInstallArtifactLifecycleListener} with the service registry. Enumerates any existing
+ * {@link InstallArtifact} objects that exist from the Kernel deployer
+ */
+ @PostConstruct
+ public void initialize() {
+ ModelInstallArtifactLifecycleListener listener = new ModelInstallArtifactLifecycleListener(this.bundleContext, this.artifactRepository);
+ this.registrationTracker.track(this.bundleContext.registerService(InstallArtifactLifecycleListener.class.getCanonicalName(), listener, null));
+ for (DeploymentIdentity deploymentIdentity : this.runtimeArtifactModel.getDeploymentIdentities()) {
+ InstallArtifact installArtifact = this.runtimeArtifactModel.get(deploymentIdentity);
+ try {
+ if (installArtifact instanceof PlanInstallArtifact) {
+ this.artifactRepository.add(new DeployerCompositeArtifact(this.bundleContext, (PlanInstallArtifact) installArtifact));
+ } else if (installArtifact instanceof BundleInstallArtifact) {
+ this.artifactRepository.remove(installArtifact.getType(), installArtifact.getName(), installArtifact.getVersion());
+ this.artifactRepository.add(new DeployerBundleArtifact(this.bundleContext, (BundleInstallArtifact) installArtifact));
+ } else {
+ this.artifactRepository.remove(installArtifact.getType(), installArtifact.getName(), installArtifact.getVersion());
+ this.artifactRepository.add(new DeployerArtifact(this.bundleContext, installArtifact));
+ }
+ } catch (Exception e) {
+ logger.error(String.format("Exception adding deployer artifact '%s:%s' to the repository", installArtifact.getName(),
+ installArtifact.getVersion().toString()), e);
+ }
+ }
+ }
+
+ /**
+ * Unregisters the listener from the service registry
+ */
+ public void destroy() {
+ this.registrationTracker.unregisterAll();
+ }
+}
diff --git a/org.eclipse.virgo.kernel.model/src/main/java/org/eclipse/virgo/kernel/model/management/InstallException.java b/org.eclipse.virgo.kernel.model/src/main/java/org/eclipse/virgo/kernel/model/management/InstallException.java
new file mode 100644
index 00000000..4a5162d3
--- /dev/null
+++ b/org.eclipse.virgo.kernel.model/src/main/java/org/eclipse/virgo/kernel/model/management/InstallException.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.model.management;
+
+/**
+ * An exception thrown during the process of installing an artifact
+ * <p />
+ *
+ * <strong>Concurrent Semantics</strong><br />
+ *
+ * Thread-safe
+ *
+ */
+public final class InstallException extends Exception {
+
+ private static final long serialVersionUID = -7001124052781481556L;
+
+ public InstallException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ public InstallException(String message) {
+ super(message);
+ }
+
+}
diff --git a/org.eclipse.virgo.kernel.model/src/main/java/org/eclipse/virgo/kernel/model/management/Installer.java b/org.eclipse.virgo.kernel.model/src/main/java/org/eclipse/virgo/kernel/model/management/Installer.java
new file mode 100644
index 00000000..a6ae50b4
--- /dev/null
+++ b/org.eclipse.virgo.kernel.model/src/main/java/org/eclipse/virgo/kernel/model/management/Installer.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.model.management;
+
+import javax.management.MXBean;
+import javax.management.ObjectName;
+
+/**
+ * Allows the installation of an artifact from a URI.
+ * <p />
+ *
+ * <strong>Concurrent Semantics</strong><br />
+ *
+ * Implementations must be threadsafe
+ *
+ */
+@MXBean
+public interface Installer {
+
+ /**
+ * Install an artifact from a URI. This URI's scheme can be something like <code>file:</code> or
+ * <code>repository:</code>.
+ *
+ * @param uri The artifacts URI
+ * @return The name of the Object in the model
+ * @throws InstallException
+ */
+ ObjectName install(String uri) throws InstallException;
+}
diff --git a/org.eclipse.virgo.kernel.model/src/main/java/org/eclipse/virgo/kernel/model/management/ManageableArtifact.java b/org.eclipse.virgo.kernel.model/src/main/java/org/eclipse/virgo/kernel/model/management/ManageableArtifact.java
new file mode 100644
index 00000000..9a2204d3
--- /dev/null
+++ b/org.eclipse.virgo.kernel.model/src/main/java/org/eclipse/virgo/kernel/model/management/ManageableArtifact.java
@@ -0,0 +1,98 @@
+/*******************************************************************************
+ * 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.model.management;
+
+import java.util.Map;
+
+import javax.management.MXBean;
+import javax.management.ObjectName;
+
+import org.osgi.framework.Version;
+
+/**
+ * Represents an artifact in the runtime model of this system. Acts as a generic interface that delegates to the richer
+ * {@Artifact} type and translates types that are JMX-unfriendly to types that are JMX-friendly.
+ * <p />
+ *
+ * <strong>Concurrent Semantics</strong><br />
+ *
+ * Implementations must be threadsafe
+ *
+ */
+@MXBean
+public interface ManageableArtifact {
+
+ /**
+ * Start this {@link ManageableArtifact}
+ */
+ void start();
+
+ /**
+ * Stop this {@link ManageableArtifact}
+ */
+ void stop();
+
+ /**
+ * Update and refresh the contents of this {@link ManageableArtifact}
+ * @return true if refresh is successful, false if refresh is not done
+ */
+ boolean refresh();
+
+ /**
+ * Uninstall this {@link ManageableArtifact}
+ */
+ void uninstall();
+
+ /**
+ * Get the {@link ManageableArtifact}s that this {@link ManageableArtifact} depends on. The dependency can be of any
+ * kind and will be determined by the type of {@link ManageableArtifact} represented.
+ *
+ * @return This {@link ManageableArtifact}'s dependents
+ */
+ ObjectName[] getDependents();
+
+ /**
+ * Get the type of this {@link ManageableArtifact}
+ *
+ * @return The type of this {@link ManageableArtifact}
+ */
+ String getType();
+
+ /**
+ * Get the name of this {@link ManageableArtifact}
+ *
+ * @return The name of this {@link ManageableArtifact}
+ */
+ String getName();
+
+ /**
+ * Get the {@link Version} of this {@link ManageableArtifact}
+ *
+ * @return The @{link Version} of this {@link ManageableArtifact}
+ */
+ String getVersion();
+
+ /**
+ * Get the state of this {@link ManageableArtifact}
+ *
+ * @return The state of this {@link ManageableArtifact}
+ */
+ String getState();
+
+ /**
+ * Get this {@link ManageableArtifact}'s properties. This map is free to hold any properties contributed by any
+ * collaborator.
+ *
+ * @return This {@link ManageableArtifact}'s properties
+ */
+ Map<String, String> getProperties();
+}
diff --git a/org.eclipse.virgo.kernel.model/src/main/java/org/eclipse/virgo/kernel/model/management/ManageableBundleArtifact.java b/org.eclipse.virgo.kernel.model/src/main/java/org/eclipse/virgo/kernel/model/management/ManageableBundleArtifact.java
new file mode 100644
index 00000000..32297c0e
--- /dev/null
+++ b/org.eclipse.virgo.kernel.model/src/main/java/org/eclipse/virgo/kernel/model/management/ManageableBundleArtifact.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.model.management;
+
+import javax.management.MXBean;
+
+/**
+ * Represents a bundle artifact (an artifact that represents an OSGi bundle) in the runtime model of this system. Acts
+ * as a generic interface that delegates to the richer {@BundleArtifact} type and translates types that
+ * are JMX-unfriendly to types that are JMX-friendly.
+ * <p />
+ *
+ * <strong>Concurrent Semantics</strong><br />
+ *
+ * Implementations must be threadsafe
+ *
+ */
+@MXBean
+public interface ManageableBundleArtifact extends ManageableArtifact {
+
+ /**
+ * Update an entry within this bundle. If the target path does not already exist, creates a new entry at that
+ * location.
+ *
+ * @param inputPath The path to read update from
+ * @param targetPath The bundle relative path to write the update to
+ */
+ void updateEntry(String inputPath, String targetPath);
+
+ /**
+ * Delete an entry in a bundle
+ *
+ * @param targetPath The bundle relative path to delete
+ */
+ void deleteEntry(String targetPath);
+}
diff --git a/org.eclipse.virgo.kernel.model/src/main/java/org/eclipse/virgo/kernel/model/management/ManageableCompositeArtifact.java b/org.eclipse.virgo.kernel.model/src/main/java/org/eclipse/virgo/kernel/model/management/ManageableCompositeArtifact.java
new file mode 100644
index 00000000..5de87ff9
--- /dev/null
+++ b/org.eclipse.virgo.kernel.model/src/main/java/org/eclipse/virgo/kernel/model/management/ManageableCompositeArtifact.java
@@ -0,0 +1,44 @@
+/*******************************************************************************
+ * 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.model.management;
+
+import javax.management.MXBean;
+
+/**
+ * Represents a composite artifact (an artifact that contains other artifacts) in the runtime model of this system. Acts
+ * as a generic interface that delegates to the richer {@CompositeArtifact} type and translates
+ * types that are JMX-unfriendly to types that are JMX-friendly.
+ * <p />
+ *
+ * <strong>Concurrent Semantics</strong><br />
+ *
+ * Implementations must be threadsafe
+ *
+ */
+@MXBean
+public interface ManageableCompositeArtifact extends ManageableArtifact {
+
+ /**
+ * Get whether this @{link ManageableCompositeArtifact} is scoped or not
+ *
+ * @return Whether this {@link ManageableCompositeArtifact} is scoped or not
+ */
+ boolean isScoped();
+
+ /**
+ * Get whether this @{link ManageableCompositeArtifact} is atomic or not
+ *
+ * @return Whether this {@link ManageableCompositeArtifact} is atomic or not
+ */
+ boolean isAtomic();
+
+}
diff --git a/org.eclipse.virgo.kernel.model/src/main/java/org/eclipse/virgo/kernel/model/management/RuntimeArtifactModelObjectNameCreator.java b/org.eclipse.virgo.kernel.model/src/main/java/org/eclipse/virgo/kernel/model/management/RuntimeArtifactModelObjectNameCreator.java
new file mode 100644
index 00000000..7c70a376
--- /dev/null
+++ b/org.eclipse.virgo.kernel.model/src/main/java/org/eclipse/virgo/kernel/model/management/RuntimeArtifactModelObjectNameCreator.java
@@ -0,0 +1,102 @@
+/*******************************************************************************
+ * 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.model.management;
+
+import javax.management.ObjectName;
+
+import org.eclipse.virgo.kernel.model.Artifact;
+import org.eclipse.virgo.kernel.model.internal.AbstractArtifact;
+import org.osgi.framework.Version;
+
+
+/**
+ * An strategy interface for creating object names based on an input {@link Artifact}
+ * <p />
+ *
+ * <strong>Concurrent Semantics</strong><br />
+ *
+ * Implementations must be threadsafe
+ *
+ */
+public interface RuntimeArtifactModelObjectNameCreator {
+
+ /**
+ * Create an {@link ObjectName} based on an input {@link Artifact}. Names generated from equal (
+ * {@link AbstractArtifact#equals(Object)}) {@link Artifact}s should be equal as well.
+ *
+ * @param artifact The artifact to generate an {@link ObjectName} for
+ * @return The {@link ObjectName} for the {@link Artifact}
+ */
+ ObjectName create(Artifact artifact);
+
+ /**
+ * Creates an {@link ObjectName} based on an input type, name, and version.
+ *
+ * @param type The type of the object to create an @{link ObjectName} for
+ * @param name The name of the object to create an @{link ObjectName} for
+ * @param version The version of the object to create an @{link ObjectName} for
+ * @return An {@link ObjectName} for the runtime artifact represented by this type name and version
+ */
+ ObjectName create(String type, String name, Version version);
+
+ /**
+ * Creates a query {@link ObjectName} that can be used to enumerate all of the artifacts in the runtime artifact
+ * model
+ *
+ * @return An {@link ObjectName} that can be used for querying
+ */
+ ObjectName createArtifactsQuery();
+
+ /**
+ * Creates a query {@link ObjectName} that can be used to enumerate all of the artifacts of a given type in the
+ * runtime artifact model
+ *
+ * @param type The type of artifacts to query for
+ * @return An {@link ObjectName} that can be used for querying
+ */
+ ObjectName createArtifactsOfTypeQuery(String type);
+
+ /**
+ * Creates a query {@link ObjectName} that can be used to enumerate all of the versions of a given artifact type and
+ * name in the runtime artifact model
+ *
+ * @param type The type of artifacts to query for
+ * @param name The name of artifacts to query for
+ * @return An {@link ObjectName} that can be used for querying
+ */
+ ObjectName createArtifactVersionsQuery(String type, String name);
+
+ /**
+ * Gets the type of an artifact identified by an {@link ObjectName}
+ *
+ * @param objectName The identifying {@link ObjectName}
+ * @return The type of the artifact
+ */
+ String getType(ObjectName objectName);
+
+ /**
+ * Gets the name of an artifact identified by an {@link ObjectName}
+ *
+ * @param objectName The identifying {@link ObjectName}
+ * @return The name of the artifact
+ */
+ String getName(ObjectName objectName);
+
+ /**
+ * Gets the version of an artifact identified by an {@link ObjectName}
+ *
+ * @param objectName The identifying {@link ObjectName}
+ * @return The version of the artifact
+ */
+ String getVersion(ObjectName objectName);
+
+}
diff --git a/org.eclipse.virgo.kernel.model/src/main/java/org/eclipse/virgo/kernel/model/management/internal/DefaultRuntimeArtifactModelObjectNameCreator.java b/org.eclipse.virgo.kernel.model/src/main/java/org/eclipse/virgo/kernel/model/management/internal/DefaultRuntimeArtifactModelObjectNameCreator.java
new file mode 100644
index 00000000..0ab5ee66
--- /dev/null
+++ b/org.eclipse.virgo.kernel.model/src/main/java/org/eclipse/virgo/kernel/model/management/internal/DefaultRuntimeArtifactModelObjectNameCreator.java
@@ -0,0 +1,121 @@
+/*******************************************************************************
+ * 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.model.management.internal;
+
+import javax.management.MalformedObjectNameException;
+import javax.management.ObjectName;
+
+import org.eclipse.virgo.kernel.model.Artifact;
+import org.eclipse.virgo.kernel.model.management.RuntimeArtifactModelObjectNameCreator;
+import org.eclipse.virgo.kernel.serviceability.NonNull;
+import org.osgi.framework.Version;
+
+
+/**
+ * The default implementation of {@link RuntimeArtifactModelObjectNameCreator}. This implementation creates names based
+ * on the following pattern:
+ * <p />
+ * <code>&lt;domain&gt;:type=Model,artifact-type=&lt;type&gt;,name=&lt;name&gt;,version=&lt;version&gt;</code>
+ *
+ * <strong>Concurrent Semantics</strong><br />
+ *
+ * Threadsafe
+ *
+ */
+public final class DefaultRuntimeArtifactModelObjectNameCreator implements RuntimeArtifactModelObjectNameCreator {
+
+ private static final String ARTIFACTS_FORMAT = "%s:type=Model,*";
+
+ private static final String ARTIFACTS_OF_TYPE_FORMAT = "%s:type=Model,artifact-type=%s,*";
+
+ private static final String ARTIFACTS_OF_TYPE_AND_NAME_FORMAT = "%s:type=Model,artifact-type=%s,name=%s,*";
+
+ private static final String ARTIFACT_FORMAT = "%s:type=Model,artifact-type=%s,name=%s,version=%s";
+
+ private static final String KEY_TYPE = "artifact-type";
+
+ private static final String KEY_NAME = "name";
+
+ private static final String KEY_VERSION = "version";
+
+ private final String domain;
+
+ public DefaultRuntimeArtifactModelObjectNameCreator(String domain) {
+ this.domain = domain;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public ObjectName create(@NonNull Artifact artifact) {
+ return create(artifact.getType(), artifact.getName(), artifact.getVersion());
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public ObjectName create(String type, String name, Version version) {
+ return createObjectName(String.format(ARTIFACT_FORMAT, this.domain, type, name, version));
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public ObjectName createArtifactsOfTypeQuery(String type) {
+ return createObjectName(String.format(ARTIFACTS_OF_TYPE_FORMAT, this.domain, type));
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public ObjectName createArtifactVersionsQuery(String type, String name) {
+ return createObjectName(String.format(ARTIFACTS_OF_TYPE_AND_NAME_FORMAT, this.domain, type, name));
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public ObjectName createArtifactsQuery() {
+ return createObjectName(String.format(ARTIFACTS_FORMAT, this.domain));
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public String getType(ObjectName objectName) {
+ return objectName.getKeyProperty(KEY_TYPE);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public String getName(ObjectName objectName) {
+ return objectName.getKeyProperty(KEY_NAME);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public String getVersion(ObjectName objectName) {
+ return objectName.getKeyProperty(KEY_VERSION);
+ }
+
+ private ObjectName createObjectName(String objectName) {
+ try {
+ return new ObjectName(objectName);
+ } catch (MalformedObjectNameException e) {
+ throw new RuntimeException(String.format("Unable to create object name '%s'", objectName), e);
+ } catch (NullPointerException e) {
+ throw new RuntimeException(String.format("Unable to create object name '%s'", objectName), e);
+ }
+ }
+}
diff --git a/org.eclipse.virgo.kernel.model/src/main/java/org/eclipse/virgo/kernel/model/management/internal/DelegatingInstaller.java b/org.eclipse.virgo.kernel.model/src/main/java/org/eclipse/virgo/kernel/model/management/internal/DelegatingInstaller.java
new file mode 100644
index 00000000..17307d19
--- /dev/null
+++ b/org.eclipse.virgo.kernel.model/src/main/java/org/eclipse/virgo/kernel/model/management/internal/DelegatingInstaller.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.model.management.internal;
+
+import java.net.URI;
+
+import javax.management.ObjectName;
+
+import org.eclipse.virgo.kernel.deployer.core.ApplicationDeployer;
+import org.eclipse.virgo.kernel.deployer.core.DeploymentException;
+import org.eclipse.virgo.kernel.deployer.core.DeploymentIdentity;
+import org.eclipse.virgo.kernel.model.management.InstallException;
+import org.eclipse.virgo.kernel.model.management.Installer;
+import org.eclipse.virgo.kernel.model.management.RuntimeArtifactModelObjectNameCreator;
+import org.osgi.framework.Version;
+
+
+/**
+ * Implementation of {@link Installer} that delegates to the deployer
+ * <p />
+ *
+ * <strong>Concurrent Semantics</strong><br />
+ *
+ * Threadsafe
+ *
+ */
+public final class DelegatingInstaller implements Installer {
+
+ private final ApplicationDeployer deployer;
+
+ private final RuntimeArtifactModelObjectNameCreator artifactObjectNameCreator;
+
+ public DelegatingInstaller(ApplicationDeployer deployer, RuntimeArtifactModelObjectNameCreator artifactObjectNameCreator) {
+ this.deployer = deployer;
+ this.artifactObjectNameCreator = artifactObjectNameCreator;
+ }
+
+ public ObjectName install(String uri) throws InstallException {
+ DeploymentIdentity deploymentIdentity;
+ try {
+ deploymentIdentity = this.deployer.install(URI.create(uri));
+ } catch (DeploymentException e) {
+ throw new InstallException(String.format("Exception encountered while installing '%s'", uri), e);
+ }
+ return this.artifactObjectNameCreator.create(deploymentIdentity.getType(), deploymentIdentity.getSymbolicName(),
+ new Version(deploymentIdentity.getVersion()));
+ }
+
+}
diff --git a/org.eclipse.virgo.kernel.model/src/main/java/org/eclipse/virgo/kernel/model/management/internal/DelegatingManageableArtifact.java b/org.eclipse.virgo.kernel.model/src/main/java/org/eclipse/virgo/kernel/model/management/internal/DelegatingManageableArtifact.java
new file mode 100644
index 00000000..48dd83cd
--- /dev/null
+++ b/org.eclipse.virgo.kernel.model/src/main/java/org/eclipse/virgo/kernel/model/management/internal/DelegatingManageableArtifact.java
@@ -0,0 +1,131 @@
+/*******************************************************************************
+ * 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.model.management.internal;
+
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import javax.management.ObjectName;
+
+import org.eclipse.virgo.kernel.model.Artifact;
+import org.eclipse.virgo.kernel.model.management.ManageableArtifact;
+import org.eclipse.virgo.kernel.model.management.RuntimeArtifactModelObjectNameCreator;
+import org.eclipse.virgo.kernel.serviceability.NonNull;
+
+
+/**
+ * Implementation of {@link ManageableArtifact} that delegates to an {@link Artifact} for all methods and translates
+ * types that are JMX-unfriendly to types that are JMX-friendly
+ * <p />
+ *
+ * <strong>Concurrent Semantics</strong><br />
+ *
+ * Threadsafe
+ *
+ * @see Artifact
+ */
+class DelegatingManageableArtifact implements ManageableArtifact {
+
+ private final RuntimeArtifactModelObjectNameCreator artifactObjectNameCreator;
+
+ private final Artifact artifact;
+
+ public DelegatingManageableArtifact(@NonNull RuntimeArtifactModelObjectNameCreator artifactObjectNameCreator, @NonNull Artifact artifact) {
+ this.artifactObjectNameCreator = artifactObjectNameCreator;
+ this.artifact = artifact;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public final ObjectName[] getDependents() {
+ return convertToObjectNames(this.artifact.getDependents());
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public final String getName() {
+ return this.artifact.getName();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public final String getState() {
+ return this.artifact.getState().toString();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public final String getType() {
+ return this.artifact.getType();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public final String getVersion() {
+ return this.artifact.getVersion().toString();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public final boolean refresh() {
+ return this.artifact.refresh();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public final void start() {
+ this.artifact.start();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public final void stop() {
+ this.artifact.stop();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public final void uninstall() {
+ this.artifact.uninstall();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public final Map<String, String> getProperties() {
+ return this.artifact.getProperties();
+ }
+
+ /**
+ * Convert a collection of {@link Artifact}s to a collection of {@link ObjectName}s
+ *
+ * @param artifacts The {@link Artifact}s to convert
+ * @return The {@link ObjectName}s converted to
+ */
+ protected final ObjectName[] convertToObjectNames(Set<Artifact> artifacts) {
+ Set<ObjectName> objectNames = new HashSet<ObjectName>(artifacts.size());
+ for (Artifact artifact : artifacts) {
+ objectNames.add(artifactObjectNameCreator.create(artifact));
+ }
+ return objectNames.toArray(new ObjectName[objectNames.size()]);
+ }
+}
diff --git a/org.eclipse.virgo.kernel.model/src/main/java/org/eclipse/virgo/kernel/model/management/internal/DelegatingManageableBundleArtifact.java b/org.eclipse.virgo.kernel.model/src/main/java/org/eclipse/virgo/kernel/model/management/internal/DelegatingManageableBundleArtifact.java
new file mode 100644
index 00000000..54dbd62c
--- /dev/null
+++ b/org.eclipse.virgo.kernel.model/src/main/java/org/eclipse/virgo/kernel/model/management/internal/DelegatingManageableBundleArtifact.java
@@ -0,0 +1,49 @@
+/*******************************************************************************
+ * 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.model.management.internal;
+
+import org.eclipse.virgo.kernel.model.BundleArtifact;
+import org.eclipse.virgo.kernel.model.management.ManageableBundleArtifact;
+import org.eclipse.virgo.kernel.model.management.RuntimeArtifactModelObjectNameCreator;
+import org.eclipse.virgo.kernel.serviceability.NonNull;
+
+
+/**
+ * Implementation of {@link ManageableBundleArtifact} that delegates to a {@link BundleArtifact} for all methods and
+ * translates types that are JMX-unfriendly to types that are JMX-friendly
+ * <p />
+ *
+ * <strong>Concurrent Semantics</strong><br />
+ *
+ * Threadsafe
+ *
+ * @see BundleArtifact
+ */
+final class DelegatingManageableBundleArtifact extends DelegatingManageableArtifact implements ManageableBundleArtifact {
+
+ private final BundleArtifact bundleArtifact;
+
+ public DelegatingManageableBundleArtifact(@NonNull RuntimeArtifactModelObjectNameCreator artifactObjectNameCreator,
+ @NonNull BundleArtifact bundleArtifact) {
+ super(artifactObjectNameCreator, bundleArtifact);
+ this.bundleArtifact = bundleArtifact;
+ }
+
+ public void deleteEntry(String targetPath) {
+ this.bundleArtifact.deleteEntry(targetPath);
+ }
+
+ public void updateEntry(String inputPath, String targetPath) {
+ this.bundleArtifact.updateEntry(inputPath, targetPath);
+ }
+
+}
diff --git a/org.eclipse.virgo.kernel.model/src/main/java/org/eclipse/virgo/kernel/model/management/internal/DelegatingManageableCompositeArtifact.java b/org.eclipse.virgo.kernel.model/src/main/java/org/eclipse/virgo/kernel/model/management/internal/DelegatingManageableCompositeArtifact.java
new file mode 100644
index 00000000..f0520145
--- /dev/null
+++ b/org.eclipse.virgo.kernel.model/src/main/java/org/eclipse/virgo/kernel/model/management/internal/DelegatingManageableCompositeArtifact.java
@@ -0,0 +1,54 @@
+/*******************************************************************************
+ * 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.model.management.internal;
+
+import org.eclipse.virgo.kernel.model.CompositeArtifact;
+import org.eclipse.virgo.kernel.model.management.ManageableCompositeArtifact;
+import org.eclipse.virgo.kernel.model.management.RuntimeArtifactModelObjectNameCreator;
+import org.eclipse.virgo.kernel.serviceability.NonNull;
+
+
+/**
+ * Implementation of {@link ManageableCompositeArtifact} that delegates to an {@link CompositeArtifact} for all methods
+ * and translates types that are JMX-unfriendly to types that are JMX-friendly
+ * <p />
+ *
+ * <strong>Concurrent Semantics</strong><br />
+ *
+ * Threadsafe
+ *
+ * @see CompositeArtifact
+ */
+final class DelegatingManageableCompositeArtifact extends DelegatingManageableArtifact implements ManageableCompositeArtifact {
+
+ private final CompositeArtifact planArtifact;
+
+ public DelegatingManageableCompositeArtifact(@NonNull RuntimeArtifactModelObjectNameCreator artifactObjectNameCreator, @NonNull CompositeArtifact planArtifact) {
+ super(artifactObjectNameCreator, planArtifact);
+ this.planArtifact = planArtifact;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean isAtomic() {
+ return this.planArtifact.isAtomic();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean isScoped() {
+ return this.planArtifact.isScoped();
+ }
+
+}
diff --git a/org.eclipse.virgo.kernel.model/src/main/java/org/eclipse/virgo/kernel/model/management/internal/JmxArtifactRepositoryListener.java b/org.eclipse.virgo.kernel.model/src/main/java/org/eclipse/virgo/kernel/model/management/internal/JmxArtifactRepositoryListener.java
new file mode 100644
index 00000000..5765a3c7
--- /dev/null
+++ b/org.eclipse.virgo.kernel.model/src/main/java/org/eclipse/virgo/kernel/model/management/internal/JmxArtifactRepositoryListener.java
@@ -0,0 +1,108 @@
+/*******************************************************************************
+ * 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.model.management.internal;
+
+import java.lang.management.ManagementFactory;
+import java.util.Set;
+
+import javax.management.InstanceAlreadyExistsException;
+import javax.management.InstanceNotFoundException;
+import javax.management.MBeanRegistrationException;
+import javax.management.MBeanServer;
+import javax.management.NotCompliantMBeanException;
+import javax.management.ObjectName;
+
+import org.eclipse.virgo.kernel.model.Artifact;
+import org.eclipse.virgo.kernel.model.BundleArtifact;
+import org.eclipse.virgo.kernel.model.CompositeArtifact;
+import org.eclipse.virgo.kernel.model.internal.ArtifactRepositoryListener;
+import org.eclipse.virgo.kernel.model.management.RuntimeArtifactModelObjectNameCreator;
+import org.eclipse.virgo.kernel.serviceability.NonNull;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+/**
+ * An implementation of {@link ArtifactRepositoryListener} that notices creation and deletion of {@link Artifact}s and
+ * adds and removes respectively MBeans from the JMX MBeanServer
+ * <p />
+ *
+ * <strong>Concurrent Semantics</strong><br />
+ *
+ * Threadsafe
+ *
+ */
+public class JmxArtifactRepositoryListener implements ArtifactRepositoryListener {
+
+ private final Logger logger = LoggerFactory.getLogger(this.getClass());
+
+ private final MBeanServer server = ManagementFactory.getPlatformMBeanServer();
+
+ private final RuntimeArtifactModelObjectNameCreator artifactObjectNameCreator;
+
+ public JmxArtifactRepositoryListener(@NonNull RuntimeArtifactModelObjectNameCreator artifactObjectNameCreator) {
+ this.artifactObjectNameCreator = artifactObjectNameCreator;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void added(Artifact artifact) {
+ ObjectName objectName = this.artifactObjectNameCreator.create(artifact);
+
+ try {
+ if (artifact instanceof CompositeArtifact) {
+ this.server.registerMBean(new DelegatingManageableCompositeArtifact(this.artifactObjectNameCreator, (CompositeArtifact) artifact),
+ objectName);
+ } else if (artifact instanceof BundleArtifact) {
+ this.server.registerMBean(new DelegatingManageableBundleArtifact(this.artifactObjectNameCreator, (BundleArtifact) artifact),
+ objectName);
+ } else {
+ this.server.registerMBean(new DelegatingManageableArtifact(this.artifactObjectNameCreator, artifact), objectName);
+ }
+ } catch (InstanceAlreadyExistsException e) {
+ logger.error(String.format("Unable to register '%s'", objectName.toString()), e);
+ } catch (MBeanRegistrationException e) {
+ logger.error(String.format("Unable to register '%s'", objectName.toString()), e);
+ } catch (NotCompliantMBeanException e) {
+ logger.error(String.format("Unable to register '%s'", objectName.toString()), e);
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void removed(Artifact artifact) {
+ ObjectName objectName = this.artifactObjectNameCreator.create(artifact);
+
+ try {
+ this.server.unregisterMBean(objectName);
+ } catch (MBeanRegistrationException e) {
+ logger.error(String.format("Unable to unregister '%s'", objectName.toString()), e);
+ } catch (InstanceNotFoundException e) {
+ logger.error(String.format("Unable to unregister '%s'", objectName.toString()), e);
+ }
+ }
+
+ public void destroy() {
+ Set<ObjectName> objectNames = this.server.queryNames(this.artifactObjectNameCreator.createArtifactsQuery(), null);
+ for (ObjectName objectName : objectNames) {
+ try {
+ this.server.unregisterMBean(objectName);
+ } catch (MBeanRegistrationException e) {
+ // Swallow exception to allow others to proceed
+ } catch (InstanceNotFoundException e) {
+ // Swallow exception to allow others to proceed
+ }
+ }
+ }
+}
diff --git a/org.eclipse.virgo.kernel.model/src/main/resources/META-INF/spring/module-context.xml b/org.eclipse.virgo.kernel.model/src/main/resources/META-INF/spring/module-context.xml
new file mode 100644
index 00000000..78edaead
--- /dev/null
+++ b/org.eclipse.virgo.kernel.model/src/main/resources/META-INF/spring/module-context.xml
@@ -0,0 +1,75 @@
+<?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:context="http://www.springframework.org/schema/context"
+ xsi:schemaLocation="
+ http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
+ http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd">
+
+ <bean class="org.eclipse.virgo.kernel.model.internal.bundle.ModelBundleListenerInitializer">
+ <constructor-arg ref="artifactRepository"/>
+ <constructor-arg ref="packageAdminUtil"/>
+ <constructor-arg ref="bundleContext"/>
+ <constructor-arg ref="userBundleContext"/>
+ </bean>
+
+ <bean class="org.eclipse.virgo.kernel.model.internal.configurationadmin.ModelConfigurationListenerInitializer">
+ <constructor-arg ref="artifactRepository"/>
+ <constructor-arg ref="bundleContext"/>
+ <constructor-arg ref="configurationAdmin"/>
+ </bean>
+
+ <bean class="org.eclipse.virgo.kernel.model.internal.deployer.ModelInstallArtifactLifecycleListenerInitializer">
+ <constructor-arg ref="artifactRepository"/>
+ <constructor-arg ref="bundleContext"/>
+ <constructor-arg ref="runtimeArtifactModel"/>
+ </bean>
+
+ <bean id="bundleDependencyDeterminer" class="org.eclipse.virgo.kernel.model.internal.bundle.BundleDependencyDeterminer">
+ <constructor-arg ref="quasiFrameworkFactory"/>
+ <constructor-arg ref="artifactRepository"/>
+ </bean>
+
+ <bean id="deployerCompositeArtifactDependencyDeterminer"
+ class="org.eclipse.virgo.kernel.model.internal.deployer.DeployerCompositeArtifactDependencyDeterminer">
+ <constructor-arg ref="artifactRepository"/>
+ </bean>
+
+ <bean id="artifactRepository" class="org.eclipse.virgo.kernel.model.internal.NotifyingRuntimeArtifactRepository">
+ <constructor-arg ref="artifactRepositoryListener"/>
+ </bean>
+
+ <bean id="artifactRepositoryListener" class="org.eclipse.virgo.kernel.model.management.internal.JmxArtifactRepositoryListener"
+ destroy-method="destroy">
+ <constructor-arg ref="runtimeArtifactModelObjectNameCreator"/>
+ </bean>
+
+ <bean id="runtimeArtifactModelObjectNameCreator" class="org.eclipse.virgo.kernel.model.management.internal.DefaultRuntimeArtifactModelObjectNameCreator">
+ <constructor-arg value="${domain}"/>
+ </bean>
+
+ <bean id="installer" class="org.eclipse.virgo.kernel.model.management.internal.DelegatingInstaller">
+ <constructor-arg ref="applicationDeployer"/>
+ <constructor-arg ref="runtimeArtifactModelObjectNameCreator"/>
+ </bean>
+
+ <context:property-placeholder properties-ref="config-admin"/>
+
+ <context:annotation-config/>
+
+ <bean id="exporter" class="org.springframework.jmx.export.MBeanExporter">
+ <property name="beans">
+ <map>
+ <entry key="installer" value-ref="installer"/>
+ </map>
+ </property>
+ <property name="namingStrategy">
+ <bean class="org.springframework.jmx.export.naming.KeyNamingStrategy">
+ <property name="mappings">
+ <props>
+ <prop key="installer">${domain}:type=Model,name=installer</prop>
+ </props>
+ </property>
+ </bean>
+ </property>
+ </bean>
+
+</beans>
diff --git a/org.eclipse.virgo.kernel.model/src/main/resources/META-INF/spring/osgi-context.xml b/org.eclipse.virgo.kernel.model/src/main/resources/META-INF/spring/osgi-context.xml
new file mode 100644
index 00000000..d47d47e8
--- /dev/null
+++ b/org.eclipse.virgo.kernel.model/src/main/resources/META-INF/spring/osgi-context.xml
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<beans:beans
+ xmlns="http://www.springframework.org/schema/osgi"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns:beans="http://www.springframework.org/schema/beans"
+ xmlns:osgi-compendium="http://www.springframework.org/schema/osgi-compendium"
+ xsi:schemaLocation="
+ http://www.springframework.org/schema/osgi-compendium http://www.springframework.org/schema/osgi-compendium/spring-osgi-compendium-1.2.xsd
+ 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-2.0.xsd">
+
+ <service ref="artifactRepository" interface="org.eclipse.virgo.kernel.model.RuntimeArtifactRepository"/>
+
+ <service ref="bundleDependencyDeterminer" interface="org.eclipse.virgo.kernel.model.internal.DependencyDeterminer">
+ <service-properties>
+ <beans:entry key="artifactType" value="bundle"/>
+ </service-properties>
+ </service>
+
+ <service ref="deployerCompositeArtifactDependencyDeterminer" interface="org.eclipse.virgo.kernel.model.internal.DependencyDeterminer">
+ <service-properties>
+ <beans:entry key="artifactType" value="plan"/>
+ </service-properties>
+ </service>
+
+ <service ref="deployerCompositeArtifactDependencyDeterminer" interface="org.eclipse.virgo.kernel.model.internal.DependencyDeterminer">
+ <service-properties>
+ <beans:entry key="artifactType" value="par"/>
+ </service-properties>
+ </service>
+
+ <service ref="runtimeArtifactModelObjectNameCreator" interface="org.eclipse.virgo.kernel.model.management.RuntimeArtifactModelObjectNameCreator"/>
+
+ <reference id="packageAdminUtil" interface="org.eclipse.virgo.kernel.osgi.framework.PackageAdminUtil"/>
+
+ <reference id="configurationAdmin" interface="org.osgi.service.cm.ConfigurationAdmin"/>
+
+ <reference id="quasiFrameworkFactory" interface="org.eclipse.virgo.kernel.osgi.quasi.QuasiFrameworkFactory"/>
+
+ <reference id="runtimeArtifactModel" interface="org.eclipse.virgo.kernel.deployer.model.RuntimeArtifactModel"/>
+
+ <reference id="userBundleContext" interface="org.osgi.framework.BundleContext" filter="(org.eclipse.virgo.kernel.regionContext=true)"/>
+
+ <reference id="applicationDeployer" interface="org.eclipse.virgo.kernel.deployer.core.ApplicationDeployer"/>
+
+ <osgi-compendium:cm-properties id="config-admin" persistent-id="org.eclipse.virgo.kernel"/>
+
+</beans:beans>
diff --git a/org.eclipse.virgo.kernel.model/src/test/java/org/eclipse/virgo/kernel/model/StubArtifactRepository.java b/org.eclipse.virgo.kernel.model/src/test/java/org/eclipse/virgo/kernel/model/StubArtifactRepository.java
new file mode 100644
index 00000000..6ffa70ae
--- /dev/null
+++ b/org.eclipse.virgo.kernel.model/src/test/java/org/eclipse/virgo/kernel/model/StubArtifactRepository.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.model;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import org.eclipse.virgo.kernel.model.Artifact;
+import org.eclipse.virgo.kernel.model.RuntimeArtifactRepository;
+import org.osgi.framework.Version;
+
+public class StubArtifactRepository implements RuntimeArtifactRepository {
+
+ private final Set<Artifact> artifacts = new HashSet<Artifact>();
+
+ public boolean add(Artifact artifact) {
+ return this.artifacts.add(artifact);
+ }
+
+ public boolean remove(String type, String name, Version version) {
+ return this.artifacts.remove(getArtifact(type, name, version));
+ }
+
+ public Set<Artifact> getArtifacts() {
+ return this.artifacts;
+ }
+
+ public Artifact getArtifact(String type, String name, Version version) {
+ for (Artifact artifact : this.artifacts) {
+ if (artifact.getType().equals(type) && artifact.getName().equals(name) && artifact.getVersion().equals(version)) {
+ return artifact;
+ }
+ }
+ return null;
+ }
+}
diff --git a/org.eclipse.virgo.kernel.model/src/test/java/org/eclipse/virgo/kernel/model/StubCompositeArtifact.java b/org.eclipse.virgo.kernel.model/src/test/java/org/eclipse/virgo/kernel/model/StubCompositeArtifact.java
new file mode 100644
index 00000000..7d2508ed
--- /dev/null
+++ b/org.eclipse.virgo.kernel.model/src/test/java/org/eclipse/virgo/kernel/model/StubCompositeArtifact.java
@@ -0,0 +1,72 @@
+/*******************************************************************************
+ * 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.model;
+
+import java.util.Map;
+import java.util.Set;
+
+import org.eclipse.virgo.kernel.model.Artifact;
+import org.eclipse.virgo.kernel.model.ArtifactState;
+import org.eclipse.virgo.kernel.model.CompositeArtifact;
+import org.osgi.framework.Version;
+
+public class StubCompositeArtifact implements CompositeArtifact {
+
+ public Set<Artifact> getDependents() {
+ throw new UnsupportedOperationException();
+ }
+
+ public String getName() {
+ return "test-name";
+ }
+
+ public ArtifactState getState() {
+ throw new UnsupportedOperationException();
+ }
+
+ public String getType() {
+ return "test-type";
+ }
+
+ public Version getVersion() {
+ return Version.emptyVersion;
+ }
+
+ public boolean refresh() {
+ throw new UnsupportedOperationException();
+ }
+
+ public void start() {
+ throw new UnsupportedOperationException();
+ }
+
+ public void stop() {
+ throw new UnsupportedOperationException();
+ }
+
+ public void uninstall() {
+ throw new UnsupportedOperationException();
+ }
+
+ public boolean isAtomic() {
+ throw new UnsupportedOperationException();
+ }
+
+ public boolean isScoped() {
+ throw new UnsupportedOperationException();
+ }
+
+ public Map<String, String> getProperties() {
+ throw new UnsupportedOperationException();
+ }
+
+}
diff --git a/org.eclipse.virgo.kernel.model/src/test/java/org/eclipse/virgo/kernel/model/internal/AbztractArtifactTests.java b/org.eclipse.virgo.kernel.model/src/test/java/org/eclipse/virgo/kernel/model/internal/AbztractArtifactTests.java
new file mode 100644
index 00000000..0d312f5e
--- /dev/null
+++ b/org.eclipse.virgo.kernel.model/src/test/java/org/eclipse/virgo/kernel/model/internal/AbztractArtifactTests.java
@@ -0,0 +1,151 @@
+/*******************************************************************************
+ * 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.model.internal;
+
+import static org.easymock.EasyMock.createMock;
+import static org.easymock.EasyMock.expect;
+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.HashSet;
+import java.util.Hashtable;
+import java.util.Set;
+
+import org.junit.Test;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Version;
+
+
+import org.eclipse.virgo.kernel.model.Artifact;
+import org.eclipse.virgo.kernel.model.ArtifactState;
+import org.eclipse.virgo.kernel.model.StubCompositeArtifact;
+import org.eclipse.virgo.kernel.model.internal.AbstractArtifact;
+import org.eclipse.virgo.kernel.model.internal.DependencyDeterminer;
+import org.eclipse.virgo.kernel.serviceability.Assert.FatalAssertionException;
+import org.eclipse.virgo.teststubs.osgi.framework.StubBundleContext;
+import org.eclipse.virgo.teststubs.osgi.support.TrueFilter;
+
+public class AbztractArtifactTests {
+
+ private final StubBundleContext bundleContext;
+
+ private final AbstractArtifact artifact;
+
+ {
+ bundleContext = new StubBundleContext();
+ String filterString = String.format("(&(objectClass=%s)(artifactType=test-type))", DependencyDeterminer.class.getCanonicalName());
+ bundleContext.addFilter(filterString, new TrueFilter(filterString));
+ artifact = new StubArtifact(bundleContext, "test-type", "test-name", Version.emptyVersion);
+ }
+
+ @Test(expected = FatalAssertionException.class)
+ public void nullBundleContext() {
+ new StubArtifact(null, "type", "name", Version.emptyVersion);
+ }
+
+ @Test(expected = FatalAssertionException.class)
+ public void nullType() {
+ new StubArtifact(new StubBundleContext(), null, "name", Version.emptyVersion);
+ }
+
+ @Test(expected = FatalAssertionException.class)
+ public void nullName() {
+ new StubArtifact(new StubBundleContext(), "type", null, Version.emptyVersion);
+ }
+
+ @Test(expected = FatalAssertionException.class)
+ public void nullVersion() {
+ new StubArtifact(new StubBundleContext(), "type", "name", null);
+ }
+
+ @Test(expected = RuntimeException.class)
+ public void badFilter() {
+ new StubArtifact(new StubBundleContext(), "type", "name", Version.emptyVersion);
+ }
+
+ @Test
+ public void getType() {
+ assertEquals("test-type", artifact.getType());
+ }
+
+ @Test
+ public void getName() {
+ assertEquals("test-name", artifact.getName());
+ }
+
+ @Test
+ public void getVersion() {
+ assertEquals(Version.emptyVersion, artifact.getVersion());
+ }
+
+ @SuppressWarnings("unchecked")
+ @Test
+ public void getDependents() {
+ assertEquals(0, artifact.getDependents().size());
+
+ DependencyDeterminer determiner = createMock(DependencyDeterminer.class);
+ Dictionary properties = new Hashtable();
+ properties.put("artifactType", "test-type");
+ bundleContext.registerService(DependencyDeterminer.class.getCanonicalName(), determiner, properties);
+
+ expect(determiner.getDependents(artifact)).andReturn(getArtifacts());
+ replay(determiner);
+ assertEquals(3, artifact.getDependents().size());
+ verify(determiner);
+ }
+
+ @Test
+ public void getProperties() {
+ assertEquals(0, artifact.getProperties().size());
+ }
+
+ private Set<Artifact> getArtifacts() {
+ Set<Artifact> artifacts = new HashSet<Artifact>();
+ for (int i = 0; i < 3; i++) {
+ artifacts.add(new StubCompositeArtifact());
+ }
+ return artifacts;
+ }
+
+ private static class StubArtifact extends AbstractArtifact {
+
+ public StubArtifact(BundleContext bundleContext) {
+ super(bundleContext, "test-type", "test-name", Version.emptyVersion);
+ }
+
+ public StubArtifact(BundleContext bundleContext, String type, String name, Version version) {
+ super(bundleContext, type, name, version);
+ }
+
+ public ArtifactState getState() {
+ throw new UnsupportedOperationException();
+ }
+
+ public boolean refresh() {
+ throw new UnsupportedOperationException();
+ }
+
+ public void start() {
+ throw new UnsupportedOperationException();
+ }
+
+ public void stop() {
+ throw new UnsupportedOperationException();
+ }
+
+ public void uninstall() {
+ throw new UnsupportedOperationException();
+ }
+ }
+}
diff --git a/org.eclipse.virgo.kernel.model/src/test/java/org/eclipse/virgo/kernel/model/internal/NotifyingArtifactRepositoryTests.java b/org.eclipse.virgo.kernel.model/src/test/java/org/eclipse/virgo/kernel/model/internal/NotifyingArtifactRepositoryTests.java
new file mode 100644
index 00000000..00e0e128
--- /dev/null
+++ b/org.eclipse.virgo.kernel.model/src/test/java/org/eclipse/virgo/kernel/model/internal/NotifyingArtifactRepositoryTests.java
@@ -0,0 +1,104 @@
+/*******************************************************************************
+ * 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.model.internal;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotSame;
+import static org.junit.Assert.assertTrue;
+
+import java.util.Set;
+
+import org.eclipse.virgo.kernel.model.Artifact;
+import org.eclipse.virgo.kernel.model.StubCompositeArtifact;
+import org.eclipse.virgo.kernel.model.internal.ArtifactRepositoryListener;
+import org.eclipse.virgo.kernel.model.internal.NotifyingRuntimeArtifactRepository;
+import org.junit.Test;
+
+
+public class NotifyingArtifactRepositoryTests {
+
+ private final NotifyingRuntimeArtifactRepository artifactRepository = new NotifyingRuntimeArtifactRepository();
+
+ @Test
+ public void add() {
+ StubCompositeArtifact artifact = new StubCompositeArtifact();
+ assertTrue(this.artifactRepository.add(artifact));
+ assertFalse(this.artifactRepository.add(artifact));
+ }
+
+ @Test
+ public void remove() {
+ StubCompositeArtifact artifact = new StubCompositeArtifact();
+ assertTrue(this.artifactRepository.add(artifact));
+ assertTrue(this.artifactRepository.remove(artifact.getType(), artifact.getName(), artifact.getVersion()));
+ assertFalse(this.artifactRepository.remove(artifact.getType(), artifact.getName(), artifact.getVersion()));
+ }
+
+ @Test
+ public void listeners() {
+ StubArtifactRepositoryListener listener1 = new StubArtifactRepositoryListener(true);
+ StubArtifactRepositoryListener listener2 = new StubArtifactRepositoryListener(false);
+ NotifyingRuntimeArtifactRepository artifactRepository = new NotifyingRuntimeArtifactRepository(listener1, listener2);
+ StubCompositeArtifact artifact = new StubCompositeArtifact();
+ artifactRepository.add(artifact);
+ artifactRepository.remove(artifact.getType(), artifact.getName(), artifact.getVersion());
+ assertTrue(listener1.getAdded());
+ assertTrue(listener2.getAdded());
+ assertTrue(listener1.getRemoved());
+ assertTrue(listener2.getRemoved());
+ }
+
+ @Test
+ public void getArtifacts() {
+ this.artifactRepository.add(new StubCompositeArtifact());
+ Set<Artifact> artifacts1 = this.artifactRepository.getArtifacts();
+ assertEquals(1, artifacts1.size());
+ Set<Artifact> artifacts2 = this.artifactRepository.getArtifacts();
+ assertNotSame(artifacts1, artifacts2);
+ }
+
+ private static class StubArtifactRepositoryListener implements ArtifactRepositoryListener {
+
+ private final boolean throwException;
+
+ private volatile boolean added = false;
+
+ private volatile boolean removed = false;
+
+ public StubArtifactRepositoryListener(boolean throwException) {
+ this.throwException = throwException;
+ }
+
+ public void added(Artifact artifact) {
+ this.added = true;
+ if (throwException) {
+ throw new RuntimeException();
+ }
+ }
+
+ public void removed(Artifact artifact) {
+ this.removed = true;
+ if (throwException) {
+ throw new RuntimeException();
+ }
+ }
+
+ public boolean getAdded() {
+ return added;
+ }
+
+ public boolean getRemoved() {
+ return removed;
+ }
+ }
+}
diff --git a/org.eclipse.virgo.kernel.model/src/test/java/org/eclipse/virgo/kernel/model/internal/bundle/BundleArtifactTests.java b/org.eclipse.virgo.kernel.model/src/test/java/org/eclipse/virgo/kernel/model/internal/bundle/BundleArtifactTests.java
new file mode 100644
index 00000000..b27975af
--- /dev/null
+++ b/org.eclipse.virgo.kernel.model/src/test/java/org/eclipse/virgo/kernel/model/internal/bundle/BundleArtifactTests.java
@@ -0,0 +1,117 @@
+/*******************************************************************************
+ * 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.model.internal.bundle;
+
+import static org.easymock.EasyMock.aryEq;
+import static org.easymock.EasyMock.createMock;
+import static org.easymock.EasyMock.replay;
+import static org.easymock.EasyMock.verify;
+import static org.junit.Assert.assertEquals;
+
+import org.junit.Test;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleException;
+
+import org.eclipse.virgo.kernel.osgi.framework.PackageAdminUtil;
+
+import org.eclipse.virgo.kernel.model.ArtifactState;
+import org.eclipse.virgo.kernel.model.internal.AbstractArtifact;
+import org.eclipse.virgo.kernel.model.internal.DependencyDeterminer;
+import org.eclipse.virgo.kernel.model.internal.bundle.BundleArtifact;
+import org.eclipse.virgo.kernel.serviceability.Assert.FatalAssertionException;
+import org.eclipse.virgo.teststubs.osgi.framework.StubBundle;
+import org.eclipse.virgo.teststubs.osgi.framework.StubBundleContext;
+import org.eclipse.virgo.teststubs.osgi.support.TrueFilter;
+
+public class BundleArtifactTests {
+
+ private final PackageAdminUtil packageAdminUtil = createMock(PackageAdminUtil.class);
+
+ private final StubBundle bundle = new StubBundle();
+
+ private final StubBundleContext bundleContext;
+
+ {
+ this.bundleContext = (StubBundleContext) bundle.getBundleContext();
+ String filterString = String.format("(&(objectClass=%s)(artifactType=bundle))", DependencyDeterminer.class.getCanonicalName());
+ bundleContext.addFilter(filterString, new TrueFilter(filterString));
+ }
+
+ private final AbstractArtifact artifact = new BundleArtifact(bundleContext, packageAdminUtil, bundle);
+
+ @Test(expected = FatalAssertionException.class)
+ public void nullBundleContext() {
+ new BundleArtifact(null, packageAdminUtil, bundle);
+ }
+
+ @Test(expected = FatalAssertionException.class)
+ public void nullPackageAdminUtil() {
+ new BundleArtifact(bundleContext, null, bundle);
+ }
+
+ @Test(expected = FatalAssertionException.class)
+ public void nullBundle() {
+ new BundleArtifact(bundleContext, packageAdminUtil, null);
+ }
+
+ @Test
+ public void getState() {
+ this.bundle.setState(Bundle.UNINSTALLED);
+ assertEquals(ArtifactState.UNINSTALLED, this.artifact.getState());
+ this.bundle.setState(Bundle.INSTALLED);
+ assertEquals(ArtifactState.INSTALLED, this.artifact.getState());
+ this.bundle.setState(Bundle.RESOLVED);
+ assertEquals(ArtifactState.RESOLVED, this.artifact.getState());
+ this.bundle.setState(Bundle.STARTING);
+ assertEquals(ArtifactState.STARTING, this.artifact.getState());
+ this.bundle.setState(Bundle.STOPPING);
+ assertEquals(ArtifactState.STOPPING, this.artifact.getState());
+ this.bundle.setState(Bundle.ACTIVE);
+ assertEquals(ArtifactState.ACTIVE, this.artifact.getState());
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void illegalState() {
+ this.bundle.setState(10000);
+ this.artifact.getState();
+ }
+
+ @Test
+ public void updateAndRefresh() {
+ this.packageAdminUtil.synchronouslyRefreshPackages(aryEq(new Bundle[] { this.bundle }));
+ replay(this.packageAdminUtil);
+ this.artifact.refresh();
+ verify(this.packageAdminUtil);
+ }
+
+ @Test
+ public void start() throws BundleException {
+ this.bundle.setState(Bundle.RESOLVED);
+ this.artifact.start();
+ assertEquals(Bundle.ACTIVE, this.bundle.getState());
+ }
+
+ @Test
+ public void stop() throws BundleException {
+ this.bundle.setState(Bundle.ACTIVE);
+ this.artifact.stop();
+ assertEquals(Bundle.RESOLVED, this.bundle.getState());
+
+ }
+
+ @Test
+ public void uninstall() throws BundleException {
+ this.bundle.setState(Bundle.ACTIVE);
+ this.artifact.uninstall();
+ assertEquals(Bundle.UNINSTALLED, this.bundle.getState());
+ }
+}
diff --git a/org.eclipse.virgo.kernel.model/src/test/java/org/eclipse/virgo/kernel/model/internal/bundle/BundleDependencyDeterminerTests.java b/org.eclipse.virgo.kernel.model/src/test/java/org/eclipse/virgo/kernel/model/internal/bundle/BundleDependencyDeterminerTests.java
new file mode 100644
index 00000000..457ec64d
--- /dev/null
+++ b/org.eclipse.virgo.kernel.model/src/test/java/org/eclipse/virgo/kernel/model/internal/bundle/BundleDependencyDeterminerTests.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.model.internal.bundle;
+
+import static org.easymock.EasyMock.createMock;
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.replay;
+import static org.easymock.EasyMock.verify;
+import static org.junit.Assert.assertEquals;
+
+import java.util.Collections;
+import java.util.Set;
+
+import org.eclipse.virgo.kernel.model.Artifact;
+import org.eclipse.virgo.kernel.model.RuntimeArtifactRepository;
+import org.eclipse.virgo.kernel.model.StubArtifactRepository;
+import org.eclipse.virgo.kernel.model.StubCompositeArtifact;
+import org.eclipse.virgo.kernel.model.internal.bundle.BundleDependencyDeterminer;
+import org.eclipse.virgo.kernel.serviceability.Assert.FatalAssertionException;
+import org.junit.Test;
+
+import org.eclipse.virgo.kernel.osgi.quasi.QuasiBundle;
+import org.eclipse.virgo.kernel.osgi.quasi.QuasiFramework;
+import org.eclipse.virgo.kernel.osgi.quasi.QuasiFrameworkFactory;
+
+public class BundleDependencyDeterminerTests {
+
+ private final QuasiFrameworkFactory quasiFrameworkFactory = createMock(QuasiFrameworkFactory.class);
+
+ private final RuntimeArtifactRepository artifactRepository = new StubArtifactRepository();
+
+ private final BundleDependencyDeterminer determiner = new BundleDependencyDeterminer(quasiFrameworkFactory, artifactRepository);
+
+ @Test(expected = FatalAssertionException.class)
+ public void nullFactory() {
+ new BundleDependencyDeterminer(null, artifactRepository);
+ }
+
+ @Test(expected = FatalAssertionException.class)
+ public void nullRepository() {
+ new BundleDependencyDeterminer(quasiFrameworkFactory, null);
+ }
+
+ @Test
+ public void unknownBundle() {
+ QuasiFramework framework = createMock(QuasiFramework.class);
+ expect(quasiFrameworkFactory.create()).andReturn(framework);
+ expect(framework.getBundles()).andReturn(Collections.<QuasiBundle> emptyList());
+ replay(quasiFrameworkFactory, framework);
+
+ Set<Artifact> dependents = this.determiner.getDependents(new StubCompositeArtifact());
+ assertEquals(Collections.<Artifact> emptySet(), dependents);
+
+ verify(quasiFrameworkFactory, framework);
+ }
+
+}
diff --git a/org.eclipse.virgo.kernel.model/src/test/java/org/eclipse/virgo/kernel/model/internal/bundle/ModelBundleListenerInitializerTests.java b/org.eclipse.virgo.kernel.model/src/test/java/org/eclipse/virgo/kernel/model/internal/bundle/ModelBundleListenerInitializerTests.java
new file mode 100644
index 00000000..760a6e4b
--- /dev/null
+++ b/org.eclipse.virgo.kernel.model/src/test/java/org/eclipse/virgo/kernel/model/internal/bundle/ModelBundleListenerInitializerTests.java
@@ -0,0 +1,84 @@
+/*******************************************************************************
+ * 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.model.internal.bundle;
+
+import static org.easymock.EasyMock.createMock;
+import static org.junit.Assert.assertEquals;
+
+import java.io.IOException;
+
+import org.junit.Test;
+import org.osgi.framework.InvalidSyntaxException;
+
+import org.eclipse.virgo.kernel.osgi.framework.PackageAdminUtil;
+
+import org.eclipse.virgo.kernel.model.StubArtifactRepository;
+import org.eclipse.virgo.kernel.model.internal.DependencyDeterminer;
+import org.eclipse.virgo.kernel.model.internal.bundle.ModelBundleListenerInitializer;
+import org.eclipse.virgo.kernel.serviceability.Assert.FatalAssertionException;
+import org.eclipse.virgo.teststubs.osgi.framework.StubBundle;
+import org.eclipse.virgo.teststubs.osgi.framework.StubBundleContext;
+import org.eclipse.virgo.teststubs.osgi.support.TrueFilter;
+
+public class ModelBundleListenerInitializerTests {
+
+ private final StubArtifactRepository artifactRepository = new StubArtifactRepository();
+
+ private final PackageAdminUtil packageAdminUtil = createMock(PackageAdminUtil.class);
+
+ private final StubBundleContext bundleContext;
+ {
+ StubBundle bundle = new StubBundle();
+ this.bundleContext = (StubBundleContext) bundle.getBundleContext();
+ String filterString = String.format("(&(objectClass=%s)(artifactType=bundle))", DependencyDeterminer.class.getCanonicalName());
+ this.bundleContext.addFilter(filterString, new TrueFilter(filterString));
+ this.bundleContext.addInstalledBundle(bundle);
+ }
+
+ private final ModelBundleListenerInitializer initializer = new ModelBundleListenerInitializer(artifactRepository, packageAdminUtil, bundleContext, bundleContext);
+
+ @Test(expected = FatalAssertionException.class)
+ public void nullArtifactRepository() {
+ new ModelBundleListenerInitializer(null, packageAdminUtil, bundleContext, bundleContext);
+ }
+
+ @Test(expected = FatalAssertionException.class)
+ public void nullPackageAdminUtil() {
+ new ModelBundleListenerInitializer(artifactRepository, null, bundleContext, bundleContext);
+ }
+
+ @Test(expected = FatalAssertionException.class)
+ public void nullKernelBundleContext() {
+ new ModelBundleListenerInitializer(artifactRepository, packageAdminUtil, null, bundleContext);
+ }
+
+ @Test(expected = FatalAssertionException.class)
+ public void nullUserBundleContext() {
+ new ModelBundleListenerInitializer(artifactRepository, packageAdminUtil, bundleContext, null);
+ }
+
+ @Test
+ public void initialize() throws IOException, InvalidSyntaxException {
+ assertEquals(0, this.bundleContext.getBundleListeners().size());
+ this.initializer.initialize();
+ assertEquals(1, this.bundleContext.getBundleListeners().size());
+ assertEquals(1, this.artifactRepository.getArtifacts().size());
+ }
+
+ @Test
+ public void destroy() throws IOException, InvalidSyntaxException {
+ this.initializer.initialize();
+ assertEquals(1, this.bundleContext.getBundleListeners().size());
+ this.initializer.destroy();
+ assertEquals(0, this.bundleContext.getBundleListeners().size());
+ }
+}
diff --git a/org.eclipse.virgo.kernel.model/src/test/java/org/eclipse/virgo/kernel/model/internal/bundle/ModelBundleListenerTests.java b/org.eclipse.virgo.kernel.model/src/test/java/org/eclipse/virgo/kernel/model/internal/bundle/ModelBundleListenerTests.java
new file mode 100644
index 00000000..98fda81e
--- /dev/null
+++ b/org.eclipse.virgo.kernel.model/src/test/java/org/eclipse/virgo/kernel/model/internal/bundle/ModelBundleListenerTests.java
@@ -0,0 +1,89 @@
+/*******************************************************************************
+ * 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.model.internal.bundle;
+
+import static org.easymock.EasyMock.createMock;
+import static org.junit.Assert.assertEquals;
+
+import org.junit.Test;
+import org.osgi.framework.BundleEvent;
+
+import org.eclipse.virgo.kernel.osgi.framework.PackageAdminUtil;
+
+import org.eclipse.virgo.kernel.model.StubArtifactRepository;
+import org.eclipse.virgo.kernel.model.internal.DependencyDeterminer;
+import org.eclipse.virgo.kernel.model.internal.bundle.ModelBundleListener;
+import org.eclipse.virgo.kernel.serviceability.Assert.FatalAssertionException;
+import org.eclipse.virgo.teststubs.osgi.framework.StubBundle;
+import org.eclipse.virgo.teststubs.osgi.framework.StubBundleContext;
+import org.eclipse.virgo.teststubs.osgi.support.TrueFilter;
+
+public class ModelBundleListenerTests {
+
+ private final StubArtifactRepository artifactRepository = new StubArtifactRepository();
+
+ private final PackageAdminUtil packageAdminUtil = createMock(PackageAdminUtil.class);
+
+ private final StubBundleContext bundleContext;
+ {
+ this.bundleContext = new StubBundleContext();
+ String filterString = String.format("(&(objectClass=%s)(artifactType=bundle))", DependencyDeterminer.class.getCanonicalName());
+ this.bundleContext.addFilter(filterString, new TrueFilter(filterString));
+ }
+
+ private final ModelBundleListener listener = new ModelBundleListener(bundleContext, artifactRepository, packageAdminUtil);
+
+ @Test(expected = FatalAssertionException.class)
+ public void nullBundleContext() {
+ new ModelBundleListener(null, artifactRepository, packageAdminUtil);
+ }
+
+ @Test(expected = FatalAssertionException.class)
+ public void nullArtifactRepository() {
+ new ModelBundleListener(bundleContext, null, packageAdminUtil);
+ }
+
+ @Test(expected = FatalAssertionException.class)
+ public void nullPackageAdminUtil() {
+ new ModelBundleListener(bundleContext, artifactRepository, null);
+ }
+
+ @Test
+ public void installed() {
+ assertEquals(0, this.artifactRepository.getArtifacts().size());
+ BundleEvent event1 = new BundleEvent(BundleEvent.INSTALLED, new StubBundle().setBundleContext(this.bundleContext));
+ this.listener.bundleChanged(event1);
+ assertEquals(1, this.artifactRepository.getArtifacts().size());
+ BundleEvent event2 = new BundleEvent(BundleEvent.INSTALLED, new StubBundle().setBundleContext(this.bundleContext));
+ this.listener.bundleChanged(event2);
+ assertEquals(1, this.artifactRepository.getArtifacts().size());
+ }
+
+ @Test
+ public void uninstalled() {
+ BundleEvent event1 = new BundleEvent(BundleEvent.INSTALLED, new StubBundle().setBundleContext(this.bundleContext));
+ this.listener.bundleChanged(event1);
+ assertEquals(1, this.artifactRepository.getArtifacts().size());
+ BundleEvent event2 = new BundleEvent(BundleEvent.UNINSTALLED, new StubBundle().setBundleContext(this.bundleContext));
+ this.listener.bundleChanged(event2);
+ assertEquals(0, this.artifactRepository.getArtifacts().size());
+ BundleEvent event3 = new BundleEvent(BundleEvent.UNINSTALLED, new StubBundle().setBundleContext(this.bundleContext));
+ this.listener.bundleChanged(event3);
+ assertEquals(0, this.artifactRepository.getArtifacts().size());
+ }
+
+ @Test
+ public void unknownEventType() {
+ BundleEvent event = new BundleEvent(-1, new StubBundle().setBundleContext(this.bundleContext));
+ this.listener.bundleChanged(event);
+ }
+}
diff --git a/org.eclipse.virgo.kernel.model/src/test/java/org/eclipse/virgo/kernel/model/internal/configurationadmin/ConfgurationArtifactTests.java b/org.eclipse.virgo.kernel.model/src/test/java/org/eclipse/virgo/kernel/model/internal/configurationadmin/ConfgurationArtifactTests.java
new file mode 100644
index 00000000..04de9dc0
--- /dev/null
+++ b/org.eclipse.virgo.kernel.model/src/test/java/org/eclipse/virgo/kernel/model/internal/configurationadmin/ConfgurationArtifactTests.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.model.internal.configurationadmin;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+
+import java.io.IOException;
+
+import org.junit.Test;
+import org.osgi.framework.InvalidSyntaxException;
+
+
+import org.eclipse.virgo.kernel.model.ArtifactState;
+import org.eclipse.virgo.kernel.model.internal.DependencyDeterminer;
+import org.eclipse.virgo.kernel.model.internal.configurationadmin.ConfigurationArtifact;
+import org.eclipse.virgo.kernel.serviceability.Assert.FatalAssertionException;
+import org.eclipse.virgo.teststubs.osgi.framework.StubBundleContext;
+import org.eclipse.virgo.teststubs.osgi.service.cm.StubConfigurationAdmin;
+import org.eclipse.virgo.teststubs.osgi.support.TrueFilter;
+
+public class ConfgurationArtifactTests {
+
+ private final StubBundleContext bundleContext;
+ {
+ bundleContext = new StubBundleContext();
+ String filterString = String.format("(&(objectClass=%s)(artifactType=configuration))", DependencyDeterminer.class.getCanonicalName());
+ bundleContext.addFilter(filterString, new TrueFilter(filterString));
+ }
+
+ private final StubConfigurationAdmin configurationAdmin = new StubConfigurationAdmin();
+
+ private final ConfigurationArtifact artifact = new ConfigurationArtifact(bundleContext, configurationAdmin, "test-pid");
+
+ @Test(expected = FatalAssertionException.class)
+ public void nullBundleContext() {
+ new ConfigurationArtifact(null, configurationAdmin, "test-pid");
+ }
+
+ @Test(expected = FatalAssertionException.class)
+ public void nullConfigurationAdmin() {
+ new ConfigurationArtifact(bundleContext, null, "test-pid");
+ }
+
+ @Test(expected = FatalAssertionException.class)
+ public void nullArtifactRepository() {
+ new ConfigurationArtifact(bundleContext, configurationAdmin, null);
+ }
+
+ @Test
+ public void getState() {
+ assertEquals(ArtifactState.ACTIVE, this.artifact.getState());
+ }
+
+ @Test
+ public void updateAndRefresh() {
+ this.artifact.refresh();
+ }
+
+ @Test
+ public void start() {
+ this.artifact.start();
+ }
+
+ @Test
+ public void stop() {
+ this.artifact.stop();
+ }
+
+ @Test
+ public void uninstall() throws IOException, InvalidSyntaxException {
+ this.configurationAdmin.createConfiguration("test-pid").addProperty("key", "value");
+ assertEquals(1, this.configurationAdmin.listConfigurations(null).length);
+ this.artifact.uninstall();
+ assertNull(this.configurationAdmin.listConfigurations(null));
+ }
+}
diff --git a/org.eclipse.virgo.kernel.model/src/test/java/org/eclipse/virgo/kernel/model/internal/configurationadmin/ModelConfigurationListenerInitializerTests.java b/org.eclipse.virgo.kernel.model/src/test/java/org/eclipse/virgo/kernel/model/internal/configurationadmin/ModelConfigurationListenerInitializerTests.java
new file mode 100644
index 00000000..a9028b7a
--- /dev/null
+++ b/org.eclipse.virgo.kernel.model/src/test/java/org/eclipse/virgo/kernel/model/internal/configurationadmin/ModelConfigurationListenerInitializerTests.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.model.internal.configurationadmin;
+
+import static org.junit.Assert.assertEquals;
+
+import java.io.IOException;
+
+import org.junit.Test;
+import org.osgi.framework.InvalidSyntaxException;
+
+
+import org.eclipse.virgo.kernel.model.StubArtifactRepository;
+import org.eclipse.virgo.kernel.model.internal.DependencyDeterminer;
+import org.eclipse.virgo.kernel.model.internal.configurationadmin.ModelConfigurationListenerInitializer;
+import org.eclipse.virgo.kernel.serviceability.Assert.FatalAssertionException;
+import org.eclipse.virgo.teststubs.osgi.framework.StubBundleContext;
+import org.eclipse.virgo.teststubs.osgi.service.cm.StubConfigurationAdmin;
+import org.eclipse.virgo.teststubs.osgi.support.TrueFilter;
+
+public class ModelConfigurationListenerInitializerTests {
+
+ private final StubArtifactRepository artifactRepository = new StubArtifactRepository();
+
+ private final StubBundleContext bundleContext = new StubBundleContext();
+ {
+ String filterString = String.format("(&(objectClass=%s)(artifactType=configuration))", DependencyDeterminer.class.getCanonicalName());
+ this.bundleContext.addFilter(filterString, new TrueFilter(filterString));
+ }
+
+ private final StubConfigurationAdmin configurationAdmin = new StubConfigurationAdmin();
+
+ private final ModelConfigurationListenerInitializer initializer = new ModelConfigurationListenerInitializer(artifactRepository, bundleContext,
+ configurationAdmin);
+
+ @Test(expected = FatalAssertionException.class)
+ public void nullArtifactRepository() {
+ new ModelConfigurationListenerInitializer(null, bundleContext, configurationAdmin);
+ }
+
+ @Test(expected = FatalAssertionException.class)
+ public void nullBundleContext() {
+ new ModelConfigurationListenerInitializer(artifactRepository, null, configurationAdmin);
+ }
+
+ @Test(expected = FatalAssertionException.class)
+ public void nullConfigurationAdmin() {
+ new ModelConfigurationListenerInitializer(artifactRepository, bundleContext, null);
+ }
+
+ @Test
+ public void initialize() throws IOException, InvalidSyntaxException {
+ this.configurationAdmin.createConfiguration("test-pid").addProperty("key", "value");
+ assertEquals(0, this.bundleContext.getServiceRegistrations().size());
+ this.initializer.initialize();
+ assertEquals(1, this.bundleContext.getServiceRegistrations().size());
+ assertEquals(1, this.artifactRepository.getArtifacts().size());
+ }
+
+ @Test
+ public void destroy() throws IOException, InvalidSyntaxException {
+ this.initializer.initialize();
+ assertEquals(1, this.bundleContext.getServiceRegistrations().size());
+ this.initializer.destroy();
+ assertEquals(0, this.bundleContext.getServiceRegistrations().size());
+ }
+}
diff --git a/org.eclipse.virgo.kernel.model/src/test/java/org/eclipse/virgo/kernel/model/internal/configurationadmin/ModelConfigurationListenerTests.java b/org.eclipse.virgo.kernel.model/src/test/java/org/eclipse/virgo/kernel/model/internal/configurationadmin/ModelConfigurationListenerTests.java
new file mode 100644
index 00000000..d85fa3cf
--- /dev/null
+++ b/org.eclipse.virgo.kernel.model/src/test/java/org/eclipse/virgo/kernel/model/internal/configurationadmin/ModelConfigurationListenerTests.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.model.internal.configurationadmin;
+
+import static org.junit.Assert.assertEquals;
+
+import org.junit.Test;
+import org.osgi.framework.ServiceReference;
+import org.osgi.service.cm.ConfigurationAdmin;
+import org.osgi.service.cm.ConfigurationEvent;
+
+
+import org.eclipse.virgo.kernel.model.StubArtifactRepository;
+import org.eclipse.virgo.kernel.model.internal.DependencyDeterminer;
+import org.eclipse.virgo.kernel.model.internal.configurationadmin.ModelConfigurationListener;
+import org.eclipse.virgo.kernel.serviceability.Assert.FatalAssertionException;
+import org.eclipse.virgo.teststubs.osgi.framework.StubBundleContext;
+import org.eclipse.virgo.teststubs.osgi.framework.StubServiceRegistration;
+import org.eclipse.virgo.teststubs.osgi.service.cm.StubConfigurationAdmin;
+import org.eclipse.virgo.teststubs.osgi.support.TrueFilter;
+
+public class ModelConfigurationListenerTests {
+
+ private final StubArtifactRepository artifactRepository = new StubArtifactRepository();
+
+ private final StubBundleContext bundleContext;
+ {
+ this.bundleContext = new StubBundleContext();
+ String filterString = String.format("(&(objectClass=%s)(artifactType=configuration))", DependencyDeterminer.class.getCanonicalName());
+ this.bundleContext.addFilter(filterString, new TrueFilter(filterString));
+ }
+
+ private final ServiceReference reference = new StubServiceRegistration(bundleContext, ConfigurationAdmin.class.getCanonicalName()).getReference();
+
+ private final StubConfigurationAdmin configurationAdmin = new StubConfigurationAdmin();
+
+ private final ModelConfigurationListener listener = new ModelConfigurationListener(artifactRepository, bundleContext, configurationAdmin);
+
+ @Test(expected = FatalAssertionException.class)
+ public void nullArtifactRepository() {
+ new ModelConfigurationListener(null, bundleContext, configurationAdmin);
+ }
+
+ @Test(expected = FatalAssertionException.class)
+ public void nullBundleContext() {
+ new ModelConfigurationListener(artifactRepository, null, configurationAdmin);
+ }
+
+ @Test(expected = FatalAssertionException.class)
+ public void nullConfigurationAdmin() {
+ new ModelConfigurationListener(artifactRepository, bundleContext, null);
+ }
+
+ @Test
+ public void added() {
+ ConfigurationEvent event = new ConfigurationEvent(this.reference, ConfigurationEvent.CM_UPDATED, null, "test");
+ this.listener.configurationEvent(event);
+ assertEquals(1, this.artifactRepository.getArtifacts().size());
+ }
+
+ @Test
+ public void updated() {
+ ConfigurationEvent event1 = new ConfigurationEvent(this.reference, ConfigurationEvent.CM_UPDATED, null, "test");
+ this.listener.configurationEvent(event1);
+ ConfigurationEvent event2 = new ConfigurationEvent(this.reference, ConfigurationEvent.CM_UPDATED, null, "test");
+ this.listener.configurationEvent(event2);
+ assertEquals(1, this.artifactRepository.getArtifacts().size());
+ }
+
+ @Test
+ public void deleted() {
+ ConfigurationEvent event1 = new ConfigurationEvent(this.reference, ConfigurationEvent.CM_UPDATED, null, "test");
+ this.listener.configurationEvent(event1);
+ ConfigurationEvent event2 = new ConfigurationEvent(this.reference, ConfigurationEvent.CM_DELETED, null, "test");
+ this.listener.configurationEvent(event2);
+ assertEquals(0, this.artifactRepository.getArtifacts().size());
+ }
+
+ @Test
+ public void deletedNonExistant() {
+ ConfigurationEvent event = new ConfigurationEvent(this.reference, ConfigurationEvent.CM_DELETED, null, "test");
+ this.listener.configurationEvent(event);
+ assertEquals(0, this.artifactRepository.getArtifacts().size());
+ }
+
+ @Test
+ public void unknownEventType() {
+ ConfigurationEvent event = new ConfigurationEvent(this.reference, 3, null, "test");
+ this.listener.configurationEvent(event);
+ }
+}
diff --git a/org.eclipse.virgo.kernel.model/src/test/java/org/eclipse/virgo/kernel/model/internal/deployer/DeployerArtifactTests.java b/org.eclipse.virgo.kernel.model/src/test/java/org/eclipse/virgo/kernel/model/internal/deployer/DeployerArtifactTests.java
new file mode 100644
index 00000000..d5778e77
--- /dev/null
+++ b/org.eclipse.virgo.kernel.model/src/test/java/org/eclipse/virgo/kernel/model/internal/deployer/DeployerArtifactTests.java
@@ -0,0 +1,117 @@
+/*******************************************************************************
+ * 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.model.internal.deployer;
+
+import static org.easymock.EasyMock.createMock;
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.replay;
+import static org.easymock.EasyMock.verify;
+import static org.junit.Assert.assertEquals;
+
+import org.junit.Test;
+import org.osgi.framework.Version;
+
+import org.eclipse.virgo.kernel.install.artifact.InstallArtifact;
+import org.eclipse.virgo.kernel.install.artifact.InstallArtifact.State;
+import org.eclipse.virgo.kernel.model.ArtifactState;
+import org.eclipse.virgo.kernel.model.internal.DependencyDeterminer;
+import org.eclipse.virgo.kernel.model.internal.deployer.DeployerArtifact;
+
+
+import org.eclipse.virgo.kernel.core.KernelException;
+import org.eclipse.virgo.kernel.deployer.core.DeploymentException;
+import org.eclipse.virgo.kernel.serviceability.Assert.FatalAssertionException;
+import org.eclipse.virgo.kernel.stubs.StubInstallArtifact;
+import org.eclipse.virgo.teststubs.osgi.framework.StubBundleContext;
+import org.eclipse.virgo.teststubs.osgi.support.TrueFilter;
+
+public class DeployerArtifactTests {
+
+ private final StubBundleContext bundleContext = new StubBundleContext();
+ {
+ String filterString = String.format("(&(objectClass=%s)(artifactType=bundle))", DependencyDeterminer.class.getCanonicalName());
+ bundleContext.addFilter(filterString, new TrueFilter(filterString));
+ }
+
+ private final DeployerArtifact artifact = new DeployerArtifact(bundleContext, new StubInstallArtifact("bundle"));
+
+ @Test(expected = FatalAssertionException.class)
+ public void testNullBundleContext() {
+ new DeployerArtifact(null, new StubInstallArtifact("bundle"));
+ }
+
+ @Test(expected = FatalAssertionException.class)
+ public void testNullInstallArtifact() {
+ new DeployerArtifact(this.bundleContext, null);
+ }
+
+ @Test
+ public void getState() {
+ InstallArtifact installArtifact = createMock(InstallArtifact.class);
+
+ expect(installArtifact.getType()).andReturn("bundle");
+ expect(installArtifact.getName()).andReturn("test");
+ expect(installArtifact.getVersion()).andReturn(Version.emptyVersion);
+
+ expect(installArtifact.getState()).andReturn(State.INITIAL);
+ expect(installArtifact.getState()).andReturn(State.INSTALLING);
+ expect(installArtifact.getState()).andReturn(State.INSTALLED);
+ expect(installArtifact.getState()).andReturn(State.RESOLVING);
+ expect(installArtifact.getState()).andReturn(State.RESOLVED);
+ expect(installArtifact.getState()).andReturn(State.STARTING);
+ expect(installArtifact.getState()).andReturn(State.ACTIVE);
+ expect(installArtifact.getState()).andReturn(State.STOPPING);
+ expect(installArtifact.getState()).andReturn(State.UNINSTALLING);
+ expect(installArtifact.getState()).andReturn(State.UNINSTALLED);
+ replay(installArtifact);
+
+ DeployerArtifact artifact1 = new DeployerArtifact(bundleContext, installArtifact);
+
+ assertEquals(ArtifactState.INITIAL, artifact1.getState());
+ assertEquals(ArtifactState.INSTALLING, artifact1.getState());
+ assertEquals(ArtifactState.INSTALLED, artifact1.getState());
+ assertEquals(ArtifactState.RESOLVING, artifact1.getState());
+ assertEquals(ArtifactState.RESOLVED, artifact1.getState());
+ assertEquals(ArtifactState.STARTING, artifact1.getState());
+ assertEquals(ArtifactState.ACTIVE, artifact1.getState());
+ assertEquals(ArtifactState.STOPPING, artifact1.getState());
+ assertEquals(ArtifactState.UNINSTALLING, artifact1.getState());
+ assertEquals(ArtifactState.UNINSTALLED, artifact1.getState());
+
+ verify(installArtifact);
+ }
+
+ @Test
+ public void start() throws KernelException {
+ this.artifact.start();
+ }
+
+ @Test
+ public void stop() throws DeploymentException {
+ this.artifact.stop();
+ }
+
+ @Test
+ public void uninstall() throws DeploymentException {
+ this.artifact.uninstall();
+ }
+
+ @Test
+ public void updateAndRefresh() throws DeploymentException {
+ this.artifact.refresh();
+ }
+
+ @Test
+ public void getProperties() throws DeploymentException {
+ this.artifact.getProperties();
+ }
+}
diff --git a/org.eclipse.virgo.kernel.model/src/test/java/org/eclipse/virgo/kernel/model/internal/deployer/DeployerCompositeArtifactDependencyDeterminerTests.java b/org.eclipse.virgo.kernel.model/src/test/java/org/eclipse/virgo/kernel/model/internal/deployer/DeployerCompositeArtifactDependencyDeterminerTests.java
new file mode 100644
index 00000000..a68bb6da
--- /dev/null
+++ b/org.eclipse.virgo.kernel.model/src/test/java/org/eclipse/virgo/kernel/model/internal/deployer/DeployerCompositeArtifactDependencyDeterminerTests.java
@@ -0,0 +1,65 @@
+/*******************************************************************************
+ * 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.model.internal.deployer;
+
+import static org.junit.Assert.assertEquals;
+
+import org.junit.Test;
+
+import org.eclipse.virgo.kernel.install.artifact.InstallArtifact;
+import org.eclipse.virgo.kernel.model.RuntimeArtifactRepository;
+import org.eclipse.virgo.kernel.model.StubArtifactRepository;
+import org.eclipse.virgo.kernel.model.StubCompositeArtifact;
+import org.eclipse.virgo.kernel.model.internal.DependencyDeterminer;
+import org.eclipse.virgo.kernel.model.internal.deployer.DeployerCompositeArtifact;
+import org.eclipse.virgo.kernel.model.internal.deployer.DeployerCompositeArtifactDependencyDeterminer;
+
+
+import org.eclipse.virgo.kernel.serviceability.Assert.FatalAssertionException;
+import org.eclipse.virgo.kernel.stubs.StubInstallArtifact;
+import org.eclipse.virgo.kernel.stubs.StubPlanInstallArtifact;
+import org.eclipse.virgo.teststubs.osgi.framework.StubBundleContext;
+import org.eclipse.virgo.teststubs.osgi.support.TrueFilter;
+import org.eclipse.virgo.util.common.ThreadSafeArrayListTree;
+
+public class DeployerCompositeArtifactDependencyDeterminerTests {
+
+ private final RuntimeArtifactRepository artifactRepository = new StubArtifactRepository();
+
+ private final StubBundleContext bundleContext;
+ {
+ this.bundleContext = new StubBundleContext();
+ String filterString = String.format("(&(objectClass=%s)(artifactType=plan))", DependencyDeterminer.class.getCanonicalName());
+ this.bundleContext.addFilter(filterString, new TrueFilter(filterString));
+ }
+
+ private final DeployerCompositeArtifactDependencyDeterminer determiner = new DeployerCompositeArtifactDependencyDeterminer(artifactRepository);
+
+ @Test(expected = FatalAssertionException.class)
+ public void nullRepository() {
+ new DeployerCompositeArtifactDependencyDeterminer(null);
+ }
+
+ @Test
+ public void nonCompositeArtifact() {
+ assertEquals(0, this.determiner.getDependents(new StubCompositeArtifact()).size());
+ }
+
+ @Test
+ public void success() {
+ StubPlanInstallArtifact installArtifact = new StubPlanInstallArtifact();
+ installArtifact.getTree().addChild(new ThreadSafeArrayListTree<InstallArtifact>(new StubInstallArtifact()));
+ DeployerCompositeArtifact artifact = new DeployerCompositeArtifact(bundleContext, installArtifact);
+ assertEquals(1, this.determiner.getDependents(artifact).size());
+ }
+
+}
diff --git a/org.eclipse.virgo.kernel.model/src/test/java/org/eclipse/virgo/kernel/model/internal/deployer/DeployerCompositeArtifactTests.java b/org.eclipse.virgo.kernel.model/src/test/java/org/eclipse/virgo/kernel/model/internal/deployer/DeployerCompositeArtifactTests.java
new file mode 100644
index 00000000..8ddade64
--- /dev/null
+++ b/org.eclipse.virgo.kernel.model/src/test/java/org/eclipse/virgo/kernel/model/internal/deployer/DeployerCompositeArtifactTests.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.model.internal.deployer;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+
+import org.junit.Test;
+
+
+import org.eclipse.virgo.kernel.model.internal.DependencyDeterminer;
+import org.eclipse.virgo.kernel.model.internal.deployer.DeployerArtifact;
+import org.eclipse.virgo.kernel.model.internal.deployer.DeployerCompositeArtifact;
+import org.eclipse.virgo.kernel.serviceability.Assert.FatalAssertionException;
+import org.eclipse.virgo.kernel.stubs.StubPlanInstallArtifact;
+import org.eclipse.virgo.teststubs.osgi.framework.StubBundleContext;
+import org.eclipse.virgo.teststubs.osgi.support.TrueFilter;
+
+public class DeployerCompositeArtifactTests {
+
+ private final StubBundleContext bundleContext = new StubBundleContext();
+ {
+ String filterString = String.format("(&(objectClass=%s)(artifactType=plan))", DependencyDeterminer.class.getCanonicalName());
+ bundleContext.addFilter(filterString, new TrueFilter(filterString));
+ }
+
+ private final DeployerCompositeArtifact artifact = new DeployerCompositeArtifact(bundleContext, new StubPlanInstallArtifact());
+
+ @Test(expected = FatalAssertionException.class)
+ public void testNullBundleContext() {
+ new DeployerArtifact(null, new StubPlanInstallArtifact());
+ }
+
+ @Test(expected = FatalAssertionException.class)
+ public void testNullInstallArtifact() {
+ new DeployerArtifact(this.bundleContext, null);
+ }
+
+ @Test
+ public void isAtomic() {
+ assertFalse(this.artifact.isAtomic());
+ }
+
+ @Test
+ public void isScoped() {
+ assertFalse(this.artifact.isScoped());
+ }
+
+ @Test
+ public void getInstallArtifact() {
+ assertNotNull(this.artifact.getInstallArtifact());
+ }
+}
diff --git a/org.eclipse.virgo.kernel.model/src/test/java/org/eclipse/virgo/kernel/model/internal/deployer/ModelInstallArtifactLifecycleListenerInitializerTests.java b/org.eclipse.virgo.kernel.model/src/test/java/org/eclipse/virgo/kernel/model/internal/deployer/ModelInstallArtifactLifecycleListenerInitializerTests.java
new file mode 100644
index 00000000..62f93ad9
--- /dev/null
+++ b/org.eclipse.virgo.kernel.model/src/test/java/org/eclipse/virgo/kernel/model/internal/deployer/ModelInstallArtifactLifecycleListenerInitializerTests.java
@@ -0,0 +1,115 @@
+/*******************************************************************************
+ * 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.model.internal.deployer;
+
+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.io.IOException;
+
+import org.junit.Test;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.framework.Version;
+
+
+import org.eclipse.virgo.kernel.deployer.core.DeploymentIdentity;
+import org.eclipse.virgo.kernel.deployer.model.RuntimeArtifactModel;
+import org.eclipse.virgo.kernel.model.StubArtifactRepository;
+import org.eclipse.virgo.kernel.model.internal.DependencyDeterminer;
+import org.eclipse.virgo.kernel.model.internal.deployer.ModelInstallArtifactLifecycleListenerInitializer;
+import org.eclipse.virgo.kernel.serviceability.Assert.FatalAssertionException;
+import org.eclipse.virgo.kernel.stubs.StubInstallArtifact;
+import org.eclipse.virgo.kernel.stubs.StubPlanInstallArtifact;
+import org.eclipse.virgo.teststubs.osgi.framework.StubBundleContext;
+import org.eclipse.virgo.teststubs.osgi.support.TrueFilter;
+
+public class ModelInstallArtifactLifecycleListenerInitializerTests {
+
+ private final StubArtifactRepository artifactRepository = new StubArtifactRepository();
+
+ private final RuntimeArtifactModel runtimeArtifactModel = createMock(RuntimeArtifactModel.class);
+
+ private final StubBundleContext bundleContext;
+ {
+ this.bundleContext = new StubBundleContext();
+ String filterString1 = String.format("(&(objectClass=%s)(artifactType=bundle))", DependencyDeterminer.class.getCanonicalName());
+ this.bundleContext.addFilter(filterString1, new TrueFilter(filterString1));
+ String filterString2 = String.format("(&(objectClass=%s)(artifactType=plan))", DependencyDeterminer.class.getCanonicalName());
+ this.bundleContext.addFilter(filterString2, new TrueFilter(filterString2));
+ }
+
+ private final ModelInstallArtifactLifecycleListenerInitializer initializer = new ModelInstallArtifactLifecycleListenerInitializer(
+ artifactRepository, bundleContext, runtimeArtifactModel);
+
+ @Test(expected = FatalAssertionException.class)
+ public void nullArtifactRepository() {
+ new ModelInstallArtifactLifecycleListenerInitializer(null, bundleContext, runtimeArtifactModel);
+ }
+
+ @Test(expected = FatalAssertionException.class)
+ public void nullBundleContext() {
+ new ModelInstallArtifactLifecycleListenerInitializer(artifactRepository, null, runtimeArtifactModel);
+ }
+
+ @Test
+ public void initialize() throws IOException, InvalidSyntaxException {
+ expect(this.runtimeArtifactModel.getDeploymentIdentities()).andReturn(
+ new DeploymentIdentity[] { new StubDeploymentIdentity("plan"), new StubDeploymentIdentity("bundle") });
+ expect(this.runtimeArtifactModel.get(isA(DeploymentIdentity.class))).andReturn(new StubInstallArtifact("bundle"));
+ expect(this.runtimeArtifactModel.get(isA(DeploymentIdentity.class))).andReturn(new StubPlanInstallArtifact());
+ replay(this.runtimeArtifactModel);
+ assertEquals(0, this.bundleContext.getServiceRegistrations().size());
+ this.initializer.initialize();
+ assertEquals(1, this.bundleContext.getServiceRegistrations().size());
+ assertEquals(2, this.artifactRepository.getArtifacts().size());
+ verify(this.runtimeArtifactModel);
+ }
+
+ @Test
+ public void destroy() throws IOException, InvalidSyntaxException {
+ expect(this.runtimeArtifactModel.getDeploymentIdentities()).andReturn(new DeploymentIdentity[0]);
+ replay(this.runtimeArtifactModel);
+ this.initializer.initialize();
+ assertEquals(1, this.bundleContext.getServiceRegistrations().size());
+ this.initializer.destroy();
+ assertEquals(0, this.bundleContext.getServiceRegistrations().size());
+ verify(this.runtimeArtifactModel);
+ }
+
+ private static class StubDeploymentIdentity implements DeploymentIdentity {
+
+ private static final long serialVersionUID = 1L;
+
+ private final String type;
+
+ public StubDeploymentIdentity(String type) {
+ this.type = type;
+ }
+
+ public String getSymbolicName() {
+ return "test";
+ }
+
+ public String getType() {
+ return this.type;
+ }
+
+ public String getVersion() {
+ return Version.emptyVersion.toString();
+ }
+
+ }
+}
diff --git a/org.eclipse.virgo.kernel.model/src/test/java/org/eclipse/virgo/kernel/model/internal/deployer/ModelInstallArtifactLifecycleListenerTests.java b/org.eclipse.virgo.kernel.model/src/test/java/org/eclipse/virgo/kernel/model/internal/deployer/ModelInstallArtifactLifecycleListenerTests.java
new file mode 100644
index 00000000..086df7f0
--- /dev/null
+++ b/org.eclipse.virgo.kernel.model/src/test/java/org/eclipse/virgo/kernel/model/internal/deployer/ModelInstallArtifactLifecycleListenerTests.java
@@ -0,0 +1,103 @@
+/*******************************************************************************
+ * 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.model.internal.deployer;
+
+import static org.junit.Assert.assertEquals;
+
+import org.junit.Test;
+
+import org.eclipse.virgo.kernel.install.artifact.InstallArtifact;
+import org.eclipse.virgo.kernel.model.StubArtifactRepository;
+import org.eclipse.virgo.kernel.model.internal.DependencyDeterminer;
+import org.eclipse.virgo.kernel.model.internal.deployer.ModelInstallArtifactLifecycleListener;
+
+
+import org.eclipse.virgo.kernel.deployer.core.DeploymentException;
+import org.eclipse.virgo.kernel.serviceability.Assert.FatalAssertionException;
+import org.eclipse.virgo.kernel.stubs.StubInstallArtifact;
+import org.eclipse.virgo.kernel.stubs.StubPlanInstallArtifact;
+import org.eclipse.virgo.teststubs.osgi.framework.StubBundleContext;
+import org.eclipse.virgo.teststubs.osgi.support.TrueFilter;
+
+public class ModelInstallArtifactLifecycleListenerTests {
+
+ private final StubArtifactRepository artifactRepository = new StubArtifactRepository();
+
+ private final StubBundleContext bundleContext;
+ {
+ this.bundleContext = new StubBundleContext();
+ String filterString1 = String.format("(&(objectClass=%s)(artifactType=bundle))", DependencyDeterminer.class.getCanonicalName());
+ this.bundleContext.addFilter(filterString1, new TrueFilter(filterString1));
+ String filterString2 = String.format("(&(objectClass=%s)(artifactType=plan))", DependencyDeterminer.class.getCanonicalName());
+ this.bundleContext.addFilter(filterString2, new TrueFilter(filterString2));
+ }
+
+ private final ModelInstallArtifactLifecycleListener listener = new ModelInstallArtifactLifecycleListener(bundleContext, artifactRepository);
+
+ @Test(expected = FatalAssertionException.class)
+ public void nullBundleContext() {
+ new ModelInstallArtifactLifecycleListener(null, artifactRepository);
+ }
+
+ @Test(expected = FatalAssertionException.class)
+ public void nullArtifactRepository() {
+ new ModelInstallArtifactLifecycleListener(bundleContext, null);
+ }
+
+ @Test
+ public void installing() throws DeploymentException {
+ checkNumberOfArtifacts(0);
+
+ StubInstallArtifact bundleInstallArtifact = new StubInstallArtifact("bundle");
+ this.listener.onInstalling(bundleInstallArtifact);
+ checkNumberOfArtifacts(1);
+
+ this.listener.onInstalling(bundleInstallArtifact);
+ checkNumberOfArtifacts(1);
+
+ StubPlanInstallArtifact planInstallArtifact = new StubPlanInstallArtifact();
+ this.listener.onInstalling(planInstallArtifact);
+ checkNumberOfArtifacts(2);
+
+ this.listener.onInstalling(planInstallArtifact);
+ checkNumberOfArtifacts(2);
+ }
+
+ @Test
+ public void installFailed() throws DeploymentException {
+ checkNumberOfArtifacts(0);
+
+ InstallArtifact bundleInstallArtifact = new StubInstallArtifact("bundle");
+ this.listener.onInstalling(bundleInstallArtifact);
+ checkNumberOfArtifacts(1);
+
+ this.listener.onInstallFailed(bundleInstallArtifact);
+ checkNumberOfArtifacts(0);
+ }
+
+ @Test
+ public void uninstalled() throws DeploymentException {
+ InstallArtifact bundleInstallArtifact = new StubInstallArtifact("bundle");
+ this.listener.onInstalling(bundleInstallArtifact);
+ checkNumberOfArtifacts(1);
+
+ this.listener.onUninstalled(bundleInstallArtifact);
+ checkNumberOfArtifacts(0);
+
+ this.listener.onUninstalled(bundleInstallArtifact);
+ checkNumberOfArtifacts(0);
+ }
+
+ private void checkNumberOfArtifacts(int expectedNumberOfArtifacts) {
+ assertEquals(expectedNumberOfArtifacts, this.artifactRepository.getArtifacts().size());
+ }
+}
diff --git a/org.eclipse.virgo.kernel.model/src/test/java/org/eclipse/virgo/kernel/model/management/internal/DefaultArtifactObjectNameCreatorTests.java b/org.eclipse.virgo.kernel.model/src/test/java/org/eclipse/virgo/kernel/model/management/internal/DefaultArtifactObjectNameCreatorTests.java
new file mode 100644
index 00000000..f3aac773
--- /dev/null
+++ b/org.eclipse.virgo.kernel.model/src/test/java/org/eclipse/virgo/kernel/model/management/internal/DefaultArtifactObjectNameCreatorTests.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.model.management.internal;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+import javax.management.ObjectName;
+
+import org.eclipse.virgo.kernel.model.StubCompositeArtifact;
+import org.eclipse.virgo.kernel.model.management.internal.DefaultRuntimeArtifactModelObjectNameCreator;
+import org.eclipse.virgo.kernel.serviceability.Assert.FatalAssertionException;
+import org.junit.Test;
+
+
+public class DefaultArtifactObjectNameCreatorTests {
+
+ private final DefaultRuntimeArtifactModelObjectNameCreator creator = new DefaultRuntimeArtifactModelObjectNameCreator("test-domain");
+
+ @Test(expected = FatalAssertionException.class)
+ public void nullArtifact() {
+ creator.create(null);
+ }
+
+ @Test
+ public void success() {
+ ObjectName objectName = creator.create(new StubCompositeArtifact());
+ assertNotNull(objectName);
+ assertEquals("test-domain:artifact-type=test-type,name=test-name,type=Model,version=0.0.0", objectName.getCanonicalName());
+ }
+}
diff --git a/org.eclipse.virgo.kernel.model/src/test/java/org/eclipse/virgo/kernel/model/management/internal/DelegatingManageableArtifactTests.java b/org.eclipse.virgo.kernel.model/src/test/java/org/eclipse/virgo/kernel/model/management/internal/DelegatingManageableArtifactTests.java
new file mode 100644
index 00000000..a717ad98
--- /dev/null
+++ b/org.eclipse.virgo.kernel.model/src/test/java/org/eclipse/virgo/kernel/model/management/internal/DelegatingManageableArtifactTests.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.model.management.internal;
+
+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 static org.junit.Assert.assertTrue;
+
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+
+import javax.management.MalformedObjectNameException;
+import javax.management.ObjectName;
+
+import org.eclipse.virgo.kernel.model.Artifact;
+import org.eclipse.virgo.kernel.model.ArtifactState;
+import org.eclipse.virgo.kernel.model.StubCompositeArtifact;
+import org.eclipse.virgo.kernel.model.management.RuntimeArtifactModelObjectNameCreator;
+import org.eclipse.virgo.kernel.model.management.internal.DelegatingManageableArtifact;
+import org.eclipse.virgo.kernel.serviceability.Assert.FatalAssertionException;
+import org.junit.Test;
+import org.osgi.framework.Version;
+
+
+public class DelegatingManageableArtifactTests {
+
+ @Test(expected = FatalAssertionException.class)
+ public void nullCreator() {
+ new DelegatingManageableArtifact(null, new StubCompositeArtifact());
+ }
+
+ @Test(expected = FatalAssertionException.class)
+ public void nullArtifact() {
+ new DelegatingManageableArtifact(createMock(RuntimeArtifactModelObjectNameCreator.class), null);
+ }
+
+ @Test
+ public void success() throws MalformedObjectNameException, NullPointerException {
+ RuntimeArtifactModelObjectNameCreator creator = createMock(RuntimeArtifactModelObjectNameCreator.class);
+ Artifact artifact = createMock(Artifact.class);
+
+ DelegatingManageableArtifact manageableArtifact = new DelegatingManageableArtifact(creator, artifact);
+
+ expect(artifact.getDependents()).andReturn(getArtifacts());
+ expect(creator.create(isA(Artifact.class))).andReturn(new ObjectName("domain:key=value1"));
+ expect(creator.create(isA(Artifact.class))).andReturn(new ObjectName("domain:key=value2"));
+ expect(creator.create(isA(Artifact.class))).andReturn(new ObjectName("domain:key=value3"));
+ expect(artifact.getName()).andReturn("test-name");
+ expect(artifact.getState()).andReturn(ArtifactState.ACTIVE);
+ expect(artifact.getType()).andReturn("test-type");
+ expect(artifact.getVersion()).andReturn(Version.emptyVersion);
+ expect(artifact.getProperties()).andReturn(Collections.<String, String> emptyMap());
+ expect(artifact.refresh()).andReturn(true);
+ artifact.start();
+ artifact.stop();
+ artifact.uninstall();
+ replay(creator, artifact);
+
+ assertEquals(3, manageableArtifact.getDependents().length);
+ manageableArtifact.getName();
+ assertEquals("ACTIVE", manageableArtifact.getState());
+ assertEquals("test-type", manageableArtifact.getType());
+ assertEquals("0.0.0", manageableArtifact.getVersion());
+ assertEquals(0, manageableArtifact.getProperties().size());
+ assertTrue(manageableArtifact.refresh());
+ manageableArtifact.start();
+ manageableArtifact.stop();
+ manageableArtifact.uninstall();
+
+ verify(creator, artifact);
+ }
+
+ private Set<Artifact> getArtifacts() {
+ Set<Artifact> artifacts = new HashSet<Artifact>();
+ for (int i = 0; i < 3; i++) {
+ artifacts.add(new StubCompositeArtifact());
+ }
+ return artifacts;
+ }
+}
diff --git a/org.eclipse.virgo.kernel.model/src/test/java/org/eclipse/virgo/kernel/model/management/internal/DelegatingManageableCompositeArtifactTests.java b/org.eclipse.virgo.kernel.model/src/test/java/org/eclipse/virgo/kernel/model/management/internal/DelegatingManageableCompositeArtifactTests.java
new file mode 100644
index 00000000..8671ae95
--- /dev/null
+++ b/org.eclipse.virgo.kernel.model/src/test/java/org/eclipse/virgo/kernel/model/management/internal/DelegatingManageableCompositeArtifactTests.java
@@ -0,0 +1,59 @@
+/*******************************************************************************
+ * 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.model.management.internal;
+
+import static org.easymock.EasyMock.createMock;
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.replay;
+import static org.easymock.EasyMock.verify;
+import static org.junit.Assert.assertTrue;
+
+import javax.management.MalformedObjectNameException;
+
+import org.eclipse.virgo.kernel.model.CompositeArtifact;
+import org.eclipse.virgo.kernel.model.StubCompositeArtifact;
+import org.eclipse.virgo.kernel.model.management.RuntimeArtifactModelObjectNameCreator;
+import org.eclipse.virgo.kernel.model.management.internal.DelegatingManageableCompositeArtifact;
+import org.eclipse.virgo.kernel.serviceability.Assert.FatalAssertionException;
+import org.junit.Test;
+
+
+public class DelegatingManageableCompositeArtifactTests {
+
+ @Test(expected = FatalAssertionException.class)
+ public void nullCreator() {
+ new DelegatingManageableCompositeArtifact(null, new StubCompositeArtifact());
+ }
+
+ @Test(expected = FatalAssertionException.class)
+ public void nullArtifact() {
+ new DelegatingManageableCompositeArtifact(createMock(RuntimeArtifactModelObjectNameCreator.class), null);
+ }
+
+ @Test
+ public void success() throws MalformedObjectNameException, NullPointerException {
+ RuntimeArtifactModelObjectNameCreator creator = createMock(RuntimeArtifactModelObjectNameCreator.class);
+ CompositeArtifact artifact = createMock(CompositeArtifact.class);
+
+ DelegatingManageableCompositeArtifact manageablePlanArtifact = new DelegatingManageableCompositeArtifact(creator, artifact);
+
+ expect(artifact.isAtomic()).andReturn(true);
+ expect(artifact.isScoped()).andReturn(true);
+ replay(creator, artifact);
+
+ assertTrue(manageablePlanArtifact.isAtomic());
+ assertTrue(manageablePlanArtifact.isScoped());
+
+ verify(creator, artifact);
+ }
+
+}
diff --git a/org.eclipse.virgo.kernel.model/src/test/java/org/eclipse/virgo/kernel/model/management/internal/JmxArtifactRepositoryListenerTests.java b/org.eclipse.virgo.kernel.model/src/test/java/org/eclipse/virgo/kernel/model/management/internal/JmxArtifactRepositoryListenerTests.java
new file mode 100644
index 00000000..9207a4d1
--- /dev/null
+++ b/org.eclipse.virgo.kernel.model/src/test/java/org/eclipse/virgo/kernel/model/management/internal/JmxArtifactRepositoryListenerTests.java
@@ -0,0 +1,71 @@
+/*******************************************************************************
+ * 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.model.management.internal;
+
+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.lang.management.ManagementFactory;
+
+import javax.management.MBeanServer;
+import javax.management.MalformedObjectNameException;
+import javax.management.ObjectName;
+
+import org.eclipse.virgo.kernel.model.Artifact;
+import org.eclipse.virgo.kernel.model.StubCompositeArtifact;
+import org.eclipse.virgo.kernel.model.management.RuntimeArtifactModelObjectNameCreator;
+import org.eclipse.virgo.kernel.model.management.internal.JmxArtifactRepositoryListener;
+import org.eclipse.virgo.kernel.serviceability.Assert.FatalAssertionException;
+import org.junit.Test;
+
+
+public class JmxArtifactRepositoryListenerTests {
+
+ private final MBeanServer server = ManagementFactory.getPlatformMBeanServer();
+
+ private final RuntimeArtifactModelObjectNameCreator creator = createMock(RuntimeArtifactModelObjectNameCreator.class);
+
+ private final JmxArtifactRepositoryListener listener = new JmxArtifactRepositoryListener(creator);
+
+ @Test(expected = FatalAssertionException.class)
+ public void nullCreator() {
+ new JmxArtifactRepositoryListener(null);
+ }
+
+ @Test
+ public void added() throws MalformedObjectNameException, NullPointerException {
+ expect(this.creator.create(isA(Artifact.class))).andReturn(new ObjectName("test:key=1"));
+ replay(creator);
+
+ int initial = this.server.getMBeanCount();
+ this.listener.added(new StubCompositeArtifact());
+ assertEquals(initial + 1, (int) this.server.getMBeanCount());
+ verify(creator);
+ }
+
+ @Test
+ public void removed() throws MalformedObjectNameException, NullPointerException {
+ expect(this.creator.create(isA(Artifact.class))).andReturn(new ObjectName("test:key=1")).times(2);
+ replay(creator);
+
+ this.listener.added(new StubCompositeArtifact());
+ int initial = this.server.getMBeanCount();
+ this.listener.removed(new StubCompositeArtifact());
+ assertEquals(initial - 1, (int) this.server.getMBeanCount());
+ verify(creator);
+ }
+
+}
diff --git a/org.eclipse.virgo.kernel.model/src/test/resources/.gitignore b/org.eclipse.virgo.kernel.model/src/test/resources/.gitignore
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/org.eclipse.virgo.kernel.model/src/test/resources/.gitignore
diff --git a/org.eclipse.virgo.kernel.model/template.mf b/org.eclipse.virgo.kernel.model/template.mf
new file mode 100644
index 00000000..763ceb30
--- /dev/null
+++ b/org.eclipse.virgo.kernel.model/template.mf
@@ -0,0 +1,19 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: Virgo Kernel Runtime Artifact Model
+Bundle-SymbolicName: org.eclipse.virgo.kernel.model
+Bundle-Version: 2.1.0
+Import-Template:
+ org.eclipse.virgo.kernel.*;version="${version:[=.=.=, =.+1)}",
+ org.eclipse.virgo.util.*;version="${org.eclipse.virgo.util:[=.=.=, =.+1)}",
+ org.eclipse.virgo.medic.*;version="${org.eclipse.virgo.medic:[=.=.=, =.+1)}",
+ org.aspectj.*;version="${org.aspectj:[=.=.=.=, +1)}",
+ org.springframework.*;version="${org.springframework:[2.5.6, =.+1)}",
+ javax.annotation.*;version="0",
+ javax.management.*;version="0",
+ org.osgi.framework.*;version="0",
+ org.osgi.service.cm.*;version="0",
+ org.osgi.util.tracker.*;version="0",
+ org.slf4j.*;version="${org.slf4j:[=.=.=, +1)}"
+Excluded-Exports:
+ *.internal.*

Back to the top