Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'bundles/org.eclipse.equinox.p2.metadata')
-rw-r--r--bundles/org.eclipse.equinox.p2.metadata/.classpath7
-rw-r--r--bundles/org.eclipse.equinox.p2.metadata/.project28
-rw-r--r--bundles/org.eclipse.equinox.p2.metadata/.settings/org.eclipse.jdt.core.prefs331
-rw-r--r--bundles/org.eclipse.equinox.p2.metadata/.settings/org.eclipse.jdt.ui.prefs57
-rw-r--r--bundles/org.eclipse.equinox.p2.metadata/.settings/org.eclipse.pde.core.prefs4
-rw-r--r--bundles/org.eclipse.equinox.p2.metadata/META-INF/MANIFEST.MF19
-rw-r--r--bundles/org.eclipse.equinox.p2.metadata/about.html28
-rw-r--r--bundles/org.eclipse.equinox.p2.metadata/build.properties15
-rw-r--r--bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/internal/prov/metadata/ArtifactKey.java84
-rw-r--r--bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/internal/prov/metadata/InternalInstallableUnit.java16
-rw-r--r--bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/internal/prov/metadata/Messages.java26
-rw-r--r--bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/internal/prov/metadata/MetadataActivator.java32
-rw-r--r--bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/internal/prov/metadata/messages.properties14
-rw-r--r--bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/metadata/ConstrainableElement.java14
-rw-r--r--bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/metadata/IArtifactKey.java54
-rw-r--r--bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/metadata/IInstallableUnit.java72
-rw-r--r--bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/metadata/IInstallableUnitConstants.java36
-rw-r--r--bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/metadata/IInstallableUnitFragment.java19
-rw-r--r--bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/metadata/IMetadataVisitor.java20
-rw-r--r--bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/metadata/IResolvedInstallableUnit.java16
-rw-r--r--bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/metadata/IResolvedInstallableUnitFragment.java13
-rw-r--r--bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/metadata/Inclusion.java21
-rw-r--r--bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/metadata/InstallableUnit.java217
-rw-r--r--bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/metadata/InstallableUnitFragment.java67
-rw-r--r--bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/metadata/ProvidedCapability.java73
-rw-r--r--bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/metadata/Recommendation.java125
-rw-r--r--bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/metadata/RecommendationDescriptor.java116
-rw-r--r--bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/metadata/RequiredCapability.java158
-rw-r--r--bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/metadata/ResolvedInstallableUnit.java148
-rw-r--r--bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/metadata/ResolvedInstallableUnitFragment.java26
-rw-r--r--bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/metadata/Selector.java44
-rw-r--r--bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/metadata/TouchpointData.java55
-rw-r--r--bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/metadata/TouchpointType.java78
-rw-r--r--bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/query/CompoundIterator.java98
-rw-r--r--bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/query/IQueryable.java25
-rw-r--r--bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/query/Query.java73
-rw-r--r--bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/query/QueryableArray.java47
-rw-r--r--bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/resolution/ResolutionHelper.java171
-rw-r--r--bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/resolution/StateMetadataMap.java34
-rw-r--r--bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/resolution/Transformer.java141
-rw-r--r--bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/resolution/UnsatisfiedCapability.java56
41 files changed, 2678 insertions, 0 deletions
diff --git a/bundles/org.eclipse.equinox.p2.metadata/.classpath b/bundles/org.eclipse.equinox.p2.metadata/.classpath
new file mode 100644
index 000000000..7cdeb7319
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.metadata/.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.metadata/.project b/bundles/org.eclipse.equinox.p2.metadata/.project
new file mode 100644
index 000000000..bd63dce6d
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.metadata/.project
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>org.eclipse.equinox.prov.metadata</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.metadata/.settings/org.eclipse.jdt.core.prefs b/bundles/org.eclipse.equinox.p2.metadata/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 000000000..78523cd05
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.metadata/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,331 @@
+#Thu Aug 16 11:00:59 EDT 2007
+eclipse.preferences.version=1
+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_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_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.metadata/.settings/org.eclipse.jdt.ui.prefs b/bundles/org.eclipse.equinox.p2.metadata/.settings/org.eclipse.jdt.ui.prefs
new file mode 100644
index 000000000..f3f395b81
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.metadata/.settings/org.eclipse.jdt.ui.prefs
@@ -0,0 +1,57 @@
+#Sun Sep 23 11:58:15 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.metadata/.settings/org.eclipse.pde.core.prefs b/bundles/org.eclipse.equinox.p2.metadata/.settings/org.eclipse.pde.core.prefs
new file mode 100644
index 000000000..7913d20db
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.metadata/.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.metadata/META-INF/MANIFEST.MF b/bundles/org.eclipse.equinox.p2.metadata/META-INF/MANIFEST.MF
new file mode 100644
index 000000000..be3a5230d
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.metadata/META-INF/MANIFEST.MF
@@ -0,0 +1,19 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: Metadata Plug-in (Incubation)
+Bundle-SymbolicName: org.eclipse.equinox.prov.metadata
+Bundle-Version: 0.1.0.qualifier
+Export-Package: org.eclipse.equinox.internal.prov.metadata;x-friends:="org.eclipse.equinox.prov.metadata.generator",
+ org.eclipse.equinox.prov.metadata,
+ org.eclipse.equinox.prov.query,
+ org.eclipse.equinox.prov.resolution
+Import-Package: org.eclipse.osgi.service.resolver;version="1.1.0",
+ org.eclipse.osgi.util;version="1.1.0",
+ org.osgi.framework;version="1.3.0"
+Bundle-Activator: org.eclipse.equinox.internal.prov.metadata.MetadataActivator
+Eclipse-LazyStart: true
+Bundle-RequiredExecutionEnvironment: CDC-1.1/Foundation-1.1,
+ J2SE-1.4
+Require-Bundle: org.eclipse.equinox.common,
+ com.thoughtworks.xstream,
+ org.eclipse.equinox.prov.core
diff --git a/bundles/org.eclipse.equinox.p2.metadata/about.html b/bundles/org.eclipse.equinox.p2.metadata/about.html
new file mode 100644
index 000000000..460233046
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.metadata/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.metadata/build.properties b/bundles/org.eclipse.equinox.p2.metadata/build.properties
new file mode 100644
index 000000000..475da1dec
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.metadata/build.properties
@@ -0,0 +1,15 @@
+###############################################################################
+# 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/,\
+ .,\
+ about.html
diff --git a/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/internal/prov/metadata/ArtifactKey.java b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/internal/prov/metadata/ArtifactKey.java
new file mode 100644
index 000000000..71546915b
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/internal/prov/metadata/ArtifactKey.java
@@ -0,0 +1,84 @@
+/*******************************************************************************
+ * 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.metadata;
+
+import org.eclipse.equinox.prov.metadata.IArtifactKey;
+import org.osgi.framework.Version;
+
+/**
+ * The concrete type for representing IArtifactKey's.
+ * <p>
+ * See {link IArtifact for a description of the lifecycle of artifact keys)
+ */
+public class ArtifactKey implements IArtifactKey {
+
+ static final int NO_SEGMENTS = 5;
+ private static final char SEP_CHAR = ',';
+
+ private String namespace;
+ private String id;
+ private String classifier;
+ private transient Version versionObject;
+ private String version;
+
+ public ArtifactKey(String namespace, String classifier, String id, Version aVersion) {
+ super();
+ if (namespace.indexOf(SEP_CHAR) != -1)
+ throw new IllegalArgumentException("comma not allowed in namespace"); //$NON-NLS-1$
+ if (classifier.indexOf(SEP_CHAR) != -1)
+ throw new IllegalArgumentException("comma not allowed in classifier"); //$NON-NLS-1$
+ if (id.indexOf(SEP_CHAR) != -1)
+ throw new IllegalArgumentException("comma not allowed in id"); //$NON-NLS-1$
+ this.namespace = namespace;
+ this.classifier = classifier;
+ this.id = id;
+ this.versionObject = aVersion;
+ this.version = aVersion == null ? null : aVersion.toString();
+ }
+
+ public String getNamespace() {
+ return namespace;
+ }
+
+ public String getClassifier() {
+ return classifier;
+ }
+
+ public Version getVersion() {
+ if (versionObject == null)
+ versionObject = version == null ? Version.emptyVersion : new Version(version);
+ return versionObject;
+ }
+
+ public int hashCode() {
+ int hash = id.hashCode();
+ hash = 17 * hash + getVersion().hashCode();
+ hash = 17 * hash + namespace.hashCode();
+ hash = 17 * hash + classifier.hashCode();
+ return hash;
+ }
+
+ public String toString() {
+ return "ArtifactKey=" + id + '/' + namespace + '/' + classifier + '/' + getVersion(); //$NON-NLS-1$
+ }
+
+ public boolean equals(Object obj) {
+ if (!(obj instanceof ArtifactKey))
+ return false;
+ ArtifactKey ak = (ArtifactKey) obj;
+ return ak.id.equals(id) && ak.getVersion().equals(getVersion()) && ak.namespace.equals(namespace) && ak.classifier.equals(classifier);
+ }
+
+ public String getId() {
+ return id;
+ }
+
+}
diff --git a/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/internal/prov/metadata/InternalInstallableUnit.java b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/internal/prov/metadata/InternalInstallableUnit.java
new file mode 100644
index 000000000..6ab875e14
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/internal/prov/metadata/InternalInstallableUnit.java
@@ -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
+ ******************************************************************************/
+package org.eclipse.equinox.internal.prov.metadata;
+
+import org.eclipse.equinox.prov.metadata.IInstallableUnit;
+import org.eclipse.equinox.prov.metadata.IResolvedInstallableUnit;
+
+public interface InternalInstallableUnit extends IInstallableUnit {
+ public IResolvedInstallableUnit getResolved();
+}
diff --git a/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/internal/prov/metadata/Messages.java b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/internal/prov/metadata/Messages.java
new file mode 100644
index 000000000..00c7aef16
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/internal/prov/metadata/Messages.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.internal.prov.metadata;
+
+import org.eclipse.osgi.util.NLS;
+
+public class Messages extends NLS {
+
+ private static final String BUNDLE_NAME = "org.eclipse.equinox.internal.prov.metadata.messages"; //$NON-NLS-1$
+
+ static {
+ // load message values from bundle file and assign to fields below
+ NLS.initializeMessages(BUNDLE_NAME, Messages.class);
+ }
+
+ public static String QUERY_PROGRESS;
+
+}
diff --git a/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/internal/prov/metadata/MetadataActivator.java b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/internal/prov/metadata/MetadataActivator.java
new file mode 100644
index 000000000..9e717f490
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/internal/prov/metadata/MetadataActivator.java
@@ -0,0 +1,32 @@
+/*******************************************************************************
+ * 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.metadata;
+
+import org.osgi.framework.BundleActivator;
+import org.osgi.framework.BundleContext;
+
+public class MetadataActivator implements BundleActivator {
+ public static final String PI_METADATA = "org.eclipse.equinox.prov.metadata"; //$NON-NLS-1$
+ public static BundleContext context;
+
+ public static BundleContext getContext() {
+ return context;
+ }
+
+ public void start(BundleContext context) throws Exception {
+ MetadataActivator.context = context;
+ }
+
+ public void stop(BundleContext context) throws Exception {
+ MetadataActivator.context = null;
+ }
+
+}
diff --git a/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/internal/prov/metadata/messages.properties b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/internal/prov/metadata/messages.properties
new file mode 100644
index 000000000..138d56215
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/internal/prov/metadata/messages.properties
@@ -0,0 +1,14 @@
+###############################################################################
+# 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
+###############################################################################
+
+QUERY_PROGRESS=Executing query.
+
+
diff --git a/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/metadata/ConstrainableElement.java b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/metadata/ConstrainableElement.java
new file mode 100644
index 000000000..a45c91031
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/metadata/ConstrainableElement.java
@@ -0,0 +1,14 @@
+/*******************************************************************************
+ * 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.metadata;
+
+public class ConstrainableElement {
+}
diff --git a/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/metadata/IArtifactKey.java b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/metadata/IArtifactKey.java
new file mode 100644
index 000000000..3f45b9f9c
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/metadata/IArtifactKey.java
@@ -0,0 +1,54 @@
+/*******************************************************************************
+ * 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.metadata;
+
+import org.osgi.framework.Version;
+
+/**
+ * Provide standardized artifact information to uniquely identify the
+ * corresponding bytes (perhaps not stored as a file).
+ * <p>
+ * Artifact keys represent both a unique opaque identifier as well as structured
+ * and standardized pieces of information.
+ */
+
+public interface IArtifactKey {
+
+ /**
+ * The namespace.
+ * @return This returns the namespace segment of the artifact. Never
+ * null or empty.
+ */
+ String getNamespace();
+
+ /**
+ * The classifier.
+ * @return This returns the classifier segment of the key. Never
+ * null. Can be empty.
+ */
+ String getClassifier();
+
+ /**
+ * The identity of the artifact.
+ * @return This returns the id segment of the artifact. Can
+ * be empty.
+ *
+ * TODO: consider renaming this to getIdentity.
+ */
+ String getId();
+
+ /**
+ * The version of the artifact.
+ * @return This returns the version of the artifact. Never null. Can
+ * be empty (Version.emptyVersion).
+ */
+ Version getVersion();
+}
diff --git a/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/metadata/IInstallableUnit.java b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/metadata/IInstallableUnit.java
new file mode 100644
index 000000000..399747f34
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/metadata/IInstallableUnit.java
@@ -0,0 +1,72 @@
+/*******************************************************************************
+ * 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.metadata;
+
+import org.osgi.framework.Version;
+
+public interface IInstallableUnit extends Comparable {
+
+ /**
+ * A capability namespace representing a particular kind of installable unit.
+ * For example, an InstallableUnit may specify that it provides the "group" kind
+ * capability to express that it represents a group of instalable units.
+ */
+ public static final String IU_KIND_NAMESPACE = "org.eclipse.equinox.prov.type"; //$NON-NLS-1$
+ /**
+ * A capability namespace representing a particular InstallableUnit by name.
+ * Each InstallableUnit automatically provides an instance of this namespace representing
+ * itself, and other InstallableUnits can require such a capability to state that they
+ * require a particular InstallableUnit to be present.
+ */
+ public static final String IU_NAMESPACE = "org.eclipse.equinox.prov.iunamespace"; //$NON-NLS-1$
+ /**
+ * A capability namespace representing a particular profile flavor.
+ */
+ public static final String FLAVOR_NAMESPACE = "flavor"; //$NON-NLS-1$
+ //These two constants needs to be moved somewhere more appropriate...
+ public static final String CAPABILITY_ECLIPSE_TYPES = "org.eclipse.equinox.prov.eclipsetouchpoint.types"; //$NON-NLS-1$
+ public static final String CAPABILITY_ECLIPSE_BUNDLE = "bundle"; //$NON-NLS-1$
+
+ public abstract TouchpointType getTouchpointType();
+
+ public abstract String getId();
+
+ /**
+ * Returns the filter on this installable unit. The filter is matched against
+ * the selection context of the profile the unit is installed into. An IU will not
+ * be installed if it has a filter condition that is not satisfied by the context.
+ *
+ * See Profile#getSelectionContext.
+ */
+ public abstract String getFilter();
+
+ public abstract Version getVersion();
+
+ public abstract IArtifactKey[] getArtifacts();
+
+ public abstract RequiredCapability[] getRequiredCapabilities();
+
+ // public ProvidedCapability[] getProvidedCapabilities() {
+ // return providedCapabilities;
+ // }
+ //
+ public abstract ProvidedCapability[] getProvidedCapabilities();
+
+ public abstract boolean isSingleton();
+
+ public abstract String getProperty(String key);
+
+ public abstract TouchpointData[] getTouchpointData();
+
+ public abstract boolean isFragment();
+
+ public abstract String getApplicabilityFilter();
+
+ public abstract void accept(IMetadataVisitor visitor);
+} \ No newline at end of file
diff --git a/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/metadata/IInstallableUnitConstants.java b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/metadata/IInstallableUnitConstants.java
new file mode 100644
index 000000000..36c73a0b8
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/metadata/IInstallableUnitConstants.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.metadata;
+
+/**
+ * Definitions for constants associated with InstallableUnits.
+ */
+public interface IInstallableUnitConstants {
+
+ /*
+ * Keys for common properties that optionally
+ * be defined in InstallableUnits.
+ */
+ public String NAME = "equinox.prov.name"; //$NON-NLS-1$
+ public String DESCRIPTION = "equinox.prov.description"; //$NON-NLS-1$
+ public String DOC_URL = "equinox.prov.doc.url"; //$NON-NLS-1$
+ public String PROVIDER = "equinox.prov.provider"; //$NON-NLS-1$
+ public String CONTACT = "equinox.prov.contact"; //$NON-NLS-1$
+ public String LICENSE = "equinox.prov.license"; //$NON-NLS-1$
+ public String COPYRIGHT = "equinox.prov.copyright"; //$NON-NLS-1$
+ public String UPDATE_SITE = "equinox.prov.update.site"; //$NON-NLS-1$
+ public String UPDATE_FROM = "equinox.prov.update.from"; //$NON-NLS-1$
+ public String UPDATE_RANGE = "equinox.prov.update.range"; //$NON-NLS-1$
+
+ //TODO This is not the ideal location for these constants
+ public String ENTRYPOINT_IU_KEY = "entryPoint"; //$NON-NLS-1$
+ public static final String PROFILE_IU_KEY = "profileIU"; //$NON-NLS-1$
+
+}
diff --git a/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/metadata/IInstallableUnitFragment.java b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/metadata/IInstallableUnitFragment.java
new file mode 100644
index 000000000..5f11ed83b
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/metadata/IInstallableUnitFragment.java
@@ -0,0 +1,19 @@
+/*******************************************************************************
+ * 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.metadata;
+
+import org.eclipse.osgi.service.resolver.VersionRange;
+
+public interface IInstallableUnitFragment extends IInstallableUnit {
+
+ public abstract String getHostId();
+
+ public abstract VersionRange getHostVersionRange();
+
+} \ No newline at end of file
diff --git a/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/metadata/IMetadataVisitor.java b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/metadata/IMetadataVisitor.java
new file mode 100644
index 000000000..737afd742
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/metadata/IMetadataVisitor.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.metadata;
+
+public interface IMetadataVisitor {
+ public void visitInstallableUnit(IInstallableUnit iu);
+
+ public void visitCapability(ProvidedCapability capability);
+
+ public void visitRequiredCapability(RequiredCapability capability);
+
+}
diff --git a/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/metadata/IResolvedInstallableUnit.java b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/metadata/IResolvedInstallableUnit.java
new file mode 100644
index 000000000..e73ad5565
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/metadata/IResolvedInstallableUnit.java
@@ -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
+ ******************************************************************************/
+package org.eclipse.equinox.prov.metadata;
+
+public interface IResolvedInstallableUnit extends IInstallableUnit {
+
+ public abstract IInstallableUnitFragment[] getFragments();
+
+ public abstract IInstallableUnit getOriginal();
+} \ No newline at end of file
diff --git a/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/metadata/IResolvedInstallableUnitFragment.java b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/metadata/IResolvedInstallableUnitFragment.java
new file mode 100644
index 000000000..eb1b34e6a
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/metadata/IResolvedInstallableUnitFragment.java
@@ -0,0 +1,13 @@
+/*******************************************************************************
+ * 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.metadata;
+
+public interface IResolvedInstallableUnitFragment extends IInstallableUnitFragment, IResolvedInstallableUnit {
+
+}
diff --git a/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/metadata/Inclusion.java b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/metadata/Inclusion.java
new file mode 100644
index 000000000..7ba050b2d
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/metadata/Inclusion.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.metadata;
+
+public abstract class Inclusion {
+ String selectorId;
+
+ public String getSelectorId() {
+ return selectorId;
+ }
+
+ public abstract void accept(IMetadataVisitor visitor);
+}
diff --git a/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/metadata/InstallableUnit.java b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/metadata/InstallableUnit.java
new file mode 100644
index 000000000..000911032
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/metadata/InstallableUnit.java
@@ -0,0 +1,217 @@
+/*******************************************************************************
+ * 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.metadata;
+
+import org.eclipse.equinox.internal.prov.metadata.InternalInstallableUnit;
+import org.eclipse.equinox.prov.core.helpers.OrderedProperties;
+import org.eclipse.equinox.prov.core.helpers.UnmodifiableProperties;
+import org.osgi.framework.Version;
+
+public class InstallableUnit implements IInstallableUnitConstants, IInstallableUnit, InternalInstallableUnit {
+ private static final RequiredCapability[] NO_REQUIRES = new RequiredCapability[0];
+ private static final OrderedProperties NO_PROPERTIES = new OrderedProperties();
+
+ private String id;
+ private transient Version versionObject;
+ private String version;
+ private boolean singleton;
+
+ private OrderedProperties properties;
+
+ private IArtifactKey[] artifacts;
+ private TouchpointType touchpointType;
+ private TouchpointData immutableTouchpointData;
+
+ private RequiredCapability[] requires;
+
+ private String filter;
+
+ String applicabilityFilter;
+
+ ProvidedCapability[] providedCapabilities = new ProvidedCapability[0];
+
+ public InstallableUnit() {
+ super();
+ }
+
+ public TouchpointType getTouchpointType() {
+ return touchpointType == null ? TouchpointType.NONE : touchpointType;
+ }
+
+ public String getId() {
+ return id;
+ }
+
+ public String getFilter() {
+ return filter;
+ }
+
+ public Version getVersion() {
+ if (versionObject == null)
+ versionObject = version == null ? Version.emptyVersion : new Version(version);
+ return versionObject;
+ }
+
+ public IArtifactKey[] getArtifacts() {
+ return artifacts;
+ }
+
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ public void setVersion(Version newVersion) {
+ this.versionObject = newVersion;
+ this.version = newVersion == null ? null : newVersion.toString();
+ }
+
+ public void setTouchpointType(TouchpointType type) {
+ this.touchpointType = type == TouchpointType.NONE ? null : type;
+ }
+
+ public void setArtifacts(IArtifactKey[] value) {
+ artifacts = value;
+ }
+
+ public RequiredCapability[] getRequiredCapabilities() {
+ return requires != null ? requires : NO_REQUIRES;
+
+ }
+
+ public ProvidedCapability[] getProvidedCapabilities() {
+ ProvidedCapability self = new ProvidedCapability(IU_NAMESPACE, id, getVersion());
+ if (providedCapabilities == null)
+ return new ProvidedCapability[] {self};
+
+ ProvidedCapability[] result = new ProvidedCapability[providedCapabilities.length + 1];
+ result[0] = self;
+ System.arraycopy(providedCapabilities, 0, result, 1, providedCapabilities.length);
+ return result;
+ }
+
+ public void setRequiredCapabilities(RequiredCapability[] capabilities) {
+ if (capabilities == NO_REQUIRES) {
+ this.requires = null;
+ } else {
+ //copy array for safety
+ this.requires = (RequiredCapability[]) capabilities.clone();
+ }
+ }
+
+ public void accept(IMetadataVisitor visitor) {
+ visitor.visitInstallableUnit(this);
+ }
+
+ public boolean isSingleton() {
+ return singleton;
+ }
+
+ public void setSingleton(boolean singleton) {
+ this.singleton = singleton;
+ }
+
+ public String getProperty(String key) {
+ return getProperties().getProperty(key);
+ }
+
+ public String setProperty(String key, String value) {
+ if (properties == null)
+ properties = new OrderedProperties();
+ return (String) properties.setProperty(key, value);
+ }
+
+ public String toString() {
+ return id + ' ' + getVersion();
+ }
+
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + ((id == null) ? 0 : id.hashCode());
+ result = prime * result + ((getVersion() == null) ? 0 : getVersion().hashCode());
+ return result;
+ }
+
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (!(obj instanceof IInstallableUnit))
+ return false;
+ final IInstallableUnit other = (IInstallableUnit) obj;
+ if (id == null) {
+ if (other.getId() != null)
+ return false;
+ } else if (!id.equals(other.getId()))
+ return false;
+ if (getVersion() == null) {
+ if (other.getVersion() != null)
+ return false;
+ } else if (!getVersion().equals(other.getVersion()))
+ return false;
+ return true;
+ }
+
+ public void setFilter(String filter) {
+ this.filter = filter;
+ }
+
+ public TouchpointData[] getTouchpointData() {
+ return immutableTouchpointData == null ? TouchpointData.NO_TOUCHPOINT_DATA : new TouchpointData[] {immutableTouchpointData};
+ }
+
+ public void setImmutableTouchpointData(TouchpointData immutableData) {
+ this.immutableTouchpointData = immutableData;
+ }
+
+ OrderedProperties getProperties() {
+ return properties == null ? NO_PROPERTIES : properties;
+ }
+
+ /**
+ * Get an <i>unmodifiable copy</i> of the properties
+ * associated with the installable unit.
+ *
+ * @return an <i>unmodifiable copy</i> of the IU properties.
+ */
+ public OrderedProperties copyProperties() {
+ return (properties != null ? new UnmodifiableProperties(getProperties()) : new UnmodifiableProperties(new OrderedProperties()));
+ }
+
+ public boolean isFragment() {
+ return false;
+ }
+
+ public void setCapabilities(ProvidedCapability[] exportedCapabilities) {
+ providedCapabilities = exportedCapabilities;
+ }
+
+ public void setApplicabilityFilter(String ldapFilter) {
+ applicabilityFilter = ldapFilter;
+ }
+
+ public String getApplicabilityFilter() {
+ return applicabilityFilter;
+ }
+
+ public IResolvedInstallableUnit getResolved() {
+ return new ResolvedInstallableUnit(this);
+ }
+
+ public int compareTo(Object toCompareTo) {
+ if (!(toCompareTo instanceof IInstallableUnit)) {
+ return -1;
+ }
+ IInstallableUnit other = (IInstallableUnit) toCompareTo;
+ if (getId().compareTo(other.getId()) == 0)
+ return (getVersion().compareTo(other.getVersion()));
+ return getId().compareTo(other.getId());
+ }
+}
diff --git a/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/metadata/InstallableUnitFragment.java b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/metadata/InstallableUnitFragment.java
new file mode 100644
index 000000000..74180a9c8
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/metadata/InstallableUnitFragment.java
@@ -0,0 +1,67 @@
+/*******************************************************************************
+ * 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.metadata;
+
+import org.eclipse.osgi.service.resolver.VersionRange;
+import org.osgi.framework.Version;
+
+public class InstallableUnitFragment extends InstallableUnit implements IInstallableUnitFragment, IInstallableUnit {
+ public static ProvidedCapability FRAGMENT_CAPABILITY = new ProvidedCapability(IU_KIND_NAMESPACE, "iu.fragment", new Version(1, 0, 0));
+
+ private String hostId;
+ private transient VersionRange hostRangeObject;
+ private String hostRange;
+
+ public ProvidedCapability[] getProvidedCapabilities() {
+ ProvidedCapability[] otherCapabilities = super.getProvidedCapabilities();
+ if (otherCapabilities.length == 0)
+ return new ProvidedCapability[] {FRAGMENT_CAPABILITY};
+ ProvidedCapability[] result = new ProvidedCapability[otherCapabilities.length + 1];
+ System.arraycopy(otherCapabilities, 0, result, 1, otherCapabilities.length);
+ result[0] = FRAGMENT_CAPABILITY;
+ return result;
+ }
+
+ public void setHost(String iuId, VersionRange versionRange) {
+ if (iuId == null || versionRange == null)
+ throw new IllegalArgumentException();
+ hostId = iuId;
+ hostRangeObject = versionRange;
+ hostRange = versionRange == null ? null : versionRange.toString();
+ addRequiredCapability(RequiredCapability.createRequiredCapabilityForName(iuId, versionRange, false));
+ }
+
+ public String getHostId() {
+ return hostId;
+ }
+
+ public VersionRange getHostVersionRange() {
+ if (hostRangeObject == null)
+ hostRangeObject = hostRange == null ? VersionRange.emptyRange : new VersionRange(hostRange);
+ return hostRangeObject;
+ }
+
+ private void addRequiredCapability(RequiredCapability toAdd) {
+ RequiredCapability[] current = super.getRequiredCapabilities();
+ RequiredCapability[] result = new RequiredCapability[current.length + 1];
+ System.arraycopy(current, 0, result, 0, current.length);
+ result[current.length] = toAdd;
+ setRequiredCapabilities(result);
+ }
+
+ public boolean isFragment() {
+ return true;
+ }
+
+ public IResolvedInstallableUnit getResolved() {
+ return new ResolvedInstallableUnitFragment(this);
+ }
+}
diff --git a/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/metadata/ProvidedCapability.java b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/metadata/ProvidedCapability.java
new file mode 100644
index 000000000..ffe074ded
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/metadata/ProvidedCapability.java
@@ -0,0 +1,73 @@
+/*******************************************************************************
+ * 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.metadata;
+
+import org.osgi.framework.Version;
+
+/**
+ * Describes a capability as exposed or required by an installable unit
+ */
+public class ProvidedCapability {
+ String namespace;
+ String name;
+ transient Version versionObject;
+ String version;
+
+ public String getNamespace() {
+ return namespace;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public Version getVersion() {
+ if (versionObject == null)
+ versionObject = version == null ? Version.emptyVersion : new Version(version);
+ return versionObject;
+ }
+
+ public ProvidedCapability(String namespace, String name, Version newVersion) {
+ this.name = name;
+ this.versionObject = newVersion;
+ this.version = newVersion == null ? null : newVersion.toString();
+ this.namespace = namespace;
+ }
+
+ public boolean isSatisfiedBy(RequiredCapability candidate) {
+ if (getName() == null || !getName().equals(candidate.getName()))
+ return false;
+ if (getNamespace() == null || !getNamespace().equals(candidate.getNamespace()))
+ return false;
+ return candidate.getRange().isIncluded(getVersion());
+ }
+
+ public void accept(IMetadataVisitor visitor) {
+ visitor.visitCapability(this);
+ }
+
+ public boolean equals(Object other) {
+ if (other instanceof ProvidedCapability) {
+ ProvidedCapability otherCapability = (ProvidedCapability) other;
+ return otherCapability.namespace.equals(namespace) && otherCapability.name.equals(name) && otherCapability.getVersion().equals(getVersion());
+ }
+ return false;
+ }
+
+ public int hashCode() {
+ return namespace.hashCode() * name.hashCode() * getVersion().hashCode();
+ }
+
+ public String toString() {
+ return namespace + '/' + name + '/' + getVersion();
+ }
+
+}
diff --git a/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/metadata/Recommendation.java b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/metadata/Recommendation.java
new file mode 100644
index 000000000..e3ff45ca4
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/metadata/Recommendation.java
@@ -0,0 +1,125 @@
+/*******************************************************************************
+ * 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.metadata;
+
+import org.eclipse.osgi.service.resolver.VersionRange;
+import org.osgi.framework.Version;
+
+public class Recommendation {
+ private RequiredCapability applyOn;
+ private RequiredCapability newValue;
+
+ public Recommendation(RequiredCapability applyOn2, RequiredCapability newValue2) {
+ this.applyOn = applyOn2;
+ this.newValue = newValue2;
+ }
+
+ public RequiredCapability applyOn() {
+ return applyOn;
+ }
+
+ public RequiredCapability newValue() {
+ return newValue;
+ }
+
+ public boolean matches(RequiredCapability toMatch) {
+ if (!toMatch.getNamespace().equals(applyOn.getNamespace()))
+ return false;
+ if (!toMatch.getName().equals(applyOn.getName()))
+ return false;
+ if (toMatch.getRange().equals(applyOn.getRange()))
+ return true;
+
+ //TODO Here, in the long run we want to be smarter .for example we could check that the range of the match is a subset of the range specified on applyOn.
+ return false;
+ }
+
+ boolean matches(Recommendation toMatch) {
+ return matches(toMatch.applyOn());
+ }
+
+ protected Recommendation merge(Recommendation r2) {
+ VersionRange result = intersect(newValue().getRange(), r2.newValue().getRange());
+ if (result == null)
+ return null;
+ return new Recommendation(applyOn, new RequiredCapability(applyOn.getNamespace(), applyOn.getName(), result));
+ }
+
+ private VersionRange intersect(VersionRange r1, VersionRange r2) {
+ Version resultMin = null;
+ boolean resultMinIncluded = false;
+ Version resultMax = null;
+ boolean resultMaxIncluded = false;
+
+ int minCompare = r1.getMinimum().compareTo(r2.getMinimum());
+ if (minCompare < 0) {
+ resultMin = r2.getMinimum();
+ resultMinIncluded = r2.getIncludeMinimum();
+ } else if (minCompare > 0) {
+ resultMin = r1.getMinimum();
+ resultMinIncluded = r1.getIncludeMinimum();
+ } else if (minCompare == 0) {
+ resultMin = r1.getMinimum();
+ resultMinIncluded = r1.getIncludeMinimum() && r2.getIncludeMinimum();
+ }
+
+ int maxCompare = r1.getMaximum().compareTo(r2.getMaximum());
+ if (maxCompare > 0) {
+ resultMax = r2.getMaximum();
+ resultMaxIncluded = r2.getIncludeMaximum();
+ } else if (maxCompare < 0) {
+ resultMax = r1.getMaximum();
+ resultMaxIncluded = r1.getIncludeMaximum();
+ } else if (maxCompare == 0) {
+ resultMax = r1.getMaximum();
+ resultMaxIncluded = r1.getIncludeMaximum() && r2.getIncludeMaximum();
+ }
+
+ int resultRangeComparison = resultMin.compareTo(resultMax);
+ if (resultRangeComparison < 0)
+ return new VersionRange(resultMin, resultMinIncluded, resultMax, resultMaxIncluded);
+ else if (resultRangeComparison == 0 && resultMinIncluded == resultMaxIncluded)
+ return new VersionRange(resultMin, resultMinIncluded, resultMax, resultMaxIncluded);
+ else
+ return null;
+ }
+
+ public boolean isCompatible(Recommendation other) {
+ return intersect(newValue.getRange(), other.newValue.getRange()) != null;
+ }
+
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + ((applyOn == null) ? 0 : applyOn.hashCode());
+ result = prime * result + ((newValue == null) ? 0 : newValue.hashCode());
+ return result;
+ }
+
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ final Recommendation other = (Recommendation) obj;
+ if (applyOn == null) {
+ if (other.applyOn != null)
+ return false;
+ } else if (!applyOn.equals(other.applyOn))
+ return false;
+ if (newValue == null) {
+ if (other.newValue != null)
+ return false;
+ } else if (!newValue.equals(other.newValue))
+ return false;
+ return true;
+ }
+} \ No newline at end of file
diff --git a/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/metadata/RecommendationDescriptor.java b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/metadata/RecommendationDescriptor.java
new file mode 100644
index 000000000..4a6722074
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/metadata/RecommendationDescriptor.java
@@ -0,0 +1,116 @@
+/*******************************************************************************
+ * 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.metadata;
+
+import java.util.*;
+import org.eclipse.core.runtime.*;
+import org.eclipse.equinox.internal.prov.metadata.MetadataActivator;
+import org.eclipse.osgi.service.resolver.VersionRange;
+
+public class RecommendationDescriptor {
+ public static final String TOUCHPOINT_DATA_KEY = "recommendations";
+ public static final String KIND = "recommendation";
+
+ private Set recommendations;
+
+ public RecommendationDescriptor(Set recommendations) {
+ this.recommendations = recommendations;
+ }
+
+ public Set getRecommendations() {
+ return recommendations;
+ }
+
+ public Recommendation findRecommendation(RequiredCapability toMatch) {
+ for (Iterator iterator = recommendations.iterator(); iterator.hasNext();) {
+ Recommendation name = (Recommendation) iterator.next();
+ if (name.matches(toMatch))
+ return name;
+ }
+ return null;
+ }
+
+ public Recommendation findRecommendation(Recommendation toMatch) {
+ for (Iterator iterator = recommendations.iterator(); iterator.hasNext();) {
+ Recommendation name = (Recommendation) iterator.next();
+ if (name.matches(toMatch))
+ return name;
+ }
+ return null;
+ }
+
+ //Merge the other descriptor into this one. Return an OK Status is the merged succeeded, otherwise return an INFO Status
+ public IStatus merge(RecommendationDescriptor other) {
+ MultiStatus result = null;
+ for (Iterator it = other.recommendations.iterator(); it.hasNext();) {
+ Recommendation otherRecommendation = (Recommendation) it.next();
+ Recommendation matchInThis = findRecommendation(otherRecommendation);
+ if (matchInThis == null) {
+ recommendations.add(otherRecommendation);
+ continue;
+ }
+ Recommendation newRec = otherRecommendation.merge(matchInThis);
+ if (newRec != null) {
+ recommendations.remove(matchInThis);
+ recommendations.add(newRec);
+ continue;
+ } else {
+ if (result == null)
+ result = new MultiStatus(MetadataActivator.PI_METADATA, 0, "Conflict between recommendations", null);
+ result.add(new Status(IStatus.INFO, MetadataActivator.PI_METADATA, "can't merge " + otherRecommendation + " with " + matchInThis));
+ }
+ }
+ if (result == null)
+ return Status.OK_STATUS;
+ return result;
+
+ }
+
+ public static RecommendationDescriptor parse(String descriptor) {
+ StringTokenizer entries = new StringTokenizer(descriptor, "\n");
+ Set recommendations = new HashSet(entries.countTokens());
+ while (entries.hasMoreElements()) {
+ StringTokenizer oneRec = new StringTokenizer((String) entries.nextElement(), "/");
+ if (oneRec.countTokens() != 4) {
+ //format error, ignore and continue
+
+ continue;
+ }
+ String ns = oneRec.nextToken().trim();
+ String name = oneRec.nextToken().trim();
+ String oldRange = oneRec.nextToken().trim();
+ String newRange = oneRec.nextToken().trim();
+ recommendations.add(new Recommendation(new RequiredCapability(ns, name, new VersionRange(oldRange)), new RequiredCapability(ns, name, new VersionRange(newRange))));
+ }
+ return new RecommendationDescriptor(recommendations);
+ }
+
+ public static String serialize(RecommendationDescriptor toSerialize) {
+ StringBuffer result = new StringBuffer();
+ for (Iterator iterator = toSerialize.recommendations.iterator(); iterator.hasNext();) {
+ Recommendation entry = (Recommendation) iterator.next();
+ result.append(entry.applyOn().getNamespace() + '/' + entry.applyOn().getName() + '/' + entry.applyOn().getRange().toString() + '/' + entry.newValue().getRange().toString() + '\n');
+ }
+ return result.toString();
+ }
+
+ public boolean isCompatible(RecommendationDescriptor other) {
+ for (Iterator it = other.recommendations.iterator(); it.hasNext();) {
+ Recommendation otherRecommendation = (Recommendation) it.next();
+ Recommendation matchInThis = findRecommendation(otherRecommendation);
+ if (matchInThis == null) {
+ continue;
+ }
+ if (!otherRecommendation.isCompatible(matchInThis))
+ return false;
+ }
+ return true;
+
+ }
+}
diff --git a/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/metadata/RequiredCapability.java b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/metadata/RequiredCapability.java
new file mode 100644
index 000000000..3ad8a8ee8
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/metadata/RequiredCapability.java
@@ -0,0 +1,158 @@
+/*******************************************************************************
+ * 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.metadata;
+
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.osgi.service.resolver.VersionRange;
+
+/**
+ * A required capability represents some external constraint on an {@link InstallableUnit}.
+ * Each capability represents something an {@link InstallableUnit} needs that
+ * it expects to be provided by another {@link InstallableUnit}. Capabilities are
+ * entirely generic, and are intended to be capable of representing anything that
+ * an {@link InstallableUnit} may need either at install time, or at runtime.
+ * <p>
+ * Capabilities are segmented into namespaces. Anyone can introduce new
+ * capability namespaces. Some well-known namespaces are introduced directly
+ * by the provisioning framework.
+ *
+ * @see InstallableUnit#IU_KIND_NAMESPACE
+ * @see InstallableUnit#IU_NAMESPACE
+ */
+public class RequiredCapability {
+ private String filter;
+
+ private boolean multiple;
+ private String name;
+ private String namespace;
+ boolean optional;
+ private String range;
+ private String[] selectors;
+ private transient VersionRange rangeObject;
+
+ /**
+ * Returns a {@link RequiredCapability} on the installable unit with the given name
+ * and version range.
+ */
+ public static RequiredCapability createRequiredCapabilityForName(String name, VersionRange versionRange, boolean optional) {
+ return new RequiredCapability(IInstallableUnit.IU_NAMESPACE, name, versionRange, null, optional, false);
+ }
+
+ public RequiredCapability(String namespace, String name, VersionRange range) {
+ this(namespace, name, range, null, false, false);
+ }
+
+ public RequiredCapability(String namespace, String name, VersionRange range, String filter, boolean optional, boolean multiple) {
+ this(namespace, name, range, null, filter, optional, multiple);
+ }
+
+ public RequiredCapability(String namespace, String name, VersionRange range, String[] selectors, String filter, boolean optional, boolean multiple) {
+ Assert.isNotNull(namespace);
+ Assert.isNotNull(name);
+ this.namespace = namespace;
+ this.name = name;
+ this.rangeObject = range;
+ this.range = rangeObject == null ? null : rangeObject.toString();
+ this.selectors = selectors == null ? new String[0] : selectors;
+ this.optional = optional;
+ this.filter = filter;
+ this.multiple = multiple;
+ }
+
+ public void accept(IMetadataVisitor visitor) {
+ visitor.visitRequiredCapability(this);
+ }
+
+ public String getFilter() {
+ return filter;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public String getNamespace() {
+ return namespace;
+ }
+
+ public VersionRange getRange() {
+ if (rangeObject == null)
+ rangeObject = range == null ? VersionRange.emptyRange : new VersionRange(range);
+ return rangeObject;
+ }
+
+ public boolean isMultiple() {
+ return multiple;
+ }
+
+ public boolean isOptional() {
+ return optional;
+ }
+
+ public String toString() {
+ return "requiredCapability: " + namespace + '/' + name + '/' + range;
+ }
+
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + ((filter == null) ? 0 : filter.hashCode());
+ result = prime * result + (multiple ? 1231 : 1237);
+ result = prime * result + ((name == null) ? 0 : name.hashCode());
+ result = prime * result + ((namespace == null) ? 0 : namespace.hashCode());
+ result = prime * result + (optional ? 1231 : 1237);
+ result = prime * result + ((rangeObject == null) ? 0 : rangeObject.hashCode());
+ return result;
+ }
+
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ final RequiredCapability other = (RequiredCapability) obj;
+ if (filter == null) {
+ if (other.filter != null)
+ return false;
+ } else if (!filter.equals(other.filter))
+ return false;
+ if (multiple != other.multiple)
+ return false;
+ if (name == null) {
+ if (other.name != null)
+ return false;
+ } else if (!name.equals(other.name))
+ return false;
+ if (namespace == null) {
+ if (other.namespace != null)
+ return false;
+ } else if (!namespace.equals(other.namespace))
+ return false;
+ if (optional != other.optional)
+ return false;
+ if (rangeObject == null) {
+ if (other.rangeObject != null)
+ return false;
+ } else if (!rangeObject.equals(other.rangeObject))
+ return false;
+ return true;
+ }
+
+ /**
+ * Returns the properties to use for evaluating required capability filters
+ * downstream from this capability. For example, if the selector "doc"
+ * is provided, then a downstream InstallableUnit with a required capability
+ * filtered with "doc=true" will be included.
+ */
+ public String[] getSelectors() {
+ return selectors;
+ }
+}
diff --git a/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/metadata/ResolvedInstallableUnit.java b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/metadata/ResolvedInstallableUnit.java
new file mode 100644
index 000000000..f6f5bc034
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/metadata/ResolvedInstallableUnit.java
@@ -0,0 +1,148 @@
+/*******************************************************************************
+ * 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.metadata;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import org.eclipse.equinox.internal.prov.metadata.InternalInstallableUnit;
+import org.osgi.framework.Version;
+
+public class ResolvedInstallableUnit implements IResolvedInstallableUnit, InternalInstallableUnit {
+ private static IInstallableUnit[] NO_IU = new IInstallableUnit[0];
+
+ private IInstallableUnit[] fragments = NO_IU;
+ protected InstallableUnit resolved;
+
+ public ResolvedInstallableUnit(InstallableUnit resolved) {
+ this.resolved = resolved;
+ }
+
+ public void setFragments(IResolvedInstallableUnit[] fragments) {
+ this.fragments = fragments;
+ }
+
+ public IInstallableUnitFragment[] getFragments() {
+ ArrayList result = new ArrayList();
+ if (fragments != null)
+ result.addAll(Arrays.asList(fragments));
+ for (int i = 0; i < result.size(); i++) {
+ result.addAll(Arrays.asList(((IResolvedInstallableUnit) result.get(i)).getFragments()));
+ }
+ return (IInstallableUnitFragment[]) result.toArray(new IInstallableUnitFragment[result.size()]);
+ }
+
+ public String getApplicabilityFilter() {
+ return resolved.getApplicabilityFilter();
+ }
+
+ public IArtifactKey[] getArtifacts() {
+ return resolved.getArtifacts();
+ }
+
+ public String getFilter() {
+ return resolved.getFilter();
+ }
+
+ public String getId() {
+ return resolved.getId();
+ }
+
+ public String getProperty(String key) {
+ return resolved.getProperty(key);
+ }
+
+ public ProvidedCapability[] getProvidedCapabilities() {
+ ArrayList result = new ArrayList();
+ result.addAll(Arrays.asList(resolved.getProvidedCapabilities()));
+ for (int i = 0; i < fragments.length; i++) {
+ result.addAll(Arrays.asList(fragments[i].getProvidedCapabilities()));
+ }
+ return resolved.getProvidedCapabilities();
+ }
+
+ public RequiredCapability[] getRequiredCapabilities() {
+ ArrayList result = new ArrayList();
+ result.addAll(Arrays.asList(resolved.getRequiredCapabilities()));
+ for (int i = 0; i < fragments.length; i++) {
+ result.addAll(Arrays.asList(fragments[i].getRequiredCapabilities()));
+ }
+ return (RequiredCapability[]) result.toArray(new RequiredCapability[result.size()]);
+
+ }
+
+ public TouchpointData[] getTouchpointData() {
+ ArrayList result = new ArrayList();
+ result.addAll(Arrays.asList(resolved.getTouchpointData()));
+ for (int i = 0; i < fragments.length; i++) {
+ TouchpointData[] data = fragments[i].getTouchpointData();
+ for (int j = 0; j < data.length; j++) {
+ result.add(data[j]);
+ }
+ }
+ return (TouchpointData[]) result.toArray(new TouchpointData[result.size()]);
+ }
+
+ public TouchpointType getTouchpointType() {
+ return resolved.getTouchpointType();
+ }
+
+ public Version getVersion() {
+ return resolved.getVersion();
+ }
+
+ public boolean isFragment() {
+ return resolved.isFragment();
+ }
+
+ public boolean isSingleton() {
+ return resolved.isSingleton();
+ }
+
+ public void accept(IMetadataVisitor visitor) {
+ visitor.visitInstallableUnit(this);
+ }
+
+ public boolean equals(Object obj) {
+ //TODO This is pretty ugly....
+ boolean result = resolved.equals(obj);
+ if (result)
+ return true;
+ if (obj instanceof ResolvedInstallableUnit)
+ return resolved.equals(((ResolvedInstallableUnit) obj).resolved);
+ return false;
+ }
+
+ public int hashCode() {
+ // TODO Auto-generated method stub
+ return resolved.hashCode();
+ }
+
+ public String toString() {
+ return "[R]" + resolved.toString();
+ }
+
+ public IInstallableUnit getOriginal() {
+ return resolved;
+ }
+
+ public int compareTo(Object toCompareTo) {
+ if (!(toCompareTo instanceof IInstallableUnit)) {
+ return -1;
+ }
+ IInstallableUnit other = (IInstallableUnit) toCompareTo;
+ if (getId().compareTo(other.getId()) == 0)
+ return (getVersion().compareTo(other.getVersion()));
+ return getId().compareTo(other.getId());
+ }
+
+ public IResolvedInstallableUnit getResolved() {
+ return this;
+ }
+
+}
diff --git a/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/metadata/ResolvedInstallableUnitFragment.java b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/metadata/ResolvedInstallableUnitFragment.java
new file mode 100644
index 000000000..f7532d2a9
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/metadata/ResolvedInstallableUnitFragment.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.metadata;
+
+import org.eclipse.osgi.service.resolver.VersionRange;
+
+public class ResolvedInstallableUnitFragment extends ResolvedInstallableUnit implements IResolvedInstallableUnitFragment {
+
+ public ResolvedInstallableUnitFragment(InstallableUnitFragment resolved) {
+ super(resolved);
+ }
+
+ public String getHostId() {
+ return ((InstallableUnitFragment) resolved).getHostId();
+ }
+
+ public VersionRange getHostVersionRange() {
+ return ((InstallableUnitFragment) resolved).getHostVersionRange();
+ }
+}
diff --git a/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/metadata/Selector.java b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/metadata/Selector.java
new file mode 100644
index 000000000..a63f39bc3
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/metadata/Selector.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.prov.metadata;
+
+import java.util.Dictionary;
+import org.eclipse.equinox.internal.prov.metadata.MetadataActivator;
+import org.osgi.framework.InvalidSyntaxException;
+
+public class Selector {
+ private String id;
+ private String filter;
+ private boolean internal;
+
+ public Selector(String id, String filter, boolean internal) {
+ this.id = id;
+ this.filter = filter;
+ this.internal = internal;
+ }
+
+ public String getId() {
+ return id;
+ }
+
+ public boolean eval(Dictionary context) {
+ try {
+ return MetadataActivator.context.createFilter(filter).match(context);
+ } catch (InvalidSyntaxException e) {
+ //TODO log something. though that should not happen
+ return false;
+ }
+ }
+
+ public boolean isInternal() {
+ return internal;
+ }
+}
diff --git a/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/metadata/TouchpointData.java b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/metadata/TouchpointData.java
new file mode 100644
index 000000000..67b56c6de
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/metadata/TouchpointData.java
@@ -0,0 +1,55 @@
+/*******************************************************************************
+ * 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.metadata;
+
+import java.util.Map;
+
+public class TouchpointData {
+ public static TouchpointData[] NO_TOUCHPOINT_DATA = new TouchpointData[0];
+
+ /**
+ * Map of (String->String). The values represent the instructions. The set
+ * of keys supported is up to the touchpoint that will process these
+ * instructions
+ */
+ private Map instructions;
+
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + ((instructions == null) ? 0 : instructions.hashCode());
+ return result;
+ }
+
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ final TouchpointData other = (TouchpointData) obj;
+ if (instructions == null) {
+ if (other.instructions != null)
+ return false;
+ } else if (!instructions.equals(other.instructions))
+ return false;
+ return true;
+ }
+
+ public TouchpointData(Map instructions) {
+ this.instructions = instructions;
+ }
+
+ public String getInstructions(String instructionKey) {
+ return (String) instructions.get(instructionKey);
+ }
+}
diff --git a/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/metadata/TouchpointType.java b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/metadata/TouchpointType.java
new file mode 100644
index 000000000..1a99d8a2a
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/metadata/TouchpointType.java
@@ -0,0 +1,78 @@
+/*******************************************************************************
+ * 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.metadata;
+
+import org.osgi.framework.Version;
+
+/**
+ * Identifies a particular touchpoint. A touchpoint is identified by an id
+ * and a version.
+ */
+public class TouchpointType {
+ /**
+ * A touchpoint type indicating that the "null" touchpoint should be used.
+ * The null touchpoint does not participate in any install phase.
+ */
+ public static final TouchpointType NONE = new TouchpointType("null", new Version("0")); //$NON-NLS-1$//$NON-NLS-2$
+ private String id;
+ private Version versionObject;
+ private String version;
+
+ public TouchpointType(String id, Version aVersion) {
+ this.id = id;
+ this.versionObject = aVersion;
+ this.version = aVersion == null ? null : aVersion.toString();
+ }
+
+ public String getId() {
+ return id;
+ }
+
+ public Version getVersion() {
+ if (versionObject == null)
+ versionObject = version == null ? Version.emptyVersion : new Version(version);
+ return versionObject;
+ }
+
+ public String toString() {
+ return "Touchpoint: " + id + ' ' + getVersion();
+ }
+
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + ((id == null) ? 0 : id.hashCode());
+ result = prime * result + ((getVersion() == null) ? 0 : getVersion().hashCode());
+ return result;
+ }
+
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (super.equals(obj))
+ return true;
+ if (getClass() != obj.getClass())
+ return false;
+ final TouchpointType other = (TouchpointType) obj;
+ if (id == null) {
+ if (other.id != null)
+ return false;
+ } else if (!id.equals(other.id))
+ return false;
+ if (getVersion() == null) {
+ if (other.getVersion() != null)
+ return false;
+ } else if (!getVersion().equals(other.getVersion()))
+ return false;
+ return true;
+ }
+
+}
diff --git a/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/query/CompoundIterator.java b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/query/CompoundIterator.java
new file mode 100644
index 000000000..73dfaa3dd
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/query/CompoundIterator.java
@@ -0,0 +1,98 @@
+/*******************************************************************************
+ * 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.query;
+
+import java.util.*;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.equinox.internal.prov.metadata.Messages;
+import org.eclipse.equinox.prov.metadata.IInstallableUnit;
+import org.eclipse.equinox.prov.metadata.RequiredCapability;
+import org.eclipse.osgi.service.resolver.VersionRange;
+
+public class CompoundIterator implements Iterator {
+ private Iterator[] iterators;
+ private String id;
+ private VersionRange range;
+ private RequiredCapability[] requirements;
+ private boolean and;
+ private int index = 0;
+ private boolean filtered = false;
+ private IInstallableUnit lookahead = null;
+
+ public static IInstallableUnit[] asArray(Iterator i, IProgressMonitor progress) {
+ if (progress == null)
+ progress = new NullProgressMonitor();
+ progress.beginTask(Messages.QUERY_PROGRESS, IProgressMonitor.UNKNOWN);
+ HashSet result = new HashSet();
+ while (i.hasNext()) {
+ result.add(i.next());
+ progress.worked(IProgressMonitor.UNKNOWN);
+ }
+ progress.done();
+ return (IInstallableUnit[]) result.toArray(new IInstallableUnit[result.size()]);
+ }
+
+ public CompoundIterator(Iterator[] iterators) {
+ this.iterators = iterators;
+ }
+
+ public CompoundIterator(Iterator[] iterators, String id, VersionRange range, RequiredCapability[] requirements, boolean and) {
+ this(iterators);
+ this.id = id;
+ this.range = range;
+ this.requirements = requirements;
+ this.and = and;
+ filtered = true;
+ }
+
+ public boolean hasNext() {
+ if (lookahead != null)
+ return true;
+ if (index >= iterators.length)
+ return false;
+ if (filtered) {
+ while (iterators[index].hasNext()) {
+ IInstallableUnit next = (IInstallableUnit) iterators[index].next();
+ if (Query.match(next, id, range, requirements, and)) {
+ lookahead = next;
+ return true;
+ }
+ }
+ } else {
+ if (iterators[index].hasNext())
+ return true;
+ }
+ index++;
+ return hasNext();
+ }
+
+ public Object next() {
+ if (lookahead != null) {
+ IInstallableUnit result = lookahead;
+ lookahead = null;
+ return result;
+ }
+ if (index >= iterators.length)
+ throw new NoSuchElementException();
+ while (iterators[index].hasNext()) {
+ IInstallableUnit next = (IInstallableUnit) iterators[index].next();
+ if (!filtered)
+ return next;
+ if (Query.match(next, id, range, requirements, and))
+ return next;
+ }
+ index++;
+ return next();
+ }
+
+ public void remove() {
+ throw new UnsupportedOperationException();
+ }
+}
diff --git a/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/query/IQueryable.java b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/query/IQueryable.java
new file mode 100644
index 000000000..7811a750a
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/query/IQueryable.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.query;
+
+import java.util.Iterator;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.equinox.prov.metadata.IInstallableUnit;
+import org.eclipse.equinox.prov.metadata.RequiredCapability;
+import org.eclipse.osgi.service.resolver.VersionRange;
+
+public interface IQueryable {
+
+ IInstallableUnit[] query(String id, VersionRange range, RequiredCapability[] requirements, boolean and, IProgressMonitor progress);
+
+ Iterator getIterator(String id, VersionRange range, RequiredCapability[] requirements, boolean and);
+
+}
diff --git a/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/query/Query.java b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/query/Query.java
new file mode 100644
index 000000000..ac91489ed
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/query/Query.java
@@ -0,0 +1,73 @@
+/*******************************************************************************
+ * 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.query;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.equinox.internal.prov.metadata.Messages;
+import org.eclipse.equinox.prov.metadata.*;
+import org.eclipse.osgi.service.resolver.VersionRange;
+
+public class Query {
+
+ public static boolean match(IInstallableUnit source, String id, VersionRange range, RequiredCapability[] requirements, boolean and) {
+ if (id != null && !source.getId().equals(id))
+ return false;
+ if (range != null && !range.isIncluded(source.getVersion()))
+ return false;
+ if (requirements == null)
+ return true;
+ // if any of the requirements are met by any of the capabilities of the source...
+ for (int k = 0; k < requirements.length; k++) {
+ boolean valid = false;
+ ProvidedCapability[] capabilities = source.getProvidedCapabilities();
+ for (int j = 0; j < capabilities.length; j++)
+ //TODO Need to deal with option and multiplicity flag
+ if ((requirements[k].getName().equals(capabilities[j].getName()) && requirements[k].getNamespace().equals(capabilities[j].getNamespace()) && (requirements[k].getRange() == null ? true : requirements[k].getRange().isIncluded(capabilities[j].getVersion())))) {
+ valid = true;
+ }
+ // if we are OR'ing then the first time we find a requirement that is met, return success
+ if (valid && !and)
+ return true;
+ // if we are AND'ing then the first time we find a requirement that is NOT met, return failure
+ if (!valid && and)
+ return false;
+ }
+ // if we get past the requirements check and we are AND'ing then return true
+ // since all requirements must have been met. If we are OR'ing then return false
+ // since none of the requirements were met.
+ return and;
+ }
+
+ public static IInstallableUnit[] query(IQueryable[] sources, String id, VersionRange range, RequiredCapability[] requirements, boolean and, IProgressMonitor progress) {
+ if (progress == null)
+ progress = new NullProgressMonitor();
+
+ progress.beginTask(Messages.QUERY_PROGRESS, sources.length);
+ ArrayList result = new ArrayList();
+ for (int i = 0; i < sources.length; i++) {
+ IQueryable source = sources[i];
+ IInstallableUnit[] list = source.query(id, range, requirements, and, progress);
+ for (int j = 0; j < list.length; j++)
+ result.add(list[j]);
+ progress.worked(1);
+ }
+ progress.done();
+ return (IInstallableUnit[]) result.toArray(new IInstallableUnit[result.size()]);
+ }
+
+ public static Iterator getIterator(IQueryable[] sources, String id, VersionRange range, RequiredCapability[] requirements, boolean and) {
+ Iterator[] result = new Iterator[sources.length];
+ for (int i = 0; i < sources.length; i++)
+ result[i] = sources[i].getIterator(id, range, requirements, and);
+ return new CompoundIterator(result);
+ }
+}
diff --git a/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/query/QueryableArray.java b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/query/QueryableArray.java
new file mode 100644
index 000000000..01177285e
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/query/QueryableArray.java
@@ -0,0 +1,47 @@
+/*******************************************************************************
+ * 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.query;
+
+import java.util.*;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.equinox.internal.prov.metadata.Messages;
+import org.eclipse.equinox.prov.metadata.IInstallableUnit;
+import org.eclipse.equinox.prov.metadata.RequiredCapability;
+import org.eclipse.osgi.service.resolver.VersionRange;
+
+public class QueryableArray implements IQueryable {
+ private IInstallableUnit[] source;
+
+ public QueryableArray(IInstallableUnit[] source) {
+ this.source = source;
+ }
+
+ public Iterator getIterator(String id, VersionRange range, RequiredCapability[] requirements, boolean and) {
+ Iterator i = Arrays.asList(source).iterator();
+ return new CompoundIterator(new Iterator[] {i}, id, range, requirements, and);
+ }
+
+ public IInstallableUnit[] query(String id, VersionRange range, RequiredCapability[] requirements, boolean and, IProgressMonitor progress) {
+ if (progress == null)
+ progress = new NullProgressMonitor();
+ progress.beginTask(Messages.QUERY_PROGRESS, source.length);
+ Set result = new HashSet();
+ for (int i = 0; i < source.length; i++) {
+ if (Query.match(source[i], id, range, requirements, and))
+ result.add(source[i]);
+ progress.worked(1);
+ }
+ progress.done();
+ return (IInstallableUnit[]) result.toArray(new IInstallableUnit[result.size()]);
+
+ }
+}
diff --git a/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/resolution/ResolutionHelper.java b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/resolution/ResolutionHelper.java
new file mode 100644
index 000000000..5eceae0d1
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/resolution/ResolutionHelper.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.resolution;
+
+import java.util.*;
+import org.eclipse.equinox.internal.prov.metadata.InternalInstallableUnit;
+import org.eclipse.equinox.internal.prov.metadata.MetadataActivator;
+import org.eclipse.equinox.prov.metadata.*;
+import org.eclipse.osgi.service.resolver.*;
+import org.osgi.framework.ServiceReference;
+
+public class ResolutionHelper {
+ private static boolean DEBUG = false;
+
+ private Transformer transformer;
+ private State state;
+ private Dictionary selectionContext;
+ private RecommendationDescriptor recommendations;
+
+ public ResolutionHelper(Dictionary selectionContext, RecommendationDescriptor recommendations) {
+ this.selectionContext = selectionContext;
+ this.recommendations = recommendations;
+ }
+
+ private void initialize() {
+ ServiceReference sr = MetadataActivator.context.getServiceReference(PlatformAdmin.class.getName());
+ PlatformAdmin pa = (PlatformAdmin) MetadataActivator.context.getService(sr);
+ transformer = new Transformer(pa.getFactory(), selectionContext, recommendations);
+ state = pa.getFactory().createState(true);
+ if (selectionContext != null)
+ state.setPlatformProperties(selectionContext);
+ }
+
+ private void addToState(BundleDescription bd) {
+ state.addBundle(bd);
+ }
+
+ private BundleDescription addInResolution(IInstallableUnit toAdd) {
+ toAdd.accept(transformer);
+ // transformer.visitInstallableUnit(toAdd);
+ BundleDescription descriptionToAdd = transformer.getResult();
+ // bundleDescriptionToIU.put(descriptionToAdd, toAdd);
+ addToState(descriptionToAdd);
+ return descriptionToAdd;
+ }
+
+ /**
+ * Indicates if the installable unit to install will have all their constraints satisfied when installed with other installable units.
+ * @param toInstall the installable units to install
+ * @param existingState the other installable units to resolve against
+ * @return true if the installable unit to install resolves, return false otherwise.
+ */
+ public UnsatisfiedCapability[] install(Set toInstall, Set existingState) {
+ initialize();
+ BundleDescription[] addedBundle = new BundleDescription[toInstall.size()];
+ int j = 0;
+ for (Iterator iterator = toInstall.iterator(); iterator.hasNext();) {
+ addedBundle[j++] = addInResolution((IInstallableUnit) iterator.next());
+ }
+
+ for (Iterator iterator = existingState.iterator(); iterator.hasNext();) {
+ addInResolution((IInstallableUnit) iterator.next());
+ }
+
+ state.resolve(); //We may want to resolve in two times. first the existing state, then add the toInstall. This would allow to see what changes when dropping the new iu.
+ //Also it could allow us to do an incremental resolution. however the results may differ
+
+ ArrayList results = new ArrayList();
+ for (int i = 0; i < addedBundle.length; i++) {
+ results.addAll(createUnsatisfiedCapabilities(state.getStateHelper().getUnsatisfiedConstraints(addedBundle[i]), addedBundle[i]));
+ }
+ return (UnsatisfiedCapability[]) results.toArray(new UnsatisfiedCapability[results.size()]);
+
+ }
+
+ private ArrayList createUnsatisfiedCapabilities(VersionConstraint[] unsatisfied, BundleDescription description) {
+ ArrayList results = new ArrayList();
+ for (int i = 0; i < unsatisfied.length; i++) {
+ RequiredCapability originalDependency = (RequiredCapability) ((StateMetadataMap) description.getUserObject()).getGenericSpecifications().get(unsatisfied[i]);
+ results.add(new UnsatisfiedCapability(originalDependency, ((StateMetadataMap) description.getUserObject()).getUnit()));
+ }
+ return results;
+ }
+
+ /**
+ * Associates installable unit fragments to each IU being installed.
+ *
+ * TODO: This method should probably be renamed to attachFragments
+ */
+ public Collection attachCUs(Collection toAttach) {
+ initialize();
+ Collection result = new HashSet(toAttach.size());
+ for (Iterator iterator = toAttach.iterator(); iterator.hasNext();) {
+ IResolvedInstallableUnit tmp = ((InternalInstallableUnit) iterator.next()).getResolved();
+ result.add(tmp);
+ addInResolution(tmp);
+ }
+ state.resolve();
+ BundleDescription[] bds = state.getBundles();
+ for (int i = 0; i < bds.length; i++) {
+ if (DEBUG) {
+ ResolverError[] re = state.getResolverErrors(bds[i]);
+ for (int j = 0; j < re.length; j++) {
+ System.out.println(re[j]);
+ }
+ }
+ BundleDescription[] potentialIUFragments = state.getStateHelper().getDependentBundles(new BundleDescription[] {bds[i]});
+ // TODO: We need to define a way to allow IUFragments to work together to do configuration work.
+ // For now we will select just one fragment by preferring a fragment that matches the host
+
+ IInstallableUnit hostIU = ((StateMetadataMap) bds[i].getUserObject()).getUnit();
+ IResolvedInstallableUnitFragment selectedFragment = null;
+ for (int k = 0; k < potentialIUFragments.length; k++) {
+ IInstallableUnit dependentIU = ((StateMetadataMap) potentialIUFragments[k].getUserObject()).getUnit();
+ if (hostIU.equals(dependentIU))
+ continue;
+
+ if (dependentIU.isFragment()) {
+ IResolvedInstallableUnitFragment potentialFragment = (IResolvedInstallableUnitFragment) dependentIU;
+
+ if (potentialFragment.getHostId() == null) {
+ // default fragment - we'll mark it selected but keep looking for a fragment that matches the host
+ selectedFragment = potentialFragment;
+ } else if (potentialFragment.getHostId().equals(hostIU.getId()) && potentialFragment.getHostVersionRange().isIncluded(hostIU.getVersion())) {
+ // matches host - we're done
+ selectedFragment = potentialFragment;
+ break;
+ } // otherwise keep looking
+ }
+ }
+ if (selectedFragment != null)
+ ((ResolvedInstallableUnit) hostIU).setFragments(new IResolvedInstallableUnit[] {selectedFragment});
+ }
+ return result;
+ }
+
+ public boolean isResolved(IInstallableUnit iu) {
+ return state.getBundle(iu.getId(), iu.getVersion()).isResolved();
+ }
+
+ public ArrayList getAllResolved() {
+ BundleDescription[] bd = state.getResolvedBundles();
+ ArrayList result = new ArrayList(bd.length);
+ for (int i = 0; i < bd.length; i++) {
+ result.add(extractIU(bd[i]));
+ }
+ return result;
+ }
+
+ private IInstallableUnit extractIU(BundleDescription bd) {
+ return ((StateMetadataMap) bd.getUserObject()).getUnit();
+ }
+
+ public List getSorted() {
+ BundleDescription[] toSort = state.getResolvedBundles();
+ state.getStateHelper().sortBundles(toSort);
+ List result = new ArrayList(toSort.length);
+ for (int i = 0; i < toSort.length; i++) {
+ result.add(extractIU(toSort[i]));
+ }
+ return result;
+ }
+}
diff --git a/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/resolution/StateMetadataMap.java b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/resolution/StateMetadataMap.java
new file mode 100644
index 000000000..1fc262c5e
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/resolution/StateMetadataMap.java
@@ -0,0 +1,34 @@
+/*******************************************************************************
+ * 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.resolution;
+
+import java.util.Map;
+import org.eclipse.equinox.prov.metadata.IInstallableUnit;
+
+//Instances of this class are stored in the user object slot of bundlescriptions to ease navigation between the two models.
+public class StateMetadataMap {
+ private IInstallableUnit unit;
+ private Map correspondingSpecifications; //indexes in this array maps to the ones in the dependencies array. This is gross. TODO
+
+ public StateMetadataMap(IInstallableUnit unit, Map correspondingSpecifications) {
+ super();
+ this.unit = unit;
+ this.correspondingSpecifications = correspondingSpecifications;
+ }
+
+ public IInstallableUnit getUnit() {
+ return unit;
+ }
+
+ public Map getGenericSpecifications() {
+ return correspondingSpecifications;
+ }
+}
diff --git a/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/resolution/Transformer.java b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/resolution/Transformer.java
new file mode 100644
index 000000000..d9afe1cfa
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/resolution/Transformer.java
@@ -0,0 +1,141 @@
+/*******************************************************************************
+ * 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.resolution;
+
+import java.util.*;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.equinox.internal.prov.metadata.MetadataActivator;
+import org.eclipse.equinox.prov.core.helpers.LogHelper;
+import org.eclipse.equinox.prov.metadata.*;
+import org.eclipse.osgi.service.resolver.*;
+import org.osgi.framework.InvalidSyntaxException;
+
+public class Transformer implements IMetadataVisitor {
+ private static final byte IU_KIND = 0;
+ private static final String IU_NAMESPACE = "iu.namespace";
+ static long iuInternalId = 0;
+
+ private Dictionary context = null;
+ private StateObjectFactory factory = null;
+ private ArrayList iuCapabilities;
+ private Map iuDependencies;
+ private byte kind = IU_KIND;
+
+ private BundleDescription result = null;
+
+ private RecommendationDescriptor recommendations = null;
+
+ public Transformer(StateObjectFactory factory) {
+ this(factory, null, null);
+ }
+
+ public Transformer(StateObjectFactory factory, Dictionary context, RecommendationDescriptor recommendations) {
+ this.factory = factory;
+ this.context = context;
+ this.recommendations = recommendations;
+ }
+
+ private String getNamespace() {
+ switch (kind) {
+ case IU_KIND :
+ return IU_NAMESPACE;
+ default :
+ throw new IllegalStateException("unknown kind"); //This should not happen
+ }
+ }
+
+ public BundleDescription getResult() {
+ return result;
+ }
+
+ private boolean isEnabled(RequiredCapability capability) {
+ // If there is no context then be optimistic
+ if (context == null)
+ return true;
+ String filter = capability.getFilter();
+ if (filter == null)
+ return true;
+ try {
+ return MetadataActivator.getContext().createFilter(filter).match(context);
+ } catch (InvalidSyntaxException e) {
+ // If we fail to parse the filter treat it as invalid and be optimistic
+ return true;
+ }
+ }
+
+ private String toFilter(VersionRange range) {
+ if (range == null)
+ return null;
+ StringBuffer buf = new StringBuffer();
+ buf.append("(&"); //$NON-NLS-1$
+ buf.append("(version>=").append(range.getMinimum().toString()).append(')'); //$NON-NLS-1$
+ if (!range.getIncludeMinimum())
+ buf.append("(!(version=").append(range.getMinimum().toString()).append("))");
+ buf.append("(version<=").append(range.getMaximum().toString()).append(')'); //$NON-NLS-1$
+ if (!range.getIncludeMaximum())
+ buf.append("(!(version=").append(range.getMaximum().toString()).append("))");
+ buf.append(')');
+ return buf.toString();
+ }
+
+ public void visitCapability(ProvidedCapability capability) {
+ iuCapabilities.add(factory.createGenericDescription(capability.getName(), capability.getNamespace(), capability.getVersion(), null));
+ }
+
+ public void visitInstallableUnit(IInstallableUnit toTransform) {
+ kind = IU_KIND;
+
+ //Start with the dependencies
+ RequiredCapability[] requires = toTransform.getRequiredCapabilities();
+ iuDependencies = new HashMap(requires.length);
+ for (int i = 0; i < requires.length; i++) {
+ requires[i].accept(this);
+ }
+
+ //Do the capabilities
+ ProvidedCapability[] capabilities = toTransform.getProvidedCapabilities();
+ iuCapabilities = new ArrayList(requires.length + 1);
+ for (int i = 0; i < capabilities.length; i++) {
+ capabilities[i].accept(this);
+ }
+
+ //Add a capability representing the IU itself
+ iuCapabilities.add(factory.createGenericDescription(toTransform.getId(), getNamespace(), toTransform.getVersion(), null));
+
+ GenericSpecification[] genericSpecifications = new GenericSpecification[iuDependencies.size()];
+ iuDependencies.keySet().toArray(genericSpecifications);
+
+ GenericDescription[] genericDescriptions = new GenericDescription[iuCapabilities.size()];
+ iuCapabilities.toArray(genericDescriptions);
+
+ //Finally create the bundle description
+ //TODO Need to create the filter for the IU itself
+ result = factory.createBundleDescription(iuInternalId++, toTransform.getId(), toTransform.getVersion(), (String) null, (BundleSpecification[]) null, (HostSpecification) null, (ImportPackageSpecification[]) null, (ExportPackageDescription[]) null, toTransform.isSingleton(), true, true, toTransform.getFilter(), (String[]) null, genericSpecifications, genericDescriptions);
+ result.setUserObject(new StateMetadataMap(toTransform, iuDependencies));
+ }
+
+ public void visitRequiredCapability(RequiredCapability capability) {
+ try {
+ if (isEnabled(capability)) {
+ capability = rewrite(capability);
+ iuDependencies.put(factory.createGenericSpecification(capability.getName(), capability.getNamespace(), toFilter(capability.getRange()), capability.isOptional(), capability.isMultiple()), capability);
+ }
+ } catch (InvalidSyntaxException e) {
+ LogHelper.log(new Status(IStatus.ERROR, MetadataActivator.PI_METADATA, "Invalid filter: " + e.getFilter(), e)); //$NON-NLS-1$
+ }
+ }
+
+ private RequiredCapability rewrite(RequiredCapability match) {
+ if (recommendations == null)
+ return match;
+ Recommendation foundRecommendation = recommendations.findRecommendation(match);
+ return foundRecommendation != null ? foundRecommendation.newValue() : match;
+ }
+}
diff --git a/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/resolution/UnsatisfiedCapability.java b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/resolution/UnsatisfiedCapability.java
new file mode 100644
index 000000000..29d6c244d
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.metadata/src/org/eclipse/equinox/prov/resolution/UnsatisfiedCapability.java
@@ -0,0 +1,56 @@
+/*******************************************************************************
+ * 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.resolution;
+
+import org.eclipse.equinox.prov.metadata.IInstallableUnit;
+import org.eclipse.equinox.prov.metadata.RequiredCapability;
+
+/**
+ * Represents a provisioning dependency that was not satisfied during
+ * resolution.
+ */
+public class UnsatisfiedCapability {
+ private IInstallableUnit owner;
+ private RequiredCapability require;
+
+ /**
+ * Creates a new unresolved dependency
+ * @param required The dependency that was not satisfied.
+ * @param owner The installable unit whose dependency was not satisfied.
+ */
+ public UnsatisfiedCapability(RequiredCapability required, IInstallableUnit owner) {
+ this.require = required;
+ this.owner = owner;
+ }
+
+ public IInstallableUnit getOwner() {
+ return owner;
+ }
+
+ /**
+ * Returns the specific dependency that was not satisfied.
+ */
+ public RequiredCapability getRequiredCapability() {
+ return require;
+ }
+
+ /**
+ * Returns the installable unit whose dependency was not satisfied.
+ */
+ public IInstallableUnit getUnsatisfiedUnit() {
+ return owner;
+ }
+
+ /**
+ * For debugging purposes only.
+ */
+ public String toString() {
+ return "[" + owner + "] " + require.toString(); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+}

Back to the top