Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorpdobrev2008-02-13 08:41:38 +0000
committerpdobrev2008-02-13 08:41:38 +0000
commit23aa191052aa8547480db22bd674c867b1807a54 (patch)
tree69ad49a97174af89f7d037e82dcbe5b6fec7768c /bundles/org.eclipse.equinox.ip
parentd4d5d549560c5f9b38512843b96c82af2721ad73 (diff)
downloadrt.equinox.bundles-23aa191052aa8547480db22bd674c867b1807a54.tar.gz
rt.equinox.bundles-23aa191052aa8547480db22bd674c867b1807a54.tar.xz
rt.equinox.bundles-23aa191052aa8547480db22bd674c867b1807a54.zip
Graduation of the bundle from the equinox.incubator
Diffstat (limited to 'bundles/org.eclipse.equinox.ip')
-rw-r--r--bundles/org.eclipse.equinox.ip/.classpath7
-rw-r--r--bundles/org.eclipse.equinox.ip/.cvsignore1
-rw-r--r--bundles/org.eclipse.equinox.ip/.project28
-rw-r--r--bundles/org.eclipse.equinox.ip/.settings/org.eclipse.jdt.core.prefs331
-rw-r--r--bundles/org.eclipse.equinox.ip/.settings/org.eclipse.jdt.ui.prefs57
-rw-r--r--bundles/org.eclipse.equinox.ip/.settings/org.eclipse.pde.core.prefs3
-rw-r--r--bundles/org.eclipse.equinox.ip/META-INF/MANIFEST.MF41
-rw-r--r--bundles/org.eclipse.equinox.ip/OSGI-INF/permissions.perm1
-rw-r--r--bundles/org.eclipse.equinox.ip/about.html28
-rw-r--r--bundles/org.eclipse.equinox.ip/build.properties6
-rw-r--r--bundles/org.eclipse.equinox.ip/props.txt16
-rw-r--r--bundles/org.eclipse.equinox.ip/src/org/eclipse/equinox/internal/ip/ProvisioningInfoProvider.java83
-rw-r--r--bundles/org.eclipse.equinox.ip/src/org/eclipse/equinox/internal/ip/ProvisioningStorage.java48
-rw-r--r--bundles/org.eclipse.equinox.ip/src/org/eclipse/equinox/internal/ip/dscagent/DiscoveryAgent.java269
-rw-r--r--bundles/org.eclipse.equinox.ip/src/org/eclipse/equinox/internal/ip/impl/Log.java170
-rw-r--r--bundles/org.eclipse.equinox.ip/src/org/eclipse/equinox/internal/ip/impl/ProvisioningAgent.java1219
-rw-r--r--bundles/org.eclipse.equinox.ip/src/org/eclipse/equinox/internal/ip/impl/ProvisioningData.java152
-rw-r--r--bundles/org.eclipse.equinox.ip/src/org/eclipse/equinox/internal/ip/package.html9
-rw-r--r--bundles/org.eclipse.equinox.ip/src/org/eclipse/equinox/internal/ip/provider/BaseProvider.java90
-rw-r--r--bundles/org.eclipse.equinox.ip/src/org/eclipse/equinox/internal/ip/provider/env/EnvironmentInfoProvider.java127
-rw-r--r--bundles/org.eclipse.equinox.ip/src/org/eclipse/equinox/internal/ip/provider/file/FileProvider.java189
-rw-r--r--bundles/org.eclipse.equinox.ip/src/org/eclipse/equinox/internal/ip/provider/http/Context.java63
-rw-r--r--bundles/org.eclipse.equinox.ip/src/org/eclipse/equinox/internal/ip/provider/http/HttpProvider.java287
-rw-r--r--bundles/org.eclipse.equinox.ip/src/org/eclipse/equinox/internal/ip/storage/cm/CMStorage.java239
-rw-r--r--bundles/org.eclipse.equinox.ip/src/org/eclipse/equinox/internal/ip/storage/file/FileStorage.java185
25 files changed, 3649 insertions, 0 deletions
diff --git a/bundles/org.eclipse.equinox.ip/.classpath b/bundles/org.eclipse.equinox.ip/.classpath
new file mode 100644
index 00000000..ce0c7a5d
--- /dev/null
+++ b/bundles/org.eclipse.equinox.ip/.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.0%Foundation-1.0"/>
+ <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+ <classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/bundles/org.eclipse.equinox.ip/.cvsignore b/bundles/org.eclipse.equinox.ip/.cvsignore
new file mode 100644
index 00000000..ba077a40
--- /dev/null
+++ b/bundles/org.eclipse.equinox.ip/.cvsignore
@@ -0,0 +1 @@
+bin
diff --git a/bundles/org.eclipse.equinox.ip/.project b/bundles/org.eclipse.equinox.ip/.project
new file mode 100644
index 00000000..0c4d551a
--- /dev/null
+++ b/bundles/org.eclipse.equinox.ip/.project
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>org.eclipse.equinox.ip</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.ip/.settings/org.eclipse.jdt.core.prefs b/bundles/org.eclipse.equinox.ip/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 00000000..d304116c
--- /dev/null
+++ b/bundles/org.eclipse.equinox.ip/.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=warning
+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.ip/.settings/org.eclipse.jdt.ui.prefs b/bundles/org.eclipse.equinox.ip/.settings/org.eclipse.jdt.ui.prefs
new file mode 100644
index 00000000..023a27a6
--- /dev/null
+++ b/bundles/org.eclipse.equinox.ip/.settings/org.eclipse.jdt.ui.prefs
@@ -0,0 +1,57 @@
+#Tue Aug 21 11:19:11 CDT 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=99
+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.correct_indentation=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.ip/.settings/org.eclipse.pde.core.prefs b/bundles/org.eclipse.equinox.ip/.settings/org.eclipse.pde.core.prefs
new file mode 100644
index 00000000..6fb22e10
--- /dev/null
+++ b/bundles/org.eclipse.equinox.ip/.settings/org.eclipse.pde.core.prefs
@@ -0,0 +1,3 @@
+#Thu Mar 29 10:32:21 EEST 2007
+eclipse.preferences.version=1
+pluginProject.extensions=false
diff --git a/bundles/org.eclipse.equinox.ip/META-INF/MANIFEST.MF b/bundles/org.eclipse.equinox.ip/META-INF/MANIFEST.MF
new file mode 100644
index 00000000..5fdc57f7
--- /dev/null
+++ b/bundles/org.eclipse.equinox.ip/META-INF/MANIFEST.MF
@@ -0,0 +1,41 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: Initial Provisioning
+Bundle-SymbolicName: org.eclipse.equinox.ip
+Bundle-Version: 0.1.0.qualifier
+Bundle-Vendor: Eclipse
+Bundle-Description: Provides implementation of the Intial Provisioning service
+ defined by OSGi specification release 4.
+Bundle-Activator: org.eclipse.equinox.internal.ip.impl.ProvisioningAgent
+DynamicImport-Package: org.osgi.service.permissionadmin; version="1.0"
+Import-Package:
+ javax.servlet;version="2.2",
+ javax.servlet.http;version="2.2",
+ org.eclipse.equinox.internal.util.ref;version="1.0",
+ org.eclipse.equinox.internal.util.timer;version="1.0",
+ org.osgi.framework;version="1.0",
+ org.osgi.service.cm;version="1.2.0",
+ org.osgi.service.http;version="1.0",
+ org.osgi.service.log;version="1.3.0",
+ org.osgi.service.provisioning;version="1.0",
+ org.osgi.service.useradmin;version="1.0",
+ org.osgi.util.tracker;version="1.3.2"
+Export-Package:
+ org.eclipse.equinox.internal.ip;x-internal:=true,
+ org.eclipse.equinox.internal.ip.dscagent;x-internal:=true,
+ org.eclipse.equinox.internal.ip.impl;x-internal:=true,
+ org.eclipse.equinox.internal.ip.provider;x-internal:=true,
+ org.eclipse.equinox.internal.ip.provider.env;x-internal:=true,
+ org.eclipse.equinox.internal.ip.provider.file;x-internal:=true,
+ org.eclipse.equinox.internal.ip.provider.http;x-internal:=true,
+ org.eclipse.equinox.internal.ip.storage.cm;x-internal:=true,
+ org.eclipse.equinox.internal.ip.storage.file;x-internal:=true
+Content-Id: equinox.provisioning_agent
+Prv-Storage: org.eclipse.equinox.internal.ip.storage.file.FileStorage
+PrvInfo-Providers:
+ org.eclipse.equinox.internal.ip.provider.env.EnvironmentInfoProvider;300,
+ org.eclipse.equinox.internal.ip.provider.http.HttpProvider;200,
+ org.eclipse.equinox.internal.ip.provider.file.FileProvider;100
+Bundle-RequiredExecutionEnvironment: CDC-1.0/Foundation-1.0,
+ J2SE-1.3
+
diff --git a/bundles/org.eclipse.equinox.ip/OSGI-INF/permissions.perm b/bundles/org.eclipse.equinox.ip/OSGI-INF/permissions.perm
new file mode 100644
index 00000000..5a965875
--- /dev/null
+++ b/bundles/org.eclipse.equinox.ip/OSGI-INF/permissions.perm
@@ -0,0 +1 @@
+(java.security.AllPermission "*" "*") \ No newline at end of file
diff --git a/bundles/org.eclipse.equinox.ip/about.html b/bundles/org.eclipse.equinox.ip/about.html
new file mode 100644
index 00000000..40e147d9
--- /dev/null
+++ b/bundles/org.eclipse.equinox.ip/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>January 15, 2008</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>
diff --git a/bundles/org.eclipse.equinox.ip/build.properties b/bundles/org.eclipse.equinox.ip/build.properties
new file mode 100644
index 00000000..9cbab3c1
--- /dev/null
+++ b/bundles/org.eclipse.equinox.ip/build.properties
@@ -0,0 +1,6 @@
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+ .,\
+ about.html
+src.includes = about.html
diff --git a/bundles/org.eclipse.equinox.ip/props.txt b/bundles/org.eclipse.equinox.ip/props.txt
new file mode 100644
index 00000000..1dcfbf44
--- /dev/null
+++ b/bundles/org.eclipse.equinox.ip/props.txt
@@ -0,0 +1,16 @@
+# File is separated on few text and few binary parts. Each text part starts
+# with #[TEXT] while each binary starts with #[BINARY]
+# Lines that starts with # (excluding the these that are with #[TEXT] or #[BINARY])
+# are comments. Lines are trimmed so line " key=value " is equal to "key=value"
+
+# TEXT section contains properties that are to be loaded directly at load phase
+# The format of lines is :
+# <key>=<value>
+#[TEXT]
+#provisioning.spid=testgateway
+#provisioning.reference=http://localhost:80/prvsetup
+
+# BINARY section contains properties that are to be loaded indirectly
+# The format of lines is :
+# <key>=<jar entry where value is stored as byte array>
+#[BINARY] \ No newline at end of file
diff --git a/bundles/org.eclipse.equinox.ip/src/org/eclipse/equinox/internal/ip/ProvisioningInfoProvider.java b/bundles/org.eclipse.equinox.ip/src/org/eclipse/equinox/internal/ip/ProvisioningInfoProvider.java
new file mode 100644
index 00000000..f5ba4f89
--- /dev/null
+++ b/bundles/org.eclipse.equinox.ip/src/org/eclipse/equinox/internal/ip/ProvisioningInfoProvider.java
@@ -0,0 +1,83 @@
+/*******************************************************************************
+ * Copyright (c) 1997-2007 by ProSyst Software GmbH
+ * http://www.prosyst.com
+ * 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:
+ * ProSyst Software GmbH - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.equinox.internal.ip;
+
+import java.util.Dictionary;
+
+import org.osgi.service.provisioning.ProvisioningService;
+
+/**
+ * Provides a set (can be empty) of configuration properties used by the Initial
+ * Provisioning Bundle. The properties obtained by the providers become part of
+ * the Provisioning Dictionary. Arbitrary number of Configuration Loaders could
+ * be registered as services in the OSGi framework. Different providers could
+ * export different set of configuration properties. If a property is provided
+ * by more than one provider, the Provisioning Bundle uses this one, which is
+ * exported by a provider with the higher service ranking.
+ *
+ * @author Avgustin Marinov
+ * @author Pavlin Dobrev
+ * @version 1.0
+ */
+
+public interface ProvisioningInfoProvider {
+
+ /**
+ * This property specifies URL for connecting to the Management Server.
+ */
+ public static final String MANAGER_URL = "equinox.provisioning.manager.url";
+
+ /**
+ * This property specifies the host of the Gateway Manager that Management
+ * Server management agent bundle must connect to. If this property is not
+ * present in the dictionary, then Management Server bundle will listen for
+ * a back end device to push this information to.
+ */
+ public final static String GM_HOST = "equinox.provisioning.gm.host";
+
+ /**
+ * This manifest header determines the packed into the provisioning agent
+ * bundle providers that are to be started.
+ */
+ public final static String PROVIDERS = "PrvInfo-Providers";
+
+ /**
+ * Initializes provider. Give to the provider a reference to
+ * ProvisioningService dictionary. Provider can return properties that are
+ * to be set properties in the provisioning dictionary. It is not necessary
+ * for provider to insert explicitly a property unless it has to be listed
+ * through the <code>Dictionary.keys()</code> method or it evokes action
+ * (as ProvisioningService.PROVISIONIN_REFERENCE).
+ *
+ * @param prvSrv
+ * provisioning service reference
+ * @return the initial data. It can be null.
+ * @throws Exception
+ * on initialization error
+ */
+ public Dictionary init(ProvisioningService prvSrv) throws Exception;
+
+ /**
+ * Gets a property with a supplied key from the provider. This method is
+ * invoked by the Provisioning Agent when
+ * <code>Dictionary.get(propertyKey)</code> is invoked for a propertyKey
+ * which is not already stored in the ProvisioningDictionary. The method is
+ * invoked subsequently on all registered providers ordered by service
+ * ranking until some of them returns value different from <code>null</code>.
+ *
+ * @param propertyKey
+ * the key.
+ * @return the property value or <code>null</code> if there is no such
+ * property.
+ */
+ public Object get(Object propertyKey);
+}
diff --git a/bundles/org.eclipse.equinox.ip/src/org/eclipse/equinox/internal/ip/ProvisioningStorage.java b/bundles/org.eclipse.equinox.ip/src/org/eclipse/equinox/internal/ip/ProvisioningStorage.java
new file mode 100644
index 00000000..1d782076
--- /dev/null
+++ b/bundles/org.eclipse.equinox.ip/src/org/eclipse/equinox/internal/ip/ProvisioningStorage.java
@@ -0,0 +1,48 @@
+/*******************************************************************************
+ * Copyright (c) 1997-2007 by ProSyst Software GmbH
+ * http://www.prosyst.com
+ * 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:
+ * ProSyst Software GmbH - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.equinox.internal.ip;
+
+import java.util.Dictionary;
+
+/**
+ * Provides persistent storage for the Initial Provisioning Dictionary. This
+ * service is used by the Provisioning Agent to store the provisioning data.
+ *
+ * @author Avgustin Marinov, e-mail: a_marinov@prosyst.bg
+ * @author Pavlin Dobrev
+ * @version 1.0
+ */
+
+public interface ProvisioningStorage {
+
+ /**
+ * This method is invoked by Provisioning Agent on startup. The storage
+ * returns the stored data. After that the provisioning service is
+ * responsible to put the data into the provisioning service dictionary.
+ *
+ * @return the stored info
+ * @throws Exception
+ * an exception if I/O error occurs
+ */
+ public Dictionary getStoredInfo() throws Exception;
+
+ /**
+ * This method is invoked by provisioning service on provisioning data
+ * update. The storage must store the data.
+ *
+ * @param provisioningData
+ * Provisioning Data dictionary.
+ * @throws Exception
+ * if the data cannot be stored
+ */
+ public void store(Dictionary provisioningData) throws Exception;
+}
diff --git a/bundles/org.eclipse.equinox.ip/src/org/eclipse/equinox/internal/ip/dscagent/DiscoveryAgent.java b/bundles/org.eclipse.equinox.ip/src/org/eclipse/equinox/internal/ip/dscagent/DiscoveryAgent.java
new file mode 100644
index 00000000..c6c9ca41
--- /dev/null
+++ b/bundles/org.eclipse.equinox.ip/src/org/eclipse/equinox/internal/ip/dscagent/DiscoveryAgent.java
@@ -0,0 +1,269 @@
+/*******************************************************************************
+ * Copyright (c) 1997-2007 by ProSyst Software GmbH
+ * http://www.prosyst.com
+ * 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:
+ * ProSyst Software GmbH - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.equinox.internal.ip.dscagent;
+
+import java.io.IOException;
+import java.io.InterruptedIOException;
+import java.net.*;
+import java.util.Dictionary;
+import org.eclipse.equinox.internal.ip.ProvisioningInfoProvider;
+import org.eclipse.equinox.internal.ip.impl.Log;
+import org.eclipse.equinox.internal.ip.impl.ProvisioningAgent;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceReference;
+import org.osgi.service.provisioning.ProvisioningService;
+
+/**
+ * Agent who make FW available for UDM multicast discovery. It joins
+ * provisioning agent to a MulticastSocket and waits for ping replies. The
+ * response contains data that describes gateway. HTTP port is determined using
+ * next algorithm: <BR>
+ * <OL>
+ * <LI>If <I>"equinox.provisioning.gwhttp.port"</I> property is set it is used
+ * for HTTP port value.</LI>
+ * <LI>Else if there has <I>org.osgi.service.HttpService</I> is registered and
+ * the default such service has registration property "openPort", value of this
+ * property is assumed as port. </LI>
+ * <LI>Else HTTP port is assumed to be "80" (the default HTTP port).</LI>
+ * </OL>
+ *
+ * @author Avgustin Marinov
+ * @author Pavlin Dobrev
+ * @version 1.0
+ */
+
+public class DiscoveryAgent implements Runnable {
+
+ /**
+ * This property can be used when HTTP service is not a prosyst's
+ * implementation or HTTP is not always, which gives a port with
+ * registration property "openPort", available.
+ */
+ public static final String HTTP_PORT = "equinox.provisioning.gwhttp.port";
+
+ /**
+ * This property can be used when HTTPS service is not a prosyst's
+ * implementation, HTTPS is old prosyst's https implementation, or http is
+ * not always, which gives a port with registration property
+ * "secureOpenPort", or HTTPS is not always available.
+ */
+ public static final String HTTPS_PORT = "equinox.provisioning.gwhttps.port";
+
+ /**
+ * Packet Timeout
+ */
+ public static final String TIMEOUT = "equinox.provisioning.packet.timeout";
+
+ /**
+ * Separator used in string representing gateway. It separates different
+ * parts of that string.
+ */
+ public static final char SEPARATOR = '#';
+
+ /**
+ * The String that corresponds to lack of sPID.
+ */
+ public static final String NULL = new String(new byte[] {1});
+
+ /** Reference to provisioning agent. */
+ private ProvisioningAgent prvAgent;
+
+ /** If discoverer service is active. */
+ private boolean active = true;
+
+ // Net staff
+ /** The multicast socket. */
+ private MulticastSocket mcsocket;
+ /** The group. */
+ private InetAddress group;
+
+ /**
+ * Bundles context used for determining of HTTP port in ProSyst HTTPS
+ * Service Implementation.
+ */
+ private BundleContext bc;
+
+ /**
+ * Constructs instance of Discovery agent.
+ *
+ * @param address
+ * address of multicast host.
+ * @param port
+ * port of multicast host.
+ * @param bc
+ * bundle context used to be accessed framework.
+ * @param prvAgent
+ * the provisioning agent
+ * @throws UnknownHostException
+ * when address cannot be resolved
+ * @throws IOException
+ * on I/O error, when accessing the given address
+ */
+ public DiscoveryAgent(String address, int port, BundleContext bc, ProvisioningAgent prvAgent) throws UnknownHostException, IOException {
+ group = InetAddress.getByName(address);
+ mcsocket = new MulticastSocket(port);
+ this.bc = bc;
+ this.prvAgent = prvAgent;
+ mcsocket.joinGroup(group);
+ mcsocket.setSoTimeout(ProvisioningAgent.getInteger(TIMEOUT, 10000));
+ Log.debug("Discovery Agent has joined to multicast socket " + address + ":" + port + ".");
+ }
+
+ /**
+ * Until close() method is invoked this method accepts packages broadcasted
+ * to multicast host.
+ */
+ public void run() {
+ byte[] buffer = new byte[256];
+ DatagramPacket request = new DatagramPacket(buffer, buffer.length);
+ Log.debug("Discovery Agent starting listening.");
+ int errors = 0;
+ while (active) {
+ try {
+ mcsocket.receive(request);
+ /* It is ping send by the backend discoverer */
+ if ("equinox.provisioning.ping".equals(new String(request.getData(), 0, request.getLength()))) {
+ byte[] data = getResponse();
+ if (data != null) {
+ DatagramPacket response = new DatagramPacket(data, data.length, group, request.getPort());
+ /* response.setData(data); */
+ mcsocket.send(response);
+ }
+ }
+ request.setLength(buffer.length); /* Restore packet length */
+ } catch (InterruptedIOException _) {
+ } catch (IOException e) {
+ if (errors++ > 5) {
+ Log.debug("Seventh unexpected exception. Discoverer will be closed!", e);
+ return;
+ }
+ }
+ }
+ }
+
+ /**
+ * Closes discoverer agent
+ */
+ public void close() {
+ try {
+ active = false;
+ mcsocket.leaveGroup(group);
+ mcsocket.close();
+ } catch (Exception e) {
+ Log.debug(e);
+ }
+ }
+
+ /**
+ * Encodes some valuable gateways parameters into string. The format is as
+ * follows:<BR>
+ * <I>&lt;spid&gt;#&lt;host&gt;#&lt;http port&gt;#&lt;ready&gt;#&lt;others
+ * info&gt;</I><BR>
+ * where:<BR>
+ * <OL>
+ * <LI><I>sPID</I> is service platform id</LI>
+ * <LI><I>host</I> is service platform host</LI>
+ * <LI><I>HTTP port</I> is service platform HTTP port</LI>
+ * <LI><I>ready</I> is service platform is ready with deploying management
+ * agent bundle</LI>
+ * <LI><I>others info</I> is service platform others info in format:
+ * <I>{&lt;key0&gt;=&lt;value0&gt;,&lt;key1&gt;=&lt;value1&gt;...}</I></LI>
+ * </OL>
+ *
+ * @return string representation of gateway data as byte array.
+ */
+ private byte[] getResponse() {
+ String httpPort = ProvisioningAgent.bc.getProperty(HTTP_PORT);
+ String httpsPort = ProvisioningAgent.bc.getProperty(HTTPS_PORT);
+
+ // try to determine from service
+ if (httpPort == null || httpsPort == null) {
+ // Not using HttpService.class.getName(), because we don't need to
+ // import
+ // it.
+ ServiceReference sref = bc.getServiceReference("org.osgi.service.http.HttpService");
+ // HTTP Service is available - explore it
+ if (httpPort == null)
+ httpPort = getPortProperty(sref, "openPort");
+ if (httpsPort == null)
+ httpsPort = getPortProperty(sref, "secureOpenPort");
+ }
+
+ Dictionary info = prvAgent.getInformation();
+ if (info == null) {
+ return null;
+ }
+
+ StringBuffer buff = new StringBuffer();
+ String spid = (String) info.get(ProvisioningService.PROVISIONING_SPID);
+ buff.append(spid == null || spid.length() == 0 ? NULL : spid);
+ buff.append(SEPARATOR);
+ String host = null;
+ try {
+ host = InetAddress.getLocalHost().getHostName();
+ } catch (Exception e) {
+ host = "unknown";
+ }
+ buff.append(host);
+ buff.append(SEPARATOR);
+ buff.append(httpPort);
+ buff.append(SEPARATOR);
+ buff.append(httpsPort);
+ buff.append(SEPARATOR);
+ buff.append(info.get(ProvisioningInfoProvider.MANAGER_URL) != null);
+ buff.append(SEPARATOR);
+ buff.append('{');
+ buff.append(ProvisioningService.PROVISIONING_REFERENCE);
+ buff.append('=');
+ buff.append(info.get(ProvisioningService.PROVISIONING_REFERENCE));
+ buff.append(',');
+ buff.append(ProvisioningService.PROVISIONING_START_BUNDLE);
+ buff.append('=');
+ buff.append(info.get(ProvisioningService.PROVISIONING_START_BUNDLE));
+ buff.append('}');
+ buff.append(SEPARATOR);
+ buff.append(getFlag());
+ Log.debug("Discoverer agent sends gw info : " + buff);
+ return buff.toString().getBytes();
+ }
+
+ public int getFlag() {
+ int flag = 0;
+ if (prvAgent.getHttpAllowed()) {
+ try {
+ new URL("http://").openConnection();
+ flag |= 0x01;
+ } catch (Exception e) {
+ }
+ }
+
+ try {
+ new URL("rsh://").openConnection();
+ flag |= 0x02;
+ } catch (Exception e) {
+ }
+
+ try {
+ new URL("https://").openConnection();
+ flag |= 0x04;
+ } catch (Exception e) {
+ }
+
+ return flag;
+ }
+
+ private static final String getPortProperty(ServiceReference ref, String property) {
+ Object ret = ref != null ? ref.getProperty(property) : null;
+ return ret == null ? "-1" : "" + ret;
+ }
+
+}
diff --git a/bundles/org.eclipse.equinox.ip/src/org/eclipse/equinox/internal/ip/impl/Log.java b/bundles/org.eclipse.equinox.ip/src/org/eclipse/equinox/internal/ip/impl/Log.java
new file mode 100644
index 00000000..bf97d6e2
--- /dev/null
+++ b/bundles/org.eclipse.equinox.ip/src/org/eclipse/equinox/internal/ip/impl/Log.java
@@ -0,0 +1,170 @@
+/*******************************************************************************
+ * Copyright (c) 1997-2007 by ProSyst Software GmbH
+ * http://www.prosyst.com
+ * 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:
+ * ProSyst Software GmbH - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.equinox.internal.ip.impl;
+
+import java.io.*;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.util.Dictionary;
+import org.osgi.service.log.LogService;
+import org.osgi.service.provisioning.ProvisioningService;
+
+/**
+ * Simple debug class for provisioning agent bundle.
+ *
+ * @author Avgustin Marinov
+ * @author Pavlin Dobrev
+ * @version 1.0
+ */
+
+public class Log {
+
+ /**
+ * Property for workaround the J9 2.0 problem with Content-Length, the
+ * content length is not set if property is "true"
+ */
+ public static boolean j9workAround;
+
+ /** If debug mode is on. */
+ public static boolean debug;
+ /** If debug mode is on. */
+ public static boolean remoteDebug;
+ /** If to send trace */
+ public static boolean sendTrace;
+
+ /** Message that trace is not send */
+ public static byte[] NO_TRACE = "NoTrace".getBytes();
+
+ /** Reference to provisioning service */
+ public static ProvisioningService prvSrv;
+
+ /** Log stream to receive logged messages. */
+ private static PrintStream logStream;
+
+ /** org.eclipse.equinox.internal.util.ref.Log class to receive logged messages */
+ public static org.eclipse.equinox.internal.util.ref.Log log;
+
+ static {
+ try {
+ String logFile = ProvisioningAgent.bc.getProperty("equinox.provisioning.provisioning.logfile");
+ if (logFile != null && (logFile = logFile.trim()).length() != 0) {
+ File log = new File(logFile);
+ log = log.isDirectory() ? new File(log, "log.txt") : log;
+ logStream = new PrintStream(new FileOutputStream(log), true);
+ }
+ } catch (Exception e) {
+ logStream = null;
+ }
+ }
+
+ /**
+ * Dumps a debug string
+ *
+ * @param obj
+ * a debug string
+ */
+ public static void debug(String obj) {
+ String message = "[PROVISIONING] " + obj;
+ if (debug && logStream != null) {
+ logStream.println(message);
+ } else if (log != null) {
+ log.debug(message, null);
+ }
+ }
+
+ /**
+ * Dumps a debug exception
+ *
+ * @param e
+ * a debugged Throwable
+ */
+ public static void debug(Throwable e) {
+ debug(null, e, remoteDebug);
+ }
+
+ /**
+ * Dumps an exception if debug mode is enabled
+ *
+ * @param e
+ * the exception to dump
+ */
+ public static void debug(String message, Throwable e) {
+ debug(message, e, remoteDebug);
+ }
+
+ private static void debug(String message, Throwable e, boolean sendRemote) {
+ if (debug && logStream != null) {
+ logStream.println("[PROVISIONING] " + message);
+ e.printStackTrace(logStream);
+ } else if (log != null) {
+ log.debug(message, e);
+ }
+ if (sendRemote && e != null && (e.getMessage() == null || e.getMessage().indexOf("Error from Backend") == -1)) {
+ log(message, e);
+ }
+ }
+
+ /**
+ * Logs an exception
+ *
+ * @param e
+ * the exception
+ */
+ private static void log(String message, Throwable e) {
+ debug("Log exception remotely.");
+ String logUrl = null;
+ try {
+ ProvisioningService prvSrv = Log.prvSrv;
+ if (prvSrv != null) {
+ Dictionary info = prvSrv.getInformation();
+ if (info != null) {
+ logUrl = (String) info.get("equinox.provisioning.prv.log");
+ if (logUrl != null) {
+ debug("Log url = " + logUrl);
+ HttpURLConnection conn = (HttpURLConnection) new URL(logUrl).openConnection();
+ conn.setRequestMethod("POST");
+ conn.setRequestProperty("Connection", "close");
+ conn.setRequestProperty(ProvisioningService.PROVISIONING_SPID, info.get(ProvisioningService.PROVISIONING_SPID) + "");
+ conn.setRequestProperty("msg", (message != null ? message + ": " : "") + e.getMessage());
+ conn.setRequestProperty("lvl", LogService.LOG_ERROR + "");
+
+ OutputStream os = new ByteArrayOutputStream();
+ if (sendTrace) {
+ e.printStackTrace(new PrintStream(os));
+ } else {
+ os.write(NO_TRACE);
+ }
+ byte[] stackTrace = ((ByteArrayOutputStream) os).toByteArray();
+ if (!j9workAround) {
+ conn.setRequestProperty("Content-Length", stackTrace.length + "");
+ }
+
+ conn.setDoOutput(true);
+ conn.setDoInput(true);
+ conn.setUseCaches(false);
+ conn.connect();
+
+ os = conn.getOutputStream();
+ os.write(stackTrace);
+ os.flush();
+
+ InputStream is = conn.getInputStream();
+ while (is.read() != -1) {
+ }
+ }
+ }
+ }
+ } catch (Throwable t) {
+ debug("Error while logging remotely to url \"" + logUrl + '"', t, false);
+ }
+ }
+}
diff --git a/bundles/org.eclipse.equinox.ip/src/org/eclipse/equinox/internal/ip/impl/ProvisioningAgent.java b/bundles/org.eclipse.equinox.ip/src/org/eclipse/equinox/internal/ip/impl/ProvisioningAgent.java
new file mode 100644
index 00000000..e31025d8
--- /dev/null
+++ b/bundles/org.eclipse.equinox.ip/src/org/eclipse/equinox/internal/ip/impl/ProvisioningAgent.java
@@ -0,0 +1,1219 @@
+/*******************************************************************************
+ * Copyright (c) 1997-2007 by ProSyst Software GmbH
+ * http://www.prosyst.com
+ * 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:
+ * ProSyst Software GmbH - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.equinox.internal.ip.impl;
+
+import java.io.*;
+import java.lang.reflect.*;
+import java.net.*;
+import java.util.*;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipInputStream;
+import org.eclipse.equinox.internal.ip.ProvisioningInfoProvider;
+import org.eclipse.equinox.internal.ip.ProvisioningStorage;
+import org.eclipse.equinox.internal.util.timer.Timer;
+import org.eclipse.equinox.internal.util.timer.TimerListener;
+import org.osgi.framework.*;
+import org.osgi.service.provisioning.ProvisioningService;
+
+/**
+ * Class implementing provisioning management based on OSGi RFC 27. On start
+ * this <I>BundleActivator</I> gets its manifest headers
+ * <I>ProvisioningAgent.providerS</I> and <I>ProvisioningAgent.STORAGE</I>.
+ * Using them it decides which <I>ProvisioningInfoProvider</I>-s and which
+ * <I>ProvisioningStorage</I> are packed in the bundle. It make instances them.
+ * To be succesfull instantiation they MUST have constructor without parameters.
+ * All packed in bundle providers that implement <I>BundleActivator</I>. Their
+ * methods <I>start(BundleContext)</I> are invoked after instantiation. (On
+ * stop their <I>stop(BundleContext)</I>-s are invoked). ProvisioningStorage is
+ * used for saving provisioning service data. If no such storage thatas are lost
+ * on restart of bundle. Any fail in provider/storage instantiation, providers
+ * casting to <I>BundleActivator</I> ends with exception in bundle start and
+ * bundle will not reach state ACTIVE.
+ *
+ * Also it starts DiscoveryAgent which is prosyst's feature. It is constructed
+ * using values of system properties: "equinox.multicast.host" as host and
+ * "equinox.multicast.port" as port. If one of these properties is null no
+ * instance of DiscoveryAgent is made.
+ *
+ * @author Avgustin Marinov
+ * @author Pavlin Dobrev
+ * @version 1.0
+ */
+
+public class ProvisioningAgent implements BundleActivator, ProvisioningService, ServiceListener, FrameworkListener, TimerListener {
+
+ /**
+ * This manifest header determines the packed into the provisioning agent
+ * bundle storage (if such exists) that is to be setarted.
+ */
+ public final static String STORAGE = "Prv-Storage";
+
+ /**
+ * This manifest header determines URL Handlers packed into the provisioning
+ * agent bundle that are to be started.
+ */
+ public final static String URL_HANDLERS = "Url-Handlers";
+
+ /** This system property that determines multicast host for discoverer agent. */
+ public final static String MULTICAST_HOST = "equinox.provisioning.multicast.host";
+
+ /** This system property taht determines multicast port for discoverer agent. */
+ public final static String MULTICAST_PORT = "equinox.provisioning.multicast.port";
+
+ /**
+ * This system property determines if provisioning can use HTTP transport
+ * (assumed as unsecured) for provisioning data assignments.
+ */
+ public final static String HTTP_ALLOWED = "equinox.provisioning.httpprv.allowed";
+
+ /**
+ * This system property determines if provisioning must waits until the
+ * framework is started.
+ */
+ public final static String WAIT_FW_START = "equinox.provisioning.prv.fwstart";
+
+ /**
+ * This system property determines if provisioning should try to make
+ * provisioning on every start
+ */
+ public final static String REPROVISIONING_ON_START = "equinox.provisioning.reprovision.onstart";
+
+ /**
+ * Close Zip after reading.
+ */
+ public final static String CLOSE_ZIP = "equinox.provisioning.close.zip";
+
+ /**
+ * This system property determines if provisioning agent should print debug
+ * and error information on the console.
+ */
+ public final static String DEBUG = "equinox.provisioning.debug";
+
+ /**
+ * This system property determines if provisioning agent should print debug
+ * and error information on the console.
+ */
+ public final static String REMOTE_DEBUG = "equinox.provisioning.remote.debug";
+
+ /** BundleContext used for interactions with framework. */
+ public static BundleContext bc;
+
+ /** Provisioning data. */
+ private ProvisioningData info;
+ /** Registration of ProvisioningService. */
+ private ServiceRegistration sreg;
+ /**
+ * Configuration store used for data storing. It is null after start if no
+ * storage packed in bundle.
+ */
+ private ProvisioningStorage storage;
+
+ /** If HTTP protocol is allows for provisioning data assignments. */
+ private boolean httpAllowed;
+
+ /**
+ * If storage is inner packed but it is not inner provider, and is
+ * BundleActivator and its start method has been invoked, it must be
+ * stopped.
+ */
+ private boolean destroyStorageOnStop = false;
+
+ /**
+ * Contains providers packed in bundle. It can be null after start if no
+ * providers packed in bundle.
+ */
+ private Vector providers;
+
+ /**
+ * Contains URL handlers packed in bundle. It can be null after start if no
+ * providers packed in bundle.
+ */
+ private Vector urlHandlers;
+
+ /**
+ * DiscoveryAgent instantiated by this object on start(BundleContext). It is
+ * null after start id host or port arenot set in manifest.
+ */
+ private Runnable da;
+
+ /** If there is need to wait for start of framework. */
+ private boolean wfs;
+ /** If the information is added and provistioning assignements are allowed. */
+ private boolean active;
+ /**
+ * Flag if the start data is processed from frameworkEvent or from
+ * start(BundleContext) method.
+ */
+ private boolean startProcessed;
+ /** If to do reprovisiong */
+ private boolean reprovision;
+ /**
+ * If the service is already registered. Used to be avided duplicated
+ * registration on start.
+ */
+ private boolean registered;
+ /** If to close zip after reading */
+ private boolean closeZip;
+
+ // =================================================================================//
+ private static final int PROVISIONING = 1;
+
+ private static final String HAS_FAILED_PROVISIONG = "!@#$_hasFailedPrv";
+
+ private boolean reAfterPrvFailureDisabled;
+ private int a;
+ private int b;
+ private int changePeriod;
+ private int maxPeriod;
+
+ private Timer timer;
+ private long nextProvisioningAfter;
+ private int times;
+ // =================================================================================//
+
+ public final static int ERROR_UNKNOWN = 0;
+ public final static int ERROR_LOAD_STORE_DATA = 1;
+ public final static int ERROR_MALFORMED_URL = 2;
+ public final static int ERROR_IO_EXCEPTION = 3;
+ public final static int ERROR_CORRUPTED_ZIP = 4;
+
+ /**
+ * Invoked by framework on bundle start.
+ *
+ * @param bc
+ * bundle context
+ * @exception java.lang.Exception
+ * mostly when manifest dont match to packed
+ * providers/storage or their implementation do not match
+ * expectations.
+ */
+ public void start(BundleContext bc) throws Exception {
+ ProvisioningAgent.bc = bc;
+ active = false;
+ startProcessed = false;
+ wfs = true;
+ if (bc.getProperty(WAIT_FW_START) != null)
+ if (bc.getProperty(WAIT_FW_START).equals("false"))
+ wfs = false;
+ httpAllowed = true;
+ if (bc.getProperty(HTTP_ALLOWED) != null)
+ if (bc.getProperty(HTTP_ALLOWED).equals("false"))
+ httpAllowed = false;
+ reprovision = getBoolean(ProvisioningAgent.REPROVISIONING_ON_START);
+ closeZip = getBoolean(CLOSE_ZIP);
+
+ // =================================================================================//
+ reAfterPrvFailureDisabled = getBoolean("equinox.provisioning.provisioning.reAfterPrvFailure.disabled");
+ a = getInteger("equinox.provisioning.provisioning.reAfterPrvFailure.a", 60000);
+ b = getInteger("equinox.provisioning.provisioning.reAfterPrvFailure.b", 60000);
+ changePeriod = getInteger("equinox.provisioning.provisioning.reAfterPrvFailure.changePeriod", 300000);
+ maxPeriod = getInteger("equinox.provisioning.provisioning.reAfterPrvFailure.maxperiod", 3600000);
+ nextProvisioningAfter = a;
+ // =================================================================================//
+ Log.j9workAround = getBoolean("equinox.provisioning.j9.2.0.workaround");
+ Log.debug = getBoolean(DEBUG);
+ Log.remoteDebug = getBoolean(REMOTE_DEBUG);
+ Log.sendTrace = getBoolean("equinox.provisioning.send.trace");
+ Log.prvSrv = this;
+
+ org.eclipse.equinox.internal.util.ref.Log log = new org.eclipse.equinox.internal.util.ref.Log(bc);
+ log.setDebug(true); // always log to LogService!
+ log.setPrintOnConsole(Log.debug);
+ Log.log = log;
+
+ try {
+ start0(bc);
+ } catch (Exception exc) {
+ Log.log.close();
+ Log.log = null;
+ throw exc;
+ }
+ }
+
+ private void start0(BundleContext bc) throws Exception {
+ Log.debug("Starting provisioning agent ...");
+
+ Bundle thisBundle = bc.getBundle();
+
+ // Starts URL handlers packed into the provisioning bundle
+ String urlHandlersHeader = (String) thisBundle.getHeaders().get(URL_HANDLERS);
+ if (urlHandlersHeader != null) {
+ StringTokenizer strTok = new StringTokenizer(urlHandlersHeader, ", ");
+ urlHandlers = new Vector(strTok.countTokens());
+ while (strTok.hasMoreTokens()) {
+ try {
+ BundleActivator handler = (BundleActivator) Class.forName(strTok.nextToken().trim()).newInstance();
+ handler.start(bc);
+ urlHandlers.addElement(handler);
+ } catch (Exception e) {
+ Log.debug("Can't instantiate or start a handler!");
+ throw e;
+ }
+ }
+ urlHandlersHeader = null;
+ }
+
+ // Gets inner storage activator class name (if inner storage exists).
+ String storageName = (String) thisBundle.getHeaders().get(STORAGE);
+ if (storageName != null) {
+ storageName.trim();
+ }
+
+ // Registers configuration providers packed into the bundle
+ String providersHeader = (String) thisBundle.getHeaders().get(ProvisioningInfoProvider.PROVIDERS);
+ if (providersHeader != null) {
+ providers = new Vector(5);
+ StringTokenizer strTok = new StringTokenizer(providersHeader, ",; ");
+ while (strTok.hasMoreTokens()) {
+ String providerName = strTok.nextToken().trim();
+ strTok.nextToken(); // Skips ranking
+ Object provider = Class.forName(providerName).newInstance();
+ if (provider instanceof BundleActivator) {
+ ((BundleActivator) provider).start(bc);
+ }
+ if (providerName.equals(storageName)) {
+ storage = (ProvisioningStorage) provider;
+ destroyStorageOnStop = true;
+ }
+ providers.addElement(provider);
+ }
+ }
+
+ if (storage == null && storageName != null && storageName.length() != 0) {
+ try {
+ storage = (ProvisioningStorage) Class.forName(storageName).newInstance();
+ if (storage instanceof BundleActivator) {
+ ((BundleActivator) storage).start(bc);
+ destroyStorageOnStop = true;
+ }
+ } catch (Exception e) {
+ Log.debug("Can't instantiate or start storage \"" + storage + "\"!");
+ throw e;
+ }
+ }
+
+ info = new ProvisioningData();
+
+ if (storage == null) {
+ synchronized (this) {
+ bc.addServiceListener(this, "(|" + '(' + Constants.OBJECTCLASS + '=' + ProvisioningStorage.class.getName() + ")" + '(' + Constants.OBJECTCLASS + '=' + ProvisioningInfoProvider.class.getName() + ")" + '(' + Constants.OBJECTCLASS + '=' + Timer.class.getName() + ')' + ")");
+
+ storage = getStorage();
+ }
+ } else {
+ bc.addServiceListener(this, "(|" + '(' + Constants.OBJECTCLASS + '=' + ProvisioningInfoProvider.class.getName() + ')' + '(' + Constants.OBJECTCLASS + '=' + Timer.class.getName() + ')' + ")");
+ }
+
+ synchronized (this) {
+ if (timer == null) {
+ ServiceReference sRef = bc.getServiceReference(Timer.class.getName());
+ if (sRef != null) {
+ timer = (Timer) bc.getService(sRef);
+ }
+ }
+ }
+
+ if (storage != null) {
+ Log.debug("Loads from " + storage + " storage.");
+ try {
+ Dictionary storedInfo = storage.getStoredInfo();
+ if (storedInfo != null && storedInfo.size() != 0) {
+ info.add(storedInfo);
+ }
+ } catch (Exception e) { // NPE or storage specific exception can be
+ // thrown
+ Log.debug(e);
+ setError(ERROR_LOAD_STORE_DATA, e.toString());
+ if (destroyStorageOnStop) {
+ Log.debug("Warning: the storage could be unavailable!");
+ } else {
+ storage = null;
+ }
+ }
+ }
+
+ if (getHasFailedPrv() && !reAfterPrvFailureDisabled) {
+ reprovision = true;
+ }
+
+ boolean hasLoadedInfo = false;
+
+ ServiceReference[] srefs = bc.getServiceReferences(ProvisioningInfoProvider.class.getName(), null);
+ if (srefs != null) {
+ sort(srefs);
+ for (int i = 0; i < srefs.length; i++) {
+ ProvisioningInfoProvider provider = ((ProvisioningInfoProvider) bc.getService(srefs[i]));
+ try {
+ synchronized (info) {
+ if (!info.providers.contains(provider)) {
+ Log.debug("Loads from " + provider + " provider.");
+ info.providers.addElement(provider);
+ Dictionary toAdd = provider.init(this);
+ if (toAdd != null && toAdd.size() != 0) {
+ String prvref = (String) toAdd.get(ProvisioningService.PROVISIONING_REFERENCE);
+ if (prvref != null && prvref.trim().length() != 0) { // reference
+ // is
+ // changed
+ // by
+ // loader
+ reprovision = true;
+ }
+ info.add(toAdd);
+ hasLoadedInfo = true;
+ }
+ }
+ }
+ } catch (Exception e) {
+ Log.debug(e);
+ }
+ }
+ }
+
+ if (!isFrameworkStarted()) {
+ bc.addFrameworkListener(this);
+ } else {
+ wfs = false;
+ }
+
+ if (hasLoadedInfo) {
+ store();
+ }
+ active = true;
+ processStart();
+
+ // Join GW to a multicast host.
+ try {
+ String host = "225.0.0.0";
+ if (bc.getProperty(MULTICAST_HOST) != null)
+ host = bc.getProperty(MULTICAST_HOST);
+ String port = Integer.toString(getInteger(MULTICAST_PORT, 7777));
+ if (host.length() != 0 && port.length() != 0) {
+ Class dscAgentClass = Class.forName("org.eclipse.equinox.internal.ip.impl.dscagent.DiscoveryAgent");
+ Constructor constr = dscAgentClass.getConstructor(new Class[] {String.class, int.class, BundleContext.class, ProvisioningAgent.class});
+ new Thread(da = (Runnable) constr.newInstance(new Object[] {host, new Integer(Integer.parseInt(port)), bc, this}), "Discovery Agent").start();
+ } // "info" is already initialized
+ } catch (Throwable t) {
+ Log.debug("Can't create discovery agent!");
+ }
+ Log.debug("Provisioning agent started ...");
+ }
+
+ /**
+ * @see org.osgi.framework.BundleActivator#stop(org.osgi.framework.BundleContext)
+ */
+ public void stop(BundleContext bc) throws Exception {
+ Log.debug("Stopping provisionig agent ...");
+
+ if (timer != null) {
+ try {
+ timer.removeListener(this, PROVISIONING);
+ } catch (Throwable _) {
+ }
+ timer = null;
+ }
+
+ registered = false;
+
+ try {
+ bc.removeServiceListener(this);
+ } catch (Exception _) {
+ }
+
+ try {
+ bc.removeFrameworkListener(this);
+ } catch (Exception _) {
+ }
+
+ if (sreg != null) {
+ try {
+ sreg.unregister();
+ } catch (Exception _) {
+ }
+ sreg = null;
+ } // Unregisters ProvisioningService
+
+ if (da != null) {
+ try {
+ Method close = da.getClass().getMethod("close", new Class[] {});
+ close.invoke(da, new Object[0]);
+ } catch (Exception e) {
+ Log.debug(e);
+ }
+ da = null;
+ } // Closes DiscoveryAgent
+
+ if (storage != null) {
+ if (destroyStorageOnStop) {
+ try {
+ if (storage instanceof BundleActivator) {
+ ((BundleActivator) storage).stop(bc);
+ }
+ } catch (Exception e) {
+ Log.debug(e);
+ }
+ destroyStorageOnStop = false;
+ }
+ storage = null;
+ } // Stores data
+
+ if (providers != null) {
+ for (int i = providers.size(); i-- > 0;) {
+ try {
+ ((BundleActivator) providers.elementAt(i)).stop(bc);
+ } catch (Exception e) {
+ Log.debug(e);
+ }
+ }
+ providers = null;
+ } // Stops providers
+
+ if (urlHandlers != null) {
+ for (int i = urlHandlers.size(); i-- > 0;) {
+ try {
+ ((BundleActivator) urlHandlers.elementAt(i)).stop(bc);
+ } catch (Exception e) {
+ Log.debug(e);
+ }
+ }
+ urlHandlers = null;
+ } // Stops providers
+
+ info = null;
+ Log.debug("Provisioning agent stopped ...");
+ Log.log.close();
+ Log.log = null;
+ }
+
+ public Dictionary getInformation() {
+ return info;
+ }
+
+ public void setInformation(Dictionary info) {
+ boolean refChanged = info.get(ProvisioningService.PROVISIONING_REFERENCE) != null;
+ synchronized (this.info) {
+ Integer version = (Integer) this.info.get(ProvisioningService.PROVISIONING_UPDATE_COUNT);
+ Integer newVersion = new Integer(version.intValue() + 1);
+ this.info.set(info);
+ incrementUC(newVersion);
+ }
+ modify();
+ updated(refChanged);
+ }
+
+ public void addInformation(Dictionary info) {
+ addInformation(info, null);
+ }
+
+ private static final ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ private static final byte[] buffer = new byte[1024];
+
+ private static byte[] readSream(InputStream is) throws IOException {
+ synchronized (buffer) {
+ baos.reset();
+ int read;
+ while ((read = is.read(buffer, 0, buffer.length)) != -1) {
+ baos.write(buffer, 0, read);
+ }
+ return baos.toByteArray();
+ }
+ }
+
+ private Bundle installBundle(String name, InputStream is) {
+ Bundle bundle = null;
+ try {
+ bundle = getBundle(name);
+ if (bundle == null) { /* install the bundle */
+ if (Log.debug)
+ Log.debug("Installing management bundle '" + name + "'");
+ bundle = bc.installBundle(name, is);
+ } else { /* just update it */
+ if (Log.debug)
+ Log.debug("Updating management bundle '" + name + "'");
+ bundle.update(is);
+ }
+ } catch (Throwable t) {
+ setHasFailedPrv(true);
+ Log.debug("WARNING: Failed to install management bundle '" + name + "'", t);
+ }
+ return bundle;
+ }
+
+ public void addInformation(ZipInputStream zis) {
+ Log.debug("Add Information form ZIS.");
+ Dictionary info = new Hashtable(5);
+ Vector bundlesToStart = new Vector(5);
+ try {
+ ZipEntry ze;
+
+ while ((ze = zis.getNextEntry()) != null) {
+ /* read type */
+ byte[] extra = ze.getExtra();
+ String type = extra == null ? null : new String(extra).toLowerCase();
+ /* read name */
+ String name = ze.getName();
+ if (name.charAt(0) == '/')
+ name = name.substring(1);
+
+ if (Log.debug) {
+ Log.debug("Processing entry '" + name + "' of type " + type);
+ }
+
+ /* process entry */
+ if (MIME_BUNDLE.equals(type)) {
+ installBundle(name, new ISWrapper(zis));
+ } else if (MIME_BYTE_ARRAY.equals(type)) {
+ info.put(name, readSream(zis));
+ } else if (MIME_STRING.equals(type)) {
+ String value = getUTF8String(readSream(zis));
+ info.put(name, value);
+ /*
+ * FIXME: actually there can be only ONE key of that type! -
+ * so why using vector
+ */
+ if (PROVISIONING_START_BUNDLE.equals(name)) {
+ grantAllPermissions(value);
+ bundlesToStart.addElement(value);
+ }
+ } else if (MIME_BUNDLE_URL.equals(type)) {
+ String value = getUTF8String(readSream(zis));
+ installBundle(name, new URL(value).openStream());
+ } else {
+ this.info.setError(ERROR_CORRUPTED_ZIP, "Unknown MIME type (" + type + ") for entry '" + name + "'");
+ setHasFailedPrv(true);
+ }
+ zis.closeEntry();
+ }
+ } catch (Throwable e) {
+ this.info.setError(ERROR_CORRUPTED_ZIP, e.toString());
+ Log.debug("Error reading provisioning package", e);
+ setHasFailedPrv(true);
+ }
+
+ /* close the zip file */
+ if (closeZip) {
+ try {
+ zis.close();
+ } catch (Exception _) {
+ }
+ }
+
+ /* update info and start all required bundles */
+ addInformation(info, bundlesToStart); // bundle should
+ }
+
+ public void serviceChanged(ServiceEvent se) {
+ Object service = bc.getService(se.getServiceReference());
+ if (service instanceof ProvisioningStorage) {
+ if (se.getType() == ServiceEvent.REGISTERED) {
+ synchronized (this) {
+ if (storage == null) { // If there is a storage it won't be
+ // replaced.
+ storage = (ProvisioningStorage) service;
+ } else {
+ return;
+ }
+ }
+ try {
+ Object oldUC = info.get(ProvisioningService.PROVISIONING_UPDATE_COUNT);
+ int iOldUC = 0;
+ if (oldUC != null && oldUC instanceof Integer) {
+ iOldUC = ((Integer) oldUC).intValue();
+ }
+
+ Dictionary toAdd = storage.getStoredInfo();
+ Object newUC = toAdd.get(ProvisioningService.PROVISIONING_UPDATE_COUNT);
+ int iNewUC = 0;
+ if (newUC != null && newUC instanceof Integer) {
+ iNewUC = ((Integer) newUC).intValue();
+ }
+
+ boolean refChanged = toAdd.get(ProvisioningService.PROVISIONING_REFERENCE) != null && (iNewUC == 0 || reprovision);
+
+ boolean increment = iNewUC > iOldUC; // In this case it
+ // is assummed that
+ // is most probably
+ // that this
+ // is the original version but storage is started after the
+ // provisioning bundle.
+
+ synchronized (info) {
+ info.set(toAdd);
+ if (increment) {
+ incrementUC(new Integer(iNewUC));
+ modify();
+ }
+ }
+
+ updated(refChanged);
+ } catch (Exception e) {
+ Log.debug(e);
+ }
+ Log.debug("Storage is available.");
+ } else if (se.getType() == ServiceEvent.UNREGISTERING) {
+ if (storage == bc.getService(se.getServiceReference())) {
+ Log.debug("Storage is removed!");
+ try {
+ storage.store(info);
+ } catch (Exception e) {
+ Log.debug("Can't store provisioning info!", e);
+ }
+ storage = null; // No more than one Storage service should
+ // be registered on the FW
+ }
+ }
+ }
+
+ if (service instanceof ProvisioningInfoProvider) { // a Storage could
+ // be a Provider
+ if (se.getType() == ServiceEvent.REGISTERED) {
+ ProvisioningInfoProvider provider = (ProvisioningInfoProvider) service;
+ Log.debug("Loads from " + provider + " provider.");
+ try {
+ if (!info.providers.contains(provider)) {
+ Dictionary toAdd = provider.init(this);
+ boolean refChanged = false;
+ if (toAdd != null) {
+ String prvref = (String) toAdd.get(ProvisioningService.PROVISIONING_REFERENCE);
+ if (prvref != null && prvref.trim().length() != 0) { // reference
+ // is
+ // changed
+ // by
+ // loader
+ refChanged = true;
+ }
+ }
+ boolean added = true;
+ synchronized (info) {
+ if (!info.providers.contains(provider)) {
+ info.providers.addElement(provider);
+ info.add(toAdd);
+ if (refChanged) {
+ reprovision = true;
+ }
+ Integer version = (Integer) info.get(ProvisioningService.PROVISIONING_UPDATE_COUNT);
+ Integer newVersion = new Integer(version.intValue() + 1);
+ incrementUC(newVersion);
+ } else {
+ added = false;
+ }
+ }
+ if (added) {
+ modify();
+ updated(refChanged);
+ }
+ }
+ } catch (Exception e) {
+ Log.debug(e);
+ }
+ } else if (se.getType() == ServiceEvent.UNREGISTERING) {
+ info.providers.removeElement(service);
+ }
+ }
+
+ if (service instanceof Timer) { // timer is expected to be single
+ // service
+ switch (se.getType()) {
+ case ServiceEvent.REGISTERED : {
+ synchronized (this) {
+ if (timer == null) {
+ timer = (Timer) service;
+ if (getHasFailedPrv() && !reAfterPrvFailureDisabled) {
+ try {
+ timer.notifyAfterMillis(this, nextPrvAfter(), PROVISIONING); // TO DO - Won't be
+ // updated with newer
+ // method - it will not
+ // run on older FW
+ } catch (Exception e) {
+ Log.debug(e);
+ }
+ }
+ }
+ }
+ break;
+ }
+ case ServiceEvent.UNREGISTERING : {
+ timer = null;
+ break;
+ }
+ }
+ }
+ }
+
+ public synchronized void timer(int event) {
+ Log.debug("Timer event " + event);
+ try {
+ switch (event) {
+ case PROVISIONING : {
+ Log.debug("Remake failed provisioning.");
+ if (getHasFailedPrv()) {
+ processPrvAssignment();
+ }
+ break;
+ }
+ }
+ } catch (Exception e) {
+ Log.debug(e);
+ }
+ }
+
+ public void frameworkEvent(FrameworkEvent event) {
+ if (event.getType() == FrameworkEvent.STARTED) {
+ wfs = false;
+ processStart();
+ }
+ }
+
+ public boolean getHttpAllowed() {
+ return httpAllowed;
+ }
+
+ // Synchronize frameworkEvent and start(BundleContext) initial reactions
+ private void processStart() {
+ synchronized (this) {
+ try {
+ Log.debug("Reprovision = " + reprovision + ", update counter = " + info.get(ProvisioningService.PROVISIONING_UPDATE_COUNT) + ", provisioning reference = " + info.get(ProvisioningService.PROVISIONING_REFERENCE));
+ if ((reprovision || ((Integer) info.get(ProvisioningService.PROVISIONING_UPDATE_COUNT)).intValue() == 0) && info.get(ProvisioningService.PROVISIONING_REFERENCE) != null) {
+ if (!startProcessed) {
+ if (processPrvAssignment()) {
+ startProcessed = true;
+ }
+ }
+ }
+ } catch (Throwable t) {
+ Log.debug(t);
+ }
+ }
+
+ synchronized (this) {
+ if (active && !wfs && !registered) {
+ registered = true;
+ } else {
+ return;
+ }
+ }
+ Log.debug("Registering ProvisioningService.");
+ sreg = bc.registerService(ProvisioningService.class.getName(), this, getRegProps());
+ }
+
+ /**
+ * This is called by ProvisioningData when one puts new
+ * <I>ProvisioningService.PROVISIONING_UPDATE_COUNT</I>.
+ *
+ * @param refChanged
+ * if ProvisioningService.PROVISIONING_REFERENCE changed
+ */
+ private void updated(boolean refUpdated) {
+ Log.debug("ProvisioingDictionary updated. Reference updated = " + refUpdated);
+
+ store();
+
+ synchronized (this) {
+ if (refUpdated) {
+ if (!processPrvAssignment()) {
+ reprovision = true;
+ }
+ }
+ }
+ }
+
+ private void store() {
+ if (storage != null) {
+ try {
+ Dictionary info = this.info;
+ if (info != null) {
+ storage.store(info);
+ }
+ } catch (Exception e) {
+ Log.debug(e);
+ }
+ } else {
+ Log.debug("Warning: No storage available.");
+ }
+ }
+
+ private boolean processPrvAssignment() {
+ if (active && !wfs) {
+ new Thread() {
+ public void run() {
+ try {
+ process();
+ } catch (Exception e) {
+ Log.debug(e);
+ }
+ }
+ }.start();
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Make provisioning data assignement to nextRef.
+ *
+ * @param nextRef
+ * next reference.
+ */
+ synchronized void process() {
+ if (info == null)
+ return; // the bundle is stopped
+ setHasFailedPrv(false);
+ String ref = (String) info.get(ProvisioningService.PROVISIONING_REFERENCE);
+ Log.debug("Reference = \"" + ref + '"');
+ if (ref != null && (ref = ref.trim()).length() != 0) {
+ String spid = (String) info.get(ProvisioningService.PROVISIONING_SPID);
+ Log.debug("Setup from \"" + ref + "\", SPID = " + spid);
+
+ if (!httpAllowed) {
+ if (ref.startsWith("http://")) {
+ Log.debug("Won't make setup to " + ref + " because http is forbidden!");
+ setError(ERROR_MALFORMED_URL, "Provisioning reference is a HTTP URL, but non-secure HTTP is forbidden!");
+ setHasFailedPrv(true);
+ return;
+ }
+ }
+
+ if (!ref.startsWith("file:") && ref.indexOf("service_platform_id") == -1) {
+ if (ref.indexOf('?') == -1) {
+ ref += '?';
+ } else {
+ ref += '&';
+ }
+ ref += "service_platform_id" + '=' + URLEncoder.encode(spid == null ? "" : spid);
+ }
+ Log.debug("Setup url = \"" + ref);
+
+ URLConnection conn = null;
+
+ try {
+ URL url = new URL(ref);
+ InputStream is = null;
+
+ try {
+ conn = url.openConnection();
+ if (conn == null) {
+ throw new IOException("Can't open connection to " + url + "!");
+ }
+ conn.setRequestProperty("Connection", "close");
+
+ conn.connect();
+ String error = conn.getHeaderField("error"); // Such
+ // error
+ // message
+ // is not by
+ // specification
+ // and is
+ // returned
+ // by
+ // Provisioining
+ // Service
+ // Backend
+ if (error == null) {
+ if ((conn instanceof HttpURLConnection) && ((HttpURLConnection) conn).getResponseCode() != HttpURLConnection.HTTP_OK) {
+ String errorMsg = "Warning! ResponseCode = " + ((HttpURLConnection) conn).getResponseCode() + "!";
+ Log.debug(errorMsg);
+ setError(ERROR_IO_EXCEPTION, errorMsg);
+ } else {
+ is = conn.getInputStream();
+ }
+ } else {
+ setError(ERROR_IO_EXCEPTION, error);
+ Log.debug("Error from Backend: " + error + "! Setup failed!");
+ }
+ } catch (IOException e) {
+ setError(ERROR_IO_EXCEPTION, e.toString());
+ Log.debug(e);
+ }
+
+ if (is == null) {
+ setHasFailedPrv(true);
+ } else {
+ try {
+ ZipInputStream zis = new ZipInputStream(is);
+ try {
+ addInformation(zis); // the addInformation method
+ // closes stream
+ Log.debug("Setup ended.");
+ } finally {
+ if (!closeZip) {
+ try {
+ zis.close();
+ } catch (Exception _) {
+ }
+ }
+ }
+ } catch (Exception e) {
+ setError(ERROR_CORRUPTED_ZIP, e.toString());
+ setHasFailedPrv(true);
+ Log.debug(e);
+ }
+ }
+ } catch (IOException e) { // new URL ---> MalformedURLException
+ setError(ERROR_MALFORMED_URL, "Invalid Provisioning Reference: " + ref);
+ } finally {
+ if (conn != null && conn instanceof HttpURLConnection) {
+ try {
+ ((HttpURLConnection) conn).disconnect();
+ } catch (Exception _) {
+ }
+ }
+ }
+ }
+
+ if (getHasFailedPrv()) {
+ if (!reAfterPrvFailureDisabled) {
+ try {
+ if (timer != null) {
+ timer.notifyAfterMillis(this, nextPrvAfter(), PROVISIONING); // TO DO - Won't be updated with
+ // newer method - it will not
+ // run on older FW
+ }
+ } catch (Exception e) {
+ Log.debug(e);
+ }
+ }
+ } else {
+ times = 0;
+ nextProvisioningAfter = a;
+ }
+ }
+
+ private synchronized long nextPrvAfter() {
+ times++;
+ if (nextProvisioningAfter < maxPeriod && nextProvisioningAfter * times > changePeriod) {
+ nextProvisioningAfter += b;
+ times = 0;
+ }
+ Log.debug("Next bootstrap after " + nextProvisioningAfter + "ms");
+ return nextProvisioningAfter;
+ }
+
+ // bundlesToStart is null on addInfo from provider/storage, and != null on
+ // add from ZIS
+ // pending error must be cleared only in second case!
+ private void addInformation(Dictionary info, Vector bundlesToStart) {
+ boolean refChanged = info.get(ProvisioningService.PROVISIONING_REFERENCE) != null;
+ synchronized (this.info) {
+ this.info.add(info);
+ Integer version = (Integer) this.info.get(ProvisioningService.PROVISIONING_UPDATE_COUNT);
+ Integer newVersion = new Integer(version.intValue() + 1);
+ incrementUC(newVersion);
+ }
+
+ Log.debug("Bundles to start: " + bundlesToStart);
+ if (bundlesToStart != null) {
+ for (int i = 0; i < bundlesToStart.size(); i++) {
+ Object next = bundlesToStart.elementAt(i);
+ try {
+ if (next instanceof Bundle) {
+ ((Bundle) next).start();
+ } else {
+ Bundle b = getBundle((String) next);
+ if (b != null) {
+ b.start();
+ } else {
+ Log.debug("Can't find '" + next + "' bundle to start it!");
+ }
+ }
+ } catch (Exception e) {
+ Log.debug("Exception while starting " + (next instanceof Bundle ? ((Bundle) next).getLocation() : next), e);
+ setHasFailedPrv(true);
+ return;
+ }
+ }
+
+ clearError();
+ }
+
+ modify();
+ updated(refChanged);
+ }
+
+ private boolean isFrameworkStarted() {
+ if (!wfs)
+ return true;
+ Bundle system = bc.getBundle(0);
+ return system != null ? system.getState() == Bundle.ACTIVE : true;
+ }
+
+ /**
+ * Make management agent bundle deployment. Sets java.security.AllPermission
+ * if PermissionAdmin is available..
+ *
+ * @param maRef
+ * management agent reference.
+ */
+ private void grantAllPermissions(String location) {
+ try {
+ ServiceReference sref = bc.getServiceReference("org.osgi.service.permissionadmin.PermissionAdmin"); // the
+ // org.osgi.service.permissionadmin
+ // is
+ // not
+ // imported
+ // for
+ // R1
+ if (sref != null) {
+ Method method = Class.forName("org.osgi.service.permissionadmin.PermissionAdmin").getMethod("setPermissions", new Class[] {String.class, Class.forName("[Lorg.osgi.service.permissionadmin.PermissionInfo;")});
+ Object[] allPerms = (Object[]) Array.newInstance(Class.forName("org.osgi.service.permissionadmin.PermissionInfo"), 1);
+ Constructor constr = Class.forName("org.osgi.service.permissionadmin.PermissionInfo").getConstructor(new Class[] {String.class, String.class, String.class});
+ allPerms[0] = constr.newInstance(new String[] {"java.security.AllPermission", "", ""});
+ method.invoke(bc.getService(sref), new Object[] {location, allPerms});
+ }
+ } catch (Exception e) {
+ Log.debug(e);
+ }
+ }
+
+ private ProvisioningStorage getStorage() {
+ ServiceReference sref = bc.getServiceReference(ProvisioningStorage.class.getName());
+ return sref != null ? (ProvisioningStorage) bc.getService(sref) : null;
+ }
+
+ private Bundle getBundle(String location) {
+ Bundle[] bundles = bc.getBundles();
+ for (int i = bundles.length; i-- > 0;) {
+ if (location.equalsIgnoreCase(bundles[i].getLocation())) {
+ return bundles[i];
+ }
+ }
+ return null;
+ }
+
+ private void incrementUC(Integer uc) {
+ if (!active) {
+ return;
+ }
+ info.putUC(uc);
+ }
+
+ private void modify() {
+ if (!active || sreg == null) {
+ return;
+ }
+ try {
+ sreg.setProperties(getRegProps());
+ } catch (Exception e) {
+ }
+ }
+
+ private Dictionary getRegProps() {
+ Hashtable prvsprops = new Hashtable(1, 1.0F);
+ prvsprops.put("Vendor", "ProSyst");
+ prvsprops.put(ProvisioningService.PROVISIONING_UPDATE_COUNT, info.get(ProvisioningService.PROVISIONING_UPDATE_COUNT));
+ return prvsprops;
+ }
+
+ private void sort(ServiceReference[] srefs) {
+ for (int i = srefs.length - 1; i > 0; i--) {
+ for (int j = 0; j < i; j++) {
+ if (less(srefs[j + 1], srefs[j])) {
+ ServiceReference temp = srefs[j];
+ srefs[j] = srefs[j + 1];
+ srefs[j + 1] = temp;
+ }
+ }
+ }
+ }
+
+ private boolean less(ServiceReference sref1, ServiceReference sref2) {
+ return getRanking(sref1) < getRanking(sref2);
+ }
+
+ private int getRanking(ServiceReference sref) {
+ Integer ranking = (Integer) sref.getProperty(Constants.SERVICE_RANKING);
+ return ranking == null ? 0 : ranking.intValue();
+ }
+
+ private String getUTF8String(byte[] body) {
+ try {
+ return new String(body, "UTF-8");
+ } catch (Exception _0) {
+ try {
+ return new String(body, "UTF8"); // for personal java
+ // problems
+ } catch (Exception _1) {
+ return new String(body);
+ }
+ }
+ }
+
+ private void setError(int code, String message) {
+ ProvisioningData data = this.info;
+ if (data == null) {
+ return;
+ }
+
+ data.setError(code, message);
+
+ Integer version = (Integer) data.get(ProvisioningService.PROVISIONING_UPDATE_COUNT);
+ Integer newVersion = new Integer(version.intValue() + 1);
+ info.putUC(newVersion);
+
+ modify();
+ }
+
+ private void clearError() {
+ ProvisioningData data = this.info;
+ if (data == null) {
+ return;
+ }
+
+ data.clearError();
+ }
+
+ private boolean getHasFailedPrv() {
+ return "true".equals(info.get(HAS_FAILED_PROVISIONG));
+ }
+
+ private void setHasFailedPrv(boolean hasFailedPrv) {
+ if (getHasFailedPrv() != hasFailedPrv) {
+ info.putPrivate(HAS_FAILED_PROVISIONG, hasFailedPrv ? "true" : null);
+ store();
+ }
+ }
+
+ private static class ISWrapper extends InputStream {
+
+ private InputStream is;
+
+ ISWrapper(InputStream is) {
+ this.is = is;
+ }
+
+ public int read() throws IOException {
+ return is.read();
+ }
+
+ public int read(byte[] src, int off, int len) throws IOException {
+ return is.read(src, off, len);
+ }
+
+ public void close() {
+ }
+ }
+
+ public static boolean getBoolean(String property) {
+ String prop = (bc != null) ? bc.getProperty(property) : System.getProperty(property);
+ return ((prop != null) && prop.equalsIgnoreCase("true"));
+ }
+
+ public static int getInteger(String property, int defaultValue) {
+ String prop = (bc != null) ? bc.getProperty(property) : System.getProperty(property);
+ if (prop != null) {
+ try {
+ return Integer.decode(prop).intValue();
+ } catch (NumberFormatException e) {
+ //do nothing
+ }
+ }
+ return defaultValue;
+ }
+}
diff --git a/bundles/org.eclipse.equinox.ip/src/org/eclipse/equinox/internal/ip/impl/ProvisioningData.java b/bundles/org.eclipse.equinox.ip/src/org/eclipse/equinox/internal/ip/impl/ProvisioningData.java
new file mode 100644
index 00000000..b66672b7
--- /dev/null
+++ b/bundles/org.eclipse.equinox.ip/src/org/eclipse/equinox/internal/ip/impl/ProvisioningData.java
@@ -0,0 +1,152 @@
+/*******************************************************************************
+ * Copyright (c) 1997-2007 by ProSyst Software GmbH
+ * http://www.prosyst.com
+ * 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:
+ * ProSyst Software GmbH - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.equinox.internal.ip.impl;
+
+import java.util.*;
+import org.eclipse.equinox.internal.ip.ProvisioningInfoProvider;
+import org.osgi.service.provisioning.ProvisioningService;
+
+/**
+ * Provisioning data implementation. This Dictionary do not store a Strings with
+ * length 0 (skips them). Also skips on put values "null".
+ *
+ * @author Avgustin Marinov
+ * @author Pavlin Dobrev
+ * @version 1.0
+ */
+
+public class ProvisioningData extends Hashtable {
+
+ private static final long serialVersionUID = 1L;
+
+ /** List of all providers used for data load. The highest ranking is last. */
+ Vector providers = new Vector();
+
+ public final static String PROVISIONING_ERROR = "provisioning.error";
+
+ /**
+ * Constructs ProvisioningData.
+ *
+ * @param bc
+ * bundle context.
+ * @param agent
+ * ProvisioningAgent.
+ */
+ ProvisioningData() {
+ super.put(ProvisioningService.PROVISIONING_UPDATE_COUNT, new Integer(0));
+ }
+
+ /**
+ * @see java.util.Hashtable#put(java.lang.Object, java.lang.Object)
+ */
+ public Object put(Object key, Object value) {
+ throw newUnsupportedOperation("put");
+ }
+
+ public Object remove(Object key) {
+ throw newUnsupportedOperation("remove");
+ }
+
+ /**
+ * Gets value for key using all providers. The service with highest ranking.
+ *
+ * @see java.util.Hashtable#get(java.lang.Object)
+ */
+ public synchronized Object get(Object key) {
+ Object value = super.get(key);
+ Object emptyCash = null;
+ // if somewhere have "" or byte[0] it will be overiden next ocurence of
+ // the
+ // value is found - for CM set "" when there is not value set
+ boolean hasEmptyString = value != null && isEmpty(value);
+ if (hasEmptyString)
+ emptyCash = value;
+ if (value == null || hasEmptyString) {
+ synchronized (providers) {
+ for (int i = providers.size(); i-- > 0;) {
+ value = ((ProvisioningInfoProvider) providers.elementAt(i)).get(key);
+ if (value != null && !isEmpty(value)) {
+ break;
+ }
+ if (value != null && !hasEmptyString && isEmpty(value)) {
+ if (!hasEmptyString)
+ emptyCash = value;
+ hasEmptyString = true;
+ }
+ }
+ }
+ }
+ if (value == null && hasEmptyString) {
+ value = emptyCash;
+ }
+ return value;
+ }
+
+ void set(Dictionary newData) {
+ super.clear();
+ add(newData);
+ }
+
+ void add(Dictionary toAdd) {
+ if (toAdd == null) {
+ return;
+ }
+ for (Enumeration e = toAdd.keys(); e.hasMoreElements();) {
+ Object key = e.nextElement();
+ if (key instanceof String) {
+ Object value = toAdd.get(key);
+ if (value instanceof String || value instanceof byte[] || (key.equals(ProvisioningService.PROVISIONING_UPDATE_COUNT) && value instanceof Integer)) {
+ if (ProvisioningService.PROVISIONING_REFERENCE.equals(key)) {
+ value = ((String) value).trim();
+ }
+ super.put(key, value);
+ }
+ }
+ }
+ }
+
+ void putUC(Integer uc) {
+ super.put(ProvisioningService.PROVISIONING_UPDATE_COUNT, uc);
+ }
+
+ void putPrivate(String key, String value) {
+ if (value == null) {
+ super.remove(key);
+ } else {
+ super.put(key, value);
+ }
+ }
+
+ void setError(int code, String message) {
+ String value = code + " " + ((message != null) ? message : " No details.");
+ super.put(PROVISIONING_ERROR, value);
+ }
+
+ void clearError() {
+ super.remove(PROVISIONING_ERROR);
+ }
+
+ private final boolean isEmpty(Object value) {
+ return (value instanceof String && ((String) value).length() == 0) || (value instanceof byte[] && ((byte[]) value).length == 0);
+ }
+
+ private final RuntimeException newUnsupportedOperation(String methodName) {
+ RuntimeException e;
+ try {
+ e = (RuntimeException) Class.forName("java.lang.UnsupportedOperationException").newInstance();
+ } catch (Throwable t) {
+ e = new IllegalStateException(methodName + " is unsupported method for provisioning dictionary!");
+ }
+ return e;
+ }
+
+}
diff --git a/bundles/org.eclipse.equinox.ip/src/org/eclipse/equinox/internal/ip/package.html b/bundles/org.eclipse.equinox.ip/src/org/eclipse/equinox/internal/ip/package.html
new file mode 100644
index 00000000..8291ee31
--- /dev/null
+++ b/bundles/org.eclipse.equinox.ip/src/org/eclipse/equinox/internal/ip/package.html
@@ -0,0 +1,9 @@
+<html>
+<body>
+This package contains ProSyst specific interfaces for Provisioning process. Implementation of these interfaces can customize provisioning agent behavior. This can be done by registering on the service gateway one ( or both) of the following interfaces:<br>
+<ul>
+<li>{@link org.eclipse.equinox.ip.ProvisioningInfoProvider <TT>org.eclipse.equinox.ip.ProvisioningInfoProvider</TT>}
+<li>{@link org.eclipse.equinox.ip.ProvisioningStorage <TT>org.eclipse.equinox.ip.ProvisioningStorage</TT>}
+</ul>
+</body>
+</html> \ No newline at end of file
diff --git a/bundles/org.eclipse.equinox.ip/src/org/eclipse/equinox/internal/ip/provider/BaseProvider.java b/bundles/org.eclipse.equinox.ip/src/org/eclipse/equinox/internal/ip/provider/BaseProvider.java
new file mode 100644
index 00000000..43d4091f
--- /dev/null
+++ b/bundles/org.eclipse.equinox.ip/src/org/eclipse/equinox/internal/ip/provider/BaseProvider.java
@@ -0,0 +1,90 @@
+/*******************************************************************************
+ * Copyright (c) 1997-2007 by ProSyst Software GmbH
+ * http://www.prosyst.com
+ * 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:
+ * ProSyst Software GmbH - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.equinox.internal.ip.provider;
+
+import java.util.Hashtable;
+import org.eclipse.equinox.internal.ip.ProvisioningInfoProvider;
+import org.eclipse.equinox.internal.ip.impl.Log;
+import org.eclipse.equinox.internal.ip.impl.ProvisioningAgent;
+import org.osgi.framework.*;
+
+/**
+ * Base class for inner providers. Implements their registering and
+ * unregistering as services, their common debug.
+ *
+ * @author Avgustin Marinov
+ * @author Pavlin Dobrev
+ * @version 1.0
+ */
+public class BaseProvider implements BundleActivator {
+
+ /** Service Registration of ConfigurationLoader service. */
+ private ServiceRegistration reg;
+
+ /**
+ * Invoked from ProvisioningAgent if provider is packed in provisioning
+ * agent bundle or by FW when it is packed as standalone bundle. Registers
+ * itself as ProvisioningInfoProvider service with
+ * <I>Constants.SERVICE_RANKING</I> get from manifest. Puts in provisioning
+ * dictionary entire stored data.
+ *
+ * @see org.osgi.framework.BundleActivator#start(org.osgi.framework.BundleContext)
+ */
+ public void start(BundleContext bc) throws Exception {
+ Log.debug = ProvisioningAgent.getBoolean("equinox.provisioning.debug");
+ String providers = (String) bc.getBundle().getHeaders().get(ProvisioningInfoProvider.PROVIDERS);
+
+ if (providers != null) {
+ String className = this.getClass().getName();
+ int index = (providers = providers.trim()).indexOf(className);
+ if (index != -1) {
+ index += className.length();
+ index = providers.indexOf(';', index);
+ if (index != -1) {
+ int end = providers.indexOf(',', index);
+ if (end == -1) {
+ end = providers.length();
+ }
+ Integer ranking = null;
+ try {
+ ranking = new Integer(providers.substring(index + 1, end).trim());
+ } catch (NumberFormatException nfe) {
+ throw new Exception("Bad \"" + ProvisioningInfoProvider.PROVIDERS + "\" header format in manifest! " + toString() + "'s ranking \"" + providers.substring(index + 1, end).trim() + "\" is not valid integer!");
+ }
+
+ Log.debug("Registers " + this + " provider with ranking = " + ranking + ".");
+ Hashtable props = new Hashtable(1, 1.0F);
+ props.put(Constants.SERVICE_RANKING, ranking);
+ reg = bc.registerService(ProvisioningInfoProvider.class.getName(), this, props);
+ return;
+ }
+ }
+ }
+ throw new Exception("Bad \"" + ProvisioningInfoProvider.PROVIDERS + "\" header format in manifest! Loader " + toString() + " can't be loaded!");
+ }
+
+ /**
+ * Invoked from ProvisioningAgent if provider is packed in provisioning
+ * agent bundle or by FW when it is packed as standalone bundle. Unregister
+ * service.
+ *
+ * @see org.osgi.framework.BundleActivator#stop(org.osgi.framework.BundleContext)
+ */
+ public void stop(BundleContext bc) {
+ if (reg != null) {
+ try {
+ reg.unregister();
+ } catch (Exception _) {
+ }
+ }
+ }
+}
diff --git a/bundles/org.eclipse.equinox.ip/src/org/eclipse/equinox/internal/ip/provider/env/EnvironmentInfoProvider.java b/bundles/org.eclipse.equinox.ip/src/org/eclipse/equinox/internal/ip/provider/env/EnvironmentInfoProvider.java
new file mode 100644
index 00000000..17667d78
--- /dev/null
+++ b/bundles/org.eclipse.equinox.ip/src/org/eclipse/equinox/internal/ip/provider/env/EnvironmentInfoProvider.java
@@ -0,0 +1,127 @@
+/*******************************************************************************
+ * Copyright (c) 1997-2007 by ProSyst Software GmbH
+ * http://www.prosyst.com
+ * 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:
+ * ProSyst Software GmbH - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.equinox.internal.ip.provider.env;
+
+import java.util.*;
+import org.eclipse.equinox.internal.ip.ProvisioningInfoProvider;
+import org.eclipse.equinox.internal.ip.impl.Log;
+import org.eclipse.equinox.internal.ip.impl.ProvisioningAgent;
+import org.eclipse.equinox.internal.ip.provider.BaseProvider;
+import org.osgi.framework.BundleContext;
+import org.osgi.service.provisioning.ProvisioningService;
+
+/**
+ * Implements ConfiguratorLoader. Reads from system properties and
+ * BundleContext. Acts as provider.
+ *
+ * @author Avgustin Marinov,
+ * @author Pavlin Dobrev
+ * @version 1.0
+ */
+
+public class EnvironmentInfoProvider extends BaseProvider implements ProvisioningInfoProvider {
+
+ /**
+ * This is a key for property that points if manual setting of info is
+ * allowed.
+ */
+ public static final String MANUAL_SUPPORT = "equinox.provisioning.env.provider.allowed";
+
+ /**
+ * This is a system properties key that points that the system properties
+ * starting with this key should be pushed into ProvisioningService If value
+ * for the key is not set or is "" no system properties are pushed. If "*"
+ * all are pushed. Else -> only the properties with key started with the
+ * PUSH_STARTING_WITH are pushed.
+ */
+ public static final String PUSH_STARTING_WITH = "equinox.provisioning.env.provider.push.starting.with";
+
+ /** Properties that are to be loaded into dictionary. */
+ private static final String[] props = {ProvisioningService.PROVISIONING_REFERENCE};
+
+ private BundleContext bc;
+
+ /**
+ * If manual support is available starts it.
+ *
+ * @see org.eclipse.equinox.internal.ip.impl.provider.BaseProvider#start(org.osgi.framework.BundleContext)
+ */
+ public void start(BundleContext bc) throws Exception {
+ boolean manualsupport = true;
+ if (bc.getProperty(MANUAL_SUPPORT) != null)
+ if (bc.getProperty(MANUAL_SUPPORT).equals("false"))
+ manualsupport = false;
+ if (!manualsupport) {
+ Log.debug(this + " is not an allowed provider.");
+ return;
+ }
+ this.bc = bc;
+ super.start(bc);
+ }
+
+ /**
+ * @see org.eclipse.equinox.internal.ip.ProvisioningInfoProvider#init(org.osgi.service.provisioning.ProvisioningService)
+ */
+ public Dictionary init(ProvisioningService prvSrv) {
+ Dictionary info = new Hashtable();
+ for (int i = props.length; i-- > 0;) {
+ String value = ProvisioningAgent.bc.getProperty(props[i]);
+ if (value != null) {
+ info.put(props[i], value);
+ }
+ }
+ if (ProvisioningAgent.bc.getProperty(PUSH_STARTING_WITH) != null) {
+ String prefix = ProvisioningAgent.bc.getProperty(PUSH_STARTING_WITH).trim();
+ if (prefix.length() != 0) {
+ boolean all = "*".equals(prefix);
+ Dictionary sprops = System.getProperties();
+ for (Enumeration e = sprops.keys(); e.hasMoreElements();) {
+ try {
+ String key = (String) e.nextElement();
+ if (all || key.startsWith(prefix)) {
+ info.put(key, sprops.get(key));
+ }
+ } catch (Exception _) {
+ }
+ }
+ }
+ }
+ return info;
+ }
+
+ /**
+ * Gets system property
+ *
+ * @param key
+ * the key.
+ * @return the value.
+ */
+ public Object get(Object key) {
+ Object value = null;
+ if (key instanceof String) {
+ value = ProvisioningAgent.bc.getProperty((String) key);
+ if (value == null) {
+ value = bc.getProperty((String) key);
+ }
+ }
+ return value;
+ }
+
+ /**
+ * Returns name of this provider.
+ *
+ * @return the name.
+ */
+ public String toString() {
+ return "Environment";
+ }
+}
diff --git a/bundles/org.eclipse.equinox.ip/src/org/eclipse/equinox/internal/ip/provider/file/FileProvider.java b/bundles/org.eclipse.equinox.ip/src/org/eclipse/equinox/internal/ip/provider/file/FileProvider.java
new file mode 100644
index 00000000..38a871cf
--- /dev/null
+++ b/bundles/org.eclipse.equinox.ip/src/org/eclipse/equinox/internal/ip/provider/file/FileProvider.java
@@ -0,0 +1,189 @@
+/*******************************************************************************
+ * Copyright (c) 1997-2007 by ProSyst Software GmbH
+ * http://www.prosyst.com
+ * 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:
+ * ProSyst Software GmbH - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.equinox.internal.ip.provider.file;
+
+import java.io.*;
+import java.util.Dictionary;
+import java.util.Hashtable;
+import org.eclipse.equinox.internal.ip.ProvisioningInfoProvider;
+import org.eclipse.equinox.internal.ip.impl.Log;
+import org.eclipse.equinox.internal.ip.impl.ProvisioningAgent;
+import org.eclipse.equinox.internal.ip.provider.BaseProvider;
+import org.osgi.framework.BundleContext;
+import org.osgi.service.provisioning.ProvisioningService;
+
+/**
+ * Loads data from inner (in jar) file or from file on hard disk. Only string
+ * "TEXT" data is loaded directly into provisioning dictionary. All binaries are
+ * load into inner dictionary only and are delivered only to when get method is
+ * invoked.
+ *
+ * @author Avgustin Marinov
+ * @author Pavlin Dobrev
+ * @version 1.0
+ */
+
+public class FileProvider extends BaseProvider implements ProvisioningInfoProvider {
+
+ /** Name of configuration file. */
+ public static final String PROPS_FILE = "/props.txt";
+
+ /** This line points start of TEXT section in props.txt file */
+ public static final String TEXT = "#[TEXT]";
+
+ /** This line points start of BINARY section in props.txt file */
+ public static final String BINARY = "#[BINARY]";
+
+ /** This property is used to be determined if to be used this allowed. */
+ public static final String FILE_SUPPORT = "equinox.provisioning.file.provider.allowed";
+
+ /**
+ * This property is used to be determined if to be provider only if this
+ * provider is started for first.
+ */
+ public static final String LOAD_ONCE = "equinox.provisioning.file.load.once";
+
+ /**
+ * This dictionary keeps data that is provided by provider but is not put
+ * into provisioning data.
+ */
+ private Dictionary innerDict = new Hashtable();
+
+ /** File that is used as flag if this is first start of provider. */
+ private File file;
+
+ /**
+ * @see org.eclipse.equinox.internal.ip.impl.provider.BaseProvider#start(org.osgi.framework.BundleContext)
+ */
+ public void start(BundleContext bc) throws Exception {
+ boolean filesupport = true;
+ if (bc.getProperty(FILE_SUPPORT) != null)
+ if (bc.getProperty(FILE_SUPPORT).equals("false"))
+ filesupport = false;
+ if (!filesupport) {
+ Log.debug(this + " is not an allowed provider.");
+ return;
+ }
+
+ file = bc.getDataFile("_mark123");
+ boolean loadonce = true;
+ if (bc.getProperty(LOAD_ONCE) != null)
+ if (bc.getProperty(LOAD_ONCE).equals("false"))
+ loadonce = false;
+ if (file.exists() && loadonce) {
+ Log.debug("File provider have loaded data already!");
+ return;
+ }
+ super.start(bc);
+ }
+
+ /**
+ * Loads data from inner (in jar) file or from file on hard disk. Data from
+ * "props" is put into provisioning data dictionary but others entries are
+ * put into "innerDict" and are available if someone request them.
+ *
+ * @see org.eclipse.equinox.internal.ip.ProvisioningInfoProvider#init(org.osgi.service.provisioning.ProvisioningService)
+ */
+ public Dictionary init(ProvisioningService prvSrv) throws Exception {
+ boolean loadonce = true;
+ if (ProvisioningAgent.bc.getProperty(LOAD_ONCE) != null)
+ if (ProvisioningAgent.bc.getProperty(LOAD_ONCE).equals("false"))
+ loadonce = false;
+ if (file.exists() && loadonce) {
+ Log.debug("File provider have loaded data already!");
+ return null;
+ }
+ String externalFileLocation = ProvisioningAgent.bc.getProperty("equinox.provisioning.file.provider.specfile.location");
+ BufferedReader reader = new BufferedReader(new InputStreamReader(externalFileLocation == null ? FileProvider.class.getResourceAsStream(PROPS_FILE) : new FileInputStream(externalFileLocation)));
+ Dictionary dictionary = new Hashtable(10, 1.0F);
+ try {
+ ByteArrayOutputStream baos = null;
+ byte[] buffer = null;
+ int i;
+
+ String line;
+ boolean stringMode = true;
+ while ((line = reader.readLine()) != null) {
+ if (!(line = line.trim()).startsWith("#")) {
+ if ((i = line.indexOf('=')) != -1) {
+ if (stringMode) {
+ dictionary.put(line.substring(0, i), line.substring(i + 1));
+ } else {
+ if (baos == null) {
+ baos = new ByteArrayOutputStream();
+ buffer = new byte[256];
+ }
+
+ String key = line.substring(0, i);
+ String entryName = line.substring(i + 1);
+ InputStream is;
+ if (externalFileLocation == null) {
+ is = FileProvider.class.getResourceAsStream(entryName);
+ if (is == null && entryName.length() != 0 && entryName.charAt(0) != '/') {
+ is = FileProvider.class.getResourceAsStream('/' + entryName);
+ }
+ } else
+ is = new FileInputStream(entryName);
+ for (; //
+ (i = is.read(buffer, 0, buffer.length)) != -1; //
+ baos.write(buffer, 0, i)) {
+ }
+
+ innerDict.put(key, baos.toByteArray());
+
+ baos.reset();
+ }
+ }
+ } else {
+ if (line.equalsIgnoreCase(TEXT)) {
+ stringMode = true;
+ } else if (line.equalsIgnoreCase(BINARY)) {
+ stringMode = false;
+ }
+ }
+ }
+ if (!file.exists()) {
+ FileOutputStream fos = new FileOutputStream(file);
+ try {
+ fos.write(ZERO_BYTE_ARRAY);
+ } finally {
+ fos.close();
+ }
+ }
+ } finally {
+ reader.close();
+ }
+ return dictionary;
+ }
+
+ private static final byte[] ZERO_BYTE_ARRAY = new byte[] {0};
+
+ /**
+ * Provides value for this key form "innnerDict".
+ *
+ * @param key
+ * the key.
+ * @return the value.
+ */
+ public Object get(Object key) {
+ return innerDict.get(key);
+ }
+
+ /**
+ * Returns name of this provider.
+ *
+ * @return name of provider.
+ */
+ public String toString() {
+ return "File";
+ }
+}
diff --git a/bundles/org.eclipse.equinox.ip/src/org/eclipse/equinox/internal/ip/provider/http/Context.java b/bundles/org.eclipse.equinox.ip/src/org/eclipse/equinox/internal/ip/provider/http/Context.java
new file mode 100644
index 00000000..2b439c6b
--- /dev/null
+++ b/bundles/org.eclipse.equinox.ip/src/org/eclipse/equinox/internal/ip/provider/http/Context.java
@@ -0,0 +1,63 @@
+/*******************************************************************************
+ * Copyright (c) 1997-2007 by ProSyst Software GmbH
+ * http://www.prosyst.com
+ * 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:
+ * ProSyst Software GmbH - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.equinox.internal.ip.provider.http;
+
+import java.net.URL;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.osgi.service.http.HttpContext;
+
+/**
+ * @author Pavlin Dobrev
+ * @version 1.0
+ */
+
+final class Context implements HttpContext {
+
+ private Context() {
+ // prevent instantiation
+ }
+
+ private static Context singleton;
+
+ public static final Context getInstance() {
+ if (singleton == null) {
+ singleton = new Context();
+ }
+ return singleton;
+ }
+
+ /**
+ * @see org.osgi.service.http.HttpContext#getResource(java.lang.String)
+ */
+ public URL getResource(String name) {
+ return this.getClass().getResource(name);
+ }
+
+ /**
+ * @see org.osgi.service.http.HttpContext#getMimeType(java.lang.String)
+ */
+ public String getMimeType(String name) {
+ return null;
+ }
+
+ /**
+ * @see org.osgi.service.http.HttpContext#handleSecurity(javax.servlet.http.HttpServletRequest,
+ * javax.servlet.http.HttpServletResponse)
+ */
+ public boolean handleSecurity(HttpServletRequest request, HttpServletResponse response) {
+ return true;
+ }
+
+}
diff --git a/bundles/org.eclipse.equinox.ip/src/org/eclipse/equinox/internal/ip/provider/http/HttpProvider.java b/bundles/org.eclipse.equinox.ip/src/org/eclipse/equinox/internal/ip/provider/http/HttpProvider.java
new file mode 100644
index 00000000..3531d433
--- /dev/null
+++ b/bundles/org.eclipse.equinox.ip/src/org/eclipse/equinox/internal/ip/provider/http/HttpProvider.java
@@ -0,0 +1,287 @@
+/*******************************************************************************
+ * Copyright (c) 1997-2007 by ProSyst Software GmbH
+ * http://www.prosyst.com
+ * 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:
+ * ProSyst Software GmbH - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.equinox.internal.ip.provider.http;
+
+import java.util.*;
+import javax.servlet.http.*;
+import org.eclipse.equinox.internal.ip.ProvisioningInfoProvider;
+import org.eclipse.equinox.internal.ip.impl.Log;
+import org.eclipse.equinox.internal.ip.impl.ProvisioningAgent;
+import org.eclipse.equinox.internal.ip.provider.BaseProvider;
+import org.osgi.framework.*;
+import org.osgi.service.http.HttpService;
+import org.osgi.service.provisioning.ProvisioningService;
+import org.osgi.service.useradmin.*;
+
+/**
+ * Implements ProvisioningInfoProvider. Allows remote data loading through HTTP.
+ * Acts as dynamic provider. On <I>load(Dictionary)</I> it just get reference
+ * to provisioning data.
+ *
+ * @author Avgustin Marinov
+ * @author Pavlin Dobrev
+ * @version 1.0
+ */
+public class HttpProvider extends BaseProvider implements ProvisioningInfoProvider, ServiceListener {
+
+ /** Alias this servlet will be registered if remote configuration is allowed. */
+ public static final String ALIAS = "/rminit";
+ /**
+ * This is a key for property that points if remote setting of info is
+ * allowed.
+ */
+ public static final String HTTP_SUPPORT = "equinox.provisioning.http.provider.allowed";
+ /**
+ * This system property is used to be determined if to accepts only
+ * HttpServletRequest-s with scheme "https".
+ */
+ public static final String SECURE = "equinox.provisioning.http.provider.secure";
+ /** This system property determines if to requires authentication. */
+ public static final String REQUIRE_AUTH = "equinox.provisioning.require.auth";
+
+ /** If to accepts only HttpServletRequests with scheme "https". */
+ static boolean secure;
+ /** Reference to provisioning service. */
+ ProvisioningService prvSrv;
+ /** Bundle context reference. */
+ private BundleContext bc;
+ /** HTTP service that is used for registration of servlet. */
+ private HttpService http;
+ /** Servlet that is registered. */
+ private HttpServlet servlet = new HttpServletImpl();
+
+ /**
+ * @see org.eclipse.equinox.internal.ip.impl.provider.BaseProvider#start(org.osgi.framework.BundleContext)
+ */
+ public void start(BundleContext bc) throws Exception {
+ boolean httpsupport = true;
+ if (bc.getProperty(HTTP_SUPPORT) != null)
+ if (bc.getProperty(HTTP_SUPPORT).equals("false"))
+ httpsupport = false;
+ if (!httpsupport) {
+ Log.debug(this + " is not an allowed provider.");
+ return;
+ }
+
+ this.bc = bc;
+ super.start(bc);
+ }
+
+ /**
+ * Stops provider. Unregister servlet.
+ *
+ * @see org.eclipse.equinox.internal.ip.impl.provider.BaseProvider#stop(org.osgi.framework.BundleContext)
+ */
+ public void stop(BundleContext bc) {
+ super.stop(bc);
+ if (http != null) {
+ try {
+ http.unregister(ALIAS);
+ } catch (Exception e) {
+ // Not fatal
+ }
+ http = null;
+ }
+ }
+
+ /**
+ * @see org.eclipse.equinox.internal.ip.ProvisioningInfoProvider#init(org.osgi.service.provisioning.ProvisioningService)
+ */
+ public Dictionary init(ProvisioningService prvSrv) {
+ this.prvSrv = prvSrv;
+ secure = false;
+ if (ProvisioningAgent.bc.getProperty(SECURE) != null)
+ if (ProvisioningAgent.bc.getProperty(SECURE).equals("true"))
+ secure = true;
+ try {
+ bc.addServiceListener(this, '(' + "objectClass" + '=' + HttpService.class.getName() + ')');
+ } catch (Exception e) {
+ Log.debug(e);
+ }
+
+ synchronized (this) {
+ if (http == null) {
+ ServiceReference sref = bc.getServiceReference(HttpService.class.getName());
+ if (sref != null) {
+ http = (HttpService) bc.getService(sref);
+ registerServlet();
+ }
+ }
+ }
+ return null; // Do not loads
+ }
+
+ /**
+ * @see org.eclipse.equinox.internal.ip.ProvisioningInfoProvider#get(java.lang.Object)
+ */
+ public Object get(Object key) {
+ return null;
+ }
+
+ /**
+ * Manages servlet (un)registration.
+ *
+ * @see org.osgi.framework.ServiceListener#serviceChanged(org.osgi.framework.ServiceEvent)
+ */
+ public synchronized void serviceChanged(ServiceEvent se) {
+ if (se.getType() == ServiceEvent.REGISTERED) {
+ if (http == null) {
+ http = (HttpService) bc.getService(se.getServiceReference());
+ registerServlet();
+ }
+ } else if (se.getType() == ServiceEvent.UNREGISTERING) {
+ if (http != null) {
+ try {
+ http.unregister(ALIAS);
+ } catch (Exception e) {
+ // Not fatal
+ }
+ http = null;
+ ServiceReference sref = bc.getServiceReference(HttpService.class.getName());
+ if (sref != null) {
+ http = (HttpService) bc.getService(sref);
+ registerServlet();
+ }
+ }
+ }
+ }
+
+ // Registers servlet with ALIAS.
+ private void registerServlet() {
+ try {
+ http.registerServlet(ALIAS, servlet, null, Context.getInstance());
+ Log.debug("Servlet \"" + ALIAS + "\" registered.");
+ } catch (Exception e) {
+ // Servlet won't be registered
+ Log.debug("Error registering HTTP provider servlet!", e);
+ }
+ }
+
+ /**
+ * Return name of provider.
+ *
+ * @return name.
+ */
+ public String toString() {
+ return "Http";
+ }
+
+ /**
+ * Class implements servlet which enables (un)secure remote configuration.
+ */
+ class HttpServletImpl extends HttpServlet {
+
+ private static final long serialVersionUID = 1L;
+
+ // If supports remote configuration
+ /**
+ * @see javax.servlet.http.HttpServlet#doGet(javax.servlet.http.HttpServletRequest,
+ * javax.servlet.http.HttpServletResponse)
+ */
+ public void doGet(HttpServletRequest request, HttpServletResponse response) {
+ Log.debug("doGet ...");
+ if (request.getHeader("Get-Id") == null) {
+ Log.debug("Redirect to doPost.");
+ doPost(request, response);
+ } else {
+ Log.debug("Request for spid.");
+ if (secure && !request.getScheme().equals("https")) {
+ Log.debug("Request to secure HttpLoader must be via https!");
+ response.setHeader("error", "Request to secure HttpLoader must be via https!");
+ response.setStatus(HttpServletResponse.SC_OK);
+ return;
+ }
+ String spid = (String) prvSrv.getInformation().get(ProvisioningService.PROVISIONING_SPID);
+ if (spid != null && spid.length() != 0) {
+ response.setHeader("Gw-Id", spid);
+ }
+ response.setStatus(HttpServletResponse.SC_OK);
+ }
+ }
+
+ // If supports remote configuration
+ /**
+ * @see javax.servlet.http.HttpServlet#doPost(javax.servlet.http.HttpServletRequest,
+ * javax.servlet.http.HttpServletResponse)
+ */
+ public void doPost(HttpServletRequest request, HttpServletResponse response) {
+ Log.debug("doPost ...");
+ if (secure && !request.getScheme().equals("https")) {
+ Log.debug("Request to secure HttpLoader must be via https!");
+ response.setHeader("error", "Request to secure HttpLoader must be via https!");
+ response.setStatus(HttpServletResponse.SC_OK);
+ return;
+ }
+
+ String user = request.getParameter("user");
+ String pass = request.getParameter("pass");
+
+ boolean req_auth = false;
+ if (ProvisioningAgent.bc.getProperty(REQUIRE_AUTH) != null)
+ if (ProvisioningAgent.bc.getProperty(REQUIRE_AUTH).equals("true"))
+ req_auth = true;
+
+ if (!req_auth && !checkAccount(user, pass)) {
+ Log.debug("Incorrect Account!");
+ response.setHeader("error", "Incorrect account!");
+ return;
+ }
+
+ Dictionary info = new Hashtable();
+ Log.debug("HttpLoader loads:");
+ for (Enumeration e = request.getParameterNames(); e.hasMoreElements();) {
+ String name = (String) e.nextElement();
+ if (!"user".equals(name) && !"pass".equals(name)) {
+ String param = request.getParameter(name);
+ if (ProvisioningInfoProvider.GM_HOST.equals(name) && "no".equals(param)) {
+ continue;
+ }
+ Log.debug(" " + name + '=' + param);
+ info.put(name, param);
+ }
+ }
+
+ prvSrv.addInformation(info);
+ response.setStatus(HttpServletResponse.SC_OK);
+ }
+ }
+
+ /*
+ * Returns if account is correct.
+ *
+ * TODO: add user admin to tracked services
+ */
+ boolean checkAccount(String user, String pass) {
+ if (user == null || pass == null) {
+ return false;
+ }
+
+ ServiceReference sref = bc.getServiceReference(UserAdmin.class.getName());
+ if (sref == null) {
+ return false;
+ }
+ UserAdmin userAdmin = (UserAdmin) bc.getService(sref);
+ if (userAdmin != null) {
+ try {
+ User userRole = (User) userAdmin.getRole(user);
+ if (userRole != null && userRole.hasCredential("password", pass)) {
+ Authorization authorization = userAdmin.getAuthorization(userRole);
+ return authorization.hasRole("administration");
+ }
+ } catch (Exception e) {
+ Log.debug(e);
+ }
+ }
+ return false;
+ }
+
+}
diff --git a/bundles/org.eclipse.equinox.ip/src/org/eclipse/equinox/internal/ip/storage/cm/CMStorage.java b/bundles/org.eclipse.equinox.ip/src/org/eclipse/equinox/internal/ip/storage/cm/CMStorage.java
new file mode 100644
index 00000000..1e06e4b3
--- /dev/null
+++ b/bundles/org.eclipse.equinox.ip/src/org/eclipse/equinox/internal/ip/storage/cm/CMStorage.java
@@ -0,0 +1,239 @@
+/*******************************************************************************
+ * Copyright (c) 1997-2007 by ProSyst Software GmbH
+ * http://www.prosyst.com
+ * 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:
+ * ProSyst Software GmbH - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.equinox.internal.ip.storage.cm;
+
+import java.io.IOException;
+import java.util.Dictionary;
+import java.util.Hashtable;
+import org.eclipse.equinox.internal.ip.ProvisioningStorage;
+import org.eclipse.equinox.internal.ip.impl.Log;
+import org.eclipse.equinox.internal.ip.impl.ProvisioningAgent;
+import org.osgi.framework.*;
+import org.osgi.service.cm.*;
+import org.osgi.service.provisioning.ProvisioningService;
+import org.osgi.util.tracker.ServiceTracker;
+
+/**
+ * Implements Storage by using CM.
+ *
+ * @author Avgustin Marinov
+ * @author Pavlin Dobrev
+ * @version 1.0
+ */
+
+public class CMStorage implements ProvisioningStorage, ManagedService, BundleActivator {
+
+ /** PID for Configuration Manager */
+ public static final String PID = "equinox.provisioning.provisioning.pid";
+ /**
+ * This system property is used for determining if to be used this
+ * storage/provider.
+ */
+ public static final String CM_SUPPORT = "equinox.provisioning.cm.support";
+
+ /** Registration as Managed Service. */
+ private ServiceRegistration msSReg;
+ /** Registration as Storage Service. */
+ private ServiceRegistration sSReg;
+
+ /** Tracker for ProvisioningService. */
+ private ServiceTracker prvSrvTracker;
+ /** Tracker for ConfigurationAdmin. */
+ private ServiceTracker cmTracker;
+
+ // /** Initial data data.*/
+ // private Dictionary info;
+ /** BundleContext. */
+ private BundleContext bc;
+
+ /** Counter is used for skipping "own update()-s". */
+ private int counter;
+
+ private boolean infoLoaded;
+ private boolean skipStore;
+
+ private boolean registering;
+
+ /**
+ * Opens tracker an register itself as ManagedService.
+ *
+ * @see org.osgi.framework.BundleActivator#start(org.osgi.framework.BundleContext)
+ */
+ public void start(BundleContext bc) throws Exception {
+ Log.debug = ProvisioningAgent.getBoolean("equinox.provisioning.debug");
+ boolean cmsupport = true;
+ if (ProvisioningAgent.bc.getProperty(CM_SUPPORT) != null)
+ if (ProvisioningAgent.bc.getProperty(CM_SUPPORT).equals("false"))
+ cmsupport = false;
+ if (!cmsupport) {
+ Log.debug(this + " is not supported provider/storage!");
+ return;
+ } // Do not be used as provider or storage
+
+ this.bc = bc;
+ counter = 0;
+ registering = false;
+
+ prvSrvTracker = new ServiceTracker(bc, ProvisioningService.class.getName(), null);
+ prvSrvTracker.open();
+
+ cmTracker = new ServiceTracker(bc, ConfigurationAdmin.class.getName(), null);
+ cmTracker.open();
+
+ Dictionary props = new Hashtable(1, 1.0F);
+ props.put(Constants.SERVICE_PID, PID);
+ msSReg = bc.registerService(ManagedService.class.getName(), this, props);
+ Log.debug("Managed Service Registered.");
+ }
+
+ /**
+ * Closes cmTracker and unregister service.
+ *
+ * @see org.osgi.framework.BundleActivator#stop(org.osgi.framework.BundleContext)
+ */
+ public void stop(BundleContext bc) {
+ Log.debug("Close " + this + '.');
+ bc = null;
+ try {
+ if (sSReg != null) {
+ sSReg.unregister();
+ sSReg = null;
+ }
+ } catch (Exception _) {
+ }
+ try {
+ if (msSReg != null) {
+ msSReg.unregister();
+ msSReg = null;
+ }
+ } catch (Exception _) {
+ }
+
+ prvSrvTracker.close();
+ prvSrvTracker = null;
+
+ cmTracker.close();
+ cmTracker = null;
+ }
+
+ /**
+ * @see org.eclipse.equinox.internal.ip.ProvisioningStorage#getStoredInfo()
+ */
+ public Dictionary getStoredInfo() {
+ try {
+ ConfigurationAdmin cm = (ConfigurationAdmin) cmTracker.getService();
+ if (cm == null) {
+ return null;
+ }
+ Configuration config = cm.getConfiguration(PID);
+ Dictionary info = config.getProperties();
+ infoLoaded = true;
+ return info;
+ } catch (IOException ioe) {
+ Log.debug(ioe);
+ }
+ return null;
+ }
+
+ /**
+ * @see org.eclipse.equinox.internal.ip.ProvisioningStorage#store(java.util.Dictionary)
+ */
+ public void store(Dictionary provisioningData) {
+ try {
+ synchronized (this) {
+ if (skipStore) {
+ skipStore = false;
+ return;
+ }
+ }
+ ConfigurationAdmin cm = (ConfigurationAdmin) cmTracker.getService();
+ if (cm == null) {
+ return;
+ }
+ Configuration config = cm.getConfiguration(PID);
+
+ synchronized (this) {
+ Log.debug("Store data into CM");
+ config.update(provisioningData);
+ counter++;
+ }
+ } catch (IOException e) {
+ // Should be impossible
+ Log.debug(e);
+ }
+ }
+
+ /**
+ * @see org.osgi.service.cm.ManagedService#updated(java.util.Dictionary)
+ */
+ public void updated(Dictionary props) {
+ boolean register = false;
+ synchronized (this) {
+ if (registering) {
+ try {
+ wait();
+ } catch (InterruptedException ioe) {
+ } // Should not happened
+ }
+ if (sSReg == null && bc != null) {
+ registering = true;
+ register = true;
+ }
+ }
+
+ if (register) {
+ try {
+ sSReg = bc.registerService(ProvisioningStorage.class.getName(), this, null);
+ Log.debug(this + " Registered.");
+ } catch (Exception e) {
+ Log.debug(e);
+ }
+ synchronized (this) {
+ registering = false;
+ notifyAll();
+ }
+ return;
+ }
+
+ Log.debug("CM Storage Updated : counter = " + counter);
+ synchronized (this) {
+ if (counter != 0) {
+ counter--;
+ return;
+ } // This is an own update() so one updated() will be skipped
+ }
+
+ if (props == null) {
+ return;
+ }
+
+ ProvisioningService prvSrv = (ProvisioningService) prvSrvTracker.getService();
+ if (prvSrv != null) {
+ synchronized (this) {
+ if (!infoLoaded) {
+ skipStore = true;
+ infoLoaded = true;
+ }
+ }
+ prvSrv.addInformation(props);
+ }
+ }
+
+ /**
+ * Returns name of Storage.
+ *
+ * @return name.
+ */
+ public String toString() {
+ return "CM Storage";
+ }
+}
diff --git a/bundles/org.eclipse.equinox.ip/src/org/eclipse/equinox/internal/ip/storage/file/FileStorage.java b/bundles/org.eclipse.equinox.ip/src/org/eclipse/equinox/internal/ip/storage/file/FileStorage.java
new file mode 100644
index 00000000..9b4cb64a
--- /dev/null
+++ b/bundles/org.eclipse.equinox.ip/src/org/eclipse/equinox/internal/ip/storage/file/FileStorage.java
@@ -0,0 +1,185 @@
+/*******************************************************************************
+ * Copyright (c) 1997-2007 by ProSyst Software GmbH
+ * http://www.prosyst.com
+ * 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:
+ * ProSyst Software GmbH - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.equinox.internal.ip.storage.file;
+
+import java.io.*;
+import java.util.*;
+import java.util.zip.*;
+import org.eclipse.equinox.internal.ip.ProvisioningStorage;
+import org.eclipse.equinox.internal.ip.impl.Log;
+import org.eclipse.equinox.internal.ip.impl.ProvisioningAgent;
+import org.osgi.framework.BundleActivator;
+import org.osgi.framework.BundleContext;
+import org.osgi.service.provisioning.ProvisioningService;
+
+/**
+ * File Storage.
+ *
+ * @author Avgustin Marinov,
+ * @author Pavlin Dobrev
+ * @version 1.0
+ */
+
+public class FileStorage implements ProvisioningStorage, BundleActivator {
+
+ /** Name of data file used for storing configuration. */
+ public static final String FILE_NAME = "_storage.zip";
+
+ /** Bundle context. */
+ private BundleContext bc;
+
+ /**
+ * @see org.osgi.framework.BundleActivator#start(org.osgi.framework.BundleContext)
+ */
+ public void start(BundleContext bc) throws Exception {
+ Log.debug = ProvisioningAgent.getBoolean("equinox.provisioning.debug");
+ this.bc = bc;
+ }
+
+ /**
+ * @see org.osgi.framework.BundleActivator#stop(org.osgi.framework.BundleContext)
+ */
+ public void stop(BundleContext bc) throws Exception {
+ }
+
+ /**
+ * @see org.eclipse.equinox.internal.ip.ProvisioningStorage#getStoredInfo()
+ */
+ public Dictionary getStoredInfo() {
+ FileInputStream fis = null;
+ try {
+ fis = new FileInputStream(bc.getDataFile(FILE_NAME));
+ } catch (Exception e) {
+ return null;
+ }
+ try {
+ Dictionary toAdd = new Hashtable();
+ getInfo(fis, toAdd);
+ fis.close();
+ return toAdd;
+ } catch (Exception e) {
+ Log.debug(e);
+ return null;
+ }
+ }
+
+ /**
+ * @see org.eclipse.equinox.internal.ip.ProvisioningStorage#store(java.util.Dictionary)
+ */
+ public void store(Dictionary dictionary) {
+ try {
+ FileOutputStream fos = new FileOutputStream(bc.getDataFile(FILE_NAME));
+ saveInfo(fos, dictionary);
+ fos.close();
+ } catch (Exception e) {
+ Log.debug(e);
+ }
+ }
+
+ /**
+ * Returns string name of storage.
+ *
+ * @see java.lang.Object#toString()
+ */
+ public String toString() {
+ return "File Storage";
+ }
+
+ /**
+ * Decodes data from input stream and loads it in passed dictionary.
+ *
+ * @param is
+ * input stream in specific format.
+ * @param info
+ * dictionary.
+ */
+ private void getInfo(InputStream is, Dictionary info) {
+ if (is != null) {
+ try {
+ ZipInputStream zis = new ZipInputStream(is);
+ ZipEntry ze;
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ int read;
+ byte[] buff = new byte[256];
+ while ((ze = zis.getNextEntry()) != null) {
+ if ("props.txt".equals(ze.getName())) {
+ BufferedReader reader = new BufferedReader(new InputStreamReader(zis));
+ String line;
+ int index;
+ while ((line = reader.readLine()) != null) {
+ if (!(line = line.trim()).startsWith("#")) {
+ if ((index = line.indexOf("=")) != -1) {
+ String key = line.substring(0, index);
+ if (ProvisioningService.PROVISIONING_UPDATE_COUNT.equals(key)) {
+ int uc = 0;
+ try {
+ uc = Integer.parseInt(line.substring(index + 1).trim());
+ } catch (Exception _) {
+ }
+ info.put(key, new Integer(uc));
+ } else {
+ info.put(key, line.substring(index + 1));
+ }
+ }
+ }
+ }
+ } else {
+ while ((read = zis.read(buff)) != -1) {
+ baos.write(buff, 0, read);
+ }
+ info.put(ze.getName(), baos.toByteArray());
+ baos.reset();
+ }
+ zis.closeEntry();
+ }
+ } catch (Exception e) {
+ Log.debug(e);
+ // What is loaded is loaded.
+ }
+ }
+ }
+
+ /**
+ * Encodes "info" and saves it into an output stream.
+ *
+ * @param os
+ * output stream where to be saved data.
+ */
+ private void saveInfo(OutputStream os, Dictionary info) {
+ try {
+ ZipOutputStream zos = new ZipOutputStream(os);
+ ByteArrayOutputStream strings = new ByteArrayOutputStream();
+ Object key;
+ Object value;
+ for (Enumeration e = info.keys(); e.hasMoreElements();) {
+ key = e.nextElement();
+ value = info.get(key);
+ if (value instanceof String || ProvisioningService.PROVISIONING_UPDATE_COUNT.equals(key)) {
+ strings.write((key + "=" + value + "\r\n").getBytes());
+ } else if (value instanceof byte[]) {
+ ZipEntry ze = new ZipEntry((String) key);
+ zos.putNextEntry(ze);
+ zos.write((byte[]) value);
+ zos.closeEntry();
+ }
+ }
+ ZipEntry ze = new ZipEntry("props.txt");
+ zos.putNextEntry(ze);
+ zos.write(strings.toByteArray());
+ zos.closeEntry();
+ zos.close();
+ } catch (Exception e) {
+ Log.debug(e);
+ // What is load is load.
+ }
+ }
+}

Back to the top