Bug 571007 - Move copyright tool to buildtools repository
Change-Id: If086ef0e615510101cc01ff512aac0f7236cb513
Signed-off-by: Sravan Kumar Lakkimsetti <sravankumarl@in.ibm.com>
diff --git a/bundles/org.eclipse.releng.tools/.classpath b/bundles/org.eclipse.releng.tools/.classpath
new file mode 100644
index 0000000..e801ebf
--- /dev/null
+++ b/bundles/org.eclipse.releng.tools/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-11"/>
+ <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+ <classpathentry kind="src" path="src"/>
+ <classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/bundles/org.eclipse.releng.tools/.project b/bundles/org.eclipse.releng.tools/.project
new file mode 100644
index 0000000..263fdd6
--- /dev/null
+++ b/bundles/org.eclipse.releng.tools/.project
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>org.eclipse.releng.tools</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.releng.tools/.settings/org.eclipse.core.resources.prefs b/bundles/org.eclipse.releng.tools/.settings/org.eclipse.core.resources.prefs
new file mode 100644
index 0000000..99f26c0
--- /dev/null
+++ b/bundles/org.eclipse.releng.tools/.settings/org.eclipse.core.resources.prefs
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+encoding/<project>=UTF-8
diff --git a/bundles/org.eclipse.releng.tools/.settings/org.eclipse.core.runtime.prefs b/bundles/org.eclipse.releng.tools/.settings/org.eclipse.core.runtime.prefs
new file mode 100644
index 0000000..5a0ad22
--- /dev/null
+++ b/bundles/org.eclipse.releng.tools/.settings/org.eclipse.core.runtime.prefs
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+line.separator=\n
diff --git a/bundles/org.eclipse.releng.tools/.settings/org.eclipse.jdt.core.prefs b/bundles/org.eclipse.releng.tools/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..cac1666
--- /dev/null
+++ b/bundles/org.eclipse.releng.tools/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,414 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.annotation.inheritNullAnnotations=disabled
+org.eclipse.jdt.core.compiler.annotation.missingNonNullByDefaultAnnotation=ignore
+org.eclipse.jdt.core.compiler.annotation.nonnull=org.eclipse.jdt.annotation.NonNull
+org.eclipse.jdt.core.compiler.annotation.nonnull.secondary=
+org.eclipse.jdt.core.compiler.annotation.nonnullbydefault=org.eclipse.jdt.annotation.NonNullByDefault
+org.eclipse.jdt.core.compiler.annotation.nonnullbydefault.secondary=
+org.eclipse.jdt.core.compiler.annotation.nullable=org.eclipse.jdt.annotation.Nullable
+org.eclipse.jdt.core.compiler.annotation.nullable.secondary=
+org.eclipse.jdt.core.compiler.annotation.nullanalysis=disabled
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=11
+org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
+org.eclipse.jdt.core.compiler.compliance=11
+org.eclipse.jdt.core.compiler.debug.lineNumber=generate
+org.eclipse.jdt.core.compiler.debug.localVariable=generate
+org.eclipse.jdt.core.compiler.debug.sourceFile=generate
+org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.autoboxing=ignore
+org.eclipse.jdt.core.compiler.problem.comparingIdentical=warning
+org.eclipse.jdt.core.compiler.problem.deadCode=error
+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=ignore
+org.eclipse.jdt.core.compiler.problem.emptyStatement=ignore
+org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.problem.explicitlyClosedAutoCloseable=warning
+org.eclipse.jdt.core.compiler.problem.fallthroughCase=warning
+org.eclipse.jdt.core.compiler.problem.fatalOptionalError=disabled
+org.eclipse.jdt.core.compiler.problem.fieldHiding=ignore
+org.eclipse.jdt.core.compiler.problem.finalParameterBound=warning
+org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning
+org.eclipse.jdt.core.compiler.problem.forbiddenReference=error
+org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=warning
+org.eclipse.jdt.core.compiler.problem.includeNullInfoFromAsserts=disabled
+org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning
+org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=error
+org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=warning
+org.eclipse.jdt.core.compiler.problem.localVariableHiding=ignore
+org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=warning
+org.eclipse.jdt.core.compiler.problem.missingDefaultCase=ignore
+org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=warning
+org.eclipse.jdt.core.compiler.problem.missingEnumCaseDespiteDefault=disabled
+org.eclipse.jdt.core.compiler.problem.missingHashCodeMethod=ignore
+org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=warning
+org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotationForInterfaceMethodImplementation=enabled
+org.eclipse.jdt.core.compiler.problem.missingSerialVersion=warning
+org.eclipse.jdt.core.compiler.problem.missingSynchronizedOnInheritedMethod=ignore
+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.nonnullParameterAnnotationDropped=warning
+org.eclipse.jdt.core.compiler.problem.nonnullTypeVariableFromLegacyInvocation=warning
+org.eclipse.jdt.core.compiler.problem.nullAnnotationInferenceConflict=error
+org.eclipse.jdt.core.compiler.problem.nullReference=error
+org.eclipse.jdt.core.compiler.problem.nullSpecViolation=error
+org.eclipse.jdt.core.compiler.problem.nullUncheckedConversion=warning
+org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning
+org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore
+org.eclipse.jdt.core.compiler.problem.pessimisticNullAnalysisForFreeTypeVariables=warning
+org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=warning
+org.eclipse.jdt.core.compiler.problem.potentialNullReference=ignore
+org.eclipse.jdt.core.compiler.problem.potentiallyUnclosedCloseable=ignore
+org.eclipse.jdt.core.compiler.problem.rawTypeReference=warning
+org.eclipse.jdt.core.compiler.problem.redundantNullAnnotation=warning
+org.eclipse.jdt.core.compiler.problem.redundantNullCheck=ignore
+org.eclipse.jdt.core.compiler.problem.redundantSpecificationOfTypeArguments=warning
+org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=warning
+org.eclipse.jdt.core.compiler.problem.reportMethodCanBePotentiallyStatic=ignore
+org.eclipse.jdt.core.compiler.problem.reportMethodCanBeStatic=ignore
+org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning
+org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled
+org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning
+org.eclipse.jdt.core.compiler.problem.suppressOptionalErrors=disabled
+org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled
+org.eclipse.jdt.core.compiler.problem.syntacticNullAnalysisForFields=disabled
+org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore
+org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning
+org.eclipse.jdt.core.compiler.problem.unavoidableGenericTypeProblems=enabled
+org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning
+org.eclipse.jdt.core.compiler.problem.unclosedCloseable=warning
+org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=ignore
+org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning
+org.eclipse.jdt.core.compiler.problem.unnecessaryElse=ignore
+org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=warning
+org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=ignore
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionExemptExceptionAndThrowable=enabled
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionIncludeDocCommentReference=enabled
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled
+org.eclipse.jdt.core.compiler.problem.unusedExceptionParameter=ignore
+org.eclipse.jdt.core.compiler.problem.unusedImport=warning
+org.eclipse.jdt.core.compiler.problem.unusedLabel=warning
+org.eclipse.jdt.core.compiler.problem.unusedLocal=error
+org.eclipse.jdt.core.compiler.problem.unusedObjectAllocation=ignore
+org.eclipse.jdt.core.compiler.problem.unusedParameter=ignore
+org.eclipse.jdt.core.compiler.problem.unusedParameterIncludeDocCommentReference=enabled
+org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled
+org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled
+org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning
+org.eclipse.jdt.core.compiler.problem.unusedTypeParameter=ignore
+org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning
+org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning
+org.eclipse.jdt.core.compiler.release=enabled
+org.eclipse.jdt.core.compiler.source=11
+org.eclipse.jdt.core.formatter.align_type_members_on_columns=false
+org.eclipse.jdt.core.formatter.alignment_for_additive_operator=16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation=0
+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_bitwise_operator=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_logical_operator=16
+org.eclipse.jdt.core.formatter.alignment_for_method_declaration=0
+org.eclipse.jdt.core.formatter.alignment_for_multiple_fields=16
+org.eclipse.jdt.core.formatter.alignment_for_multiplicative_operator=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_resources_in_try=80
+org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation=16
+org.eclipse.jdt.core.formatter.alignment_for_string_concatenation=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.alignment_for_union_type_in_multicatch=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_lambda_body=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=true
+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=true
+org.eclipse.jdt.core.formatter.comment.format_line_comments=true
+org.eclipse.jdt.core.formatter.comment.format_source_code=true
+org.eclipse.jdt.core.formatter.comment.indent_parameter_description=true
+org.eclipse.jdt.core.formatter.comment.indent_root_tags=true
+org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags=insert
+org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter=insert
+org.eclipse.jdt.core.formatter.comment.line_length=80
+org.eclipse.jdt.core.formatter.comment.new_lines_at_block_boundaries=true
+org.eclipse.jdt.core.formatter.comment.new_lines_at_javadoc_boundaries=true
+org.eclipse.jdt.core.formatter.comment.preserve_white_space_between_code_and_line_comments=false
+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.disabling_tag=@formatter\:off
+org.eclipse.jdt.core.formatter.enabling_tag=@formatter\:on
+org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line=false
+org.eclipse.jdt.core.formatter.format_line_comment_starting_on_first_column=true
+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=false
+org.eclipse.jdt.core.formatter.indentation.size=4
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_field=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_method=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_package=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_type=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_label=do not 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_after_type_annotation=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=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_additive_operator=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_bitwise_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments=do not 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_lambda_arrow=insert
+org.eclipse.jdt.core.formatter.insert_space_after_logical_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_after_multiplicative_operator=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=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_try=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_relational_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for=insert
+org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_try_resources=insert
+org.eclipse.jdt.core.formatter.insert_space_after_shift_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_after_string_concatenation=insert
+org.eclipse.jdt.core.formatter.insert_space_after_unary_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_additive_operator=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_bitwise_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=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_try=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=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional=insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default=do not 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_lambda_arrow=insert
+org.eclipse.jdt.core.formatter.insert_space_before_logical_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_before_multiplicative_operator=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_try=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_relational_operator=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_semicolon_in_try_resources=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_shift_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_before_string_concatenation=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.join_lines_in_comments=true
+org.eclipse.jdt.core.formatter.join_wrapped_lines=true
+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=120
+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=true
+org.eclipse.jdt.core.formatter.tabulation.char=tab
+org.eclipse.jdt.core.formatter.tabulation.size=4
+org.eclipse.jdt.core.formatter.use_on_off_tags=false
+org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations=false
+org.eclipse.jdt.core.formatter.wrap_before_additive_operator=true
+org.eclipse.jdt.core.formatter.wrap_before_bitwise_operator=true
+org.eclipse.jdt.core.formatter.wrap_before_logical_operator=true
+org.eclipse.jdt.core.formatter.wrap_before_multiplicative_operator=true
+org.eclipse.jdt.core.formatter.wrap_before_or_operator_multicatch=true
+org.eclipse.jdt.core.formatter.wrap_before_string_concatenation=true
+org.eclipse.jdt.core.formatter.wrap_outer_expressions_when_nested=true
+org.eclipse.jdt.core.javaFormatter=org.eclipse.jdt.core.defaultJavaFormatter
diff --git a/bundles/org.eclipse.releng.tools/.settings/org.eclipse.jdt.ui.prefs b/bundles/org.eclipse.releng.tools/.settings/org.eclipse.jdt.ui.prefs
new file mode 100644
index 0000000..991e1b2
--- /dev/null
+++ b/bundles/org.eclipse.releng.tools/.settings/org.eclipse.jdt.ui.prefs
@@ -0,0 +1,51 @@
+eclipse.preferences.version=1
+editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true
+formatter_profile=org.eclipse.jdt.ui.default.eclipse_profile
+formatter_settings_version=12
+sp_cleanup.add_default_serial_version_id=true
+sp_cleanup.add_generated_serial_version_id=false
+sp_cleanup.add_missing_annotations=true
+sp_cleanup.add_missing_deprecated_annotations=true
+sp_cleanup.add_missing_nls_tags=false
+sp_cleanup.add_missing_override_annotations=true
+sp_cleanup.add_serial_version_id=false
+sp_cleanup.always_use_blocks=true
+sp_cleanup.always_use_parentheses_in_expressions=false
+sp_cleanup.always_use_this_for_non_static_field_access=false
+sp_cleanup.always_use_this_for_non_static_method_access=false
+sp_cleanup.convert_to_enhanced_for_loop=false
+sp_cleanup.format_source_code=false
+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.releng.tools/.settings/org.eclipse.pde.prefs b/bundles/org.eclipse.releng.tools/.settings/org.eclipse.pde.prefs
new file mode 100644
index 0000000..ba85338
--- /dev/null
+++ b/bundles/org.eclipse.releng.tools/.settings/org.eclipse.pde.prefs
@@ -0,0 +1,32 @@
+compilers.f.unresolved-features=1
+compilers.f.unresolved-plugins=1
+compilers.incompatible-environment=0
+compilers.p.build=1
+compilers.p.build.bin.includes=1
+compilers.p.build.encodings=2
+compilers.p.build.java.compiler=2
+compilers.p.build.java.compliance=1
+compilers.p.build.missing.output=2
+compilers.p.build.output.library=1
+compilers.p.build.source.library=1
+compilers.p.build.src.includes=1
+compilers.p.deprecated=1
+compilers.p.discouraged-class=1
+compilers.p.internal=1
+compilers.p.missing-packages=0
+compilers.p.missing-version-export-package=2
+compilers.p.missing-version-import-package=2
+compilers.p.missing-version-require-bundle=2
+compilers.p.no-required-att=0
+compilers.p.not-externalized-att=1
+compilers.p.unknown-attribute=0
+compilers.p.unknown-class=0
+compilers.p.unknown-element=0
+compilers.p.unknown-identifier=1
+compilers.p.unknown-resource=0
+compilers.p.unresolved-ex-points=0
+compilers.p.unresolved-import=0
+compilers.s.create-docs=false
+compilers.s.doc-folder=doc
+compilers.s.open-tags=1
+eclipse.preferences.version=1
diff --git a/bundles/org.eclipse.releng.tools/META-INF/MANIFEST.MF b/bundles/org.eclipse.releng.tools/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..847f8c1
--- /dev/null
+++ b/bundles/org.eclipse.releng.tools/META-INF/MANIFEST.MF
@@ -0,0 +1,32 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: %PluginName
+Bundle-SymbolicName: org.eclipse.releng.tools; singleton:=true
+Bundle-Version: 4.1.100.qualifier
+Bundle-Activator: org.eclipse.releng.tools.RelEngPlugin
+Bundle-Vendor: %PluginProvider
+Bundle-Localization: plugin
+Require-Bundle: org.eclipse.ui.ide;resolution:=optional,
+ org.eclipse.ui.views;resolution:=optional,
+ org.eclipse.jface.text;resolution:=optional,
+ org.eclipse.ui.workbench.texteditor;resolution:=optional,
+ org.eclipse.ui.editors;resolution:=optional,
+ org.eclipse.core.resources,
+ org.eclipse.ui,
+ org.eclipse.team.core,
+ org.eclipse.core.runtime,
+ org.eclipse.team.core,
+ org.eclipse.team.ui,
+ org.eclipse.compare,
+ org.eclipse.ui.console,
+ org.eclipse.jgit;bundle-version="4.0.0";resolution:=optional,
+ org.eclipse.egit.core;bundle-version="4.0.0";resolution:=optional,
+ org.eclipse.text
+Bundle-ActivationPolicy: lazy
+Bundle-RequiredExecutionEnvironment: JavaSE-11
+Export-Package:
+ org.eclipse.releng.tools,
+ org.eclipse.releng.tools.git;x-friends:="org.eclipse.releng.tests",
+ org.eclipse.releng.tools.preferences,
+ org.eclipse.releng.internal.tools.pomversion;x-internal:=true
+Automatic-Module-Name: org.eclipse.releng.tools
diff --git a/bundles/org.eclipse.releng.tools/about.html b/bundles/org.eclipse.releng.tools/about.html
new file mode 100644
index 0000000..164f781
--- /dev/null
+++ b/bundles/org.eclipse.releng.tools/about.html
@@ -0,0 +1,36 @@
+<!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>November 30, 2017</p>
+ <h3>License</h3>
+
+ <p>
+ The Eclipse Foundation makes available all content in this plug-in
+ ("Content"). Unless otherwise indicated below, the Content
+ is provided to you under the terms and conditions of the Eclipse
+ Public License Version 2.0 ("EPL"). A copy of the EPL is
+ available at <a href="http://www.eclipse.org/legal/epl-2.0">http://www.eclipse.org/legal/epl-2.0</a>.
+ For purposes of the EPL, "Program" 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
+ ("Redistributor") and different terms and conditions may
+ apply to your use of any object code in the Content. Check the
+ Redistributor's license that was provided with the Content. If no such
+ license exists, contact the Redistributor. Unless otherwise indicated
+ below, the terms and conditions of the EPL still apply to any source
+ code in the Content and such source code may be obtained at <a
+ href="http://www.eclipse.org/">http://www.eclipse.org</a>.
+ </p>
+
+</body>
+</html>
\ No newline at end of file
diff --git a/bundles/org.eclipse.releng.tools/build.properties b/bundles/org.eclipse.releng.tools/build.properties
new file mode 100644
index 0000000..04811aa
--- /dev/null
+++ b/bundles/org.eclipse.releng.tools/build.properties
@@ -0,0 +1,23 @@
+###############################################################################
+# Copyright (c) 2000, 2005 IBM Corporation and others.
+#
+# This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License 2.0
+# which accompanies this distribution, and is available at
+# https://www.eclipse.org/legal/epl-2.0/
+#
+# SPDX-License-Identifier: EPL-2.0
+#
+# Contributors:
+# IBM Corporation - initial API and implementation
+###############################################################################
+bin.includes = .,\
+ plugin.xml,\
+ about.html,\
+ icons/,\
+ plugin.properties,\
+ META-INF/
+src.includes = about.html
+jars.compile.order = .
+source.. = src/
+output.. = bin/
diff --git a/bundles/org.eclipse.releng.tools/forceQualifierUpdate.txt b/bundles/org.eclipse.releng.tools/forceQualifierUpdate.txt
new file mode 100644
index 0000000..0afa641
--- /dev/null
+++ b/bundles/org.eclipse.releng.tools/forceQualifierUpdate.txt
@@ -0,0 +1,7 @@
+# To force a version qualifier update add the bug here
+Bug 403352 - Update all parent versions to match our build stream
+Bug 416387 - don't sign inner jars in tools and test framework
+Bug 416582 - ignore warnings in releng tools similar to unit tests
+Bug 510976 - Several source bundles missing in SDK repository
+Bug 515093 - Source bundles missing for org.eclipse.releng.tools
+Bug 534597 - Unanticipated comparator errors in I20180511-2000
\ No newline at end of file
diff --git a/bundles/org.eclipse.releng.tools/plugin.properties b/bundles/org.eclipse.releng.tools/plugin.properties
new file mode 100644
index 0000000..13ece09
--- /dev/null
+++ b/bundles/org.eclipse.releng.tools/plugin.properties
@@ -0,0 +1,35 @@
+###############################################################################
+# Copyright (c) 2003, 2013 IBM Corporation and others.
+#
+# This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License 2.0
+# which accompanies this distribution, and is available at
+# https://www.eclipse.org/legal/epl-2.0/
+#
+# SPDX-License-Identifier: EPL-2.0
+#
+# Contributors:
+# IBM Corporation - initial API and implementation
+###############################################################################
+
+PluginName=RelEng Plug-in
+PluginProvider=Eclipse.org
+
+RelEng=RelEng Tools
+RelEngActionSet.description=RelEng Tool Action Set
+RelEngActionSet.Release=Releasing...
+RelEngActionSet.tooltip=Release Projects
+
+releaseAction.label = Re&lease...
+releasedAction.label = Released
+compareProjectsAction.tooltip = Compare the selected project(s) with the released versions
+replaceProjectsAction.tooltip = Replace the selcted project(s) with the released versions
+loadMapProjectsAction.label = Load Map Projects
+tagMapProjectsAction.label = Tag Map Projects
+fixCopyrightsAction.label = Fix Copyrights
+copyrightToolPrefPage.name = Copyright Tool
+relengMapProjectPrefPage.name = Releng Map Project Selection
+pomPrefPage.name = POM Version Tool
+pomVersionMarker.name = POM Version Problem
+pomVersionMarkerCategory.name = POM Version Problems
+action.label = Release...
\ No newline at end of file
diff --git a/bundles/org.eclipse.releng.tools/plugin.xml b/bundles/org.eclipse.releng.tools/plugin.xml
new file mode 100644
index 0000000..8c98405
--- /dev/null
+++ b/bundles/org.eclipse.releng.tools/plugin.xml
@@ -0,0 +1,96 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.0"?>
+
+<plugin>
+
+ <extension
+ point="org.eclipse.ui.popupMenus">
+ <objectContribution
+ adaptable="true"
+ objectClass="org.eclipse.ui.IWorkingSet"
+ id="org.eclipse.releng.tools.WorkingSetContributions">
+ <action
+ label="%fixCopyrightsAction.label"
+ class="org.eclipse.releng.tools.AdvancedFixCopyrightAction"
+ menubarPath="additions"
+ enablesFor="+"
+ id="org.eclipse.releng.tools.advancedFixCopyrights">
+ </action>
+ </objectContribution>
+ <objectContribution
+ adaptable="true"
+ objectClass="org.eclipse.core.resources.IResource"
+ id="org.eclipse.releng.internal.tools.AdvancedCopyrightContribution">
+ <action
+ label="%fixCopyrightsAction.label"
+ class="org.eclipse.releng.tools.AdvancedFixCopyrightAction"
+ menubarPath="additions"
+ enablesFor="+"
+ id="org.eclipse.releng.tools.advancedFixCopyrights">
+ </action>
+ </objectContribution>
+ </extension>
+
+ <!-- ********** Preference Pages ************** -->
+ <extension point="org.eclipse.ui.preferencePages">
+ <page
+ name="%copyrightToolPrefPage.name"
+ class="org.eclipse.releng.tools.preferences.CopyrightPreferencePage"
+ id="org.eclipse.releng.tools.preferences.CopyrightPreferencePage">
+ </page>
+ <page
+ class="org.eclipse.releng.tools.preferences.PomVersionPreferencePage"
+ id="org.eclipse.releng.tools.preferences.PomVersionPreferencePage"
+ name="%pomPrefPage.name">
+ </page>
+ </extension>
+
+
+ <!-- ********** Preference Initializing ************** -->
+ <extension point="org.eclipse.core.runtime.preferences">
+ <initializer class="org.eclipse.releng.tools.preferences.RelEngPreferenceInitializer"/>
+ </extension>
+ <extension
+ point="org.eclipse.core.runtime.adapters">
+ <factory
+ adaptableType="org.eclipse.egit.core.internal.GitRepositoryProviderType"
+ class="org.eclipse.releng.tools.git.GitCopyrightAdapterFactory">
+ <adapter
+ type="org.eclipse.releng.tools.IRepositoryProviderCopyrightAdapterFactory">
+ </adapter>
+ </factory>
+ </extension>
+<extension id="pomVersionProblem" point="org.eclipse.core.resources.markers" name="%pomVersionMarker.name">
+ <super type="org.eclipse.core.resources.problemmarker"/>
+ <super type="org.eclipse.core.resources.textmarker"/>
+ <persistent value="true"/>
+</extension>
+ <extension
+ point="org.eclipse.ui.ide.markerSupport">
+ <markerTypeCategory
+ name="%pomVersionMarkerCategory.name">
+ <markerTypeReference
+ id="org.eclipse.releng.tools.pomVersionProblem">
+ </markerTypeReference>
+ </markerTypeCategory>
+ </extension>
+ <extension
+ point="org.eclipse.ui.ide.markerResolution">
+ <markerResolutionGenerator
+ class="org.eclipse.releng.internal.tools.pomversion.PomVersionResolutionGenerator"
+ markerType="org.eclipse.releng.tools.pomVersionProblem">
+ </markerResolutionGenerator>
+ </extension>
+ <extension
+ point="org.eclipse.ui.console.consolePageParticipants">
+ <consolePageParticipant
+ class="org.eclipse.releng.tools.FixPageParticipant"
+ id="org.eclipse.releng.tools.fixPageParticipant">
+ <enablement>
+ <instanceof
+ value="org.eclipse.releng.tools.AdvancedFixCopyrightAction$FixConsole">
+ </instanceof></enablement>
+ </consolePageParticipant>
+ </extension>
+
+</plugin>
diff --git a/bundles/org.eclipse.releng.tools/pom.xml b/bundles/org.eclipse.releng.tools/pom.xml
new file mode 100644
index 0000000..07cd769
--- /dev/null
+++ b/bundles/org.eclipse.releng.tools/pom.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (c) 2012, 2016 Eclipse Foundation and others.
+ All rights reserved. This program and the accompanying materials
+ are made available under the terms of the Eclipse Distribution License v1.0
+ which accompanies this distribution, and is available at
+ http://www.eclipse.org/org/documents/edl-v10.php
+
+ Contributors:
+ Igor Fedorenko - initial implementation
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>org.eclipse.platform</groupId>
+ <artifactId>bundles</artifactId>
+ <version>1.0.101-SNAPSHOT</version>
+
+ </parent>
+ <groupId>org.eclipse.releng</groupId>
+ <artifactId>org.eclipse.releng.tools</artifactId>
+ <version>4.1.100-SNAPSHOT</version>
+ <packaging>eclipse-plugin</packaging>
+ <properties>
+ <defaultSigning-excludeInnerJars>true</defaultSigning-excludeInnerJars>
+ <code.ignoredWarnings>${tests.ignoredWarnings}</code.ignoredWarnings>
+ </properties>
+</project>
diff --git a/bundles/org.eclipse.releng.tools/src/org/eclipse/releng/internal/tools/pomversion/IPomVersionConstants.java b/bundles/org.eclipse.releng.tools/src/org/eclipse/releng/internal/tools/pomversion/IPomVersionConstants.java
new file mode 100644
index 0000000..6c8667f
--- /dev/null
+++ b/bundles/org.eclipse.releng.tools/src/org/eclipse/releng/internal/tools/pomversion/IPomVersionConstants.java
@@ -0,0 +1,62 @@
+/*******************************************************************************
+ * Copyright (c) 2013, 2014 IBM Corporation and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.releng.internal.tools.pomversion;
+
+import org.eclipse.releng.tools.RelEngPlugin;
+
+
+/**
+ * Contains all the constants used by the POM version tool.
+ */
+public interface IPomVersionConstants {
+
+ /**
+ * The marker type id for POM version problems specified in the markers extension.
+ * Value is: <code>org.eclipse.releng.tools.pomVersionProblem</code>
+ */
+ public final static String PROBLEM_MARKER_TYPE = RelEngPlugin.ID + ".pomVersionProblem"; //$NON-NLS-1$
+
+ /**
+ * String attribute stored in the problem marker for the correct version that should be in the POM file
+ */
+ public static final String POM_CORRECT_VERSION = "pom.CorrectVersion"; //$NON-NLS-1$
+
+ /**
+ * Preference setting that stores the severity level for pom version problem markers.
+ * Preference value must be a string and one of {@link #VALUE_ERROR}, {@link #VALUE_WARNING} or {@link #VALUE_IGNORE}.
+ */
+ public final static String POM_VERSION_ERROR_LEVEL = RelEngPlugin.ID + ".invalidPomVersionErrorLevel"; //$NON-NLS-1$
+
+ /**
+ * Preference setting that stores a version number that identifies the revision of the plug-in that last validated the whole workspace.
+ * Preference value must be an integer.
+ */
+ public final static String WORKSPACE_VALIDATED = RelEngPlugin.ID + ".workspaceValidated"; //$NON-NLS-1$
+
+ /**
+ * Constant representing the preference value 'ignore'.
+ * Value is: <code>Ignore</code>
+ */
+ public static final String VALUE_IGNORE = "Ignore"; //$NON-NLS-1$
+ /**
+ * Constant representing the preference value 'warning'.
+ * Value is: <code>Warning</code>
+ */
+ public static final String VALUE_WARNING = "Warning"; //$NON-NLS-1$
+ /**
+ * Constant representing the preference value 'error'.
+ * Value is: <code>Error</code>
+ */
+ public static final String VALUE_ERROR = "Error"; //$NON-NLS-1$
+}
diff --git a/bundles/org.eclipse.releng.tools/src/org/eclipse/releng/internal/tools/pomversion/Messages.java b/bundles/org.eclipse.releng.tools/src/org/eclipse/releng/internal/tools/pomversion/Messages.java
new file mode 100644
index 0000000..57c45c5
--- /dev/null
+++ b/bundles/org.eclipse.releng.tools/src/org/eclipse/releng/internal/tools/pomversion/Messages.java
@@ -0,0 +1,36 @@
+/*******************************************************************************
+ * Copyright (c) 2013 IBM Corporation and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.releng.internal.tools.pomversion;
+
+import org.eclipse.osgi.util.NLS;
+
+
+final class Messages extends NLS {
+
+ private static final String BUNDLE_NAME = "org.eclipse.releng.internal.tools.pomversion.messages"; //$NON-NLS-1$
+
+ public static String PomVersionErrorReporter_pom_version_error_marker_message;
+ public static String PomVersionErrorReporter_pom_version_error_marker_message_feature;
+ public static String PomVersionMarkerResolution_label;
+
+ static {
+ // initialize resource bundle
+ NLS.initializeMessages(BUNDLE_NAME, Messages.class);
+ }
+
+ private Messages() {
+ // Do not instantiate
+ }
+
+}
diff --git a/bundles/org.eclipse.releng.tools/src/org/eclipse/releng/internal/tools/pomversion/PomVersionErrorReporter.java b/bundles/org.eclipse.releng.tools/src/org/eclipse/releng/internal/tools/pomversion/PomVersionErrorReporter.java
new file mode 100644
index 0000000..d74d47d
--- /dev/null
+++ b/bundles/org.eclipse.releng.tools/src/org/eclipse/releng/internal/tools/pomversion/PomVersionErrorReporter.java
@@ -0,0 +1,521 @@
+/*******************************************************************************
+ * Copyright (c) 2013, 2016 IBM Corporation and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ * Lars Vogel <Lars.Vogel@vogella.com> - Bug 489985
+ *******************************************************************************/
+package org.eclipse.releng.internal.tools.pomversion;
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Stack;
+import java.util.jar.JarFile;
+
+import javax.xml.parsers.SAXParser;
+import javax.xml.parsers.SAXParserFactory;
+
+import org.eclipse.core.filebuffers.FileBuffers;
+import org.eclipse.core.filebuffers.ITextFileBuffer;
+import org.eclipse.core.filebuffers.ITextFileBufferManager;
+import org.eclipse.core.filebuffers.LocationKind;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IMarker;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IResourceChangeEvent;
+import org.eclipse.core.resources.IResourceChangeListener;
+import org.eclipse.core.resources.IResourceDelta;
+import org.eclipse.core.resources.IResourceDeltaVisitor;
+import org.eclipse.core.resources.IWorkspaceRoot;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.OperationCanceledException;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.core.runtime.preferences.IEclipsePreferences;
+import org.eclipse.core.runtime.preferences.IEclipsePreferences.PreferenceChangeEvent;
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.osgi.util.ManifestElement;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.releng.tools.RelEngPlugin;
+import org.eclipse.ui.texteditor.MarkerUtilities;
+import org.osgi.framework.BundleException;
+import org.osgi.framework.Constants;
+import org.osgi.framework.Version;
+import org.xml.sax.Attributes;
+import org.xml.sax.Locator;
+import org.xml.sax.SAXException;
+import org.xml.sax.helpers.DefaultHandler;
+
+
+/**
+ * Validates the content of the pom.xml. Currently the only check is that the
+ * version specified in pom.xml matches the bundle version.
+ *
+ */
+public class PomVersionErrorReporter implements IResourceChangeListener, IEclipsePreferences.IPreferenceChangeListener {
+
+ class PomResourceDeltaVisitor implements IResourceDeltaVisitor {
+
+ @Override
+ public boolean visit(IResourceDelta delta) {
+ if (delta != null) {
+ IResource resource = delta.getResource();
+ switch(resource.getType()) {
+ case IResource.PROJECT: {
+ if(delta.getKind() == IResourceDelta.REMOVED) {
+ return false;
+ }
+ IProject project = (IProject) resource;
+ try {
+ if(project.isAccessible() && (project.getDescription().hasNature("org.eclipse.pde.PluginNature") || project.getDescription().hasNature("org.eclipse.pde.FeatureNature"))) { //$NON-NLS-1$ //$NON-NLS-2$
+ if((delta.getFlags() & IResourceDelta.OPEN) > 0) {
+ validate(project);
+ return false;
+ }
+ return true;
+ }
+ }
+ catch(CoreException ce) {
+ RelEngPlugin.log(ce);
+ }
+ return false;
+ }
+ case IResource.ROOT:
+ case IResource.FOLDER: {
+ return true;
+ }
+ case IResource.FILE: {
+ switch(delta.getKind()) {
+ case IResourceDelta.REMOVED: {
+ //if manifest or feature removed, clean up markers
+ if(resource.getProjectRelativePath().equals(FEATURE_PATH) ||
+ resource.getProjectRelativePath().equals(MANIFEST_PATH)) {
+ IProject p = resource.getProject();
+ if(p.isAccessible()) {
+ cleanMarkers(p);
+ }
+ }
+ break;
+ }
+ case IResourceDelta.ADDED: {
+ //if the POM, manifest or feature.xml has been added scan them
+ if(resource.getProjectRelativePath().equals(FEATURE_PATH) ||
+ resource.getProjectRelativePath().equals(MANIFEST_PATH) ||
+ resource.getProjectRelativePath().equals(POM_PATH)) {
+ validate(resource.getProject());
+ }
+ break;
+ }
+ case IResourceDelta.CHANGED: {
+ //if the content has changed clean + scan
+ if((delta.getFlags() & IResourceDelta.CONTENT) > 0) {
+ if(resource.getProjectRelativePath().equals(FEATURE_PATH) ||
+ resource.getProjectRelativePath().equals(MANIFEST_PATH) ||
+ resource.getProjectRelativePath().equals(POM_PATH)) {
+ validate(resource.getProject());
+ }
+ }
+ break;
+ }
+ default: {
+ break;
+ }
+ }
+ return false;
+ }
+ }
+ }
+ return false;
+ }
+ }
+
+ /**
+ * XML parsing handler to check the POM version infos
+ */
+ class PomVersionHandler extends DefaultHandler {
+ private Version version;
+ private Stack<String> elements = new Stack<>();
+ private boolean checkVersion = false;
+ private boolean isFeatureProject = false;
+ private Locator locator;
+ IFile pom = null;
+ String severity = null;
+
+ public PomVersionHandler(IFile file, Version bundleVersion, String pref) {
+ this(file, bundleVersion, pref, false);
+ }
+
+ public PomVersionHandler(IFile file, Version version, String pref, boolean isFeatureProject) {
+ pom = file;
+ severity = pref;
+ this.version = version;
+ this.isFeatureProject = isFeatureProject;
+ }
+
+ @Override
+ public void setDocumentLocator(Locator locator) {
+ this.locator = locator;
+ }
+
+ @Override
+ public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
+ if (ELEMENT_VERSION.equals(qName)) {
+ if (!elements.isEmpty() && ELEMENT_PROJECT.equals(elements.peek())) {
+ checkVersion = true;
+ }
+ }
+ elements.push(qName);
+ }
+
+ @Override
+ public void endElement(String uri, String localName, String qName) throws SAXException {
+ elements.pop();
+ }
+
+ @Override
+ public void characters(char[] ch, int start, int length) throws SAXException {
+ if (checkVersion) {
+ checkVersion = false;
+
+ try {
+ // Remove the snapshot suffix
+ String versionString = new String(ch, start, length);
+ String origVer = versionString;
+ int index = versionString.indexOf(SNAPSHOT_SUFFIX);
+ if (index >= 0) {
+ versionString = versionString.substring(0, index);
+ }
+
+ // Create corrected version (no qualifiers, add back snapshot suffix)
+ Version bundleVersion2 = new Version(version.getMajor(), version.getMinor(), version.getMicro());
+ String correctedVersion = bundleVersion2.toString();
+ if (index >= 0) {
+ correctedVersion = correctedVersion.concat(SNAPSHOT_SUFFIX);
+ }
+
+ // Check if the pom version is a valid OSGi version
+ Version pomVersion = null;
+ try {
+ pomVersion = Version.parseVersion(versionString);
+ } catch (IllegalArgumentException e){
+ // Need to create a document to calculate the markers charstart and charend
+ IDocument doc = createDocument(pom);
+ int lineOffset = doc.getLineOffset(locator.getLineNumber() - 1); // locator lines start at 1
+ int linLength = doc.getLineLength(locator.getLineNumber() - 1);
+ String str = doc.get(lineOffset, linLength);
+ index = str.indexOf(origVer);
+ int charStart = lineOffset + index;
+ int charEnd = charStart + origVer.length();
+
+ String message = isFeatureProject ? Messages.PomVersionErrorReporter_pom_version_error_marker_message_feature : Messages.PomVersionErrorReporter_pom_version_error_marker_message;
+ reportMarker(NLS.bind(message, versionString, bundleVersion2.toString()),
+ locator.getLineNumber(),
+ charStart,
+ charEnd,
+ correctedVersion,
+ pom,
+ severity);
+ }
+
+ if (pomVersion == null){
+ return;
+ }
+
+ // Compare the versions
+ Version pomVersion2 = new Version(pomVersion.getMajor(), pomVersion.getMinor(), pomVersion.getMicro());
+ if (!bundleVersion2.equals(pomVersion2)) {
+ // Need to create a document to calculate the markers charstart and charend
+ IDocument doc = createDocument(pom);
+ int lineOffset = doc.getLineOffset(locator.getLineNumber() - 1); // locator lines start at 1
+ int linLength = doc.getLineLength(locator.getLineNumber() - 1);
+ String str = doc.get(lineOffset, linLength);
+ index = str.indexOf(origVer);
+ int charStart = lineOffset + index;
+ int charEnd = charStart + origVer.length();
+ String message = isFeatureProject ? Messages.PomVersionErrorReporter_pom_version_error_marker_message_feature : Messages.PomVersionErrorReporter_pom_version_error_marker_message;
+ reportMarker(NLS.bind(message, pomVersion2.toString(), bundleVersion2.toString()),
+ locator.getLineNumber(),
+ charStart,
+ charEnd,
+ correctedVersion,
+ pom,
+ severity);
+ }
+ } catch (IllegalArgumentException e) {
+ // If the manifest version is broken, let PDE report the problem
+ } catch (BadLocationException e) {
+ RelEngPlugin.log(e);
+ }
+ }
+ }
+ }
+
+ /**
+ * XML parsing handler to check the feature.xml version
+ */
+ class FeatureVersionHandler extends DefaultHandler {
+ private String featureVersion;
+
+ public FeatureVersionHandler() {
+ }
+
+ @Override
+ public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
+ // The version is on the root element, check for the attribute then throw exception to exit early
+ featureVersion = attributes.getValue("version"); //$NON-NLS-1$
+ throw new OperationCanceledException();
+ }
+
+ /**
+ * Returns the string version value found in the feature.xml or <code>null</code>
+ *
+ * @return string version from feature.xml or <code>null</code>
+ */
+ public String getVersion() {
+ return featureVersion;
+ }
+
+ }
+
+ /**
+ * Project relative path to the pom.xml file.
+ */
+ public static final IPath POM_PATH = new Path("pom.xml"); //$NON-NLS-1$
+
+ /**
+ * Project relative path to the manifest file.
+ */
+ public static final IPath MANIFEST_PATH = new Path(JarFile.MANIFEST_NAME);
+
+ /**
+ * Version of the PomVersionErrorReporter. Needs to be incremented when the version check algorithm changes
+ * in a way that requires re-validation of the whole workspace.
+ */
+ public static final int VERSION= 1;
+
+ /**
+ * Project relative path to the feature.xml file.
+ */
+ public static final IPath FEATURE_PATH = new Path("feature.xml"); //$NON-NLS-1$
+
+ private static final String ELEMENT_PROJECT = "project"; //$NON-NLS-1$
+ private static final String ELEMENT_VERSION = "version"; //$NON-NLS-1$
+ private static final String SNAPSHOT_SUFFIX = "-SNAPSHOT"; //$NON-NLS-1$
+
+
+ /**
+ * Clean up all markers
+ *
+ * @param project
+ */
+ void cleanMarkers(IResource resource) {
+ try {
+ resource.deleteMarkers(IPomVersionConstants.PROBLEM_MARKER_TYPE, false, IResource.DEPTH_INFINITE);
+ }
+ catch(CoreException e) {
+ RelEngPlugin.log(e);
+ }
+ }
+
+ /**
+ * Validates the manifest or feature version against the version in the <code>pom.xml</code> file
+ *
+ * @param project
+ * @param severity
+ */
+ public void validate(IProject project) {
+ if(project == null || !project.isAccessible()) {
+ return;
+ }
+ // Clean up existing markers
+ cleanMarkers(project);
+
+ String severity = RelEngPlugin.getPlugin().getPreferenceStore().getString(IPomVersionConstants.POM_VERSION_ERROR_LEVEL);
+ if (IPomVersionConstants.VALUE_IGNORE.equals(severity)) {
+ return;
+ }
+ IFile pom = project.getFile(POM_PATH);
+ if(!pom.exists()) {
+ return;
+ }
+
+ IFile manifest = project.getFile(MANIFEST_PATH);
+ if(manifest.exists()) {
+ // Get the manifest version
+ Version bundleVersion = Version.emptyVersion;
+ try {
+ Map<String, String> headers = new HashMap<>();
+ ManifestElement.parseBundleManifest(manifest.getContents(), headers);
+ String ver = headers.get(Constants.BUNDLE_VERSION);
+ if(ver == null) {
+ return;
+ }
+ bundleVersion = Version.parseVersion(ver);
+ } catch (IOException e) {
+ // Ignored, if there is a problem with the manifest, don't create a marker
+ return;
+ } catch (CoreException e){
+ // Ignored, if there is a problem with the manifest, don't create a marker
+ return;
+ } catch (BundleException e) {
+ // Ignored, if there is a problem with the manifest, don't create a marker
+ return;
+ } catch (IllegalArgumentException e){
+ // Ignored, if there is a problem with the manifest, don't create a marker
+ return;
+ }
+ // Compare it to the POM file version
+ try {
+ SAXParserFactory parserFactory = SAXParserFactory.newInstance();
+ SAXParser parser = parserFactory.newSAXParser();
+ PomVersionHandler handler = new PomVersionHandler(pom, bundleVersion, severity);
+ parser.parse(pom.getContents(), handler);
+ } catch (Exception e) {
+ // Ignored, if there is a problem with the POM file don't create a marker
+ return;
+ }
+
+ } else {
+ IFile feature = project.getFile(FEATURE_PATH);
+ if (feature.exists()){
+ try {
+ // Get the feature version
+ Version featureVersion = Version.emptyVersion;
+ SAXParserFactory parserFactory = SAXParserFactory.newInstance();
+ SAXParser parser = parserFactory.newSAXParser();
+ FeatureVersionHandler handler = new FeatureVersionHandler();
+ try {
+ parser.parse(feature.getContents(), handler);
+ } catch (OperationCanceledException e){
+ // Do nothing, used to avoid parsing the entire file
+ }
+
+ String version = handler.getVersion();
+ if (version == null){
+ // Ignored, if there is a problem with the feature, don't create a marker
+ return;
+ }
+ featureVersion = Version.parseVersion(version);
+
+ // Compare it to the POM file version
+ PomVersionHandler pomHandler = new PomVersionHandler(pom, featureVersion, severity, true);
+ parser.parse(pom.getContents(), pomHandler);
+ } catch (Exception e) {
+ // Ignored, if there is a problem with the POM file don't create a marker
+ return;
+ }
+ }
+ }
+ }
+
+ /**
+ * Creates a new POM version problem marker with the given attributes
+ * @param message the message for the marker
+ * @param lineNumber the line number of the problem
+ * @param charStart the starting character offset
+ * @param charEnd the ending character offset
+ * @param correctedVersion the correct version to be inserted
+ * @param pom the handle to the POM file
+ * @param severity the severity of the marker to create
+ */
+ void reportMarker(String message, int lineNumber, int charStart, int charEnd, String correctedVersion, IFile pom, String severity) {
+ try {
+ HashMap<String, Object> attributes = new HashMap<>();
+ attributes.put(IMarker.MESSAGE, message);
+ if (severity.equals(IPomVersionConstants.VALUE_WARNING)){
+ attributes.put(IMarker.SEVERITY, Integer.valueOf(IMarker.SEVERITY_WARNING));
+ } else {
+ attributes.put(IMarker.SEVERITY, Integer.valueOf(IMarker.SEVERITY_ERROR));
+ }
+ if (lineNumber == -1) {
+ lineNumber = 1;
+ }
+ attributes.put(IMarker.LINE_NUMBER, Integer.valueOf(lineNumber));
+ attributes.put(IMarker.CHAR_START, Integer.valueOf(charStart));
+ attributes.put(IMarker.CHAR_END, Integer.valueOf(charEnd));
+ attributes.put(IPomVersionConstants.POM_CORRECT_VERSION, correctedVersion);
+ MarkerUtilities.createMarker(pom, attributes, IPomVersionConstants.PROBLEM_MARKER_TYPE);
+ } catch (CoreException e){
+ RelEngPlugin.log(e);
+ }
+ }
+
+ /**
+ * Creates a new {@link IDocument} for the given {@link IFile}. <code>null</code>
+ * is returned if the {@link IFile} does not exist or the {@link ITextFileBufferManager}
+ * cannot be acquired or there was an exception trying to create the {@link IDocument}.
+ *
+ * @param file
+ * @return a new {@link IDocument} or <code>null</code>
+ */
+ protected IDocument createDocument(IFile file) {
+ if (!file.exists()) {
+ return null;
+ }
+ ITextFileBufferManager manager = FileBuffers.getTextFileBufferManager();
+ if (manager == null) {
+ return null;
+ }
+ try {
+ manager.connect(file.getFullPath(), LocationKind.NORMALIZE, null);
+ ITextFileBuffer textBuf = manager.getTextFileBuffer(file.getFullPath(), LocationKind.NORMALIZE);
+ IDocument document = textBuf.getDocument();
+ manager.disconnect(file.getFullPath(), LocationKind.NORMALIZE, null);
+ return document;
+ } catch (CoreException e) {
+ RelEngPlugin.log(e);
+ }
+ return null;
+ }
+
+ @Override
+ public void resourceChanged(IResourceChangeEvent event) {
+ IResourceDelta delta = event.getDelta();
+ if(delta != null) {
+ final PomResourceDeltaVisitor visitor = new PomResourceDeltaVisitor();
+ try {
+ delta.accept(visitor);
+ } catch (CoreException e) {
+ RelEngPlugin.log(e);
+ }
+ }
+ }
+
+ @Override
+ public void preferenceChange(PreferenceChangeEvent event) {
+ if(IPomVersionConstants.POM_VERSION_ERROR_LEVEL.equals(event.getKey())) {
+ final String newSeverity = (String) event.getNewValue();
+ final Object oldSeverity= event.getOldValue();
+ if(newSeverity != null) {
+ if(IPomVersionConstants.VALUE_IGNORE.equals(newSeverity)) {
+ //we turned it off
+ ResourcesPlugin.getWorkspace().removeResourceChangeListener(this);
+ } else if(oldSeverity == null || IPomVersionConstants.VALUE_IGNORE.equals(oldSeverity)) {
+ // we turned it on
+ ResourcesPlugin.getWorkspace().addResourceChangeListener(this, IResourceChangeEvent.POST_BUILD);
+ }
+ validateWorkspace();
+ }
+ }
+ }
+
+ public void validateWorkspace() {
+ IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
+ IProject[] projects = root.getProjects();
+ for (int i = 0; i < projects.length; i++) {
+ validate(projects[i]);
+ }
+ RelEngPlugin.getPlugin().getPreferenceStore().setValue(IPomVersionConstants.WORKSPACE_VALIDATED, VERSION);
+ }
+}
diff --git a/bundles/org.eclipse.releng.tools/src/org/eclipse/releng/internal/tools/pomversion/PomVersionMarkerResolution.java b/bundles/org.eclipse.releng.tools/src/org/eclipse/releng/internal/tools/pomversion/PomVersionMarkerResolution.java
new file mode 100644
index 0000000..130330c
--- /dev/null
+++ b/bundles/org.eclipse.releng.tools/src/org/eclipse/releng/internal/tools/pomversion/PomVersionMarkerResolution.java
@@ -0,0 +1,143 @@
+/*******************************************************************************
+ * Copyright (c) 2013, 2017 IBM Corporation and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.releng.internal.tools.pomversion;
+
+import java.util.HashSet;
+
+import org.eclipse.core.filebuffers.FileBuffers;
+import org.eclipse.core.filebuffers.ITextFileBuffer;
+import org.eclipse.core.filebuffers.ITextFileBufferManager;
+import org.eclipse.core.filebuffers.LocationKind;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IMarker;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.releng.tools.RelEngPlugin;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.ui.views.markers.WorkbenchMarkerResolution;
+
+
+/**
+ * Marker resolution for when version in pom.xml does not match the plug-in version.
+ * Replaces the version string to one based on the version in the manifest. The corrected
+ * version must have been stored on the marker at creation time.
+ */
+public class PomVersionMarkerResolution extends WorkbenchMarkerResolution {
+
+ private IMarker marker;
+ private String correctedVersion;
+
+ /**
+ * New marker resolution that will offer to replace the current POM version with corrected version
+ * @param correctedVersion new version to insert
+ * @deprecated Use PomVersionMarkerResolution(IMarker marker,String correctedVersion) instead
+ */
+ @Deprecated
+ public PomVersionMarkerResolution(String correctedVersion) {
+ this.correctedVersion = correctedVersion;
+ }
+
+ public PomVersionMarkerResolution(IMarker marker,String correctedVersion) {
+ this.marker = marker;
+ this.correctedVersion = correctedVersion;
+ }
+
+ @Override
+ public String getLabel() {
+ return NLS.bind(Messages.PomVersionMarkerResolution_label, correctedVersion);
+ }
+
+ @Override
+ public void run(IMarker marker) {
+ try {
+ correctedVersion = (String) marker.getAttribute(IPomVersionConstants.POM_CORRECT_VERSION);
+ } catch (CoreException e1) {
+ RelEngPlugin.log(e1);
+ }
+ if (correctedVersion == null || correctedVersion.trim().length() == 0) {
+ return;
+ }
+ int charstart = marker.getAttribute(IMarker.CHAR_START, -1);
+ int charend = marker.getAttribute(IMarker.CHAR_END, -1);
+ if(charstart < 0 || charend < 0) {
+ return;
+ }
+ IResource resource = marker.getResource();
+ if (resource.exists() && resource.getType() == IResource.FILE) {
+ IFile file = (IFile) resource;
+ if (!file.isReadOnly()) {
+ NullProgressMonitor monitor = new NullProgressMonitor();
+ ITextFileBufferManager fbm = FileBuffers.getTextFileBufferManager();
+ IPath location = file.getFullPath();
+ ITextFileBuffer buff = null;
+ try {
+ fbm.connect(location, LocationKind.IFILE, monitor);
+ buff = fbm.getTextFileBuffer(location, LocationKind.IFILE);
+ if(buff != null) {
+ IDocument doc = buff.getDocument();
+ try {
+ if(charstart > -1 && charend > -1) {
+ doc.replace(charstart, charend-charstart, correctedVersion);
+ buff.commit(monitor, true);
+ }
+ } catch(BadLocationException ble) {
+ RelEngPlugin.log(ble);
+ }
+ }
+ } catch (CoreException e) {
+ RelEngPlugin.log(e);
+ } finally {
+ try {
+ if (buff != null)
+ fbm.disconnect(location, LocationKind.IFILE, monitor);
+ } catch (CoreException e) {
+ RelEngPlugin.log(e);
+ }
+ }
+ }
+ }
+ }
+
+ @Override
+ public String getDescription() {
+ return null;
+ }
+
+ @Override
+ public Image getImage() {
+ return null ;
+ }
+
+ @Override
+ public IMarker[] findOtherMarkers(IMarker[] markers) {
+ HashSet<IMarker> mset = new HashSet<>(markers.length);
+ for (IMarker iMarker : markers) {
+ if (iMarker.equals(marker))
+ continue;
+ try {
+ if (iMarker.getType().equals(IPomVersionConstants.PROBLEM_MARKER_TYPE))
+ mset.add(iMarker);
+ } catch (CoreException e) {
+
+ }
+ }
+ int size = mset.size();
+ return mset.toArray(new IMarker[size]);
+ }
+}
diff --git a/bundles/org.eclipse.releng.tools/src/org/eclipse/releng/internal/tools/pomversion/PomVersionResolutionGenerator.java b/bundles/org.eclipse.releng.tools/src/org/eclipse/releng/internal/tools/pomversion/PomVersionResolutionGenerator.java
new file mode 100644
index 0000000..279e309
--- /dev/null
+++ b/bundles/org.eclipse.releng.tools/src/org/eclipse/releng/internal/tools/pomversion/PomVersionResolutionGenerator.java
@@ -0,0 +1,45 @@
+/*******************************************************************************
+ * Copyright (c) 2013, 2017 IBM Corporation and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.releng.internal.tools.pomversion;
+
+import org.eclipse.core.resources.IMarker;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.releng.tools.RelEngPlugin;
+import org.eclipse.ui.IMarkerResolution;
+import org.eclipse.ui.IMarkerResolutionGenerator;
+
+
+public class PomVersionResolutionGenerator implements IMarkerResolutionGenerator {
+
+ private static IMarkerResolution[] NO_RESOLUTIONS = new IMarkerResolution[0];
+
+ @Override
+ public IMarkerResolution[] getResolutions(IMarker marker) {
+ int charstart = marker.getAttribute(IMarker.CHAR_START, -1);
+ int charend = marker.getAttribute(IMarker.CHAR_END, -1);
+ if(charstart > -1 && charend > -1) {
+ try {
+ if (marker.getType().equals(IPomVersionConstants.PROBLEM_MARKER_TYPE)){
+ String correctedVersion = (String) marker.getAttribute(IPomVersionConstants.POM_CORRECT_VERSION);
+ if (correctedVersion != null && correctedVersion.length() > 0){
+ return new IMarkerResolution[] {new PomVersionMarkerResolution(marker,correctedVersion)};
+ }
+ }
+ } catch (CoreException e){
+ RelEngPlugin.log(e);
+ }
+ }
+ return NO_RESOLUTIONS;
+ }
+}
diff --git a/bundles/org.eclipse.releng.tools/src/org/eclipse/releng/internal/tools/pomversion/messages.properties b/bundles/org.eclipse.releng.tools/src/org/eclipse/releng/internal/tools/pomversion/messages.properties
new file mode 100644
index 0000000..edc1bac
--- /dev/null
+++ b/bundles/org.eclipse.releng.tools/src/org/eclipse/releng/internal/tools/pomversion/messages.properties
@@ -0,0 +1,17 @@
+###############################################################################
+# Copyright (c) 2013 IBM Corporation and others.
+#
+# This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License 2.0
+# which accompanies this distribution, and is available at
+# https://www.eclipse.org/legal/epl-2.0/
+#
+# SPDX-License-Identifier: EPL-2.0
+#
+# Contributors:
+# IBM Corporation - initial API and implementation
+###############################################################################
+
+PomVersionErrorReporter_pom_version_error_marker_message=POM artifact version {0} does not match bundle version {1}
+PomVersionErrorReporter_pom_version_error_marker_message_feature=POM artifact version {0} does not match feature version {1}
+PomVersionMarkerResolution_label=Replace version in pom.xml with {0}
diff --git a/bundles/org.eclipse.releng.tools/src/org/eclipse/releng/tools/AdvancedCopyrightComment.java b/bundles/org.eclipse.releng.tools/src/org/eclipse/releng/tools/AdvancedCopyrightComment.java
new file mode 100644
index 0000000..9ad7bbb
--- /dev/null
+++ b/bundles/org.eclipse.releng.tools/src/org/eclipse/releng/tools/AdvancedCopyrightComment.java
@@ -0,0 +1,408 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2016 IBM Corporation and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ * Martin Oberhuber (Wind River) - [276255] fix insertion of extra space chars
+ * Leo Ufimtsev lufimtse@redhat.com - [369991] Major re-write to handle multiple years. + added test cases.
+ *******************************************************************************/
+package org.eclipse.releng.tools;
+
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.util.ArrayList;
+import java.util.StringTokenizer;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.text.TextUtilities;
+import org.eclipse.releng.tools.preferences.RelEngCopyrightConstants;
+
+/**
+ * <h2>Handle incomming 'raw' comments and convert them <br>
+ * into a comment format with access to creation/revision year. <br>
+ * When retrieving the comment, update the revision year or append one if it's not there.</h2>
+ *
+ * <p>
+ * Tested in {@link org.eclipse.releng.tests.AdvancedCopyrightCommentTestsJunit4}<br>
+ * Please verify that tests run after modifications.
+ * </p>
+ *
+ */
+public class AdvancedCopyrightComment extends CopyrightComment {
+
+ /** A regex mattern to match years in the range {@code 19** to 23** } */
+ private static final String YEAR_REGEX = "(19|20|21|22|23)\\d{2}"; //$NON-NLS-1$
+
+ private static final String DATE_VAR = "${date}"; //$NON-NLS-1$
+ private static final String NEW_LINE = "\n"; //$NON-NLS-1$
+
+ /** Everything before the line with the year(s) on it. */
+ private String preYearLinesString = null;
+
+ /** The line with the year(s) on it. */
+ private String yearLineString = null; // this is updated when we return a comment.
+
+ /** Everything after the line with the year(s) on it. */
+ private String postYearLineString = null;
+
+ /** Number of year units matching {@link #YEAR_REGEX YEAR_REGEX} in the comment. e.g '2000, 2011-2014' has 3 */
+ private int yearsCount;
+
+ /**
+ * Return the body of this copyright comment or null if it cannot be built.
+ */
+ @Override
+ public String getCopyrightComment() {
+
+ if ((preYearLinesString != null || postYearLineString != null)) {
+ StringBuilder copyrightComment = new StringBuilder();
+
+ // Pre-append everything before the years
+ if (preYearLinesString != null) {
+ copyrightComment.append(preYearLinesString);
+ }
+
+ // Check if the comment has a revised year. Fix the years on the line if so.
+ if (hasRevisionYear() && (getRevisionYear() != getCreationYear())) {
+
+ String fixedYearLine;
+ if (yearsCount == 1) {
+ // Insert a 2nd year '2000' -> '2000-2010'.
+ fixedYearLine = insertRevisedYear(yearLineString, getRevisionYear());
+ } else {
+ // update the last found year on line: '2000 ... 2005' -> '2000 ... 2015'
+ fixedYearLine = updateLastYear(yearLineString, getRevisionYear());
+ if (fixedYearLine == null) {
+ return null; //failed to update last year.
+ }
+ }
+
+ copyrightComment.append(fixedYearLine);
+ } else {
+ // Otherwise put back the original year line.
+ copyrightComment.append(yearLineString);
+ }
+
+ // Post append everything after the year line
+ copyrightComment.append(postYearLineString);
+
+ return copyrightComment.toString();
+ }
+
+ String linePrefix = getCommentPrefix();
+ if (linePrefix == null)
+ return null;
+
+ StringWriter out = new StringWriter();
+
+ try (PrintWriter writer = new PrintWriter(out)) {
+ writeCommentStart(writer);
+ writeLegal(writer, linePrefix);
+ writeCommentEnd(writer);
+ return out.toString();
+ }
+ }
+
+ /**
+ * <h1>Parse a raw comment.</h1>
+ * <p>
+ * Create an instance the same as the argument comment but with the revision year <br>
+ * updated if needed. Return the default comment if the argument comment is null <br>
+ * or an empty string.
+ * </p>
+ *
+ * @param comment
+ * the original comment from the file.
+ * @param commentStyle
+ * the comment style. {@link CopyrightComment}
+ * @return {@link AdvancedCopyrightComment} an copyright comment with the year updated.
+ *
+ */
+ public static AdvancedCopyrightComment parse(BlockComment commentBock, int commentStyle) {
+ // If the given comment is empty, return the default comment.
+ if (commentBock == null) {
+ return defaultComment(commentStyle);
+ }
+
+ String comment = commentBock.getContents();
+
+ // identify which line delimiter is used. (for writing back to file )
+ String fileLineDelimiter = TextUtilities.determineLineDelimiter(comment, "\n"); //$NON-NLS-1$
+
+ // Split Comment into Seperate lines for easier proccessing:
+ String commentLines[] = comment.split("\\r?\\n"); //$NON-NLS-1$
+
+ // lines before the line with the year comment on it.
+ StringBuilder preYearLines = new StringBuilder();
+
+ // line with the year(s) on it. 'copyright 2002, 2010-2011 ... etc..
+ String yearLine = null;
+
+ // Lines after the line with the year comment on it.
+ StringBuilder postYearLines = new StringBuilder();
+
+ // Break down the comment into the three sections.
+ boolean yearFound = false;
+ String line;
+ for (int i = 0; i < commentLines.length; i++) {
+
+ line = commentLines[i]; // for clarity.
+
+ if (yearFound) {
+ // We have already found the year line and are just appending the last lines.
+
+ // Conditionally append a newline delimiter.
+ if (i != (commentLines.length - 1)) {
+ // normally, append a new line.
+ postYearLines.append(line + fileLineDelimiter);
+ } else {
+ // for the last line, only append if the original comment had a newline delimiter.
+ Character lastchar = comment.charAt(comment.length() - 1);
+ if (Character.isWhitespace(lastchar)) {
+ postYearLines.append(line + lastchar);
+ } else {
+ postYearLines.append(line);
+ }
+ }
+
+ } else if (line.matches(".*" + YEAR_REGEX + ".*")) { //$NON-NLS-1$ //$NON-NLS-2$
+ // We found the line with the copy-right years on it.
+ yearFound = true;
+ yearLine = line + fileLineDelimiter;
+ } else {
+ // We are parsting the top part of the comment and have not reached the year-line yet.
+ preYearLines.append(line + fileLineDelimiter);
+ }
+ }
+
+ // The comment didn't contain any years that we can update.
+ if (!yearFound) {
+ return null;
+ }
+
+ // Determine first year.
+ int createdYear = getFirstYear(yearLine);
+ if (createdYear == 0) {
+ return null; //Failed to read a year.
+ }
+
+
+ int yearsOnLine = countYearsOnLine(yearLine);
+ // Determine the last year
+ int revisedYear;
+ if (yearsOnLine == 1) {
+ revisedYear = -1;
+ } else {
+ revisedYear = getLastYear(yearLine);
+ }
+
+ return new AdvancedCopyrightComment(commentStyle, createdYear, revisedYear, yearsOnLine,
+ preYearLines.toString(), yearLine, postYearLines.toString());
+ }
+
+ /**
+ * <p> Construct a new default comment for the file.</p>
+ *
+ * @param commentStyle As defined in: CopyrightComment
+ * @return a newly created comment.
+ */
+ public static AdvancedCopyrightComment defaultComment(int commentStyle) {
+ return new AdvancedCopyrightComment(commentStyle, -1, -1, 1, null, null, null);
+ }
+
+
+ private AdvancedCopyrightComment(int commentStyle, int creationYear, int revisionYear,
+ int yearsCount, String preYearComment, String middleYearsComment, String postYearComment) {
+ super(commentStyle, creationYear == -1 ? getPreferenceStore().getInt(
+ RelEngCopyrightConstants.CREATION_YEAR_KEY) : creationYear, revisionYear);
+ this.preYearLinesString = preYearComment;
+ this.yearLineString = middleYearsComment;
+ this.postYearLineString = postYearComment;
+ this.yearsCount = yearsCount;
+ }
+
+ /**
+ * Get the copyright tool preference store.
+ *
+ * @return preference store used the releng plugin.
+ */
+ private static IPreferenceStore getPreferenceStore() {
+ return RelEngPlugin.getDefault().getPreferenceStore();
+ }
+
+ /**
+ * Get the copyright statement in form of an array of Strings where
+ * each item is a line of the copyright statement.
+ *
+ * @return String[] array of lines making up the comment. Containing $date template.
+ */
+ private static String[] getLegalLines() {
+ StringTokenizer st = new StringTokenizer(getPreferenceStore().getString(
+ RelEngCopyrightConstants.COPYRIGHT_TEMPLATE_KEY), NEW_LINE, true);
+ ArrayList<String> lines = new ArrayList<>();
+ String previous = NEW_LINE;
+ while (st.hasMoreTokens()) {
+ String current = st.nextToken();
+ // add empty lines to array as well
+ if (NEW_LINE.equals(previous)) {
+ lines.add(current);
+ }
+ previous = current;
+ }
+ String[] stringLines = new String[lines.size()];
+ stringLines = lines.toArray(stringLines);
+ return stringLines;
+ }
+
+ /**
+ * Write out the copyright statement, line by line, adding in the created/revision
+ * year as well as comment line prefixes.
+ *
+ * @param writer
+ * @param linePrefix
+ */
+ private void writeLegal(PrintWriter writer, String linePrefix) {
+ String[] legalLines = getLegalLines();
+ for (String currentLine : legalLines) {
+ int offset = currentLine.indexOf(DATE_VAR);
+ // if this is the line, containing the ${date}, add in the year
+ if (offset > -1) {
+ writer.print(linePrefix + ' ' + currentLine.substring(0, offset)
+ + getCreationYear());
+ if (hasRevisionYear() && getRevisionYear() != getCreationYear()) {
+ writer.print(", " + getRevisionYear()); //$NON-NLS-1$
+ }
+ println(writer,
+ currentLine.substring(offset + DATE_VAR.length(), currentLine.length()));
+ } else {
+ // just write out the line
+ if (NEW_LINE.equals(currentLine)) {
+ // handle empty lines
+ println(writer, linePrefix);
+ } else {
+ println(writer, linePrefix + ' ' + currentLine);
+ }
+ }
+ }
+ }
+
+ /**
+ * Replace the last year in the provided string that matches {@link #YEAR_REGEX}.
+ *
+ * @param line
+ * the line that contains the year that you want to update.
+ * @param newYear
+ * the new year that you want to update to.
+ * @return the string with the last year updated or null if it fails to find a year.
+ */
+ private static String updateLastYear(String line, int newYear) {
+
+ Matcher matcher = Pattern.compile(YEAR_REGEX).matcher(line);
+
+ // Find position of last year in the string.
+ int lastStart = -1;
+ while (matcher.find()) {
+ lastStart = matcher.start();
+ }
+
+ // Failed to find a year. Return the original line.
+ if (lastStart == -1) {
+ return null;
+ }
+
+ // Insert new year
+ String before = line.substring(0, lastStart);
+ String after = line.substring(lastStart + 4);
+ String updatedLine = before + Integer.toString(newYear) + after;
+
+ return updatedLine;
+ }
+
+ /**
+ * In the situation that a line only has a single year 'Copyright 2000 IBM ... '. <br>
+ * append the revision year to make it like: 'Copyright 2000-2010 IBM ... '. <br>
+ *
+ * <p>
+ * This should <b>only</b> be used for lines that have a single year.
+ * </p>
+ *
+ * @param line
+ * @param year
+ * @return
+ */
+ private static String insertRevisedYear(String line, int year) {
+ Matcher matcher = Pattern.compile(YEAR_REGEX).matcher(line);
+
+ if (!matcher.find())
+ return line; // no year found. Return original.
+
+ // Insert new year.
+ String before = line.substring(0, matcher.end());
+ String after = line.substring(matcher.end());
+ String updatedLine = before + ", " + Integer.toString(year) + after; //$NON-NLS-1$
+
+ return updatedLine;
+ }
+
+ /**
+ * Given a line with one or multiple years on it, count how many years occur on it.
+ *
+ * @param line
+ * @return
+ */
+ private static int countYearsOnLine(String line) {
+ Matcher yearMatcher = Pattern.compile(YEAR_REGEX).matcher(line);
+ int count = 0;
+ while (yearMatcher.find()) {
+ count++;
+ }
+ return count;
+ }
+
+ /**
+ * <h1>Get first year in line. </h1>
+ * <p> For example given a line like '2000, 2012, 2011, IMB..' it would return 2000. <br>
+ *
+ * Pre-condition: The line must contain a valid year in the range YEAR_REGEX
+ *
+ * @see #YEAR_REGEX
+ * @param line Line containing a year.
+ * @return the first found year. 0 if none found. (caller should check).
+ */
+ private static int getFirstYear(String line) {
+ Matcher yearMatcher = Pattern.compile(YEAR_REGEX).matcher(line);
+ if (yearMatcher.find()) {
+ return Integer.parseInt(yearMatcher.group()); // exception never thrown since match only matches integer.
+ }
+ return 0; //No year was found on this line.
+ }
+
+ /**
+ * <h2>Get the last year in a line. '2000, 2012, 2011, IMB..'</h2> Pre-condition: The line must contain a valid year
+ * in the range YEAR_REGEX
+ *
+ * @see #YEAR_REGEX
+ * @param line
+ * @return e.g 2011
+ */
+ private static int getLastYear(String line) {
+ Matcher yearMatcher = Pattern.compile(YEAR_REGEX).matcher(line);
+
+ int lastYear = -1;
+ // loop till the last occurance.
+ while (yearMatcher.find()) {
+ lastYear = Integer.parseInt(yearMatcher.group()); // exception never thrown since match only matches
+ // integer.
+ }
+ return lastYear;
+ }
+}
diff --git a/bundles/org.eclipse.releng.tools/src/org/eclipse/releng/tools/AdvancedFixCopyrightAction.java b/bundles/org.eclipse.releng.tools/src/org/eclipse/releng/tools/AdvancedFixCopyrightAction.java
new file mode 100644
index 0000000..5e6fdf8
--- /dev/null
+++ b/bundles/org.eclipse.releng.tools/src/org/eclipse/releng/tools/AdvancedFixCopyrightAction.java
@@ -0,0 +1,578 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2020 IBM Corporation and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ * IBH SYSTEMS GmbH - allow removing the consoles
+ *******************************************************************************/
+package org.eclipse.releng.tools;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.GregorianCalendar;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IResourceVisitor;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.resources.WorkspaceJob;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IAdaptable;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.MultiStatus;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.core.runtime.SubMonitor;
+import org.eclipse.jface.action.IAction;
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.releng.tools.preferences.RelEngCopyrightConstants;
+import org.eclipse.team.core.RepositoryProvider;
+import org.eclipse.team.core.RepositoryProviderType;
+import org.eclipse.ui.IActionDelegate;
+import org.eclipse.ui.IObjectActionDelegate;
+import org.eclipse.ui.IWorkbenchPart;
+import org.eclipse.ui.IWorkingSet;
+import org.eclipse.ui.PartInitException;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.console.ConsolePlugin;
+import org.eclipse.ui.console.IConsole;
+import org.eclipse.ui.console.IConsoleConstants;
+import org.eclipse.ui.console.MessageConsole;
+import org.eclipse.ui.console.MessageConsoleStream;
+
+public class AdvancedFixCopyrightAction implements IObjectActionDelegate {
+
+ final class FixConsole extends MessageConsole {
+ private FixConsole() {
+ super(Messages.getString("AdvancedFixCopyrightAction.0"), null); //$NON-NLS-1$
+ }
+ }
+
+
+ public class FixCopyrightVisitor implements IResourceVisitor {
+ private final IProgressMonitor monitor;
+ private final RepositoryProviderCopyrightAdapter adapter;
+
+ public FixCopyrightVisitor(RepositoryProviderCopyrightAdapter adapter, IProgressMonitor monitor) {
+ this.adapter = adapter;
+ this.monitor = monitor;
+ }
+
+ @Override
+ public boolean visit(IResource resource) throws CoreException {
+ if (!monitor.isCanceled()) {
+ if (resource.getType() == IResource.FILE) {
+ monitor.subTask(((IFile) resource).getFullPath().toOSString());
+ processFile((IFile) resource, adapter, monitor);
+ monitor.worked(1);
+ }
+ }
+ return true;
+ }
+ }
+
+ /**
+ * Visit each file to count total number of files that we will traverse.
+ * This is used to show the progress correctly.
+ */
+ private class FileCountVisitor implements IResourceVisitor {
+ private int fileCount;
+
+ public FileCountVisitor() {
+ this.fileCount = 0;
+ }
+
+ @Override
+ public boolean visit(IResource resource) throws CoreException {
+ if (resource.getType() == IResource.FILE) {
+ fileCount += 1;
+ }
+ return true;
+ }
+
+ public int getfileCount() {
+ return this.fileCount;
+ }
+ }
+
+ private String newLine = System.lineSeparator();
+ private Map<String, List<String>> log = new HashMap<>();
+ private MessageConsole console;
+
+ // The current selection
+ protected IStructuredSelection selection;
+
+ private static final int currentYear = new GregorianCalendar().get(Calendar.YEAR);
+
+ /**
+ * Returns the selected resources.
+ *
+ * @return the selected resources
+ */
+ protected IResource[] getSelectedResources() {
+ ArrayList<IResource> resources = new ArrayList<>();
+ if (!selection.isEmpty()) {
+
+ Iterator<?> elements = selection.iterator();
+ while (elements.hasNext()) {
+ addResource(elements.next(), resources);
+ }
+ }
+ IResource[] result = new IResource[resources.size()];
+ resources.toArray(result);
+ return result;
+ }
+
+ private void addResource(Object element, ArrayList<IResource> resources) {
+ if (element instanceof IResource) {
+ resources.add((IResource) element);
+ } else if (element instanceof IWorkingSet) {
+ IWorkingSet ws = (IWorkingSet) element;
+ IAdaptable[] elements = ws.getElements();
+ for (int i = 0; i < elements.length; i++)
+ addResource(elements[i], resources);
+ } else if (element instanceof IAdaptable) {
+ IAdaptable a = (IAdaptable) element;
+ addResource(a.getAdapter(IResource.class), resources);
+ }
+ }
+
+ /**
+ * @see IObjectActionDelegate#setActivePart(IAction, IWorkbenchPart)
+ */
+ @Override
+ public void setActivePart(IAction action, IWorkbenchPart targetPart) {
+ }
+
+ /**
+ * @see IActionDelegate#run(IAction)
+ */
+ @Override
+ public void run(IAction action) {
+ log = new HashMap<>();
+ console = new FixConsole();
+ ConsolePlugin.getDefault().getConsoleManager().addConsoles(new IConsole[] { console });
+ try {
+ PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage()
+ .showView(IConsoleConstants.ID_CONSOLE_VIEW);
+ } catch (PartInitException e) {
+ // Don't fail if we can't show the console
+ RelEngPlugin.log(e);
+ }
+ final MessageConsoleStream stream = console.newMessageStream();
+
+ WorkspaceJob wJob = new WorkspaceJob(Messages.getString("AdvancedFixCopyrightAction.1")) { //$NON-NLS-1$
+ @Override
+ public IStatus runInWorkspace(IProgressMonitor monitor) throws CoreException {
+ try {
+ long start = System.currentTimeMillis();
+ stream.println(Messages.getString("AdvancedFixCopyrightAction.2")); //$NON-NLS-1$
+ IResource[] results = getSelectedResources();
+ stream.println(NLS.bind(Messages.getString("AdvancedFixCopyrightAction.3"), //$NON-NLS-1$
+ Integer.toString(results.length)));
+
+ int totalFileCount = countFiles(results);
+ SubMonitor subMonitor = SubMonitor.convert(monitor, totalFileCount);
+ subMonitor.beginTask(Messages.getString("AdvancedFixCopyrightAction.4"), totalFileCount); //$NON-NLS-1$
+
+ RepositoryProviderCopyrightAdapter adapter = createCopyrightAdapter(results);
+ if (adapter == null) {
+ if (!RelEngPlugin.getDefault().getPreferenceStore()
+ .getBoolean(RelEngCopyrightConstants.USE_DEFAULT_REVISION_YEAR_KEY)) {
+ throw new CoreException(new Status(IStatus.ERROR, RelEngPlugin.ID, 0,
+ Messages.getString("AdvancedFixCopyrightAction.5"), null)); //$NON-NLS-1$
+ }
+ } else {
+ adapter.initialize(subMonitor);
+ }
+ List<CoreException> exceptions = new ArrayList<>();
+ for (IResource resource : results) {
+ stream.println(
+ NLS.bind(Messages.getString("AdvancedFixCopyrightAction.6"), resource.getName())); //$NON-NLS-1$
+ try {
+ resource.accept(new FixCopyrightVisitor(adapter, subMonitor));
+ } catch (CoreException e1) {
+ exceptions.add(e1);
+ }
+ }
+
+ writeLogs();
+ displayLogs(stream);
+ stream.println(Messages.getString("AdvancedFixCopyrightAction.7")); //$NON-NLS-1$
+ long end = System.currentTimeMillis();
+ stream.println(
+ NLS.bind(Messages.getString("AdvancedFixCopyrightAction.8"), Long.toString(end - start))); //$NON-NLS-1$
+ if (!exceptions.isEmpty()) {
+ stream.println(Messages.getString("AdvancedFixCopyrightAction.9")); //$NON-NLS-1$
+ if (exceptions.size() == 1) {
+ throw exceptions.get(0);
+ } else {
+ List<Status> status = new ArrayList<>();
+ for (CoreException ce : exceptions) {
+ status.add(new Status(ce.getStatus().getSeverity(), ce.getStatus().getPlugin(),
+ ce.getStatus().getCode(), ce.getStatus().getMessage(), ce));
+ }
+ throw new CoreException(
+ new MultiStatus(RelEngPlugin.ID, 0, status.toArray(new IStatus[status.size()]),
+ Messages.getString("AdvancedFixCopyrightAction.10"), //$NON-NLS-1$
+ null));
+ }
+ }
+ } finally {
+ monitor.done();
+ }
+ return Status.OK_STATUS;
+ }
+
+ private int countFiles(IResource[] results) {
+ int sum = 0;
+ for (IResource file : results) {
+ FileCountVisitor fileCountVisitor = new FileCountVisitor();
+ try {
+ file.accept(fileCountVisitor);
+ } catch (CoreException e) {
+ // This exception can be ignored.
+ // Here we are only counting files.
+ // It will be handled when files are actually
+ // proccessed.
+ }
+ sum += fileCountVisitor.getfileCount();
+ }
+ return sum;
+ }
+ };
+
+ wJob.setRule(ResourcesPlugin.getWorkspace().getRoot());
+ wJob.setUser(true);
+ wJob.schedule();
+ }
+
+ protected RepositoryProviderCopyrightAdapter createCopyrightAdapter(IResource[] results) throws CoreException {
+ RepositoryProviderType providerType = null;
+ for (IResource resource : results) {
+ RepositoryProvider p = RepositoryProvider.getProvider(resource.getProject());
+ if (p != null) {
+ if (providerType == null) {
+ providerType = RepositoryProviderType.getProviderType(p.getID());
+ } else if (!providerType.getID().equals(p.getID())) {
+ throw new CoreException(new Status(IStatus.ERROR, RelEngPlugin.ID, 0,
+ Messages.getString("AdvancedFixCopyrightAction.11"), null)); //$NON-NLS-1$
+ }
+ }
+ }
+ if (providerType == null) {
+ return null;
+ }
+ IRepositoryProviderCopyrightAdapterFactory factory = providerType
+ .getAdapter(IRepositoryProviderCopyrightAdapterFactory.class);
+ if (factory == null) {
+ factory = (IRepositoryProviderCopyrightAdapterFactory) Platform.getAdapterManager()
+ .loadAdapter(providerType, IRepositoryProviderCopyrightAdapterFactory.class.getName());
+ if (factory == null) {
+ throw new CoreException(new Status(IStatus.ERROR, RelEngPlugin.ID, 0,
+ NLS.bind(Messages.getString("AdvancedFixCopyrightAction.12"), providerType.getID()), null)); //$NON-NLS-1$
+ }
+ }
+ return factory.createAdapater(results);
+ }
+
+ /**
+ *
+ */
+ private void writeLogs() {
+
+ FileOutputStream aStream;
+ try {
+ File aFile = new File(Platform.getLocation().toFile(), "copyrightLog.txt"); //$NON-NLS-1$
+ aStream = new FileOutputStream(aFile);
+ Set<Map.Entry<String, List<String>>> aSet = log.entrySet();
+ Iterator<Map.Entry<String, List<String>>> errorIterator = aSet.iterator();
+ while (errorIterator.hasNext()) {
+ Map.Entry<String, List<String>> anEntry = errorIterator.next();
+ String errorDescription = anEntry.getKey();
+ aStream.write(errorDescription.getBytes());
+ aStream.write(newLine.getBytes());
+ List<String> fileList = anEntry.getValue();
+ Iterator<String> listIterator = fileList.iterator();
+ while (listIterator.hasNext()) {
+ String fileName = listIterator.next();
+ aStream.write(" ".getBytes()); //$NON-NLS-1$
+ aStream.write(fileName.getBytes());
+ aStream.write(newLine.getBytes());
+ }
+ }
+ aStream.close();
+ } catch (FileNotFoundException e) {
+ e.printStackTrace();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+
+ private void displayLogs(MessageConsoleStream stream) {
+
+ Set<Map.Entry<String, List<String>>> aSet = log.entrySet();
+ Iterator<Map.Entry<String, List<String>>> errorIterator = aSet.iterator();
+ while (errorIterator.hasNext()) {
+ Map.Entry<String, List<String>> anEntry = errorIterator.next();
+ String errorDescription = anEntry.getKey();
+ stream.println(errorDescription);
+ List<String> fileList = anEntry.getValue();
+ Iterator<String> listIterator = fileList.iterator();
+ while (listIterator.hasNext()) {
+ String fileName = listIterator.next();
+ stream.println(" " + fileName); //$NON-NLS-1$
+ }
+ }
+ }
+
+ /**
+ * Handle an induvidual file at a time
+ *
+ * <p>
+ * Functions:
+ * <ul>
+ * -
+ * <li>get user defined default date</li> -
+ * <li>identify if multiple comments inserted.</li>
+ * <li>update existing comment or insert a new one</li>
+ * </ul>
+ *
+ * @param file
+ * - file to be proccessed (.java, .bat, .xml etc...)
+ * @param adapter
+ * @param monitor
+ */
+ private void processFile(IFile file, RepositoryProviderCopyrightAdapter adapter, IProgressMonitor monitor) {
+
+ // Missign file Extension
+ if (!checkFileExtension(file)) {
+ return;
+ }
+
+ // Create an instance of the appropriate Source container.
+ // (xml/java/bash etc..)
+ SourceFile aSourceFile = SourceFile.createFor(file);
+ if (!checkSourceCreatedOk(aSourceFile, file)) {
+ return;
+ }
+
+ // Aquire user settings
+ IPreferenceStore prefStore = RelEngPlugin.getDefault().getPreferenceStore();
+
+ // Check if user wants to skip over this file
+ if (!checkUserFileIgnoreSettings(prefStore, aSourceFile)) {
+ return;
+ }
+
+ // Skip over source files that have multiple copy-right notes
+ if (!checkMultipleCopyright(file, aSourceFile)) {
+ return;
+ }
+
+ // Extract 'current' 'raw' comment from the document.
+ BlockComment copyrightComment = aSourceFile.getFirstCopyrightComment();
+
+ CopyrightComment ibmCopyright = null;
+
+ // if replacing all comments, don't even parse, just use default
+ // copyright comment
+ if (prefStore.getBoolean(RelEngCopyrightConstants.REPLACE_ALL_EXISTING_KEY)) {
+
+ // Aquire user default comments from settings.
+ ibmCopyright = AdvancedCopyrightComment.defaultComment(aSourceFile.getFileType());
+ } else {
+
+ // Parse the raw comment and update the last revision year.
+ // (inserting a revision year if neccessary).
+ ibmCopyright = AdvancedCopyrightComment.parse(copyrightComment, aSourceFile.getFileType());
+
+ // Check that the newly created comment was constructed correctly.
+ if (ibmCopyright == null) {
+
+ // Check against a standard IBM copyright header.
+ // Let's see if the file is EPL
+ ibmCopyright = IBMCopyrightComment.parse(copyrightComment, aSourceFile.getFileType());
+ if (ibmCopyright != null) {
+ // Could not proccess file at all.
+ warn(file, copyrightComment, Messages.getString("AdvancedFixCopyrightAction.15")); //$NON-NLS-1$
+ }
+ }
+ }
+
+ // Could not determine the 'new' 'copyright' header. Do not procces
+ // file.
+ if (ibmCopyright == null) {
+ warn(file, copyrightComment, Messages.getString("AdvancedFixCopyrightAction.16")); //$NON-NLS-1$
+ return;
+ }
+
+ ibmCopyright.setLineDelimiter(aSourceFile.getLineDelimiter());
+
+ // year last revised as listed in the copyright header.
+ int revised = ibmCopyright.getRevisionYear();
+
+ // lasdMod = last touched by user. (e.g as defined 'default' in
+ // options).
+ int lastMod = revised;
+
+ // Read user defined year from options.
+ if (prefStore.getBoolean(RelEngCopyrightConstants.USE_DEFAULT_REVISION_YEAR_KEY) || adapter == null)
+ lastMod = prefStore.getInt(RelEngCopyrightConstants.REVISION_YEAR_KEY);
+ else {
+ // figure out if the comment should be updated by comparing the date
+ // range
+ // in the comment to the last modification time provided by adapter
+ if (lastMod < currentYear) {
+ try {
+ lastMod = adapter.getLastModifiedYear(file, monitor);
+ } catch (CoreException e) {
+ // Let's log the exception and continue
+ RelEngPlugin.log(IStatus.ERROR,
+ NLS.bind(Messages.getString("AdvancedFixCopyrightAction.17"), file.getFullPath()), e); //$NON-NLS-1$
+ }
+ if (lastMod > currentYear) {
+ // Don't allow future years to be used in the copyright
+ lastMod = currentYear;
+ }
+ if (lastMod == 0) {
+ warn(file, copyrightComment, Messages.getString("AdvancedFixCopyrightAction.18")); //$NON-NLS-1$
+ return;
+ }
+ // use default revision year
+ if (lastMod == -1) {
+ lastMod = prefStore.getInt(RelEngCopyrightConstants.REVISION_YEAR_KEY);
+ }
+ if (lastMod < revised) {
+ // Don't let the copyright date go backwards
+ lastMod = revised;
+ }
+ }
+ }
+
+ // only exit if existing copyright comment already contains the year
+ // of last modification and not overwriting all comments
+ if (lastMod <= revised && (copyrightComment != null)
+ && (!prefStore.getBoolean(RelEngCopyrightConstants.REPLACE_ALL_EXISTING_KEY)))
+ return;
+
+ // either replace old copyright or put the new one at the top of the
+ // file
+ ibmCopyright.setRevisionYear(lastMod);
+ if (copyrightComment == null) // do this on files without comments
+ aSourceFile.insert(ibmCopyright.getCopyrightComment());
+ else { // do this with files that have a copy-right comment already.
+
+ // Verify that the comment is at the top of the file. Warn
+ // otherwise.
+ // [276257] XML file is a special case because it can have an
+ // xml-header and other headers, thus it can start at an arbirary
+ // position.
+ if (!copyrightComment.atTop() && (aSourceFile.getFileType() != CopyrightComment.XML_COMMENT)) {
+ warn(file, copyrightComment, Messages.getString("AdvancedFixCopyrightAction.19")); //$NON-NLS-1$
+ }
+ aSourceFile.replace(copyrightComment, ibmCopyright.getCopyrightComment());
+ }
+ }
+
+ private boolean checkFileExtension(IFile file) {
+ if (file.getFileExtension() == null) {
+ warn(file, null, Messages.getString("AdvancedFixCopyrightAction.13")); //$NON-NLS-1$
+ return false;
+ } else {
+ return true;
+ }
+ }
+
+ private boolean checkSourceCreatedOk(SourceFile sourceFile, IFile file) {
+ if (sourceFile == null) {
+ // Warn if source creation failed.
+ warn(file, null, Messages.getString("AdvancedFixCopyrightAction.20")); //$NON-NLS-1$
+ return false;
+ } else {
+ return true;
+ }
+
+ }
+
+ /**
+ * Check if user chose to skip files of this kind.
+ *
+ * @param prefStore
+ * Copyright preference store
+ * @param aSourceFile
+ * Instance of the file to be checked.
+ * @return false if user wishes to skip over the file.
+ */
+ private boolean checkUserFileIgnoreSettings(IPreferenceStore prefStore, SourceFile aSourceFile) {
+
+ // -- Skip file if it's a property file and user chose to ignore
+ // property files.
+ if (aSourceFile.getFileType() == CopyrightComment.PROPERTIES_COMMENT
+ && prefStore.getBoolean(RelEngCopyrightConstants.IGNORE_PROPERTIES_KEY)) {
+ return false;
+ }
+ // -- Skip over xml file if the user selected to skip xml files.
+ if (aSourceFile.getFileType() == CopyrightComment.XML_COMMENT
+ && prefStore.getBoolean(RelEngCopyrightConstants.IGNORE_XML_KEY)) {
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * Check if the file has multiple copyright notices. Skip such files.
+ *
+ * @param file
+ * @param aSourceFile
+ * @return true if it has a single notice.
+ */
+ private boolean checkMultipleCopyright(IFile file, SourceFile aSourceFile) {
+ if (aSourceFile.hasMultipleCopyrights()) {
+ warn(file, null, Messages.getString("AdvancedFixCopyrightAction.14")); //$NON-NLS-1$
+ return false;
+ } else {
+ return true;
+ }
+ }
+
+ private void warn(IFile file, BlockComment firstBlockComment, String errorDescription) {
+ List<String> aList = log.get(errorDescription);
+ if (aList == null) {
+ aList = new ArrayList<>();
+ log.put(errorDescription, aList);
+ }
+ aList.add(file.getFullPath().toString());
+ }
+
+ /**
+ * @see IActionDelegate#selectionChanged(IAction, ISelection)
+ */
+ @Override
+ public void selectionChanged(IAction action, ISelection selection) {
+ if (selection instanceof IStructuredSelection) {
+ this.selection = (IStructuredSelection) selection;
+ }
+ }
+
+}
diff --git a/bundles/org.eclipse.releng.tools/src/org/eclipse/releng/tools/BatFile.java b/bundles/org.eclipse.releng.tools/src/org/eclipse/releng/tools/BatFile.java
new file mode 100644
index 0000000..093f937
--- /dev/null
+++ b/bundles/org.eclipse.releng.tools/src/org/eclipse/releng/tools/BatFile.java
@@ -0,0 +1,58 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2010 IBM Corporation and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ * Martin Oberhuber (Wind River) - [235572] detect existing comments in bat files
+ *******************************************************************************/
+package org.eclipse.releng.tools;
+
+import java.util.regex.Pattern;
+
+import org.eclipse.core.resources.IFile;
+
+
+public class BatFile extends SourceFile {
+
+ public BatFile(IFile file) {
+ super(file);
+ }
+
+ //Optional Whitespace, #, optional whitespace, then at least 2 non-word chars repeated till EOL
+ private static Pattern p = Pattern.compile("\\s*@?[rR][eE][mM]\\s+\\W{2,}\\s*"); //$NON-NLS-1$
+
+ @Override
+ public boolean isCommentStart(String aLine) {
+ return p.matcher(aLine).matches();
+ }
+
+ @Override
+ public boolean isCommentEnd(String aLine, String commentStartString) {
+ String s = commentStartString.trim();
+ s = s.substring(s.length()-2);
+ return aLine.trim().endsWith(s);
+ }
+
+ @Override
+ public String getCommentStart() {
+ return "@rem **"; //unused, Pattern matcher above will be used instead //$NON-NLS-1$
+ }
+
+ @Override
+ public String getCommentEnd() {
+ return "**"; //unused, Pattern matcher above will be used instead //$NON-NLS-1$
+ }
+
+ @Override
+ public int getFileType() {
+ return CopyrightComment.BAT_COMMENT;
+ }
+
+}
diff --git a/bundles/org.eclipse.releng.tools/src/org/eclipse/releng/tools/BlockComment.java b/bundles/org.eclipse.releng.tools/src/org/eclipse/releng/tools/BlockComment.java
new file mode 100644
index 0000000..2939888
--- /dev/null
+++ b/bundles/org.eclipse.releng.tools/src/org/eclipse/releng/tools/BlockComment.java
@@ -0,0 +1,144 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2020 IBM Corporation and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.releng.tools;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.StringReader;
+import java.util.ArrayList;
+import java.util.List;
+
+
+/**
+ * @author droberts
+ */
+public class BlockComment {
+
+ int start;
+ int end;
+ private String contents;
+ private static String newLine = System.lineSeparator();
+ private String copyrightHolder;
+ private List<String> nonIBMContributors = new ArrayList<>();
+ private String commentEnd;
+
+
+ /**
+ * @param commentStart
+ * @param commentEnd
+ * @param comment
+ */
+ public BlockComment(int commentStartLine, int commentEndLine, String comment, String commentStartString, String commentEndString) {
+ start = commentStartLine;
+ end = commentEndLine;
+ commentEnd = commentEndString;
+ contents = comment;
+ }
+
+ public String getContents() {
+ return contents;
+ }
+
+ /**
+ * @return boolean
+ */
+ public boolean isCopyright() {
+ return contents.toLowerCase().indexOf("copyright") != -1;
+ }
+
+ /**
+ * @return boolean
+ */
+ public boolean atTop() {
+ return start == 0;
+ }
+
+ /**
+ * @return boolean
+ */
+ public boolean notIBM() {
+
+ String lowerCaseContents = contents.toLowerCase();
+ if (copyrightHolder == null) {
+ int start = lowerCaseContents.indexOf("copyright");
+ if (start == -1) {
+ return false;
+ }
+
+ int end = lowerCaseContents.indexOf(newLine, start);
+
+ copyrightHolder = contents.substring(start + "copyright".length(), end);
+ }
+
+ String lowercaseCopyrightHolder = copyrightHolder.toLowerCase();
+
+ int result = lowercaseCopyrightHolder.indexOf("ibm");
+ if (result != -1) {
+ return false;
+ }
+
+ result = lowercaseCopyrightHolder.indexOf("international business machine");
+ if (result != -1) {
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * @return String
+ */
+ public String getCopyrightHolder() {
+ return copyrightHolder;
+ }
+
+ /**
+ *
+ */
+ public List<String> nonIBMContributors() {
+
+ String lowerCaseContents = contents.toLowerCase();
+ int start = lowerCaseContents.indexOf("contributors");
+ if (start == -1) {
+ return nonIBMContributors;
+ }
+
+ start = lowerCaseContents.indexOf(newLine, start);
+ if (start == -1) {
+ return nonIBMContributors;
+ }
+
+ start = start + newLine.length();
+ BufferedReader aReader = new BufferedReader(new StringReader(lowerCaseContents.substring(start)));
+
+ String aLine;
+ try {
+ aLine = aReader.readLine();
+ while (aLine != null) {
+ aLine = aLine.trim();
+ if ((aLine.length() > 0) && (aLine.indexOf(commentEnd) == -1)) {
+ if ((aLine.indexOf("ibm") == -1) && (aLine.indexOf("international business machine") == -1)) {
+ nonIBMContributors.add(aLine);
+ }
+ }
+ aLine = aReader.readLine();
+ }
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+
+ return nonIBMContributors;
+ }
+
+}
diff --git a/bundles/org.eclipse.releng.tools/src/org/eclipse/releng/tools/CFile.java b/bundles/org.eclipse.releng.tools/src/org/eclipse/releng/tools/CFile.java
new file mode 100644
index 0000000..d694d1d
--- /dev/null
+++ b/bundles/org.eclipse.releng.tools/src/org/eclipse/releng/tools/CFile.java
@@ -0,0 +1,40 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2010 IBM Corporation and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.releng.tools;
+
+
+import org.eclipse.core.resources.IFile;
+
+public class CFile extends SourceFile {
+
+ public CFile(IFile file) {
+ super(file);
+ }
+
+ @Override
+ public String getCommentStart() {
+ return "/*"; //$NON-NLS-1$
+ }
+
+ @Override
+ public String getCommentEnd() {
+ return "*/"; //$NON-NLS-1$
+ }
+
+ @Override
+ public int getFileType() {
+ return CopyrightComment.C_COMMENT;
+ }
+
+}
diff --git a/bundles/org.eclipse.releng.tools/src/org/eclipse/releng/tools/CopyrightComment.java b/bundles/org.eclipse.releng.tools/src/org/eclipse/releng/tools/CopyrightComment.java
new file mode 100644
index 0000000..9dd7395
--- /dev/null
+++ b/bundles/org.eclipse.releng.tools/src/org/eclipse/releng/tools/CopyrightComment.java
@@ -0,0 +1,146 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2012 IBM Corporation and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ * Martin Oberhuber (Wind River) - [276255] fix insertion of extra space chars
+ * Martin Oberhuber (Wind River) - [234872] avoid rem's that echo to the console
+ *******************************************************************************/
+package org.eclipse.releng.tools;
+
+import java.io.PrintWriter;
+import java.util.Calendar;
+
+
+public abstract class CopyrightComment {
+
+ public static final int UNKNOWN_COMMENT = -1;
+ public static final int JAVA_COMMENT = 1;
+ public static final int PROPERTIES_COMMENT = 2;
+ public static final int C_COMMENT = 3;
+ public static final int SHELL_MAKE_COMMENT = 4;
+ public static final int BAT_COMMENT = 5;
+ public static final int JAVASCRIPT_COMMENT = 6;
+ public static final int XML_COMMENT = 7;
+
+ private int commentStyle;
+ private int creationYear = -1;
+ private int revisionYear = -1;
+ private String lineDelimiter;
+
+ protected CopyrightComment(int commentStyle, int creationYear, int revisionYear) {
+ this.commentStyle = commentStyle;
+ this.creationYear = creationYear == -1 ? (Calendar.getInstance().get(Calendar.YEAR)) : creationYear;
+ this.revisionYear = revisionYear;
+ }
+
+ public static String getLinePrefix(int commentStyle) {
+ switch(commentStyle) {
+ case JAVA_COMMENT:
+ case C_COMMENT:
+ case JAVASCRIPT_COMMENT:
+ return " *"; //$NON-NLS-1$
+ case PROPERTIES_COMMENT:
+ return "#"; //$NON-NLS-1$
+ case SHELL_MAKE_COMMENT:
+ return "#"; //$NON-NLS-1$
+ case BAT_COMMENT:
+ return "@rem"; //$NON-NLS-1$
+ case XML_COMMENT:
+ return " "; //$NON-NLS-1$
+ default:
+ return null;
+ }
+ }
+
+ protected void writeCommentStart(PrintWriter writer) {
+ switch(commentStyle) {
+ case JAVA_COMMENT:
+ case C_COMMENT:
+ case JAVASCRIPT_COMMENT:
+ println(writer, "/*******************************************************************************"); //$NON-NLS-1$
+ break;
+ case PROPERTIES_COMMENT:
+ println(writer, "###############################################################################"); //$NON-NLS-1$
+ break;
+ case SHELL_MAKE_COMMENT:
+ println(writer, "#*******************************************************************************"); //$NON-NLS-1$
+ break;
+ case BAT_COMMENT:
+ println(writer, "@rem ***************************************************************************"); //$NON-NLS-1$
+ break;
+ case XML_COMMENT:
+ println(writer, "<!--"); //$NON-NLS-1$
+ break;
+ }
+ }
+
+ protected void writeCommentEnd(PrintWriter writer) {
+ switch(commentStyle) {
+ case JAVA_COMMENT:
+ case C_COMMENT:
+ case JAVASCRIPT_COMMENT:
+ println(writer, " *******************************************************************************/"); //$NON-NLS-1$
+ break;
+ case PROPERTIES_COMMENT:
+ println(writer, "###############################################################################"); //$NON-NLS-1$
+ break;
+ case SHELL_MAKE_COMMENT:
+ println(writer, "#*******************************************************************************"); //$NON-NLS-1$
+ break;
+ case BAT_COMMENT:
+ println(writer, "@rem ***************************************************************************"); //$NON-NLS-1$
+ break;
+ case XML_COMMENT:
+ println(writer, " -->"); //$NON-NLS-1$
+ break;
+ }
+ }
+
+
+ public int getRevisionYear() {
+ return revisionYear == -1 ? creationYear : revisionYear;
+ }
+
+ public boolean hasRevisionYear() {
+ return revisionYear != -1;
+ }
+
+ public void setRevisionYear(int year) {
+ if (revisionYear != -1 || creationYear != year)
+ revisionYear = year;
+ }
+
+ /**
+ * @param lineDelimiter
+ * @since 3.7
+ */
+ public void setLineDelimiter(String lineDelimiter) {
+ this.lineDelimiter= lineDelimiter;
+ }
+
+ public int getCreationYear() {
+ return creationYear;
+ }
+
+ public String getCommentPrefix() {
+ return getLinePrefix(commentStyle);
+ }
+
+ public abstract String getCopyrightComment();
+
+ /**
+ * @since 3.7
+ */
+ protected void println(PrintWriter writer, String line) {
+ writer.print(line);
+ writer.print(lineDelimiter);
+ }
+}
diff --git a/bundles/org.eclipse.releng.tools/src/org/eclipse/releng/tools/FixPageParticipant.java b/bundles/org.eclipse.releng.tools/src/org/eclipse/releng/tools/FixPageParticipant.java
new file mode 100644
index 0000000..b127544
--- /dev/null
+++ b/bundles/org.eclipse.releng.tools/src/org/eclipse/releng/tools/FixPageParticipant.java
@@ -0,0 +1,51 @@
+/*******************************************************************************
+ * Copyright (c) 2014, 2016 IBH SYSTEMS GmbH.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * IBH SYSTEMS GmbH - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.releng.tools;
+
+import org.eclipse.ui.IActionBars;
+import org.eclipse.ui.console.IConsole;
+import org.eclipse.ui.console.IConsoleConstants;
+import org.eclipse.ui.console.IConsolePageParticipant;
+import org.eclipse.ui.part.IPageBookViewPage;
+
+public class FixPageParticipant implements IConsolePageParticipant {
+
+ @Override
+ public <T> T getAdapter(Class<T> adapter) {
+ return null;
+ }
+
+ @Override
+ public void init(IPageBookViewPage page, IConsole console) {
+ IActionBars actionBars = page.getSite().getActionBars();
+ actionBars.getToolBarManager().appendToGroup(
+ IConsoleConstants.LAUNCH_GROUP,
+ new RemoveConsoleAction(console));
+ actionBars.getToolBarManager().appendToGroup(
+ IConsoleConstants.LAUNCH_GROUP, new RemoveAllConsolesAction());
+ }
+
+ @Override
+ public void dispose() {
+ }
+
+ @Override
+ public void activated() {
+ }
+
+ @Override
+ public void deactivated() {
+ }
+
+}
diff --git a/bundles/org.eclipse.releng.tools/src/org/eclipse/releng/tools/IBMCopyrightComment.java b/bundles/org.eclipse.releng.tools/src/org/eclipse/releng/tools/IBMCopyrightComment.java
new file mode 100644
index 0000000..e3e6fcd
--- /dev/null
+++ b/bundles/org.eclipse.releng.tools/src/org/eclipse/releng/tools/IBMCopyrightComment.java
@@ -0,0 +1,190 @@
+/*******************************************************************************
+ * Copyright (c) 2010, 2060 IBM Corporation and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.releng.tools;
+
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.StringTokenizer;
+
+
+public class IBMCopyrightComment extends CopyrightComment {
+
+ private static final int DEFAULT_CREATION_YEAR = 2005;
+
+ private List<String> contributors;
+ private int yearRangeStart, yearRangeEnd;
+ private String originalText;
+
+ private IBMCopyrightComment(int commentStyle, int creationYear, int revisionYear, List<String> contributors, int yearRangeStart, int yearRangeEnd, String originalText) {
+ super(commentStyle, creationYear == -1 ? DEFAULT_CREATION_YEAR : creationYear, revisionYear);
+ this.contributors = contributors;
+ this.yearRangeStart = yearRangeStart;
+ this.yearRangeEnd = yearRangeEnd;
+ this.originalText = originalText;
+ }
+
+ public static IBMCopyrightComment defaultComment(int commentStyle) {
+ return new IBMCopyrightComment(commentStyle, DEFAULT_CREATION_YEAR, -1, null, 0, 0, null);
+ }
+
+ /**
+ * Create an instance the same as the argument comment but with the revision year
+ * updated if needed. Return the default comment if the argument comment is null
+ * or an empty string. Return null if the argument comment is not recognized as
+ * an IBM copyright comment.
+ */
+ public static IBMCopyrightComment parse(BlockComment comment, int commentStyle) {
+ if (comment == null)
+ return defaultComment(commentStyle);
+
+ String body = comment.getContents();
+
+ final String copyrightLabel = "Copyright (c) "; //$NON-NLS-1$
+ int start = body.indexOf(copyrightLabel);
+ if (start == -1) return null;
+ int contrib = body.indexOf("Contributors:", start); //$NON-NLS-1$
+ int rangeEnd = body.indexOf(" IBM Corp", start); //$NON-NLS-1$ // catch both IBM Corporation and IBM Corp.
+
+ if (rangeEnd == -1 || rangeEnd > contrib) // IBM must be on the copyright line, not the contributor line
+ return null;
+
+ int rangeStart = start + copyrightLabel.length();
+ String yearRange = body.substring(rangeStart, rangeEnd);
+
+ int comma = yearRange.indexOf(","); //$NON-NLS-1$
+ if (comma == -1) {
+ comma = yearRange.indexOf("-"); //$NON-NLS-1$
+ }
+
+ String startStr = comma == -1 ? yearRange : yearRange.substring(0, comma);
+ if (comma != -1 && Character.isWhitespace(yearRange.charAt(comma))) comma++;
+ String endStr = comma == -1 ? null : yearRange.substring(comma + 1);
+
+ int startYear = -1;
+ if (startStr != null) {
+ try {
+ startYear = Integer.parseInt(startStr.trim());
+ } catch(NumberFormatException e) {
+ // do nothing
+ }
+ }
+
+ int endYear = -1;
+ if (endStr != null) {
+ try {
+ endYear = Integer.parseInt(endStr.trim());
+ } catch(NumberFormatException e) {
+ // do nothing
+ }
+ }
+
+ String contribComment = body.substring(contrib);
+ StringTokenizer tokens = new StringTokenizer(contribComment, "\r\n"); //$NON-NLS-1$
+ tokens.nextToken();
+ ArrayList<String> contributors = new ArrayList<>();
+ String linePrefix = getLinePrefix(commentStyle);
+ while(tokens.hasMoreTokens()) {
+ String contributor = tokens.nextToken();
+ if (contributor.indexOf("***********************************") == -1 //$NON-NLS-1$
+ && contributor.indexOf("###################################") == -1) { //$NON-NLS-1$
+ int c = contributor.indexOf(linePrefix);
+ if (c == -1 && linePrefix.equals(" *")) { //$NON-NLS-1$
+ // special case: old prefix was "*" and new prefix is " *"
+ c = contributor.indexOf("*"); //$NON-NLS-1$
+ }
+ if (c == 0) {
+ // prefix has to be at the beginning of the line
+ contributor = contributor.substring(c + linePrefix.length());
+ }
+ contributors.add(contributor);
+ }
+ }
+
+ return new IBMCopyrightComment(commentStyle, startYear, endYear, contributors, rangeStart, rangeEnd, body);
+ }
+
+ /**
+ * Return the body of this copyright comment or null if it cannot be built.
+ */
+ @Override
+ public String getCopyrightComment() {
+ String linePrefix = getCommentPrefix();
+ if (linePrefix == null)
+ return null;
+
+ StringWriter out = new StringWriter();
+
+ try (PrintWriter writer = new PrintWriter(out)) {
+ writeCommentStart(writer);
+ writeLegal(writer, linePrefix);
+ writeContributions(writer, linePrefix);
+ writeCommentEnd(writer);
+ return out.toString();
+ }
+ }
+
+ /**
+ * Return the body of the original copyright comment with new dates.
+ */
+ public String getOriginalCopyrightComment() {
+ StringWriter out = new StringWriter();
+
+ try (PrintWriter writer = new PrintWriter(out)) {
+ writer.print(originalText.substring(0, yearRangeStart));
+ writer.print(getCreationYear());
+ if (hasRevisionYear() && getRevisionYear() != getCreationYear())
+ writer.print(", " + getRevisionYear()); //$NON-NLS-1$
+ writer.print(originalText.substring(yearRangeEnd));
+ return out.toString();
+ }
+ }
+
+ private void writeLegal(PrintWriter writer, String linePrefix) {
+ writer.print(linePrefix + " Copyright (c) " + getCreationYear()); //$NON-NLS-1$
+ if (hasRevisionYear() && getRevisionYear() != getCreationYear())
+ writer.print(", " + getRevisionYear()); //$NON-NLS-1$
+ println(writer, " IBM Corporation and others."); //$NON-NLS-1$
+
+ println(writer, linePrefix + " All rights reserved. This program and the accompanying materials"); //$NON-NLS-1$
+ println(writer, linePrefix + " are made available under the terms of the Eclipse Public License v1.0"); //$NON-NLS-1$
+ println(writer, linePrefix + " which accompanies this distribution, and is available at"); //$NON-NLS-1$
+ println(writer, linePrefix + " http://www.eclipse.org/legal/epl-v10.html"); //$NON-NLS-1$
+ }
+
+ private void writeContributions(PrintWriter writer, String linePrefix) {
+ println(writer, linePrefix);
+ println(writer, linePrefix + " Contributors:"); //$NON-NLS-1$
+
+ if (contributors == null || contributors.size() <= 0)
+ println(writer, linePrefix + " IBM Corporation - initial API and implementation"); //$NON-NLS-1$
+ else {
+ Iterator<String> i = contributors.iterator();
+ while (i.hasNext()) {
+ String contributor = i.next();
+ if (contributor.length() > 0) {
+ if (Character.isWhitespace(contributor.charAt(0))) {
+ println(writer, linePrefix + contributor);
+ } else {
+ println(writer, linePrefix + " " + contributor); //$NON-NLS-1$
+ }
+ } else {
+ println(writer, linePrefix);
+ }
+ }
+ }
+ }
+}
diff --git a/bundles/org.eclipse.releng.tools/src/org/eclipse/releng/tools/IRepositoryProviderCopyrightAdapterFactory.java b/bundles/org.eclipse.releng.tools/src/org/eclipse/releng/tools/IRepositoryProviderCopyrightAdapterFactory.java
new file mode 100644
index 0000000..4ee67b8
--- /dev/null
+++ b/bundles/org.eclipse.releng.tools/src/org/eclipse/releng/tools/IRepositoryProviderCopyrightAdapterFactory.java
@@ -0,0 +1,34 @@
+/*******************************************************************************
+ * Copyright (c) 2008 IBM Corporation and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.releng.tools;
+
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.IAdapterManager;
+
+/**
+ * This interface supports the creation of a {@link RepositoryProviderCopyrightAdapter}
+ * that can be used by the {@link AdvancedFixCopyrightAction} to determine the last modified year
+ * for a set of files. It should be obtained by adapting the repository provider type to an instance
+ * of this interface using the {@link IAdapterManager}.
+ *
+ */
+public interface IRepositoryProviderCopyrightAdapterFactory {
+
+ /**
+ * Create an adapter for the given set of resources
+ * @param resources the resources
+ * @return an adapter
+ */
+ public RepositoryProviderCopyrightAdapter createAdapater(IResource[] resources);
+}
diff --git a/bundles/org.eclipse.releng.tools/src/org/eclipse/releng/tools/JavaFile.java b/bundles/org.eclipse.releng.tools/src/org/eclipse/releng/tools/JavaFile.java
new file mode 100644
index 0000000..e6b36da
--- /dev/null
+++ b/bundles/org.eclipse.releng.tools/src/org/eclipse/releng/tools/JavaFile.java
@@ -0,0 +1,43 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2017 IBM Corporation and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.releng.tools;
+
+import org.eclipse.core.resources.IFile;
+
+
+public class JavaFile extends SourceFile {
+
+ /**
+ * @param file
+ */
+ public JavaFile(IFile file) {
+ super(file);
+ }
+
+ @Override
+ public String getCommentStart() {
+ return "/*"; //$NON-NLS-1$
+ }
+
+ @Override
+ public String getCommentEnd() {
+ return "*/"; //$NON-NLS-1$
+ }
+
+ @Override
+ public int getFileType() {
+ return CopyrightComment.JAVA_COMMENT;
+ }
+
+}
diff --git a/bundles/org.eclipse.releng.tools/src/org/eclipse/releng/tools/JavaScriptFile.java b/bundles/org.eclipse.releng.tools/src/org/eclipse/releng/tools/JavaScriptFile.java
new file mode 100644
index 0000000..cfa00e5
--- /dev/null
+++ b/bundles/org.eclipse.releng.tools/src/org/eclipse/releng/tools/JavaScriptFile.java
@@ -0,0 +1,39 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2017 IBM Corporation and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.releng.tools;
+
+import org.eclipse.core.resources.IFile;
+
+
+public class JavaScriptFile extends SourceFile {
+
+ public JavaScriptFile(IFile file) {
+ super(file);
+ }
+
+ @Override
+ public String getCommentStart() {
+ return "/*"; //$NON-NLS-1$
+ }
+
+ @Override
+ public String getCommentEnd() {
+ return "*/"; //$NON-NLS-1$
+ }
+ @Override
+ public int getFileType() {
+ return CopyrightComment.JAVASCRIPT_COMMENT;
+ }
+
+}
diff --git a/bundles/org.eclipse.releng.tools/src/org/eclipse/releng/tools/Messages.java b/bundles/org.eclipse.releng.tools/src/org/eclipse/releng/tools/Messages.java
new file mode 100644
index 0000000..a29d493
--- /dev/null
+++ b/bundles/org.eclipse.releng.tools/src/org/eclipse/releng/tools/Messages.java
@@ -0,0 +1,33 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.releng.tools;
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+
+public class Messages {
+ private static final String BUNDLE_NAME = "org.eclipse.releng.tools.messages";//$NON-NLS-1$
+ private static final ResourceBundle RESOURCE_BUNDLE = ResourceBundle
+ .getBundle(BUNDLE_NAME);
+
+ private Messages() {
+ }
+
+ public static String getString(String key) {
+ try {
+ return RESOURCE_BUNDLE.getString(key);
+ } catch (MissingResourceException e) {
+ return '!' + key + '!';
+ }
+ }
+}
diff --git a/bundles/org.eclipse.releng.tools/src/org/eclipse/releng/tools/PropertiesFile.java b/bundles/org.eclipse.releng.tools/src/org/eclipse/releng/tools/PropertiesFile.java
new file mode 100644
index 0000000..50725a0
--- /dev/null
+++ b/bundles/org.eclipse.releng.tools/src/org/eclipse/releng/tools/PropertiesFile.java
@@ -0,0 +1,43 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2017 IBM Corporation and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.releng.tools;
+
+import org.eclipse.core.resources.IFile;
+
+
+public class PropertiesFile extends SourceFile {
+
+ /**
+ * @param file
+ */
+ public PropertiesFile(IFile file) {
+ super(file);
+ }
+
+ @Override
+ public String getCommentStart() {
+ return "##"; //$NON-NLS-1$
+ }
+
+ @Override
+ public String getCommentEnd() {
+ return "##"; //$NON-NLS-1$
+ }
+
+ @Override
+ public int getFileType() {
+ return CopyrightComment.PROPERTIES_COMMENT;
+ }
+
+}
diff --git a/bundles/org.eclipse.releng.tools/src/org/eclipse/releng/tools/RelEngPlugin.java b/bundles/org.eclipse.releng.tools/src/org/eclipse/releng/tools/RelEngPlugin.java
new file mode 100644
index 0000000..8fd8894
--- /dev/null
+++ b/bundles/org.eclipse.releng.tools/src/org/eclipse/releng/tools/RelEngPlugin.java
@@ -0,0 +1,197 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2017 IBM Corporation and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.releng.tools;
+
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResourceChangeEvent;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.resources.WorkspaceJob;
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.core.runtime.preferences.IEclipsePreferences;
+import org.eclipse.core.runtime.preferences.InstanceScope;
+import org.eclipse.releng.internal.tools.pomversion.IPomVersionConstants;
+import org.eclipse.releng.internal.tools.pomversion.PomVersionErrorReporter;
+import org.eclipse.team.core.RepositoryProvider;
+import org.eclipse.ui.plugin.AbstractUIPlugin;
+import org.osgi.framework.BundleContext;
+
+
+/**
+ * A Plugin for performing certain important RelEng tasks.
+ * <p>
+ * Currently this Plugin provides support for:
+ * <li>RelEng Map File Validator
+ * <li>Builder and associated project nature
+ * <li>Fix Copyright action
+ */
+public class RelEngPlugin extends AbstractUIPlugin {
+
+ public static final String ID = "org.eclipse.releng.tools"; //$NON-NLS-1$
+ public static final String MAP_PROJECT_NAME = Messages.getString("RelEngPlugin.1"); //$NON-NLS-1$
+ public static final String MAP_FOLDER = Messages.getString("RelEngPlugin.2"); //$NON-NLS-1$
+ private static final String BINARY_REPOSITORY_PROVIDER_CLASS_NAME= "org.eclipse.pde.internal.core.BinaryRepositoryProvider"; //$NON-NLS-1$
+
+ private PomVersionErrorReporter fPomReporter = new PomVersionErrorReporter();
+
+
+ //The shared instance.
+ private static RelEngPlugin plugin;
+ //Resource bundle.
+ private ResourceBundle resourceBundle;
+
+ /**
+ * The constructor.
+ */
+ public RelEngPlugin() {
+ plugin = this;
+ try {
+ resourceBundle= ResourceBundle.getBundle(ID + Messages.getString("RelEngPlugin.3")); //$NON-NLS-1$
+ } catch (MissingResourceException x) {
+ resourceBundle = null;
+ }
+ }
+
+ @Override
+ public void start(BundleContext context) throws Exception {
+ super.start(context);
+ IEclipsePreferences node = InstanceScope.INSTANCE.getNode(ID);
+ if(node != null) {
+ node.addPreferenceChangeListener(fPomReporter);
+ String severity = getPreferenceStore().getString(IPomVersionConstants.POM_VERSION_ERROR_LEVEL);
+ if(!IPomVersionConstants.VALUE_IGNORE.equals(severity)) {
+ ResourcesPlugin.getWorkspace().addResourceChangeListener(fPomReporter, IResourceChangeEvent.POST_BUILD);
+ int workspaceValidated= node.getInt(IPomVersionConstants.WORKSPACE_VALIDATED, 0);
+ if (workspaceValidated < PomVersionErrorReporter.VERSION) {
+ new WorkspaceJob(Messages.getString("RelEngPlugin.0")) { //$NON-NLS-1$
+ @Override
+ public IStatus runInWorkspace(IProgressMonitor monitor) throws CoreException {
+ fPomReporter.validateWorkspace();
+ return Status.OK_STATUS;
+ }
+ }.schedule();
+ }
+ }
+ }
+ }
+
+ @Override
+ public void stop(BundleContext context) throws Exception {
+ IEclipsePreferences node = InstanceScope.INSTANCE.getNode(ID);
+ if(node != null) {
+ node.removePreferenceChangeListener(fPomReporter);
+ ResourcesPlugin.getWorkspace().removeResourceChangeListener(fPomReporter);
+ }
+ super.stop(context);
+ }
+
+ /**
+ * Returns the shared instance.
+ */
+ public static RelEngPlugin getDefault() {
+ return plugin;
+ }
+
+ /**
+ * Returns the string from the plugin's resource bundle,
+ * or 'key' if not found.
+ */
+ public static String getResourceString(String key) {
+ ResourceBundle bundle= RelEngPlugin.getDefault().getResourceBundle();
+ try {
+ return bundle.getString(key);
+ } catch (MissingResourceException e) {
+ return key;
+ }
+ }
+
+ /**
+ * Returns the plugin's resource bundle,
+ */
+ public ResourceBundle getResourceBundle() {
+ return resourceBundle;
+ }
+ /**
+ * Convenience method for logging CoreExceptions to the plugin log
+ */
+ public static void log(CoreException e) {
+ log(e.getStatus().getSeverity(), e.getMessage(), e);
+ }
+
+ /**
+ * Log the given exception along with the provided message and severity indicator
+ */
+ public static void log(int severity, String message, Throwable e) {
+ log(new Status(severity, ID, 0, message, e));
+ }
+
+ /**
+ * Log the given exception as an error.
+ *
+ * @param e exception to log
+ */
+ public static void log(Throwable e){
+ log(new Status(IStatus.ERROR, ID, 0, e.getMessage(), e));
+ }
+
+ /**
+ * Log the given status. Do not use this method for the IStatus from a CoreException.
+ * Use<code>log(CoreException)</code> instead so the stack trace is not lost.
+ */
+ public static void log(IStatus status) {
+ getPlugin().getLog().log(status);
+ }
+ /**
+ * Returns the singleton plug-in instance.
+ *
+ * @return the plugin instance
+ */
+ public static RelEngPlugin getPlugin() {
+ // If the instance has not been initialized, we will wait.
+ // This can occur if multiple threads try to load the plugin at the same
+ // time (see bug 33825: http://bugs.eclipse.org/bugs/show_bug.cgi?id=33825)
+ while (plugin == null) {
+ try {
+ Thread.sleep(50);
+ } catch (InterruptedException e) {
+ // ignore and keep trying
+ }
+ }
+ return plugin;
+ }
+
+ /**
+ * Tells whether the given project is shared.
+ *
+ * @param project the project
+ * @return <code>true</code> if the project is shared
+ * @since 3.7
+ */
+ static boolean isShared(IProject project) {
+ Assert.isLegal(project != null);
+ if (!RepositoryProvider.isShared(project))
+ return false;
+
+ // Check for PDE's binary projects that also connect a provider to the project
+ RepositoryProvider provider= RepositoryProvider.getProvider(project);
+ return provider != null && !BINARY_REPOSITORY_PROVIDER_CLASS_NAME.equals(provider.getClass().getName());
+ }
+
+}
diff --git a/bundles/org.eclipse.releng.tools/src/org/eclipse/releng/tools/RemoveAllConsolesAction.java b/bundles/org.eclipse.releng.tools/src/org/eclipse/releng/tools/RemoveAllConsolesAction.java
new file mode 100644
index 0000000..f6df86a
--- /dev/null
+++ b/bundles/org.eclipse.releng.tools/src/org/eclipse/releng/tools/RemoveAllConsolesAction.java
@@ -0,0 +1,53 @@
+/*******************************************************************************
+ * Copyright (c) 2014, 2019 IBH SYSTEMS GmbH.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * IBH SYSTEMS GmbH - initial API and implementation
+ * Alexander Fedorov <alexander.fedorov@arsysop.ru> - Bug 548799
+ *******************************************************************************/
+package org.eclipse.releng.tools;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.jface.action.Action;
+import org.eclipse.jface.resource.ResourceLocator;
+import org.eclipse.releng.tools.AdvancedFixCopyrightAction.FixConsole;
+import org.eclipse.ui.console.ConsolePlugin;
+import org.eclipse.ui.console.IConsole;
+
+public class RemoveAllConsolesAction extends Action {
+ public RemoveAllConsolesAction() {
+ super(Messages.getString("RemoveAllConsolesAction.Text")); //$NON-NLS-1$
+ ResourceLocator.imageDescriptorFromBundle(RelEngPlugin.ID, "icons/full/elcl16/console_remall.png").ifPresent(d-> setImageDescriptor(d)); //$NON-NLS-1$
+ }
+
+ @Override
+ public void run() {
+ List<IConsole> consolesList = new ArrayList<>();
+
+ for (IConsole console : ConsolePlugin.getDefault().getConsoleManager()
+ .getConsoles()) {
+ if (console instanceof FixConsole) {
+ consolesList.add(console);
+ }
+ }
+
+ if (consolesList.isEmpty())
+ return;
+
+ IConsole[] consoles = new IConsole[consolesList.size()];
+ for (int i = 0; i < consoles.length; i++) {
+ consoles[i] = consolesList.get(i);
+ }
+
+ ConsolePlugin.getDefault().getConsoleManager().removeConsoles(consoles);
+ }
+}
diff --git a/bundles/org.eclipse.releng.tools/src/org/eclipse/releng/tools/RemoveConsoleAction.java b/bundles/org.eclipse.releng.tools/src/org/eclipse/releng/tools/RemoveConsoleAction.java
new file mode 100644
index 0000000..0e58cab
--- /dev/null
+++ b/bundles/org.eclipse.releng.tools/src/org/eclipse/releng/tools/RemoveConsoleAction.java
@@ -0,0 +1,36 @@
+/*******************************************************************************
+ * Copyright (c) 2014, 2019 IBH SYSTEMS GmbH.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * IBH SYSTEMS GmbH - initial API and implementation
+ * Alexander Fedorov <alexander.fedorov@arsysop.ru> - Bug 548799
+ *******************************************************************************/
+package org.eclipse.releng.tools;
+
+import org.eclipse.jface.action.Action;
+import org.eclipse.jface.resource.ResourceLocator;
+import org.eclipse.ui.console.ConsolePlugin;
+import org.eclipse.ui.console.IConsole;
+
+public class RemoveConsoleAction extends Action {
+
+ private final IConsole console;
+
+ public RemoveConsoleAction(IConsole console) {
+ super(Messages.getString("RemoveConsoleAction.Text")); //$NON-NLS-1$
+ ResourceLocator.imageDescriptorFromBundle(RelEngPlugin.ID, "icons/full/elcl16/console_rem.png").ifPresent(d-> setImageDescriptor(d)); //$NON-NLS-1$
+ this.console = console;
+ }
+
+ @Override
+ public void run() {
+ ConsolePlugin.getDefault().getConsoleManager().removeConsoles(new IConsole[]{console});
+ }
+}
diff --git a/bundles/org.eclipse.releng.tools/src/org/eclipse/releng/tools/RepositoryProviderCopyrightAdapter.java b/bundles/org.eclipse.releng.tools/src/org/eclipse/releng/tools/RepositoryProviderCopyrightAdapter.java
new file mode 100644
index 0000000..87b1865
--- /dev/null
+++ b/bundles/org.eclipse.releng.tools/src/org/eclipse/releng/tools/RepositoryProviderCopyrightAdapter.java
@@ -0,0 +1,57 @@
+/*******************************************************************************
+ * Copyright (c) 2008 IBM Corporation and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.releng.tools;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+
+/**
+ * This class allows the repository provider to plug into the Fix Copyright action
+ * in order to provide the last modified year for one or more files.
+ */
+public abstract class RepositoryProviderCopyrightAdapter {
+
+ private final IResource[] resources;
+
+ public RepositoryProviderCopyrightAdapter(IResource[] resources) {
+ this.resources = resources;
+ }
+
+ /**
+ * Initialize the adapter. This call is provided to support the batch fetching
+ * of the last modifies year for all the files of interest.
+ * @param monitor a progress monitor
+ */
+ public abstract void initialize(IProgressMonitor monitor) throws CoreException;
+
+ /**
+ * Return the last modified year for the given file or -1 if the
+ * last modified year could not be determined.
+ * @param file the file
+ * @param monitor a progress monitor
+ * @return the last modified year or -1
+ * @throws CoreException
+ */
+ public abstract int getLastModifiedYear(IFile file, IProgressMonitor monitor) throws CoreException;
+
+ /**
+ * Return the resources that are involved in this operation
+ * @return the resources
+ */
+ public IResource[] getResources() {
+ return resources;
+ }
+}
diff --git a/bundles/org.eclipse.releng.tools/src/org/eclipse/releng/tools/ShellMakeFile.java b/bundles/org.eclipse.releng.tools/src/org/eclipse/releng/tools/ShellMakeFile.java
new file mode 100644
index 0000000..c04af16
--- /dev/null
+++ b/bundles/org.eclipse.releng.tools/src/org/eclipse/releng/tools/ShellMakeFile.java
@@ -0,0 +1,107 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2014 IBM Corporation and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ * Martin Oberhuber (Wind River) - [235572] detect existing comments in bat files
+ * Leo Ufimtsev adding fix of : Gunnar Wagenknecht (wagenknecht) - [276253] detect '#!/bin/sh' header.
+ *******************************************************************************/
+package org.eclipse.releng.tools;
+
+import java.io.IOException;
+import java.util.regex.Pattern;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.IDocument;
+
+
+public class ShellMakeFile extends SourceFile {
+
+ public ShellMakeFile(IFile file) {
+ super(file);
+ }
+
+ //Optional Whitespace, #, optional whitespace, then at least 2 non-word chars repeated till EOL
+ private static Pattern p = Pattern.compile("\\s*#\\s*\\W{2,}\\s*"); //$NON-NLS-1$
+
+ @Override
+ public boolean isCommentStart(String aLine) {
+ return p.matcher(aLine).matches();
+ }
+
+ @Override
+ public boolean isCommentEnd(String aLine, String commentStartString) {
+ String s = commentStartString.trim();
+ s = s.substring(s.length()-2);
+ return aLine.trim().endsWith(s);
+ }
+
+ @Override
+ public String getCommentStart() {
+ return "#*"; //unused, Pattern matcher above will be used instead //$NON-NLS-1$
+ }
+
+ @Override
+ public String getCommentEnd() {
+ return "**"; //unused, Pattern matcher above will be used instead //$NON-NLS-1$
+ }
+
+ @Override
+ public int getFileType() {
+ return CopyrightComment.SHELL_MAKE_COMMENT;
+ }
+
+ @Override
+ protected void doInsert(final String comment, IDocument document) throws BadLocationException, IOException {
+ // find insert offset (we must skip instructions)
+ int insertOffset = findInsertOffset(document);
+
+ // insert comment
+ document.replace(insertOffset, 0, comment);
+ }
+
+ private int findInsertOffset(IDocument document) throws BadLocationException {
+ boolean inInstruction = false;
+ int insertOffset = 0;
+
+ for (int offset = 0; offset < document.getLength(); offset++) {
+ char c = document.getChar(offset);
+
+ // also look at next char
+ char c2 = ((offset + 1) < document.getLength()) ? document.getChar(offset + 1) : 0;
+
+ // look for line ending
+ if (inInstruction) {
+ if (c == '\n' && c2 == '\r' || c == '\r' && c2 == '\n') {
+ insertOffset = offset + 2;
+ break; // done
+ } else if (c == '\n') {
+ insertOffset = offset + 1;
+ break; // done
+ } else {
+ // continue looking for ending
+ continue;
+ }
+ }
+
+ // next chars must start an instruction
+ if (c == '#' && c2 == '!') {
+ inInstruction = true;
+ offset++; // don't need to analyse c2 again
+ continue;
+ } else {
+ // if it's something else, we can stop seeking
+ break;
+ }
+ }
+ return insertOffset;
+ }
+}
diff --git a/bundles/org.eclipse.releng.tools/src/org/eclipse/releng/tools/SourceFile.java b/bundles/org.eclipse.releng.tools/src/org/eclipse/releng/tools/SourceFile.java
new file mode 100644
index 0000000..0a546da
--- /dev/null
+++ b/bundles/org.eclipse.releng.tools/src/org/eclipse/releng/tools/SourceFile.java
@@ -0,0 +1,328 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2016 IBM Corporation and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ * Martin Oberhuber (Wind River) - [235572] detect existing comments in bat files
+ * Leo Ufimtsev lufimtse@redhat.com [276257] fix xml issues.
+ *******************************************************************************/
+package org.eclipse.releng.tools;
+
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.IOException;
+import java.io.StringReader;
+import java.io.StringWriter;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.eclipse.core.filebuffers.FileBuffers;
+import org.eclipse.core.filebuffers.ITextFileBuffer;
+import org.eclipse.core.filebuffers.ITextFileBufferManager;
+import org.eclipse.core.filebuffers.LocationKind;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.TextUtilities;
+import org.eclipse.osgi.util.NLS;
+
+
+/**
+ * @author droberts
+ */
+public abstract class SourceFile {
+
+ IFile file;
+ List<BlockComment> comments = new ArrayList<>();
+ StringWriter contents = new StringWriter();
+ private ITextFileBufferManager textFileBufferManager;
+ private String lineDelimiter;
+
+ public static SourceFile createFor(IFile file) {
+ String extension = file.getFileExtension();
+ if (extension != null) {
+ extension = extension.toLowerCase();
+ if (extension.equals("java")) { //$NON-NLS-1$
+ return new JavaFile(file);
+ } else if (extension.equals("c") || extension.equals("h") || extension.equals("rc") || extension.equals("cc") || extension.equals("cpp")) { //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$
+ return new CFile(file);
+ } else if (extension.equals("properties")) { //$NON-NLS-1$
+ return new PropertiesFile(file);
+ } else if (extension.equals("sh") || extension.equals("csh") || extension.equals("mak") || extension.equals("pl") || extension.equals("tcl")) { //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$
+ return new ShellMakeFile(file);
+ } else if (extension.equals("bat")) { //$NON-NLS-1$
+ return new BatFile(file);
+ } else if (extension.equals("js")) { //$NON-NLS-1$
+ return new JavaScriptFile(file);
+ } else if (extension.equals("xml")) { //$NON-NLS-1$
+ //[276257] re-enable xml support.
+ return new XmlFile(file);
+ }
+ }
+ return null;
+ }
+
+ public SourceFile(IFile file) {
+ super();
+ this.file = file;
+ initialize();
+ }
+
+ /**
+ * Test if the given line marks the start of a potential Copyright comment.
+ * Can be overridden in subclasses to perform advanced detection.
+ * @param aLine a line of text to check
+ * @return <code>true</code> if the line can mark a copyright comment start.
+ * @since 3.5
+ */
+ public boolean isCommentStart(String aLine) {
+ return aLine.trim().startsWith(getCommentStart());
+ }
+ /**
+ * Test if the given line marks the end of a potential Copyright comment.
+ * Can be overridden in subclasses to perform advanced detection.
+ * @param aLine a line of text to check
+ * @param commentStartString the line which started the block comment
+ * @return <code>true</code> if the line can mark a copyright comment end.
+ * @since 3.5
+ */
+ public boolean isCommentEnd(String aLine, String commentStartString) {
+ return aLine.trim().endsWith(getCommentEnd());
+ }
+ public abstract String getCommentStart();
+ public abstract String getCommentEnd();
+
+
+ private void initialize() {
+ textFileBufferManager= FileBuffers.createTextFileBufferManager();
+ try {
+
+ IDocument document;
+ try {
+ //connect file buffer.
+ ITextFileBuffer fileBuffer = openFileBuffer();
+ if (fileBuffer == null)
+ return;
+
+ document = fileBuffer.getDocument();
+ } finally {
+ //Close file buffer.
+ closeFileBuffer();
+ }
+
+ lineDelimiter= TextUtilities.getDefaultLineDelimiter(document);
+ try (BufferedReader aReader = new BufferedReader(new StringReader(document.get()))) {
+ String aLine = aReader.readLine();
+ String comment = ""; //$NON-NLS-1$
+ BufferedWriter contentsWriter = new BufferedWriter(contents);
+ int lineNumber = 0;
+ int commentStart = 0;
+ int commentEnd = 0;
+ boolean inComment = false;
+ String commentStartString = ""; //$NON-NLS-1$
+
+ // Loop over the document, extract the comment.
+ while (aLine != null) {
+ contentsWriter.write(aLine);
+ contentsWriter.newLine();
+ if (!inComment && isCommentStart(aLine)) {
+ // start saving comment
+ inComment = true;
+ commentStart = lineNumber;
+ commentStartString = aLine;
+ }
+
+ if (inComment) {
+ comment = comment + aLine + lineDelimiter;
+
+ if (isCommentEnd(aLine, commentStartString) && commentStart != lineNumber) {
+ // stop saving comment
+ inComment = false;
+ commentEnd = lineNumber;
+ String commentEndString = aLine.trim();
+ commentEndString = commentEndString.substring(commentEndString.length() - 2);
+ BlockComment aComment = new BlockComment(commentStart, commentEnd, comment.toString(),
+ commentStartString, commentEndString);
+ comments.add(aComment);
+ comment = ""; //$NON-NLS-1$
+ commentStart = 0;
+ commentEnd = 0;
+ commentStartString = ""; //$NON-NLS-1$
+ }
+ }
+
+ aLine = aReader.readLine();
+ lineNumber++;
+ }
+
+ }
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ * @return BlockComment
+ */
+ public BlockComment firstBlockComment() {
+ if (comments.isEmpty()) {
+ return null;
+ } else {
+ return comments.get(0);
+ }
+ }
+
+ /**
+ * If this method is called, <b>ensure</b> that you close the file buffer after usage. <br>
+ * Otherwise you leave a memory leak. {@link #closeFileBuffer()}
+ * {@code textFileBufferManager.disconnect(file.getFullPath(), LocationKind.IFILE, null); }
+ * @return
+ */
+ private ITextFileBuffer openFileBuffer() {
+ try {
+ textFileBufferManager.connect(file.getFullPath(), LocationKind.IFILE, null);
+ } catch (CoreException e) {
+ e.printStackTrace();
+ return null;
+ }
+
+ ITextFileBuffer fileBuffer= textFileBufferManager.getTextFileBuffer(file.getFullPath(), LocationKind.IFILE);
+ if (fileBuffer != null)
+ return fileBuffer;
+
+ System.err.println(NLS.bind(Messages.getString("SourceFile.0"), file.getFullPath())); //$NON-NLS-1$
+ return null;
+ }
+
+ /**
+ * This should be called before ending a file operation. <br>
+ * Companion function to getFileBuffer();
+ */
+ private void closeFileBuffer() {
+ try {
+ textFileBufferManager.disconnect(file.getFullPath(), LocationKind.IFILE, null);
+ } catch (CoreException e) {
+ e.printStackTrace();
+ }
+ }
+
+
+ /**
+ * Given the copyright comment, this method inserts it into the right place in the file.
+ *
+ * @param copyRightComment the complete comment that will be inserted.
+ */
+ public void insert(String copyRightComment) {
+ try {
+ ITextFileBuffer fileBuffer= openFileBuffer();
+ if (fileBuffer == null)
+ return;
+
+ IDocument document= fileBuffer.getDocument();
+ doInsert(copyRightComment, document);
+ fileBuffer.commit(null, false);
+ } catch (BadLocationException e) {
+ e.printStackTrace();
+ } catch (CoreException e) {
+ e.printStackTrace();
+ } catch (IOException e) {
+ e.printStackTrace();
+ } finally {
+ closeFileBuffer();
+ }
+ }
+
+ protected void doInsert(String comment, IDocument document) throws BadLocationException, CoreException, IOException {
+ document.replace(0, 0, comment);
+ }
+
+ /**
+ * @return BlockComment
+ */
+ public BlockComment getFirstCopyrightComment() {
+ Iterator<BlockComment> anIterator = comments.iterator();
+ while (anIterator.hasNext()) {
+ BlockComment aComment = anIterator.next();
+ if (aComment.isCopyright()) {
+ return aComment;
+ }
+ }
+
+ return null;
+ }
+
+ /**
+ * @param aCommet
+ * @param newCopyrightComment Comment to be inserted.
+ */
+ public void replace(BlockComment aComment, String newCopyrightComment) {
+
+
+ try {
+ ITextFileBuffer fileBuffer = openFileBuffer();
+ if (fileBuffer == null)
+ return;
+
+ IDocument document= fileBuffer.getDocument();
+
+ IRegion startLine= document.getLineInformation(aComment.start);
+ IRegion endLine= document.getLineInformation(aComment.end + 1);
+ document.replace(startLine.getOffset(), endLine.getOffset() - startLine.getOffset(), newCopyrightComment);
+
+ fileBuffer.commit(null, false);
+
+ } catch (BadLocationException e) {
+ e.printStackTrace();
+ } catch (CoreException e) {
+ e.printStackTrace();
+ } finally {
+ closeFileBuffer();
+ try {
+ FileBuffers.getTextFileBufferManager().disconnect(file.getFullPath(), LocationKind.IFILE, null);
+ } catch (CoreException e) {
+ e.printStackTrace();
+ return;
+ }
+ }
+ }
+
+ /**
+ * @return boolean
+ */
+ public boolean hasMultipleCopyrights() {
+ int count = 0;
+ Iterator<BlockComment> anIterator = comments.iterator();
+ while (anIterator.hasNext()) {
+ BlockComment aComment = anIterator.next();
+ if (aComment.isCopyright()) {
+ count++;
+ }
+ if (count > 1) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public abstract int getFileType();
+
+ /**
+ * Returns the line delimiter.
+ *
+ * @return the line delimiter
+ * @since 3.7
+ */
+ public String getLineDelimiter() {
+ return lineDelimiter;
+ }
+}
\ No newline at end of file
diff --git a/bundles/org.eclipse.releng.tools/src/org/eclipse/releng/tools/XmlFile.java b/bundles/org.eclipse.releng.tools/src/org/eclipse/releng/tools/XmlFile.java
new file mode 100644
index 0000000..26e0123
--- /dev/null
+++ b/bundles/org.eclipse.releng.tools/src/org/eclipse/releng/tools/XmlFile.java
@@ -0,0 +1,262 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2014 Gunnar Wagenknecht and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * Gunnar Wagenknecht - initial API and implementation
+ * Leo Ufimtsev lufimtse@redhat.com - fixed xml header issues.
+ * https://bugs.eclipse.org/381147
+ * https://bugs.eclipse.org/bugs/show_bug.cgi?id=276257 //used.
+ *
+ *
+ *******************************************************************************/
+package org.eclipse.releng.tools;
+
+import java.io.IOException;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.IDocument;
+
+
+/*
+ * Test notes:
+ * [x] Empty Document
+ * [x] Empty Document with XML header
+ * [x] Document with content, no XML header.
+ * [x] Document with XML header and content on 2nd line
+ * [x] Document with XML header, copyright on first line with content on first line.
+ * [x] Document with XML header, content on the first line that doesn't close properly.
+ * Example:
+ * <?xml version="1.0" encoding="UTF-8"?><fragment><extension
+ * //Copy-right comment is executed correctly, '<fragment ..' is put onto new line.
+ *
+ * [x] Document with XML header, copyright on 2nd line, stuff.
+ * [x] test with non-IBM header.
+ * 2014.07.15 tested.
+ *
+ */
+
+/**
+ * <h2> XML File handler. </h2>
+ *
+ * <p> This class deals with the special case of 'xml' files.</p>
+ *
+ * <p> * If an xml header exists for example: {@code <?xml version="1.0" encoding="UTF-8"?> } <br>
+ * then the copyright comment is inserted exactly at the end of it, on a new line, <br>
+ * moving any content down below the xml header. </p>
+ *
+ * <p> It does take into account multiple headers also. e.g:<br>
+ * {@code <?xml version="1.0" encoding="UTF-8"?>}<br>
+ {@code <?eclipse version="3.2"?> }<br>
+ In this case, the copy right comment is inserted below the last header. </p>
+
+ * <p> If no xml header exists, then the copyright comment is inserted at the top of the xml file.<p>
+ */
+public class XmlFile extends SourceFile {
+
+ public XmlFile(IFile file) {
+ super(file);
+ }
+
+ /**
+ * Deals with the fact that XML files can start with a header and the copy <br>
+ * right comment can start at the end of the header. <br>
+ *
+ * <p> For example: {@code <?xml?> <!-- } </p>
+ *
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean isCommentStart(String aLine) {
+ return aLine.trim().contains(getCommentStart());
+
+ //Note, above is a bit different from parent, contains/startswithd:
+ //Parent:
+ //return aLine.trim().STARTSWITH(getCommentStart());
+
+ }
+
+ /**
+ * Deals with the fact that XML files can end with a header and the copy <br>
+ * right comment can start at the end of the header. <br>
+ *
+ * <p> For exaple: {@code <?xml?> <!-- } </p>
+ *
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean isCommentEnd(String aLine, String commentStartString) {
+ return aLine.trim().contains(getCommentEnd());
+ //Similarly, uses 'contains' instead of 'starts with'
+ }
+
+ @Override
+ public String getCommentStart() {
+ return "<!--"; //$NON-NLS-1$
+ }
+
+ @Override
+ public String getCommentEnd() {
+ return "-->"; //$NON-NLS-1$
+ }
+
+ @Override
+ public int getFileType() {
+ return CopyrightComment.XML_COMMENT;
+ }
+
+ /**
+ * Given the new constructed copyright comment, it inserts it into the the document.
+ *
+ * <p> Note, this is only called if inserting an actual comment.<br>
+ * If only updating the year, this method is not called. </p>
+ * @see org.eclipse.releng.tools.SourceFile#doInsert(java.lang.String, org.eclipse.jface.text.IDocument)
+ */
+ @Override
+ protected void doInsert(final String comment, IDocument document) throws BadLocationException, IOException {
+
+ //----------------- XML COMMENT CLEAN UP
+ // XML comments need extra-tidy up because we need to consider the existance of an XML header
+ String tidyComment = comment.trim();
+
+ //Append new-line at the end for cleaner look.
+ tidyComment += '\n';
+
+ // check for existance of an xml header (<?xml)
+ // If so, put the comment 'below' it.
+ // example:
+ //<?xml .... ?>
+ //<--
+ // comment start....
+ if (containsXmlEncoding(document)) {
+ // If encoding is present, pre-append a new line.
+ tidyComment = '\n' + tidyComment;
+ }
+
+ //------------------ COMMENT INSERT
+ // find insert offset (we must skip instructions)
+ int insertOffset = findInsertOffset(document);
+
+ // insert comment
+ document.replace(insertOffset, 0, tidyComment);
+ }
+
+ /**
+ * Given the document, find the place after the xml header to insert the comment.
+ * @param document
+ * @return
+ * @throws BadLocationException
+ */
+ private int findInsertOffset(IDocument document) throws BadLocationException {
+ boolean inInstruction = false;
+ int insertOffset = 0;
+
+ for (int offset = 0; offset < document.getLength(); offset++) {
+ char c = document.getChar(offset);
+
+ // ignore whitespace and new lines
+ if(Character.isWhitespace(c)) {
+ // we update the offset to ignore whitespaces
+ // after instruction ends
+ insertOffset = offset;
+ continue;
+ }
+
+ // look at next char
+ char c2 = ((offset+1) < document.getLength()) ? document.getChar(offset+1) : 0;
+
+ // look for instruction ending
+ if(inInstruction) {
+ if(c == '?' && c2 == '>') {
+
+ //Offset is '+2' not '+1' because of '?' in '?>'
+ insertOffset = offset + 2;
+ inInstruction = false;
+ offset++; // don't need to analyse c2 again
+ // we continue in case there are more instructions
+ continue;
+ } else {
+ // look for ending
+ continue;
+ }
+ }
+
+ // next chars must start an instruction
+ if(c == '<' && c2 =='?') {
+ inInstruction = true;
+ offset++; // don't need to analyse c2 again
+ continue;
+ } else {
+ // if it's something else, we can stop seeking
+ break;
+ }
+ }
+ return insertOffset;
+ }
+
+ /**
+ * Find out if an XML document contains an XML meta header.
+ *
+ * <p> XML documents <b> sometimes </b> contain a header specifying various attributes such as <br>
+ * version, encoding etc... </p>
+ *
+ * <p> Examples include: <br>
+ * {@literal <?xml version="1.0" encoding="UTF-8"?> }<br>
+ * {@literal<?xml version="1.0" encoding="UTF-8" standalone="no"?> } <br>
+ * {@literal <?xml version="1.0" ?> } </p>
+ *
+ * @param xmlDoc
+ * @return True if it contains a header.
+ * @throws BadLocationException
+ */
+ public boolean containsXmlEncoding(IDocument xmlDoc) throws BadLocationException {
+
+ //XML attribute headers *must* reside on the first line.
+ //We identify if the xml document contains a header by checking the first tag and see if it starts with: <?xml
+
+ //-- Check to see if the document is long enough to contain the minimum '<?xml?>' tag
+ if (xmlDoc.getLength() < 7) {
+ return false;
+ }
+
+ for (int offset = 0; offset < xmlDoc.getLength(); offset++) {
+
+ //Read Char.
+ char c = xmlDoc.getChar(offset);
+
+ // ignore whitespace and new lines
+ if(Character.isWhitespace(c)) {
+ continue;
+ }
+
+ //Once we've found the first '<', check that it's a '<?xml'
+ if (c == '<') {
+
+ //check that document is long enough to close a header if we are to read it: '<?xml
+ if ((offset + 4) < xmlDoc.getLength()) {
+
+ //Read "<?xml" equivalent.
+ String xmlTag = "" + c + xmlDoc.getChar(offset+1) + xmlDoc.getChar(offset+2) + //$NON-NLS-1$
+ xmlDoc.getChar(offset+3) + xmlDoc.getChar(offset+4);
+
+ if ( xmlTag.compareToIgnoreCase("<?xml") == 0) { //$NON-NLS-1$
+ return true;
+ } else {
+ return false;
+ }
+ }
+ }
+ }
+
+ //if parsing an empty xml document, return false.
+ return false;
+ }
+
+}
diff --git a/bundles/org.eclipse.releng.tools/src/org/eclipse/releng/tools/git/GitCopyrightAdapter.java b/bundles/org.eclipse.releng.tools/src/org/eclipse/releng/tools/git/GitCopyrightAdapter.java
new file mode 100644
index 0000000..2a3f770
--- /dev/null
+++ b/bundles/org.eclipse.releng.tools/src/org/eclipse/releng/tools/git/GitCopyrightAdapter.java
@@ -0,0 +1,125 @@
+/*******************************************************************************
+ * Copyright (c) 2010, 2019 AGETO Service GmbH and others.
+ * All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License 2.0 which accompanies this distribution,
+t https://www.eclipse.org/legal/epl-2.0/
+t
+t SPDX-License-Identifier: EPL-2.0.
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation of CVS adapter
+ * Gunnar Wagenknecht - initial API and implementation of Git adapter
+ * IBM Corporation - ongoing maintenance
+ *******************************************************************************/
+package org.eclipse.releng.tools.git;
+
+import java.io.IOException;
+import java.util.Calendar;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.egit.core.project.RepositoryMapping;
+import org.eclipse.jgit.lib.Constants;
+import org.eclipse.jgit.lib.ObjectId;
+import org.eclipse.jgit.lib.Repository;
+import org.eclipse.jgit.revwalk.RevCommit;
+import org.eclipse.jgit.revwalk.RevWalk;
+import org.eclipse.jgit.treewalk.filter.AndTreeFilter;
+import org.eclipse.jgit.treewalk.filter.PathFilter;
+import org.eclipse.jgit.treewalk.filter.TreeFilter;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.releng.tools.RelEngPlugin;
+import org.eclipse.releng.tools.RepositoryProviderCopyrightAdapter;
+
+public class GitCopyrightAdapter extends RepositoryProviderCopyrightAdapter {
+
+ private static String filterString = "copyright"; // lowercase //$NON-NLS-1$
+
+ /**
+ * Bugs to be filtered because they modified a lot of files in a trivial way
+ * and should not change the copyright year.
+ * <p>
+ * If the last commit message for a checked file starts with one of these
+ * strings the year will not be modified for this file.
+ * </p>
+ */
+ private static final String[] FILTER_BUGS = new String[] {
+ "Bug 535802", // license version update //$NON-NLS-1$
+ "Bug 543933", // build javadocs with Java 11 //$NON-NLS-1$
+ };
+
+ public GitCopyrightAdapter(IResource[] resources) {
+ super(resources);
+ }
+
+ @Override
+ public int getLastModifiedYear(IFile file, IProgressMonitor monitor) throws CoreException {
+ final RepositoryMapping mapping = RepositoryMapping.getMapping(file);
+ if (mapping != null) {
+ final Repository repo = mapping.getRepository();
+ if (repo != null) {
+ try (RevWalk walk = new RevWalk(repo)) {
+ final ObjectId start = repo.resolve(Constants.HEAD);
+
+ walk.setTreeFilter(AndTreeFilter.create(PathFilter.create(mapping.getRepoRelativePath(file)),
+ TreeFilter.ANY_DIFF));
+ walk.markStart(walk.lookupCommit(start));
+ // dramatically increase performance for this use case
+ // see https://bugs.eclipse.org/bugs/show_bug.cgi?id=468850#c17
+ walk.setRewriteParents(false);
+ final RevCommit commit = walk.next();
+ if (commit != null) {
+ if (filterString != null
+ && commit.getFullMessage().toLowerCase().indexOf(filterString) != -1) {
+ // the last update was a copyright check in -
+ // ignore
+ return 0;
+ }
+
+ for (String bugId : FILTER_BUGS) {
+ if (commit.getShortMessage().startsWith(bugId)) {
+ return 0;
+ }
+ }
+
+ boolean isSWT = file.getProject().getName().startsWith("org.eclipse.swt"); //$NON-NLS-1$
+ String logComment = commit.getFullMessage();
+ if (isSWT && (logComment.indexOf("restore HEAD after accidental deletion") != -1 //$NON-NLS-1$
+ || logComment.indexOf("fix permission of files") != -1)) { //$NON-NLS-1$
+ // ignore commits with above comments
+ return 0;
+ }
+
+ boolean isPlatform = file.getProject().getName().equals("eclipse.platform"); //$NON-NLS-1$
+ if (isPlatform && (logComment.indexOf("Merge in ant and update from origin/master") != -1 //$NON-NLS-1$
+ || logComment.indexOf(
+ "Fixed bug 381684: Remove update from repository and map files") != -1)) { //$NON-NLS-1$
+ // ignore commits with above comments
+ return 0;
+ }
+
+ final Calendar calendar = Calendar.getInstance();
+ calendar.setTimeInMillis(0);
+ calendar.add(Calendar.SECOND, commit.getCommitTime());
+ return calendar.get(Calendar.YEAR);
+ }
+ } catch (final IOException e) {
+ throw new CoreException(new Status(IStatus.ERROR, RelEngPlugin.ID, 0,
+ NLS.bind("An error occured when processing {0}", file.getName()), e)); //$NON-NLS-1$
+ }
+ }
+ }
+ return -1;
+ }
+
+ @Override
+ public void initialize(IProgressMonitor monitor) throws CoreException {
+ }
+
+}
diff --git a/bundles/org.eclipse.releng.tools/src/org/eclipse/releng/tools/git/GitCopyrightAdapterFactory.java b/bundles/org.eclipse.releng.tools/src/org/eclipse/releng/tools/git/GitCopyrightAdapterFactory.java
new file mode 100644
index 0000000..9b38c9e
--- /dev/null
+++ b/bundles/org.eclipse.releng.tools/src/org/eclipse/releng/tools/git/GitCopyrightAdapterFactory.java
@@ -0,0 +1,53 @@
+/*******************************************************************************
+ * Copyright (c) 2010, 2016 AGETO Service GmbH and others.
+ * All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License 2.0 which accompanies this distribution,
+t https://www.eclipse.org/legal/epl-2.0/
+t
+t SPDX-License-Identifier: EPL-2.0.
+ *
+ * Contributors:
+ * Gunnar Wagenknecht - initial API and implementation
+ * IBM Corporation - ongoing maintenance
+ *******************************************************************************/
+package org.eclipse.releng.tools.git;
+
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.IAdapterFactory;
+import org.eclipse.releng.tools.IRepositoryProviderCopyrightAdapterFactory;
+import org.eclipse.releng.tools.RepositoryProviderCopyrightAdapter;
+import org.eclipse.team.core.RepositoryProviderType;
+
+public class GitCopyrightAdapterFactory implements IAdapterFactory,
+ IRepositoryProviderCopyrightAdapterFactory {
+
+ private static final Class<?>[] ADAPTER_LIST = new Class[] { IRepositoryProviderCopyrightAdapterFactory.class };
+
+ @Override
+ public <T> T getAdapter(Object adaptableObject, Class<T> adapterType) {
+ if (IRepositoryProviderCopyrightAdapterFactory.class
+ .equals(adapterType)) {
+ return adapterType.cast(getGitCopyrightAdapter(adaptableObject));
+ }
+ return null;
+ }
+
+ private Object getGitCopyrightAdapter(Object adaptableObject) {
+ if (!(adaptableObject instanceof RepositoryProviderType))
+ return null;
+ return this;
+ }
+
+ @Override
+ public Class<?>[] getAdapterList() {
+ return ADAPTER_LIST;
+ }
+
+ @Override
+ public RepositoryProviderCopyrightAdapter createAdapater(
+ IResource[] resources) {
+ return new GitCopyrightAdapter(resources);
+ }
+}
diff --git a/bundles/org.eclipse.releng.tools/src/org/eclipse/releng/tools/messages.properties b/bundles/org.eclipse.releng.tools/src/org/eclipse/releng/tools/messages.properties
new file mode 100644
index 0000000..5c1ac7e
--- /dev/null
+++ b/bundles/org.eclipse.releng.tools/src/org/eclipse/releng/tools/messages.properties
@@ -0,0 +1,53 @@
+###############################################################################
+# Copyright (c) 2003, 2019 IBM Corporation and others.
+#
+# This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License 2.0
+# which accompanies this distribution, and is available at
+# https://www.eclipse.org/legal/epl-2.0/
+#
+# SPDX-License-Identifier: EPL-2.0
+#
+# Contributors:
+# IBM Corporation - initial API and implementation
+###############################################################################
+RelEngPlugin.0=POM version validation
+RelEngPlugin.1=org.eclipse.releng
+RelEngPlugin.2=maps
+RelEngPlugin.3=RelEngPluginResources
+RelEngPreferenceInitializer.0=Copyright (c) ${date} IBM Corporation and others.\n\nThis program and the accompanying materials\nare made available under the terms of the Eclipse Public License 2.0\nwhich accompanies this distribution, and is available at\nhttps://www.eclipse.org/legal/epl-2.0/\n\nSPDX-License-Identifier: EPL-2.0\n\nContributors:\n IBM Corporation - initial API and implementation
+RemoveConsoleAction.Text=Remove
+RemoveAllConsolesAction.Text=Remove All
+CopyrightPreferencePage.0=Use "${date}" to substitute in "creation_year, revision_year"
+CopyrightPreferencePage.1=Default creation year:
+CopyrightPreferencePage.2=Replace all existing copyright comments with this copyright template
+CopyrightPreferencePage.4=Skip over properties files
+CopyrightPreferencePage.5=Copyright template
+CopyrightPreferencePage.6=Default year must be a positive number
+CopyrightPreferencePage.7=Default revision year:
+CopyrightPreferencePage.8=Always use default revision year instead of repository lookup
+CopyrightPreferencePage.9=Skip over XML files
+SourceFile.0=The file buffer could not be acquired for: {0}
+AdvancedFixCopyrightAction.0=Fix Copyrights
+AdvancedFixCopyrightAction.1=Fixing copyrights
+AdvancedFixCopyrightAction.9=Errors occurred during the operation. Consult the error log for details
+AdvancedFixCopyrightAction.10=The following errors occurred while fixing copyrights
+AdvancedFixCopyrightAction.11=The selected resources do not all belong to the same repository provider
+AdvancedFixCopyrightAction.12=Copyright adapter could not be found for {0}
+AdvancedFixCopyrightAction.13=File has no extension. File UNCHANGED.
+AdvancedFixCopyrightAction.14=Multiple copyrights found. File UNCHANGED.
+AdvancedFixCopyrightAction.15=File is licensed under IBM EPL. Revision year may be updated.
+AdvancedFixCopyrightAction.16=Could not interpret copyright comment. File UNCHANGED.
+AdvancedFixCopyrightAction.17=The year could not be determined for {0}
+AdvancedFixCopyrightAction.18=Last commit was copyright change. File UNCHANGED.
+AdvancedFixCopyrightAction.19=Old copyright not at start of file, new copyright replaces old in same location
+AdvancedFixCopyrightAction.20=Failed to create internal source file for proccessing the file
+AdvancedFixCopyrightAction.21=Failed to find the first year in the copyright heading.
+AdvancedFixCopyrightAction.22=Initializing...
+AdvancedFixCopyrightAction.2=Start Fixing Copyrights
+AdvancedFixCopyrightAction.3=Resources selected: {0}
+AdvancedFixCopyrightAction.4=Fixing copyrights...
+AdvancedFixCopyrightAction.5=None of the selected resources is shared in a team repository
+AdvancedFixCopyrightAction.6=Fixing copyrights for {0}
+AdvancedFixCopyrightAction.7=Done Fixing Copyrights
+AdvancedFixCopyrightAction.8=Total time: {0} ms
diff --git a/bundles/org.eclipse.releng.tools/src/org/eclipse/releng/tools/preferences/ConfigurationBlock.java b/bundles/org.eclipse.releng.tools/src/org/eclipse/releng/tools/preferences/ConfigurationBlock.java
new file mode 100644
index 0000000..a8e2404
--- /dev/null
+++ b/bundles/org.eclipse.releng.tools/src/org/eclipse/releng/tools/preferences/ConfigurationBlock.java
@@ -0,0 +1,170 @@
+/*******************************************************************************
+ * Copyright (c) 2013, 2016 IBM Corporation and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.releng.tools.preferences;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.FocusEvent;
+import org.eclipse.swt.events.FocusListener;
+import org.eclipse.swt.events.MouseAdapter;
+import org.eclipse.swt.events.MouseEvent;
+import org.eclipse.swt.events.MouseListener;
+import org.eclipse.swt.events.MouseMoveListener;
+import org.eclipse.swt.events.MouseTrackAdapter;
+import org.eclipse.swt.events.PaintEvent;
+import org.eclipse.swt.events.PaintListener;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.graphics.Rectangle;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.widgets.Combo;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Label;
+
+/**
+ * General functions useful to all widgets that create preference blocks
+ *
+ * @since 3.8
+ */
+public abstract class ConfigurationBlock {
+
+ private static final int HIGHLIGHT_FOCUS = SWT.COLOR_WIDGET_DARK_SHADOW;
+ private static final int HIGHLIGHT_MOUSE = SWT.COLOR_WIDGET_NORMAL_SHADOW;
+ private static final int HIGHLIGHT_NONE = SWT.NONE;
+
+ protected void addHighlight(final Composite parent, final Label labelControl, final Combo comboBox) {
+ comboBox.addFocusListener(new FocusListener() {
+ @Override
+ public void focusLost(FocusEvent e) {
+ highlight(parent, labelControl, comboBox, HIGHLIGHT_NONE);
+ }
+ @Override
+ public void focusGained(FocusEvent e) {
+ highlight(parent, labelControl, comboBox, HIGHLIGHT_FOCUS);
+ }
+ });
+
+ MouseTrackAdapter labelComboListener= new MouseTrackAdapter() {
+ @Override
+ public void mouseEnter(MouseEvent e) {
+ highlight(parent, labelControl, comboBox, comboBox.isFocusControl() ? HIGHLIGHT_FOCUS : HIGHLIGHT_MOUSE);
+ }
+ @Override
+ public void mouseExit(MouseEvent e) {
+ if (! comboBox.isFocusControl())
+ highlight(parent, labelControl, comboBox, HIGHLIGHT_NONE);
+ }
+ };
+ comboBox.addMouseTrackListener(labelComboListener);
+ labelControl.addMouseTrackListener(labelComboListener);
+
+ class MouseMoveTrackListener extends MouseTrackAdapter implements MouseMoveListener, MouseListener {
+ @Override
+ public void mouseExit(MouseEvent e) {
+ if (! comboBox.isFocusControl())
+ highlight(parent, labelControl, comboBox, HIGHLIGHT_NONE);
+ }
+ @Override
+ public void mouseMove(MouseEvent e) {
+ int color= comboBox.isFocusControl() ? HIGHLIGHT_FOCUS : isAroundLabel(e) ? HIGHLIGHT_MOUSE : HIGHLIGHT_NONE;
+ highlight(parent, labelControl, comboBox, color);
+ }
+ @Override
+ public void mouseDown(MouseEvent e) {
+ if (isAroundLabel(e))
+ comboBox.setFocus();
+ }
+ @Override
+ public void mouseDoubleClick(MouseEvent e) {
+ // not used
+ }
+ @Override
+ public void mouseUp(MouseEvent e) {
+ // not used
+ }
+ private boolean isAroundLabel(MouseEvent e) {
+ int lx= labelControl.getLocation().x;
+ Rectangle c= comboBox.getBounds();
+ int x= e.x;
+ int y= e.y;
+ boolean isAroundLabel= lx - 5 < x && x < c.x && c.y - 2 < y && y < c.y + c.height + 2;
+ return isAroundLabel;
+ }
+ }
+ MouseMoveTrackListener parentListener= new MouseMoveTrackListener();
+ parent.addMouseMoveListener(parentListener);
+ parent.addMouseTrackListener(parentListener);
+ parent.addMouseListener(parentListener);
+
+ MouseAdapter labelClickListener= new MouseAdapter() {
+ @Override
+ public void mouseDown(MouseEvent e) {
+ comboBox.setFocus();
+ }
+ };
+ labelControl.addMouseListener(labelClickListener);
+ }
+
+ protected void highlight(final Composite parent, final Label labelControl, final Combo comboBox, final int color) {
+
+ class HighlightPainter implements PaintListener {
+
+ private int fColor= color;
+
+ @Override
+ public void paintControl(PaintEvent e) {
+ if (((GridData) labelControl.getLayoutData()).exclude) {
+ parent.removePaintListener(this);
+ labelControl.setData(null);
+ return;
+ }
+
+ int GAP= 7;
+ int ARROW= 3;
+ Rectangle l= labelControl.getBounds();
+ Point c= comboBox.getLocation();
+
+ e.gc.setForeground(e.display.getSystemColor(fColor));
+ int x2= c.x - GAP;
+ int y= l.y + l.height / 2 + 1;
+
+ e.gc.drawLine(l.x + l.width + GAP, y, x2, y);
+ e.gc.drawLine(x2 - ARROW, y - ARROW, x2, y);
+ e.gc.drawLine(x2 - ARROW, y + ARROW, x2, y);
+ }
+ }
+
+ Object data= labelControl.getData();
+ if (data == null) {
+ if (color != HIGHLIGHT_NONE) {
+ PaintListener painter= new HighlightPainter();
+ parent.addPaintListener(painter);
+ labelControl.setData(painter);
+ } else {
+ return;
+ }
+ } else {
+ if (color == HIGHLIGHT_NONE) {
+ parent.removePaintListener((PaintListener) data);
+ labelControl.setData(null);
+ } else if (color != ((HighlightPainter) data).fColor){
+ ((HighlightPainter) data).fColor= color;
+ } else {
+ return;
+ }
+ }
+
+ parent.redraw();
+ parent.update();
+ }
+
+}
diff --git a/bundles/org.eclipse.releng.tools/src/org/eclipse/releng/tools/preferences/CopyrightPreferencePage.java b/bundles/org.eclipse.releng.tools/src/org/eclipse/releng/tools/preferences/CopyrightPreferencePage.java
new file mode 100644
index 0000000..0f585d0
--- /dev/null
+++ b/bundles/org.eclipse.releng.tools/src/org/eclipse/releng/tools/preferences/CopyrightPreferencePage.java
@@ -0,0 +1,324 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2016 IBM Corporation and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.releng.tools.preferences;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.preferences.InstanceScope;
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.preference.PreferencePage;
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.Document;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.source.SourceViewer;
+import org.eclipse.jface.text.source.SourceViewerConfiguration;
+import org.eclipse.releng.tools.Messages;
+import org.eclipse.releng.tools.RelEngPlugin;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.KeyAdapter;
+import org.eclipse.swt.events.KeyEvent;
+import org.eclipse.swt.events.KeyListener;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Text;
+import org.eclipse.ui.IWorkbench;
+import org.eclipse.ui.IWorkbenchPreferencePage;
+import org.osgi.service.prefs.BackingStoreException;
+
+/**
+ * Copyright tools preference page
+ */
+public class CopyrightPreferencePage extends PreferencePage implements IWorkbenchPreferencePage {
+ private final String NEW_LINE = "\n"; //$NON-NLS-1$
+ private Composite fComposite;
+ private Label fCopyrightLabel;
+ private SourceViewer fEditor;
+ private Text fInstructions;
+ private Label fCreationYearLabel;
+ private Text fCreationYear;
+ private Label fRevisionYearLabel;
+ private Text fRevisionYear;
+ private Button fUseDefaultRevisionYear;
+ private Button fReplaceAllExisting;
+ // disable fix up existing copyright till it works better
+// private Button fFixExisting;
+ private Button fIgnoreProperties;
+ private Button fIgnoreXml;
+
+ @Override
+ public void init(IWorkbench workbench) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ protected Control createContents(Composite parent) {
+
+ //The main composite
+ fComposite = new Composite(parent, SWT.NONE);
+ GridLayout layout = new GridLayout();
+ layout.numColumns = 2;
+ layout.marginWidth = 0;
+ layout.marginHeight = 0;
+ fComposite.setLayout(layout);
+ fComposite.setLayoutData(new GridData(GridData.FILL_BOTH));
+
+ // copyright template editor
+ fEditor = createEditor(fComposite);
+
+ GridData data = new GridData(GridData.FILL_HORIZONTAL);
+ data.horizontalSpan = 2;
+ data.horizontalIndent = 0;
+ fInstructions = new Text(fComposite, SWT.READ_ONLY);
+ fInstructions.setText(Messages.getString("CopyrightPreferencePage.0")); //$NON-NLS-1$
+ fInstructions.setLayoutData(data);
+
+ // default creation year
+ fCreationYearLabel = new Label(fComposite, SWT.NONE);
+ fCreationYearLabel.setText(Messages.getString("CopyrightPreferencePage.1")); //$NON-NLS-1$
+ fCreationYear = new Text(fComposite, SWT.BORDER);
+ fCreationYear.setTextLimit(4);
+
+ // default revision year
+ fRevisionYearLabel = new Label(fComposite, SWT.NONE);
+ fRevisionYearLabel.setText(Messages.getString("CopyrightPreferencePage.7")); //$NON-NLS-1$
+ fRevisionYear = new Text(fComposite, SWT.BORDER);
+ fRevisionYear.setTextLimit(4);
+
+ // always use default revision year instead of cvs lookup
+ fUseDefaultRevisionYear = new Button(fComposite, SWT.CHECK);
+ fUseDefaultRevisionYear.setText(Messages.getString("CopyrightPreferencePage.8")); //$NON-NLS-1$
+ data = new GridData();
+ data.horizontalSpan = 2;
+ fUseDefaultRevisionYear.setLayoutData(data);
+
+ // replace all existing copyright statement
+ fReplaceAllExisting = new Button(fComposite, SWT.CHECK);
+ fReplaceAllExisting.setText(Messages.getString("CopyrightPreferencePage.2")); //$NON-NLS-1$
+ data = new GridData();
+ data.horizontalSpan = 2;
+ fReplaceAllExisting.setLayoutData(data);
+
+ // disable fix up existing copyright till it works better
+// // fix up existing copyright statement
+// fFixExisting = new Button(fComposite, SWT.CHECK);
+// fFixExisting.setText(Messages.getString("CopyrightPreferencePage.3")); //$NON-NLS-1$
+// data = new GridData();
+// data.horizontalSpan = 2;
+// fFixExisting.setLayoutData(data);
+
+ // ignore properties files
+ fIgnoreProperties = new Button(fComposite, SWT.CHECK);
+ fIgnoreProperties.setText(Messages.getString("CopyrightPreferencePage.4")); //$NON-NLS-1$
+ data = new GridData();
+ data.horizontalSpan = 2;
+ fIgnoreProperties.setLayoutData(data);
+
+
+ //[276257] re-enabling xml files
+ fIgnoreXml = new Button(fComposite, SWT.CHECK);
+ fIgnoreXml.setText(Messages.getString("CopyrightPreferencePage.9")); //$NON-NLS-1$
+ data = new GridData();
+ data.horizontalSpan = 2;
+ fIgnoreXml.setLayoutData(data);
+
+
+ KeyListener listener1 = new KeyAdapter() {
+ @Override
+ public void keyReleased(KeyEvent e) {
+ validateValues();
+ }
+ };
+ fCreationYear.addKeyListener(listener1);
+ fRevisionYear.addKeyListener(listener1);
+
+ initializeValues();
+ applyDialogFont(fComposite);
+ return fComposite;
+ }
+
+ /**
+ * Create the sourceviewer editor to be used to edit the copyright template
+ */
+ private SourceViewer createEditor(Composite parent) {
+ fCopyrightLabel = new Label(parent, SWT.NONE);
+ fCopyrightLabel.setText(Messages.getString("CopyrightPreferencePage.5")); //$NON-NLS-1$
+ GridData data= new GridData();
+ data.horizontalSpan= 2;
+ fCopyrightLabel.setLayoutData(data);
+
+ SourceViewer viewer= createViewer(parent);
+
+ IDocument document= new Document();
+ viewer.setEditable(true);
+ viewer.setDocument(document);
+
+ // just use a default 10 lines
+ int nLines = 10;
+// int nLines= document.getNumberOfLines();
+// if (nLines < 5) {
+// nLines= 5;
+// } else if (nLines > 12) {
+// nLines= 12;
+// }
+
+ Control control= viewer.getControl();
+ data= new GridData(GridData.FILL_HORIZONTAL);
+ data.widthHint= convertWidthInCharsToPixels(80);
+ data.heightHint= convertHeightInCharsToPixels(nLines);
+ data.horizontalSpan = 2;
+ control.setLayoutData(data);
+
+ return viewer;
+ }
+
+ /**
+ * Creates the viewer to be used to display the copyright.
+ *
+ * @param parent the parent composite of the viewer
+ * @return a configured <code>SourceViewer</code>
+ */
+ private SourceViewer createViewer(Composite parent) {
+ SourceViewer viewer= new SourceViewer(parent, null, null, false, SWT.BORDER | SWT.V_SCROLL | SWT.H_SCROLL);
+ SourceViewerConfiguration configuration= new SourceViewerConfiguration();
+ viewer.configure(configuration);
+ return viewer;
+ }
+
+ /**
+ * Initialize the control values in this preference page
+ */
+ private void initializeValues() {
+ IPreferenceStore store = getPreferenceStore();
+
+ fEditor.getDocument().set(store.getString(RelEngCopyrightConstants.COPYRIGHT_TEMPLATE_KEY));
+ fCreationYear.setText(store.getString(RelEngCopyrightConstants.CREATION_YEAR_KEY));
+ fRevisionYear.setText(store.getString(RelEngCopyrightConstants.REVISION_YEAR_KEY));
+ fUseDefaultRevisionYear.setSelection(store.getBoolean(RelEngCopyrightConstants.USE_DEFAULT_REVISION_YEAR_KEY));
+ fReplaceAllExisting.setSelection(store.getBoolean(RelEngCopyrightConstants.REPLACE_ALL_EXISTING_KEY));
+ // disable fix up existing copyright till it works better
+// handleReplaceAllEnabled(fReplaceAllExisting.getSelection(), store.getBoolean(RelEngCopyrightConstants.FIX_UP_EXISTING_KEY));
+ fIgnoreProperties.setSelection(store.getBoolean(RelEngCopyrightConstants.IGNORE_PROPERTIES_KEY));
+
+ //[276257] re-enabling xml files
+ fIgnoreXml.setSelection(store.getBoolean(RelEngCopyrightConstants.IGNORE_XML_KEY));
+ }
+
+ /**
+ * Validate the control values in this preference page
+ */
+ private void validateValues() {
+ String ERROR_MESSAGE = Messages.getString("CopyrightPreferencePage.6"); //$NON-NLS-1$
+
+ String errorMsg = null;
+
+ // creation & revision year must be an integer
+ String creationYear = fCreationYear.getText();
+ String revisionYear = fRevisionYear.getText();
+ try {
+ int year = Integer.parseInt(creationYear);
+ if (year < 0) {
+ errorMsg = ERROR_MESSAGE;
+ }
+ year = Integer.parseInt(revisionYear);
+ if (year < 0) {
+ errorMsg = ERROR_MESSAGE;
+ }
+ } catch (NumberFormatException e) {
+ errorMsg = ERROR_MESSAGE;
+ }
+ setErrorMessage(errorMsg);
+ setValid(errorMsg == null);
+ }
+
+ @Override
+ protected IPreferenceStore doGetPreferenceStore() {
+ return RelEngPlugin.getDefault().getPreferenceStore();
+ }
+
+ @Override
+ protected void performDefaults() {
+ IPreferenceStore store = getPreferenceStore();
+
+ fEditor.getDocument().set(store.getDefaultString(RelEngCopyrightConstants.COPYRIGHT_TEMPLATE_KEY));
+ fCreationYear.setText(store.getDefaultString(RelEngCopyrightConstants.CREATION_YEAR_KEY));
+ fRevisionYear.setText(store.getDefaultString(RelEngCopyrightConstants.REVISION_YEAR_KEY));
+ fUseDefaultRevisionYear.setSelection(getPreferenceStore().getDefaultBoolean(RelEngCopyrightConstants.USE_DEFAULT_REVISION_YEAR_KEY));
+ fReplaceAllExisting.setSelection(getPreferenceStore().getDefaultBoolean(RelEngCopyrightConstants.REPLACE_ALL_EXISTING_KEY));
+ // disable fix up existing copyright till it works better
+// handleReplaceAllEnabled(fReplaceAllExisting.getSelection(), getPreferenceStore().getDefaultBoolean(RelEngCopyrightConstants.FIX_UP_EXISTING_KEY));
+ fIgnoreProperties.setSelection(getPreferenceStore().getDefaultBoolean(RelEngCopyrightConstants.IGNORE_PROPERTIES_KEY));
+
+ //[276257] re-enabling xml files
+ fIgnoreXml.setSelection(getPreferenceStore().getDefaultBoolean(RelEngCopyrightConstants.IGNORE_XML_KEY));
+
+ super.performDefaults();
+ }
+
+ @Override
+ public boolean performOk() {
+ IPreferenceStore store = getPreferenceStore();
+
+ store.setValue(RelEngCopyrightConstants.COPYRIGHT_TEMPLATE_KEY, fixupLineDelimiters(fEditor.getDocument()));
+ store.setValue(RelEngCopyrightConstants.CREATION_YEAR_KEY, fCreationYear.getText());
+ store.setValue(RelEngCopyrightConstants.REVISION_YEAR_KEY, fRevisionYear.getText());
+ store.setValue(RelEngCopyrightConstants.USE_DEFAULT_REVISION_YEAR_KEY, fUseDefaultRevisionYear.getSelection());
+ store.setValue(RelEngCopyrightConstants.REPLACE_ALL_EXISTING_KEY, fReplaceAllExisting.getSelection());
+ // disable fix up existing copyright till it works better
+// store.setValue(RelEngCopyrightConstants.FIX_UP_EXISTING_KEY, fFixExisting.getSelection());
+ store.setValue(RelEngCopyrightConstants.IGNORE_PROPERTIES_KEY, fIgnoreProperties.getSelection());
+
+ //[276257] re-enabling xml files
+ store.setValue(RelEngCopyrightConstants.IGNORE_XML_KEY, fIgnoreXml.getSelection());
+
+ try {
+ InstanceScope.INSTANCE.getNode(RelEngPlugin.ID).flush();
+ } catch (BackingStoreException e) {
+ RelEngPlugin.log(IStatus.ERROR, "could not save preferences", e); //$NON-NLS-1$
+ }
+
+ return super.performOk();
+ }
+
+ /**
+ * Fix up line delimiters in doc to use only \n
+ * @param doc
+ * @return
+ */
+ private String fixupLineDelimiters(IDocument doc) {
+ String docContents = doc.get();
+ String newText = ""; //$NON-NLS-1$
+ int lineCount = doc.getNumberOfLines();
+ for (int i = 0; i < lineCount; i++) {
+ try {
+ IRegion lineInfo = doc.getLineInformation(i);
+ int lineStartOffset = lineInfo.getOffset();
+ int lineLength = lineInfo.getLength();
+ int lineEndOffset = lineStartOffset + lineLength;
+ newText += docContents.substring(lineStartOffset, lineEndOffset);
+
+ if ((i < lineCount - 1) && (fEditor.getDocument().getLineDelimiter(i) != null))
+ newText += NEW_LINE;
+ }
+ catch (BadLocationException exception) {
+ // exception
+ }
+ }
+ return newText;
+ }
+}
diff --git a/bundles/org.eclipse.releng.tools/src/org/eclipse/releng/tools/preferences/Messages.java b/bundles/org.eclipse.releng.tools/src/org/eclipse/releng/tools/preferences/Messages.java
new file mode 100644
index 0000000..f608a83
--- /dev/null
+++ b/bundles/org.eclipse.releng.tools/src/org/eclipse/releng/tools/preferences/Messages.java
@@ -0,0 +1,34 @@
+/*******************************************************************************
+ * Copyright (c) 2013 IBM Corporation and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.releng.tools.preferences;
+
+import org.eclipse.osgi.util.NLS;
+
+
+final class Messages extends NLS {
+
+ private static final String BUNDLE_NAME = "org.eclipse.releng.tools.preferences.messages"; //$NON-NLS-1$
+
+ public static String PomErrorLevelBlock_mismatched_pom_versions_pref;
+ public static String PomVersionPreferencePage_pom_pref_message;
+
+ static {
+ // initialize resource bundle
+ NLS.initializeMessages(BUNDLE_NAME, Messages.class);
+ }
+
+ private Messages() {
+ // Do not instantiate
+ }
+}
diff --git a/bundles/org.eclipse.releng.tools/src/org/eclipse/releng/tools/preferences/PomErrorLevelBlock.java b/bundles/org.eclipse.releng.tools/src/org/eclipse/releng/tools/preferences/PomErrorLevelBlock.java
new file mode 100644
index 0000000..2a0d7ad
--- /dev/null
+++ b/bundles/org.eclipse.releng.tools/src/org/eclipse/releng/tools/preferences/PomErrorLevelBlock.java
@@ -0,0 +1,397 @@
+/*******************************************************************************
+ * Copyright (c) 2013, 2016 IBM Corporation and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.releng.tools.preferences;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.core.runtime.preferences.DefaultScope;
+import org.eclipse.core.runtime.preferences.IEclipsePreferences;
+import org.eclipse.core.runtime.preferences.IScopeContext;
+import org.eclipse.core.runtime.preferences.InstanceScope;
+import org.eclipse.jface.dialogs.Dialog;
+import org.eclipse.releng.internal.tools.pomversion.IPomVersionConstants;
+import org.eclipse.releng.tools.RelEngPlugin;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Combo;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.ui.preferences.IWorkbenchPreferenceContainer;
+import org.eclipse.ui.preferences.IWorkingCopyManager;
+import org.eclipse.ui.preferences.WorkingCopyManager;
+import org.osgi.service.prefs.BackingStoreException;
+
+/**
+ * This block is used to add error/warning combos to the {@link PomVersionPreferencePage}
+ *
+ */
+public class PomErrorLevelBlock extends ConfigurationBlock {
+ /**
+ * Provides data information for created controls
+ */
+ protected static class ControlData {
+ Key key;
+ private String[] values;
+
+ /**
+ * Constructor
+ * @param key
+ * @param values
+ */
+ public ControlData(Key key, String[] values) {
+ this.key = key;
+ this.values = values;
+ }
+
+ public Key getKey() {
+ return key;
+ }
+
+ public String getValue(boolean selection) {
+ int index= selection ? 0 : 1;
+ return values[index];
+ }
+
+ public String getValue(int index) {
+ return values[index];
+ }
+
+ public int getSelection(String value) {
+ if (value != null) {
+ for (int i= 0; i < values.length; i++) {
+ if (value.equals(values[i])) {
+ return i;
+ }
+ }
+ }
+ return values.length -1; // assume the last option is the least severe
+ }
+ }
+
+ /**
+ * Provides management for changed/stored values for a given preference key
+ */
+ protected static class Key {
+
+ private String qualifier;
+ private String key;
+
+ /**
+ * Constructor
+ * @param qualifier
+ * @param key
+ */
+ public Key(String qualifier, String key) {
+ this.qualifier= qualifier;
+ this.key= key;
+ }
+
+ /**
+ * Returns the {@link IEclipsePreferences} node for the given context and {@link IWorkingCopyManager}
+ * @param context
+ * @param manager
+ * @return the {@link IEclipsePreferences} node or <code>null</code>
+ */
+ private IEclipsePreferences getNode(IScopeContext context, IWorkingCopyManager manager) {
+ IEclipsePreferences node = context.getNode(qualifier);
+ if (manager != null) {
+ return manager.getWorkingCopy(node);
+ }
+ return node;
+ }
+
+ /**
+ * Returns the value stored in the {@link IEclipsePreferences} node from the given context and working copy manager
+ * @param context
+ * @param manager
+ * @return the value from the {@link IEclipsePreferences} node or <code>null</code>
+ */
+ public String getStoredValue(IScopeContext context, IWorkingCopyManager manager) {
+ IEclipsePreferences node = getNode(context, manager);
+ if(node != null) {
+ return node.get(key, null);
+ }
+ return null;
+ }
+
+ /**
+ * Returns the stored value of this {@link IEclipsePreferences} node using a given lookup order, and allowing the
+ * top scope to be ignored
+ * @param lookupOrder
+ * @param ignoreTopScope
+ * @param manager
+ * @return the value from the {@link IEclipsePreferences} node or <code>null</code>
+ */
+ public String getStoredValue(IScopeContext[] lookupOrder, boolean ignoreTopScope, IWorkingCopyManager manager) {
+ for (int i = ignoreTopScope ? 1 : 0; i < lookupOrder.length; i++) {
+ String value = getStoredValue(lookupOrder[i], manager);
+ if (value != null) {
+ return value;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Sets the value of this key
+ * @param context
+ * @param value
+ * @param manager
+ */
+ public void setStoredValue(IScopeContext context, String value, IWorkingCopyManager manager) {
+ IEclipsePreferences node = getNode(context, manager);
+ if (value != null) {
+ node.put(key, value);
+ } else {
+ node.remove(key);
+ }
+ }
+
+ @Override
+ public String toString() {
+ return qualifier + '/' + key;
+ }
+ }
+
+ private static final Key KEY_POM_VERSION_ERROR_LEVEL = new Key(RelEngPlugin.ID, IPomVersionConstants.POM_VERSION_ERROR_LEVEL);
+
+ /**
+ * An array of all of the keys for the page
+ */
+ private static Key[] fgAllKeys = {
+ KEY_POM_VERSION_ERROR_LEVEL
+ };
+
+ /**
+ * Constant representing the severity values presented in the combo boxes for each option
+ */
+ private static final String[] SEVERITIES_LABELS = {
+ "Error", //$NON-NLS-1$
+ "Warning", //$NON-NLS-1$
+ "Ignore" //$NON-NLS-1$
+ };
+
+ /**
+ * Constant representing the severity values presented in the combo boxes for each option
+ */
+ private static final String[] SEVERITIES = {
+ IPomVersionConstants.VALUE_ERROR,
+ IPomVersionConstants.VALUE_WARNING,
+ IPomVersionConstants.VALUE_IGNORE,
+ };
+
+ /**
+ * Default selection listener for controls on the page
+ */
+ private SelectionListener selectionlistener = new SelectionAdapter() {
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ if(e.widget instanceof Combo) {
+ Combo combo = (Combo) e.widget;
+ ControlData data = (ControlData) combo.getData();
+ data.key.setStoredValue(fLookupOrder[0], combo.getText(), fManager);
+ fDirty = true;
+ }
+ }
+ };
+
+ /**
+ * Listing of all of the {@link Combo}s added to the block
+ */
+ private Combo fCombo = null;
+
+ /**
+ * The context of settings locations to search for values in
+ */
+ IScopeContext[] fLookupOrder = null;
+
+ /**
+ * the working copy manager to work with settings
+ */
+ IWorkingCopyManager fManager = null;
+
+ /**
+ * The main composite for the configuration block, used for enabling/disabling the block
+ */
+ private Composite fMainComp = null;
+
+
+ /**
+ * Flag used to know if the page needs saving or not
+ */
+ boolean fDirty = false;
+
+ /**
+ * Constructor
+ * @param project
+ */
+ public PomErrorLevelBlock(IWorkbenchPreferenceContainer container) {
+ fLookupOrder = new IScopeContext[] {
+ InstanceScope.INSTANCE,
+ DefaultScope.INSTANCE
+ };
+ if(container == null) {
+ fManager = new WorkingCopyManager();
+ }
+ else {
+ fManager = container.getWorkingCopyManager();
+ }
+ }
+
+ /**
+ * Creates the control in the parent control
+ *
+ * @param parent the parent control
+ */
+ public Control createControl(Composite parent) {
+ fMainComp = new Composite(parent, SWT.NONE);
+ GridLayout gl = new GridLayout(2, false);
+ gl.marginHeight = 0;
+ gl.marginWidth = 0;
+ fMainComp.setLayout(gl);
+ fMainComp.setLayoutData(new GridData(SWT.FILL, SWT.BEGINNING, true, false));
+ fMainComp.setFont(parent.getFont());
+ this.fCombo = createComboControl(fMainComp, Messages.PomErrorLevelBlock_mismatched_pom_versions_pref, KEY_POM_VERSION_ERROR_LEVEL);
+ Dialog.applyDialogFont(fMainComp);
+ return fMainComp;
+ }
+
+ /**
+ * Saves all of the changes on the page
+ */
+ public void performOK() {
+ save();
+ }
+
+ /**
+ * Directly applies all of the changes on the page
+ */
+ public void performApply() {
+ save();
+ }
+
+ /**
+ * Performs the save operation on the working copy manager
+ */
+ private void save() {
+ if(fDirty) {
+ try {
+ ArrayList<Key> changes = new ArrayList<>();
+ collectChanges(fLookupOrder[0], changes);
+ if(changes.size() > 0) {
+ fManager.applyChanges();
+ }
+ fDirty = false;
+ }
+ catch(BackingStoreException bse) {
+ RelEngPlugin.log(new Status(IStatus.ERROR, RelEngPlugin.ID, bse.getMessage(), bse));
+ }
+ }
+ }
+
+ /**
+ * Cancels all of the changes on the page
+ */
+ public void performCancel() {}
+
+ /**
+ * Reverts all of the settings back to their defaults
+ */
+ public void performDefaults() {
+ String defval = null;
+ for(int i = 0; i < fgAllKeys.length; i++) {
+ defval = fgAllKeys[i].getStoredValue(fLookupOrder, true, fManager);
+ fgAllKeys[i].setStoredValue(fLookupOrder[0], defval, fManager);
+ }
+ updateCombos();
+ fDirty = true;
+ }
+
+ /**
+ * Updates all of the registered {@link Combo}s on the page.
+ * Registration implies that the {@link Combo} control was added to the listing
+ * of fCombos
+ */
+ private void updateCombos() {
+ if (this.fCombo != null) {
+ ControlData data = (ControlData) fCombo.getData();
+ this.fCombo.select(data.getSelection(data.getKey().getStoredValue(fLookupOrder, false, fManager)));
+ }
+ }
+
+ /**
+ * Disposes the controls from this page
+ */
+ public void dispose() {
+ fMainComp.getParent().dispose();
+ }
+
+ /**
+ * Creates a {@link Label} | {@link Combo} control. The combo is initialised from the given {@link Key}
+ * @param parent
+ * @param label
+ * @param key
+ */
+ protected Combo createComboControl(Composite parent, String label, Key key) {
+ Label lbl = new Label(parent, SWT.NONE);
+ GridData gd = new GridData(GridData.BEGINNING, GridData.CENTER, true, false);
+ lbl.setLayoutData(gd);
+ lbl.setText(label);
+ Combo combo = new Combo(parent, SWT.DROP_DOWN | SWT.READ_ONLY);
+ gd = new GridData(GridData.END, GridData.CENTER, false, false);
+ combo.setLayoutData(gd);
+ ControlData data = new ControlData(key, SEVERITIES);
+ combo.setData(data);
+ combo.setItems(SEVERITIES_LABELS);
+ combo.addSelectionListener(selectionlistener);
+ combo.select(data.getSelection(key.getStoredValue(fLookupOrder, false, fManager)));
+ addHighlight(parent, lbl, combo);
+ return combo;
+ }
+
+ /**
+ * Collects the keys that have changed on the page into the specified list
+ * @param changes the {@link List} to collect changed keys into
+ */
+ private void collectChanges(IScopeContext context, List<Key> changes) {
+ String origval = null,
+ newval = null;
+ for (Key key : fgAllKeys) {
+ origval = key.getStoredValue(context, null);
+ newval = key.getStoredValue(context, fManager);
+ if(newval == null) {
+ if(origval != null) {
+ changes.add(key);
+ }
+ key.setStoredValue(context, key.getStoredValue(fLookupOrder, true, fManager), fManager);
+ changes.add(key);
+ }
+ else if(!newval.equals(origval)) {
+ changes.add(key);
+ }
+ }
+ }
+
+ public static Key[] getAllKeys() {
+ return fgAllKeys;
+ }
+}
diff --git a/bundles/org.eclipse.releng.tools/src/org/eclipse/releng/tools/preferences/PomVersionPreferencePage.java b/bundles/org.eclipse.releng.tools/src/org/eclipse/releng/tools/preferences/PomVersionPreferencePage.java
new file mode 100644
index 0000000..18feb37
--- /dev/null
+++ b/bundles/org.eclipse.releng.tools/src/org/eclipse/releng/tools/preferences/PomVersionPreferencePage.java
@@ -0,0 +1,91 @@
+/*******************************************************************************
+ * Copyright (c) 2013, 2016 IBM Corporation and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.releng.tools.preferences;
+
+import org.eclipse.jface.dialogs.Dialog;
+import org.eclipse.jface.preference.PreferencePage;
+import org.eclipse.releng.tools.RelEngPlugin;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.ui.IWorkbench;
+import org.eclipse.ui.IWorkbenchPreferencePage;
+import org.eclipse.ui.preferences.IWorkbenchPreferenceContainer;
+
+/**
+ * This preference page allows the error level of the POM version tool to be set
+ */
+public class PomVersionPreferencePage extends PreferencePage implements
+ IWorkbenchPreferencePage {
+
+ public static final String ID = RelEngPlugin.ID + "PomVersionPreferencePage"; //$NON-NLS-1$
+
+ /**
+ * The main configuration block for the page
+ */
+ private PomErrorLevelBlock block = null;
+
+ @Override
+ protected Control createContents(Composite parent) {
+ Composite comp = new Composite(parent, SWT.NONE);
+ GridLayout gl = new GridLayout();
+ gl.marginHeight = 0;
+ gl.marginWidth = 0;
+ comp.setLayout(gl);
+ comp.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
+
+ Label label = new Label(comp, SWT.WRAP);
+ GridData gd = new GridData(SWT.FILL, SWT.BEGINNING, true, false);
+ gd.widthHint = 400;
+ label.setLayoutData(gd);
+ label.setText(Messages.PomVersionPreferencePage_pom_pref_message);
+ label.setFont(comp.getFont());
+
+ block = new PomErrorLevelBlock((IWorkbenchPreferenceContainer)getContainer());
+ block.createControl(comp);
+ Dialog.applyDialogFont(comp);
+ return comp;
+ }
+
+ @Override
+ public void init(IWorkbench workbench) {
+ }
+
+ @Override
+ public boolean performCancel() {
+ if (this.block != null) {
+ this.block.performCancel();
+ }
+ return super.performCancel();
+ }
+
+ @Override
+ public boolean performOk() {
+ this.block.performOK();
+ return true;
+ }
+
+ @Override
+ protected void performApply() {
+ this.block.performApply();
+ }
+
+ @Override
+ protected void performDefaults() {
+ this.block.performDefaults();
+ }
+}
diff --git a/bundles/org.eclipse.releng.tools/src/org/eclipse/releng/tools/preferences/RelEngCopyrightConstants.java b/bundles/org.eclipse.releng.tools/src/org/eclipse/releng/tools/preferences/RelEngCopyrightConstants.java
new file mode 100644
index 0000000..17a92ba
--- /dev/null
+++ b/bundles/org.eclipse.releng.tools/src/org/eclipse/releng/tools/preferences/RelEngCopyrightConstants.java
@@ -0,0 +1,29 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2014 IBM Corporation and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.releng.tools.preferences;
+
+/**
+ * Contains all the constants used by the releng copyright tool
+ */
+public class RelEngCopyrightConstants {
+ public final static String COPYRIGHT_TEMPLATE_KEY = "org.eclipse.releng.tools.copyrightTemplate"; //$NON-NLS-1$
+ public final static String CREATION_YEAR_KEY = "org.eclipse.releng.tools.creationYear"; //$NON-NLS-1$
+ public final static String REVISION_YEAR_KEY = "org.eclipse.releng.tools.revisionYear"; //$NON-NLS-1$
+ public final static String USE_DEFAULT_REVISION_YEAR_KEY = "org.eclipse.releng.tools.useDefaultRevisionYear"; //$NON-NLS-1$
+ // disable fix up existing copyright till it works better
+// public final static String FIX_UP_EXISTING_KEY = "org.eclipse.releng.tools.fixUpExisting"; //$NON-NLS-1$
+ public final static String REPLACE_ALL_EXISTING_KEY = "org.eclipse.releng.tools.replaceAllExisting"; //$NON-NLS-1$
+ public final static String IGNORE_PROPERTIES_KEY = "org.eclipse.releng.tools.ignoreProperties"; //$NON-NLS-1$
+ public final static String IGNORE_XML_KEY = "org.eclipse.releng.tools.ignoreXml"; //$NON-NLS-1$
+}
diff --git a/bundles/org.eclipse.releng.tools/src/org/eclipse/releng/tools/preferences/RelEngPreferenceInitializer.java b/bundles/org.eclipse.releng.tools/src/org/eclipse/releng/tools/preferences/RelEngPreferenceInitializer.java
new file mode 100644
index 0000000..1a2cade
--- /dev/null
+++ b/bundles/org.eclipse.releng.tools/src/org/eclipse/releng/tools/preferences/RelEngPreferenceInitializer.java
@@ -0,0 +1,47 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2013 IBM Corporation and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.releng.tools.preferences;
+
+import java.util.Calendar;
+
+import org.eclipse.core.runtime.preferences.AbstractPreferenceInitializer;
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.releng.internal.tools.pomversion.IPomVersionConstants;
+import org.eclipse.releng.tools.Messages;
+import org.eclipse.releng.tools.RelEngPlugin;
+
+/**
+ * Initializes default preferences for release engineering tool
+ */
+public class RelEngPreferenceInitializer extends AbstractPreferenceInitializer {
+ private final String LEGAL_LINE = Messages.getString("RelEngPreferenceInitializer.0"); //$NON-NLS-1$
+
+ @Override
+ public void initializeDefaultPreferences() {
+ IPreferenceStore store = RelEngPlugin.getDefault().getPreferenceStore();
+ int year = Calendar.getInstance().get(Calendar.YEAR);
+ store.setDefault(RelEngCopyrightConstants.COPYRIGHT_TEMPLATE_KEY, LEGAL_LINE);
+ store.setDefault(RelEngCopyrightConstants.CREATION_YEAR_KEY, year);
+ store.setDefault(RelEngCopyrightConstants.REVISION_YEAR_KEY, year);
+ store.setDefault(RelEngCopyrightConstants.USE_DEFAULT_REVISION_YEAR_KEY, false);
+ // disable fix up existing copyright till it works better
+// store.setDefault(RelEngCopyrightConstants.FIX_UP_EXISTING_KEY, false);
+ store.setDefault(RelEngCopyrightConstants.REPLACE_ALL_EXISTING_KEY, false);
+ store.setDefault(RelEngCopyrightConstants.IGNORE_PROPERTIES_KEY, false);
+ store.setDefault(RelEngCopyrightConstants.IGNORE_XML_KEY, false);
+
+ store.setDefault(IPomVersionConstants.POM_VERSION_ERROR_LEVEL, IPomVersionConstants.VALUE_ERROR);
+ }
+
+}
diff --git a/bundles/org.eclipse.releng.tools/src/org/eclipse/releng/tools/preferences/messages.properties b/bundles/org.eclipse.releng.tools/src/org/eclipse/releng/tools/preferences/messages.properties
new file mode 100644
index 0000000..168baa3
--- /dev/null
+++ b/bundles/org.eclipse.releng.tools/src/org/eclipse/releng/tools/preferences/messages.properties
@@ -0,0 +1,16 @@
+###############################################################################
+# Copyright (c) 2013 IBM Corporation and others.
+#
+# This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License 2.0
+# which accompanies this distribution, and is available at
+# https://www.eclipse.org/legal/epl-2.0/
+#
+# SPDX-License-Identifier: EPL-2.0
+#
+# Contributors:
+# IBM Corporation - initial API and implementation
+###############################################################################
+
+PomErrorLevelBlock_mismatched_pom_versions_pref=&Mismatched plug-in and pom.xml version numbers
+PomVersionPreferencePage_pom_pref_message=The POM Version tool will compare the artifact version in a pom.xml file at the root of the project to the plug-in version in the manifest. If the two versions do not match a problem marker will be created. The severity of this problem can be configured on this page.
diff --git a/bundles/pom.xml b/bundles/pom.xml
index 0f1ca40..1004a94 100644
--- a/bundles/pom.xml
+++ b/bundles/pom.xml
@@ -17,6 +17,7 @@
<module>org.eclipse.releng.build.tools.convert.application</module>
<module>org.eclipse.releng.build.tools.comparator</module>
<module>org.eclipse.test.performance.ui</module>
+ <module>org.eclipse.releng.tools</module>
</modules>
<build>
<plugins>
diff --git a/features/org.eclipse.releng.tools/.project b/features/org.eclipse.releng.tools/.project
new file mode 100644
index 0000000..a3152dc
--- /dev/null
+++ b/features/org.eclipse.releng.tools/.project
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>org.eclipse.releng.tools (feature)</name>
+ <comment>test</comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.pde.FeatureBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.pde.FeatureNature</nature>
+ </natures>
+</projectDescription>
diff --git a/features/org.eclipse.releng.tools/.settings/org.eclipse.core.resources.prefs b/features/org.eclipse.releng.tools/.settings/org.eclipse.core.resources.prefs
new file mode 100644
index 0000000..ae3a78c
--- /dev/null
+++ b/features/org.eclipse.releng.tools/.settings/org.eclipse.core.resources.prefs
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+separateDerivedEncodings=true
diff --git a/features/org.eclipse.releng.tools/.settings/org.eclipse.core.runtime.prefs b/features/org.eclipse.releng.tools/.settings/org.eclipse.core.runtime.prefs
new file mode 100644
index 0000000..5a0ad22
--- /dev/null
+++ b/features/org.eclipse.releng.tools/.settings/org.eclipse.core.runtime.prefs
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+line.separator=\n
diff --git a/features/org.eclipse.releng.tools/build.properties b/features/org.eclipse.releng.tools/build.properties
new file mode 100644
index 0000000..18b4366
--- /dev/null
+++ b/features/org.eclipse.releng.tools/build.properties
@@ -0,0 +1,14 @@
+###############################################################################
+# Copyright (c) 2005, 2006 IBM Corporation and others.
+#
+# This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License 2.0
+# which accompanies this distribution, and is available at
+# https://www.eclipse.org/legal/epl-2.0/
+#
+# SPDX-License-Identifier: EPL-2.0
+#
+# Contributors:
+# IBM Corporation - initial API and implementation
+###############################################################################
+bin.includes = feature.xml,feature.properties
diff --git a/features/org.eclipse.releng.tools/feature.properties b/features/org.eclipse.releng.tools/feature.properties
new file mode 100644
index 0000000..db98c0b
--- /dev/null
+++ b/features/org.eclipse.releng.tools/feature.properties
@@ -0,0 +1,42 @@
+###############################################################################
+# Copyright (c) 2000, 2020 IBM Corporation and others.
+#
+# This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License 2.0
+# which accompanies this distribution, and is available at
+# https://www.eclipse.org/legal/epl-2.0/
+#
+# SPDX-License-Identifier: EPL-2.0
+#
+# Contributors:
+# IBM Corporation - initial API and implementation
+###############################################################################
+# feature.properties
+# contains externalized strings for feature.xml
+# "%foo" in feature.xml corresponds to the key "foo" in this file
+# java.io.Properties file (ISO 8859-1 with "\" escapes)
+# This file should be translated.
+
+# "featureName" property - name of the feature
+featureName=Eclipse Releng Tools
+
+# "providerName" property - name of the company that provides the feature
+providerName=Eclipse.org
+
+# "description" property - description of the feature
+description=Eclipse Releng Tools
+
+# "copyright" property - text of the "Feature Update Copyright"
+copyright=\
+Copyright (c) 2000, 2020 IBM Corporation and others.\n\
+
+This program and the accompanying materials\n\
+are made available under the terms of the Eclipse Public License 2.0\n\
+which accompanies this distribution, and is available at\n\
+https://www.eclipse.org/legal/epl-2.0/
+
+SPDX-License-Identifier: EPL-2.0\n\
+\n\
+Contributors:\n\
+ IBM Corporation - initial API and implementation\n
+################ end of copyright property ####################################
\ No newline at end of file
diff --git a/features/org.eclipse.releng.tools/feature.xml b/features/org.eclipse.releng.tools/feature.xml
new file mode 100644
index 0000000..e9e8246
--- /dev/null
+++ b/features/org.eclipse.releng.tools/feature.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<feature
+ id="org.eclipse.releng.tools"
+ label="%featureName"
+ version="3.11.100.qualifier"
+ provider-name="%providerName"
+ image="eclipse_update_120.jpg"
+ license-feature="org.eclipse.license"
+ license-feature-version="0.0.0">
+
+ <description>
+ %description
+ </description>
+
+ <copyright>
+ %copyright
+ </copyright>
+
+ <license url="%licenseURL">
+ %license
+ </license>
+
+ <plugin
+ id="org.eclipse.releng.tools"
+ download-size="0"
+ install-size="0"
+ version="0.0.0"/>
+
+</feature>
diff --git a/features/org.eclipse.releng.tools/forceQualifierUpdate.txt b/features/org.eclipse.releng.tools/forceQualifierUpdate.txt
new file mode 100644
index 0000000..1f61f41
--- /dev/null
+++ b/features/org.eclipse.releng.tools/forceQualifierUpdate.txt
@@ -0,0 +1,3 @@
+# To force a version qualifier update add the bug here
+Bug 403352 - Update all parent versions to match our build stream
+Bug 540097 - Comparator Errors in I20181012-1800 Build
diff --git a/features/org.eclipse.releng.tools/pom.xml b/features/org.eclipse.releng.tools/pom.xml
new file mode 100644
index 0000000..c0e06b0
--- /dev/null
+++ b/features/org.eclipse.releng.tools/pom.xml
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (c) 2012, 2017 Eclipse Foundation and others.
+ All rights reserved. This program and the accompanying materials
+ are made available under the terms of the Eclipse Distribution License v1.0
+ which accompanies this distribution, and is available at
+ http://www.eclipse.org/org/documents/edl-v10.php
+
+ Contributors:
+ Igor Fedorenko - initial implementation
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>org.eclipse.platform</groupId>
+ <artifactId>features</artifactId>
+ <version>1.0.101-SNAPSHOT</version>
+ </parent>
+ <groupId>org.eclipse.releng.feature</groupId>
+ <artifactId>org.eclipse.releng.tools</artifactId>
+ <version>3.11.100-SNAPSHOT</version>
+ <packaging>eclipse-feature</packaging>
+ <build>
+ <plugins>
+ <!--
+ <plugin>
+ <groupId>org.eclipse.tycho</groupId>
+ <artifactId>tycho-source-plugin</artifactId>
+ <version>${tycho.version}</version>
+ <executions>
+ <execution>
+ <phase>package</phase>
+ <id>feature-source</id>
+ <goals>
+ <goal>feature-source</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ -->
+ <plugin>
+ <groupId>org.eclipse.tycho</groupId>
+ <artifactId>tycho-p2-plugin</artifactId>
+ <version>${tycho.version}</version>
+ <executions>
+ <execution>
+ <id>attach-p2-metadata</id>
+ <phase>package</phase>
+ <goals>
+ <goal>p2-metadata</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+</project>
diff --git a/features/pom.xml b/features/pom.xml
index 3410b29..154fee0 100644
--- a/features/pom.xml
+++ b/features/pom.xml
@@ -11,6 +11,7 @@
<packaging>pom</packaging>
<modules>
<module>org.eclipse.releng.build.tools.feature</module>
+ <module>org.eclipse.releng.tools</module>
</modules>
<build>
<plugins>
diff --git a/pom.xml b/pom.xml
index 148f19c..4a6bd63 100644
--- a/pom.xml
+++ b/pom.xml
@@ -23,7 +23,7 @@
</prerequisites>
<properties>
- <tycho.version>2.0.0</tycho.version>
+ <tycho.version>2.2.0</tycho.version>
<cbi-plugins.version>1.1.7</cbi-plugins.version>
<maven.build.timestamp.format>yyyyMMdd-HHmm</maven.build.timestamp.format>
<buildTimestamp>${maven.build.timestamp}</buildTimestamp>
@@ -35,12 +35,10 @@
<buildTimestamp>${maven.build.timestamp}</buildTimestamp>
<buildType>I</buildType>
<buildId>${buildType}${buildTimestamp}</buildId>
- <comparator.repo>http://download.eclipse.org/eclipse/updates/4.18-I-builds</comparator.repo>
+ <comparator.repo>http://download.eclipse.org/eclipse/updates/4.19-I-builds</comparator.repo>
<egit-repo.url>http://download.eclipse.org/egit/updates</egit-repo.url>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<cbi-jdt-repo.url>https://repo.eclipse.org/content/repositories/eclipse-staging/</cbi-jdt-repo.url>
- <cbi-ecj-version>3.21.0.v20200304-1404</cbi-ecj-version>
-
<cbi-snapshots-repo.url>https://repo.eclipse.org/content/repositories/cbi-snapshots/</cbi-snapshots-repo.url>
<eclipse-repo.url>https://repo.eclipse.org/content/repositories/cbi/</eclipse-repo.url>
@@ -94,7 +92,12 @@
<id>eclipse-platform-repository</id>
<layout>p2</layout>
<!-- Normally should be "latest milestone" for stability, once we have one for 4.9. -->
- <url>http://download.eclipse.org/eclipse/updates/4.18-I-builds/</url>
+ <url>https://download.eclipse.org/eclipse/updates/I-builds/</url>
+ </repository>
+ <repository>
+ <id>git-repository</id>
+ <url>https://download.eclipse.org/egit/updates/</url>
+ <layout>p2</layout>
</repository>
<repository>
<id>cbi-common-license</id>
@@ -160,13 +163,6 @@
<groupId>org.eclipse.tycho</groupId>
<artifactId>tycho-compiler-plugin</artifactId>
<version>${tycho.version}</version>
- <dependencies>
- <dependency>
- <groupId>org.eclipse.jdt</groupId>
- <artifactId>ecj</artifactId>
- <version>${cbi-ecj-version}</version>
- </dependency>
- </dependencies>
<configuration>
<compilerArgs>
<args>-verbose</args>
@@ -175,10 +171,6 @@
<args>-encoding</args>
<args>${project.build.sourceEncoding}</args>
<args>-proceedOnError</args>
- <!-- Use this form, for Tycho 22 or less.
- <args>-log</args>
- <args>${project.build.directory}/@dot.xml</args>
- -->
</compilerArgs>
<!-- Use this form for Tycho 23 or greater -->
<log>xml</log>
diff --git a/repository/category.xml b/repository/category.xml
index 57eab7c..6608984 100644
--- a/repository/category.xml
+++ b/repository/category.xml
@@ -3,7 +3,10 @@
<feature url="features/org.eclipse.releng.build.tools.feature_1.0.101.qualifier.jar" id="org.eclipse.releng.build.tools.feature" version="1.0.101.qualifier">
<category name="org.eclipse.releng.build.repository"/>
</feature>
- <feature url="features/org.eclipse.releng.build.tools.feature.source_1.0.101.qualifier.jar" id="org.eclipse.releng.build.tools.feature.source" version="1.0.101.qualifier">
+ <feature url="features/org.eclipse.releng.build.tools.feature.source_1.0.101.qualifier.jar" id="org.eclipse.releng.build.tools.feature.source" version="1.0.101.qualifier">
+ <category name="org.eclipse.releng.build.repository"/>
+ </feature>
+ <feature url="features/org.eclipse.releng.tools_3.11.100.qualifier.jar" id="org.eclipse.releng.tools" version="3.11.100.qualifier">
<category name="org.eclipse.releng.build.repository"/>
</feature>
<category-def name="org.eclipse.releng.build.repository" label="Build Tools and Ant Tasks"/>