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.util
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.util')
-rw-r--r--bundles/org.eclipse.equinox.util/.classpath7
-rw-r--r--bundles/org.eclipse.equinox.util/.cvsignore1
-rw-r--r--bundles/org.eclipse.equinox.util/.project28
-rw-r--r--bundles/org.eclipse.equinox.util/.settings/org.eclipse.jdt.core.prefs331
-rw-r--r--bundles/org.eclipse.equinox.util/.settings/org.eclipse.jdt.ui.prefs57
-rw-r--r--bundles/org.eclipse.equinox.util/.settings/org.eclipse.pde.core.prefs4
-rw-r--r--bundles/org.eclipse.equinox.util/META-INF/MANIFEST.MF27
-rw-r--r--bundles/org.eclipse.equinox.util/OSGI-INF/permissions.perm1
-rw-r--r--bundles/org.eclipse.equinox.util/about.html28
-rw-r--r--bundles/org.eclipse.equinox.util/build.properties6
-rw-r--r--bundles/org.eclipse.equinox.util/src/org/eclipse/equinox/internal/util/TracerMap.java50
-rw-r--r--bundles/org.eclipse.equinox.util/src/org/eclipse/equinox/internal/util/UtilActivator.java194
-rw-r--r--bundles/org.eclipse.equinox.util/src/org/eclipse/equinox/internal/util/event/EventThread.java310
-rw-r--r--bundles/org.eclipse.equinox.util/src/org/eclipse/equinox/internal/util/event/Queue.java97
-rw-r--r--bundles/org.eclipse.equinox.util/src/org/eclipse/equinox/internal/util/event/SystemListener.java40
-rw-r--r--bundles/org.eclipse.equinox.util/src/org/eclipse/equinox/internal/util/event/package.html1
-rw-r--r--bundles/org.eclipse.equinox.util/src/org/eclipse/equinox/internal/util/hash/HashIntObjNS.java273
-rw-r--r--bundles/org.eclipse.equinox.util/src/org/eclipse/equinox/internal/util/hash/HashIntObjS.java54
-rw-r--r--bundles/org.eclipse.equinox.util/src/org/eclipse/equinox/internal/util/hash/HashLongObjNS.java273
-rw-r--r--bundles/org.eclipse.equinox.util/src/org/eclipse/equinox/internal/util/hash/HashLongObjS.java54
-rw-r--r--bundles/org.eclipse.equinox.util/src/org/eclipse/equinox/internal/util/hash/HashObjIntNS.java295
-rw-r--r--bundles/org.eclipse.equinox.util/src/org/eclipse/equinox/internal/util/hash/HashObjIntS.java54
-rw-r--r--bundles/org.eclipse.equinox.util/src/org/eclipse/equinox/internal/util/hash/HashObjLongNS.java281
-rw-r--r--bundles/org.eclipse.equinox.util/src/org/eclipse/equinox/internal/util/hash/HashObjLongS.java54
-rw-r--r--bundles/org.eclipse.equinox.util/src/org/eclipse/equinox/internal/util/hash/package.html9
-rw-r--r--bundles/org.eclipse.equinox.util/src/org/eclipse/equinox/internal/util/impl/tpt/ServiceFactoryImpl.java86
-rw-r--r--bundles/org.eclipse.equinox.util/src/org/eclipse/equinox/internal/util/impl/tpt/threadpool/Executor.java159
-rw-r--r--bundles/org.eclipse.equinox.util/src/org/eclipse/equinox/internal/util/impl/tpt/threadpool/Job.java106
-rw-r--r--bundles/org.eclipse.equinox.util/src/org/eclipse/equinox/internal/util/impl/tpt/threadpool/ThreadPoolFactoryImpl.java162
-rw-r--r--bundles/org.eclipse.equinox.util/src/org/eclipse/equinox/internal/util/impl/tpt/threadpool/ThreadPoolManagerImpl.java253
-rw-r--r--bundles/org.eclipse.equinox.util/src/org/eclipse/equinox/internal/util/impl/tpt/timer/TimerFactory.java81
-rw-r--r--bundles/org.eclipse.equinox.util/src/org/eclipse/equinox/internal/util/impl/tpt/timer/TimerImpl.java277
-rw-r--r--bundles/org.eclipse.equinox.util/src/org/eclipse/equinox/internal/util/impl/tpt/timer/TimerQueue.java204
-rw-r--r--bundles/org.eclipse.equinox.util/src/org/eclipse/equinox/internal/util/impl/tpt/timer/TimerQueueNode.java170
-rw-r--r--bundles/org.eclipse.equinox.util/src/org/eclipse/equinox/internal/util/pool/ObjectCreator.java22
-rw-r--r--bundles/org.eclipse.equinox.util/src/org/eclipse/equinox/internal/util/pool/ObjectPool.java190
-rw-r--r--bundles/org.eclipse.equinox.util/src/org/eclipse/equinox/internal/util/pool/package.html9
-rw-r--r--bundles/org.eclipse.equinox.util/src/org/eclipse/equinox/internal/util/ref/Log.java819
-rw-r--r--bundles/org.eclipse.equinox.util/src/org/eclipse/equinox/internal/util/ref/LogInterface.java107
-rw-r--r--bundles/org.eclipse.equinox.util/src/org/eclipse/equinox/internal/util/ref/TimerRef.java40
-rw-r--r--bundles/org.eclipse.equinox.util/src/org/eclipse/equinox/internal/util/ref/package.html36
-rw-r--r--bundles/org.eclipse.equinox.util/src/org/eclipse/equinox/internal/util/security/PrivilegedAction.java47
-rw-r--r--bundles/org.eclipse.equinox.util/src/org/eclipse/equinox/internal/util/security/PrivilegedRunner.java173
-rw-r--r--bundles/org.eclipse.equinox.util/src/org/eclipse/equinox/internal/util/security/SecurityUtil.java756
-rw-r--r--bundles/org.eclipse.equinox.util/src/org/eclipse/equinox/internal/util/security/package.html13
-rw-r--r--bundles/org.eclipse.equinox.util/src/org/eclipse/equinox/internal/util/threadpool/ThreadContext.java35
-rw-r--r--bundles/org.eclipse.equinox.util/src/org/eclipse/equinox/internal/util/threadpool/ThreadPoolFactory.java42
-rw-r--r--bundles/org.eclipse.equinox.util/src/org/eclipse/equinox/internal/util/threadpool/ThreadPoolManager.java65
-rw-r--r--bundles/org.eclipse.equinox.util/src/org/eclipse/equinox/internal/util/threadpool/package.html165
-rw-r--r--bundles/org.eclipse.equinox.util/src/org/eclipse/equinox/internal/util/timer/Timer.java190
-rw-r--r--bundles/org.eclipse.equinox.util/src/org/eclipse/equinox/internal/util/timer/TimerListener.java36
-rw-r--r--bundles/org.eclipse.equinox.util/src/org/eclipse/equinox/internal/util/timer/package.html174
52 files changed, 6946 insertions, 0 deletions
diff --git a/bundles/org.eclipse.equinox.util/.classpath b/bundles/org.eclipse.equinox.util/.classpath
new file mode 100644
index 000000000..ce0c7a5d4
--- /dev/null
+++ b/bundles/org.eclipse.equinox.util/.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.util/.cvsignore b/bundles/org.eclipse.equinox.util/.cvsignore
new file mode 100644
index 000000000..ba077a403
--- /dev/null
+++ b/bundles/org.eclipse.equinox.util/.cvsignore
@@ -0,0 +1 @@
+bin
diff --git a/bundles/org.eclipse.equinox.util/.project b/bundles/org.eclipse.equinox.util/.project
new file mode 100644
index 000000000..e0c4bd69a
--- /dev/null
+++ b/bundles/org.eclipse.equinox.util/.project
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>org.eclipse.equinox.util</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.util/.settings/org.eclipse.jdt.core.prefs b/bundles/org.eclipse.equinox.util/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 000000000..d304116cd
--- /dev/null
+++ b/bundles/org.eclipse.equinox.util/.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.util/.settings/org.eclipse.jdt.ui.prefs b/bundles/org.eclipse.equinox.util/.settings/org.eclipse.jdt.ui.prefs
new file mode 100644
index 000000000..023a27a64
--- /dev/null
+++ b/bundles/org.eclipse.equinox.util/.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.util/.settings/org.eclipse.pde.core.prefs b/bundles/org.eclipse.equinox.util/.settings/org.eclipse.pde.core.prefs
new file mode 100644
index 000000000..5ead3a631
--- /dev/null
+++ b/bundles/org.eclipse.equinox.util/.settings/org.eclipse.pde.core.prefs
@@ -0,0 +1,4 @@
+#Fri Mar 30 10:11:50 EEST 2007
+eclipse.preferences.version=1
+pluginProject.extensions=false
+resolve.requirebundle=false
diff --git a/bundles/org.eclipse.equinox.util/META-INF/MANIFEST.MF b/bundles/org.eclipse.equinox.util/META-INF/MANIFEST.MF
new file mode 100644
index 000000000..0d37e6b92
--- /dev/null
+++ b/bundles/org.eclipse.equinox.util/META-INF/MANIFEST.MF
@@ -0,0 +1,27 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-SymbolicName: org.eclipse.equinox.util
+Bundle-Name: Equinox Util Bundle
+Bundle-Version: 0.1.0.qualifier
+Bundle-Vendor: Eclipse
+Bundle-Activator: org.eclipse.equinox.internal.util.UtilActivator
+Bundle-Description: The Equinox Util Bundle contains services to facilitate bundle developers in their programming, and to lighten resource usage at runtime.
+Import-Package:
+ org.osgi.framework;version="1.3",
+ org.osgi.service.cm;version="1.0",
+ org.osgi.service.log;version="1.0.0",
+ org.osgi.util.tracker;version="1.2"
+Export-Package:
+ org.eclipse.equinox.internal.util;x-internal:=true,
+ org.eclipse.equinox.internal.util.event;version="1.0";x-friends:="org.eclipse.equinox.ds",
+ org.eclipse.equinox.internal.util.hash;version="1.0";x-friends:="org.eclipse.equinox.ds,org.eclipse.equinox.io,org.eclipse.equinox.wireadmin",
+ org.eclipse.equinox.internal.util.impl.tpt;x-internal:=true,
+ org.eclipse.equinox.internal.util.impl.tpt.threadpool;x-internal:=true,
+ org.eclipse.equinox.internal.util.impl.tpt.timer;x-internal:=true,
+ org.eclipse.equinox.internal.util.pool;version="1.0";x-friends:="org.eclipse.equinox.ds,org.eclipse.equinox.io",
+ org.eclipse.equinox.internal.util.ref;version="1.0";x-friends:="org.eclipse.equinox.ds,org.eclipse.equinox.io,org.eclipse.equinox.ip,org.eclipse.equinox.wireadmin",
+ org.eclipse.equinox.internal.util.security;x-internal:=true,
+ org.eclipse.equinox.internal.util.threadpool;version="1.0";x-friends:="org.eclipse.equinox.ds",
+ org.eclipse.equinox.internal.util.timer;version="1.0";x-friends:="org.eclipse.equinox.ds,org.eclipse.equinox.ip"
+Bundle-RequiredExecutionEnvironment: CDC-1.0/Foundation-1.0,
+ J2SE-1.3
diff --git a/bundles/org.eclipse.equinox.util/OSGI-INF/permissions.perm b/bundles/org.eclipse.equinox.util/OSGI-INF/permissions.perm
new file mode 100644
index 000000000..5a965875d
--- /dev/null
+++ b/bundles/org.eclipse.equinox.util/OSGI-INF/permissions.perm
@@ -0,0 +1 @@
+(java.security.AllPermission "*" "*") \ No newline at end of file
diff --git a/bundles/org.eclipse.equinox.util/about.html b/bundles/org.eclipse.equinox.util/about.html
new file mode 100644
index 000000000..40e147d98
--- /dev/null
+++ b/bundles/org.eclipse.equinox.util/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.util/build.properties b/bundles/org.eclipse.equinox.util/build.properties
new file mode 100644
index 000000000..9cbab3c13
--- /dev/null
+++ b/bundles/org.eclipse.equinox.util/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.util/src/org/eclipse/equinox/internal/util/TracerMap.java b/bundles/org.eclipse.equinox.util/src/org/eclipse/equinox/internal/util/TracerMap.java
new file mode 100644
index 000000000..08b41fd65
--- /dev/null
+++ b/bundles/org.eclipse.equinox.util/src/org/eclipse/equinox/internal/util/TracerMap.java
@@ -0,0 +1,50 @@
+/*******************************************************************************
+ * 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.util;
+
+import org.eclipse.equinox.internal.util.hash.HashIntObjNS;
+
+/**
+ * @author Pavlin Dobrev
+ * @version 1.0
+ */
+
+public class TracerMap {
+
+ public static HashIntObjNS getMap() {
+ HashIntObjNS map = new HashIntObjNS(29);
+
+ map.put(1, "[BEGIN - start method]");
+ map.put(1001, "[BEGIN - Log instance] Loading referent classes took");
+ map.put(101, "Getting system props, bundle id and log service took ");
+ map.put(102, "Getting Trace Service took ");
+ map.put(3001, "Loading tracer map took ");
+ map.put(2001, "[END - Log instance] Creating log instance took ");
+ map.put(3, "Creating Thread Pool service took ");
+ map.put(4, "Registering Thread Pool service took ");
+ map.put(33, "Creating Timer service took ");
+ map.put(5, "Registering Timer service took ");
+ map.put(16, "[END - start method] PutilActivator.start() method executed for ");
+ map.put(0, "Putil Activator");
+ map.put(-0x0100, "Threadpool");
+ map.put(10001, "Registering commands with groupname ");
+ map.put(10002, "Unregistering commands with groupname ");
+ map.put(10003, "START Running: ");
+ map.put(10004, "END Running: ");
+ map.put(10005, "Going to run: ");
+ return map;
+ }
+
+ public static HashIntObjNS getStarts() {
+ return null;
+ }
+}
diff --git a/bundles/org.eclipse.equinox.util/src/org/eclipse/equinox/internal/util/UtilActivator.java b/bundles/org.eclipse.equinox.util/src/org/eclipse/equinox/internal/util/UtilActivator.java
new file mode 100644
index 000000000..6acddbb04
--- /dev/null
+++ b/bundles/org.eclipse.equinox.util/src/org/eclipse/equinox/internal/util/UtilActivator.java
@@ -0,0 +1,194 @@
+/*******************************************************************************
+ * 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.util;
+
+import org.eclipse.equinox.internal.util.impl.tpt.threadpool.ThreadPoolFactoryImpl;
+import org.eclipse.equinox.internal.util.impl.tpt.timer.TimerFactory;
+import org.eclipse.equinox.internal.util.ref.Log;
+import org.eclipse.equinox.internal.util.ref.TimerRef;
+import org.eclipse.equinox.internal.util.threadpool.ThreadPoolFactory;
+import org.eclipse.equinox.internal.util.threadpool.ThreadPoolManager;
+import org.eclipse.equinox.internal.util.timer.Timer;
+import org.osgi.framework.*;
+
+/**
+ * Bundle activator for the Utility Bundle. This class is responsible to the
+ * registration of ProSyst utility services as Parser Service, Thread Pool
+ * Service, etc.
+ *
+ * @author Maria Ivanova
+ * @author Daniel Yanev
+ * @author Plamen K. Kosseff
+ * @author Pavlin Dobrev
+ * @version 1.0
+ */
+public class UtilActivator implements BundleActivator {
+
+ public static ThreadPoolFactoryImpl thMan;
+ private ServiceRegistration thManReg;
+
+ public static TimerFactory timer;
+ private ServiceRegistration timerReg;
+ public static Log log;
+ public static int debugLevel = 1;
+ public static BundleContext bc;
+ public static boolean LOG_DEBUG;
+ public static boolean startup;
+
+ static long time[] = null;
+
+ static void timeLog(int id) {
+ time[1] = time[0];
+ log.debug(0, id, String.valueOf((time[0] = System.currentTimeMillis()) - time[1]), null, false, true);
+ }
+
+ public static long[] points = null;
+
+ /**
+ * This is implementation of BundleActivator start method. Thsi method is
+ * responsible to the registering of the thread pool, system, pasrser and
+ * timer services. Also adds the framework and system pluggable commands to
+ * the parser service pluggable commands.
+ *
+ * @param bc
+ * The execution context of the bundle being started.
+ * @exception BundleException
+ * If this method throws an exception, the bundle is marked
+ * as stopped and the framework will remove the bundle's
+ * listeners, unregister all service's registered by the
+ * bundle, release all services used by the bundle.
+ */
+ public void start(BundleContext bc) throws BundleException {
+ UtilActivator.bc = bc;
+ startup = getBoolean("equinox.measurements.full") || getBoolean("equinox.measurements.bundles");
+ if (startup) {
+ long tmp = System.currentTimeMillis();
+ time = new long[] {tmp, 0, tmp};
+ points = new long[3];
+ }
+
+ UtilActivator.bc = bc;
+ try {
+ log = new Log(bc, false);
+ LOG_DEBUG = getBoolean("equinox.putil.debug");
+ log.setDebug(LOG_DEBUG);
+ log.setPrintOnConsole(getBoolean("equinox.putil.console"));
+ debugLevel = getInteger("equinox.putil.debug.level", 1);
+
+ if (startup) {
+ if (LOG_DEBUG)
+ log.setMaps(TracerMap.getMap(), TracerMap.getStarts());
+
+ /* 1 = "[BEGIN - start method]" */
+ log.debug(0, 1, null, null, false, true);
+ /* 1001 = "[BEGIN - Log instance] Loading referent classes took" */
+ log.debug(0, 1001, String.valueOf(points[0] - time[0]), null, false, true);
+ /* 101 = "Getting system props, bundle id and log service took " */
+ log.debug(0, 101, String.valueOf(points[1] - points[0]), null, false, true);
+ /* 102 = "Getting Trace Service took " */
+ log.debug(0, 102, String.valueOf(points[2] - points[1]), null, false, true);
+ time[1] = time[0];
+ /* 3001 = "Loading tracer map took " */
+ log.debug(0, 3001, String.valueOf((time[0] = System.currentTimeMillis()) - points[2]), null, false, true);
+ /* 2001 = "[END - Log instance] Creating log instance took " */
+ log.debug(0, 2001, String.valueOf(time[0] - time[1]), null, false, true);
+ }
+
+ String bundleName = ThreadPoolFactoryImpl.getName(bc.getBundle());
+ thMan = new ThreadPoolFactoryImpl(bundleName, log);
+ if (startup)
+ timeLog(3); /* 3 = "Creating Thread Pool service took " */
+
+ thManReg = bc.registerService(new String[] {ThreadPoolManager.class.getName(), ThreadPoolFactory.class.getName()}, thMan, null);
+ if (startup)
+ timeLog(4); /* 4 = "Registering Thread Pool service took " */
+
+ timer = new TimerFactory(bundleName, thMan, log);
+ if (startup)
+ timeLog(33); /* 33 = "Creating Timer service took " */
+
+ int i = getInteger("equinox.util.threadpool.inactiveTime", 30);
+ timerReg = bc.registerService(Timer.class.getName(), timer, null);
+ timer.addNotifyListener(ThreadPoolFactoryImpl.threadPool, Thread.NORM_PRIORITY, Timer.PERIODICAL_TIMER, (i * 1000L), 0);
+
+ TimerRef.timer = timer;
+
+ if (startup)
+ timeLog(5); /* 5 = "Registering Timer service took " */
+
+ if (startup) {
+
+ /*
+ * 16 = "[END - start method] PutilActivator.start() method
+ * executed for "
+ */
+ log.debug(0, 16, String.valueOf(time[0] - time[2]), null, false, true);
+ time = points = null;
+ }
+
+ } catch (Throwable ee) {
+ ee.printStackTrace();
+ System.out.println("log1: " + log);
+ log.error("[UtilActivator] An error has occurred while starting ProSyst Utility Bundle.", ee);
+ throw new BundleException("Error while starting ProSyst Utililty Bundle!", ee);
+ }
+ }
+
+ /**
+ * This is implementation of BundleActivator stop method. This method
+ * unregisteres the thread pool, system, parser and timer services.
+ *
+ * @param bc
+ * The execution context of the bundle being stopped.
+ * @exception BundleException
+ * If this method throws an exception, the bundle is still
+ * marked as stopped and the framework will remove the
+ * bundle's listeners, unregister all service's registered by
+ * the bundle, release all service's used by the bundle.
+ */
+ public void stop(BundleContext bc) throws BundleException {
+ try {
+ thManReg.unregister();
+
+ timerReg.unregister();
+ TimerFactory.stopTimer();
+ TimerRef.timer = timer = null;
+
+ ThreadPoolFactoryImpl.stopThreadPool();
+ thMan = null;
+ } catch (Throwable e) {
+ log.error("[UtilActivator] An error has occurred while stopping ProSyst Utility Bundle.", e);
+ throw new BundleException("Error while stopping ProSyst Utililty Bundle!", e);
+ } finally {
+ log.close();
+ log = null;
+ }
+ }
+
+ 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.util/src/org/eclipse/equinox/internal/util/event/EventThread.java b/bundles/org.eclipse.equinox.util/src/org/eclipse/equinox/internal/util/event/EventThread.java
new file mode 100644
index 000000000..34b638608
--- /dev/null
+++ b/bundles/org.eclipse.equinox.util/src/org/eclipse/equinox/internal/util/event/EventThread.java
@@ -0,0 +1,310 @@
+/*******************************************************************************
+ * 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.util.event;
+
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import org.eclipse.equinox.internal.util.UtilActivator;
+
+/**
+ * Abstract class for asynchronous event dispatching
+ *
+ * @author Pavlin Dobrev
+ * @version 1.0
+ */
+
+public abstract class EventThread implements Runnable {
+
+ /**
+ * The last callbacked listener. If the events thread is not responding,
+ * subclasses can take the appropriate actions - remove the listener for
+ * example
+ */
+ public Object bad;
+
+ /**
+ * The event queue. This object must be used for synchronization with the
+ * events thread's state
+ */
+ protected Queue queue;
+
+ /**
+ * The state of the thread.
+ * <li> bit 0: 0 = started / 1 = stopped;
+ * <li> bit 1: 0 not waiting / 1 = waiting
+ */
+ protected int state;
+
+ /**
+ * The time spent in the current callback, or 0 if the thread is not in a
+ * callback
+ */
+ protected long time = 0;
+ /**
+ * Instancies counter. Subclasses must not modify it.
+ */
+ protected int counter = 1;
+
+ /**
+ * The event to be dispatched
+ */
+ protected Object element;
+ protected String baseName;
+ protected String name;
+ protected Thread thread;
+ protected ThreadGroup group;
+ private static PrivilegedActionImpl privilegedAction = null;
+
+ /**
+ * Constructs the first instance of the EventThread
+ *
+ * @param group
+ * The ThreadGroup of the thread, or null for the current thread
+ * group
+ * @param name
+ * The base name of the thread. The <code> counter </code> value
+ * will be added at the end of the string to construct the full
+ * name.
+ * @param size
+ * The initial number of elements of the events queue
+ */
+ public EventThread(ThreadGroup group, String name, int size) {
+ makeThread(this.group = group, this.name = name + '0');
+ baseName = name;
+ queue = new Queue(size);
+ int priority = getThreadPriority();
+ if (priority != Thread.NORM_PRIORITY)
+ thread.setPriority(priority);
+ }
+
+ /**
+ * Constructs the first instance of the EventThread
+ *
+ * @param group
+ * The ThreadGroup of the thread, or null for the current thread
+ * group
+ * @param name
+ * The base name of the thread. The <code> counter </code> value
+ * will be added at the end of the string to construct the full
+ * name.
+ * @param queue
+ * The events queue
+ */
+ public EventThread(ThreadGroup group, String name, Queue queue) {
+ makeThread(this.group = group, this.name = name + '0');
+ baseName = name;
+ this.queue = queue;
+ int priority = getThreadPriority();
+ if (priority != Thread.NORM_PRIORITY)
+ thread.setPriority(priority);
+ }
+
+ /**
+ * Constructs a new EventThread, after the <code> old </code> event thread
+ * has stopped responding
+ *
+ * @param old
+ * The previous instance
+ */
+ protected EventThread(EventThread old) {
+ makeThread(group = old.thread.getThreadGroup(), name = old.baseName + old.counter++);
+ baseName = old.baseName;
+ counter = old.counter;
+ queue = old.queue;
+ int priority = getThreadPriority();
+ if (priority != Thread.NORM_PRIORITY)
+ thread.setPriority(priority);
+ }
+
+ public void start() {
+ thread.start();
+ }
+
+ /**
+ * Adds an event in the event queue. The method must be synchronized
+ * outside, on the <code> queue </code> field.
+ *
+ * @param event
+ * The event to add
+ * @param check
+ * If true, the method will check if the EventThread is still
+ * responding
+ */
+ public void addEvent(Object event, boolean check) {
+ try {
+ queue.put(event);
+ } catch (Throwable t) {
+ print(t);
+ return;
+ }
+ if ((state & 2) != 0)
+ queue.notify();
+ else if (check && checkTime())
+ try {
+ state |= 1;
+ newEventDispatcher(); // must call start
+ } catch (Throwable t) {
+ print(t);
+ state &= 254;
+ }
+ }
+
+ /**
+ * Processes the event queue. Sets the event to be dispathed in the
+ * <code> element </code> field and calls <cope> processEvent </code>
+ */
+ public void run() {
+ synchronized (queue) {
+ queue.notifyAll();
+ }
+ while (true) {
+ try {
+ synchronized (queue) {
+ if ((state & 1) != 0)
+ return; // closed
+ while ((element = queue.get()) == null)
+ try {
+ state |= 2; // waiting
+ queue.wait();
+ if ((state & 1) != 0)
+ return; // closed
+ state &= 253; // not waiting
+ } catch (InterruptedException ie) {
+ }
+ }
+ processEvent();
+
+ } catch (Throwable t) {
+ print(t);
+ try { // fix memory leak
+ throw new Exception();
+ } catch (Exception _) {
+ }
+ }
+ }
+ }
+
+ private void makeThread(ThreadGroup group, String name) {
+ try {
+ if (privilegedAction == null) {
+ privilegedAction = new PrivilegedActionImpl();
+ }
+ privilegedAction.set(group, this, name);
+ thread = (Thread) AccessController.doPrivileged(privilegedAction);
+ // thread = new Thread(group, this, name);
+ // thread.setDaemon(false);
+ // if (!disableContextClassLoader)
+ // thread.setContextClassLoader(null);
+ } catch (RuntimeException re) {
+ throw re;
+ } catch (Exception exc) {
+ throw new RuntimeException(exc.toString());
+ }
+ }
+
+ public Thread getThread() {
+ return thread;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * Returns the desired thread priority. Called in the constructors of the
+ * class in order to set the returned value to the thread.
+ *
+ * @return
+ */
+ public abstract int getThreadPriority();
+
+ /**
+ * Performs the actual event delivery. The event is stored in the
+ * <code> element </code> field. The method is supposed to perform the
+ * following for every listener:
+ * <li> synchronized on <code> queue </code> check the state of the thread -
+ * if it si closed - return
+ * <li> set the fields <code> bad and time <code>
+ * <li> callback
+ * <li> set bad to null and time to 0
+ */
+ public abstract void processEvent();
+
+ /**
+ * Checks if the thread is still active. The fields <code> time </code> and
+ * <code> bad </code> must be used. The method is called from the addEvent
+ * method - thus should be synchronizes on the <code> queue </code> field
+ * outside and additional synchronization is not needed.
+ */
+ public abstract boolean checkTime();
+
+ /**
+ * The method must create a new EventThread instance, using
+ * <code> super.EventThread(this) </code> and start it.
+ */
+ public abstract void newEventDispatcher();
+
+ /**
+ * Logs the error.
+ *
+ * @param t
+ */
+ public abstract void print(Throwable t);
+}
+
+class PrivilegedActionImpl implements PrivilegedAction {
+ private ThreadGroup group;
+ private Runnable runnable;
+ private String name;
+
+ private boolean locked = false;
+ private int waiting = 0;
+
+ void set(ThreadGroup group, Runnable runnable, String name) {
+ lock();
+ this.group = group;
+ this.runnable = runnable;
+ this.name = name;
+ }
+
+ public Object run() {
+ ThreadGroup group = this.group;
+ Runnable runnable = this.runnable;
+ String name = this.name;
+ unlock();
+ Thread th = new Thread(group, runnable, name);
+ if (!UtilActivator.getBoolean("equinox.disableContextClassLoader"))
+ th.setContextClassLoader(null);
+ th.setDaemon(false);
+ return th;
+ }
+
+ private synchronized void lock() {
+ while (locked)
+ try {
+ waiting++;
+ wait();
+ waiting--;
+ } catch (Exception exc) {
+ }
+ locked = true;
+ }
+
+ private synchronized void unlock() {
+ locked = false;
+ group = null;
+ runnable = null;
+ name = null;
+ if (waiting > 0)
+ notifyAll();
+ }
+}
diff --git a/bundles/org.eclipse.equinox.util/src/org/eclipse/equinox/internal/util/event/Queue.java b/bundles/org.eclipse.equinox.util/src/org/eclipse/equinox/internal/util/event/Queue.java
new file mode 100644
index 000000000..e507a9e61
--- /dev/null
+++ b/bundles/org.eclipse.equinox.util/src/org/eclipse/equinox/internal/util/event/Queue.java
@@ -0,0 +1,97 @@
+/*******************************************************************************
+ * 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.util.event;
+
+/**
+ * @author Pavlin Dobrev
+ * @version 1.0
+ */
+
+public class Queue {
+
+ protected Object[] queue;
+ protected int first, last = -1;
+ protected int initial, count;
+ protected int increment;
+ protected int decrement;
+
+ public Queue(int size) {
+ queue = new Object[initial = size];
+ increment = initial / 2;
+ decrement = increment + (increment / 2);
+ }
+
+ public void put(Object element) {
+ if (count == queue.length)
+ resize(true);
+ queue[++last == queue.length ? last = 0 : last] = element;
+ count++;
+ }
+
+ public void unget(Object element) {
+ if (count == queue.length)
+ resize(true);
+ queue[--first == -1 ? first = queue.length - 1 : first] = element;
+ count++;
+ }
+
+ public Object get() {
+ if (count == 0)
+ return null;
+ if (queue.length > initial && queue.length - count > decrement)
+ resize(false);
+ Object element = queue[first];
+ queue[first++] = null;
+ if (first == queue.length)
+ first = 0;
+ count--;
+ return element;
+ }
+
+ public void clear() {
+ if (queue.length > initial) {
+ queue = new Object[initial];
+ count = 0;
+ } else
+ for (; count > 0; count--) {
+ queue[first++] = null;
+ if (first == queue.length)
+ first = 0;
+ }
+ first = 0;
+ last = -1;
+ }
+
+ public int size() {
+ return count;
+ }
+
+ protected void resize(boolean up) {
+ Object[] tmp = new Object[queue.length + (up ? increment : -increment)];
+ if (first <= last)
+ System.arraycopy(queue, first, tmp, 0, count);
+ else {
+ int count1 = queue.length - first;
+ if (count1 > 0)
+ System.arraycopy(queue, first, tmp, 0, count1);
+ if (count > count1)
+ System.arraycopy(queue, 0, tmp, count1, count - count1);
+ }
+ queue = tmp;
+ first = 0;
+ last = count - 1;
+
+ increment = queue.length / 2;
+ decrement = increment + (increment / 2);
+ }
+}
diff --git a/bundles/org.eclipse.equinox.util/src/org/eclipse/equinox/internal/util/event/SystemListener.java b/bundles/org.eclipse.equinox.util/src/org/eclipse/equinox/internal/util/event/SystemListener.java
new file mode 100644
index 000000000..85bca6af2
--- /dev/null
+++ b/bundles/org.eclipse.equinox.util/src/org/eclipse/equinox/internal/util/event/SystemListener.java
@@ -0,0 +1,40 @@
+/*******************************************************************************
+ * 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.util.event;
+
+/**
+ * This interface marks any listener implementation as system listener. System
+ * listener are very important for the correct functionality of the system. When
+ * the execution of user implemented listener's methods is too slow this
+ * listener is presumed as "bad" listener and it is removed automatically by the
+ * framework unless it is implementing the SystemListener interface. Instead of
+ * removing it automatically as a bad listener, the system dispatchers will
+ * notify the listener by calling timeoutOccured().
+ *
+ * @author Stoyan Boshev
+ * @author Pavlin Dobrev
+ * @version 1.0
+ *
+ */
+public interface SystemListener {
+
+ /**
+ * Notifies the listener that a timeout has occured while processing one of
+ * its methods. The listeners logic may decide whether it has to be removed
+ * as listener or not
+ *
+ * @return true, if the listener has to be removed from the list of
+ * listeners
+ */
+ public boolean timeoutOccured();
+
+}
diff --git a/bundles/org.eclipse.equinox.util/src/org/eclipse/equinox/internal/util/event/package.html b/bundles/org.eclipse.equinox.util/src/org/eclipse/equinox/internal/util/event/package.html
new file mode 100644
index 000000000..ef2d0dda5
--- /dev/null
+++ b/bundles/org.eclipse.equinox.util/src/org/eclipse/equinox/internal/util/event/package.html
@@ -0,0 +1 @@
+<BODY> <P>This package provides APIs for event dispatching. </P> <p>Bundles wishing to use this package must list the package in the Import-Package header of the bundle's manifest. For example: </p> <pre> Import-Package: org.eclipse.equinox.util.framework.event; specification-version=1.0 </pre> </BODY> \ No newline at end of file
diff --git a/bundles/org.eclipse.equinox.util/src/org/eclipse/equinox/internal/util/hash/HashIntObjNS.java b/bundles/org.eclipse.equinox.util/src/org/eclipse/equinox/internal/util/hash/HashIntObjNS.java
new file mode 100644
index 000000000..48c2b32c7
--- /dev/null
+++ b/bundles/org.eclipse.equinox.util/src/org/eclipse/equinox/internal/util/hash/HashIntObjNS.java
@@ -0,0 +1,273 @@
+/*******************************************************************************
+ * 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.util.hash;
+
+/**
+ * Hashtable for mapping int keys to Object values. The methods of this
+ * hashtable are not synchronized, and if used concurently must be externally
+ * synchronized
+ *
+ * @author Pavlin Dobrev
+ * @version 1.0
+ */
+
+public class HashIntObjNS {
+
+ static final float LOAD_FACTOR = 0.75f;
+
+ // count of elements available in table
+ private int count = 0;
+ // used for computation of next position
+ private int step = 499979;
+
+ /**
+ * Used to enumerate the keys in the hash table. The key at index
+ * <code>i</code> is valid only if
+ * <ul>
+ * <code> values[i] != null </code>
+ * </ul>
+ */
+ public int[] keys;
+
+ /**
+ * Used to enumerate the values in the hash table. The value at index
+ * <code>i</code> is valid only if
+ * <ul>
+ * <code> values[i] != null </code>
+ * </ul>
+ */
+ public Object[] values;
+
+ /**
+ * Can be used to check if a key or value is valid. The value or key at
+ * index <code>i</code> is valid if the following expression is true
+ * <ul>
+ * <code> next[i] != -1 && next[i] < next.length </code>
+ * </ul>
+ */
+ public int[] next;
+
+ private int limit;
+ private double loadFactor;
+
+ /**
+ * Constructs an empty hash table with keys of type int and values af type
+ * Object. Uses default load factor (0.75) and default capacity (89)
+ *
+ */
+ public HashIntObjNS() {
+ this(101, LOAD_FACTOR);
+ }
+
+ /**
+ * Constructs an empty hash table with keys of type int and values af type
+ * Object. Uses default load factor (0.75).
+ *
+ * @param capacity
+ * initial capacity of the table
+ *
+ * @exception IllegalArgumentException
+ * if <code>capacity</code> < 1.
+ */
+ public HashIntObjNS(int capacity) {
+ this(capacity, LOAD_FACTOR);
+ }
+
+ /**
+ * Constructs an empty hash table with keys of type int and values of type
+ * Object.
+ *
+ * @param capacity
+ * initial capacity of the table
+ * @param lf
+ * load factor ot the table
+ *
+ * @exception IllegalArgumentException
+ * if <code>capacity</code> < 1 or <code>lf</code> < 0.0
+ */
+ public HashIntObjNS(int capacity, double lf) {
+ if (capacity < 0) {
+ throw new IllegalArgumentException("Invalid hashtable capacity: " + capacity + ".");
+ }
+
+ if (capacity == 0)
+ capacity = 101;
+
+ if (lf < 0) {
+ throw new IllegalArgumentException("Invalid load factor: " + lf + ".");
+ }
+
+ if (lf > 1.0) {
+ lf = 1.0;
+ }
+ loadFactor = lf;
+ limit = (int) (capacity * lf);
+ count = 0;
+
+ keys = new int[capacity];
+ values = new Object[capacity];
+ next = new int[capacity];
+ for (int i = 0; i < capacity; i++) {
+ keys[i] = 0;
+ next[i] = -1;
+ }
+ }
+
+ /**
+ * Adds in the hashtable an element with <code>key</code> key and
+ * <code>value</code> value. If an element with the specified key is
+ * already in the table only change it's value.
+ *
+ * @param key
+ * the key of the inserted element
+ * @param value
+ * the value of the inserted element
+ */
+ public void put(int key, Object value) {
+ if (count >= limit) {
+ rehash();
+ }
+ if (_put(key, value)) {
+ count++;
+ }
+ }
+
+ /**
+ * Returns an value which is mapped to the <code>key</code> key.
+ *
+ * @param key
+ * the key we are searching for
+ * @return the value this key is mapped to in the table, or null
+ */
+ public Object get(int key) {
+ int pos = find(key);
+ return (pos == -1) ? null : values[pos];
+ }
+
+ /**
+ * Removes an element with the specified key from the table. Does nothing if
+ * there is no element with this key.
+ *
+ * @param key
+ * the key of the element we want to remove
+ * @return the removed value, or null if there was nothing to remove
+ */
+ public Object remove(int key) {
+ int pos = find(key);
+ if (pos == -1)
+ return null;
+ next[pos] += next.length; // mark this field as empty
+ count--;
+ Object tmp = values[pos];
+ values[pos] = null;
+ return tmp;
+ }
+
+ /**
+ * Empties the hash table
+ */
+ public void removeAll() {
+ for (int i = 0; i < values.length; i++) {
+ values[i] = null;
+ keys[i] = 0;
+ next[i] = -1;
+ }
+ count = 0;
+ }
+
+ /**
+ * Rehashes the contents of the hashtable into a hashtable with a larger
+ * capacity. This method is called automatically when the number of keys in
+ * the hashtable exceeds this hashtable's capacity and load factor.
+ */
+ public void rehash() {
+ int[] tmpKeys = keys;
+ Object[] tmpValues = values;
+ int[] tmpNext = next;
+
+ int capacity = keys.length * 2 + 1;
+
+ // polzwame temp array-i za da ne se namaje hashtable-a pri OutOfMemory
+ int[] keys = new int[capacity];
+ Object[] values = new Object[capacity];
+ int[] next = new int[capacity];
+ for (int i = 0; i < next.length; i++) {
+ next[i] = -1;
+ }
+
+ this.keys = keys;
+ this.values = values;
+ this.next = next;
+
+ for (int i = 0; i < tmpNext.length; i++) {
+ if ((tmpNext[i] >= 0) && (tmpNext[i] < tmpNext.length)) {
+ _put(tmpKeys[i], tmpValues[i]);
+ }
+ }
+
+ limit = (int) (capacity * loadFactor);
+ }
+
+ /**
+ * Returns the count of elements currently in the table
+ *
+ * @return the count of elements
+ */
+ public int size() {
+ return count;
+ }
+
+ private int find(int key) {
+ int pos = (key & 0x7fffffff) % keys.length;
+ int i = 0;
+
+ while (next[pos] >= 0) {
+ if (keys[pos] == key) {
+ if (next[pos] < next.length) {
+ return pos;
+ }
+ }
+ if ((pos = next[pos]) >= next.length) {
+ pos -= next.length;
+ }
+ if (++i > next.length) {
+ return -1;
+ }
+ }
+
+ return -1;
+ } // find
+
+ private boolean _put(int key, Object value) {
+ int index = find(key);
+ if (index != -1) {
+ values[index] = value;
+ return false;
+ }
+
+ int pos = (key & 0x7fffffff) % keys.length;
+
+ while ((next[pos] >= 0) && (next[pos] < next.length)) {
+ pos = next[pos];
+ }
+
+ keys[pos] = key;
+ values[pos] = value;
+ if (next[pos] < 0) {
+ next[pos] = (pos + step) % next.length;
+ } else {
+ next[pos] -= next.length;
+ }
+ return true;
+ } // _put
+
+}
diff --git a/bundles/org.eclipse.equinox.util/src/org/eclipse/equinox/internal/util/hash/HashIntObjS.java b/bundles/org.eclipse.equinox.util/src/org/eclipse/equinox/internal/util/hash/HashIntObjS.java
new file mode 100644
index 000000000..268db31f2
--- /dev/null
+++ b/bundles/org.eclipse.equinox.util/src/org/eclipse/equinox/internal/util/hash/HashIntObjS.java
@@ -0,0 +1,54 @@
+/*******************************************************************************
+ * 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.util.hash;
+
+/**
+ * Synchronized extension of org.eclipse.equinox.internal.util.hash.HashIntObjNS
+ *
+ * @author Pavlin Dobrev
+ * @version 1.0
+ */
+
+public final class HashIntObjS extends HashIntObjNS {
+
+ public HashIntObjS() {
+ super(101, LOAD_FACTOR);
+ }
+
+ public HashIntObjS(int capacity) {
+ super(capacity, LOAD_FACTOR);
+ }
+
+ public HashIntObjS(int capacity, double lf) {
+ super(capacity, lf);
+ }
+
+ public synchronized void put(int key, Object value) {
+ super.put(key, value);
+ }
+
+ public synchronized Object get(int key) {
+ return super.get(key);
+ }
+
+ public synchronized Object remove(int key) {
+ return super.remove(key);
+ }
+
+ public synchronized int size() {
+ return super.size();
+ }
+
+ public synchronized void removeAll() {
+ super.removeAll();
+ }
+}
diff --git a/bundles/org.eclipse.equinox.util/src/org/eclipse/equinox/internal/util/hash/HashLongObjNS.java b/bundles/org.eclipse.equinox.util/src/org/eclipse/equinox/internal/util/hash/HashLongObjNS.java
new file mode 100644
index 000000000..175d1eb71
--- /dev/null
+++ b/bundles/org.eclipse.equinox.util/src/org/eclipse/equinox/internal/util/hash/HashLongObjNS.java
@@ -0,0 +1,273 @@
+/*******************************************************************************
+ * 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.util.hash;
+
+/**
+ * Hashtable for mapping long keys to Object values. The methods of this
+ * hashtable are not synchronized, and if used concurently must be externally
+ * synchronized
+ *
+ * @author Pavlin Dobrev
+ * @version 1.0
+ */
+
+public class HashLongObjNS {
+
+ static final float LOAD_FACTOR = 0.75f;
+
+ // count of elements available in table
+ private int count = 0;
+ // used for computation of next position
+ private int step = 499979;
+
+ /**
+ * Used to enumerate the keys in the hash table. The key at index
+ * <code>i</code> is valid only if
+ * <ul>
+ * <code> values[i] != null </code>
+ * </ul>
+ */
+ public long[] keys;
+
+ /**
+ * Used to enumerate the values in the hash table. The value at index
+ * <code>i</code> is valid only if
+ * <ul>
+ * <code> values[i] != null </code>
+ * </ul>
+ */
+ public Object[] values;
+
+ /**
+ * Can be used to check if a key or value is valid. The value or key at
+ * index <code>i</code> is valid if the following expression is true
+ * <ul>
+ * <code> next[i] != -1 && next[i] < next.length </code>
+ * </ul>
+ */
+ public int[] next;
+
+ private int limit;
+ private double loadFactor;
+
+ /**
+ * Constructs an empty hash table with keys of type long and values af type
+ * int. Uses default load factor (0.75) and default capacity (89)
+ *
+ */
+ public HashLongObjNS() {
+ this(101, LOAD_FACTOR);
+ }
+
+ /**
+ * Constructs an empty hash table with keys of type long and values af type
+ * int. Uses default load factor (0.75).
+ *
+ * @param capacity
+ * initial capacity of the table
+ *
+ * @exception IllegalArgumentException
+ * if <code>capacity</code> < 1.
+ */
+ public HashLongObjNS(int capacity) {
+ this(capacity, LOAD_FACTOR);
+ }
+
+ /**
+ * Constructs an empty hash table with keys of type long and values of type
+ * int.
+ *
+ * @param capacity
+ * initial capacity of the table
+ * @param lf
+ * load factor ot the table
+ *
+ * @exception IllegalArgumentException
+ * if <code>capacity</code> < 1 or <code>lf</code> < 0.0
+ */
+ public HashLongObjNS(int capacity, double lf) {
+ if (capacity < 0) {
+ throw new IllegalArgumentException("Invalid hashtable capacity: " + capacity + ".");
+ }
+
+ if (capacity == 0)
+ capacity = 101;
+
+ if (lf < 0) {
+ throw new IllegalArgumentException("Invalid load factor: " + lf + ".");
+ }
+
+ if (lf > 1.0) {
+ lf = 1.0;
+ }
+ loadFactor = lf;
+ limit = (int) (capacity * lf);
+ count = 0;
+
+ keys = new long[capacity];
+ values = new Object[capacity];
+ next = new int[capacity];
+ for (int i = 0; i < capacity; i++) {
+ keys[i] = 0;
+ next[i] = -1;
+ }
+ }
+
+ /**
+ * Adds in hashtable an element with <code>key</code> key and
+ * <code>value</code> value. If an element with the specified key is
+ * already in the table only change it's value.
+ *
+ * @param key
+ * the key of the inserted element
+ * @param value
+ * the value of the inserted element
+ */
+ public void put(long key, Object value) {
+ if (count >= limit) {
+ rehash();
+ }
+ if (_put(key, value)) {
+ count++;
+ }
+ }
+
+ /**
+ * Returns an value which is mapped to the <code>key</code> key.
+ *
+ * @param key
+ * the key we are searching for
+ * @return the value this key is mapped to in the table, or null
+ */
+ public Object get(long key) {
+ int pos = find(key);
+ return (pos == -1) ? null : values[pos];
+ }
+
+ /**
+ * Removes an element with the specified key from the table. Does nothing if
+ * there is no element with this key.
+ *
+ * @param key
+ * the key of the element we want to remove
+ * @return the removed value, or null if there was nothing to remove
+ */
+ public Object remove(long key) {
+ int pos = find(key);
+ if (pos == -1)
+ return null;
+ next[pos] += next.length; // mark this field as empty
+ count--;
+ Object tmp = values[pos];
+ values[pos] = null;
+ return tmp;
+ }
+
+ /**
+ * Empties the hash table
+ */
+ public void removeAll() {
+ for (int i = 0; i < values.length; i++) {
+ values[i] = null;
+ keys[i] = 0;
+ next[i] = -1;
+ }
+ count = 0;
+ }
+
+ /**
+ * Rehashes the contents of the hashtable into a hashtable with a larger
+ * capacity. This method is called automatically when the number of keys in
+ * the hashtable exceeds this hashtable's capacity and load factor.
+ */
+ public void rehash() {
+ long[] tmpKeys = keys;
+ Object[] tmpValues = values;
+ int[] tmpNext = next;
+
+ int capacity = keys.length * 2 + 1;
+
+ // polzwame temp array-i za da ne se namaje hashtable-a pri OutOfMemory
+ long[] keys = new long[capacity];
+ Object[] values = new Object[capacity];
+ int[] next = new int[capacity];
+ for (int i = 0; i < next.length; i++) {
+ next[i] = -1;
+ }
+
+ this.keys = keys;
+ this.values = values;
+ this.next = next;
+
+ for (int i = 0; i < tmpNext.length; i++) {
+ if ((tmpNext[i] >= 0) && (tmpNext[i] < tmpNext.length)) {
+ _put(tmpKeys[i], tmpValues[i]);
+ }
+ }
+
+ limit = (int) (capacity * loadFactor);
+ }
+
+ /**
+ * Returns the count of elements currently in the table
+ *
+ * @return the count of elements
+ */
+ public int size() {
+ return count;
+ }
+
+ private int find(long key) {
+ int pos = (int) (key & 0x7fffffff) % keys.length;
+ int i = 0;
+
+ while (next[pos] >= 0) {
+ if (keys[pos] == key) {
+ if (next[pos] < next.length) {
+ return pos;
+ }
+ }
+ if ((pos = next[pos]) >= next.length) {
+ pos -= next.length;
+ }
+ if (++i > next.length) {
+ return -1;
+ }
+ }
+
+ return -1;
+ } // find
+
+ private boolean _put(long key, Object value) {
+ int index = find(key);
+ if (index != -1) {
+ values[index] = value;
+ return false;
+ }
+
+ int pos = (int) (key & 0x7fffffff) % keys.length;
+
+ while ((next[pos] >= 0) && (next[pos] < next.length)) {
+ pos = next[pos];
+ }
+
+ keys[pos] = key;
+ values[pos] = value;
+ if (next[pos] < 0) {
+ next[pos] = (pos + step) % next.length;
+ } else {
+ next[pos] -= next.length;
+ }
+ return true;
+ } // _put
+
+}
diff --git a/bundles/org.eclipse.equinox.util/src/org/eclipse/equinox/internal/util/hash/HashLongObjS.java b/bundles/org.eclipse.equinox.util/src/org/eclipse/equinox/internal/util/hash/HashLongObjS.java
new file mode 100644
index 000000000..26a380c00
--- /dev/null
+++ b/bundles/org.eclipse.equinox.util/src/org/eclipse/equinox/internal/util/hash/HashLongObjS.java
@@ -0,0 +1,54 @@
+/*******************************************************************************
+ * 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.util.hash;
+
+/**
+ * Synchronized extension of org.eclipse.equinox.internal.util.hash.HashLongObjNS
+ *
+ * @author Pavlin Dobrev
+ * @version 1.0
+ */
+
+public final class HashLongObjS extends HashLongObjNS {
+
+ public HashLongObjS() {
+ super(101, LOAD_FACTOR);
+ }
+
+ public HashLongObjS(int capacity) {
+ super(capacity, LOAD_FACTOR);
+ }
+
+ public HashLongObjS(int capacity, double lf) {
+ super(capacity, lf);
+ }
+
+ public synchronized void put(long key, Object value) {
+ super.put(key, value);
+ }
+
+ public synchronized Object get(long key) {
+ return super.get(key);
+ }
+
+ public synchronized Object remove(long key) {
+ return super.remove(key);
+ }
+
+ public synchronized int size() {
+ return super.size();
+ }
+
+ public synchronized void removeAll() {
+ super.removeAll();
+ }
+}
diff --git a/bundles/org.eclipse.equinox.util/src/org/eclipse/equinox/internal/util/hash/HashObjIntNS.java b/bundles/org.eclipse.equinox.util/src/org/eclipse/equinox/internal/util/hash/HashObjIntNS.java
new file mode 100644
index 000000000..1b83753be
--- /dev/null
+++ b/bundles/org.eclipse.equinox.util/src/org/eclipse/equinox/internal/util/hash/HashObjIntNS.java
@@ -0,0 +1,295 @@
+/*******************************************************************************
+ * 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.util.hash;
+
+import java.util.NoSuchElementException;
+
+/**
+ * Hashtable for mapping Object keys to int values. The methods of this
+ * hashtable are not synchronized, and if used concurently must be externally
+ * synchronized
+ *
+ * @author Pavlin Dobrev
+ * @version 1.0
+ */
+
+public class HashObjIntNS {
+
+ static final float LOAD_FACTOR = 0.75f;
+
+ // count of elements available in table
+ private int count = 0;
+ // used for computation of next position
+ private int step = 499979;
+
+ /**
+ * Used to enumerate the keys in the hash table. The key at index
+ * <code>i</code> is valid only if
+ * <ul>
+ * <code> keys[i] != null </code>
+ * </ul>
+ */
+ public Object[] keys;
+
+ /**
+ * Used to enumerate the values in the hash table. The value at index
+ * <code>i</code> is valid only if
+ * <ul>
+ * <code> keys[i] != null </code>
+ * </ul>
+ */
+ public int[] values;
+
+ /**
+ * Can be used to check if a key or value is valid. The value or key at
+ * index <code>i</code> is valid if the following expression is true
+ * <ul>
+ * <code> next[i] != -1 && next[i] < next.length </code>
+ * </ul>
+ */
+ public int[] next;
+
+ private int limit;
+ private double loadFactor;
+
+ /**
+ * Constructs an empty hash table with keys of type int and values af type
+ * Object. Uses default load factor (0.75) and default capacity (89)
+ *
+ */
+ public HashObjIntNS() {
+ this(101, LOAD_FACTOR);
+ }
+
+ /**
+ * Constructs an empty hash table with keys of type int and values af type
+ * Object. Uses default load factor (0.75).
+ *
+ * @param capacity
+ * initial capacity of the table
+ *
+ * @exception IllegalArgumentException
+ * if <code>capacity</code> < 1.
+ */
+ public HashObjIntNS(int capacity) {
+ this(capacity, LOAD_FACTOR);
+ }
+
+ /**
+ * Constructs an empty hash table with keys of type int and values of type
+ * Object.
+ *
+ * @param capacity
+ * initial capacity of the table
+ * @param lf
+ * load factor ot the table
+ *
+ * @exception IllegalArgumentException
+ * if <code>capacity</code> < 1 or <code>lf</code> < 0.0
+ */
+ public HashObjIntNS(int capacity, double lf) {
+ if (capacity < 0) {
+ throw new IllegalArgumentException("Invalid hashtable capacity: " + capacity + ".");
+ }
+
+ if (capacity == 0)
+ capacity = 101;
+
+ if (lf < 0) {
+ throw new IllegalArgumentException("Invalid load factor: " + lf + ".");
+ }
+
+ if (lf > 1.0) {
+ lf = 1.0;
+ }
+ loadFactor = lf;
+ limit = (int) (capacity * lf);
+ count = 0;
+
+ keys = new Object[capacity];
+ values = new int[capacity];
+ next = new int[capacity];
+ for (int i = 0; i < capacity; i++) {
+ next[i] = -1;
+ }
+ }
+
+ /**
+ * Adds in hashtable an element with <code>key</code> key and
+ * <code>value</code> value. If an element with the specified key is
+ * already in the table only change it's value.
+ *
+ * @param key
+ * the key of the inserted element
+ * @param value
+ * the value of the inserted element
+ */
+ public void put(Object key, int value) {
+ if (count >= limit) {
+ rehash();
+ }
+ if (_put(key, value)) {
+ count++;
+ }
+ }
+
+ /**
+ * Returns an value which is mapped to the <code>key</code> key. If there
+ * is no such a key, throws <code>NoSuchElementException</code>.
+ *
+ * @param key
+ * the key we are searching for
+ * @return the value this key is mapped to in the table.
+ *
+ * @exception NoSuchElementException
+ * if there is no element with the specified key.
+ */
+ public int get(Object key) {
+ int pos = find(key);
+ if (pos == -1)
+ throw new NoSuchElementException();
+ return values[pos];
+ }
+
+ /**
+ * Removes an element with the specified key from the table. throws
+ * <code>NoSuchElementException</code> if there is no element with this
+ * key.
+ *
+ * @param key
+ * the key of the element we want to remove
+ * @exception NoSuchElementException
+ * if there is no element with the specified key.
+ */
+ public int remove(Object key) {
+ int pos = find(key);
+ if (pos == -1)
+ throw new NoSuchElementException();
+ next[pos] += next.length; // mark this field as empty
+ count--;
+ keys[pos] = null;
+ return values[pos];
+ }
+
+ /**
+ * Empties the hash table
+ */
+ public void removeAll() {
+ for (int i = 0; i < values.length; i++) {
+ keys[i] = null;
+ next[i] = -1;
+ }
+ }
+
+ /**
+ * Rehashes the contents of the hashtable into a hashtable with a larger
+ * capacity. This method is called automatically when the number of keys in
+ * the hashtable exceeds this hashtable's capacity and load factor.
+ */
+ public void rehash() {
+ Object[] tmpKeys = keys;
+ int[] tmpValues = values;
+ int[] tmpNext = next;
+
+ int capacity = keys.length * 2 + 1;
+
+ // polzwame temp array-i za da ne se namaje hashtable-a pri OutOfMemory
+ Object[] keys = new Object[capacity];
+ int[] values = new int[capacity];
+ int[] next = new int[capacity];
+ for (int i = 0; i < next.length; i++) {
+ next[i] = -1;
+ }
+
+ this.keys = keys;
+ this.values = values;
+ this.next = next;
+
+ for (int i = 0; i < tmpNext.length; i++) {
+ if ((tmpNext[i] >= 0) && (tmpNext[i] < tmpNext.length)) {
+ _put(tmpKeys[i], tmpValues[i]);
+ }
+ }
+
+ limit = (int) (capacity * loadFactor);
+ }
+
+ /**
+ * Returns the count of elements currently in the table
+ *
+ * @return the count of elements
+ */
+ public int size() {
+ return count;
+ }
+
+ public Object[] getKeys() {
+ return keys;
+ }
+
+ private int find(Object key) {
+ return find(key, (key.hashCode() & 0x7fffffff) % keys.length);
+ } // find
+
+ private int find(Object key, int pos) {
+ int i = 0;
+
+ // System.out.println("In Zarko's code");
+ //
+ // if (key == null)
+ // System.out.println("key is null");
+ //
+ while (next[pos] >= 0) {
+
+ if (keys[pos] != null) {
+ // System.out.println("is null");
+
+ if (key.equals(keys[pos])) {
+ if (next[pos] < next.length) {
+ return pos;
+ }
+ }
+ }
+ if ((pos = next[pos]) >= next.length) {
+ pos -= next.length;
+ }
+ if (++i > next.length) {
+ return -1;
+ }
+ }
+
+ return -1;
+ }
+
+ private boolean _put(Object key, int value) {
+ int pos = (key.hashCode() & 0x7fffffff) % keys.length;
+ int index = find(key, pos);
+ if (index != -1) {
+ values[index] = value;
+ return false;
+ }
+
+ while ((next[pos] >= 0) && (next[pos] < next.length)) {
+ pos = next[pos];
+ }
+
+ keys[pos] = key;
+ values[pos] = value;
+ if (next[pos] < 0) {
+ next[pos] = (pos + step) % next.length;
+ } else {
+ next[pos] -= next.length;
+ }
+ return true;
+ } // _put
+
+}
diff --git a/bundles/org.eclipse.equinox.util/src/org/eclipse/equinox/internal/util/hash/HashObjIntS.java b/bundles/org.eclipse.equinox.util/src/org/eclipse/equinox/internal/util/hash/HashObjIntS.java
new file mode 100644
index 000000000..2a7856dc9
--- /dev/null
+++ b/bundles/org.eclipse.equinox.util/src/org/eclipse/equinox/internal/util/hash/HashObjIntS.java
@@ -0,0 +1,54 @@
+/*******************************************************************************
+ * 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.util.hash;
+
+/**
+ * Synchronized extension of org.eclipse.equinox.internal.util.hash.HashObjIntNS
+ *
+ * @author Pavlin Dobrev
+ * @version 1.0
+ */
+
+public final class HashObjIntS extends HashObjIntNS {
+
+ public HashObjIntS() {
+ super(101, LOAD_FACTOR);
+ }
+
+ public HashObjIntS(int capacity) {
+ super(capacity, LOAD_FACTOR);
+ }
+
+ public HashObjIntS(int capacity, double lf) {
+ super(capacity, lf);
+ }
+
+ public synchronized void put(Object key, int value) {
+ super.put(key, value);
+ }
+
+ public synchronized int get(Object key) {
+ return super.get(key);
+ }
+
+ public synchronized int remove(Object key) {
+ return super.remove(key);
+ }
+
+ public synchronized int size() {
+ return super.size();
+ }
+
+ public synchronized void removeAll() {
+ super.removeAll();
+ }
+}
diff --git a/bundles/org.eclipse.equinox.util/src/org/eclipse/equinox/internal/util/hash/HashObjLongNS.java b/bundles/org.eclipse.equinox.util/src/org/eclipse/equinox/internal/util/hash/HashObjLongNS.java
new file mode 100644
index 000000000..b9c318704
--- /dev/null
+++ b/bundles/org.eclipse.equinox.util/src/org/eclipse/equinox/internal/util/hash/HashObjLongNS.java
@@ -0,0 +1,281 @@
+/*******************************************************************************
+ * 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.util.hash;
+
+import java.util.NoSuchElementException;
+
+/**
+ * Hashtable for mapping Object keys to long values. The methods of this
+ * hashtable are not synchronized, and if used concurently must be externally
+ * synchronized
+ *
+ * @author Pavlin Dobrev
+ * @version 1.0
+ */
+
+public class HashObjLongNS {
+
+ static final float LOAD_FACTOR = 0.75f;
+
+ // count of elements available in table
+ private int count = 0;
+ // used for computation of next position
+ private int step = 499979;
+
+ /**
+ * Used to enumerate the keys in the hash table. The key at index
+ * <code>i</code> is valid only if
+ * <ul>
+ * <code> keys[i] != null </code>
+ * </ul>
+ */
+ public Object[] keys;
+
+ /**
+ * Used to enumerate the values in the hash table. The value at index
+ * <code>i</code> is valid only if
+ * <ul>
+ * <code> keys[i] != null </code>
+ * </ul>
+ */
+ public long[] values;
+
+ /**
+ * Can be used to check if a key or value is valid. The value or key at
+ * index <code>i</code> is valid if the following expression is true
+ * <ul>
+ * <code> next[i] != -1 && next[i] < next.length </code>
+ * </ul>
+ */
+ public int[] next;
+
+ private int limit;
+ private double loadFactor;
+
+ /**
+ * Constructs an empty hash table with keys of type int and values af type
+ * Object. Uses default load factor (0.75) and default capacity (89)
+ *
+ */
+ public HashObjLongNS() {
+ this(101, LOAD_FACTOR);
+ }
+
+ /**
+ * Constructs an empty hash table with keys of type int and values af type
+ * Object. Uses default load factor (0.75).
+ *
+ * @param capacity
+ * initial capacity of the table
+ *
+ * @exception IllegalArgumentException
+ * if <code>capacity</code> < 1.
+ */
+ public HashObjLongNS(int capacity) {
+ this(capacity, LOAD_FACTOR);
+ }
+
+ /**
+ * Constructs an empty hash table with keys of type int and values of type
+ * Object.
+ *
+ * @param capacity
+ * initial capacity of the table
+ * @param lf
+ * load factor ot the table
+ *
+ * @exception IllegalArgumentException
+ * if <code>capacity</code> < 1 or <code>lf</code> < 0.0
+ */
+ public HashObjLongNS(int capacity, double lf) {
+ if (capacity < 0) {
+ throw new IllegalArgumentException("Invalid hashtable capacity: " + capacity + ".");
+ }
+
+ if (capacity == 0)
+ capacity = 101;
+
+ if (lf < 0) {
+ throw new IllegalArgumentException("Invalid load factor: " + lf + ".");
+ }
+
+ if (lf > 1.0) {
+ lf = 1.0;
+ }
+ loadFactor = lf;
+ limit = (int) (capacity * lf);
+ count = 0;
+
+ keys = new Object[capacity];
+ values = new long[capacity];
+ next = new int[capacity];
+ for (int i = 0; i < capacity; i++) {
+ next[i] = -1;
+ }
+ }
+
+ /**
+ * Adds in hashtable an element with <code>key</code> key and
+ * <code>value</code> value. If an element with the specified key is
+ * already in the table only change it's value.
+ *
+ * @param key
+ * the key of the inserted element
+ * @param value
+ * the value of the inserted element
+ */
+ public void put(Object key, long value) {
+ if (count >= limit) {
+ rehash();
+ }
+ if (_put(key, value)) {
+ count++;
+ }
+ }
+
+ /**
+ * Returns an value which is mapped to the <code>key</code> key. If there
+ * is no such a key, throws <code>NoSuchElementException</code>.
+ *
+ * @param key
+ * the key we are searching for
+ * @return the value this key is mapped to in the table.
+ *
+ * @exception NoSuchElementException
+ * if there is no element with the specified key.
+ */
+ public long get(Object key) {
+ int pos = find(key);
+ if (pos == -1)
+ throw new NoSuchElementException();
+ return values[pos];
+ }
+
+ /**
+ * Removes an element with the specified key from the table. throws
+ * <code>NoSuchElementException</code> if there is no element with this
+ * key.
+ *
+ * @param key
+ * the key of the element we want to remove
+ * @exception NoSuchElementException
+ * if there is no element with the specified key.
+ */
+ public long remove(Object key) {
+ int pos = find(key);
+ if (pos == -1)
+ throw new NoSuchElementException();
+ next[pos] += next.length; // mark this field as empty
+ keys[pos] = null;
+ count--;
+ return values[pos];
+ }
+
+ /**
+ * Empties the hash table
+ */
+ public void removeAll() {
+ for (int i = 0; i < values.length; i++) {
+ keys[i] = null;
+ next[i] = -1;
+ }
+ }
+
+ /**
+ * Rehashes the contents of the hashtable into a hashtable with a larger
+ * capacity. This method is called automatically when the number of keys in
+ * the hashtable exceeds this hashtable's capacity and load factor.
+ */
+ public void rehash() {
+ Object[] tmpKeys = keys;
+ long[] tmpValues = values;
+ int[] tmpNext = next;
+
+ int capacity = keys.length * 2 + 1;
+
+ // polzwame temp array-i za da ne se namaje hashtable-a pri OutOfMemory
+ Object[] keys = new Object[capacity];
+ long[] values = new long[capacity];
+ int[] next = new int[capacity];
+ for (int i = 0; i < next.length; i++) {
+ next[i] = -1;
+ }
+
+ this.keys = keys;
+ this.values = values;
+ this.next = next;
+
+ for (int i = 0; i < tmpNext.length; i++) {
+ if ((tmpNext[i] >= 0) && (tmpNext[i] < tmpNext.length)) {
+ _put(tmpKeys[i], tmpValues[i]);
+ }
+ }
+
+ limit = (int) (capacity * loadFactor);
+ }
+
+ /**
+ * Returns the count of elements currently in the table
+ *
+ * @return the count of elements
+ */
+ public int size() {
+ return count;
+ }
+
+ private int find(Object key) {
+ return find(key, (key.hashCode() & 0x7fffffff) % keys.length);
+ } // find
+
+ private int find(Object key, int pos) {
+ int i = 0;
+
+ while (next[pos] >= 0) {
+ if (key.equals(keys[pos])) {
+ if (next[pos] < next.length) {
+ return pos;
+ }
+ }
+ if ((pos = next[pos]) >= next.length) {
+ pos -= next.length;
+ }
+ if (++i > next.length) {
+ return -1;
+ }
+ }
+
+ return -1;
+ }
+
+ private boolean _put(Object key, long value) {
+ int pos = (key.hashCode() & 0x7fffffff) % keys.length;
+ int index = find(key, pos);
+ if (index != -1) {
+ values[index] = value;
+ return false;
+ }
+
+ while ((next[pos] >= 0) && (next[pos] < next.length)) {
+ pos = next[pos];
+ }
+
+ keys[pos] = key;
+ values[pos] = value;
+ if (next[pos] < 0) {
+ next[pos] = (pos + step) % next.length;
+ } else {
+ next[pos] -= next.length;
+ }
+ return true;
+ } // _put
+
+}
diff --git a/bundles/org.eclipse.equinox.util/src/org/eclipse/equinox/internal/util/hash/HashObjLongS.java b/bundles/org.eclipse.equinox.util/src/org/eclipse/equinox/internal/util/hash/HashObjLongS.java
new file mode 100644
index 000000000..4e6b039e1
--- /dev/null
+++ b/bundles/org.eclipse.equinox.util/src/org/eclipse/equinox/internal/util/hash/HashObjLongS.java
@@ -0,0 +1,54 @@
+/*******************************************************************************
+ * 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.util.hash;
+
+/**
+ * Synchronized extension of org.eclipse.equinox.internal.util.hash.HashObjLongNS
+ *
+ * @author Pavlin Dobrev
+ * @version 1.0
+ */
+
+public final class HashObjLongS extends HashObjLongNS {
+
+ public HashObjLongS() {
+ super(101, LOAD_FACTOR);
+ }
+
+ public HashObjLongS(int capacity) {
+ super(capacity, LOAD_FACTOR);
+ }
+
+ public HashObjLongS(int capacity, double lf) {
+ super(capacity, lf);
+ }
+
+ public synchronized void put(Object key, long value) {
+ super.put(key, value);
+ }
+
+ public synchronized long get(Object key) {
+ return super.get(key);
+ }
+
+ public synchronized long remove(Object key) {
+ return super.remove(key);
+ }
+
+ public synchronized int size() {
+ return super.size();
+ }
+
+ public synchronized void removeAll() {
+ super.removeAll();
+ }
+}
diff --git a/bundles/org.eclipse.equinox.util/src/org/eclipse/equinox/internal/util/hash/package.html b/bundles/org.eclipse.equinox.util/src/org/eclipse/equinox/internal/util/hash/package.html
new file mode 100644
index 000000000..9f23940ea
--- /dev/null
+++ b/bundles/org.eclipse.equinox.util/src/org/eclipse/equinox/internal/util/hash/package.html
@@ -0,0 +1,9 @@
+<HTML>
+<HEAD>
+<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=windows-1252">
+<TITLE>org.eclipse.equinox.util.hash</TITLE>
+</HEAD>
+<BODY LINK="#0000ff" VLINK="#800080">
+<P>Provides hashing utilities among which are several Hashtables accepting primitive data types for keys or values.</P>
+</BODY>
+</HTML>
diff --git a/bundles/org.eclipse.equinox.util/src/org/eclipse/equinox/internal/util/impl/tpt/ServiceFactoryImpl.java b/bundles/org.eclipse.equinox.util/src/org/eclipse/equinox/internal/util/impl/tpt/ServiceFactoryImpl.java
new file mode 100644
index 000000000..b7904262b
--- /dev/null
+++ b/bundles/org.eclipse.equinox.util/src/org/eclipse/equinox/internal/util/impl/tpt/ServiceFactoryImpl.java
@@ -0,0 +1,86 @@
+/*******************************************************************************
+ * 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.util.impl.tpt;
+
+import org.eclipse.equinox.internal.util.UtilActivator;
+import org.eclipse.equinox.internal.util.ref.Log;
+import org.osgi.framework.*;
+
+/**
+ * @author Pavlin Dobrev
+ * @version 1.0
+ */
+
+public abstract class ServiceFactoryImpl implements ServiceFactory {
+
+ public String bundleName;
+ public static Log log;
+
+ private static Bundle systemBundle = null;
+ static {
+ try {
+ systemBundle = UtilActivator.bc.getBundle(0);
+ } catch (Exception e) {
+ }
+ }
+ static boolean emptyStorage;
+
+ private static boolean security = Log.security();
+
+ public static boolean privileged() {
+ emptyStorage = UtilActivator.bc.getProperty("equinox.storage.empty") != null;
+ return ((systemBundle.getState() != Bundle.STARTING) || emptyStorage) && security;
+ }
+
+ public static boolean useNames = true;
+ static String suseNames;
+
+ public ServiceFactoryImpl(String bundleName, Log log) {
+ this.bundleName = bundleName;
+ ServiceFactoryImpl.log = log;
+
+ String tmp = UtilActivator.bc.getProperty("equinox.util.threadpool.useNames");
+ if (suseNames != tmp)
+ useNames = tmp == null || !tmp.equals("false");
+ }
+
+ public ServiceFactoryImpl(String bundleName) {
+ this.bundleName = bundleName;
+ }
+
+ public Object getService(Bundle caller, ServiceRegistration sReg) {
+ return getInstance(useNames ? getName(caller) : null);
+ }
+
+ public static String getName(Bundle caller) {
+ StringBuffer bf = new StringBuffer(13);
+ bf.append(" (Bundle ");
+ bf.append(caller.getBundleId());
+ bf.append(')');
+ return bf.toString();
+ }
+
+ /**
+ * Nothing to be done here.
+ *
+ * @param caller
+ * caller bundle, which releases the factory instance
+ * @param sReg
+ * @param service
+ * object that is released
+ */
+ public void ungetService(Bundle caller, ServiceRegistration sReg, Object service) {
+ }
+
+ public abstract Object getInstance(String bundleName);
+}
diff --git a/bundles/org.eclipse.equinox.util/src/org/eclipse/equinox/internal/util/impl/tpt/threadpool/Executor.java b/bundles/org.eclipse.equinox.util/src/org/eclipse/equinox/internal/util/impl/tpt/threadpool/Executor.java
new file mode 100644
index 000000000..38e3cc003
--- /dev/null
+++ b/bundles/org.eclipse.equinox.util/src/org/eclipse/equinox/internal/util/impl/tpt/threadpool/Executor.java
@@ -0,0 +1,159 @@
+/*******************************************************************************
+ * 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.util.impl.tpt.threadpool;
+
+import java.lang.reflect.Method;
+import java.security.*;
+import org.eclipse.equinox.internal.util.UtilActivator;
+import org.eclipse.equinox.internal.util.impl.tpt.ServiceFactoryImpl;
+import org.eclipse.equinox.internal.util.threadpool.ThreadContext;
+
+/**
+ * @author Pavlin Dobrev
+ * @version 1.0
+ */
+
+public class Executor extends Thread implements ThreadContext {
+
+ static Method setCCL;
+ static Object[] args;
+ static {
+ try {
+ setCCL = Thread.class.getMethod("setContextClassLoader", new Class[] {ClassLoader.class});
+ args = new Object[] {null};
+ } catch (Throwable ignore) {
+ }
+ }
+
+ public static final String iname = "[ThreadPool Manager] - Idle Thread";
+ public static final String nullname = "[ThreadPool Manager] - Occupied Thread ";
+ public static final String xname = "ThreadPool Manager Thread";
+
+ ThreadPoolFactoryImpl factory;
+ boolean accessed = false;
+
+ private Runnable job = null;
+
+ private boolean terminated = false;
+
+ AccessControlContext acc;
+ PEA pea;
+
+ public synchronized void setRunnable(Runnable job, String name, ThreadPoolFactoryImpl factory, AccessControlContext acc) {
+
+ this.job = job;
+ this.factory = factory;
+
+ if (ServiceFactoryImpl.useNames)
+ setName(name == null ? nullname : name);
+
+ this.acc = acc;
+
+ notify();
+ }
+
+ public void run() {
+ while (!terminated) {
+ if (job != null) {
+ try {
+ if (UtilActivator.debugLevel == 2 && UtilActivator.LOG_DEBUG) {
+ UtilActivator.log.debug(0x0100, 10003, getName(), null, false);
+ }
+
+ accessed = true;
+ if (acc != null) {
+ if (pea == null)
+ pea = new PEA();
+ pea.job = job;
+ AccessController.doPrivileged(pea, acc);
+ } else
+ job.run();
+ } catch (Throwable t) {
+ try { // fix memory leak
+ throw new Exception();
+ } catch (Exception _) {
+ }
+ if (ServiceFactoryImpl.log != null) {
+ ServiceFactoryImpl.log.error("[ThreadPool Manager]\r\nException while executing: \r\nNAME: " + this + "\r\nJOB: " + job + "\r\n", t);
+ }
+
+ }
+ if (UtilActivator.debugLevel == 2 && UtilActivator.LOG_DEBUG) {
+ UtilActivator.log.debug(0x0100, 10004, getName(), null, false);
+ }
+ job = null;
+ if (ServiceFactoryImpl.useNames)
+ setName(iname);
+ if (ThreadPoolManagerImpl.threadPool == null || (!ThreadPoolManagerImpl.threadPool.releaseObject(this))) {
+ terminated = true;
+ continue;
+ }
+ }
+
+ if (this.job != null) {
+ continue;
+ }
+ synchronized (this) {
+ if (this.job != null || terminated) {
+ continue;
+ }
+
+ try {
+ wait();
+ } catch (InterruptedException ie) {
+ }
+ }
+ }
+
+ clear();
+ }
+
+ void clear() {
+ job = null;
+ }
+
+ public synchronized void terminate() {
+ terminated = true;
+ notify();
+ }
+
+ public Executor() {
+ super(ServiceFactoryImpl.useNames ? iname : xname);
+ if (setCCL != null)
+ try {
+ setCCL.invoke(this, args);
+ } catch (Throwable ignore) {
+ }
+ start();
+ }
+
+ public Runnable getRunnable() {
+ return job;
+ }
+
+ public void setPriorityI(int p) {
+ if (this.getPriority() != p) {
+ setPriority(p);
+ }
+ }
+}
+
+class PEA implements PrivilegedAction {
+
+ Runnable job;
+
+ public Object run() {
+ job.run();
+ return null;
+ }
+}
diff --git a/bundles/org.eclipse.equinox.util/src/org/eclipse/equinox/internal/util/impl/tpt/threadpool/Job.java b/bundles/org.eclipse.equinox.util/src/org/eclipse/equinox/internal/util/impl/tpt/threadpool/Job.java
new file mode 100644
index 000000000..1763e2400
--- /dev/null
+++ b/bundles/org.eclipse.equinox.util/src/org/eclipse/equinox/internal/util/impl/tpt/threadpool/Job.java
@@ -0,0 +1,106 @@
+/*******************************************************************************
+ * 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.util.impl.tpt.threadpool;
+
+import java.security.AccessControlContext;
+import org.eclipse.equinox.internal.util.pool.ObjectCreator;
+
+/**
+ * @author Pavlin Dobrev
+ * @version 1.0
+ */
+
+class Job implements ObjectCreator {
+
+ public Runnable run;
+
+ public String name;
+
+ public String context;
+
+ public int priority = -1;
+ public ThreadPoolFactoryImpl factory;
+
+ AccessControlContext acc;
+
+ private void setJob(Runnable run, String name, int priority, ThreadPoolFactoryImpl factory, AccessControlContext acc) {
+ this.run = run;
+ this.name = name;
+ this.priority = priority;
+ this.factory = factory;
+ this.acc = acc;
+ }
+
+ public Object getInstance() {
+ return new Job();
+ }
+
+ public Job root = null;
+
+ public Job last = null;
+
+ private Job next;
+
+ int counter = 0;
+
+ public Job addJob(Runnable run, String name, int priority, ThreadPoolFactoryImpl factory, AccessControlContext acc) {
+ Job tmp = (Job) (ThreadPoolManagerImpl.jobPool.getObject());
+ counter++;
+ tmp.setJob(run, name, priority, factory, acc);
+ if (root == null) {
+ root = tmp;
+ last = tmp;
+ return tmp;
+ }
+ last.next = tmp;
+ last = tmp;
+ return tmp;
+ }
+
+ public void addJob(Job j) {
+ counter++;
+ if (root == null) {
+ root = j;
+ last = j;
+ return;
+ }
+ last.next = j;
+ last = j;
+ }
+
+ private void clear() {
+ next = null;
+ }
+
+ public void fullClear() {
+ next = null;
+ run = null;
+ name = null;
+ context = null;
+ acc = null;
+ }
+
+ public Job getJob() {
+ Job r = null;
+ if (root == null) {
+ return null;
+ }
+ counter--;
+ r = root;
+ root = root.next;
+ if (root == null)
+ last = root;
+ r.clear();
+ return r;
+ }
+}
diff --git a/bundles/org.eclipse.equinox.util/src/org/eclipse/equinox/internal/util/impl/tpt/threadpool/ThreadPoolFactoryImpl.java b/bundles/org.eclipse.equinox.util/src/org/eclipse/equinox/internal/util/impl/tpt/threadpool/ThreadPoolFactoryImpl.java
new file mode 100644
index 000000000..167f00db0
--- /dev/null
+++ b/bundles/org.eclipse.equinox.util/src/org/eclipse/equinox/internal/util/impl/tpt/threadpool/ThreadPoolFactoryImpl.java
@@ -0,0 +1,162 @@
+/*******************************************************************************
+ * 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.util.impl.tpt.threadpool;
+
+import java.security.AccessControlContext;
+import java.security.AccessController;
+import org.eclipse.equinox.internal.util.UtilActivator;
+import org.eclipse.equinox.internal.util.impl.tpt.ServiceFactoryImpl;
+import org.eclipse.equinox.internal.util.ref.Log;
+import org.eclipse.equinox.internal.util.threadpool.ThreadPoolFactory;
+import org.eclipse.equinox.internal.util.threadpool.ThreadPoolManager;
+
+/**
+ * @author Pavlin Dobrev
+ * @version 1.0
+ */
+
+public class ThreadPoolFactoryImpl extends ServiceFactoryImpl implements ThreadPoolManager, ThreadPoolFactory {
+
+ public static ThreadPoolManagerImpl threadPool;
+ private int limit;
+ private int used = 0;
+ private Job queue;
+ private static int defaultPercent;;
+
+ public ThreadPoolFactoryImpl(String bundleName, Log log) {
+
+ super(bundleName, log);
+ threadPool = ThreadPoolManagerImpl.getThreadPool();
+ defaultPercent = UtilActivator.getInteger("equinox.util.threadpool.percent", 30);
+ limit = (ThreadPoolManagerImpl.tMaximum * defaultPercent) / 100;
+ if (limit == 0)
+ limit = 1;
+ queue = new Job();
+ }
+
+ public ThreadPoolFactoryImpl(String bundleName, int size) {
+ super(bundleName);
+ limit = size;
+ if (limit == 0)
+ limit = 1;
+ queue = new Job();
+ }
+
+ public ThreadPoolFactoryImpl(String bundleName) {
+ this(bundleName, (ThreadPoolManagerImpl.tMaximum * defaultPercent) / 100);
+ }
+
+ public Object getInstance(String bundleName) {
+ if (threadPool == null)
+ throw new RuntimeException("ServiceFactory is currently off!");
+ return new ThreadPoolFactoryImpl(bundleName);
+ }
+
+ public static void stopThreadPool() {
+ ThreadPoolManagerImpl tmp = threadPool;
+ threadPool = null;
+ tmp.clear();
+ }
+
+ public ThreadPoolManager getThreadPool(int size, boolean sizeIsInPercents) {
+ if (threadPool == null)
+ throw new RuntimeException("[ThreadPool] ThreadPool is inaccessible");
+
+ if (sizeIsInPercents) {
+ size = (ThreadPoolManagerImpl.tMaximum * size) / 100;
+ }
+ if (size <= 0) {
+ size = 1;
+ }
+ return new ThreadPoolFactoryImpl(bundleName, size);
+ }
+
+ public void execute(Runnable job, String name) {
+ execute(job, Thread.NORM_PRIORITY, name);
+ }
+
+ public void execute0(Runnable job, int priority, String name, AccessControlContext acc) {
+ if (job == null || name == null) {
+ throw new IllegalArgumentException("the job or the name parameter is/are null");
+ }
+
+ if (ServiceFactoryImpl.useNames)
+ name = name + bundleName;
+
+ ThreadPoolManagerImpl tmp = threadPool;
+
+ if (tmp != null) {
+ synchronized (tmp.getSyncMonitor()) {
+ if (used >= limit) {
+ if (UtilActivator.LOG_DEBUG) {
+ UtilActivator.log.debug("In Bundle Queue: " + name + ", bundle queue size: " + queue.counter, null);
+ }
+ queue.addJob(job, name, priority, this, acc);
+
+ return;
+ }
+
+ used++;
+ }
+
+ tmp.execute(job, priority, name, this, acc
+
+ );
+ } else
+ throw new RuntimeException("[ThreadPool] ThreadPool is inaccessible");
+ }
+
+ public void execute(Runnable job, int priority, String name, AccessControlContext acc) {
+ execute0(job, priority, name, acc
+
+ );
+ }
+
+ public void execute(Runnable job, int priority, String name) {
+ execute0(job, priority, name, (Log.security() ? AccessController.getContext() : null));
+ }
+
+ public Executor getExecutor() {
+ ThreadPoolManagerImpl tmp = threadPool;
+ if (tmp != null) {
+ synchronized (tmp.getSyncMonitor()) {
+ if (used < limit) {
+ Executor ex = tmp.getExecutor();
+ if (ex != null)
+ used++;
+ return ex;
+ }
+ }
+ }
+ return null;
+ }
+
+ void finished() {
+ Job job = queue.getJob();
+
+ if (job != null) {
+ if (UtilActivator.LOG_DEBUG) {
+ UtilActivator.log.debug("To threadpool queue: " + job.name + ", queue size: " + threadPool.waiting.counter, null);
+ }
+ threadPool.waiting.addJob(job);
+ } else {
+ used--;
+ }
+ }
+
+ public void reset() {
+ if (threadPool != null) {
+ threadPool.reset();
+ }
+ }
+}
diff --git a/bundles/org.eclipse.equinox.util/src/org/eclipse/equinox/internal/util/impl/tpt/threadpool/ThreadPoolManagerImpl.java b/bundles/org.eclipse.equinox.util/src/org/eclipse/equinox/internal/util/impl/tpt/threadpool/ThreadPoolManagerImpl.java
new file mode 100644
index 000000000..87ff3ed35
--- /dev/null
+++ b/bundles/org.eclipse.equinox.util/src/org/eclipse/equinox/internal/util/impl/tpt/threadpool/ThreadPoolManagerImpl.java
@@ -0,0 +1,253 @@
+/*******************************************************************************
+ * 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.util.impl.tpt.threadpool;
+
+import java.security.*;
+import org.eclipse.equinox.internal.util.UtilActivator;
+import org.eclipse.equinox.internal.util.impl.tpt.ServiceFactoryImpl;
+import org.eclipse.equinox.internal.util.pool.ObjectPool;
+import org.eclipse.equinox.internal.util.timer.TimerListener;
+
+/**
+ * @author Pavlin Dobrev
+ * @version 1.0
+ */
+
+public class ThreadPoolManagerImpl extends ObjectPool implements TimerListener, PrivilegedAction {
+
+ static ThreadPoolManagerImpl threadPool = null;
+
+ static ObjectPool jobPool;
+
+ private int used = 0;
+ static int tMaximum = 0;
+
+ Job waiting = new Job();
+
+ private static String pAutoMaximum = "equinox.util.threadpool.autoMaximum";
+
+ private static String pMin = "equinox.util.threadpool.minThreads";
+
+ private static String pMax = "equinox.util.threadpool.maxThreads";
+
+ private static String pIgnoreMax = "equinox.util.threadpool.ignoreMaximum";
+
+ private static int defMin = 4;
+
+ private static int defMax = 48;
+
+ private static int MAX_WAITING = 20;
+
+ private static float MAX_OVERLOAD = 0.10F;
+
+ private static boolean ignoreMax;
+ private static boolean autoMax;
+
+ private ThreadPoolManagerImpl(int i, int j, int m) {
+ super((Class) null, i, j, m);
+ tMaximum = i * j;
+ ignoreMax = UtilActivator.getBoolean(pIgnoreMax);
+ autoMax = UtilActivator.getBoolean(pAutoMaximum);
+ jobPool = new ObjectPool(waiting, 5, 8, 4);
+ }
+
+ public static ThreadPoolManagerImpl getThreadPool() {
+ if (threadPool == null) {
+ int intSize = UtilActivator.getInteger(pMin, defMin);
+ int factor = UtilActivator.getInteger(pMax, defMax);
+ intSize = intSize < 2 ? 2 : intSize;
+ if (intSize > factor) {
+ factor = (int) (intSize * 1.5 + 0.5);
+ }
+ threadPool = new ThreadPoolManagerImpl(intSize, (factor / intSize), intSize);
+ }
+ return threadPool;
+ }
+
+ public void clear() {
+ shrink(-1);
+ threadPool = null;
+ }
+
+ public Object getInstance() throws Exception {
+ Object result = (ServiceFactoryImpl.privileged()) ? AccessController.doPrivileged(this) : new Executor();
+
+ return result;
+ }
+
+ public Object run() {
+ return new Executor();
+ }
+
+ public Object getObject() {
+ try {
+ return super.getObject();
+ } catch (Throwable tw) {
+ if (ServiceFactoryImpl.log != null) {
+ ServiceFactoryImpl.log.error("Unable to create more threads!\r\nActive Thread Pool tasks: " + used, tw);
+ }
+ }
+ return null;
+ }
+
+ public Executor getExecutor() {
+ synchronized (getSyncMonitor()) {
+ if (used < tMaximum || ignoreMax) {
+ Executor e = (Executor) getObject();
+ if (e != null) {
+ used++;
+ return e;
+ }
+ }
+ }
+ return null;
+ }
+
+ protected void shrink(int count) {
+ synchronized (getSyncMonitor()) {
+ dontExtend = true;
+ int x, y;
+ for (; nextFree > count; nextFree--) {
+ x = nextFree / factor;
+ y = nextFree % factor;
+ Executor e = (Executor) buff[x][y];
+ buff[x][y] = null;
+ e.terminate();
+ }
+ }
+ }
+
+ public void shrink() {
+ shrink(minimumFill - 1);
+ dontExtend = false;
+ }
+
+ public boolean releaseObject(Object obj) {
+ Job tmp = null;
+ Executor x = (Executor) obj;
+
+ synchronized (getSyncMonitor()) {
+ x.factory.finished();
+
+ if (used <= tMaximum || ignoreMax) {
+ tmp = waiting.getJob();
+ }
+ }
+
+ if (tmp == null) {
+ used--;
+ x.clear();
+ x.setPriorityI(Thread.NORM_PRIORITY);
+ return super.releaseObject(obj);
+ }
+ if (UtilActivator.LOG_DEBUG) {
+ UtilActivator.log.debug(0x0100, 10005, tmp.name, null, false);
+ }
+ x.setPriorityI(tmp.priority);
+
+ x.setRunnable(tmp.run, tmp.name, tmp.factory, tmp.acc);
+ tmp.fullClear();
+ jobPool.releaseObject(tmp);
+ return true;
+ }
+
+ public void timer(int event) {
+ int count = 0;
+ int all = 0;
+ synchronized (getSyncMonitor()) {
+ for (int i = 0; i < buff.length; i++) {
+ if (buff[i] != null) {
+ for (int j = 0; j < buff[i].length; j++) {
+ Executor e = (Executor) buff[i][j];
+ if (e != null) {
+ all++;
+ if (!e.accessed)
+ count++;
+ else
+ e.accessed = false;
+ }
+ }
+ }
+ }
+ if (count > 0 && all > minimumFill - 1 && all > count) {
+ /*
+ * keep in mind current thread - shrinking one more, since the
+ * current thread will be back in pool
+ */
+ if (count > minimumFill)
+ shrink(count - 2);
+ else
+ shrink(minimumFill - 2);
+ dontExtend = false;
+ }
+ }
+ }
+
+ public void execute(Runnable job, int priority, String name, ThreadPoolFactoryImpl factory, AccessControlContext acc) {
+ Executor ex = null;
+ synchronized (getSyncMonitor()) {
+ if (used < tMaximum || ignoreMax) {
+ ex = (Executor) getObject();
+ }
+ if (ex != null) {
+ used++;
+ } else {
+ addInTasksQueue(job, name, priority, factory, acc);
+
+ return;
+ }
+ }
+
+ ex.setPriorityI(priority);
+ ex.setRunnable(job, name, factory, acc);
+ }
+
+ private void addInTasksQueue(Runnable job, String name, int priority, ThreadPoolFactoryImpl factory, AccessControlContext acc) {
+
+ waiting.addJob(job, name, priority, factory, acc);
+ if (UtilActivator.LOG_DEBUG) {
+ UtilActivator.log.debug("In Threadpool Queue: " + name + ", queue size:" + waiting.counter, null);
+ }
+ if (autoMax && waiting.counter > MAX_WAITING) {
+ Executor ex = (Executor) getObject();
+ if (ex != null) {
+ tMaximum += MAX_WAITING;
+ MAX_WAITING += (int) (MAX_WAITING * MAX_OVERLOAD);
+ for (Job j = waiting.getJob(); j != null; j = waiting.getJob()) {
+ if (ex == null) {
+ ex = (Executor) getObject();
+ }
+ if (ex != null) {
+ used++;
+ ex.setPriorityI(j.priority);
+ ex.setRunnable(j.run, j.name, factory, acc);
+ ex = null;
+ } else {
+ waiting.addJob(j.run, j.name, j.priority, j.factory, acc);
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ public void reset() {
+ shrink(-1);
+ dontExtend = false;
+ }
+
+ public Object getSyncMonitor() {
+ return buff;
+ }
+
+}
diff --git a/bundles/org.eclipse.equinox.util/src/org/eclipse/equinox/internal/util/impl/tpt/timer/TimerFactory.java b/bundles/org.eclipse.equinox.util/src/org/eclipse/equinox/internal/util/impl/tpt/timer/TimerFactory.java
new file mode 100644
index 000000000..3dfe75c69
--- /dev/null
+++ b/bundles/org.eclipse.equinox.util/src/org/eclipse/equinox/internal/util/impl/tpt/timer/TimerFactory.java
@@ -0,0 +1,81 @@
+/*******************************************************************************
+ * 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.util.impl.tpt.timer;
+
+import org.eclipse.equinox.internal.util.impl.tpt.ServiceFactoryImpl;
+import org.eclipse.equinox.internal.util.impl.tpt.threadpool.ThreadPoolFactoryImpl;
+import org.eclipse.equinox.internal.util.ref.Log;
+import org.eclipse.equinox.internal.util.timer.Timer;
+import org.eclipse.equinox.internal.util.timer.TimerListener;
+
+/**
+ * @author Pavlin Dobrev
+ * @version 1.0
+ */
+
+public class TimerFactory extends ServiceFactoryImpl implements Timer {
+ private static TimerImpl timer;
+
+ public TimerFactory(String bundleName, ThreadPoolFactoryImpl factory, Log log) {
+
+ super(bundleName, log);
+ timer = new TimerImpl(factory);
+ }
+
+ public TimerFactory(String bundleName) {
+ super(bundleName);
+ }
+
+ public Object getInstance(String bundleName) {
+ if (timer == null)
+ throw new RuntimeException("ServiceFactory is currently off!");
+ return new TimerFactory(bundleName);
+ }
+
+ public void notifyAfterMillis(TimerListener listener, long timePeriod, int event) throws IllegalArgumentException {
+ addNotifyListener(listener, Thread.NORM_PRIORITY, Timer.ONE_SHOT_TIMER, timePeriod, event);
+ }
+
+ public void notifyAfterMillis(TimerListener listener, int priority, long timePeriod, int event) throws IllegalArgumentException {
+ addNotifyListener(listener, priority, Timer.ONE_SHOT_TIMER, timePeriod, event);
+ }
+
+ public void notifyAfter(TimerListener listener, int timePeriod, int event) throws IllegalArgumentException {
+ addNotifyListener(listener, Thread.NORM_PRIORITY, Timer.ONE_SHOT_TIMER, timePeriod * 1000, event);
+ }
+
+ public void notifyAfter(TimerListener listener, int priority, int timePeriod, int event) throws IllegalArgumentException {
+ addNotifyListener(listener, priority, Timer.ONE_SHOT_TIMER, timePeriod * 1000, event);
+ }
+
+ public void addNotifyListener(TimerListener listener, int priority, int timerType, long periodMilis, int event) {
+ TimerImpl tmp = timer;
+ if (tmp == null)
+ throw new RuntimeException("This is a zombie!");
+ tmp.addNotifyListener(listener, priority, timerType, periodMilis, event, bundleName);
+ }
+
+ public static void stopTimer() {
+ if (timer != null) {
+ timer.terminate();
+ timer = null;
+ }
+ }
+
+ public void removeListener(TimerListener listener, int event) {
+ TimerImpl tmp = timer;
+ if (tmp == null)
+ throw new RuntimeException("This is a zombie!");
+ tmp.removeListener(listener, event);
+ }
+}
diff --git a/bundles/org.eclipse.equinox.util/src/org/eclipse/equinox/internal/util/impl/tpt/timer/TimerImpl.java b/bundles/org.eclipse.equinox.util/src/org/eclipse/equinox/internal/util/impl/tpt/timer/TimerImpl.java
new file mode 100644
index 000000000..a8dd50eaa
--- /dev/null
+++ b/bundles/org.eclipse.equinox.util/src/org/eclipse/equinox/internal/util/impl/tpt/timer/TimerImpl.java
@@ -0,0 +1,277 @@
+/*******************************************************************************
+ * 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.util.impl.tpt.timer;
+
+import java.security.*;
+import java.util.Hashtable;
+import org.eclipse.equinox.internal.util.UtilActivator;
+import org.eclipse.equinox.internal.util.impl.tpt.ServiceFactoryImpl;
+import org.eclipse.equinox.internal.util.impl.tpt.threadpool.Executor;
+import org.eclipse.equinox.internal.util.impl.tpt.threadpool.ThreadPoolFactoryImpl;
+import org.eclipse.equinox.internal.util.pool.ObjectPool;
+import org.eclipse.equinox.internal.util.ref.Log;
+import org.eclipse.equinox.internal.util.timer.Timer;
+import org.eclipse.equinox.internal.util.timer.TimerListener;
+
+/**
+ * @author Pavlin Dobrev
+ * @version 1.0
+ */
+
+public class TimerImpl implements Runnable {
+
+ static Hashtable nodes;
+ static ObjectPool nodePool;
+
+ static ThreadPoolFactoryImpl threadPool;
+
+ private TimerQueue queue;
+ private boolean terminated = false;
+ private Object sync = new Object();
+ private Thread th;
+
+ public TimerImpl(ThreadPoolFactoryImpl threadPool) {
+ nodePool = new ObjectPool(new TimerQueueNode(), 2, 4, 2);
+ TimerImpl.threadPool = threadPool;
+ nodes = new Hashtable(10);
+ queue = new TimerQueue();
+ try {
+ th = ((ServiceFactoryImpl.privileged()) ? getOne() : new Thread(this, "[Timer] - Main Queue Handler"));
+ try {
+ String str = UtilActivator.bc.getProperty("equinox.timer.priority");
+ if (str != null)
+ th.setPriority(Integer.parseInt(str));
+ } catch (Throwable ignored) {
+ }
+ th.start();
+ } catch (Exception e) {
+ throw new RuntimeException("Can not start Timer thread!" + e.toString());
+ }
+ }
+
+ public void run() {
+ TimerQueueNode n = null;
+ while (!terminated) {
+ synchronized (sync) {
+ if (n == null && queue.isEmpty()) {
+ try {
+ sync.wait();
+ } catch (Exception e) {
+ }
+ // todo check if isEmpty is necessary
+ if (queue.isEmpty() || terminated) {
+ continue;
+ }
+ }
+ }
+ synchronized (queue) {
+ n = queue.getMin();
+ while (n != null && !n.enabled) {
+ queue.removeMin();
+ n.returnInPool();
+ n = queue.getMin();
+ }
+ if (n == null)
+ continue;
+ long current = System.currentTimeMillis();
+ if (n.runOn <= current) {
+ switch (n.type) {
+ case (Timer.ONE_SHOT_TIMER) : {
+ threadPool.execute0(n, n.priority, n.getEName(), n.acc);
+ queue.removeMin();
+ nodes.remove(n);
+ break;
+ }
+ case (Timer.ONE_SHOT_TIMER_NO_DELAY) : {
+ Executor e = threadPool.getExecutor();
+ if (e != null) {
+ e.setPriorityI(n.priority);
+ e.setRunnable(n, n.getEName(), threadPool, n.acc);
+ } else {
+ Thread th = new Thread(n, n.getEName());
+ th.setPriority(n.priority);
+ th.start();
+ }
+ queue.removeMin();
+ nodes.remove(n);
+ break;
+ }
+ case (Timer.PERIODICAL_TIMER) : {
+ threadPool.execute0(n, n.priority, n.getEName(), n.acc);
+ n.runOn += n.period;
+ if (n.runOn < current) { // time changed
+ n.runOn = current + n.period;
+ }
+ queue.rescheduleMin(n.runOn);
+ break;
+ }
+ case (Timer.PERIODICAL_TIMER_NO_DELAY) : {
+ Executor e = threadPool.getExecutor();
+ if (e != null) {
+ e.setPriorityI(n.priority);
+ e.setRunnable(n, n.getEName(), threadPool, n.acc);
+ } else {
+ Thread th = new Thread(n, n.getEName());
+ th.setPriority(n.priority);
+ th.start();
+ }
+ if (n.runOn < current) { // time changed
+ n.runOn = current + n.period;
+ }
+ queue.rescheduleMin(n.runOn);
+ }
+ }
+ continue;
+ }
+ }
+ synchronized (sync) {
+ long tmpWait;
+ if (n != null && (tmpWait = n.runOn - System.currentTimeMillis()) > 0) {
+ try {
+ sync.wait(tmpWait);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ TimerQueueNode tmp = null;
+ synchronized (queue) {
+ tmp = queue.getMin();
+ if (tmp != n) {
+ n = tmp;
+ }
+ }
+ /* what's this for - we'll continue in any case */
+ continue;
+ }
+ }
+ }// while (!terminated)
+ nodePool.clear();
+ nodePool = null;
+ nodes.clear();
+ nodes = null;
+ queue = null;
+ }
+
+ public void terminate() {
+ terminated = true;
+ synchronized (sync) {
+ sync.notify();
+ }
+ try {
+ th.join();
+ } catch (InterruptedException ie) {
+ }
+ }
+
+ private void put(TimerListener listener, int priority, int timerType, long periodMilis, int event, String name, AccessControlContext acc) {
+ if (terminated || nodePool == null) {
+ throw new RuntimeException("This Instance is a ZOMBIE!!!" + terminated + " " + nodePool);
+ }
+
+ TimerQueueNode n = (TimerQueueNode) nodePool.getObject();
+ n.setEvent(listener, priority, timerType, System.currentTimeMillis() + periodMilis, periodMilis, event, name, acc);
+ TimerQueueNode tmp = (TimerQueueNode) nodes.remove(n);
+ if (tmp != null) {
+ synchronized (queue) {
+ queue.removeTimerNode(tmp);
+ }
+ tmp.returnInPool();
+ }
+ nodes.put(n, n);
+ TimerQueueNode nx;
+ synchronized (queue) {
+ queue.add(n);
+ nx = queue.getMin();
+ }
+ if (nx == n) {
+ synchronized (sync) {
+ sync.notifyAll();
+ }
+ }
+ }
+
+ void addNotifyListener(TimerListener listener, int priority, int timerType, long periodMilis, int event, String name) {
+ if (timerType < Timer.ONE_SHOT_TIMER || timerType > Timer.PERIODICAL_TIMER_NO_DELAY) {
+ throw new IllegalArgumentException("Invalid Timer Type");
+ }
+ if (listener != null) {
+ if (priority >= Thread.MIN_PRIORITY && priority <= Thread.MAX_PRIORITY) {
+ if (periodMilis > 0) {
+ AccessControlContext acc = Log.security() ? AccessController.getContext() : null;
+ put(listener, priority, timerType, periodMilis, event, name, acc);
+ } else {
+ throw new IllegalArgumentException("Time period must be positive!");
+ }
+ } else {
+ throw new IllegalArgumentException("Priority must be between Thread.MIN_PRIORITY and Thread.MAX_PRIORITY!");
+ }
+ } else {
+ throw new IllegalArgumentException("The timer listener is null");
+ }
+ }
+
+ public void removeListener(TimerListener listener, int event) {
+ TimerQueueNode rmTmp = (TimerQueueNode) nodePool.getObject();
+ rmTmp.setEvent(listener, 0, 0, 0, 0, event, null, null);
+ TimerQueueNode old = (TimerQueueNode) nodes.remove(rmTmp);
+ if (old != null) {
+ synchronized (queue) {
+ queue.removeTimerNode(old);
+ }
+ old.returnInPool();
+ }
+ rmTmp.returnInPool();
+ }
+
+ private class PrivilegedActionImpl implements PrivilegedAction {
+ private Runnable runnable = null;
+ private boolean locked = false;
+ private boolean waiting = false;
+
+ PrivilegedActionImpl() {
+ }
+
+ public synchronized void set(Runnable runnable) {
+ while (locked) {
+ waiting = true;
+ try {
+ wait();
+ } catch (Exception _) {
+ }
+ waiting = false;
+ }
+ locked = true;
+ this.runnable = runnable;
+ }
+
+ public Object run() {
+ Runnable runnableLocal = null;
+ synchronized (this) {
+ runnableLocal = this.runnable;
+ this.runnable = null;
+ locked = false;
+ if (waiting)
+ notifyAll();
+ }
+ return new Thread(runnableLocal, "[Timer] - Main Queue Handler");
+ }
+ }
+
+ public Thread getOne() throws Exception {
+ if (action == null)
+ action = new PrivilegedActionImpl();
+ action.set(this);
+ return (Thread) AccessController.doPrivileged(action);
+ }
+
+ PrivilegedActionImpl action = null;
+}
diff --git a/bundles/org.eclipse.equinox.util/src/org/eclipse/equinox/internal/util/impl/tpt/timer/TimerQueue.java b/bundles/org.eclipse.equinox.util/src/org/eclipse/equinox/internal/util/impl/tpt/timer/TimerQueue.java
new file mode 100644
index 000000000..770acae7f
--- /dev/null
+++ b/bundles/org.eclipse.equinox.util/src/org/eclipse/equinox/internal/util/impl/tpt/timer/TimerQueue.java
@@ -0,0 +1,204 @@
+/*******************************************************************************
+ * 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.util.impl.tpt.timer;
+
+/**
+ * @author Pavlin Dobrev
+ * @version 1.0
+ */
+
+class TimerQueue {
+
+ static final int POOL_SIZE = 20;
+ QueueElement[] pool = new QueueElement[POOL_SIZE];
+ int filled = 0;
+
+ QueueElement first;
+ QueueElement lastInserted;
+
+ TimerQueue() {
+ }
+
+ /**
+ * Adds a new task to the priority queue.
+ */
+ void add(TimerQueueNode task) {
+ QueueElement toAdd = getQueueElement();
+ toAdd.node = task;
+
+ if (first == null) {
+ first = toAdd;
+ } else {
+ insertElement(toAdd);
+ }
+ }
+
+ /**
+ * Return the "head task" of the priority queue. (The head task is an task
+ * with the lowest nextExecutionTime.)
+ */
+ TimerQueueNode getMin() {
+ return (first != null) ? first.node : null;
+ }
+
+ /**
+ * Remove the head task from the priority queue.
+ */
+ void removeMin() {
+ if (first != null) {
+ if (lastInserted == first) {
+ lastInserted = null;
+ }
+ if (filled < POOL_SIZE) {
+ QueueElement toFree = first;
+ first = first.next;
+ freeQueueElement(toFree);
+ } else {
+ first = first.next;
+ }
+ }
+ }
+
+ /**
+ * Sets the nextExecutionTime associated with the head task to the specified
+ * value, and adjusts priority queue accordingly.
+ */
+ void rescheduleMin(long newTime) {
+ first.node.runOn = newTime;
+ if (first.next != null) {
+ if (lastInserted == first) {
+ lastInserted = null;
+ }
+ QueueElement el = first;
+ first = first.next;
+ el.next = null;
+ insertElement(el);
+ }
+ }
+
+ /**
+ * Returns true if the priority queue contains no elements.
+ */
+ boolean isEmpty() {
+ return first == null;
+ }
+
+ /**
+ * Removes all elements from the priority queue.
+ */
+ void clear() {
+ while (first != null) {
+ first.node.returnInPool();
+ first = first.next;
+ }
+ lastInserted = null;
+ }
+
+ void insertElement(QueueElement newElement) {
+ if (first.node.runOn >= newElement.node.runOn) {
+ /* private case - insert in the beginning of the queue */
+ newElement.next = first;
+ first = newElement;
+ } else if (lastInserted != null) {
+ if (lastInserted.node.runOn == newElement.node.runOn) {
+ QueueElement tmp = lastInserted.next;
+ lastInserted.next = newElement;
+ newElement.next = tmp;
+ } else if (lastInserted.node.runOn > newElement.node.runOn) {
+ // System.out.println("insert 1");
+ doInsertElement(first, newElement);
+ } else {
+ // System.out.println("insert 2");
+ doInsertElement(lastInserted, newElement);
+ }
+ } else {
+ // System.out.println("insert 3");
+ doInsertElement(first, newElement);
+ }
+ }
+
+ /**
+ * elToInsert should not be placed before firstEl, because firstEl may not
+ * be the first element of the queue
+ */
+ void doInsertElement(QueueElement firstEl, QueueElement elToInsert) {
+ QueueElement tmp = firstEl;
+ QueueElement prev = firstEl;
+ while (tmp != null && tmp.node.runOn < elToInsert.node.runOn) {
+ prev = tmp;
+ tmp = tmp.next;
+ }
+ if (tmp == null) {
+ /* reached the end of the queue */
+ prev.next = elToInsert;
+ } else {
+ prev.next = elToInsert;
+ elToInsert.next = tmp;
+ }
+ lastInserted = elToInsert;
+ }
+
+ void removeTimerNode(TimerQueueNode node) {
+ QueueElement tmp = first;
+ QueueElement prev = null;
+ while (tmp != null) {
+ if (node.listener == tmp.node.listener && node.event == tmp.node.event) {
+ if (prev != null) {
+ if (lastInserted == tmp) {
+ lastInserted = prev;
+ }
+ prev.next = tmp.next;
+ if (filled < POOL_SIZE) {
+ freeQueueElement(tmp);
+ }
+ } else {
+ /* removing the first element */
+ if (lastInserted == first) {
+ lastInserted = null;
+ }
+ if (filled < POOL_SIZE) {
+ QueueElement toFree = first;
+ first = first.next;
+ freeQueueElement(toFree);
+ } else {
+ first = first.next;
+ }
+ }
+ break;
+ }
+ prev = tmp;
+ tmp = tmp.next;
+ }
+ }
+
+ private QueueElement getQueueElement() {
+ return (filled > 0) ? pool[--filled] : new QueueElement();
+ }
+
+ private void freeQueueElement(QueueElement toFree) {
+ if (filled < POOL_SIZE) {
+ pool[filled] = toFree;
+ filled++;
+ toFree.next = null;
+ toFree.node = null;
+ }
+ }
+
+ private class QueueElement {
+ QueueElement next;
+ TimerQueueNode node;
+
+ public QueueElement() {
+ }
+ }
+
+}
diff --git a/bundles/org.eclipse.equinox.util/src/org/eclipse/equinox/internal/util/impl/tpt/timer/TimerQueueNode.java b/bundles/org.eclipse.equinox.util/src/org/eclipse/equinox/internal/util/impl/tpt/timer/TimerQueueNode.java
new file mode 100644
index 000000000..38b67e517
--- /dev/null
+++ b/bundles/org.eclipse.equinox.util/src/org/eclipse/equinox/internal/util/impl/tpt/timer/TimerQueueNode.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.util.impl.tpt.timer;
+
+import java.security.AccessControlContext;
+import org.eclipse.equinox.internal.util.impl.tpt.ServiceFactoryImpl;
+import org.eclipse.equinox.internal.util.pool.ObjectCreator;
+import org.eclipse.equinox.internal.util.timer.Timer;
+import org.eclipse.equinox.internal.util.timer.TimerListener;
+
+/**
+ * @author Pavlin Dobrev
+ * @version 1.0
+ */
+
+class TimerQueueNode implements Runnable, ObjectCreator {
+ public static final String PERIODICAL_TASK_NAME = "[Timer] - Periodical Task";
+
+ public static final String PERIODICAL_NO_DELAY_TASK_NAME = "[Timer] - Periodical No Delay Task";
+
+ public static final String ONE_SHOT_TASK_NAME = "[Timer] - One Shot Task";
+
+ public static final String ONE_SHOT_NO_DELAY_TASK_NAME = "[Timer] - One Shot No Delay Task";
+
+ public TimerQueueNode() {
+ }
+
+ TimerListener listener = null;
+
+ int event;
+
+ long runOn = -1;
+
+ int type = -1;
+
+ int priority = -1;
+
+ long period = -1;
+
+ boolean running = false;
+
+ private int theHash;
+
+ String name;
+
+ boolean named = false;
+
+ String context;
+
+ AccessControlContext acc;
+
+ boolean enabled = false;
+
+ public String getEName() {
+ if (ServiceFactoryImpl.useNames && !named) {
+ named = true;
+ String tmp = null;
+ switch (type) {
+ case Timer.ONE_SHOT_TIMER : {
+ tmp = ONE_SHOT_TASK_NAME;
+ break;
+ }
+ case Timer.ONE_SHOT_TIMER_NO_DELAY : {
+ tmp = ONE_SHOT_NO_DELAY_TASK_NAME;
+ break;
+ }
+ case Timer.PERIODICAL_TIMER : {
+ tmp = PERIODICAL_TASK_NAME;
+ break;
+ }
+ case Timer.PERIODICAL_TIMER_NO_DELAY : {
+ tmp = PERIODICAL_NO_DELAY_TASK_NAME;
+ break;
+ }
+ }
+ name = (name != null) ? tmp.concat(name) : tmp;
+ }
+ return ((name == null) ? "" : name);
+ }
+
+ public void setEvent(TimerListener listener, int priority, int timerType, long runOn, long periodMilis, int event, String name, AccessControlContext acc) {
+ this.enabled = true;
+ this.listener = listener;
+ theHash = listener.hashCode() + event;
+ this.priority = priority;
+ type = timerType;
+ period = periodMilis;
+ this.runOn = runOn;
+ this.event = event;
+ this.name = name;
+ this.named = false;
+ this.acc = acc;
+ }
+
+ void returnInPool() {
+ synchronized (this) {
+ if (!enabled || (running && type == Timer.ONE_SHOT_TIMER)) {
+ /* this node has already been put in pool or will be put */
+ return;
+ }
+ clear();
+ }
+ if (TimerImpl.nodePool != null) {
+ TimerImpl.nodePool.releaseObject(this);
+ }
+ }
+
+ public void run() {
+ synchronized (this) {
+ running = true;
+ }
+ TimerListener tmp = listener;
+ try {
+ if (tmp != null && enabled) {
+ tmp.timer(event);
+ }
+ } catch (Throwable t) {
+ if (ServiceFactoryImpl.log != null) {
+ ServiceFactoryImpl.log.error("[Timer] - Error while notifying:\r\n" + tmp, t);
+ }
+ }
+ tmp = null;
+ if (type == Timer.ONE_SHOT_TIMER)
+ returnInPool();
+ running = false;
+ }
+
+ public Object getInstance() {
+ return new TimerQueueNode();
+ }
+
+ private void clear() {
+ named = false;
+ name = null;
+ enabled = false;
+ listener = null;
+ event = -1;
+ runOn = Long.MAX_VALUE;
+ type = -1;
+ acc = null;
+
+ }
+
+ public int hashCode() {
+ TimerListener lis = listener;
+ return (lis != null) ? (theHash = (lis.hashCode() + event)) : theHash;
+ }
+
+ public String toString() {
+ return "QueueNode: " + super.toString() + "\r\n" + "\t\tListener: " + listener + "\r\n" + "\t\tEvent: " + event + "\r\n" + "\t\tType: " + type + "\r\n" + "\t\trunafter: " + (runOn - System.currentTimeMillis()) + "\r\n" + "\t\tEnabled: " + enabled;
+ }
+
+ public boolean equals(Object a) {
+ if (a instanceof TimerQueueNode) {
+ TimerQueueNode b = (TimerQueueNode) a;
+ return b.listener == listener && b.event == event;
+ }
+ return false;
+ }
+}
diff --git a/bundles/org.eclipse.equinox.util/src/org/eclipse/equinox/internal/util/pool/ObjectCreator.java b/bundles/org.eclipse.equinox.util/src/org/eclipse/equinox/internal/util/pool/ObjectCreator.java
new file mode 100644
index 000000000..42c8141a9
--- /dev/null
+++ b/bundles/org.eclipse.equinox.util/src/org/eclipse/equinox/internal/util/pool/ObjectCreator.java
@@ -0,0 +1,22 @@
+/*******************************************************************************
+ * 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.util.pool;
+
+/**
+ * @author Pavlin Dobrev
+ * @version 1.0
+ */
+
+public interface ObjectCreator {
+
+ public Object getInstance() throws Exception;
+}
diff --git a/bundles/org.eclipse.equinox.util/src/org/eclipse/equinox/internal/util/pool/ObjectPool.java b/bundles/org.eclipse.equinox.util/src/org/eclipse/equinox/internal/util/pool/ObjectPool.java
new file mode 100644
index 000000000..1fa1aaba4
--- /dev/null
+++ b/bundles/org.eclipse.equinox.util/src/org/eclipse/equinox/internal/util/pool/ObjectPool.java
@@ -0,0 +1,190 @@
+/*******************************************************************************
+ * 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.util.pool;
+
+/**
+ * @author Pavlin Dobrev
+ * @version 1.0
+ */
+
+public class ObjectPool {
+
+ private Class template;
+
+ protected Object[][] buff;
+
+ protected int nextFree;
+
+ protected int size;
+
+ protected int minimumFill;
+
+ protected int factor;
+
+ protected int minfSize;
+
+ protected int minffactor;
+
+ // protected int usageGet = 0;
+
+ // protected int usageReleased = 0;
+
+ protected boolean dontExtend = false;
+
+ protected ObjectCreator oc;
+
+ public Object getInstance() throws Exception {
+ return oc != null ? oc.getInstance() : template.newInstance();
+ }
+
+ public ObjectPool(ObjectCreator oc, int size, int factor) {
+ this(null, oc, size, factor, size * factor);
+ }
+
+ public ObjectPool(Class template, int size, int factor) {
+ this(template, null, size, factor, size * factor);
+ }
+
+ public ObjectPool(Class template, int size, int factor, int minimumFill) {
+ this(template, null, size, factor, (minimumFill = (minimumFill > (size * factor)) ? (size * factor) : minimumFill));
+ }
+
+ public ObjectPool(ObjectCreator oc, int size, int factor, int minimumFill) {
+ this(null, oc, size, factor, (minimumFill = minimumFill > (size * factor) ? (size * factor) : minimumFill));
+ }
+
+ protected ObjectPool(Class template, ObjectCreator oc, int size, int factor, int minimumFill) {
+
+ if (size <= 1 || factor < 1) {
+ throw new IllegalArgumentException(size + " is less or equal to 1");
+ }
+
+ this.minimumFill = minimumFill < 1 ? 1 : minimumFill;
+ this.oc = oc;
+ if (template != null) {
+ try {
+ template.getConstructor(new Class[0]);
+ this.template = template;
+ } catch (NoSuchMethodException nsm) {
+ throw new IllegalArgumentException(template + " don't have default constructor!");
+ }
+ }
+ buff = new Object[size][];
+ this.size = size;
+ this.factor = factor;
+ minfSize = this.minimumFill / factor;
+ minffactor = this.minimumFill % factor;
+ // System.out.println("minimumFill " + this.minimumFill);
+ // System.out.println("minfSize " + minfSize);
+ // System.out.println("minffactor " + minffactor);
+ if (minimumFill <= 1) {
+ nextFree = -1;
+ } else {
+ for (int i = 0; i < (minfSize == 0 ? 1 : minfSize); i++) {
+ buff[i] = new Object[factor];
+ }
+ fill();
+ }
+ // start();
+ }
+
+ private void fill() {
+ int i = 0;
+ synchronized (buff) {
+ for (; (i < minfSize); i++) {
+ put(i, factor);
+ }
+ if (minffactor > 0) {
+ put(i, minffactor);
+ }
+ }
+ nextFree = minimumFill - 1;
+ }
+
+ private void put(int i, int count) {
+ for (int j = 0; j < count; j++) {
+ try {
+ if (buff[i] == null) {
+ buff[i] = new Object[factor];
+ }
+ buff[i][j] = getInstance();
+ nextFree = i * j;
+ } catch (Throwable t) {
+ throw new RuntimeException("buffer fill failed: " + t);
+ }
+ }
+ }
+
+ public void clear() {
+ dontExtend = true;
+ shrink(-1);
+ }
+
+ protected void shrink(int count) {
+ synchronized (buff) {
+ for (; nextFree > count; nextFree--) {
+ buff[(nextFree / factor)][nextFree % factor] = null;
+ }
+ }
+ }
+
+ public void shrink() {
+ dontExtend = true;
+ shrink(minimumFill);
+ dontExtend = false;
+ }
+
+ public Object getObject() {
+ Object tmp = null;
+ synchronized (buff) {
+ if (nextFree < 0) {
+ if (dontExtend) {
+ throw new RuntimeException();
+ }
+ if (minimumFill <= 1) {
+ try {
+ return getInstance();
+ } catch (Throwable e) {
+ throw new RuntimeException("buffer fill failed: " + e);
+ }
+ }
+ fill();
+ }
+ tmp = buff[(nextFree / factor)][(nextFree % factor)];
+ buff[(nextFree / factor)][nextFree % factor] = null;
+ nextFree--;
+ // usageGet++;
+ return tmp;
+ }
+ }
+
+ public boolean releaseObject(Object obj) {
+ // usageReleased++;
+ if (dontExtend) {
+ return false;
+ }
+ synchronized (buff) {
+ int tmp = nextFree + 1;
+ int telement = tmp / factor;
+ if ((telement) < size) {
+ if (buff[telement] == null) {
+ buff[telement] = new Object[factor];
+ }
+ buff[telement][tmp % factor] = obj;
+ nextFree = tmp;
+ return true;
+ }
+ return false;
+ }
+ }
+}
diff --git a/bundles/org.eclipse.equinox.util/src/org/eclipse/equinox/internal/util/pool/package.html b/bundles/org.eclipse.equinox.util/src/org/eclipse/equinox/internal/util/pool/package.html
new file mode 100644
index 000000000..af97828e6
--- /dev/null
+++ b/bundles/org.eclipse.equinox.util/src/org/eclipse/equinox/internal/util/pool/package.html
@@ -0,0 +1,9 @@
+<HTML>
+<HEAD>
+<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=windows-1252">
+<TITLE>org.eclipse.equinox.util.pool</TITLE>
+</HEAD>
+<BODY LINK="#0000ff" VLINK="#800080">
+<P>The object pool utility creates pools of reusable objects of certain type.</P>
+</BODY>
+</HTML>
diff --git a/bundles/org.eclipse.equinox.util/src/org/eclipse/equinox/internal/util/ref/Log.java b/bundles/org.eclipse.equinox.util/src/org/eclipse/equinox/internal/util/ref/Log.java
new file mode 100644
index 000000000..2cc95ff08
--- /dev/null
+++ b/bundles/org.eclipse.equinox.util/src/org/eclipse/equinox/internal/util/ref/Log.java
@@ -0,0 +1,819 @@
+/*******************************************************************************
+ * 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.util.ref;
+
+import java.io.*;
+import java.util.Vector;
+import org.eclipse.equinox.internal.util.UtilActivator;
+import org.eclipse.equinox.internal.util.event.Queue;
+import org.eclipse.equinox.internal.util.hash.HashIntObjNS;
+import org.eclipse.equinox.internal.util.security.PrivilegedRunner;
+import org.eclipse.equinox.internal.util.security.SecurityUtil;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceReference;
+import org.osgi.service.log.LogService;
+import org.osgi.util.tracker.ServiceTracker;
+import org.osgi.util.tracker.ServiceTrackerCustomizer;
+
+/**
+ * Log class is responsible for forwarding bundles's messages to the LogService
+ * or console output.
+ *
+ * @author Pavlin Dobrev
+ * @version 1.0
+ */
+
+public class Log implements LogInterface, ServiceTrackerCustomizer, PrivilegedRunner.PrivilegedDispatcher {
+
+ /**
+ * Flag, pointing if printingOnConsole is allowed
+ *
+ * @deprecated since osgilib verion 1.3.9 use set/get PrintOnConsole
+ */
+ public boolean printOnConsole = false;
+
+ /**
+ * Flag, pointing whether printing on console should be done if log service
+ * is not available
+ */
+ public boolean autoPrintOnConsole = false;
+
+ /**
+ * Flag, pointing if logging debuging info is allowed
+ *
+ * @deprecated since osgilib verion 1.3.9 use set/get Debug
+ */
+ public boolean debug = false;
+
+ /**
+ * Flag, pointing whether printing on console should be done for errors
+ * (exceptions) and warnings
+ */
+ private boolean logErrorLevel = false;
+
+ private ServiceTracker logTracker;
+ private ServiceReference traceRef;
+
+ protected static final SecurityUtil securityUtil = new SecurityUtil();
+
+ private boolean isClosed = false;
+
+ private long bundleId;
+ /** BundleContext to get LogService and service owner of Log object BundleId */
+ protected BundleContext bc;
+ private static Vector logs = new Vector();
+ private static Log listener;
+
+ public Log(BundleContext bc) {
+ this(bc, true);
+ }
+
+ /**
+ * Constructs a log object, used for logging information in the LogService.
+ * If the LogService is unavailble, the information is printed on the
+ * server's console.
+ *
+ * @param bc
+ * BundleContext, necessary to get LogService, in case it is
+ * started.
+ */
+ public Log(BundleContext bc, boolean initDebug) {
+ if (initDebug) {
+ debug = securityUtil.getBooleanProperty("equinox.util.ref.log.debug");
+ logErrorLevel = securityUtil.getBooleanProperty("equinox.log.errorlevel");
+ autoPrintOnConsole = securityUtil.getBooleanProperty("equinox.util.ref.log.autoPrintOnConsole");
+ printOnConsole = securityUtil.getBooleanProperty("equinox.util.ref.log.printOnConsole");
+ }
+ if (bc != null) {
+ this.bc = bc;
+ bundleId = bc.getBundle().getBundleId();
+
+ if (UtilActivator.startup && UtilActivator.points != null)
+ UtilActivator.points[0] = System.currentTimeMillis();
+
+ initSysServices();
+
+ if (UtilActivator.startup && UtilActivator.points != null)
+ UtilActivator.points[1] = System.currentTimeMillis();
+ synchronized (logs) {
+ if (listener == null)
+ initListener();
+ logs.addElement(this);
+ }
+
+ if (UtilActivator.startup && UtilActivator.points != null)
+ UtilActivator.points[2] = System.currentTimeMillis();
+ } else
+ printOnConsole = true;
+ }
+
+ private void initListener() {
+ try {
+ securityUtil.doPrivileged(this, OPEN_TYPE, null);
+ } catch (IllegalStateException ise) {
+ /* must be rethrown */
+ throw ise;
+ } catch (Throwable ignore) {
+ ignore.printStackTrace();
+ }
+ }
+
+ void initListener0() {
+ synchronized (logs) {
+ initListenerNS();
+ }
+ }
+
+ void initListenerNS() {
+ logTracker = new ServiceTracker(bc, "org.osgi.service.log.LogService", this);
+ logTracker.open();
+ listener = this;
+ }
+
+ /**
+ * Logs error messages. If <code>printOnConsole</code> is true, or if the
+ * <code>LogService</code> is unavailable, log info is printed on console.
+ *
+ * @param str
+ * Message description of the error.
+ * @param ex
+ * Throwable object, containing the stack trace; may be null.
+ */
+ public void error(String str, Throwable ex) {
+ if (isClosed)
+ return;
+
+ boolean logResult = logMessage(LogService.LOG_ERROR, str, ex);
+ if (printOnConsole || (!logResult && autoPrintOnConsole) || logErrorLevel) {
+ dumpOnConsole("ERROR ", str, bundleId, ex);
+ }
+ }
+
+ /**
+ * Logs error messages. If <code>printOnConsole</code> is true, or if the
+ * <code>LogService</code> is unavailable, log info is printed on console.
+ *
+ * @param moduleID
+ * @param msgID
+ * @param msg
+ * Message description of the error.
+ * @param t
+ * Throwable object, containing the stack trace; may be null.
+ * @param synch
+ * Weather tracer to work synchronious or not
+ */
+ public void error(int moduleID, int msgID, String msg, Throwable t, boolean synch) {
+ if (isClosed)
+ return;
+
+ boolean logResult = true;
+ if (msg != null || t != null) {
+ logResult = logMessage(LogService.LOG_ERROR, msg, t);
+ }
+ if (printOnConsole || (!logResult && autoPrintOnConsole) || logErrorLevel) {
+ dumpOnConsole(buildDebugString(moduleID, msgID, msg, "ERROR " + bundleId + " "), t);
+ }
+ }
+
+ /**
+ * Logs warning messages. If <code>printOnConsole</code> is true, or if
+ * the <code>LogService</code> is unavailable, log info is printed on
+ * console.
+ *
+ * @param str
+ * Message description of the error.
+ * @param ex
+ * Throwable object, containing the stack trace; may be null.
+ */
+ public void warning(String str, Throwable ex) {
+ if (isClosed)
+ return;
+
+ boolean logResult = logMessage(LogService.LOG_WARNING, str, ex);
+ if (printOnConsole || (!logResult && autoPrintOnConsole) || logErrorLevel) {
+ dumpOnConsole("WARNING ", str, bundleId, ex);
+ }
+ }
+
+ /**
+ * Logs warning messages. If <code>printOnConsole</code> is true, or if
+ * the <code>LogService</code> is unavailable, log info is printed on
+ * console.
+ *
+ * @param moduleID
+ * @param msgID
+ * @param msg
+ * Message description of the error.
+ * @param t
+ * Throwable object, containing the stack trace; may be null.
+ * @param synch
+ * Weather tracer to work synchronious or not
+ */
+ public void warning(int moduleID, int msgID, String msg, Throwable t, boolean synch) {
+ if (isClosed)
+ return;
+
+ boolean logResult = true;
+ if (msg != null || t != null) {
+ logResult = logMessage(LogService.LOG_WARNING, msg, t);
+ }
+ if (printOnConsole || (!logResult && autoPrintOnConsole) || logErrorLevel) {
+ dumpOnConsole(buildDebugString(moduleID, msgID, msg, "WARNING " + bundleId + " "), t);
+ }
+ }
+
+ /**
+ * Logs info messages. If <code>printOnConsole</code> is true, or if the
+ * <code>LogService</code> is unavailable, message is printed on console.
+ *
+ * @param str
+ * Message to be logged.
+ */
+ public void info(String str) {
+ if (isClosed)
+ return;
+
+ boolean logResult = logMessage(LogService.LOG_INFO, str, null);
+ if (printOnConsole || (!logResult && autoPrintOnConsole)) {
+ dumpOnConsole("INFO ", str, bundleId, null);
+ }
+ }
+
+ /**
+ * Logs info messages. If <code>printOnConsole</code> is true, or if the
+ * <code>LogService</code> is unavailable, log info is printed on console.
+ *
+ * @param moduleID
+ * @param msgID
+ * @param msg
+ * Message description of the error.
+ * @param synch
+ * Weather tracer to work synchronious or not
+ */
+ public void info(int moduleID, int msgID, String msg, boolean synch) {
+ if (isClosed)
+ return;
+
+ boolean logResult = true;
+ if (msg != null) {
+ logResult = logMessage(LogService.LOG_INFO, msg, null);
+ }
+ if (printOnConsole || (!logResult && autoPrintOnConsole)) {
+ dumpOnConsole(buildDebugString(moduleID, msgID, msg, "INFO " + bundleId + " "), null);
+ }
+ }
+
+ /**
+ * Logs debug information if <code>debug</code> flag is true. If
+ * LogService is unaccessible or printOnConsole flag is true, log info is
+ * printed on console.
+ *
+ * @param str
+ * Message description.
+ * @param ex
+ * Throwable object, containing the stack trace; may be null.
+ */
+ public void debug(String str, Throwable ex) {
+ if (!debug || isClosed)
+ return;
+
+ boolean logResult = logMessage(LogService.LOG_DEBUG, str, ex);
+ if (printOnConsole || (!logResult && autoPrintOnConsole)) {
+ dumpOnConsole("DEBUG ", str, bundleId, ex);
+ }
+ }
+
+ /**
+ * Logs debug messages. If <code>printOnConsole</code> is true, or if the
+ * <code>LogService</code> is unavailable, log info is printed on console.
+ *
+ * @param moduleID
+ * @param msgID
+ * @param msg
+ * Message description of the error.
+ * @param t
+ * Throwable object, containing the stack trace; may be null.
+ * @param synch
+ * Indicates whether tracer should log the message synchronously
+ * or not
+ */
+ public void debug(int moduleID, int msgID, String msg, Throwable t, boolean synch) {
+ debug(moduleID, msgID, msg, t, synch, false, false, true);
+ }
+
+ /**
+ * Logs debug messages. If <code>printOnConsole</code> is true, or if the
+ * <code>LogService</code> is unavailable, log info is printed on console.
+ *
+ * @param moduleID
+ * @param msgID
+ * @param msg
+ * Message description of the error.
+ * @param t
+ * Throwable object, containing the stack trace; may be null.
+ * @param synch
+ * Indicates whether tracer should log the message synchronously
+ * or not
+ * @param measurement
+ * Indicates whether the message is a measurement or not
+ */
+ public void debug(int moduleID, int msgID, String msg, Throwable t, boolean synch, boolean measurement) {
+ debug(moduleID, msgID, msg, t, synch, measurement, false, true);
+ }
+
+ /**
+ * Logs debug messages. If <code>printOnConsole</code> is true, or if the
+ * <code>LogService</code> is unavailable, log info is printed on console.
+ *
+ * @param moduleID
+ * @param msgID
+ * @param msg
+ * Message description of the error.
+ * @param t
+ * Throwable object, containing the stack trace; may be null.
+ * @param synch
+ * Indicates whether tracer should log the message synchronously
+ * or not
+ * @param measurement
+ * Indicates whether the message is a measurement or not
+ * @param display
+ * Indicates whether the message should be displayed in native
+ * GUI
+ */
+ public void debug(int moduleID, int msgID, String msg, Throwable t, boolean synch, boolean measurement, boolean display) {
+ debug(moduleID, msgID, msg, t, synch, measurement, display, true);
+ }
+
+ /**
+ * Logs debug messages. If <code>printOnConsole</code> is true, or if the
+ * <code>LogService</code> is unavailable, log info is printed on console.
+ *
+ * @param moduleID
+ * @param msgID
+ * @param msg
+ * Message description of the error.
+ * @param t
+ * Throwable object, containing the stack trace; may be null.
+ * @param synch
+ * Indicates whether tracer should log the message synchronously
+ * or not
+ * @param measurement
+ * Indicates whether the message is a measurement or not
+ * @param display
+ * Indicates whether the message should be displayed in native
+ * GUI
+ * @param logInFile
+ * Indicates whether the message should be logged into the log
+ * file or not. Used for measurements' logs.
+ */
+ public void debug(int moduleID, int msgID, String msg, Throwable t, boolean synch, boolean measurement, boolean display, boolean logInFile) {
+ if (!debug && !measurement || isClosed)
+ return;
+
+ String message = msg;
+ if (measurement) {
+ message = buildDebugString(moduleID, msgID, msg, "DEBUG " + bundleId + " ");
+ }
+
+ boolean logResult = logInFile ? true : (message == null && t == null);
+ if (logInFile && (message != null || t != null)) {
+ logResult = logMessage(LogService.LOG_DEBUG, message, t);
+ }
+
+ /* Checks are added for different framework implementations. */
+ if (printOnConsole || (!logResult && autoPrintOnConsole)) {
+ message = buildDebugString(moduleID, msgID, msg, "DEBUG " + bundleId + " ");
+ dumpOnConsole(message, t);
+ }
+ }
+
+ private void initSysServices() {
+ if (security) {
+ try {
+ securityUtil.doPrivileged(this, GET_SYS_SERVICES_TYPE, null);
+ } catch (Throwable ignore) {
+ ignore.printStackTrace();
+ }
+ }
+ }
+
+ LogService getService0() throws IllegalArgumentException {
+ synchronized (logs) {
+ ServiceReference logRef = (ServiceReference) listener.logTracker.getService();
+ LogService ls = null;
+ if (logRef != null) {
+ ls = (LogService) bc.getService(logRef);
+ }
+ return ls;
+ }
+ }
+
+ private LogService getService() throws IllegalArgumentException {
+ if (bc == null)
+ return null; // standalone hack
+ try {
+ return (LogService) securityUtil.doPrivileged(this, GET_SERVICE_TYPE, null);
+ } catch (IllegalArgumentException e) {
+ throw e;
+ } catch (Exception e) {
+ /* this will not happen */
+ e.printStackTrace();
+ throw new IllegalArgumentException(e.toString());
+ }
+ }
+
+ private boolean logMessage(int messageType, String messageText, Throwable t) {
+ LogService ls = null;
+
+ try {
+ ls = getService();
+ } catch (IllegalStateException ise) { // invalid bundle context
+ synchronized (logs) {
+ close0();
+ }
+ return false;
+ }
+ boolean result = true;
+ if (ls == null) {
+ result = false;
+ testClose(); // test the listener
+ } else {
+ try {
+ ls.log(messageType, messageText, t);
+ } catch (IllegalStateException ise) { // the log service instance
+ // is not valid
+ result = false;
+ testClose(); // test the listener
+ }
+ }
+ return result;
+ }
+
+ private void dumpOnConsole(String prefix, String msg, long bundleId, Throwable t) {
+ System.out.println(prefix + bundleId + " " + msg);
+ if (t != null) {
+ t.printStackTrace();
+ }
+ }
+
+ /**
+ * Prints a message to the console or a log dispatcher
+ *
+ * @param msg -
+ * the message to print, which contains the prefix and the
+ * bundleID in itself
+ * @param t
+ * throwable object, which stack trace should be printed
+ */
+ private void dumpOnConsole(String msg, Throwable t) {
+ System.out.println(msg);
+ if (t != null) {
+ t.printStackTrace();
+ }
+ }
+
+ private void testClose() {
+ synchronized (logs) {
+ if (listener != null)
+ try {
+ listener.bc.getBundle();
+ return;
+ } catch (IllegalStateException ise) {
+ listener.close0();
+ }
+ }
+ }
+
+ /**
+ * Releases the Log's resources: ungets LogService, removes the
+ * ServiceListener from the framework and nulls references. After invocation
+ * of this method, this Log object can be used no longer.
+ */
+ public void close() {
+ if (bc != null) {
+ if (traceRef != null) {
+ bc.ungetService(traceRef);
+ traceRef = null;
+ }
+ synchronized (logs) {
+ close0();
+ }
+ }
+ }
+
+ private boolean close0() {
+ logs.removeElement(this);
+ isClosed = true;
+ if (listener == this) {
+ try {
+ logTracker.close();
+ logTracker = null;
+ } catch (IllegalStateException ise) {
+ }
+ Log ls = null;
+ while (logs.size() > 0) {
+ ls = (Log) logs.elementAt(0);
+ try {
+ ls.initListener();
+ break;
+ } catch (IllegalStateException ise) {
+ logs.removeElementAt(0);
+ ls = null;
+ }
+ }
+ listener = ls;
+ }
+ return (listener != null);
+ }
+
+ /**
+ * enable/disable print on console
+ *
+ * @param value
+ * boolean if true enables print on console else disables it
+ */
+ public void setPrintOnConsole(boolean value) {
+ printOnConsole = value;
+ }
+
+ /**
+ * enable/disable loging of debug info
+ *
+ * @param value
+ * boolean if true enables loging of debug info else disables it
+ */
+ public void setDebug(boolean value) {
+ debug = value;
+ }
+
+ /**
+ * Gets the flag, which enables logging debug messages.
+ *
+ * @return true if debugging is enabled
+ */
+ public boolean getDebug() {
+ return debug;
+ }
+
+ /**
+ * Gets the flag, which enables printing log messages on the console.
+ *
+ * @return true if printingon console is enabled
+ */
+ public boolean getPrintOnConsole() {
+ return printOnConsole;
+ }
+
+ public Object addingService(ServiceReference reference) {
+ return reference;
+ }
+
+ public void modifiedService(ServiceReference reference, Object service) {
+ }
+
+ public void removedService(ServiceReference reference, Object service) {
+ }
+
+ private HashIntObjNS map = null;
+ private HashIntObjNS starts = null;
+
+ public void setMaps(HashIntObjNS map0, HashIntObjNS starts0) {
+ map = map0;
+ starts = starts0;
+ }
+
+ private String getModuleName(int moduleID) {
+ return (String) map.get(-moduleID);
+ }
+
+ private String getMsgValue(int msgID) {
+ String res = (String) map.get(msgID);
+ if (res == null && starts != null) {
+ try {
+ int startID = ((Integer) starts.get(msgID)).intValue();
+ res = "END OF " + (String) map.get(startID);
+ } catch (Exception e) {
+ }
+ }
+ return res;
+ }
+
+ private static final char[] chars = {']', ' ', ':', ' '};
+
+ private String buildDebugString(int moduleID, int msgID, String message, String prefix) {
+
+ if (map == null) {
+ return prefix + " [" + moduleID + "] " + msgID + " : " + (message == null ? "" : message);
+ }
+
+ StringBuffer sBuf = new StringBuffer(prefix).append("[");
+
+ String module = getModuleName(moduleID);
+ sBuf.append(module != null ? module : "" + moduleID);
+
+ sBuf.append(chars, 0, 2);
+
+ if (msgID != 0) {
+ // map msgID to String
+ String msg = getMsgValue(msgID);
+ sBuf.append(msg != null ? msg : "" + msgID);
+ }
+
+ if (message != null)
+ sBuf.append(chars, 2, 2).append(message);
+
+ return sBuf.toString();
+ }
+
+ // public String toString() {
+ // return bc.toString();
+ // }
+
+ private static boolean security = false;
+
+ public static boolean security() {
+ if (UtilActivator.bc != null) {
+ try {
+ Object ssecurity = UtilActivator.bc.getProperty("equinox.security");
+ security = ssecurity != null && !"none".equals(ssecurity);
+ } catch (Throwable t) {
+ // no security implementation.
+ }
+ } else {
+ try {
+ Object ssecurity = System.getProperty("equinox.security");
+ security = ssecurity != null && !"none".equals(ssecurity);
+ } catch (Throwable t) {
+ // no security implementation.
+ }
+ }
+ return security;
+ }
+
+ String baseName;
+ boolean synch;
+ FileOutputStream fos = null;
+ static String logsdir = null;
+
+ static Queue queue;
+ static boolean running = false;
+ static Saver saver;
+ // boolean date = false;
+ long lastTime;
+
+ // byte[] bdate;
+
+ public Log(String baseName, boolean synch, BundleContext bc) {
+ this(bc);
+ this.baseName = baseName;
+ this.synch = synch;
+ if (!synch)
+ synchronized (Log.class) {
+ if (queue == null) {
+ queue = new Queue(20);
+ saver = new Saver();
+ }
+ }
+ }
+
+ public void trace(byte[] bytes) {
+ if (!synch)
+ synchronized (queue) {
+ queue.put(this);
+ queue.put(bytes);
+ if (!running) {
+ running = true;
+ UtilActivator.thMan.execute(saver, "File Log Thread");
+ }
+ }
+ else
+ trace(bytes, 0, bytes.length);
+ }
+
+ public void trace(byte[] bytes, int off, int len) {
+ if (logsdir == null)
+ synchronized (Log.class) {
+ if (logsdir == null) {
+ try {
+ logsdir = UtilActivator.bc.getProperty("equinox.logsDir");
+ if (logsdir == null)
+ logsdir = "./logs";
+ File logs = new File(logsdir);
+ logs.mkdirs();
+ } catch (Exception exc) {
+ exc.printStackTrace();
+ }
+ }
+ }
+ if (fos == null)
+ synchronized (this) {
+ if (fos == null) {
+ StringBuffer fname = new StringBuffer(logsdir.length() + baseName.length() + 1);
+ fname.append(logsdir).append(File.separatorChar).append(baseName);
+ try {
+ fos = new FileOutputStream(fname.toString(), true);
+ } catch (IOException ioExc) {
+ ioExc.printStackTrace();
+ }
+ }
+ }
+ try {
+ fos.write(bytes, off, len);
+ fos.write(10);
+ } catch (IOException ioExc) {
+ ioExc.printStackTrace();
+ }
+ }
+
+ public void finalize() {
+ if (fos != null)
+ try {
+ fos.close();
+ } catch (IOException ioExc) {
+ ioExc.printStackTrace();
+ }
+ }
+
+ /**
+ * Checks the auto print on console flag
+ *
+ * @return true, if autoPrintOnConsole is enabled
+ */
+ public boolean isAutoPrintOnConsole() {
+ return autoPrintOnConsole;
+ }
+
+ /**
+ * Enables/disables auto printing on console. This flag points whether
+ * printing on console should be done if log service is not available
+ *
+ * @param autoPrintOnConsole
+ * if true enables auto print on console else disables it.
+ */
+ public void setAutoPrintOnConsole(boolean autoPrintOnConsole) {
+ this.autoPrintOnConsole = autoPrintOnConsole;
+ }
+
+ /**
+ * Returns whether printing on console should be done for errors
+ * (exceptions) and warnings
+ *
+ * @return Returns the error log level flag - if true the error and warnings
+ * will be print on console
+ */
+ public boolean isLogErrorLevel() {
+ return logErrorLevel;
+ }
+
+ private static final byte OPEN_TYPE = 0;
+ private static final byte GET_SERVICE_TYPE = 1;
+ private static final byte GET_SYS_SERVICES_TYPE = 2;
+
+ /**
+ * @see org.eclipse.equinox.internal.util.security.PrivilegedRunner.PrivilegedDispatcher#dispatchPrivileged(int,
+ * java.lang.Object, java.lang.Object, java.lang.Object,
+ * java.lang.Object)
+ */
+ public Object dispatchPrivileged(int type, Object arg1, Object arg2, Object arg3, Object arg4) throws Exception {
+ switch (type) {
+ case OPEN_TYPE :
+ initListener0();
+ break;
+ case GET_SERVICE_TYPE :
+ return getService0();
+ case GET_SYS_SERVICES_TYPE :
+ break;
+ }
+ return null;
+ }
+
+}// Log class
+
+class Saver implements Runnable {
+
+ public void run() {
+ byte[] bytes = null;
+ Log log = null;
+ while (true) {
+ synchronized (Log.queue) {
+ log = (Log) Log.queue.get();
+ if (log == null) {
+ Log.running = false;
+ bytes = null;
+ return;
+ }
+ bytes = (byte[]) Log.queue.get();
+ }
+ log.trace(bytes, 0, bytes.length);
+ }
+ }
+}
diff --git a/bundles/org.eclipse.equinox.util/src/org/eclipse/equinox/internal/util/ref/LogInterface.java b/bundles/org.eclipse.equinox.util/src/org/eclipse/equinox/internal/util/ref/LogInterface.java
new file mode 100644
index 000000000..c215385ab
--- /dev/null
+++ b/bundles/org.eclipse.equinox.util/src/org/eclipse/equinox/internal/util/ref/LogInterface.java
@@ -0,0 +1,107 @@
+/*******************************************************************************
+ * 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.util.ref;
+
+/**
+ *
+ * @author Pavlin Dobrev
+ * @version 1.0
+ */
+
+public interface LogInterface {
+
+ public boolean printOnConsole = true;
+
+ public boolean debug = false;
+
+ /**
+ * Logs error messages. If <code>printOnConsole</code> is true, or if the
+ * <code>LogService</code> is unavailable, log info is printed on console.
+ *
+ * @param str
+ * Message description of the error.
+ * @param ex
+ * Throwable object, containing the stack trace; may be null.
+ */
+ public void error(String str, Throwable ex);
+
+ /**
+ * Logs warning messages. If <code>printOnConsole</code> is true, or if
+ * the <code>LogService</code> is unavailable, log info is printed on
+ * console.
+ *
+ * @param str
+ * Message description of the error.
+ * @param ex
+ * Throwable object, containing the stack trace; may be null.
+ */
+ public void warning(String str, Throwable ex);
+
+ /**
+ * Logs info messages. If <code>printOnConsole</code> is true, or if the
+ * <code>LogService</code> is unavailable, message is printed on console.
+ *
+ * @param str
+ * Message to be logged.
+ */
+ public void info(String str);
+
+ /**
+ * Logs debug information if <code>debug</code> flag is true. If
+ * LogService is unaccessible or printOnConsole flag is true, log info is
+ * printed on console.
+ *
+ * @param str
+ * Message description.
+ * @param e
+ * Throwable object, containing the stack trace; may be null.
+ */
+ public void debug(String str, Throwable e);
+
+ /**
+ * Releases the Log's resources: ungets LogService, removes the
+ * ServiceListener from the framework and nulls references. After invocation
+ * of this method, this Log object can be used no longer.
+ */
+ public void close();
+
+ /**
+ * enable/diasable print on console
+ *
+ * @param value
+ * boolean if true enables print on console else disables it
+ */
+ public void setPrintOnConsole(boolean value);
+
+ /**
+ * enable/diasable loging of debug info
+ *
+ * @param value
+ * boolean if true enables loging of debug info else disables it
+ */
+ public void setDebug(boolean value);
+
+ /**
+ * Gets the flag, which enables logging debug messages.
+ *
+ * @return true if debugging is enabled
+ */
+ public boolean getDebug();
+
+ /**
+ * Gets the flag, which enables printing log messages on the console.
+ *
+ * @return true if printingon console is enabled
+ */
+ public boolean getPrintOnConsole();
+
+}// Log class
diff --git a/bundles/org.eclipse.equinox.util/src/org/eclipse/equinox/internal/util/ref/TimerRef.java b/bundles/org.eclipse.equinox.util/src/org/eclipse/equinox/internal/util/ref/TimerRef.java
new file mode 100644
index 000000000..ce1574622
--- /dev/null
+++ b/bundles/org.eclipse.equinox.util/src/org/eclipse/equinox/internal/util/ref/TimerRef.java
@@ -0,0 +1,40 @@
+/*******************************************************************************
+ * 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.util.ref;
+
+import org.eclipse.equinox.internal.util.timer.Timer;
+import org.eclipse.equinox.internal.util.timer.TimerListener;
+
+/**
+ * @author Pavlin Dobrev
+ * @version 1.0
+ */
+
+public class TimerRef {
+
+ public static Timer timer = null;
+
+ public static void notifyAfter(TimerListener listener, long millis, int event) {
+
+ if (timer == null) {
+ listener.timer(event);
+ return;
+ }
+ timer.addNotifyListener(listener, Thread.NORM_PRIORITY, Timer.ONE_SHOT_TIMER, millis, event);
+ }
+
+ public static void removeListener(TimerListener listener, int event) {
+ if (timer == null)
+ return;
+ timer.removeListener(listener, event);
+ }
+}
diff --git a/bundles/org.eclipse.equinox.util/src/org/eclipse/equinox/internal/util/ref/package.html b/bundles/org.eclipse.equinox.util/src/org/eclipse/equinox/internal/util/ref/package.html
new file mode 100644
index 000000000..63af46c85
--- /dev/null
+++ b/bundles/org.eclipse.equinox.util/src/org/eclipse/equinox/internal/util/ref/package.html
@@ -0,0 +1,36 @@
+<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
+<html>
+<head>
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <meta name="Author" content="Maria Ivanova">
+ <meta name="GENERATOR" content="Mozilla/4.6 [en] (WinNT; I) [Netscape]">
+ <title>package</title>
+</head>
+<body>
+The Log Reference class, included in this package, is provided to
+isolate the bundle writers from the common and often used operations accompanying
+logging in the LogService. The Log class deals on behalf of the bundle,
+which instanciates it, while getting reference to and listening for events
+from the LogService.
+<p>A bundle, wishing to use the Log reference, must only pass its bundle
+context to the Log's constructor, from there on it can log INFO, ERROR,
+and DEBUG messages in the LogService, without caring for the availability
+even of the Log Bundle.
+<p>If there are changes in the state of the LogService (e.g. it is REGISTERED,
+or UNREGISTERING), the Log class cares to get or unget reference to it.
+While the LogService is unavailable, no matter what is the reason for this,
+the log information is printed on the server's console.
+<p>When the Log object should be released, (e.g. in case the bundle owner
+will be stopped) the resources, hold by the Log object should also be released:
+thus including ungetting LogService reference and removal of the <i>ServiceListener</i>
+from the framework. <i>close()</i> method does all the necessary
+clean up of ungetting LogService, removal of <i>ServiceListener</i> and
+internal variable clean up.
+<p>When multiple LogServices are available in the service registry, the
+Log class gets reference to only one of them. If a bundle wishes to publish
+the log information to all of the available LogServices, it can take advantage
+of the org.eclipse.equinox.util.tracker.ServiceTracker utility.
+<p>The Log Reference class implements the LogInterface class.
+<br>&nbsp;
+</body>
+</html>
diff --git a/bundles/org.eclipse.equinox.util/src/org/eclipse/equinox/internal/util/security/PrivilegedAction.java b/bundles/org.eclipse.equinox.util/src/org/eclipse/equinox/internal/util/security/PrivilegedAction.java
new file mode 100644
index 000000000..ca4a30923
--- /dev/null
+++ b/bundles/org.eclipse.equinox.util/src/org/eclipse/equinox/internal/util/security/PrivilegedAction.java
@@ -0,0 +1,47 @@
+/*******************************************************************************
+ * 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.util.security;
+
+/**
+ * <p>
+ * This class is a wrapper of java.security.PrivilegedAction &&
+ * java.security.PriviligedExceptionAction.
+ *
+ * <p>
+ * Its purpose is to hide the dependency on java.security package, so that the
+ * user of this class, could be used on JDK 1.1 compatible JVM-s and the others.
+ * In the first case, no security mechanism is provided in the JVM, so there is
+ * no need to execute doPrivileged blocks at all. In the second case the real
+ * java.security.AccessController, java.security.PrivilegedAction and
+ * java.security.PrivilegedExceptionAction are used to execute doPrivileged
+ * blocks.
+ *
+ * @deprecated java.security package API should be used in order to execute
+ * appropriately doPrivileged blocks. The provided implementation is
+ * fake and is left only for backward compatibility.
+ *
+ * @author Svetozar Dimov
+ * @author Pavlin Dobrev
+ * @version 1.0
+ *
+ */
+public interface PrivilegedAction {
+
+ /**
+ * Substitute for PrivilegedAction.run() and PrivilegedExceptionAction.run()
+ * in java.security package.
+ *
+ * @return
+ * @throws Exception
+ */
+ public Object run0() throws Exception;
+}
diff --git a/bundles/org.eclipse.equinox.util/src/org/eclipse/equinox/internal/util/security/PrivilegedRunner.java b/bundles/org.eclipse.equinox.util/src/org/eclipse/equinox/internal/util/security/PrivilegedRunner.java
new file mode 100644
index 000000000..30d998db7
--- /dev/null
+++ b/bundles/org.eclipse.equinox.util/src/org/eclipse/equinox/internal/util/security/PrivilegedRunner.java
@@ -0,0 +1,173 @@
+/*******************************************************************************
+ * 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.util.security;
+
+import java.security.*;
+import org.eclipse.equinox.internal.util.pool.ObjectCreator;
+import org.eclipse.equinox.internal.util.pool.ObjectPool;
+
+/**
+ * A simple wrapper for executing privileged actions.
+ *
+ * @author Valentin Valchev
+ * @author Pavlin Dobrev
+ * @version 1.0
+ */
+
+public final class PrivilegedRunner implements ObjectCreator {
+
+ private static ObjectPool POOL;
+
+ static {
+ try {
+ POOL = new ObjectPool(new PrivilegedRunner(), 5, 10);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ /* prevent instantiations */
+ private PrivilegedRunner() {
+ }
+
+ /**
+ * Same as the longer doPrivileged method, but fills in the first parameter
+ * only. All other parameters are set to <code>null</code>.
+ *
+ * @param context
+ * the access context
+ * @param dispatcher
+ * the dispatcher which should be called
+ * @param type
+ * the type of the action - used in the dispatcher
+ * @param arg1
+ * a parameter received by the dispatcher
+ * @see #doPrivileged(Object, PrivilegedDispatcher, int, Object)
+ * @return the object returned from the execution
+ * @throws Exception
+ * if the dispatcher fails
+ */
+ public static final Object doPrivileged(Object context, PrivilegedDispatcher dispatcher, int type, Object arg1) throws Exception {
+ return doPrivileged(context, dispatcher, type, arg1, null, null, null);
+ }
+
+ /**
+ * Performs a privileged action. The method calls the dispatcher inside the
+ * privileged call passing it the same parameters that were passed to this
+ * method.
+ *
+ * @param context
+ * the access context
+ * @param dispatcher
+ * the dispatcher which should be called
+ * @param type
+ * the type of the action - used in the dispatcher
+ * @param arg1
+ * a parameter received by the dispatcher
+ * @param arg2
+ * a parameter received by the dispatcher
+ * @param arg3
+ * a parameter received by the dispatcher
+ * @param arg4
+ * a parameter received by the dispatcher
+ * @return the object returned from the execution
+ * @throws Exception
+ * if the dispatcher fails
+ */
+ public static final Object doPrivileged(Object context, PrivilegedDispatcher dispatcher, int type, Object arg1, Object arg2, Object arg3, Object arg4) throws Exception {
+ /* init runner */
+ PA runner = (PA) POOL.getObject();
+ runner.dispatcher = dispatcher;
+ runner.type = type;
+ runner.arg1 = arg1;
+ runner.arg2 = arg2;
+ runner.arg3 = arg3;
+ runner.arg4 = arg4;
+
+ try {
+ if (System.getSecurityManager() != null) {
+ /*
+ * if security manager is set - then privileged execution is
+ * started
+ */
+ return (context != null)
+ //
+ ? AccessController.doPrivileged(runner, (AccessControlContext) context)
+ : AccessController.doPrivileged(runner);
+ }
+ /* if no security manager is set - simply run the action */
+ return runner.run();
+ } catch (PrivilegedActionException e) {
+ throw e.getException();
+ } finally {
+ runner.recycle();
+ POOL.releaseObject(runner);
+ }
+ }
+
+ /**
+ * @see org.eclipse.equinox.internal.util.pool.ObjectCreator#getInstance()
+ */
+ public Object getInstance() throws Exception {
+ return new PA();
+ }
+
+ /**
+ * This dispatcher is the handler that is called within the privileged call.
+ * It should dispatch and perform the requested actions depending on the
+ * action type and using the given job parameters.
+ *
+ * @author Valentin Valchev
+ * @version $Revision: 1.2 $
+ */
+ public static interface PrivilegedDispatcher {
+
+ /**
+ * @param type
+ * the type of the action
+ * @param arg1
+ * parameter 1 - depends on the action type
+ * @param arg2
+ * parameter 2 - depends on the action type
+ * @param arg3
+ * parameter 3 - depends on the action type
+ * @param arg4
+ * parameter 4 - depends on the action type
+ * @return an object which should be returned from the
+ * PrivilegedAction.run() method
+ * @throws Exception
+ * on error
+ */
+ Object dispatchPrivileged(int type, Object arg1, Object arg2, Object arg3, Object arg4) throws Exception;
+ }
+
+ static class PA implements PrivilegedExceptionAction {
+
+ int type;
+ Object arg1, arg2, arg3, arg4;
+ PrivilegedDispatcher dispatcher;
+
+ void recycle() {
+ dispatcher = null;
+ type = -1;
+ arg1 = arg2 = arg3 = arg4 = null;
+ }
+
+ /**
+ * @see java.security.PrivilegedExceptionAction#run()
+ */
+ public Object run() throws Exception {
+ return dispatcher.dispatchPrivileged(type, arg1, arg2, arg3, arg4);
+ }
+ }
+
+}
diff --git a/bundles/org.eclipse.equinox.util/src/org/eclipse/equinox/internal/util/security/SecurityUtil.java b/bundles/org.eclipse.equinox.util/src/org/eclipse/equinox/internal/util/security/SecurityUtil.java
new file mode 100644
index 000000000..f1061a0ef
--- /dev/null
+++ b/bundles/org.eclipse.equinox.util/src/org/eclipse/equinox/internal/util/security/SecurityUtil.java
@@ -0,0 +1,756 @@
+/*******************************************************************************
+ * 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.util.security;
+
+import java.io.*;
+import java.util.Dictionary;
+import org.eclipse.equinox.internal.util.UtilActivator;
+import org.osgi.framework.*;
+
+/**
+ * Utility class to execute common privileged code.
+ *
+ * @author Valentin Valchev
+ * @author Pavlin Dobrev
+ * @version 1.0
+ */
+
+public final class SecurityUtil implements PrivilegedRunner.PrivilegedDispatcher {
+
+ private Object controlContext;
+
+ private static final int SYSTEM_GET_PROPERTY = 41;
+ private static final int CREATE_THREAD = 42;
+ private static final int CLASS_FOR_NAME = 43;
+ private static final int SYSTEM_SET_PROPERTY = 44;
+
+ private static final int FILE_BASE = 50;
+ private static final int FILE_GET_INPUT_STREAM = FILE_BASE + 0;
+ private static final int FILE_GET_OUTPUT_STREAM = FILE_BASE + 1;
+ private static final int FILE_LENGTH = FILE_BASE + 2;
+ private static final int FILE_EXISTS = FILE_BASE + 3;
+ private static final int FILE_ISDIR = FILE_BASE + 4;
+ private static final int FILE_LAST_MODIFIED = FILE_BASE + 5;
+ private static final int FILE_LIST = FILE_BASE + 6;
+ private static final int FILE_DELETE = FILE_BASE + 7;
+ private static final int FILE_RENAME = FILE_BASE + 8;
+ private static final int FILE_GET_RANDOM_ACCESS_FILE = FILE_BASE + 9;
+
+ private static final int SERVICE_BASE = 60;
+ private static final int SERVICE_GET_REFERENCE = SERVICE_BASE + 0;
+ private static final int SERVICE_GET_SERVICE = SERVICE_BASE + 1;
+ private static final int SERVICE_REG_CLASS = SERVICE_BASE + 2;
+ private static final int SERVICE_REG_CLASSES = SERVICE_BASE + 3;
+
+ private static final int BUNDLE_BASE = 70;
+ private static final int BUNDLE_GET_LOCATION = BUNDLE_BASE + 0;
+ private static final int BUNDLE_GET_HEADERS = BUNDLE_BASE + 1;
+ private static final int BUNDLE_START = BUNDLE_BASE + 2;
+ private static final int BUNDLE_STOP = BUNDLE_BASE + 3;
+ private static final int BUNDLE_UNINSTALL = BUNDLE_BASE + 4;
+ private static final int BUNDLE_UPDATE = BUNDLE_BASE + 5;
+ private static final int BUNDLE_UPDATE_IS = BUNDLE_BASE + 6;
+
+ /**
+ * Constructs a new SecureAction object. The constructed SecureAction object
+ * uses the caller's AccessControlContext to perform security checks
+ */
+ public SecurityUtil() {
+ // save the control context to be used.
+ SecurityManager sm = System.getSecurityManager();
+ if (sm != null) {
+ controlContext = sm.getSecurityContext();
+ }
+ }
+
+ /**
+ * Creates a new Thread from a Runnable. Same as calling new
+ * Thread(target,name).
+ *
+ * @param target
+ * the Runnable to create the Thread from.
+ * @param name
+ * The name of the Thread.
+ * @return The new Thread
+ */
+ public Thread createThread(final Runnable target, final String name) {
+ try {
+ return (Thread) PrivilegedRunner.doPrivileged(controlContext, this, CREATE_THREAD, target, name, null, null);
+ } catch (Exception t) {
+ throw new RuntimeException(t.getMessage());
+ }
+ }
+
+ /**
+ * Returns a Class. Same as calling Class.forName(name)
+ *
+ * @param name
+ * the name of the class.
+ * @return a Class
+ * @throws ClassNotFoundException
+ */
+ public Class forName(final String name) throws ClassNotFoundException {
+ try {
+ return (Class) PrivilegedRunner.doPrivileged(controlContext, this, CLASS_FOR_NAME, name, null, null, null);
+ } catch (ClassNotFoundException t) {
+ throw t;
+ } catch (Exception t) {
+ throw new RuntimeException(t.getMessage());
+ }
+ }
+
+ /**
+ * Returns a system property. Same as calling System.getProperty(String).
+ *
+ * @param property
+ * the property key.
+ * @return the value of the property or null if it does not exist.
+ */
+ public String getProperty(final String property) {
+ if (property == null) {
+ throw new NullPointerException("property is null");
+ }
+ String ret;
+ try {
+ ret = (String) PrivilegedRunner.doPrivileged(controlContext, this, SYSTEM_GET_PROPERTY, property, null, null, null);
+ } catch (Exception t) {
+ ret = null;
+ }
+ return ret;
+ }
+
+ /**
+ * Returns a system property. Same as calling
+ * System.getProperty(String,String).
+ *
+ * @param property
+ * the property key.
+ * @param def
+ * the default value if the property key does not exist.
+ * @return the value of the property or the default value if the property
+ * does not exist.
+ */
+ public String getProperty(final String property, final String def) {
+ String ret = getProperty(property);
+ return ret != null ? ret : def;
+ }
+
+ /**
+ * Returns a boolean system property. Same as calling
+ * Boolean.getBoolean(String).
+ *
+ * @param property
+ * the property key.
+ * @return the value of the property or <code>false</code>, if not set
+ */
+ public boolean getBooleanProperty(final String property) {
+ String ret = getProperty(property);
+ return ret != null ? Boolean.valueOf(ret).booleanValue() : false;
+ }
+
+ /**
+ * Sets a system property. Same as System.setProperty()
+ *
+ * @param key
+ * the name of the property
+ * @param value
+ * the value of the system property
+ * @return the old value of the property, or null
+ */
+ public String setProperty(final String key, final String value) {
+ if (key == null) {
+ throw new NullPointerException("key is null");
+ }
+ if (value == null) {
+ throw new NullPointerException("key is null");
+ }
+ try {
+ return (String) PrivilegedRunner.doPrivileged(controlContext, this, SYSTEM_SET_PROPERTY, key, value, null, null);
+ } catch (Exception t) {
+ throw new RuntimeException(t.getMessage());
+ }
+ }
+
+ /**
+ * Creates a FileInputStream from a File. Same as calling new
+ * FileInputStream(File).
+ *
+ * @param file
+ * the File to create a FileInputStream from.
+ * @return The FileInputStream.
+ * @throws FileNotFoundException
+ * if the File does not exist.
+ */
+ public FileInputStream getFileInputStream(final File file) throws FileNotFoundException {
+ try {
+ return (FileInputStream) PrivilegedRunner.doPrivileged(controlContext, this, FILE_GET_INPUT_STREAM, file, null, null, null);
+ } catch (FileNotFoundException t) {
+ throw t;
+ } catch (Exception t) {
+ throw new RuntimeException(t.getMessage());
+ }
+ }
+
+ /**
+ * Creates a random access file
+ *
+ * @param file
+ * the file object
+ * @param mode
+ * the open mode
+ * @return the random seekable file object
+ * @throws FileNotFoundException
+ * if the File does not exist
+ */
+ public RandomAccessFile getRandomAccessFile(final File file, final String mode) throws FileNotFoundException {
+ try {
+ return (RandomAccessFile) PrivilegedRunner.doPrivileged(controlContext, this, FILE_GET_RANDOM_ACCESS_FILE, file, mode, null, null);
+ } catch (FileNotFoundException t) {
+ throw t;
+ } catch (Exception t) {
+ throw new RuntimeException(t.getMessage());
+ }
+ }
+
+ /**
+ * Creates a FileInputStream from a File. Same as calling new
+ * FileOutputStream(File,boolean).
+ *
+ * @param file
+ * the File to create a FileOutputStream from.
+ * @param append
+ * indicates if the OutputStream should append content.
+ * @return The FileOutputStream.
+ * @throws FileNotFoundException
+ * if the File does not exist.
+ */
+ public FileOutputStream getFileOutputStream(final File file, final boolean append) throws FileNotFoundException {
+ try {
+ return (FileOutputStream) PrivilegedRunner.doPrivileged(//
+ controlContext, this, FILE_GET_OUTPUT_STREAM, file, //
+ append ? Boolean.TRUE : Boolean.FALSE, null, null);
+ } catch (FileNotFoundException t) {
+ throw t;
+ } catch (Exception t) {
+ throw new RuntimeException(t.getMessage());
+ }
+ }
+
+ /**
+ * Returns true if a file exists, otherwise false is returned. Same as
+ * calling file.exists().
+ *
+ * @param file
+ * a file object
+ * @return true if a file exists, otherwise false
+ */
+ public boolean exists(final File file) {
+ try {
+ return ((Boolean) PrivilegedRunner.doPrivileged(controlContext, this, FILE_EXISTS, file, null, null, null)).booleanValue();
+ } catch (Exception t) {
+ throw new RuntimeException(t.getMessage());
+ }
+ }
+
+ /**
+ * Returns true if a file is a directory, otherwise false is returned. Same
+ * as calling file.isDirectory().
+ *
+ * @param file
+ * a file object
+ * @return true if a file is a directory, otherwise false
+ */
+ public boolean isDirectory(final File file) {
+ try {
+ return ((Boolean) PrivilegedRunner.doPrivileged(controlContext, this, FILE_ISDIR, file, null, null, null)).booleanValue();
+ } catch (Exception t) {
+ throw new RuntimeException(t.getMessage());
+ }
+ }
+
+ /**
+ * Returns the length of a file. Same as calling file.length().
+ *
+ * @param file
+ * a file object
+ * @return the length of a file or -1 if file doesn't exists
+ */
+ public long length(final File file) {
+ try {
+ return ((Long) PrivilegedRunner.doPrivileged(controlContext, this, FILE_LENGTH, file, null, null, null)).longValue();
+ } catch (Throwable t) {
+ return -1L;
+ }
+ }
+
+ /**
+ * Returns a file's last modified stamp. Same as calling
+ * file.lastModified().
+ *
+ * @param file
+ * a file object
+ * @return a file's last modified stamp or -1 if file doesn't exists
+ */
+ public long lastModified(final File file) {
+ try {
+ return ((Long) PrivilegedRunner.doPrivileged(controlContext, this, FILE_LAST_MODIFIED, file, null, null, null)).longValue();
+ } catch (Exception t) {
+ return -1L;
+ }
+ }
+
+ /**
+ * Returns a file's list. Same as calling file.list().
+ *
+ * @param file
+ * a file object
+ * @return a file's list.
+ */
+ public String[] list(final File file) {
+ try {
+ return (String[]) PrivilegedRunner.doPrivileged(controlContext, this, FILE_LIST, file, null, null, null);
+ } catch (Exception t) {
+ return null;
+ }
+ }
+
+ /**
+ * Deletes the specified file. Same as File.delete()
+ *
+ * @param file
+ * the file object
+ * @return if delete succeeded
+ */
+ public boolean delete(final File file) {
+ try {
+ return ((Boolean) PrivilegedRunner.doPrivileged(controlContext, this, FILE_DELETE, file, null, null, null)).booleanValue();
+ } catch (Exception t) {
+ throw new RuntimeException(t.getMessage());
+ }
+ }
+
+ /**
+ * Renames the source file to the target name. Same as File.renameTo(File)
+ *
+ * @param source
+ * the file object, that will be renamed
+ * @param target
+ * the target file name
+ * @return if rename succeeded
+ */
+ public boolean renameTo(final File source, final File target) {
+ try {
+ return ((Boolean) PrivilegedRunner.doPrivileged(controlContext, this, FILE_RENAME, source, target, null, null)).booleanValue();
+ } catch (Exception t) {
+ throw new RuntimeException(t.getMessage());
+ }
+ }
+
+ /**
+ * Gets a service object. Same as calling context.getService(reference)
+ *
+ * @param reference
+ * the ServiceReference
+ * @param context
+ * the BundleContext
+ * @return a service object
+ */
+ public Object getService(final ServiceReference reference, final BundleContext context) {
+ if (context == null) {
+ throw new NullPointerException("Context is null");
+ }
+ if (reference == null) {
+ throw new NullPointerException("Reference is null");
+ }
+ try {
+ return PrivilegedRunner.doPrivileged(controlContext, this, SERVICE_GET_SERVICE, context, reference, null, null);
+ } catch (Exception t) {
+ throw new RuntimeException(t.getMessage());
+ }
+ }
+
+ /**
+ * Gets a reference for the specified service(s). Same as calling
+ * context.getServiceReferences(class, filter)
+ *
+ * @param clazz
+ * the name of the requested service class
+ * @param filter
+ * an LDAP filter
+ * @param context
+ * the BundleContext
+ * @return a list of reference or <code>null</code>
+ * @throws InvalidSyntaxException
+ * if filter is not correct
+ */
+ public ServiceReference[] getServiceReferences(String clazz, String filter, BundleContext context) throws InvalidSyntaxException {
+ if (context == null) {
+ throw new NullPointerException("Context is null");
+ }
+ if (clazz == null && filter == null) {
+ throw new NullPointerException("Either filter or clazz parameter should not be null");
+ }
+ try {
+ return (ServiceReference[]) PrivilegedRunner.doPrivileged(controlContext, this, SERVICE_GET_REFERENCE, context, clazz, filter, null);
+ } catch (InvalidSyntaxException e) {
+ throw e;
+ } catch (Exception t) {
+ throw new RuntimeException(t.getMessage());
+ }
+ }
+
+ /**
+ * Registers a service. Same as BundleContext.register(clazz, service,
+ * properties);
+ *
+ * @param clazz
+ * the class name of the service
+ * @param service
+ * the service instance
+ * @param properties
+ * the properties.
+ * @param context
+ * the bundle context
+ * @return a service registration
+ */
+ public ServiceRegistration registerService(String clazz, Object service, Dictionary properties, BundleContext context) {
+ if (context == null) {
+ throw new NullPointerException("Context is null");
+ }
+ if (service == null) {
+ throw new NullPointerException("Service is null");
+ }
+ if (clazz == null) {
+ throw new NullPointerException("Class name is null");
+ }
+ try {
+ return (ServiceRegistration) PrivilegedRunner.doPrivileged(controlContext, this, SERVICE_REG_CLASS, context, clazz, service, properties);
+ } catch (Exception t) {
+ throw new RuntimeException(t.getMessage());
+ }
+ }
+
+ /**
+ * Registers a instance that implements many services. Same as
+ * BundleContext.register(clases, service, properties);
+ *
+ * @param classes
+ * the class names of the service
+ * @param service
+ * the service instance
+ * @param properties
+ * the properties.
+ * @param context
+ * the bundle context
+ * @return a service registration
+ */
+ public ServiceRegistration registerService(String[] classes, Object service, Dictionary properties, BundleContext context) {
+ if (context == null) {
+ throw new NullPointerException("Context is null");
+ }
+ if (service == null) {
+ throw new NullPointerException("Service is null");
+ }
+ if (classes == null) {
+ throw new NullPointerException("Class names are null");
+ }
+ try {
+ return (ServiceRegistration) PrivilegedRunner.doPrivileged(controlContext, this, SERVICE_REG_CLASSES, context, classes, service, properties);
+ } catch (Exception t) {
+ throw new RuntimeException(t.getMessage());
+ }
+ }
+
+ /**
+ * Gets the location of the bundle. Same as Bundle.getLocation().
+ *
+ * @param bundle
+ * the bundle
+ * @return the bundle location
+ */
+ public String getLocation(Bundle bundle) {
+ try {
+ return (String) PrivilegedRunner.doPrivileged(controlContext, this, BUNDLE_GET_LOCATION, bundle, null, null, null);
+ } catch (Exception t) {
+ throw new RuntimeException(t.getMessage());
+ }
+ }
+
+ /**
+ * Gets the bundle headers. Same as Bundle.getHeaders().
+ *
+ * @param bundle
+ * the bundle
+ * @return the bundle location
+ */
+ public Dictionary getHeaders(Bundle bundle) {
+ try {
+ return (Dictionary) PrivilegedRunner.doPrivileged(controlContext, this, BUNDLE_GET_HEADERS, bundle, null, null, null);
+ } catch (Exception t) {
+ throw new RuntimeException(t.getMessage());
+ }
+ }
+
+ /**
+ * Starts the bundle. Same as Bundle.start()
+ *
+ * @param bundle
+ * the bundle
+ * @throws BundleException
+ */
+ public void start(Bundle bundle) throws BundleException {
+ try {
+ PrivilegedRunner.doPrivileged(controlContext, this, BUNDLE_START, bundle, null, null, null);
+ } catch (BundleException t) {
+ throw t;
+ } catch (Exception t) {
+ throw new RuntimeException(t.getMessage());
+ }
+ }
+
+ /**
+ * Stops the bundle. Same as Bundle.stop()
+ *
+ * @param bundle
+ * the bundle
+ * @throws BundleException
+ */
+ public void stop(Bundle bundle) throws BundleException {
+ try {
+ PrivilegedRunner.doPrivileged(controlContext, this, BUNDLE_STOP, bundle, null, null, null);
+ } catch (BundleException t) {
+ throw t;
+ } catch (Exception t) {
+ throw new RuntimeException(t.getMessage());
+ }
+ }
+
+ /**
+ * Un-installs the bundle. Same as Bundle.uninstall()
+ *
+ * @param bundle
+ * the bundle
+ * @throws BundleException
+ */
+ public void uninstall(Bundle bundle) throws BundleException {
+ try {
+ PrivilegedRunner.doPrivileged(controlContext, this, BUNDLE_UNINSTALL, bundle, null, null, null);
+ } catch (BundleException t) {
+ throw t;
+ } catch (Exception t) {
+ throw new RuntimeException(t.getMessage());
+ }
+ }
+
+ /**
+ * Updates the bundle. Same as Bundle.update()
+ *
+ * @param bundle
+ * the bundle
+ * @throws BundleException
+ */
+ public void update(Bundle bundle) throws BundleException {
+ try {
+ PrivilegedRunner.doPrivileged(controlContext, this, BUNDLE_UPDATE, bundle, null, null, null);
+ } catch (BundleException t) {
+ throw t;
+ } catch (Exception t) {
+ throw new RuntimeException(t.getMessage());
+ }
+ }
+
+ /**
+ * Updates the bundle from stream. Same as Bundle.update(stream)
+ *
+ * @param bundle
+ * the bundle
+ * @param is
+ * the stream
+ * @throws BundleException
+ */
+ public void update(Bundle bundle, InputStream is) throws BundleException {
+ try {
+ PrivilegedRunner.doPrivileged(controlContext, this, BUNDLE_UPDATE_IS, bundle, is, null, null);
+ } catch (BundleException t) {
+ throw t;
+ } catch (Exception t) {
+ throw new RuntimeException(t.getMessage());
+ }
+ }
+
+ /**
+ * Performs a privileged action <b>using the current security context</b>.
+ * The method calls the dispatcher inside the privileged call passing it the
+ * same parameters that were passed to this method.
+ *
+ * @param dispatcher
+ * the dispatcher which should be called
+ * @param type
+ * the type of the action - used in the dispatcher
+ * @param arg1
+ * a parameter received by the dispatcher
+ * @param arg2
+ * a parameter received by the dispatcher
+ * @param arg3
+ * a parameter received by the dispatcher
+ * @param arg4
+ * a parameter received by the dispatcher
+ * @return the object returned from the execution
+ * @throws Exception
+ * if the dispatcher fails
+ * @see PrivilegedRunner#doPrivileged(Object,
+ * org.eclipse.equinox.internal.util.security.PrivilegedRunner.PrivilegedDispatcher,
+ * int, Object, Object, Object, Object)
+ */
+ public Object doPrivileged(PrivilegedRunner.PrivilegedDispatcher dispatcher, int type, Object arg1, Object arg2, Object arg3, Object arg4) throws Exception {
+ return PrivilegedRunner.doPrivileged(controlContext, dispatcher, type, arg1, arg2, arg3, arg4);
+ }
+
+ /**
+ * Performs a privileged action <b>using the current security context</b>.
+ * The method calls the dispatcher inside the privileged call passing it the
+ * same parameters that were passed to this method.
+ *
+ * @param dispatcher
+ * the dispatcher which should be called
+ * @param type
+ * the type of the action - used in the dispatcher
+ * @param arg1
+ * a parameter received by the dispatcher
+ * @param arg2
+ * a parameter received by the dispatcher
+ * @param arg3
+ * a parameter received by the dispatcher
+ * @return the object returned from the execution
+ * @throws Exception
+ * if the dispatcher fails
+ * @see PrivilegedRunner#doPrivileged(Object,
+ * org.eclipse.equinox.internal.util.security.PrivilegedRunner.PrivilegedDispatcher,
+ * int, Object, Object, Object, Object)
+ */
+ public Object doPrivileged(PrivilegedRunner.PrivilegedDispatcher dispatcher, int type, Object arg1, Object arg2, Object arg3) throws Exception {
+ return PrivilegedRunner.doPrivileged(controlContext, dispatcher, type, arg1, arg2, arg3, null);
+ }
+
+ /**
+ * Performs a privileged action <b>using the current security context</b>.
+ * The method calls the dispatcher inside the privileged call passing it the
+ * same parameters that were passed to this method.
+ *
+ * @param dispatcher
+ * the dispatcher which should be called
+ * @param type
+ * the type of the action - used in the dispatcher
+ * @param arg1
+ * a parameter received by the dispatcher
+ * @param arg2
+ * a parameter received by the dispatcher
+ * @return the object returned from the execution
+ * @throws Exception
+ * if the dispatcher fails
+ * @see PrivilegedRunner#doPrivileged(Object,
+ * org.eclipse.equinox.internal.util.security.PrivilegedRunner.PrivilegedDispatcher,
+ * int, Object, Object, Object, Object)
+ */
+ public Object doPrivileged(PrivilegedRunner.PrivilegedDispatcher dispatcher, int type, Object arg1, Object arg2) throws Exception {
+ return PrivilegedRunner.doPrivileged(controlContext, dispatcher, type, arg1, arg2, null, null);
+ }
+
+ /**
+ * Performs a privileged action <b>using the current security context</b>.
+ * The method calls the dispatcher inside the privileged call passing it the
+ * same parameters that were passed to this method.
+ *
+ * @param dispatcher
+ * the dispatcher which should be called
+ * @param type
+ * the type of the action - used in the dispatcher
+ * @param arg1
+ * a parameter received by the dispatcher
+ * @return the object returned from the execution
+ * @throws Exception
+ * if the dispatcher fails
+ * @see PrivilegedRunner#doPrivileged(Object,
+ * org.eclipse.equinox.internal.util.security.PrivilegedRunner.PrivilegedDispatcher,
+ * int, Object, Object, Object, Object)
+ */
+ public Object doPrivileged(PrivilegedRunner.PrivilegedDispatcher dispatcher, int type, Object arg1) throws Exception {
+ return PrivilegedRunner.doPrivileged(controlContext, dispatcher, type, arg1, null, null, null);
+ }
+
+ /**
+ * @see org.eclipse.equinox.internal.util.security.PrivilegedRunner.PrivilegedDispatcher#dispatchPrivileged(int,
+ * java.lang.Object, java.lang.Object, java.lang.Object,
+ * java.lang.Object)
+ */
+ public Object dispatchPrivileged(int type, Object arg1, Object arg2, Object arg3, Object arg4) throws Exception {
+ switch (type) {
+ case SYSTEM_GET_PROPERTY :
+ return UtilActivator.bc.getProperty((String) arg1);
+ case CREATE_THREAD :
+ return new Thread((Runnable) arg1, (String) arg2);
+ case CLASS_FOR_NAME :
+ return Class.forName((String) arg1);
+ case SYSTEM_SET_PROPERTY :
+ return System.setProperty((String) arg1, (String) arg2);
+ case FILE_GET_INPUT_STREAM :
+ return new FileInputStream((File) arg1);
+ case FILE_GET_OUTPUT_STREAM :
+ return new FileOutputStream(((File) arg1).getAbsolutePath(), ((Boolean) arg2).booleanValue());
+ case FILE_LENGTH :
+ return new Long(((File) arg1).length());
+ case FILE_EXISTS :
+ return ((File) arg1).exists() ? Boolean.TRUE : Boolean.FALSE;
+ case FILE_ISDIR :
+ return ((File) arg1).isDirectory() ? Boolean.TRUE : Boolean.FALSE;
+ case FILE_LAST_MODIFIED :
+ return new Long(((File) arg1).lastModified());
+ case FILE_LIST :
+ return ((File) arg1).list();
+ case FILE_DELETE :
+ return ((File) arg1).delete() ? Boolean.TRUE : Boolean.FALSE;
+ case FILE_RENAME :
+ return ((File) arg1).renameTo(((File) arg2)) ? Boolean.TRUE : Boolean.FALSE;
+ case FILE_GET_RANDOM_ACCESS_FILE :
+ return new RandomAccessFile((File) arg1, (String) arg2);
+ case SERVICE_GET_REFERENCE :
+ return ((BundleContext) arg1).getServiceReferences((String) arg2, (String) arg3);
+ case SERVICE_GET_SERVICE :
+ return ((BundleContext) arg1).getService((ServiceReference) arg2);
+ case SERVICE_REG_CLASS :
+ return ((BundleContext) arg1).registerService((String) arg2, arg3, (Dictionary) arg4);
+ case SERVICE_REG_CLASSES :
+ return ((BundleContext) arg1).registerService((String[]) arg2, arg3, (Dictionary) arg4);
+ case BUNDLE_GET_LOCATION :
+ return ((Bundle) arg1).getLocation();
+ case BUNDLE_GET_HEADERS :
+ return ((Bundle) arg1).getHeaders();
+ case BUNDLE_START :
+ ((Bundle) arg1).start();
+ break;
+ case BUNDLE_STOP :
+ ((Bundle) arg1).stop();
+ break;
+ case BUNDLE_UNINSTALL :
+ ((Bundle) arg1).uninstall();
+ break;
+ case BUNDLE_UPDATE :
+ ((Bundle) arg1).update();
+ break;
+ case BUNDLE_UPDATE_IS :
+ ((Bundle) arg1).update((InputStream) arg2);
+ break;
+ }
+ return null;
+ }
+
+}
diff --git a/bundles/org.eclipse.equinox.util/src/org/eclipse/equinox/internal/util/security/package.html b/bundles/org.eclipse.equinox.util/src/org/eclipse/equinox/internal/util/security/package.html
new file mode 100644
index 000000000..0a41244ec
--- /dev/null
+++ b/bundles/org.eclipse.equinox.util/src/org/eclipse/equinox/internal/util/security/package.html
@@ -0,0 +1,13 @@
+<html>
+
+<head>
+<meta http-equiv="Content-Type"
+content="text/html; charset=iso-8859-1">
+<meta name="Author" content="Maria Ivanova">
+<meta name="GENERATOR" content="Microsoft FrontPage Express 2.0">
+<title>org.eclipse.equinox.util.jar</title>
+</head>
+<body>
+<p>The package provides additional functionality to java.util.jar packages.</p>
+</body>
+</html>
diff --git a/bundles/org.eclipse.equinox.util/src/org/eclipse/equinox/internal/util/threadpool/ThreadContext.java b/bundles/org.eclipse.equinox.util/src/org/eclipse/equinox/internal/util/threadpool/ThreadContext.java
new file mode 100644
index 000000000..b993951d5
--- /dev/null
+++ b/bundles/org.eclipse.equinox.util/src/org/eclipse/equinox/internal/util/threadpool/ThreadContext.java
@@ -0,0 +1,35 @@
+/*******************************************************************************
+ * 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.util.threadpool;
+
+/**
+ * Gives access to the user-provided Runnable object of the thread. All threads
+ * created by the ThreadPoolManager service implement that interface, so that in
+ * a method called by such a thread you can get the Runnable object provided in
+ * <code>
+ * ThreadPoolManager.execute(Runnable job, String threadName)</code>
+ * with the following line:
+ * <p>
+ * <code><ul> Runnable runnable = ((ThreadContext) Thread.currentThread()).getRunnable();</ul></code>
+ *
+ * @author Pavlin Dobrev
+ * @version 1.0
+ */
+
+public interface ThreadContext {
+ /**
+ * Returns the Runnable object provided in the
+ * <code>ThreadPoolManager.execute(Runnable job, String threadName)</code>
+ * method.
+ */
+ public Runnable getRunnable();
+}
diff --git a/bundles/org.eclipse.equinox.util/src/org/eclipse/equinox/internal/util/threadpool/ThreadPoolFactory.java b/bundles/org.eclipse.equinox.util/src/org/eclipse/equinox/internal/util/threadpool/ThreadPoolFactory.java
new file mode 100644
index 000000000..4f1568ef2
--- /dev/null
+++ b/bundles/org.eclipse.equinox.util/src/org/eclipse/equinox/internal/util/threadpool/ThreadPoolFactory.java
@@ -0,0 +1,42 @@
+/*******************************************************************************
+ * 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.util.threadpool;
+
+
+/**
+ * This interface is registered as a service in the framework. It allows bundles
+ * to specify the amount of threads they will need for their normal work. A
+ * bundle may be executing no more than a specified number of threads at the
+ * same time. This interface is provided in order to prevent a scenario where
+ * one bundle allocates all threads, thus freezing all other thread requestors.
+ *
+ * @author Pavlin Dobrev
+ * @version 1.0
+ */
+
+public interface ThreadPoolFactory {
+
+ /**
+ * Gets reference to the thread pool, by specifying how many threads will be
+ * simultaneously engaged by the requesting bundle. All execution requests
+ * above this number are put in a waiting queue until a threads is free.
+ *
+ * @param poolSize
+ * count of threads that can be simultaneously used by the
+ * requestor
+ * @param sizeIsInPercents
+ * indicates if the poolSize is percent of the maximum number of
+ * threads in the pool (true) or is a fixed count (false)
+ * @return reference to the thread pool manager
+ */
+ public ThreadPoolManager getThreadPool(int poolSize, boolean sizeIsInPercents);
+}
diff --git a/bundles/org.eclipse.equinox.util/src/org/eclipse/equinox/internal/util/threadpool/ThreadPoolManager.java b/bundles/org.eclipse.equinox.util/src/org/eclipse/equinox/internal/util/threadpool/ThreadPoolManager.java
new file mode 100644
index 000000000..af970e49b
--- /dev/null
+++ b/bundles/org.eclipse.equinox.util/src/org/eclipse/equinox/internal/util/threadpool/ThreadPoolManager.java
@@ -0,0 +1,65 @@
+/*******************************************************************************
+ * 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.util.threadpool;
+
+/**
+ * The ThreadPoolManager is responsible for the management of a thread pool,
+ * whose purpose is to provide created and started threads to clients, using
+ * multiple but short-lived threads.
+ *
+ * The ThreadPoolManager's main task is to accept Runnable objects, to pass them
+ * to threads from the pool, and after the job is finished - to return back the
+ * threads in pool.
+ *
+ * @author Pavlin Dobrev
+ * @version 1.0
+ */
+
+public interface ThreadPoolManager {
+
+ /**
+ * Executes the job, by passing it to an idle thread process. If no idle
+ * threads are available, the job is moved to the pool of waiting jobs, and
+ * will be executed later.
+ *
+ * @param job
+ * job to be executed
+ * @param threadName
+ * name of job; the name will be assigned to the thread, in which
+ * the job will be processed
+ * @exception IllegalArgumentException
+ * If any of the arguments is null
+ */
+ public void execute(Runnable job, String threadName) throws IllegalArgumentException;
+
+ /**
+ * Executes the job, by passing it to an idle thread process. If no idle
+ * threads are available, the job is moved to the pool of waiting jobs, and
+ * will be executed later.
+ *
+ * @param job
+ * Runnable job to be executed
+ * @param priority
+ * the priority of the job
+ * @param threadName
+ * name of job; the name will be assigned to the thread, in which
+ * the job will be processed
+ * @exception IllegalArgumentException
+ * If any of the arguments is null
+ */
+ public void execute(Runnable job, int priority, String threadName) throws IllegalArgumentException;
+
+ /**
+ * All idle threads exit. New threads will be created when it is necessary.
+ */
+ public void reset();
+}
diff --git a/bundles/org.eclipse.equinox.util/src/org/eclipse/equinox/internal/util/threadpool/package.html b/bundles/org.eclipse.equinox.util/src/org/eclipse/equinox/internal/util/threadpool/package.html
new file mode 100644
index 000000000..d3b409822
--- /dev/null
+++ b/bundles/org.eclipse.equinox.util/src/org/eclipse/equinox/internal/util/threadpool/package.html
@@ -0,0 +1,165 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
+<HTML>
+<HEAD>
+ <META HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=windows-1251">
+ <TITLE>ThreadPool</TITLE>
+ <META NAME="GENERATOR" CONTENT="OpenOffice.org 1.0 (Win32)">
+ <META NAME="AUTHOR" CONTENT="Maria Ivanova">
+ <META NAME="CREATED" CONTENT="20020718;16042117">
+ <META NAME="CHANGED" CONTENT="20020718;17380442">
+</HEAD>
+<BODY LANG="bg-BG">
+<P>This package contains the <FONT FACE="Courier New, Courier">ThreadPoolManager</FONT>
+interface, which is the face of the ThreadPoolManager Service. The
+task of the ThreadPoolManager is to provide created and started
+threads to its clients. The idea is to be saved time for the creation
+and starting of threads, when multiple, short-lived threads are used.
+</P>
+<P>At startup the ThreadPoolManager creates and starts a given number
+of threads put in waiting state. While working new threads can be
+created but the number of all threads created by the
+ThreadPoolManager can not exceed a fixed limit.
+</P>
+<P>When a client passes a job for execution to the ThreadPoolManager,
+it immediately tries to run the job. If there is an idle thread in
+the pool - the job is run, otherwise the job is put in waiting state
+until a thread finishes its current job and is ready to accept
+another one.
+</P>
+<P>If the Runnable objects, passed to the ThreadPoolManager do not
+face the requirements of short-living, there is a possibility to slow
+down the work of thread processing as many jobs can be put in waiting
+state. Another problem appears when processing bad-written Runnable
+objects (never exiting their run method), then the number of free
+threads decreases, the number of already running threads will reach
+the limit, and it may occur that no more threads can be processed.
+</P>
+<P STYLE="margin-bottom: 0cm">Here is a simple example of a job
+(RunnableSample) that is passed to the ThreadPoolManager for
+execution. The job is simple and common: it waits for an event to
+occur to process an operation; if the event does not occur for a
+given time period (1 second in our example) another operation is
+processed. In the example below the event is the &quot;check&quot;
+flag to be turned on, and the operations are &quot;System.out.println&quot;.
+<BR>&nbsp;
+</P>
+<TABLE COLS=1 WIDTH=100% BORDER=1 CELLPADDING=2 CELLSPACING=2>
+ <TR>
+ <TD>
+ <BLOCKQUOTE><FONT SIZE=2><FONT FACE="Courier New, Courier">public
+ class RunnableSample implements Runnable {</FONT></FONT> <BR><FONT SIZE=2><FONT FACE="Courier New, Courier">&nbsp;
+ private Object synch;</FONT></FONT> <BR><FONT SIZE=2><FONT FACE="Courier New, Courier">&nbsp;
+ private String name;</FONT></FONT> <BR><FONT SIZE=2><FONT FACE="Courier New, Courier">&nbsp;
+ private boolean check;</FONT></FONT> <BR><FONT SIZE=2><FONT FACE="Courier New, Courier">&nbsp;</FONT></FONT>
+ <BR><FONT SIZE=2><FONT FACE="Courier New, Courier">&nbsp;
+ //Constructs a RunnableSample.</FONT></FONT> <BR><FONT SIZE=2><FONT FACE="Courier New, Courier">&nbsp;
+ public RunnableSample(String name) {</FONT></FONT> <BR><FONT SIZE=2><FONT FACE="Courier New, Courier">&nbsp;&nbsp;&nbsp;
+ this.name = name;</FONT></FONT> <BR><FONT SIZE=2><FONT FACE="Courier New, Courier">&nbsp;&nbsp;&nbsp;
+ check = false;</FONT></FONT> <BR><FONT SIZE=2><FONT FACE="Courier New, Courier">&nbsp;&nbsp;&nbsp;
+ synch = new Object();</FONT></FONT> <BR><FONT SIZE=2><FONT FACE="Courier New, Courier">&nbsp;
+ }</FONT></FONT> <BR><FONT SIZE=2><FONT FACE="Courier New, Courier">&nbsp;</FONT></FONT>
+ <BR><FONT SIZE=2><FONT FACE="Courier New, Courier">&nbsp; //This
+ method is executed by the ThreadPoolManager.</FONT></FONT> <BR><FONT SIZE=2><FONT FACE="Courier New, Courier">&nbsp;
+ public void run() {</FONT></FONT> <BR><FONT SIZE=2><FONT FACE="Courier New, Courier">&nbsp;&nbsp;&nbsp;
+ synchronized (synch) {</FONT></FONT> <BR><FONT SIZE=2><FONT FACE="Courier New, Courier">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+ System.out.println(&quot;Job&nbsp; &quot;&nbsp; + name + &quot;
+ starts running!&quot;);</FONT></FONT> <BR><FONT SIZE=2><FONT FACE="Courier New, Courier">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+ if (!check) {</FONT></FONT> <BR><FONT SIZE=2><FONT FACE="Courier New, Courier">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+ try {</FONT></FONT> <BR><FONT SIZE=2><FONT FACE="Courier New, Courier">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+ synch.wait(1000);</FONT></FONT> <BR><FONT SIZE=2><FONT FACE="Courier New, Courier">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+ } catch (InterruptedException e) {</FONT></FONT> <BR><FONT SIZE=2><FONT FACE="Courier New, Courier">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+ }</FONT></FONT> <BR><FONT SIZE=2><FONT FACE="Courier New, Courier">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+ }</FONT></FONT> <BR><FONT SIZE=2><FONT FACE="Courier New, Courier">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+ if (check) {</FONT></FONT> <BR><FONT SIZE=2><FONT FACE="Courier New, Courier">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+ System.out.println(&quot;OK: CHECKED&quot;);</FONT></FONT> <BR><FONT SIZE=2><FONT FACE="Courier New, Courier">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+ } else {</FONT></FONT> <BR><FONT SIZE=2><FONT FACE="Courier New, Courier">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+ System.out.println(&quot;NOT OK: NOT CHECKED&quot;);</FONT></FONT>
+ <BR><FONT SIZE=2><FONT FACE="Courier New, Courier">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+ }</FONT></FONT> <BR><FONT SIZE=2><FONT FACE="Courier New, Courier">&nbsp;&nbsp;&nbsp;
+ }</FONT></FONT> <BR><FONT SIZE=2><FONT FACE="Courier New, Courier">&nbsp;
+ }</FONT></FONT>
+ </BLOCKQUOTE>
+ <BLOCKQUOTE><FONT SIZE=2><FONT FACE="Courier New, Courier">&nbsp;
+ //Turns the check flag on.&nbsp;</FONT></FONT> <BR><FONT SIZE=2><FONT FACE="Courier New, Courier">&nbsp;
+ public void checkIt() {</FONT></FONT> <BR><FONT SIZE=2><FONT FACE="Courier New, Courier">&nbsp;&nbsp;&nbsp;
+ synchronized (synch) {</FONT></FONT> <BR><FONT SIZE=2><FONT FACE="Courier New, Courier">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+ check = true;</FONT></FONT> <BR><FONT SIZE=2><FONT FACE="Courier New, Courier">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+ synch.notify();</FONT></FONT> <BR><FONT SIZE=2><FONT FACE="Courier New, Courier">&nbsp;&nbsp;&nbsp;
+ }</FONT></FONT> <BR><FONT SIZE=2><FONT FACE="Courier New, Courier">&nbsp;
+ }</FONT></FONT>
+ </BLOCKQUOTE>
+ <BLOCKQUOTE><FONT SIZE=2><FONT FACE="Courier New, Courier">&nbsp;
+ //Wakes up this Runnable object, causing exiting its run method.</FONT></FONT>
+ <BR><FONT SIZE=2><FONT FACE="Courier New, Courier">&nbsp; public
+ void stopIt() {</FONT></FONT> <BR><FONT SIZE=2><FONT FACE="Courier New, Courier">&nbsp;&nbsp;&nbsp;
+ synchronized (synch) {</FONT></FONT> <BR><FONT SIZE=2><FONT FACE="Courier New, Courier">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+ synch.notify();</FONT></FONT> <BR><FONT SIZE=2><FONT FACE="Courier New, Courier">&nbsp;&nbsp;&nbsp;
+ }</FONT></FONT> <BR><FONT SIZE=2><FONT FACE="Courier New, Courier">&nbsp;
+ }</FONT></FONT> <BR><FONT SIZE=2><FONT FACE="Courier New, Courier">}</FONT></FONT>
+ <BR>&nbsp;</BLOCKQUOTE>
+ </TD>
+ </TR>
+</TABLE>
+<P STYLE="margin-bottom: 0cm">The sample code , which follows, gets
+reference to the ThreadPoolManager, and passes a RunnableSample job
+for execution. <BR>&nbsp;
+</P>
+<TABLE COLS=1 WIDTH=100% BORDER=1 CELLPADDING=2 CELLSPACING=2>
+ <TR>
+ <TD>
+ <P><FONT SIZE=2><FONT FACE="Courier New, Courier">import
+ org.eclipse.equinox.util.threadpool.ThreadPoolManager;</FONT></FONT>
+ <BR><FONT SIZE=2><FONT FACE="Courier New, Courier">import
+ org.osgi.framework.BundleContext;</FONT></FONT> <BR><FONT SIZE=2><FONT FACE="Courier New, Courier">import
+ org.osgi.framework.ServiceReference;</FONT></FONT> <BR><FONT SIZE=2><FONT FACE="Courier New, Courier">&nbsp;
+ ...</FONT></FONT> <BR><FONT SIZE=2><FONT FACE="Courier New, Courier">&nbsp;
+ BundleContext bc;</FONT></FONT> <BR><FONT SIZE=2><FONT FACE="Courier New, Courier">&nbsp;
+ ServiceReference thManRef;</FONT></FONT> <BR><FONT SIZE=2><FONT FACE="Courier New, Courier">&nbsp;
+ ThreadPoolManager thMan;</FONT></FONT> <BR><FONT SIZE=2><FONT FACE="Courier New, Courier">&nbsp;
+ ...</FONT></FONT>
+ </P>
+ <P><FONT SIZE=2><FONT FACE="Courier New, Courier">&nbsp; thManRef
+ =
+ bc.getServiceReference(&quot;org.eclipse.equinox.util.threadpool.ThreadPoolManager&quot;);&nbsp;</FONT></FONT>
+ <BR><FONT SIZE=2><FONT FACE="Courier New, Courier">&nbsp; thMan =
+ (ThreadPoolManager) bc.getService(thManRef);</FONT></FONT> <BR><FONT SIZE=2><FONT FACE="Courier New, Courier">&nbsp;
+ String&nbsp; jobName = &quot;RunnableSample&quot;;</FONT></FONT>
+ <BR><FONT SIZE=2><FONT FACE="Courier New, Courier">&nbsp;
+ //ThreadPoolManager will execute the job, as soon as a free thread
+ is available</FONT></FONT> <BR><FONT SIZE=2><FONT FACE="Courier New, Courier">&nbsp;
+ thMan.execute(new RunnableSample(jobName), jobName);</FONT></FONT>
+ <BR><FONT SIZE=2><FONT FACE="Courier New, Courier">&nbsp; ...</FONT></FONT>
+ <BR>&nbsp;</P>
+ </TD>
+ </TR>
+</TABLE>
+<P>The ThreadPoolManager has two system properties, which define the
+limits of the thread pool:
+</P>
+<UL>
+ <LI><P STYLE="margin-bottom: 0cm"><B>equinox.util.threadpool.minThreads</B>
+ : default value: 4; this property defines the minimum number of idle
+ threads. The property cannot be 1 - if it is set to 1, automatically
+ it is turned to 2.
+ </P>
+ <LI><P><B>equinox.util.threadpool.maxThreads</B> : default value: 48;
+ this property specifies the upper limit for the number of threads
+ in the thread pool. The real limit is calculated using the formula:
+ (((int)(max/min)) * min).</P>
+ <LI><P><B>equinox.util.threadpool.autoMaximum</B> : default value:
+ false; if this property is set to true the then if there are more
+ then 10 waitng jobs the maximum can be exceeded.</P>
+ <LI><P><B>equinox.util.threadpool.ignoreMaximum</B> : default value:
+ false; if this property is set to true, the Thread Pool Manager will
+ not regard the maxThread property and will always create new threads
+ when there are no available.</P>
+ <LI><P><B>equinox.util.threadpool.useNames</B> : default value: false;
+ if this property is set to true, allows assigning names to threads,
+ executing runnable jobs.</P>
+ <LI><P><B>equinox.util.threadpool.percent</B> : default value: 30; this
+ property specifies what default percent of the maximum number of
+ threads a bundle can occupy from the thread pool.</P>
+
+</UL>
+</BODY>
+</HTML> \ No newline at end of file
diff --git a/bundles/org.eclipse.equinox.util/src/org/eclipse/equinox/internal/util/timer/Timer.java b/bundles/org.eclipse.equinox.util/src/org/eclipse/equinox/internal/util/timer/Timer.java
new file mode 100644
index 000000000..cd38cf067
--- /dev/null
+++ b/bundles/org.eclipse.equinox.util/src/org/eclipse/equinox/internal/util/timer/Timer.java
@@ -0,0 +1,190 @@
+/*******************************************************************************
+ * 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.util.timer;
+
+/**
+ * Timer service provides means for sending notifications at given time periods
+ * to each listener registered with Timer. To receive notifications, a module
+ * should first register a TimerListener, associated with an (int) event and a
+ * time period. When the time period passes, TimerListener's timer method is
+ * invoked, and the listener is removed from the queue with the waiting event
+ * notifications.
+ *
+ * @see TimerListener
+ *
+ * @author Pavlin Dobrev
+ * @version 1.0
+ */
+
+public interface Timer {
+
+ /**
+ * Constant indicates that timer listener will be notified only once and
+ * afterwards discarded.
+ */
+ public int ONE_SHOT_TIMER = 0;
+
+ /**
+ * Constant indicates that timer listener will be notified periodically at a
+ * given time interval.
+ */
+ public int PERIODICAL_TIMER = 1;
+
+ /**
+ * Constant indicates that timer listener will be notified only once. Timer
+ * implementation would do its best to execute the notification with minimum
+ * possible delay.
+ */
+ public int ONE_SHOT_TIMER_NO_DELAY = 2;
+
+ /**
+ * Constant indicates that timer listener will be notified periodically at a
+ * given time interval. Timer implementation would do its best to execute
+ * the notification with minimum possible delay.
+ */
+ public int PERIODICAL_TIMER_NO_DELAY = 3;
+
+ /**
+ * Adds new TimerListener to the timer event quueue. The listener will be
+ * notified after the given <code>timePeriod</code> with specified
+ * <code>event</code>. If the event queue already contains a listener and
+ * event pair equal to those being passed, then the old notification object
+ * is removed from queue and the new data takes its place.
+ *
+ * @param listener
+ * the listener which will be notified after the given time
+ * period
+ * @param timePeriod
+ * time period in milliseconds after which the listener will be
+ * notified
+ * @param event
+ * which will be supplied to the listener when it is notified
+ *
+ * @exception IllegalArgumentException
+ * if time period is not positive
+ * @deprecated
+ */
+ public void notifyAfterMillis(TimerListener listener, long timePeriod, int event) throws IllegalArgumentException;
+
+ /**
+ * Adds new TimerListener to the timer event quueue. The listener will be
+ * notified after the given <code>timePeriod</code> with specified
+ * <code>event</code>. If the event queue already contains a listener and
+ * event pair equal to those being passed, then the old notification object
+ * is removed from queue and the new data takes its place.
+ *
+ * @param listener
+ * the listener which will be notified after the given time
+ * period
+ * @param priority
+ * priority of executing thread
+ * @param timePeriod
+ * time period in milliseconds after which the listener will be
+ * notified
+ * @param event
+ * which will be supplied to the listener when it is notified
+ *
+ * @exception IllegalArgumentException
+ * if time period is not positive priority is not between
+ * Thread.MIN_PRIORITY and Thread.MAX_PRIORITY
+ * @deprecated
+ */
+ public void notifyAfterMillis(TimerListener listener, int priority, long timePeriod, int event) throws IllegalArgumentException;
+
+ /**
+ * Adds new TimerListener to the timer event quueue. The listener will be
+ * notified after the given <code>timePeriod</code> with specified
+ * <code>event</code>. If the event queue already contains a listener and
+ * event pair equal to those being passed, then the old notification object
+ * is removed from queue and the new data takes its place.
+ *
+ * @param listener
+ * the listener which will be notified after the given time
+ * period
+ * @param timePeriod
+ * time period in seconds after which the listener will be
+ * notified
+ * @param event
+ * which will be supplied to the listener when it is notified
+ *
+ * @exception IllegalArgumentException
+ * if time period is not positive
+ * @deprecated
+ */
+ public void notifyAfter(TimerListener listener, int timePeriod, int event) throws IllegalArgumentException;
+
+ /**
+ * Adds new TimerListener to the timer event quueue. The listener will be
+ * notified after the given <code>timePeriod</code> with specified
+ * <code>event</code>. If the event queue already contains a listener and
+ * event pair equal to those being passed, then the old notification object
+ * is removed from queue and the new data takes its place.
+ *
+ * @param listener
+ * the listener which will be notified after the given time
+ * period
+ * @param priority
+ * priority of executing thread
+ * @param timePeriod
+ * time period in seconds after which the listener will be
+ * notified
+ * @param event
+ * which will be supplied to the listener when it is notified
+ *
+ * @exception IllegalArgumentException
+ * if time period is not positive or priority is not between
+ * Thread.MIN_PRIORITY and Thread.MAX_PRIORITY
+ * @deprecated
+ */
+ public void notifyAfter(TimerListener listener, int priority, int timePeriod, int event) throws IllegalArgumentException;
+
+ /**
+ * Adds new TimerListener to the timer event quueue. The listener will be
+ * notified after the given <code>timePeriod</code> with specified
+ * <code>event</code>. If the event queue already contains a listener and
+ * event pair equal to those being passed, then the old notification object
+ * is removed from queue and the new data takes its place.
+ *
+ * @param listener
+ * the listener which will be notified after the given time
+ * period
+ * @param priority
+ * priority of executing thread
+ * @param timerType
+ * the type of the timer "Periodical", "One shot", "Periodical No
+ * Delay", or "One shot no delay"
+ * @param timePeriod
+ * time period in seconds after which the listener will be
+ * notified
+ * @param event
+ * which will be supplied to the listener when it is notified
+ *
+ * @exception IllegalArgumentException
+ * if time period is not positive or priority is not between
+ * Thread.MIN_PRIORITY and Thread.MAX_PRIORITY or the
+ * timerType is not a correct timer type or the listener is
+ * null
+ */
+ public void addNotifyListener(TimerListener listener, int priority, int timerType, long periodMilis, int event);
+
+ /**
+ * Removes the TimerListener-event pair from the queue, so that the listener
+ * should not be notified after the time period passes.
+ *
+ * @param listener
+ * to be removed.
+ * @param event
+ * for which the timer listener should have been notified.
+ *
+ */
+ public void removeListener(TimerListener listener, int event);
+}
diff --git a/bundles/org.eclipse.equinox.util/src/org/eclipse/equinox/internal/util/timer/TimerListener.java b/bundles/org.eclipse.equinox.util/src/org/eclipse/equinox/internal/util/timer/TimerListener.java
new file mode 100644
index 000000000..a3d6e4a01
--- /dev/null
+++ b/bundles/org.eclipse.equinox.util/src/org/eclipse/equinox/internal/util/timer/TimerListener.java
@@ -0,0 +1,36 @@
+/*******************************************************************************
+ * 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.util.timer;
+
+/**
+ * This interface must be implemented by all classes which wish to be registered
+ * to the Timer service and to be notified after given time periods.
+ *
+ * @see Timer
+ *
+ * @author Pavlin Dobrev
+ * @version 1.0
+ */
+
+public interface TimerListener {
+
+ /**
+ * This method will be invoked by Timer to notify the listener for the
+ * expiration of its time period.
+ *
+ * @param event
+ * the event code which is supplied when this listener had been
+ * registered
+ */
+ public void timer(int event);
+
+}
diff --git a/bundles/org.eclipse.equinox.util/src/org/eclipse/equinox/internal/util/timer/package.html b/bundles/org.eclipse.equinox.util/src/org/eclipse/equinox/internal/util/timer/package.html
new file mode 100644
index 000000000..1f965479b
--- /dev/null
+++ b/bundles/org.eclipse.equinox.util/src/org/eclipse/equinox/internal/util/timer/package.html
@@ -0,0 +1,174 @@
+<html>
+
+<head>
+<meta http-equiv="Content-Type"
+content="text/html; charset=iso-8859-1">
+<meta name="Author" content="Maria Ivanova">
+<meta name="GENERATOR" content="Microsoft FrontPage Express 2.0">
+<title>org.eclipse.equinox.util.timer</title>
+</head>
+
+<body>
+
+<p>This package adds the Timer Service by
+adding two additional interfaces. The idea is the Timer Service
+to provide universal timers which can be used by other bundles if
+they need them. When the Util Bundle is started, the Timer
+Service is registered and started, too. To use the Timer Service,
+you have to get it from the Bundle Context. </p>
+
+<p>To create a timer, you must invoke Timer's method <i>notifyAfter(listener,
+timePeriod, event)</i> and pass correct parameters to it. </p>
+
+<blockquote>
+ <p><i>listener</i> is object of a class implementing the<i>
+ TimerListener</i> interface whose <i>time(event)</i> method
+ will be invoked after the given <i>timePeriod</i> (in seconds)
+ with event specified in the <i>notifyAfter</i> method. The
+ Timer Service makes an event queue from all started timer
+ listeners and when some <i>timePeriod</i> of them passes, it
+ invokes its timer method with specified <i>event</i> and
+ removes it from queue. If the <i>notifyAfter</i> method is
+ invoked with listener and event that already exist in queue,
+ the previous listener is removed and the new one replaces it.</p>
+</blockquote>
+
+<blockquote>
+ <p><i>event</i> is an int parameter. When more than one timer
+ is started with the same listener, <i>event</i> shows which
+ of them is to be notified.</p>
+</blockquote>
+
+<p>With the <i>removeLisener(listener, event)</i> method it is
+possible to remove a listener with the specified event from the
+queue before its <i>timePeriod</i> has passed. If the listener
+with the specified event is not found, nothing happens. <br>
+&nbsp; </p>
+
+<blockquote>
+ <p>Here is an example which starts 3 timers with diferent
+ timerPeriod. The timer with lisener lsn1 and event 1 will be
+ started again with diferent timePeriod, the Timer Service
+ will remove the previous timer and only new one will stay in
+ the queue. The timer with lisener lsn2 and event 2 will be
+ removed from the queue befor its timePeriod has passed. Only
+ timer with lisener lsn1, timePeriod 5 sec and event 1 will be
+ notified by the Timer Service when its timePeriod has passed.</p>
+</blockquote>
+
+<table border="1" width="100%" cols="1">
+ <tr>
+ <td width="100%" nowrap><blockquote>
+ <p>&nbsp; <br>
+ <font size="2" face="Courier New">public class
+ TestTimer { <br>
+ &nbsp; private BundleContext bc; <br>
+ &nbsp; private ServiceReference timerReference; <br>
+ &nbsp; private Timer timer; </font></p>
+ <p><font size="2" face="Courier New">&nbsp;public
+ TestTimer(BundleContext bc) { <br>
+ &nbsp;&nbsp;&nbsp; try { <br>
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.bc = bc; <br>
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; timerReference = bc.getServiceReference(&quot;org.eclipse.equinox.util.timer.Timer&quot;);
+ <br>
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (timerReference !=
+ null) { <br>
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; timer = (Timer)bc.getService(timerReference);
+ <br>
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+ setTimerIntervals();&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+ <br>
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } <br>
+ &nbsp;&nbsp;&nbsp; } catch (Exception e) { <br>
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println(&quot;An
+ error in start method.\n &quot; + e); <br>
+ &nbsp;&nbsp;&nbsp; } <br>
+ &nbsp; }&nbsp; <br>
+ &nbsp;&nbsp; <br>
+ &nbsp; private void setTimerIntervals() { <br>
+ &nbsp;&nbsp;&nbsp; int t;&nbsp; //timePeriod <br>
+ &nbsp;&nbsp;&nbsp; int e;&nbsp; //event <br>
+ &nbsp;&nbsp;&nbsp;&nbsp; <br>
+ &nbsp;&nbsp;&nbsp; //create lsn1 lisener implementing
+ TimerLisener interface <br>
+ &nbsp;&nbsp;&nbsp; TestTimerListener lsn1 = new
+ TestTimerListener(); <br>
+ &nbsp;&nbsp;&nbsp; t = 10; <br>
+ &nbsp;&nbsp;&nbsp; e = 1; <br>
+ &nbsp;&nbsp;&nbsp; //start timer interval <br>
+ &nbsp;&nbsp;&nbsp; timer.notifyAfter(lsn1, t, e); <br>
+ &nbsp;&nbsp;&nbsp; System.out.println(&quot;Timer
+ with lisener lsn1 was started - timePeriod &quot; + t
+ + &quot; sec, event &quot; + e); <br>
+ &nbsp;&nbsp;&nbsp;&nbsp; <br>
+ &nbsp;&nbsp;&nbsp; //create lsn2 lisener implementing
+ TimerLisener interface <br>
+ &nbsp;&nbsp;&nbsp; TestTimerListener lsn2 = new
+ TestTimerListener(); <br>
+ &nbsp;&nbsp;&nbsp; t = 12; <br>
+ &nbsp;&nbsp;&nbsp; e = 2; <br>
+ &nbsp;&nbsp;&nbsp; //start timer interval <br>
+ &nbsp;&nbsp;&nbsp; timer.notifyAfter(lsn2, t, e); <br>
+ &nbsp;&nbsp;&nbsp; System.out.println(&quot;Timer
+ with lisener lsn2 was started - timePeriod &quot; + t
+ + &quot; sec, event &quot; + e); </font></p>
+ <p><font size="2" face="Courier New">&nbsp;&nbsp;&nbsp;
+ t = 5; <br>
+ &nbsp;&nbsp;&nbsp; e = 1; <br>
+ &nbsp;&nbsp;&nbsp; //start timer interval <br>
+ &nbsp;&nbsp;&nbsp; timer.notifyAfter(lsn1, t, e); <br>
+ &nbsp;&nbsp;&nbsp; System.out.println(&quot;Timer
+ with lisener lsn1 was started - timePeriod &quot; + t
+ + &quot; sec, event &quot; + e); <br>
+ &nbsp;&nbsp;&nbsp; System.out.println(&quot;\n&quot;);
+ <br>
+ &nbsp;&nbsp;&nbsp;&nbsp; <br>
+ &nbsp;&nbsp;&nbsp; //remove lsn2 lisener with event 1
+ <br>
+ &nbsp;&nbsp;&nbsp; e = 2; <br>
+ &nbsp;&nbsp;&nbsp; timer.removeListener(lsn2, e);&nbsp;&nbsp;
+ <br>
+ &nbsp; }&nbsp; <br>
+ &nbsp;&nbsp; <br>
+ }&nbsp;&nbsp; <br>
+ &nbsp;</font></p>
+ </blockquote>
+ </td>
+ </tr>
+</table>
+
+<blockquote>
+ <p>The TestTimerListener class implements the TimerListener
+ interface and its method timer(event) will be invoked every
+ time a timerPeriod passes.</p>
+</blockquote>
+
+<table border="1" width="100%" cols="1">
+ <tr>
+ <td><blockquote>
+ <p><font size="2" face="Courier New">&nbsp; <br>
+ public class TestTimerListener implements
+ TimerListener { <br>
+ &nbsp;&nbsp; <br>
+ &nbsp; public TestTimerListener() { <br>
+ &nbsp; } <br>
+ &nbsp;&nbsp; <br>
+ &nbsp; public void timer(int event){ <br>
+ &nbsp;&nbsp;&nbsp; System.out.println(&quot;Timer
+ with event &quot; + event + &quot; has ended&quot;); <br>
+ &nbsp; }&nbsp;&nbsp; <br>
+ }</font></p>
+ </blockquote>
+ </td>
+ </tr>
+</table>
+
+<p><br>
+&nbsp; <br>
+&nbsp; <br>
+&nbsp; <br>
+&nbsp; <br>
+&nbsp; <br>
+&nbsp; </p>
+</body>
+</html>

Back to the top