Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'bundles/org.eclipse.equinox.p2.engine')
-rw-r--r--bundles/org.eclipse.equinox.p2.engine/.classpath7
-rw-r--r--bundles/org.eclipse.equinox.p2.engine/.project28
-rw-r--r--bundles/org.eclipse.equinox.p2.engine/.settings/org.eclipse.jdt.core.prefs334
-rw-r--r--bundles/org.eclipse.equinox.p2.engine/.settings/org.eclipse.jdt.ui.prefs57
-rw-r--r--bundles/org.eclipse.equinox.p2.engine/.settings/org.eclipse.pde.core.prefs4
-rw-r--r--bundles/org.eclipse.equinox.p2.engine/META-INF/MANIFEST.MF28
-rw-r--r--bundles/org.eclipse.equinox.p2.engine/about.html28
-rw-r--r--bundles/org.eclipse.equinox.p2.engine/build.properties16
-rw-r--r--bundles/org.eclipse.equinox.p2.engine/plugin.xml13
-rw-r--r--bundles/org.eclipse.equinox.p2.engine/schema/touchpoints.exsd158
-rw-r--r--bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/internal/prov/engine/CommonDef.java63
-rw-r--r--bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/internal/prov/engine/EngineActivator.java64
-rw-r--r--bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/internal/prov/engine/Messages.java44
-rw-r--r--bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/internal/prov/engine/NullTouchpoint.java43
-rw-r--r--bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/internal/prov/engine/TouchpointManager.java223
-rw-r--r--bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/internal/prov/engine/messages.properties29
-rw-r--r--bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/prov/engine/AbstractProvisioningTransaction.java135
-rw-r--r--bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/prov/engine/BeginOperationEvent.java20
-rw-r--r--bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/prov/engine/CommitOperationEvent.java20
-rw-r--r--bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/prov/engine/DefaultPhaseSet.java21
-rw-r--r--bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/prov/engine/Engine.java83
-rw-r--r--bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/prov/engine/EngineSession.java33
-rw-r--r--bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/prov/engine/IProfileRegistry.java53
-rw-r--r--bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/prov/engine/IProvisioningAction.java36
-rw-r--r--bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/prov/engine/ITouchpoint.java26
-rw-r--r--bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/prov/engine/ITouchpointAction.java18
-rw-r--r--bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/prov/engine/IUPhase.java100
-rw-r--r--bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/prov/engine/InstallableUnitEvent.java68
-rw-r--r--bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/prov/engine/Operand.java35
-rw-r--r--bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/prov/engine/Phase.java61
-rw-r--r--bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/prov/engine/PhaseSet.java64
-rw-r--r--bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/prov/engine/Profile.java142
-rw-r--r--bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/prov/engine/ProfileEvent.java36
-rw-r--r--bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/prov/engine/ProvisioningConfigurationException.java21
-rw-r--r--bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/prov/engine/RollbackOperationEvent.java28
-rw-r--r--bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/prov/engine/SimpleProfileRegistry.java184
-rw-r--r--bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/prov/engine/TransactionEvent.java30
-rw-r--r--bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/prov/engine/Utils.java25
-rw-r--r--bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/prov/engine/phases/Collect.java76
-rw-r--r--bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/prov/engine/phases/Install.java60
-rw-r--r--bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/prov/engine/phases/Messages.java33
-rw-r--r--bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/prov/engine/phases/Uninstall.java58
-rw-r--r--bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/prov/engine/phases/messages.properties17
-rw-r--r--bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/prov/installregistry/IInstallRegistry.java171
-rw-r--r--bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/prov/installregistry/IProfileInstallRegistry.java27
-rw-r--r--bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/prov/installregistry/InstallRegistry.java181
46 files changed, 3001 insertions, 0 deletions
diff --git a/bundles/org.eclipse.equinox.p2.engine/.classpath b/bundles/org.eclipse.equinox.p2.engine/.classpath
new file mode 100644
index 000000000..7cdeb7319
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.engine/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="src" path="src"/>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/CDC-1.1%Foundation-1.1"/>
+ <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+ <classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/bundles/org.eclipse.equinox.p2.engine/.project b/bundles/org.eclipse.equinox.p2.engine/.project
new file mode 100644
index 000000000..4ca5cad36
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.engine/.project
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>org.eclipse.equinox.prov.engine</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.ManifestBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.SchemaBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.pde.PluginNature</nature>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ </natures>
+</projectDescription>
diff --git a/bundles/org.eclipse.equinox.p2.engine/.settings/org.eclipse.jdt.core.prefs b/bundles/org.eclipse.equinox.p2.engine/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 000000000..f8c50cc31
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.engine/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,334 @@
+#Tue Aug 21 09:11:12 EDT 2007
+eclipse.preferences.version=1
+instance/org.eclipse.core.net/org.eclipse.core.net.hasMigrated=true
+org.eclipse.jdt.core.builder.cleanOutputFolder=clean
+org.eclipse.jdt.core.builder.duplicateResourceTask=warning
+org.eclipse.jdt.core.builder.invalidClasspath=abort
+org.eclipse.jdt.core.builder.resourceCopyExclusionFilter=*.launch
+org.eclipse.jdt.core.circularClasspath=error
+org.eclipse.jdt.core.classpath.exclusionPatterns=enabled
+org.eclipse.jdt.core.classpath.multipleOutputLocations=enabled
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=disabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.2
+org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
+org.eclipse.jdt.core.compiler.compliance=1.4
+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.doc.comment.support=enabled
+org.eclipse.jdt.core.compiler.maxProblemPerUnit=1000
+org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=warning
+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=enabled
+org.eclipse.jdt.core.compiler.problem.discouragedReference=error
+org.eclipse.jdt.core.compiler.problem.emptyStatement=warning
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=warning
+org.eclipse.jdt.core.compiler.problem.fieldHiding=warning
+org.eclipse.jdt.core.compiler.problem.finalParameterBound=ignore
+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=warning
+org.eclipse.jdt.core.compiler.problem.invalidJavadoc=error
+org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsVisibility=private
+org.eclipse.jdt.core.compiler.problem.localVariableHiding=warning
+org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=warning
+org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=ignore
+org.eclipse.jdt.core.compiler.problem.missingJavadocComments=ignore
+org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsOverriding=enabled
+org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsVisibility=public
+org.eclipse.jdt.core.compiler.problem.missingJavadocTags=ignore
+org.eclipse.jdt.core.compiler.problem.missingJavadocTagsOverriding=enabled
+org.eclipse.jdt.core.compiler.problem.missingJavadocTagsVisibility=public
+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=warning
+org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning
+org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=warning
+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=warning
+org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning
+org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning
+org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=warning
+org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning
+org.eclipse.jdt.core.compiler.problem.unnecessaryElse=warning
+org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=warning
+org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore
+org.eclipse.jdt.core.compiler.problem.unsafeTypeOperation=warning
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=warning
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=enabled
+org.eclipse.jdt.core.compiler.problem.unusedImport=error
+org.eclipse.jdt.core.compiler.problem.unusedLocal=warning
+org.eclipse.jdt.core.compiler.problem.unusedParameter=ignore
+org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=enabled
+org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=enabled
+org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=error
+org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning
+org.eclipse.jdt.core.compiler.source=1.3
+org.eclipse.jdt.core.formatter.align_type_members_on_columns=false
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant=16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call=16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation=16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression=16
+org.eclipse.jdt.core.formatter.alignment_for_assignment=0
+org.eclipse.jdt.core.formatter.alignment_for_binary_expression=16
+org.eclipse.jdt.core.formatter.alignment_for_compact_if=16
+org.eclipse.jdt.core.formatter.alignment_for_conditional_expression=80
+org.eclipse.jdt.core.formatter.alignment_for_enum_constants=0
+org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer=16
+org.eclipse.jdt.core.formatter.alignment_for_multiple_fields=16
+org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation=16
+org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration=16
+org.eclipse.jdt.core.formatter.blank_lines_after_imports=1
+org.eclipse.jdt.core.formatter.blank_lines_after_package=1
+org.eclipse.jdt.core.formatter.blank_lines_before_field=0
+org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration=0
+org.eclipse.jdt.core.formatter.blank_lines_before_imports=1
+org.eclipse.jdt.core.formatter.blank_lines_before_member_type=1
+org.eclipse.jdt.core.formatter.blank_lines_before_method=1
+org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk=1
+org.eclipse.jdt.core.formatter.blank_lines_before_package=0
+org.eclipse.jdt.core.formatter.blank_lines_between_import_groups=1
+org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations=1
+org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_array_initializer=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_block=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_block_in_case=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_enum_constant=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_method_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_switch=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_type_declaration=end_of_line
+org.eclipse.jdt.core.formatter.comment.clear_blank_lines=false
+org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment=false
+org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment=false
+org.eclipse.jdt.core.formatter.comment.format_block_comments=false
+org.eclipse.jdt.core.formatter.comment.format_comments=false
+org.eclipse.jdt.core.formatter.comment.format_header=false
+org.eclipse.jdt.core.formatter.comment.format_html=true
+org.eclipse.jdt.core.formatter.comment.format_javadoc_comments=false
+org.eclipse.jdt.core.formatter.comment.format_line_comments=false
+org.eclipse.jdt.core.formatter.comment.format_source_code=true
+org.eclipse.jdt.core.formatter.comment.indent_parameter_description=false
+org.eclipse.jdt.core.formatter.comment.indent_root_tags=false
+org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags=insert
+org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter=do not insert
+org.eclipse.jdt.core.formatter.comment.line_length=80
+org.eclipse.jdt.core.formatter.compact_else_if=true
+org.eclipse.jdt.core.formatter.continuation_indentation=2
+org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer=2
+org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line=false
+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header=true
+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header=true
+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header=true
+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header=true
+org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases=true
+org.eclipse.jdt.core.formatter.indent_empty_lines=false
+org.eclipse.jdt.core.formatter.indent_statements_compare_to_block=true
+org.eclipse.jdt.core.formatter.indent_statements_compare_to_body=true
+org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases=true
+org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch=true
+org.eclipse.jdt.core.formatter.indentation.size=4
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_annotation_declaration=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter=insert
+org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_binary_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters=insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block=insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters=insert
+org.eclipse.jdt.core.formatter.insert_space_after_ellipsis=insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional=insert
+org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for=insert
+org.eclipse.jdt.core.formatter.insert_space_after_unary_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter=insert
+org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_binary_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert=insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case=insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional=insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default=insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for=insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_ellipsis=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while=insert
+org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return=insert
+org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw=insert
+org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional=insert
+org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_semicolon=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_unary_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation=do not insert
+org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line=false
+org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line=false
+org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line=false
+org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line=false
+org.eclipse.jdt.core.formatter.lineSplit=800
+org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column=false
+org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column=false
+org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body=0
+org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve=1
+org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line=false
+org.eclipse.jdt.core.formatter.tabulation.char=tab
+org.eclipse.jdt.core.formatter.tabulation.size=4
+org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations=false
+org.eclipse.jdt.core.formatter.wrap_before_binary_operator=true
+org.eclipse.jdt.core.incompatibleJDKLevel=ignore
+org.eclipse.jdt.core.incompleteClasspath=error
diff --git a/bundles/org.eclipse.equinox.p2.engine/.settings/org.eclipse.jdt.ui.prefs b/bundles/org.eclipse.equinox.p2.engine/.settings/org.eclipse.jdt.ui.prefs
new file mode 100644
index 000000000..56bcc3e9b
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.engine/.settings/org.eclipse.jdt.ui.prefs
@@ -0,0 +1,57 @@
+#Sun Sep 23 11:58:07 EDT 2007
+eclipse.preferences.version=1
+editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true
+formatter_profile=_core
+formatter_settings_version=11
+org.eclipse.jdt.ui.ignorelowercasenames=true
+org.eclipse.jdt.ui.importorder=;
+org.eclipse.jdt.ui.ondemandthreshold=3
+org.eclipse.jdt.ui.staticondemandthreshold=3
+org.eclipse.jdt.ui.text.custom_code_templates=<?xml version\="1.0" encoding\="UTF-8" standalone\="no"?><templates/>
+sp_cleanup.add_default_serial_version_id=true
+sp_cleanup.add_generated_serial_version_id=false
+sp_cleanup.add_missing_annotations=true
+sp_cleanup.add_missing_deprecated_annotations=true
+sp_cleanup.add_missing_nls_tags=false
+sp_cleanup.add_missing_override_annotations=true
+sp_cleanup.add_serial_version_id=false
+sp_cleanup.always_use_blocks=true
+sp_cleanup.always_use_parentheses_in_expressions=false
+sp_cleanup.always_use_this_for_non_static_field_access=false
+sp_cleanup.always_use_this_for_non_static_method_access=false
+sp_cleanup.convert_to_enhanced_for_loop=false
+sp_cleanup.format_source_code=true
+sp_cleanup.make_local_variable_final=false
+sp_cleanup.make_parameters_final=false
+sp_cleanup.make_private_fields_final=true
+sp_cleanup.make_variable_declarations_final=true
+sp_cleanup.never_use_blocks=false
+sp_cleanup.never_use_parentheses_in_expressions=true
+sp_cleanup.on_save_use_additional_actions=false
+sp_cleanup.organize_imports=true
+sp_cleanup.qualify_static_field_accesses_with_declaring_class=false
+sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true
+sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true
+sp_cleanup.qualify_static_member_accesses_with_declaring_class=false
+sp_cleanup.qualify_static_method_accesses_with_declaring_class=false
+sp_cleanup.remove_private_constructors=true
+sp_cleanup.remove_trailing_whitespaces=false
+sp_cleanup.remove_trailing_whitespaces_all=true
+sp_cleanup.remove_trailing_whitespaces_ignore_empty=false
+sp_cleanup.remove_unnecessary_casts=true
+sp_cleanup.remove_unnecessary_nls_tags=false
+sp_cleanup.remove_unused_imports=false
+sp_cleanup.remove_unused_local_variables=false
+sp_cleanup.remove_unused_private_fields=true
+sp_cleanup.remove_unused_private_members=false
+sp_cleanup.remove_unused_private_methods=true
+sp_cleanup.remove_unused_private_types=true
+sp_cleanup.sort_members=false
+sp_cleanup.sort_members_all=false
+sp_cleanup.use_blocks=false
+sp_cleanup.use_blocks_only_for_return_and_throw=false
+sp_cleanup.use_parentheses_in_expressions=false
+sp_cleanup.use_this_for_non_static_field_access=false
+sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true
+sp_cleanup.use_this_for_non_static_method_access=false
+sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true
diff --git a/bundles/org.eclipse.equinox.p2.engine/.settings/org.eclipse.pde.core.prefs b/bundles/org.eclipse.equinox.p2.engine/.settings/org.eclipse.pde.core.prefs
new file mode 100644
index 000000000..7913d20db
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.engine/.settings/org.eclipse.pde.core.prefs
@@ -0,0 +1,4 @@
+
+eclipse.preferences.version=1
+pluginProject.extensions=false
+resolve.requirebundle=false
diff --git a/bundles/org.eclipse.equinox.p2.engine/META-INF/MANIFEST.MF b/bundles/org.eclipse.equinox.p2.engine/META-INF/MANIFEST.MF
new file mode 100644
index 000000000..7f3d1c98d
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.engine/META-INF/MANIFEST.MF
@@ -0,0 +1,28 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: Engine Plug-in (Incubation)
+Bundle-SymbolicName: org.eclipse.equinox.prov.engine;singleton:=true
+Bundle-Version: 0.1.0.qualifier
+Export-Package: org.eclipse.equinox.internal.prov.engine;x-internal:=true,
+ org.eclipse.equinox.prov.engine,
+ org.eclipse.equinox.prov.engine.phases,
+ org.eclipse.equinox.prov.installregistry
+Import-Package: com.thoughtworks.xstream,
+ org.eclipse.equinox.prov.artifact.repository,
+ org.eclipse.equinox.prov.core.eventbus,
+ org.eclipse.equinox.prov.core.helpers,
+ org.eclipse.equinox.prov.core.location,
+ org.eclipse.equinox.prov.download,
+ org.eclipse.equinox.prov.metadata,
+ org.eclipse.equinox.prov.query,
+ org.eclipse.osgi.service.datalocation;version="1.0.0",
+ org.eclipse.osgi.service.resolver;version="1.1.0",
+ org.eclipse.osgi.util;version="1.0.0",
+ org.osgi.framework;version="1.3.0",
+ org.osgi.util.tracker;version="1.3.3"
+Bundle-Activator: org.eclipse.equinox.internal.prov.engine.EngineActivator
+Eclipse-LazyStart: true
+Bundle-RequiredExecutionEnvironment: CDC-1.1/Foundation-1.1,
+ J2SE-1.4
+Require-Bundle: org.eclipse.equinox.common,
+ org.eclipse.equinox.registry
diff --git a/bundles/org.eclipse.equinox.p2.engine/about.html b/bundles/org.eclipse.equinox.p2.engine/about.html
new file mode 100644
index 000000000..460233046
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.engine/about.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"/>
+<title>About</title>
+</head>
+<body lang="EN-US">
+<h2>About This Content</h2>
+
+<p>June 2, 2006</p>
+<h3>License</h3>
+
+<p>The Eclipse Foundation makes available all content in this plug-in (&quot;Content&quot;). Unless otherwise
+indicated below, the Content is provided to you under the terms and conditions of the
+Eclipse Public License Version 1.0 (&quot;EPL&quot;). A copy of the EPL is available
+at <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a>.
+For purposes of the EPL, &quot;Program&quot; will mean the Content.</p>
+
+<p>If you did not receive this Content directly from the Eclipse Foundation, the Content is
+being redistributed by another party (&quot;Redistributor&quot;) and different terms and conditions may
+apply to your use of any object code in the Content. Check the Redistributor's license that was
+provided with the Content. If no such license exists, contact the Redistributor. Unless otherwise
+indicated below, the terms and conditions of the EPL still apply to any source code in the Content
+and such source code may be obtained at <a href="http://www.eclipse.org">http://www.eclipse.org</a>.</p>
+
+</body>
+</html> \ No newline at end of file
diff --git a/bundles/org.eclipse.equinox.p2.engine/build.properties b/bundles/org.eclipse.equinox.p2.engine/build.properties
new file mode 100644
index 000000000..8917af773
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.engine/build.properties
@@ -0,0 +1,16 @@
+###############################################################################
+# Copyright (c) 2007 IBM Corporation and others.
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+#
+# Contributors:
+# IBM Corporation - initial API and implementation
+###############################################################################
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+ .,\
+ plugin.xml,\
+ about.html
diff --git a/bundles/org.eclipse.equinox.p2.engine/plugin.xml b/bundles/org.eclipse.equinox.p2.engine/plugin.xml
new file mode 100644
index 000000000..990388563
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.engine/plugin.xml
@@ -0,0 +1,13 @@
+<plugin>
+<extension-point
+ id="touchpoints"
+ name="Touchpoints"
+ schema="schema/touchpoints.exsd"/>
+
+ <extension point="org.eclipse.equinox.prov.engine.touchpoints" id="null" name="Null Touchpoint">
+ <touchpoint
+ type="null"
+ class="org.eclipse.equinox.internal.prov.engine.NullTouchpoint"
+ version="1.0.0"/>
+ </extension>
+</plugin>
diff --git a/bundles/org.eclipse.equinox.p2.engine/schema/touchpoints.exsd b/bundles/org.eclipse.equinox.p2.engine/schema/touchpoints.exsd
new file mode 100644
index 000000000..e085a524a
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.engine/schema/touchpoints.exsd
@@ -0,0 +1,158 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- Schema file written by PDE -->
+<schema targetNamespace="org.eclipse.equinox.prov.engine">
+<annotation>
+ <appInfo>
+ <meta.schema plugin="org.eclipse.equinox.prov.engine" id="touchpoints" name="Touchpoints"/>
+ </appInfo>
+ <documentation>
+ [Enter description of this extension point.]
+ </documentation>
+ </annotation>
+
+ <element name="extension">
+ <complexType>
+ <sequence>
+ <element ref="touchpoint" minOccurs="0" maxOccurs="1"/>
+ <element ref="data" minOccurs="0" maxOccurs="unbounded"/>
+ </sequence>
+ <attribute name="point" type="string" use="required">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="id" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="name" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ <appInfo>
+ <meta.attribute translatable="true"/>
+ </appInfo>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <element name="touchpoint">
+ <complexType>
+ <attribute name="type" type="string" use="required">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="class" type="string" use="required">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ <appInfo>
+ <meta.attribute kind="java" basedOn="org.eclipse.equinox.prov.engine.ITouchpoint"/>
+ </appInfo>
+ </annotation>
+ </attribute>
+ <attribute name="version" type="string" use="required">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <element name="data">
+ <complexType>
+ <attribute name="name" type="string" use="required">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="type" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="description" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ <appInfo>
+ <meta.attribute translatable="true"/>
+ </appInfo>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="since"/>
+ </appInfo>
+ <documentation>
+ [Enter the first release in which this extension point appears.]
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="examples"/>
+ </appInfo>
+ <documentation>
+ &lt;p&gt;
+ &lt;pre&gt;
+ &lt;extension point=&quot;org.eclipse.equinox.prov.engine.installAdaptors&quot; id=&quot;eclipse&quot; name=&quot;Eclipse Install Adaptor&quot;&gt;
+ &lt;installAdaptor
+ type=&quot;eclipse&quot;
+ class=&quot;org.eclipse.equinox.internal.prov.eclipseAdaptor.EclipseInstallAdaptor&quot;
+ version=&quot;1.0.0&quot;/&gt;
+ &lt;/extension&gt;
+ &lt;/pre&gt;
+&lt;/p&gt;
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="apiInfo"/>
+ </appInfo>
+ <documentation>
+ [Enter API information here.]
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="implementation"/>
+ </appInfo>
+ <documentation>
+ [Enter information about supplied implementation of this extension point.]
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="copyright"/>
+ </appInfo>
+ <documentation>
+
+ </documentation>
+ </annotation>
+
+</schema>
diff --git a/bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/internal/prov/engine/CommonDef.java b/bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/internal/prov/engine/CommonDef.java
new file mode 100644
index 000000000..e24937a7f
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/internal/prov/engine/CommonDef.java
@@ -0,0 +1,63 @@
+/*******************************************************************************
+ * Copyright (c) 2007 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.equinox.internal.prov.engine;
+
+/*
+ * This interface contains global constant definitions.
+ *
+ * Use this interface to define constants that are likely to be used
+ * widely in different contexts with share a common intended meaning.
+ *
+ */
+public interface CommonDef {
+
+ public static final String EmptyString = ""; //$NON-NLS-1$
+ public static final String SpaceString = " "; //$NON-NLS-1$
+ public static final String Underscore = "_"; //$NON-NLS-1$
+ public static final String Dot = "."; //$NON-NLS-1$
+ public static final String DotDot = ".."; //$NON-NLS-1$
+
+ public static final String EncodedSpaceString = "%20"; //$NON-NLS-1$
+
+ public static final String UncPrefix = "\\\\"; //$NON-NLS-1$
+ public static final char ColonChar = ':';
+
+ /*
+ * Strings used as the type for the native and eclipse touchpoints,
+ * including the type in the touchpoints extension point.
+ */
+ public static final String NativeTouchpoint = "native"; //$NON-NLS-1$
+ public static final String EclipseTouchpoint = "eclipse"; //$NON-NLS-1$
+
+ public static final int MaxPathLength_Win32 = 256;
+ public static final int MaxPathLength_Linux = 1024;
+ //
+ // /*
+ // * Different protocols
+ // */
+ // public interface Protocols {
+ // public static final String File = "file"; //$NON-NLS-1$
+ // public static final String Http = "http"; //$NON-NLS-1$
+ // public static final String Https = "https"; //$NON-NLS-1$
+ // public static final String Ftp = "ftp"; //$NON-NLS-1$
+ // public static final String Socks = "SOCKS"; //$NON-NLS-1$
+ // }
+ //
+ // /*
+ // * File name extensions.
+ // */
+ // public interface Extensions {
+ // public static final String Xml = ".xml"; //$NON-NLS-1$
+ // public static final String Zip = ".zip"; //$NON-NLS-1$
+ // public static final String Jar = ".jar"; //$NON-NLS-1$
+ // public static final String Properties = ".properties"; //$NON-NLS-1$
+ // }
+}
diff --git a/bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/internal/prov/engine/EngineActivator.java b/bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/internal/prov/engine/EngineActivator.java
new file mode 100644
index 000000000..ee0b3eeac
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/internal/prov/engine/EngineActivator.java
@@ -0,0 +1,64 @@
+/*******************************************************************************
+ * Copyright (c) 2007 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.equinox.internal.prov.engine;
+
+import org.osgi.framework.*;
+import org.osgi.util.tracker.ServiceTracker;
+import org.osgi.util.tracker.ServiceTrackerCustomizer;
+import org.eclipse.equinox.prov.core.eventbus.ProvisioningEventBus;
+import org.eclipse.equinox.prov.engine.Engine;
+
+public class EngineActivator implements BundleActivator, ServiceTrackerCustomizer {
+ private static BundleContext context;
+ public static final String ID = "org.eclipse.equinox.prov.engine";
+
+ public static BundleContext getContext() {
+ return context;
+ }
+
+ private ServiceRegistration registration;
+ private ServiceTracker tracker;
+
+ public void start(BundleContext context) throws Exception {
+ EngineActivator.context = context;
+ tracker = new ServiceTracker(context, ProvisioningEventBus.class.getName(), this);
+ tracker.open();
+ }
+
+ public void stop(BundleContext context) throws Exception {
+ tracker.close();
+ tracker = null;
+
+ EngineActivator.context = null;
+ }
+
+ public Object addingService(ServiceReference reference) {
+ if (registration == null) {
+ ProvisioningEventBus eventBus = (ProvisioningEventBus) context.getService(reference);
+ registration = context.registerService(Engine.class.getName(), new Engine(eventBus), null);
+ return eventBus;
+ }
+ return null;
+ }
+
+ public void modifiedService(ServiceReference reference, Object service) {
+ // TODO Auto-generated method stub
+
+ }
+
+ public void removedService(ServiceReference reference, Object service) {
+ if (registration != null) {
+ registration.unregister();
+ registration = null;
+ }
+ }
+
+}
diff --git a/bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/internal/prov/engine/Messages.java b/bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/internal/prov/engine/Messages.java
new file mode 100644
index 000000000..c1dcd38fe
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/internal/prov/engine/Messages.java
@@ -0,0 +1,44 @@
+/*******************************************************************************
+ * Copyright (c) 2007 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.equinox.internal.prov.engine;
+
+import org.eclipse.osgi.util.NLS;
+
+public class Messages extends NLS {
+ private static final String BUNDLE_NAME = "org.eclipse.equinox.internal.prov.engine.messages"; //$NON-NLS-1$
+
+ static {
+ // initialize resource bundles
+ NLS.initializeMessages(BUNDLE_NAME, Messages.class);
+ }
+
+ private Messages() {
+ // Do not instantiate
+ }
+
+ public static String Engine_Error_During_Phase;
+ public static String Engine_Operation_Canceled_By_User;
+ public static String Profile_Not_Named_Self;
+ public static String Profile_Duplicate_Profile_Id;
+ public static String TouchpointManager_Null_Touchpoint_Type_Argument;
+ public static String TouchpointManager_Required_Touchpoint_Not_Found;
+ public static String TouchpointManager_No_Extension_Point;
+ public static String TouchpointManager_Incorrectly_Named_Extension;
+ public static String TouchpointManager_Attribute_Not_Specified;
+ public static String TouchpointManager_Conflicting_Touchpoint_Types;
+ public static String TouchpointManager_Touchpoint_Type_Mismatch;
+ public static String TouchpointManager_Exception_Creating_Touchpoint_Extension;
+ public static String TouchpointManager_Null_Creating_Touchpoint_Extension;
+ public static String Install_Operand_Description;
+ public static String Update_Operand_Description;
+ public static String Uninstall_Operand_Description;
+
+}
diff --git a/bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/internal/prov/engine/NullTouchpoint.java b/bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/internal/prov/engine/NullTouchpoint.java
new file mode 100644
index 000000000..2b8795770
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/internal/prov/engine/NullTouchpoint.java
@@ -0,0 +1,43 @@
+/*******************************************************************************
+ * Copyright (c) 2007 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.equinox.internal.prov.engine;
+
+import org.eclipse.equinox.prov.engine.*;
+import org.eclipse.equinox.prov.metadata.TouchpointType;
+
+/**
+ * A touchpoint that performs no processing.
+ */
+public class NullTouchpoint implements ITouchpoint {
+ public static final ITouchpoint INSTANCE = new NullTouchpoint();
+
+ /**
+ * Public constructor only intended to be called by extension registry.
+ */
+ public NullTouchpoint() {
+ super();
+ }
+
+ public TouchpointType getTouchpointType() {
+ return TouchpointType.NONE;
+ }
+
+ public boolean supports(String phaseId) {
+ if (phaseId.equals("install") || phaseId.equals("uninstall"))
+ return true;
+ return false;
+ }
+
+ public ITouchpointAction[] getActions(String phaseID, Profile profile, Operand operand) {
+ return new ITouchpointAction[] {};
+ }
+
+}
diff --git a/bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/internal/prov/engine/TouchpointManager.java b/bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/internal/prov/engine/TouchpointManager.java
new file mode 100644
index 000000000..ec2cf09a5
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/internal/prov/engine/TouchpointManager.java
@@ -0,0 +1,223 @@
+/*******************************************************************************
+ * Copyright (c) 2007 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.equinox.internal.prov.engine;
+
+import java.util.*;
+import org.eclipse.core.runtime.*;
+import org.eclipse.equinox.prov.core.helpers.LogHelper;
+import org.eclipse.equinox.prov.core.helpers.MultiStatus;
+import org.eclipse.equinox.prov.engine.ITouchpoint;
+import org.eclipse.equinox.prov.metadata.TouchpointType;
+import org.eclipse.osgi.util.NLS;
+
+//TODO This needs to support multiple version of each touchpoint and have a lookup that supports version semantics
+public class TouchpointManager implements IRegistryChangeListener {
+
+ private static TouchpointManager instance;
+
+ public static TouchpointManager getInstance() {
+ if (instance == null) {
+ instance = new TouchpointManager();
+ }
+ return instance;
+ }
+
+ private static final String PT_TOUCHPOINTS = "touchpoints"; //$NON-NLS-1$
+ private static final String ELEMENT_TOUCHPOINT = "touchpoint"; //$NON-NLS-1$
+ private static final String ELEMENT_TOUCHPOINT_DATA = "data"; //$NON-NLS-1$
+ private static final String ATTRIBUTE_CLASS = "class"; //$NON-NLS-1$
+ private static final String ATTRIBUTE_TYPE = "type"; //$NON-NLS-1$
+
+ private class TouchpointEntry {
+
+ private IConfigurationElement element;
+ private boolean createdExtension;
+ private ITouchpoint touchpoint;
+
+ public TouchpointEntry(IConfigurationElement element) {
+ super();
+ this.element = element;
+ this.touchpoint = null;
+ this.createdExtension = false;
+ }
+
+ public TouchpointEntry(IConfigurationElement element, ITouchpoint touchpoint) {
+ super();
+ this.element = element;
+ this.touchpoint = touchpoint;
+ this.createdExtension = (touchpoint != null ? true : false);
+ }
+
+ public boolean hasTouchpoint() {
+ return (this.touchpoint != null);
+ }
+
+ public ITouchpoint getTouchpoint() {
+ if (!createdExtension) {
+ String id = element.getAttribute(ATTRIBUTE_TYPE);
+ try {
+ ITouchpoint touchpoint = (ITouchpoint) element.createExecutableExtension(ATTRIBUTE_CLASS);
+ if (touchpoint != null) {
+ if (!id.equals(touchpoint.getTouchpointType().getId())) {
+ reportError(NLS.bind(Messages.TouchpointManager_Touchpoint_Type_Mismatch, id, touchpoint.getTouchpointType().getId()), null);
+ }
+ this.touchpoint = touchpoint;
+ } else {
+ String errorMsg = NLS.bind(Messages.TouchpointManager_Null_Creating_Touchpoint_Extension, id);
+ throw new CoreException(new Status(IStatus.ERROR, EngineActivator.ID, 1, errorMsg, null));
+ }
+ } catch (CoreException cexcpt) {
+ LogHelper.log(new Status(IStatus.ERROR, EngineActivator.ID, NLS.bind(Messages.TouchpointManager_Exception_Creating_Touchpoint_Extension, id), cexcpt));
+ } catch (ClassCastException ccexcpt) {
+ LogHelper.log(new Status(IStatus.ERROR, EngineActivator.ID, NLS.bind(Messages.TouchpointManager_Exception_Creating_Touchpoint_Extension, id), ccexcpt));
+ }
+ // Mark as created even in error cases,
+ // so exceptions are not logged multiple times
+ createdExtension = true;
+ }
+ return this.touchpoint;
+ }
+
+ public String toString() {
+ StringBuffer result = new StringBuffer(element.toString());
+ if (createdExtension) {
+ String touchpointString = touchpoint != null ? touchpoint.toString() : "not created"; //$NON-NLS-1$
+ result.append(" => " + touchpointString); //$NON-NLS-1$
+ }
+ return result.toString();
+ }
+ }
+
+ // TODO: Do we really want to store the touchpoints? The danger is
+ // that if two installations are performed simultaneously, then...
+ // TODO: Figure out locking, concurrency requirements for touchpoints.
+ private Map touchpointEntries;
+
+ private TouchpointManager() {
+ RegistryFactory.getRegistry().addRegistryChangeListener(this, EngineActivator.ID);
+ }
+
+ /*
+ * Return the touchpoint which is registered for the given id,
+ * or <code>null</code> if none are registered.
+ */
+ public ITouchpoint getTouchpoint(TouchpointType id) {
+ if (id == null || CommonDef.EmptyString.equals(id.getId()))
+ throw new IllegalArgumentException(Messages.TouchpointManager_Null_Touchpoint_Type_Argument);
+ if (touchpointEntries == null) {
+ initializeTouchpoints();
+ }
+ TouchpointEntry entry = (TouchpointEntry) touchpointEntries.get(id.getId());
+ return entry == null ? null : entry.getTouchpoint();
+ }
+
+ public ITouchpoint[] getAllTouchpoints() {
+ if (touchpointEntries == null) {
+ initializeTouchpoints();
+ }
+ Collection adapters = touchpointEntries.values();
+
+ ArrayList touchpoints = new ArrayList(adapters.size());
+ for (Iterator iter = adapters.iterator(); iter.hasNext();) {
+ TouchpointEntry entry = (TouchpointEntry) iter.next();
+ ITouchpoint touchpoint = entry.getTouchpoint();
+ if (touchpoint != null) {
+ touchpoints.add(touchpoint);
+ }
+ }
+ return (ITouchpoint[]) touchpoints.toArray(new ITouchpoint[touchpoints.size()]);
+ }
+
+ public ITouchpoint[] getCreatedTouchpoints() {
+ if (touchpointEntries == null)
+ return new ITouchpoint[0];
+ Collection adapters = touchpointEntries.values();
+
+ ArrayList touchpoints = new ArrayList(adapters.size());
+ for (Iterator iter = adapters.iterator(); iter.hasNext();) {
+ TouchpointEntry entry = (TouchpointEntry) iter.next();
+ if (entry.hasTouchpoint()) {
+ ITouchpoint touchpoint = entry.getTouchpoint();
+ if (touchpoint != null) {
+ touchpoints.add(touchpoint);
+ }
+ }
+ }
+ return (ITouchpoint[]) touchpoints.toArray(new ITouchpoint[touchpoints.size()]);
+ }
+
+ public IStatus validateTouchpoints(String[] requiredTypes) {
+ MultiStatus status = (touchpointEntries == null ? initializeTouchpoints() : new MultiStatus());
+
+ for (int i = 0; i < requiredTypes.length; i++) {
+ TouchpointEntry entry = (TouchpointEntry) touchpointEntries.get(requiredTypes[i]);
+ if (entry == null) {
+ reportError(NLS.bind(Messages.TouchpointManager_Required_Touchpoint_Not_Found, requiredTypes[i]), status);
+ }
+ }
+ return status;
+ }
+
+ /*
+ * Construct a map of the extensions that implement the touchpoints extension point.
+ */
+ private MultiStatus initializeTouchpoints() {
+ MultiStatus status = new MultiStatus();
+ IExtensionPoint point = RegistryFactory.getRegistry().getExtensionPoint(EngineActivator.ID, PT_TOUCHPOINTS);
+ if (point == null) {
+ reportError(NLS.bind(Messages.TouchpointManager_No_Extension_Point, EngineActivator.ID, PT_TOUCHPOINTS), status);
+ touchpointEntries = new HashMap(0);
+ return status;
+ }
+
+ IExtension[] extensions = point.getExtensions();
+ touchpointEntries = new HashMap(extensions.length);
+ for (int i = 0; i < extensions.length; i++) {
+ IConfigurationElement[] elements = extensions[i].getConfigurationElements();
+ for (int j = 0; j < elements.length; j++) {
+ String elementName = elements[j].getName();
+ if (!ELEMENT_TOUCHPOINT.equalsIgnoreCase(elements[j].getName())) {
+ if (!ELEMENT_TOUCHPOINT_DATA.equals(elementName)) { // TODO: are 'data' elements still needed?
+ reportError(NLS.bind(Messages.TouchpointManager_Incorrectly_Named_Extension, elements[j].getName(), ELEMENT_TOUCHPOINT), status);
+ }
+ continue;
+ }
+ String id = elements[j].getAttribute(ATTRIBUTE_TYPE);
+ if (id == null) {
+ reportError(NLS.bind(Messages.TouchpointManager_Attribute_Not_Specified, ATTRIBUTE_TYPE), status);
+ continue;
+ }
+ if (touchpointEntries.get(id) == null) {
+ touchpointEntries.put(id, new TouchpointEntry(elements[j]));
+ } else {
+ reportError(NLS.bind(Messages.TouchpointManager_Conflicting_Touchpoint_Types, ATTRIBUTE_TYPE, id), status);
+ }
+ }
+ }
+ return status;
+ }
+
+ private static void reportError(String errorMsg, MultiStatus status) {
+ Status errorStatus = new Status(IStatus.ERROR, EngineActivator.ID, 1, errorMsg, null);
+ if (status != null) {
+ status.add(errorStatus);
+ }
+ LogHelper.log(errorStatus);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.core.runtime.IRegistryChangeListener#registryChanged(org.eclipse.core.runtime.IRegistryChangeEvent)
+ */
+ public void registryChanged(IRegistryChangeEvent event) {
+ // just flush the cache when something changed. It will be recomputed on demand.
+ touchpointEntries = null;
+ }
+}
diff --git a/bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/internal/prov/engine/messages.properties b/bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/internal/prov/engine/messages.properties
new file mode 100644
index 000000000..9b10bd1cb
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/internal/prov/engine/messages.properties
@@ -0,0 +1,29 @@
+###############################################################################
+# Copyright (c) 2007 IBM Corporation and others.
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+#
+# Contributors:
+# IBM Corporation - initial API and implementation
+###############################################################################
+
+Engine_Error_During_Phase=Error during phase: {0}.
+Engine_Operation_Canceled_By_User=Operation canceled by the user.
+
+Profile_Duplicate_Profile_Id=Adding profile with duplicate id: {0}.
+Profile_Not_Named_Self=Can't have a profile named: {0}.
+TouchpointManager_Null_Touchpoint_Type_Argument=A null or empty string was passed as the type of a touchpoint.
+TouchpointManager_Required_Touchpoint_Not_Found=The required {0} touchpoint is not included in the installation manager configuration.
+TouchpointManager_No_Extension_Point=The extension point {0}.{1} was not found in the platform extension registry.
+TouchpointManager_Incorrectly_Named_Extension=A touchpoint extension is incorrectly named {0} instead of {1}.
+TouchpointManager_Attribute_Not_Specified=The required attribute {0} is not specified for the touchpoints extension point.
+TouchpointManager_Conflicting_Touchpoint_Types=Two or more touchpoint extensions of type {0} are defined.
+TouchpointManager_Touchpoint_Type_Mismatch=The touchpoint registered for type {0} reports its type as {1}.
+TouchpointManager_Exception_Creating_Touchpoint_Extension=An exception was thrown and caught when creating the extension point instance for the {0} touchpoint.
+TouchpointManager_Null_Creating_Touchpoint_Extension=A null object was returned when creating the extension point instance for the {0} touchpoint.
+
+Install_Operand_Description=Installing unit {0}.
+Update_Operand_Description=Updating unit {0} with unit {1}.
+Uninstall_Operand_Description=Removing unit {0}.
diff --git a/bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/prov/engine/AbstractProvisioningTransaction.java b/bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/prov/engine/AbstractProvisioningTransaction.java
new file mode 100644
index 000000000..2f48238a2
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/prov/engine/AbstractProvisioningTransaction.java
@@ -0,0 +1,135 @@
+/*******************************************************************************
+ * Copyright (c) 2007 IBM Corporation and others. All rights reserved. This
+ * program and the accompanying materials are made available under the terms of
+ * the Eclipse Public License v1.0 which accompanies this distribution, and is
+ * available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors: IBM Corporation - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.equinox.prov.engine;
+
+import java.util.ArrayList;
+import org.eclipse.core.runtime.*;
+import org.eclipse.equinox.internal.prov.engine.EngineActivator;
+import org.eclipse.equinox.prov.core.helpers.MultiStatus;
+import org.eclipse.equinox.prov.core.helpers.MultiStatusUtil;
+import org.eclipse.osgi.util.NLS;
+
+/**
+ * An abstract provisioning transaction specifies a simple mechanism
+ * for atomicity of a sequence of actions, based on the ability to
+ * revert the consequences of those actions.
+ *
+ * TODO: Implementation(s) of transactions should be registered via
+ * an extension point by classes that extended this class.
+ * This class should really be abstract.
+ */
+public abstract class AbstractProvisioningTransaction {
+
+ private ArrayList actions = new ArrayList();
+
+ private String description;
+
+ private boolean isUndoable;
+
+ private MultiStatus result;
+
+ private IProgressMonitor progressMonitor;
+
+ public AbstractProvisioningTransaction(String description, boolean isUndoable, MultiStatus result, IProgressMonitor monitor) {
+ this.description = description;
+ this.isUndoable = isUndoable;
+ this.result = (result != null ? result : new MultiStatus());
+ this.progressMonitor = monitor;
+ }
+
+ public IStatus performActions(IProvisioningAction[] ops, int[] weights, IProgressMonitor monitor) {
+ SubMonitor pm = SubMonitor.convert(monitor, weights.length);
+ IStatus status = Status.OK_STATUS;
+ try {
+ for (int i = 0; i < ops.length; i += 1) {
+ IProvisioningAction action = ops[i];
+ IProgressMonitor sub = (i < weights.length ? (IProgressMonitor) pm.newChild(weights[i]) : new NullProgressMonitor());
+ status = performAction(action, sub);
+ if (MultiStatusUtil.isErrorOrCancel(status)) {
+ break;
+ }
+ }
+ } finally {
+ pm.done();
+ }
+ return status;
+ }
+
+ protected IStatus performAction(IProvisioningAction action, IProgressMonitor monitor) {
+ actions.add(action);
+ IStatus opStatus = action.perform(this, monitor);
+ IStatus status = opStatus;
+
+ if (!isUndoable) {
+ result.add(opStatus);
+ status = Status.OK_STATUS;
+ } else if (MultiStatusUtil.isErrorOrCancel(opStatus)) {
+ int length = actions.size();
+ IProvisioningAction lastAction = (IProvisioningAction) actions.get(length - 1);
+ if (!lastAction.shouldRevertOnError()) {
+ actions.remove(length - 1);
+ }
+ } else if (monitor.isCanceled()) {
+ // first time we noticed cancellation
+ opStatus = new Status(IStatus.CANCEL, EngineActivator.ID, 0, ""/*Messages.Engine_Operation_Canceled_By_User*/, null);
+ }
+
+ if (opStatus.matches(IStatus.ERROR) && result.getMessage().length() == 0) {
+ result.setMessage(NLS.bind("Errors occurred during the transaction {0}", //$NON-NLS-1$
+ description));
+ } else if (opStatus.matches(IStatus.CANCEL) && result.getMessage().length() == 0) {
+ result.setMessage(NLS.bind("The transaction {0} was canceled", //$NON-NLS-1$
+ description));
+ }
+
+ monitor.done();
+ return status;
+ }
+
+ public void rollback(IProgressMonitor monitor) {
+ if (!isUndoable)
+ return;
+ isUndoable = false;
+
+ // TODO: is it necessary to allow support rollback that does NOT reverse the order
+ // of the actions? Consider phases.
+
+ SubMonitor pm = SubMonitor.convert(monitor, actions.size());
+ for (int i = actions.size() - 1; i >= 0; i--) {
+ IProvisioningAction action = (IProvisioningAction) actions.get(i);
+ try {
+ IStatus status = action.revert(this, pm.newChild(10));
+ // log.statusNotOK(status);
+ } catch (Exception e) {
+ // log.exception
+ }
+ }
+ }
+
+ public IProgressMonitor getProgressMonitor() {
+ return progressMonitor;
+ }
+
+ public boolean isUndoable() {
+ return isUndoable;
+ }
+
+ public String toString() {
+ StringBuffer sb = new StringBuffer();
+ sb.append("Transaction: "); //$NON-NLS-1$
+ sb.append(description);
+ sb.append(", ").append(actions.size()).append( //$NON-NLS-1$
+ " actions performed"); //$NON-NLS-1$
+ if (!isUndoable) {
+ sb.append(", isUndoable=").append(isUndoable); //$NON-NLS-1$
+ }
+ return sb.toString();
+ }
+
+}
diff --git a/bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/prov/engine/BeginOperationEvent.java b/bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/prov/engine/BeginOperationEvent.java
new file mode 100644
index 000000000..9acffd2cf
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/prov/engine/BeginOperationEvent.java
@@ -0,0 +1,20 @@
+/*******************************************************************************
+ * Copyright (c) 2007 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.equinox.prov.engine;
+
+public class BeginOperationEvent extends TransactionEvent {
+
+ private static final long serialVersionUID = 6389318375739324865L;
+
+ public BeginOperationEvent(Profile profile, PhaseSet phaseSet, Operand[] deltas, Engine engine) {
+ super(profile, phaseSet, deltas, engine);
+ }
+}
diff --git a/bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/prov/engine/CommitOperationEvent.java b/bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/prov/engine/CommitOperationEvent.java
new file mode 100644
index 000000000..e3bdd998a
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/prov/engine/CommitOperationEvent.java
@@ -0,0 +1,20 @@
+/*******************************************************************************
+ * Copyright (c) 2007 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.equinox.prov.engine;
+
+public class CommitOperationEvent extends TransactionEvent {
+ private static final long serialVersionUID = -523967775426133720L;
+
+ public CommitOperationEvent(Profile profile, PhaseSet phaseSet, Operand[] deltas, Engine engine) {
+ super(profile, phaseSet, deltas, engine);
+ }
+
+}
diff --git a/bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/prov/engine/DefaultPhaseSet.java b/bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/prov/engine/DefaultPhaseSet.java
new file mode 100644
index 000000000..ec52bb252
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/prov/engine/DefaultPhaseSet.java
@@ -0,0 +1,21 @@
+/*******************************************************************************
+ * Copyright (c) 2007 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.equinox.prov.engine;
+
+import org.eclipse.equinox.prov.engine.phases.*;
+
+public class DefaultPhaseSet extends PhaseSet {
+
+ public DefaultPhaseSet() {
+ super(new Phase[] {new Collect(10), new Uninstall(10), new Install(10)});
+ }
+
+}
diff --git a/bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/prov/engine/Engine.java b/bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/prov/engine/Engine.java
new file mode 100644
index 000000000..4a81eb640
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/prov/engine/Engine.java
@@ -0,0 +1,83 @@
+/*******************************************************************************
+ * Copyright (c) 2007 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.equinox.prov.engine;
+
+import java.util.ArrayList;
+import java.util.List;
+import org.eclipse.core.runtime.*;
+import org.eclipse.equinox.prov.core.eventbus.ProvisioningEventBus;
+import org.eclipse.equinox.prov.core.helpers.MultiStatus;
+
+public class Engine {
+
+ private final ProvisioningEventBus eventBus;
+ private List lockedProfiles = new ArrayList();
+
+ public Engine(ProvisioningEventBus eventBus) {
+ this.eventBus = eventBus;
+ }
+
+ public MultiStatus perform(Profile profile, PhaseSet phaseSet, Operand[] operands, IProgressMonitor monitor) {
+
+ // TODO -- Messages
+ if (profile == null)
+ throw new IllegalArgumentException("Profile must not be null.");
+
+ if (phaseSet == null)
+ throw new IllegalArgumentException("PhaseSet must not be null.");
+
+ if (operands == null)
+ throw new IllegalArgumentException("Operands must not be null.");
+
+ if (monitor == null)
+ monitor = new NullProgressMonitor();
+
+ if (operands.length == 0)
+ return new MultiStatus(IStatus.OK, null);
+
+ lockProfile(profile);
+ try {
+ eventBus.publishEvent(new BeginOperationEvent(profile, phaseSet, operands, this));
+
+ EngineSession session = new EngineSession();
+ MultiStatus result = phaseSet.perform(session, profile, operands, monitor);
+ if (result.isOK()) {
+ eventBus.publishEvent(new CommitOperationEvent(profile, phaseSet, operands, this));
+ session.commit();
+ }
+
+ if (result.isErrorOrCancel()) {
+ eventBus.publishEvent(new RollbackOperationEvent(profile, phaseSet, operands, this, result));
+ session.rollback();
+ }
+ return result;
+ } finally {
+ unlockProfile(profile);
+ }
+ }
+
+ private synchronized void unlockProfile(Profile profile) {
+ lockedProfiles.remove(profile);
+ notify();
+ }
+
+ private synchronized void lockProfile(Profile profile) {
+ while (lockedProfiles.contains(profile)) {
+ try {
+ wait();
+ } catch (InterruptedException e) {
+ // TODO We should think about how we want to handle blocked engine requests
+ Thread.currentThread().interrupt();
+ }
+ }
+ lockedProfiles.add(profile);
+ }
+}
diff --git a/bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/prov/engine/EngineSession.java b/bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/prov/engine/EngineSession.java
new file mode 100644
index 000000000..893e40ec0
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/prov/engine/EngineSession.java
@@ -0,0 +1,33 @@
+/*******************************************************************************
+ * Copyright (c) 2007 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.equinox.prov.engine;
+
+import java.util.*;
+
+public class EngineSession {
+ List actions = new ArrayList();
+
+ public void record(ITouchpointAction action) {
+ actions.add(action);
+ }
+
+ public void commit() {
+ actions.clear();
+ }
+
+ public void rollback() {
+ for (ListIterator it = actions.listIterator(actions.size()); it.hasPrevious();) {
+ ITouchpointAction action = (ITouchpointAction) it.previous();
+ action.undo();
+ }
+ }
+
+}
diff --git a/bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/prov/engine/IProfileRegistry.java b/bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/prov/engine/IProfileRegistry.java
new file mode 100644
index 000000000..504ae8651
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/prov/engine/IProfileRegistry.java
@@ -0,0 +1,53 @@
+/*******************************************************************************
+ * Copyright (c) 2007 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.equinox.prov.engine;
+
+/**
+ * This encapsulates the access to the profile registry.
+ * It deals with persistence in a transparent way.
+ */
+public interface IProfileRegistry {
+ public static final String SELF = "_SELF_"; //$NON-NLS-1$
+
+ /**
+ * Return the profile in the registry that has the given id. If it does not exist,
+ * then return <code>null</code>.
+ *
+ * @param id the profile identifier
+ * @return the profile or <code>null</code>
+ */
+ Profile getProfile(String id);
+
+ /**
+ * Return an array of profiles known to this registry. If there are none, then
+ * return an empty array.
+ *
+ * @return the array of profiles
+ */
+ Profile[] getProfiles();
+
+ /**
+ * Add the given profile to this profile registry.
+ *
+ * @param toAdd the profile to add
+ * @throws IllegalArgumentException if a profile
+ * with the same id is already present in the registry.
+ */
+ void addProfile(Profile toAdd) throws IllegalArgumentException;
+
+ /**
+ * Remove the given profile from this profile registry.
+ *
+ * @param toRemove the profile to remove
+ */
+ void removeProfile(Profile toRemove);
+
+}
diff --git a/bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/prov/engine/IProvisioningAction.java b/bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/prov/engine/IProvisioningAction.java
new file mode 100644
index 000000000..7b976aa69
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/prov/engine/IProvisioningAction.java
@@ -0,0 +1,36 @@
+/*******************************************************************************
+ * Copyright (c) 2007 IBM Corporation and others. All rights reserved. This
+ * program and the accompanying materials are made available under the terms of
+ * the Eclipse Public License v1.0 which accompanies this distribution, and is
+ * available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors: IBM Corporation - initial API and implementation
+ ******************************************************************************/
+
+package org.eclipse.equinox.prov.engine;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+
+/**
+ * The provisioning action interface represents a unit of work
+ * that can be performed during a provisioning activity.
+ * The granularity of the action can vary from a simple,
+ * indivisible unit of work to a complex, organized collection
+ * of steps.
+ * <p>
+ * The results of an provisioning activity must be revert-able
+ * an error or if a cancellation occurs. A provisioning action
+ * that will return an error or cancel status may choose to revert
+ * any work performed before returning or may indicate that
+ * the caller must explicitly revert.
+ */
+public interface IProvisioningAction {
+
+ public IStatus perform(AbstractProvisioningTransaction transaction, IProgressMonitor monitor);
+
+ public IStatus revert(AbstractProvisioningTransaction transaction, IProgressMonitor monitor);
+
+ public boolean shouldRevertOnError();
+
+}
diff --git a/bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/prov/engine/ITouchpoint.java b/bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/prov/engine/ITouchpoint.java
new file mode 100644
index 000000000..838d2a3de
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/prov/engine/ITouchpoint.java
@@ -0,0 +1,26 @@
+/*******************************************************************************
+ * Copyright (c) 2007 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.equinox.prov.engine;
+
+import org.eclipse.equinox.prov.metadata.TouchpointType;
+
+/**
+ * A touchpoint is responsible for executing a given phase for a given
+ * targeted system (eclipse, native). The order of phases is defined in the {@link PhaseSet}.
+ */
+public interface ITouchpoint {
+
+ public TouchpointType getTouchpointType();
+
+ public boolean supports(String phaseId);
+
+ public ITouchpointAction[] getActions(String phaseId, Profile profile, Operand operand);
+}
diff --git a/bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/prov/engine/ITouchpointAction.java b/bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/prov/engine/ITouchpointAction.java
new file mode 100644
index 000000000..c7a9a78e7
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/prov/engine/ITouchpointAction.java
@@ -0,0 +1,18 @@
+/*******************************************************************************
+ * Copyright (c) 2007 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.equinox.prov.engine;
+
+public interface ITouchpointAction {
+
+ Object execute();
+
+ Object undo();
+}
diff --git a/bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/prov/engine/IUPhase.java b/bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/prov/engine/IUPhase.java
new file mode 100644
index 000000000..4ac09ee3c
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/prov/engine/IUPhase.java
@@ -0,0 +1,100 @@
+/*******************************************************************************
+ * Copyright (c) 2007 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.equinox.prov.engine;
+
+import org.eclipse.core.runtime.*;
+import org.eclipse.equinox.prov.core.helpers.MultiStatus;
+
+// An operation that is applied to a set of IUs.
+public abstract class IUPhase extends Phase {
+ protected int PRE_PERFORM_WORK = 1000;
+ protected int PERFORM_WORK = 10000;
+ protected int POST_PERFORM_WORK = 1000;
+
+ protected IUPhase(String phaseId, int weight, String phaseName) {
+ super(phaseId, weight, phaseName);
+ }
+
+ protected void perform(MultiStatus status, EngineSession session, Profile profile, Operand[] operands, IProgressMonitor monitor) { //TODO Maybe should we do some kind of adaptable
+ SubMonitor subMonitor = SubMonitor.convert(monitor, PRE_PERFORM_WORK + PERFORM_WORK + POST_PERFORM_WORK);
+ prePerform(status, profile, operands, subMonitor.newChild(PRE_PERFORM_WORK));
+ if (status.isErrorOrCancel())
+ return;
+
+ subMonitor.setWorkRemaining(PERFORM_WORK + POST_PERFORM_WORK);
+ mainPerform(status, session, profile, operands, subMonitor.newChild(PERFORM_WORK));
+ if (status.isErrorOrCancel())
+ return;
+
+ subMonitor.setWorkRemaining(POST_PERFORM_WORK);
+ postPerform(status, profile, operands, subMonitor.newChild(POST_PERFORM_WORK));
+ if (status.isErrorOrCancel())
+ return;
+
+ subMonitor.done();
+ }
+
+ protected void mainPerform(MultiStatus status, EngineSession session, Profile profile, Operand[] operands, SubMonitor subMonitor) {
+ int operandWork = PERFORM_WORK / operands.length;
+ for (int i = 0; i < operands.length; ++i) {
+ if (subMonitor.isCanceled())
+ throw new OperationCanceledException();
+ Operand currentOperand = operands[i];
+ if (!isApplicable(currentOperand))
+ continue;
+ IStatus result = performOperand(session, profile, currentOperand, subMonitor.newChild(operandWork));
+ status.add(result);
+ if (status.isErrorOrCancel())
+ return;
+ }
+ }
+
+ protected abstract boolean isApplicable(Operand op);
+
+ // ITouchpoint touchpoint = TouchpointManager.getInstance().getTouchpoint(currentOperand.getTouchpointType());
+ // if (touchpoint == null) { //TODO Should we throw an exception instead?
+ // status.add(new Status(IStatus.ERROR, "org.eclipse.equinox.prov.engine", "The touchpoint " + currentOperand.getTouchpointType() + " is not available."));
+ // return;
+ // }
+ // if (touchpoint.supports(phaseId)) {
+ // status.add(performIU(touchpoint, currentOperand, subMonitor.newChild(operandWork)));
+ // }
+ // if (status.isErrorOrCancel() || sub.isCanceled()) {
+ // undoPerform(status, ius, i, context);
+ // return;
+ // }
+
+ // Error or cancel: undo IUs that were done.
+ // private void undoPerform(MultiStatus status, InstallableUnitPair[] ius, int currentIU, InstallContext context) {
+ // if (!status.isErrorOrCancel()) {
+ // status.setCanceled(); // first time we noticed cancelation
+ // currentIU += 1; // currentIU was completed so it must be undone
+ // }
+ // InstallableUnitPair[] undoIUs = new InstallableUnitPair[currentIU];
+ // for (int i = 0; i < currentIU; i += 1) {
+ // log.debug("Undo {0} phase for {1}", super.phaseName, ius[i]); //$NON-NLS-1$
+ // undoIUs[i] = ius[currentIU - (i + 1)].reverse();
+ // }
+ // // 1 unit to undo this phase, 10 for preceding phases
+ // SplitProgressMonitor pm = new SplitProgressMonitor(getUndoProgressMonitor(), new int[] {1, 10});
+ // doPerform(status, /*undoable*/false, undoIUs, context, pm.next());
+ // setUndoProgressMonitor(pm.next());
+ // }
+ protected abstract IStatus performOperand(EngineSession session, Profile profile, Operand operand, IProgressMonitor monitor);
+
+ protected void prePerform(MultiStatus status, Profile profile, Operand[] deltas, IProgressMonitor monitor) {
+ //Nothing to do.
+ }
+
+ protected void postPerform(MultiStatus status, Profile profile, Operand[] deltas, IProgressMonitor monitor) {
+ //Nothing to do.
+ }
+}
diff --git a/bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/prov/engine/InstallableUnitEvent.java b/bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/prov/engine/InstallableUnitEvent.java
new file mode 100644
index 000000000..6ba45dc09
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/prov/engine/InstallableUnitEvent.java
@@ -0,0 +1,68 @@
+/*******************************************************************************
+ * Copyright (c) 2007 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.equinox.prov.engine;
+
+import java.util.EventObject;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+
+public class InstallableUnitEvent extends EventObject {
+ private static final long serialVersionUID = 3318712818811459886L;
+
+ private String phaseId;
+ private boolean prePhase;
+
+ private Profile profile;
+ private Operand operand;
+ private ITouchpoint touchpoint;
+ private IStatus result;
+
+ public InstallableUnitEvent(String phaseId, boolean prePhase, Profile profile, Operand operand, ITouchpoint touchpoint) {
+ this(phaseId, prePhase, profile, operand, touchpoint, null);
+ }
+
+ public InstallableUnitEvent(String phaseId, boolean prePhase, Profile profile, Operand operand, ITouchpoint touchpoint, IStatus result) {
+ super(touchpoint); //TODO not sure if the touchpoint should be the source
+ this.phaseId = phaseId;
+ this.prePhase = prePhase;
+ this.profile = profile;
+ this.operand = operand;
+ this.result = result;
+ }
+
+ public ITouchpoint getTouchpoint() {
+ return touchpoint;
+ }
+
+ public Profile getProfile() {
+ return profile;
+ }
+
+ public Operand getOperand() {
+ return operand;
+ }
+
+ public String getPhase() {
+ return phaseId;
+ }
+
+ public boolean isPre() {
+ return prePhase;
+ }
+
+ public boolean isPost() {
+ return !prePhase;
+ }
+
+ public IStatus getResult() {
+ return (result != null ? result : Status.OK_STATUS);
+ }
+}
diff --git a/bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/prov/engine/Operand.java b/bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/prov/engine/Operand.java
new file mode 100644
index 000000000..5a4ac821e
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/prov/engine/Operand.java
@@ -0,0 +1,35 @@
+/*******************************************************************************
+ * Copyright (c) 2007 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.equinox.prov.engine;
+
+import org.eclipse.equinox.prov.metadata.IResolvedInstallableUnit;
+
+public class Operand {
+ private final IResolvedInstallableUnit first;
+ private final IResolvedInstallableUnit second;
+
+ public Operand(IResolvedInstallableUnit first, IResolvedInstallableUnit second) {
+ this.first = first;
+ this.second = second;
+ }
+
+ public IResolvedInstallableUnit first() {
+ return first;
+ }
+
+ public IResolvedInstallableUnit second() {
+ return second;
+ }
+
+ public String toString() {
+ return first + " --> " + second; //$NON-NLS-1$
+ }
+}
diff --git a/bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/prov/engine/Phase.java b/bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/prov/engine/Phase.java
new file mode 100644
index 000000000..19729096f
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/prov/engine/Phase.java
@@ -0,0 +1,61 @@
+/*******************************************************************************
+ * Copyright (c) 2007 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.equinox.prov.engine;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.equinox.internal.prov.engine.Messages;
+import org.eclipse.equinox.prov.core.helpers.MultiStatus;
+import org.eclipse.osgi.util.NLS;
+
+public abstract class Phase {
+ protected final String phaseId;
+ protected final int weight;
+ protected final String phaseName;
+
+ protected Phase(String phaseId, int weight, String phaseName) {
+ if (phaseId == null || phaseId.length() == 0) {
+ throw new IllegalArgumentException("Phase id must be set.");
+ }
+
+ if (weight <= 0) {
+ throw new IllegalArgumentException("Phase weight must be positive.");
+ }
+
+ if (phaseName == null || phaseName.length() == 0) {
+ throw new IllegalArgumentException("Phase name must be set.");
+ }
+
+ this.weight = weight;
+ this.phaseName = phaseName;
+ this.phaseId = phaseId;
+ }
+
+ public String toString() {
+ return "Phase: " + this.phaseName + " - " + this.weight; //$NON-NLS-1$ //$NON-NLS-2$
+ }
+
+ protected MultiStatus perform(EngineSession session, Profile profile, Operand[] deltas, IProgressMonitor monitor) {
+ MultiStatus status = new MultiStatus();
+ // log.start(log.info(Messages2.Engine_Performing_Phase, this.phaseName));
+ perform(status, session, profile, deltas, monitor);
+ // log.stop();
+ if (status.matches(IStatus.CANCEL)) {
+ status.setMessage(Messages.Engine_Operation_Canceled_By_User);
+ } else if (status.matches(IStatus.ERROR)) {
+ status.setMessage(NLS.bind(Messages.Engine_Error_During_Phase, this.phaseName));
+ }
+ return status;
+ }
+
+ protected abstract void perform(MultiStatus status, EngineSession session, Profile profile, Operand[] deltas, IProgressMonitor monitor);
+
+} \ No newline at end of file
diff --git a/bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/prov/engine/PhaseSet.java b/bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/prov/engine/PhaseSet.java
new file mode 100644
index 000000000..f5d85a2b4
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/prov/engine/PhaseSet.java
@@ -0,0 +1,64 @@
+/*******************************************************************************
+ * Copyright (c) 2007 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.equinox.prov.engine;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.SubMonitor;
+import org.eclipse.equinox.prov.core.helpers.MultiStatus;
+
+public abstract class PhaseSet {
+ private final Phase[] phases;
+
+ public PhaseSet(Phase[] phases) {
+ if (phases == null)
+ throw new IllegalArgumentException("Phases must not be null");
+
+ this.phases = phases;
+ }
+
+ public MultiStatus perform(EngineSession session, Profile profile, Operand[] deltas, IProgressMonitor monitor) {
+ MultiStatus result = new MultiStatus();
+ int[] weights = getProgressWeights();
+ int totalWork = getTotalWork(weights);
+ SubMonitor pm = SubMonitor.convert(monitor, totalWork);
+ try {
+ for (int i = 0; i < phases.length; i++) {
+ if (pm.isCanceled()) {
+ result.setCanceled();
+ return result;
+ }
+ Phase phase = phases[i];
+ result.add(phase.perform(session, profile, deltas, pm.newChild(weights[i])));
+ if (result.isErrorOrCancel())// || sub.isCanceled()) {
+ //TODO Need to perform the undo if we don't we use transactions
+ return result;
+ }
+ } finally {
+ pm.done();
+ }
+ return result;
+ }
+
+ private int getTotalWork(int[] weights) {
+ int sum = 0;
+ for (int i = 0; i < weights.length; i++)
+ sum += weights[i];
+ return sum;
+ }
+
+ private int[] getProgressWeights() {
+ int[] weights = new int[phases.length];
+ for (int i = 0; i < phases.length; i += 1) {
+ weights[i] = phases[i].weight;
+ }
+ return weights;
+ }
+} \ No newline at end of file
diff --git a/bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/prov/engine/Profile.java b/bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/prov/engine/Profile.java
new file mode 100644
index 000000000..1894f375d
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/prov/engine/Profile.java
@@ -0,0 +1,142 @@
+/*******************************************************************************
+ * Copyright (c) 2007 IBM Corporation and others. All rights reserved. This
+ * program and the accompanying materials are made available under the terms of
+ * the Eclipse Public License v1.0 which accompanies this distribution, and is
+ * available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors: IBM Corporation - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.equinox.prov.engine;
+
+import java.util.*;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.equinox.internal.prov.engine.EngineActivator;
+import org.eclipse.equinox.prov.core.helpers.ServiceHelper;
+import org.eclipse.equinox.prov.installregistry.IInstallRegistry;
+import org.eclipse.equinox.prov.installregistry.IProfileInstallRegistry;
+import org.eclipse.equinox.prov.metadata.IInstallableUnit;
+import org.eclipse.equinox.prov.metadata.RequiredCapability;
+import org.eclipse.equinox.prov.query.IQueryable;
+import org.eclipse.equinox.prov.query.QueryableArray;
+import org.eclipse.osgi.service.resolver.VersionRange;
+
+public class Profile implements IQueryable {
+
+ /**
+ * Profile property constant indicating the flavor for the profile.
+ */
+ public static String PROP_FLAVOR = "eclipse.prov.flavor"; //$NON-NLS-1$
+
+ /**
+ * Profile property constant indicating the install folder for the profile.
+ */
+ public static final String PROP_INSTALL_FOLDER = "eclipse.prov.installFolder"; //$NON-NLS-1$
+
+ /**
+ * Profile property constant indicating the installed language(s) for the profile.
+ */
+ public static final String PROP_NL = "eclipse.prov.nl"; //$NON-NLS-1$
+
+ /**
+ * Profile property constant for a string property indicating a user visible short
+ * textual description of this profile. May be empty or <code>null</code>, and
+ * generally will be for non-top level install contexts.
+ */
+ public static final String PROP_DESCRIPTION = "eclipse.prov.description"; //$NON-NLS-1$
+
+ /**
+ * Profile property constant for a string property indicating a user visible name of this profile.
+ * May be empty or <code>null</code>, and generally will be for non-top level
+ * install contexts.
+ */
+ public static final String PROP_NAME = "eclipse.prov.name"; //$NON-NLS-1$
+
+ /**
+ * Profile property constant indicating the list of environments
+ * (e.g., OS, WS, ...) in which a profile can operate. The value of the property
+ * is a comma-delimited string of key/value pairs.
+ */
+ public static final String PROP_ENVIRONMENTS = "eclipse.prov.environments"; //$NON-NLS-1$
+
+ /**
+ * Profile property constant for a boolean property indicating if the profiling
+ * is roaming. A roaming profile is one whose physical install location varies
+ * and is updated whenever it runs.
+ */
+ public static final String PROP_ROAMING = "eclipse.prov.roaming"; //$NON-NLS-1$
+
+ /**
+ * Profile property constant indicating the bundle pool cache location.
+ */
+ public static final String PROP_CACHE = "eclipse.prov.cache"; //$NON-NLS-1$
+
+ //Internal id of the profile
+ private String profileId;
+
+ private Profile parentProfile;
+
+ /**
+ * This storage is to be used by the touchpoints to store data. The data must be serializable
+ */
+ private Properties storage = new Properties();
+
+ public Profile(String profileId) {
+ if (profileId == null || profileId.length() == 0) {
+ throw new IllegalArgumentException("Profile id must be set.");
+ }
+ this.profileId = profileId;
+ }
+
+ public String getProfileId() {
+ return profileId;
+ }
+
+ public Profile getParentProfile() {
+ return parentProfile;
+ }
+
+ public String getValue(String key) {
+ return storage.getProperty(key);
+ }
+
+ public void setValue(String key, String value) {
+ storage.setProperty(key, value);
+ }
+
+ public Dictionary getSelectionContext() {
+ Properties result = new Properties(storage);
+ String environments = storage.getProperty(PROP_ENVIRONMENTS);
+ if (environments == null)
+ return result;
+ for (StringTokenizer tokenizer = new StringTokenizer(environments, ","); tokenizer.hasMoreElements();) {
+ String entry = tokenizer.nextToken();
+ int i = entry.indexOf('=');
+ String key = entry.substring(0, i).trim();
+ String value = entry.substring(i + 1).trim();
+ result.put(key, value);
+ }
+ return result;
+ }
+
+ private IInstallableUnit[] getAllInstallableUnits() {
+ IInstallRegistry registry = (IInstallRegistry) ServiceHelper.getService(EngineActivator.getContext(), IInstallRegistry.class.getName());
+ if (registry == null)
+ return null;
+ IProfileInstallRegistry profile = registry.getProfileInstallRegistry(new Profile(profileId));
+ if (profile == null)
+ return null;
+ return profile.getInstallableUnits();
+ }
+
+ public Iterator getIterator(String id, VersionRange range, RequiredCapability[] requirements, boolean and) {
+ return new QueryableArray(getAllInstallableUnits()).getIterator(id, range, requirements, and);
+ }
+
+ public IInstallableUnit[] query(String id, VersionRange range, RequiredCapability[] requirements, boolean and, IProgressMonitor progress) {
+ return new QueryableArray(getAllInstallableUnits()).query(id, range, requirements, and, progress);
+ }
+
+ public Iterator getInstallableUnits() {
+ return Arrays.asList(getAllInstallableUnits()).iterator();
+ }
+}
diff --git a/bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/prov/engine/ProfileEvent.java b/bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/prov/engine/ProfileEvent.java
new file mode 100644
index 000000000..cbb120e67
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/prov/engine/ProfileEvent.java
@@ -0,0 +1,36 @@
+/*******************************************************************************
+ * Copyright (c) 2007 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.equinox.prov.engine;
+
+import java.util.EventObject;
+
+public class ProfileEvent extends EventObject {
+ private static final long serialVersionUID = 3082402920617281765L;
+
+ public static byte ADDED = 0;
+ public static byte REMOVED = 1;
+
+ private byte reason;
+
+ public ProfileEvent(Profile source, byte reason) {
+ super(source);
+ this.reason = reason;
+ }
+
+ public byte getReason() {
+ return reason;
+ }
+
+ public Profile getProfile() {
+ return (Profile) getSource();
+ }
+
+}
diff --git a/bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/prov/engine/ProvisioningConfigurationException.java b/bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/prov/engine/ProvisioningConfigurationException.java
new file mode 100644
index 000000000..4c2496080
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/prov/engine/ProvisioningConfigurationException.java
@@ -0,0 +1,21 @@
+/*******************************************************************************
+ * Copyright (c) 2007 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.equinox.prov.engine;
+
+public class ProvisioningConfigurationException extends RuntimeException {
+
+ private static final long serialVersionUID = -712627437440533809L;
+
+ public ProvisioningConfigurationException(String name) {
+ super(name);
+ }
+
+}
diff --git a/bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/prov/engine/RollbackOperationEvent.java b/bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/prov/engine/RollbackOperationEvent.java
new file mode 100644
index 000000000..9de0d51c1
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/prov/engine/RollbackOperationEvent.java
@@ -0,0 +1,28 @@
+/*******************************************************************************
+ * Copyright (c) 2007 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.equinox.prov.engine;
+
+import org.eclipse.core.runtime.IStatus;
+
+public class RollbackOperationEvent extends TransactionEvent {
+
+ private static final long serialVersionUID = -2076492953949691215L;
+ private IStatus cause;
+
+ public RollbackOperationEvent(Profile profile, PhaseSet phaseSet, Operand[] deltas, Engine engine, IStatus cause) {
+ super(profile, phaseSet, deltas, engine);
+ this.cause = cause;
+ }
+
+ public IStatus getStatus() {
+ return cause;
+ }
+}
diff --git a/bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/prov/engine/SimpleProfileRegistry.java b/bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/prov/engine/SimpleProfileRegistry.java
new file mode 100644
index 000000000..ae4c4c622
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/prov/engine/SimpleProfileRegistry.java
@@ -0,0 +1,184 @@
+/*******************************************************************************
+ * Copyright (c) 2007 IBM Corporation and others. All rights reserved. This
+ * program and the accompanying materials are made available under the terms of
+ * the Eclipse Public License v1.0 which accompanies this distribution, and is
+ * available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors: IBM Corporation - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.equinox.prov.engine;
+
+import com.thoughtworks.xstream.XStream;
+import java.io.*;
+import java.net.URL;
+import java.util.LinkedHashMap;
+import java.util.Properties;
+import org.eclipse.equinox.internal.prov.engine.EngineActivator;
+import org.eclipse.equinox.internal.prov.engine.Messages;
+import org.eclipse.equinox.prov.core.eventbus.ProvisioningEventBus;
+import org.eclipse.equinox.prov.core.helpers.ServiceHelper;
+import org.eclipse.equinox.prov.core.location.AgentLocation;
+import org.eclipse.osgi.service.datalocation.Location;
+import org.eclipse.osgi.util.NLS;
+
+public class SimpleProfileRegistry implements IProfileRegistry {
+ private static String STORAGE = "profileRegistry.xml"; //$NON-NLS-1$
+
+ /**
+ * Map of String(Profile id)->Profile.
+ */
+ private LinkedHashMap profiles = new LinkedHashMap(8);
+
+ private Properties properties = new Properties();
+
+ private String self;
+
+ public SimpleProfileRegistry() {
+ self = EngineActivator.getContext().getProperty("eclipse.prov.profile"); //$NON-NLS-1$
+ restore();
+ updateRoamingProfile();
+ }
+
+ /**
+ * If the current profile for self is marked as a roaming profile, we need
+ * to update its install and bundle pool locations.
+ */
+ private void updateRoamingProfile() {
+ Profile selfProfile = getProfile(SELF);
+ if (selfProfile == null)
+ return;
+ //only update if self is a roaming profile
+ if (!Boolean.valueOf(selfProfile.getValue(Profile.PROP_ROAMING)).booleanValue())
+ return;
+ Location installLocation = (Location) ServiceHelper.getService(EngineActivator.getContext(), Location.class.getName(), Location.INSTALL_FILTER);
+ String locationString = installLocation.getURL().getPath();
+ boolean changed = false;
+ if (!locationString.equals(selfProfile.getValue(Profile.PROP_INSTALL_FOLDER))) {
+ selfProfile.setValue(Profile.PROP_INSTALL_FOLDER, locationString);
+ changed = true;
+ }
+ if (!locationString.equals(selfProfile.getValue(Profile.PROP_CACHE))) {
+ selfProfile.setValue(Profile.PROP_CACHE, locationString);
+ changed = true;
+ }
+ if (changed)
+ persist();
+ }
+
+ public String toString() {
+ return this.profiles.toString();
+ }
+
+ public Profile getProfile(String id) {
+ if (SELF.equals(id))
+ id = self;
+ return (Profile) profiles.get(id);
+ }
+
+ public Profile[] getProfiles() {
+ return (Profile[]) profiles.values().toArray(new Profile[profiles.size()]);
+ }
+
+ public void addProfile(Profile toAdd) throws IllegalArgumentException {
+ if (isNamedSelf(toAdd))
+ throw new IllegalArgumentException(NLS.bind(Messages.Profile_Not_Named_Self, toAdd.getProfileId()));
+ String id = toAdd.getProfileId();
+ if (getProfile(id) == null) {
+ profiles.put(id, toAdd);
+ } else
+ throw new IllegalArgumentException(NLS.bind(Messages.Profile_Duplicate_Profile_Id, id));
+ broadcastChangeEvent(toAdd, ProfileEvent.ADDED);
+ persist(); //TODO This is not enough to keep track of the changes that are being done in a profile. This will likely have to be based on some event like commit
+ }
+
+ private void broadcastChangeEvent(Profile profile, byte reason) {
+ ((ProvisioningEventBus) ServiceHelper.getService(EngineActivator.getContext(), ProvisioningEventBus.class.getName())).publishEvent(new ProfileEvent(profile, reason));
+ }
+
+ private void restore() {
+ try {
+ BufferedInputStream bif = null;
+ try {
+ Location agent = (Location) ServiceHelper.getService(EngineActivator.getContext(), AgentLocation.class.getName());
+ if (agent == null)
+ // TODO should likely do something here since we failed to restore.
+ return;
+ bif = new BufferedInputStream(new URL(agent.getURL(), STORAGE).openStream());
+ XStream xml = new XStream();
+ Object[] read = (Object[]) xml.fromXML(bif);
+ properties = (Properties) read[0];
+ profiles = (LinkedHashMap) read[1];
+ } finally {
+ if (bif != null)
+ bif.close();
+ }
+ } catch (FileNotFoundException e) {
+ //This is ok.
+ } catch (IOException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }
+
+ private void persist() {
+ OutputStream os;
+ try {
+ Location agent = (Location) ServiceHelper.getService(EngineActivator.getContext(), AgentLocation.class.getName());
+ if (agent == null)
+ // TODO should likely do something here since we failed to persist.
+ return;
+ if (!agent.getURL().getProtocol().equals("file"))
+ throw new IOException("can't write at the given location");
+
+ File outputFile = new File(agent.getURL().getFile(), STORAGE);
+ if (!outputFile.getParentFile().exists() && !outputFile.getParentFile().mkdirs())
+ throw new RuntimeException("can't persist profile registry at: " + outputFile);
+ os = new BufferedOutputStream(new FileOutputStream(outputFile));
+ try {
+ XStream xstream = new XStream();
+ xstream.toXML(new Object[] {properties, profiles}, os);
+ } finally {
+ os.close();
+ }
+ } catch (FileNotFoundException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ } catch (IOException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+
+ }
+
+ public void removeProfile(Profile toRemove) {
+ if (isNamedSelf(toRemove))
+ throw new IllegalArgumentException(NLS.bind(Messages.Profile_Not_Named_Self, toRemove.getProfileId()));
+ if (profiles.remove(toRemove.getProfileId()) == null)
+ return;
+ broadcastChangeEvent(toRemove, ProfileEvent.REMOVED);
+ persist();
+ }
+
+ private boolean isNamedSelf(Profile p) {
+ if (SELF.equals(p.getParentProfile()))
+ return true;
+ return false;
+ }
+
+ public Properties getProperties() {
+ return properties;
+ }
+
+ public String getProperty(String key) {
+ return properties.getProperty(key);
+ }
+
+ public void setProperty(String key, String value) {
+ properties.setProperty(key, value);
+ }
+
+ public void removeProperty(String key) {
+ properties.remove(key);
+ }
+
+}
diff --git a/bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/prov/engine/TransactionEvent.java b/bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/prov/engine/TransactionEvent.java
new file mode 100644
index 000000000..9249735a1
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/prov/engine/TransactionEvent.java
@@ -0,0 +1,30 @@
+/*******************************************************************************
+ * Copyright (c) 2007 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.equinox.prov.engine;
+
+import java.util.EventObject;
+
+public abstract class TransactionEvent extends EventObject {
+ protected Profile profile;
+ protected PhaseSet phaseSet;
+ protected Operand[] deltas;
+
+ public TransactionEvent(Profile profile, PhaseSet phaseSet, Operand[] deltas, Engine engine) {
+ super(engine);
+ this.profile = profile;
+ this.phaseSet = phaseSet;
+ this.deltas = deltas;
+ }
+
+ public Profile getProfile() {
+ return profile;
+ }
+} \ No newline at end of file
diff --git a/bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/prov/engine/Utils.java b/bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/prov/engine/Utils.java
new file mode 100644
index 000000000..949119d6b
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/prov/engine/Utils.java
@@ -0,0 +1,25 @@
+/*******************************************************************************
+ * Copyright (c) 2007 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.equinox.prov.engine;
+
+import org.eclipse.core.runtime.IAdaptable;
+
+public class Utils {
+
+ //This method will return the adapter, or will throw an exception
+ public static Object getAdapter(IAdaptable toAdapt, Class toAdaptType) throws ProvisioningConfigurationException {
+ Object result = toAdapt.getAdapter(toAdaptType);
+ if (result == null)
+ throw new ProvisioningConfigurationException("Adaptation failure. Can't adapt :" + toAdapt.getClass().getName() + " into a" + toAdaptType.getName());
+ return result;
+ }
+
+}
diff --git a/bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/prov/engine/phases/Collect.java b/bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/prov/engine/phases/Collect.java
new file mode 100644
index 000000000..e0cff6d83
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/prov/engine/phases/Collect.java
@@ -0,0 +1,76 @@
+/*******************************************************************************
+ * Copyright (c) 2007 IBM Corporation and others. All rights reserved. This
+ * program and the accompanying materials are made available under the terms of
+ * the Eclipse Public License v1.0 which accompanies this distribution, and is
+ * available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors: IBM Corporation - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.equinox.prov.engine.phases;
+
+import org.eclipse.core.runtime.*;
+import org.eclipse.equinox.internal.prov.engine.TouchpointManager;
+import org.eclipse.equinox.prov.artifact.repository.IArtifactRequest;
+import org.eclipse.equinox.prov.core.helpers.MultiStatus;
+import org.eclipse.equinox.prov.download.DownloadManager;
+import org.eclipse.equinox.prov.engine.*;
+import org.eclipse.equinox.prov.metadata.IInstallableUnit;
+import org.eclipse.osgi.util.NLS;
+
+/**
+ * The goal of the collect phase is to ask the touchpoints if the artifacts associated with an IU need to be downloaded.
+ */
+public class Collect extends IUPhase {
+ private static final String PHASE_ID = "collect"; //$NON-NLS-1$
+ private DownloadManager dm = null;
+
+ public Collect(int weight) {
+ super(PHASE_ID, weight, Messages.Engine_Collect_Phase);
+ //re-balance work since postPerform will do almost all the time-consuming work
+ PRE_PERFORM_WORK = 0;
+ PERFORM_WORK = 100;
+ POST_PERFORM_WORK = 1000;
+ }
+
+ protected IStatus performOperand(EngineSession session, Profile profile, Operand operand, IProgressMonitor monitor) {
+ IInstallableUnit unit = operand.second();
+
+ if (unit != null) {
+ monitor.subTask(NLS.bind(Messages.Engine_Collecting_For_IU, unit.getId()));
+
+ // TODO: Need do progress reporting
+
+ // Ask all the touchpoints if they need to download an artifact
+ ITouchpoint touchpoint = TouchpointManager.getInstance().getTouchpoint(unit.getTouchpointType());
+ if (touchpoint.supports(PHASE_ID)) {
+ ITouchpointAction[] actions = touchpoint.getActions(PHASE_ID, profile, operand);
+ for (int i = 0; i < actions.length; i++) {
+ Object result = actions[i].execute();
+ if (result != null)
+ dm.add((IArtifactRequest[]) result);
+ session.record(actions[i]);
+ }
+ }
+
+ if (monitor.isCanceled())
+ return Status.CANCEL_STATUS;
+ }
+
+ return Status.OK_STATUS;
+ }
+
+ protected void postPerform(MultiStatus status, Profile profile, Operand[] deltas, IProgressMonitor monitor) {
+ // Start the download
+ status.add(dm.start(monitor));
+ }
+
+ protected void prePerform(MultiStatus status, Profile profile, Operand[] deltas, IProgressMonitor monitor) {
+ dm = new DownloadManager();
+ }
+
+ protected boolean isApplicable(Operand op) {
+ if (op.second() != null)
+ return true;
+ return false;
+ }
+} \ No newline at end of file
diff --git a/bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/prov/engine/phases/Install.java b/bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/prov/engine/phases/Install.java
new file mode 100644
index 000000000..660d2f74e
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/prov/engine/phases/Install.java
@@ -0,0 +1,60 @@
+/*******************************************************************************
+ * Copyright (c) 2007 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.equinox.prov.engine.phases;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.equinox.internal.prov.engine.EngineActivator;
+import org.eclipse.equinox.internal.prov.engine.TouchpointManager;
+import org.eclipse.equinox.prov.core.eventbus.ProvisioningEventBus;
+import org.eclipse.equinox.prov.core.helpers.MultiStatus;
+import org.eclipse.equinox.prov.core.helpers.ServiceHelper;
+import org.eclipse.equinox.prov.engine.*;
+import org.eclipse.equinox.prov.metadata.IInstallableUnit;
+import org.eclipse.osgi.util.NLS;
+
+public class Install extends IUPhase {
+
+ private static final String PHASE_ID = "install"; //$NON-NLS-1$
+
+ public Install(int weight) {
+ super(PHASE_ID, weight, Messages.Engine_Install_Phase);
+ }
+
+ protected IStatus performOperand(EngineSession session, Profile profile, Operand operand, IProgressMonitor monitor) {
+ IInstallableUnit unit = operand.second();
+
+ monitor.subTask(NLS.bind(Messages.Engine_Installing_IU, unit.getId()));
+
+ ITouchpoint touchpoint = TouchpointManager.getInstance().getTouchpoint(unit.getTouchpointType());
+ if (!touchpoint.supports(PHASE_ID))
+ ((ProvisioningEventBus) ServiceHelper.getService(EngineActivator.getContext(), ProvisioningEventBus.class.getName())).publishEvent(new InstallableUnitEvent(PHASE_ID, true, profile, operand, touchpoint));
+
+ ITouchpointAction[] actions = touchpoint.getActions(PHASE_ID, profile, operand);
+ MultiStatus result = new MultiStatus();
+ for (int i = 0; i < actions.length; i++) {
+ IStatus actionStatus = (IStatus) actions[i].execute();
+ result.add(actionStatus);
+ if (!actionStatus.isOK())
+ return result;
+
+ session.record(actions[i]);
+ }
+ ((ProvisioningEventBus) ServiceHelper.getService(EngineActivator.getContext(), ProvisioningEventBus.class.getName())).publishEvent(new InstallableUnitEvent(PHASE_ID, false, profile, operand, touchpoint, result));
+ return result;
+ }
+
+ protected boolean isApplicable(Operand op) {
+ if (op.second() != null)
+ return true;
+ return false;
+ }
+} \ No newline at end of file
diff --git a/bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/prov/engine/phases/Messages.java b/bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/prov/engine/phases/Messages.java
new file mode 100644
index 000000000..f35b810e0
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/prov/engine/phases/Messages.java
@@ -0,0 +1,33 @@
+/*******************************************************************************
+ * Copyright (c) 2007 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.equinox.prov.engine.phases;
+
+import org.eclipse.osgi.util.NLS;
+
+public class Messages extends NLS {
+ private static final String BUNDLE_NAME = "org.eclipse.equinox.prov.engine.phases.messages"; //$NON-NLS-1$
+
+ static {
+ // initialize resource bundles
+ NLS.initializeMessages(BUNDLE_NAME, Messages.class);
+ }
+
+ private Messages() {
+ // Do not instantiate
+ }
+
+ public static String Engine_Collect_Phase;
+ public static String Engine_Collecting_For_IU;
+ public static String Engine_Install_Phase;
+ public static String Engine_Installing_IU;
+ public static String Engine_Uninstall_Phase;
+ public static String Engine_Uninstalling_IU;
+}
diff --git a/bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/prov/engine/phases/Uninstall.java b/bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/prov/engine/phases/Uninstall.java
new file mode 100644
index 000000000..0732680e1
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/prov/engine/phases/Uninstall.java
@@ -0,0 +1,58 @@
+/*******************************************************************************
+ * Copyright (c) 2007 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.equinox.prov.engine.phases;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.equinox.internal.prov.engine.EngineActivator;
+import org.eclipse.equinox.internal.prov.engine.TouchpointManager;
+import org.eclipse.equinox.prov.core.eventbus.ProvisioningEventBus;
+import org.eclipse.equinox.prov.core.helpers.MultiStatus;
+import org.eclipse.equinox.prov.core.helpers.ServiceHelper;
+import org.eclipse.equinox.prov.engine.*;
+import org.eclipse.equinox.prov.metadata.IInstallableUnit;
+import org.eclipse.osgi.util.NLS;
+
+public class Uninstall extends IUPhase {
+
+ private static final String PHASE_ID = "uninstall"; //$NON-NLS-1$
+
+ public Uninstall(int weight) {
+ super(PHASE_ID, weight, Messages.Engine_Uninstall_Phase);
+ }
+
+ protected IStatus performOperand(EngineSession session, Profile profile, Operand operand, IProgressMonitor monitor) {
+ IInstallableUnit unit = operand.first();
+
+ monitor.subTask(NLS.bind(Messages.Engine_Uninstalling_IU, unit.getId()));
+
+ ITouchpoint touchpoint = TouchpointManager.getInstance().getTouchpoint(unit.getTouchpointType());
+ if (touchpoint.supports(PHASE_ID))
+ ((ProvisioningEventBus) ServiceHelper.getService(EngineActivator.getContext(), ProvisioningEventBus.class.getName())).publishEvent(new InstallableUnitEvent(PHASE_ID, true, profile, operand, touchpoint));
+
+ //TODO need to protect the actual operation on a try / catch to ensure the delivery of event.
+ ITouchpointAction[] actions = touchpoint.getActions(PHASE_ID, profile, operand);
+ MultiStatus result = new MultiStatus();
+ for (int i = 0; i < actions.length; i++) {
+ result.add((IStatus) actions[i].execute());
+ session.record(actions[i]);
+ }
+
+ ((ProvisioningEventBus) ServiceHelper.getService(EngineActivator.getContext(), ProvisioningEventBus.class.getName())).publishEvent(new InstallableUnitEvent(PHASE_ID, false, profile, operand, touchpoint, result));
+ return result;
+ }
+
+ protected boolean isApplicable(Operand op) {
+ if (op.first() != null)
+ return true;
+ return false;
+ }
+} \ No newline at end of file
diff --git a/bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/prov/engine/phases/messages.properties b/bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/prov/engine/phases/messages.properties
new file mode 100644
index 000000000..9e644e32f
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/prov/engine/phases/messages.properties
@@ -0,0 +1,17 @@
+###############################################################################
+# Copyright (c) 2007 IBM Corporation and others.
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+#
+# Contributors:
+# IBM Corporation - initial API and implementation
+###############################################################################
+
+Engine_Collect_Phase=collect
+Engine_Install_Phase=install
+Engine_Uninstall_Phase=uninstall
+Engine_Collecting_For_IU=Collecting for {0}
+Engine_Installing_IU=Installing {0}
+Engine_Uninstalling_IU=Uninstalling {0} \ No newline at end of file
diff --git a/bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/prov/installregistry/IInstallRegistry.java b/bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/prov/installregistry/IInstallRegistry.java
new file mode 100644
index 000000000..3cbc8b8f5
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/prov/installregistry/IInstallRegistry.java
@@ -0,0 +1,171 @@
+/*******************************************************************************
+ * Copyright (c) 2007 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.equinox.prov.installregistry;
+
+import java.util.Collection;
+import org.eclipse.equinox.prov.engine.Profile;
+
+public interface IInstallRegistry {
+
+ /**
+ * Save the registry as XML. If exception is thrown, no change was made.
+ */
+ // public void saveXML() throws IOException {
+ // checkMetadata();
+ // File xmlFile = getLocation();
+ // plog.start(plog.debug("Saving {0}", xmlFile)); //$NON-NLS-1$
+ // if (isEmpty()) { // delete when empty
+ // xmlFile.delete();
+ // if (xmlFile.exists()) {
+ // throw new IOException(NLS.bind(Messages.InstallRegistry_Failed_To_Delete_Install_Registry, xmlFile));
+ // }
+ // } else {
+ // new FileUtil.SafeUpdate(xmlFile) {
+ // public void write(FileOutputStream stream) throws IOException {
+ // XMLWriter writer = new XMLWriter(stream, XML.getProcessingInstruction());
+ // XML.write(writer);
+ // writer.flush();
+ // stream.getFD().sync();
+ // writer.close();
+ // }
+ // }.write();
+ // }
+ // plog.stop();
+ // }
+ // private static class XML implements InstallRegistryXML {
+ // public static XMLWriter.ProcessingInstruction getProcessingInstruction() {
+ // return new XMLWriter.ProcessingInstruction(PI.INSTALL_REGISTRY, MetaInfo.formatVersion(MetaInfo.INSTALL_REGISTRY_VERSION));
+ // }
+ //
+ // public static void write(XMLWriter writer) {
+ // InstallRegistry ir = InstallRegistry.getInstance();
+ // writer.start(Elements.INSTALL_REGISTRY);
+ // writer.write(ir.profileRegistry.getProperties());
+ // for (Iterator i = ir.getProfileInstallRegistries().iterator(); i.hasNext();) {
+ // ProfileInstallRegistry registry = (ProfileInstallRegistry) i.next();
+ // if (!registry.isEmpty()) {
+ // writer.start(Elements.PROFILE);
+ // Profile profile = registry.getProfile();
+ // writer.attribute(Attrs.ID, profile.getProfileId());
+ // writer.attribute(Attrs.KIND, profile.getProfileKind());
+ // writer.writeProperty(Profile.INSTALL_LOCATION, profile.getInstallLocation());
+ // writer.write(profile.getAllData());
+ // InstallContext rootContext = profile.getRootContext();
+ // if (rootContext != null) {
+ // write(writer, rootContext);
+ // }
+ // registry.emitXML(writer);
+ // writer.end(Elements.PROFILE);
+ // }
+ // }
+ // writer.end(Elements.INSTALL_REGISTRY);
+ // }
+ //
+ // private static void write(XMLWriter writer, InstallContext installContext) {
+ // writer.start(Elements.INSTALL_CONTEXT);
+ // writer.attribute(Attrs.ID, installContext.getId());
+ // writer.attribute(Attrs.NAME, installContext.getName());
+ // writer.attribute(Attrs.DESCRIPTION, installContext.getDescription());
+ // writer.attribute(Attrs.SHAREABLE, installContext.isShareable(), true);
+ // writer.attribute(Attrs.QUALIFIABLE, installContext.isQualifiable(), false);
+ // InstallationContextScope scope = installContext.getScope();
+ // if (scope != InstallationContextScope.NONE_SCOPE) {
+ // writer.attribute(Attrs.SCOPE, scope.getName());
+ // }
+ // writer.write(installContext.getLocalProperties());
+ // String[] adapterTypes = installContext.getAdaptorTypes();
+ // for (int i = 0; i < adapterTypes.length; i += 1) {
+ // writer.start(Elements.ADAPTER);
+ // writer.attribute(Attrs.TYPE, adapterTypes[i]);
+ // writer.end();
+ // }
+ // InstallContext[] subcontexts = installContext.getSubcontexts();
+ // for (int i = 0; i < subcontexts.length; i += 1) {
+ // write(writer, subcontexts[i]);
+ // }
+ // writer.end(Elements.INSTALL_CONTEXT);
+ // }
+ // }
+ // /**
+ // * The file of the install registry.
+ // */
+ // public File getLocation() {
+ // return this.location;
+ // }
+ // // The location of the old install registry directory.
+ // // This is where the metadata is still stored.
+ // private File getLegacyLocation(String subdir) {
+ // String path = getLocation().getPath();
+ // if (path.endsWith(CommonDef.Extensions.Xml)) {
+ // path = path.substring(0, path.length() - CommonDef.Extensions.Xml.length());
+ // } else {
+ // path += ".dir"; //$NON-NLS-1$
+ // }
+ // return new File(path, subdir);
+ // }
+ public abstract IProfileInstallRegistry getProfileInstallRegistry(Profile profile);
+
+ /**
+ * Open the install registry. It must be open before any operations can be performed.
+ */
+ // public void open() throws IOException {
+ // // openFile(Agent.getInstance().getInstallRegistryLocation());
+ // }
+ //
+ // // This form is for AbstractAgentTestCase because the preferences aren't set correctly
+ // // when it needs the install registry.
+ // public void open(File dir) throws IOException {
+ // openFile(new File(dir, Agent.FILENAME_INSTALL_REGISTRY));
+ // }
+ //
+ // private void openFile(File file) throws IOException {
+ // if (isOpen()) {
+ // throw new InstallRegistryException(Messages2.InstallRegistry_Install_Registry_Is_Already_Open);
+ // }
+ // this.location = file;
+ // if (this.location.isDirectory()) {
+ // throw new InstallRegistryException(NLS.bind(Messages2.InstallRegistry_Install_Registry_Exists_And_Is_A_Directory, this.location));
+ // } else if (!this.location.exists()) {
+ // // verify we can write it
+ // this.location.getParentFile().mkdirs();
+ // new FileOutputStream(this.location).close();
+ // this.location.delete();
+ // }
+ //
+ // // TODO: move to cache
+ // File metadataDir = getLegacyLocation(METADATA_DIR);
+ // try {
+ // this.metadataRepo = StandardRepository.create(this.installedMetadata.getRepositoryGroup(), metadataDir);
+ // } catch (RuntimeException e) {
+ // // report error below
+ // }
+ // if (this.metadataRepo == null) {
+ // throw new InstallRegistryException(NLS.bind(Messages.InstallRegistry_Failed_To_Create_Install_Registry_Repo, metadataDir));
+ // }
+ // this.metadataRepo.setOpen(true);
+ // load();
+ // checkMetadata();
+ // }
+ //
+ // public void close() {
+ // this.installedMetadata.getRepositoryGroup().removeRepository(this.metadataRepo);
+ // this.metadataRepo = null;
+ // if (isEmpty()) {
+ // purge();
+ // }
+ // }
+ // public void purge() {
+ // getLocation().delete();
+ // FileUtil.rm_r(getLegacyLocation(""), /*removeRoot*/true); //$NON-NLS-1$
+ // }
+ public abstract Collection getProfileInstallRegistries();
+
+} \ No newline at end of file
diff --git a/bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/prov/installregistry/IProfileInstallRegistry.java b/bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/prov/installregistry/IProfileInstallRegistry.java
new file mode 100644
index 000000000..54f7b01fa
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/prov/installregistry/IProfileInstallRegistry.java
@@ -0,0 +1,27 @@
+/*******************************************************************************
+ * Copyright (c) 2007 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.equinox.prov.installregistry;
+
+import org.eclipse.equinox.prov.metadata.IInstallableUnit;
+
+public interface IProfileInstallRegistry {
+
+ public abstract IInstallableUnit[] getInstallableUnits();
+
+ public abstract IInstallableUnit getInstallableUnit(String id, String version);
+
+ public abstract void addInstallableUnits(IInstallableUnit toAdd);
+
+ public abstract void removeInstallableUnits(IInstallableUnit toRemove);
+
+ public abstract String getProfileId();
+
+} \ No newline at end of file
diff --git a/bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/prov/installregistry/InstallRegistry.java b/bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/prov/installregistry/InstallRegistry.java
new file mode 100644
index 000000000..2ca377a86
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.engine/src/org/eclipse/equinox/prov/installregistry/InstallRegistry.java
@@ -0,0 +1,181 @@
+/*******************************************************************************
+ * Copyright (c) 2007 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.equinox.prov.installregistry;
+
+import com.thoughtworks.xstream.XStream;
+import java.io.*;
+import java.net.URL;
+import java.util.*;
+import org.eclipse.equinox.internal.prov.engine.EngineActivator;
+import org.eclipse.equinox.prov.core.eventbus.ProvisioningEventBus;
+import org.eclipse.equinox.prov.core.eventbus.SynchronousProvisioningListener;
+import org.eclipse.equinox.prov.core.helpers.ServiceHelper;
+import org.eclipse.equinox.prov.core.location.AgentLocation;
+import org.eclipse.equinox.prov.engine.*;
+import org.eclipse.equinox.prov.metadata.IInstallableUnit;
+import org.eclipse.osgi.service.datalocation.Location;
+import org.osgi.framework.ServiceReference;
+import org.osgi.framework.Version;
+
+public class InstallRegistry implements IInstallRegistry {
+ private static String STORAGE = "installRegistry.xml";
+
+ // what is installed in each profile
+ private Map profileRegistries = new HashMap(); // Profile id -> ProfileInstallRegistry
+ // private ProfileRegistry profileRegistry; // the corresponding ProfileRegistry
+ // private File location; // xml file containing install registry
+ // private IRepository metadataRepo;
+ // private final MetadataCache installedMetadata = new MetadataCache(
+ // new RepositoryGroup("InstallRegistry"), //$NON-NLS-1$
+ // MetadataCache.POLICY_NONE);
+
+ private transient ServiceReference busReference;
+ private transient ProvisioningEventBus bus;
+
+ public InstallRegistry() {
+ busReference = EngineActivator.getContext().getServiceReference(ProvisioningEventBus.class.getName());
+ bus = (ProvisioningEventBus) EngineActivator.getContext().getService(busReference);
+ restore();
+ bus.addListener(new SynchronousProvisioningListener() {
+ public void notify(EventObject o) {
+ if (o instanceof InstallableUnitEvent) {
+ InstallableUnitEvent event = (InstallableUnitEvent) o;
+ if (event.isPre() || !event.getResult().isOK())
+ return;
+ IProfileInstallRegistry registry = getProfileInstallRegistry(event.getProfile());
+ if (event.getOperand().second() != null) {
+ registry.addInstallableUnits(event.getOperand().second().getOriginal());
+ }
+ if (event.getOperand().first() != null) {
+ registry.removeInstallableUnits(event.getOperand().first().getOriginal());
+ }
+ } else if (o instanceof CommitOperationEvent) {
+ persist();
+ return;
+ } else if (o instanceof RollbackOperationEvent) {
+ restore();
+ return;
+ } else if (o instanceof ProfileEvent) {
+ ProfileEvent pe = (ProfileEvent) o;
+ if (pe.getReason() == ProfileEvent.REMOVED) {
+ profileRegistries.remove(pe.getProfile().getProfileId());
+ persist();
+ }
+ }
+ }
+
+ });
+ }
+
+ private void persist() {
+ try {
+ BufferedOutputStream bof = null;
+ try {
+ Location agent = (Location) ServiceHelper.getService(EngineActivator.getContext(), AgentLocation.class.getName());
+ if (agent == null)
+ // TODO should likely do something here since we failed to persist.
+ return;
+ if (!agent.getURL().getProtocol().equals("file"))
+ throw new IOException("can't write at the given location");
+
+ File outputFile = new File(agent.getURL().getFile(), STORAGE);
+ if (!outputFile.getParentFile().exists() && !outputFile.getParentFile().mkdirs())
+ throw new RuntimeException("can't persist profile registry");
+ bof = new BufferedOutputStream(new FileOutputStream(outputFile, false));
+ new XStream().toXML(profileRegistries, bof);
+ } finally {
+ if (bof != null)
+ bof.close();
+ }
+ } catch (FileNotFoundException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ } catch (IOException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }
+
+ private void restore() {
+ try {
+ BufferedInputStream bif = null;
+ try {
+ Location agent = (Location) ServiceHelper.getService(EngineActivator.getContext(), AgentLocation.class.getName());
+ if (agent == null)
+ // TODO should likely do something here since we failed to restore.
+ return;
+ bif = new BufferedInputStream(new URL(agent.getURL(), STORAGE).openStream());
+ profileRegistries = (HashMap) new XStream().fromXML(bif);
+ } finally {
+ if (bif != null)
+ bif.close();
+ }
+ } catch (FileNotFoundException e) {
+ //This is ok.
+ } catch (IOException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }
+
+ public IProfileInstallRegistry getProfileInstallRegistry(Profile profile) {
+ String profileId = profile.getProfileId();
+ IProfileInstallRegistry result = (IProfileInstallRegistry) this.profileRegistries.get(profileId);
+ if (result == null) {
+ result = new ProfileInstallRegistry(profileId);
+ this.profileRegistries.put(profileId, result);
+ }
+ return result;
+ }
+
+ public Collection getProfileInstallRegistries() {
+ return this.profileRegistries.values();
+ }
+
+ /**
+ * Install registry for a single profile.
+ */
+ public class ProfileInstallRegistry implements IProfileInstallRegistry {
+ private String profileId; // id profile this data applies to
+ private Set installableUnits; //id
+
+ ProfileInstallRegistry(String profileId) {
+ this.profileId = profileId;
+ this.installableUnits = new HashSet();
+ }
+
+ public IInstallableUnit[] getInstallableUnits() {
+ IInstallableUnit[] result = new IInstallableUnit[installableUnits.size()];
+ return (IInstallableUnit[]) installableUnits.toArray(result);
+ }
+
+ public void addInstallableUnits(IInstallableUnit toAdd) {
+ installableUnits.add(toAdd);
+ }
+
+ public void removeInstallableUnits(IInstallableUnit toRemove) {
+ installableUnits.remove(toRemove);
+ }
+
+ public String getProfileId() {
+ return profileId;
+ }
+
+ public IInstallableUnit getInstallableUnit(String id, String version) {
+ for (Iterator i = installableUnits.iterator(); i.hasNext();) {
+ IInstallableUnit iu = (IInstallableUnit) i.next();
+ if (iu.getId().equals(id) && iu.getVersion().equals(new Version(version)))
+ return iu;
+ }
+ return null;
+ }
+ }
+}

Back to the top