Merge remote-tracking branch 'origin/feature/329198'
diff --git a/org.eclipse.virgo.ide.feature/feature.xml b/org.eclipse.virgo.ide.feature/feature.xml
index 6144eba..bca7023 100644
--- a/org.eclipse.virgo.ide.feature/feature.xml
+++ b/org.eclipse.virgo.ide.feature/feature.xml
@@ -72,6 +72,13 @@
install-size="0"
version="0.0.0"
unpack="false"/>
+
+ <plugin
+ id="org.eclipse.virgo.ide.pde.core"
+ download-size="0"
+ install-size="0"
+ version="0.0.0"
+ unpack="false"/>
<plugin
id="org.eclipse.virgo.ide.jdt.core"
diff --git a/org.eclipse.virgo.ide.pde.core/.classpath b/org.eclipse.virgo.ide.pde.core/.classpath
new file mode 100644
index 0000000..64c5e31
--- /dev/null
+++ b/org.eclipse.virgo.ide.pde.core/.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/J2SE-1.5"/>
+ <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+ <classpathentry kind="src" path="src"/>
+ <classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/org.eclipse.virgo.ide.pde.core/.options b/org.eclipse.virgo.ide.pde.core/.options
new file mode 100644
index 0000000..0eb83ad
--- /dev/null
+++ b/org.eclipse.virgo.ide.pde.core/.options
@@ -0,0 +1 @@
+org.eclipse.virgo.ide.pde.core/debug=false
\ No newline at end of file
diff --git a/org.eclipse.virgo.ide.pde.core/.project b/org.eclipse.virgo.ide.pde.core/.project
new file mode 100644
index 0000000..b193575
--- /dev/null
+++ b/org.eclipse.virgo.ide.pde.core/.project
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>org.eclipse.virgo.ide.pde.core</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/org.eclipse.virgo.ide.pde.core/.settings/org.eclipse.jdt.core.prefs b/org.eclipse.virgo.ide.pde.core/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..4321bd9
--- /dev/null
+++ b/org.eclipse.virgo.ide.pde.core/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,371 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.codeComplete.argumentPrefixes=
+org.eclipse.jdt.core.codeComplete.argumentSuffixes=
+org.eclipse.jdt.core.codeComplete.fieldPrefixes=
+org.eclipse.jdt.core.codeComplete.fieldSuffixes=
+org.eclipse.jdt.core.codeComplete.localPrefixes=
+org.eclipse.jdt.core.codeComplete.localSuffixes=
+org.eclipse.jdt.core.codeComplete.staticFieldPrefixes=
+org.eclipse.jdt.core.codeComplete.staticFieldSuffixes=
+org.eclipse.jdt.core.codeComplete.staticFinalFieldPrefixes=
+org.eclipse.jdt.core.codeComplete.staticFinalFieldSuffixes=
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
+org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
+org.eclipse.jdt.core.compiler.compliance=1.5
+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.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=warning
+org.eclipse.jdt.core.compiler.problem.emptyStatement=ignore
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.problem.fallthroughCase=ignore
+org.eclipse.jdt.core.compiler.problem.fatalOptionalError=enabled
+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.incompatibleNonInheritedInterfaceMethod=warning
+org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=ignore
+org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=ignore
+org.eclipse.jdt.core.compiler.problem.localVariableHiding=ignore
+org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=warning
+org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=ignore
+org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=ignore
+org.eclipse.jdt.core.compiler.problem.missingSerialVersion=warning
+org.eclipse.jdt.core.compiler.problem.noEffectAssignment=warning
+org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning
+org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=warning
+org.eclipse.jdt.core.compiler.problem.nullReference=error
+org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning
+org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore
+org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=ignore
+org.eclipse.jdt.core.compiler.problem.potentialNullReference=warning
+org.eclipse.jdt.core.compiler.problem.rawTypeReference=warning
+org.eclipse.jdt.core.compiler.problem.redundantNullCheck=ignore
+org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=ignore
+org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled
+org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning
+org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled
+org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore
+org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning
+org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=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=ignore
+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.unusedImport=warning
+org.eclipse.jdt.core.compiler.problem.unusedLabel=warning
+org.eclipse.jdt.core.compiler.problem.unusedLocal=warning
+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.unusedWarningToken=warning
+org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning
+org.eclipse.jdt.core.compiler.source=1.5
+org.eclipse.jdt.core.compiler.taskCaseSensitive=enabled
+org.eclipse.jdt.core.compiler.taskPriorities=NORMAL,HIGH,NORMAL
+org.eclipse.jdt.core.compiler.taskTags=TODO,FIXME,XXX
+org.eclipse.jdt.core.formatter.align_type_members_on_columns=false
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation=0
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant=80
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call=16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation=16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression=16
+org.eclipse.jdt.core.formatter.alignment_for_assignment=0
+org.eclipse.jdt.core.formatter.alignment_for_binary_expression=16
+org.eclipse.jdt.core.formatter.alignment_for_compact_if=16
+org.eclipse.jdt.core.formatter.alignment_for_conditional_expression=80
+org.eclipse.jdt.core.formatter.alignment_for_enum_constants=0
+org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer=16
+org.eclipse.jdt.core.formatter.alignment_for_method_declaration=0
+org.eclipse.jdt.core.formatter.alignment_for_multiple_fields=16
+org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_resources_in_try=80
+org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation=0
+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=1
+org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration=1
+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=1
+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=false
+org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment=false
+org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment=false
+org.eclipse.jdt.core.formatter.comment.format_block_comments=true
+org.eclipse.jdt.core.formatter.comment.format_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=false
+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=do not insert
+org.eclipse.jdt.core.formatter.comment.line_length=120
+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=1
+org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer=1
+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=true
+org.eclipse.jdt.core.formatter.indentation.size=4
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_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_member=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_and_in_type_parameter=insert
+org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_binary_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters=insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block=insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters=insert
+org.eclipse.jdt.core.formatter.insert_space_after_ellipsis=insert
+org.eclipse.jdt.core.formatter.insert_space_after_lambda_arrow=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_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_unary_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter=insert
+org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_binary_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer=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_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_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_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=150
+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=space
+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_binary_operator=true
+org.eclipse.jdt.core.formatter.wrap_before_or_operator_multicatch=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/org.eclipse.virgo.ide.pde.core/.settings/org.eclipse.jdt.ui.prefs b/org.eclipse.virgo.ide.pde.core/.settings/org.eclipse.jdt.ui.prefs
new file mode 100644
index 0000000..6c98016
--- /dev/null
+++ b/org.eclipse.virgo.ide.pde.core/.settings/org.eclipse.jdt.ui.prefs
@@ -0,0 +1,118 @@
+cleanup.add_default_serial_version_id=false
+cleanup.add_generated_serial_version_id=true
+cleanup.add_missing_annotations=true
+cleanup.add_missing_deprecated_annotations=true
+cleanup.add_missing_methods=false
+cleanup.add_missing_nls_tags=false
+cleanup.add_missing_override_annotations=true
+cleanup.add_missing_override_annotations_interface_methods=true
+cleanup.add_serial_version_id=true
+cleanup.always_use_blocks=true
+cleanup.always_use_parentheses_in_expressions=false
+cleanup.always_use_this_for_non_static_field_access=true
+cleanup.always_use_this_for_non_static_method_access=false
+cleanup.convert_functional_interfaces=false
+cleanup.convert_to_enhanced_for_loop=false
+cleanup.correct_indentation=false
+cleanup.format_source_code=true
+cleanup.format_source_code_changes_only=false
+cleanup.insert_inferred_type_arguments=false
+cleanup.make_local_variable_final=false
+cleanup.make_parameters_final=false
+cleanup.make_private_fields_final=true
+cleanup.make_type_abstract_if_missing_method=false
+cleanup.make_variable_declarations_final=true
+cleanup.never_use_blocks=false
+cleanup.never_use_parentheses_in_expressions=true
+cleanup.organize_imports=true
+cleanup.qualify_static_field_accesses_with_declaring_class=false
+cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true
+cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true
+cleanup.qualify_static_member_accesses_with_declaring_class=true
+cleanup.qualify_static_method_accesses_with_declaring_class=false
+cleanup.remove_private_constructors=true
+cleanup.remove_redundant_type_arguments=true
+cleanup.remove_trailing_whitespaces=true
+cleanup.remove_trailing_whitespaces_all=true
+cleanup.remove_trailing_whitespaces_ignore_empty=false
+cleanup.remove_unnecessary_casts=true
+cleanup.remove_unnecessary_nls_tags=true
+cleanup.remove_unused_imports=true
+cleanup.remove_unused_local_variables=true
+cleanup.remove_unused_private_fields=true
+cleanup.remove_unused_private_members=true
+cleanup.remove_unused_private_methods=true
+cleanup.remove_unused_private_types=true
+cleanup.sort_members=false
+cleanup.sort_members_all=false
+cleanup.use_anonymous_class_creation=false
+cleanup.use_blocks=true
+cleanup.use_blocks_only_for_return_and_throw=false
+cleanup.use_lambda=true
+cleanup.use_parentheses_in_expressions=true
+cleanup.use_this_for_non_static_field_access=true
+cleanup.use_this_for_non_static_field_access_only_if_necessary=false
+cleanup.use_this_for_non_static_method_access=false
+cleanup.use_this_for_non_static_method_access_only_if_necessary=true
+cleanup.use_type_arguments=false
+cleanup_profile=_Virgo Web Server - Code Clean Up
+cleanup_settings_version=2
+eclipse.preferences.version=1
+editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true
+formatter_profile=_Virgo Web Server - Code Formatter
+formatter_settings_version=12
+internal.default.compliance=default
+org.eclipse.jdt.ui.exception.name=e
+org.eclipse.jdt.ui.gettersetter.use.is=true
+org.eclipse.jdt.ui.keywordthis=false
+org.eclipse.jdt.ui.overrideannotation=true
+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_methods=false
+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=true
+sp_cleanup.correct_indentation=true
+sp_cleanup.format_source_code=true
+sp_cleanup.format_source_code_changes_only=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=true
+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=true
+sp_cleanup.qualify_static_method_accesses_with_declaring_class=false
+sp_cleanup.remove_private_constructors=true
+sp_cleanup.remove_trailing_whitespaces=true
+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=true
+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=true
+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/org.eclipse.virgo.ide.pde.core/.settings/org.eclipse.ltk.core.refactoring.prefs b/org.eclipse.virgo.ide.pde.core/.settings/org.eclipse.ltk.core.refactoring.prefs
new file mode 100644
index 0000000..5e7f2bd
--- /dev/null
+++ b/org.eclipse.virgo.ide.pde.core/.settings/org.eclipse.ltk.core.refactoring.prefs
@@ -0,0 +1,3 @@
+#Tue Aug 18 22:42:26 PDT 2009
+eclipse.preferences.version=1
+org.eclipse.ltk.core.refactoring.enable.project.refactoring.history=false
diff --git a/org.eclipse.virgo.ide.pde.core/.settings/org.eclipse.mylyn.tasks.ui.prefs b/org.eclipse.virgo.ide.pde.core/.settings/org.eclipse.mylyn.tasks.ui.prefs
new file mode 100644
index 0000000..d8c6d26
--- /dev/null
+++ b/org.eclipse.virgo.ide.pde.core/.settings/org.eclipse.mylyn.tasks.ui.prefs
@@ -0,0 +1,4 @@
+#Mon Jun 25 03:02:37 GMT 2007
+eclipse.preferences.version=1
+project.repository.kind=bugzilla
+project.repository.url=https\://bugs.eclipse.org/bugs
diff --git a/org.eclipse.virgo.ide.pde.core/.settings/org.eclipse.pde.core.prefs b/org.eclipse.virgo.ide.pde.core/.settings/org.eclipse.pde.core.prefs
new file mode 100644
index 0000000..455d78f
--- /dev/null
+++ b/org.eclipse.virgo.ide.pde.core/.settings/org.eclipse.pde.core.prefs
@@ -0,0 +1,19 @@
+#Thu Mar 05 23:16:15 CET 2009
+eclipse.preferences.version=1
+resolve.requirebundle=false
+compilers.incompatible-environment=1
+compilers.p.build=1
+compilers.p.deprecated=1
+compilers.p.discouraged-class=2
+compilers.p.missing-bundle-classpath-entries=1
+compilers.p.missing-packages=1
+compilers.p.no-required-att=0
+compilers.p.not-externalized-att=2
+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.use-project=true
diff --git a/org.eclipse.virgo.ide.pde.core/META-INF/MANIFEST.MF b/org.eclipse.virgo.ide.pde.core/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..2d8da20
--- /dev/null
+++ b/org.eclipse.virgo.ide.pde.core/META-INF/MANIFEST.MF
@@ -0,0 +1,16 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: %Bundle-Name
+Bundle-SymbolicName: org.eclipse.virgo.ide.pde.core;singleton:=true
+Bundle-Version: 1.0.1.qualifier
+Bundle-Vendor: %Bundle-Vendor
+Bundle-RequiredExecutionEnvironment: J2SE-1.5
+Require-Bundle: org.eclipse.core.runtime,
+ org.eclipse.debug.core,
+ org.eclipse.jdt.core,
+ org.eclipse.pde.core,
+ org.eclipse.wst.common.project.facet.core,
+ org.eclipse.virgo.ide.facet.core
+Export-Package: org.eclipse.virgo.ide.pde.core.internal,
+ org.eclipse.virgo.ide.pde.core.internal.cmd
+Bundle-Localization: OSGI-INF/l10n/bundle
diff --git a/org.eclipse.virgo.ide.pde.core/OSGI-INF/l10n/bundle.properties b/org.eclipse.virgo.ide.pde.core/OSGI-INF/l10n/bundle.properties
new file mode 100644
index 0000000..3f72026
--- /dev/null
+++ b/org.eclipse.virgo.ide.pde.core/OSGI-INF/l10n/bundle.properties
@@ -0,0 +1,5 @@
+Bundle-Name=Eclipse Virgo IDE (PDE Support)
+Bundle-Vendor=Eclipse.org - Virgo
+
+pdeNature=Eclipse Virgo PDE nature
+pdeBuilder=Eclipse Virgo PDE builder
diff --git a/org.eclipse.virgo.ide.pde.core/about.html b/org.eclipse.virgo.ide.pde.core/about.html
new file mode 100644
index 0000000..2abb573
--- /dev/null
+++ b/org.eclipse.virgo.ide.pde.core/about.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"/>
+<title>About</title>
+</head>
+<body lang="EN-US">
+<h2>About This Content</h2>
+
+<p>April 13, 2012</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 1.0 ("EPL"). A copy of the EPL is available
+at <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a>.
+For purposes of the EPL, "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/org.eclipse.virgo.ide.pde.core/build.properties b/org.eclipse.virgo.ide.pde.core/build.properties
new file mode 100644
index 0000000..57e388d
--- /dev/null
+++ b/org.eclipse.virgo.ide.pde.core/build.properties
@@ -0,0 +1,8 @@
+source.. = src/
+output.. = bin/
+bin.includes = plugin.xml,\
+ META-INF/,\
+ .,\
+ OSGI-INF/l10n/bundle.properties,\
+ OSGI-INF/,\
+ .options
diff --git a/org.eclipse.virgo.ide.pde.core/plugin.xml b/org.eclipse.virgo.ide.pde.core/plugin.xml
new file mode 100644
index 0000000..b6eb52c
--- /dev/null
+++ b/org.eclipse.virgo.ide.pde.core/plugin.xml
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.4"?>
+<!--
+/*******************************************************************************
+ * Copyright (c) 2015 GianMaria Romanato
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * GianMaria Romanato - initial API and implementation
+ *******************************************************************************/
+-->
+<plugin>
+
+ <extension
+ id="builder"
+ name="%pdeBuilder"
+ point="org.eclipse.core.resources.builders">
+ <builder
+ hasNature="true">
+ <run
+ class="org.eclipse.virgo.ide.pde.core.internal.Builder">
+ </run>
+ </builder>
+ </extension>
+ <extension
+ id="nature"
+ name="%pdeNature"
+ point="org.eclipse.core.resources.natures">
+ <runtime>
+ <run
+ class="org.eclipse.virgo.ide.pde.core.internal.Nature">
+ </run>
+ </runtime>
+ <builder
+ id="org.eclipse.virgo.ide.pde.core.builder">
+ </builder>
+ <requires-nature
+ id="org.eclipse.virgo.ide.facet.core.bundlenature">
+ </requires-nature>
+ <requires-nature
+ id="org.eclipse.pde.PluginNature">
+ </requires-nature>
+ </extension>
+
+</plugin>
diff --git a/org.eclipse.virgo.ide.pde.core/pom.xml b/org.eclipse.virgo.ide.pde.core/pom.xml
new file mode 100644
index 0000000..eb81e8d
--- /dev/null
+++ b/org.eclipse.virgo.ide.pde.core/pom.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <artifactId>org.eclipse.virgo.ide.parent</artifactId>
+ <groupId>org.eclipse.virgo.ide</groupId>
+ <version>1.0.1-SNAPSHOT</version>
+ </parent>
+ <artifactId>org.eclipse.virgo.ide.pde.core</artifactId>
+ <packaging>eclipse-plugin</packaging>
+</project>
diff --git a/org.eclipse.virgo.ide.pde.core/src/org/eclipse/virgo/ide/pde/core/internal/Builder.java b/org.eclipse.virgo.ide.pde.core/src/org/eclipse/virgo/ide/pde/core/internal/Builder.java
new file mode 100644
index 0000000..6395edf
--- /dev/null
+++ b/org.eclipse.virgo.ide.pde.core/src/org/eclipse/virgo/ide/pde/core/internal/Builder.java
@@ -0,0 +1,369 @@
+/*******************************************************************************
+ * Copyright (c) 2015 GianMaria Romanato
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * GianMaria Romanato - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.virgo.ide.pde.core.internal;
+
+import static org.eclipse.virgo.ide.pde.core.internal.Constants.META_INF;
+import static org.eclipse.virgo.ide.pde.core.internal.Constants.OSGI_INF;
+import static org.eclipse.virgo.ide.pde.core.internal.Constants.WebContent;
+import static org.eclipse.virgo.ide.pde.core.internal.Helper.DEBUG;
+
+import java.util.Map;
+
+import org.eclipse.core.resources.IFolder;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IResourceDelta;
+import org.eclipse.core.resources.IncrementalProjectBuilder;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.core.runtime.SubMonitor;
+import org.eclipse.core.runtime.SubProgressMonitor;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.osgi.util.NLS;
+
+/**
+ * A custom build command that ensures that the content of META-INF is copied to the binary folder of the plug-in
+ * project so that Virgo Server can find it via class-path.
+ * <p>
+ * Additionally the builder parsers the MANIFEST.MF and copies to bin folder any nested JAR (Bundle-ClassPath header)
+ * and native libraries (Bundle-NativeCode header).
+ *
+ *
+ *
+ */
+public class Builder extends IncrementalProjectBuilder {
+
+ private static final Path WEBCONTENT_PATH = new Path(Constants.WebContent);
+
+ private static final Path OSGI_INF_PATH = new Path(OSGI_INF);
+
+ private static final Path META_INF_PATH = new Path(META_INF);
+
+ private static abstract class Predicate<T> {
+
+ public abstract boolean accept(T t);
+
+ public final static <T> Predicate<T> tautology() {
+ return new Predicate<T>() {
+
+ @Override
+ public boolean accept(T t) {
+ return true;
+ }
+ };
+ }
+ }
+
+ public Builder() {
+ super();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.core.internal.events.InternalBuilder#build(int, java.util.Map,
+ * org.eclipse.core.runtime.IProgressMonitor)
+ */
+ @Override
+ @SuppressWarnings("rawtypes")
+ protected IProject[] build(int kind, Map args, IProgressMonitor monitor) throws CoreException {
+ Helper.forcePDEEditor(getProject());
+
+ IPath outputLocation = Helper.getOutputLocation(getProject());
+
+ if (DEBUG) {
+ String typeStr = "UNKNOWN"; //$NON-NLS-1$
+ switch (kind) {
+ case INCREMENTAL_BUILD:
+ typeStr = "INCREMENTAL"; //$NON-NLS-1$
+ break;
+ case AUTO_BUILD:
+ typeStr = "AUTO"; //$NON-NLS-1$
+ break;
+ case CLEAN_BUILD:
+ typeStr = "CLEAN"; //$NON-NLS-1$
+ break;
+ case FULL_BUILD:
+ typeStr = "FULL"; //$NON-NLS-1$
+ break;
+ }
+ debug("Build type " + typeStr + " output location: " + outputLocation.toString()); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+
+ if (kind == CLEAN_BUILD) {
+ if (DEBUG) {
+ debug("Doing nothing"); //$NON-NLS-1$
+ }
+ return null;
+ }
+
+ if (kind == FULL_BUILD) {
+ fullBuild(outputLocation, monitor);
+ } else {
+ IResourceDelta delta = getDelta(getProject());
+ if (delta == null) {
+ if (DEBUG) {
+ debug("Incremental build was requested but delta is null, performing full build"); //$NON-NLS-1$
+ }
+ fullBuild(outputLocation, monitor);
+ return null;
+ }
+
+ if (!Helper.checkMETAINFFolder(getProject())) {
+ if (DEBUG) {
+ debug("Incremental build was requested but META-INF folder is missing from output location, performing full build"); //$NON-NLS-1$
+ }
+ fullBuild(outputLocation, monitor);
+ return null;
+ }
+
+ if (!Helper.checkLibraries(getProject())) {
+ if (DEBUG) {
+ debug("Incremental build was requested but some libraries are missing from output location, performing full build"); //$NON-NLS-1$
+ }
+ fullBuild(outputLocation, monitor);
+ return null;
+ }
+
+ if (DEBUG) {
+ debug("Incremental build"); //$NON-NLS-1$
+ }
+ incrementalBuild(outputLocation, delta, monitor);
+ return null;
+ }
+
+ return null;
+ }
+
+ private void incrementalBuild(IPath outputLocation, final IResourceDelta delta, IProgressMonitor monitor) throws CoreException {
+ monitor.beginTask(Messages.Builder_IncrementalBuildMessage, 4);
+
+ if (delta.findMember(META_INF_PATH) != null) {
+ buildMetaInf(outputLocation, new SubProgressMonitor(monitor, 1));
+ } else {
+ monitor.worked(1);
+ }
+
+ if (delta.findMember(OSGI_INF_PATH) != null) {
+ buildOSGIInf(outputLocation, new SubProgressMonitor(monitor, 1));
+ } else {
+ monitor.worked(1);
+ }
+
+ if (delta.findMember(WEBCONTENT_PATH) != null) {
+ buildWebContent(outputLocation, new SubProgressMonitor(monitor, 1));
+ } else {
+ monitor.worked(1);
+ }
+
+ Predicate<String> selectChanged = new Predicate<String>() {
+
+ @Override
+ public boolean accept(String t) {
+ return delta.findMember(new Path(t)) != null;
+ }
+ };
+ buildLibraries(selectChanged, outputLocation, new SubProgressMonitor(monitor, 1));
+ monitor.done();
+ }
+
+ private void fullBuild(IPath outputLocation, IProgressMonitor monitor) throws CoreException {
+ if (DEBUG) {
+ debug("Full build, output location: " + outputLocation.toOSString()); //$NON-NLS-1$
+ }
+ monitor.beginTask(Messages.Builder_FullBuildMessage, 4);
+
+ buildMetaInf(outputLocation, new SubProgressMonitor(monitor, 1));
+ buildOSGIInf(outputLocation, new SubProgressMonitor(monitor, 1));
+ buildWebContent(outputLocation, new SubProgressMonitor(monitor, 1));
+
+ buildLibraries(null, outputLocation, new SubProgressMonitor(monitor, 1));
+
+ monitor.done();
+
+ }
+
+ private void buildLibraries(Predicate<String> predicate, IPath outputLocation, IProgressMonitor monitor) throws CoreException {
+ IFolder binFolder = ResourcesPlugin.getWorkspace().getRoot().getFolder(outputLocation);
+ binFolder.refreshLocal(IResource.DEPTH_ONE, null);
+
+ java.util.List<String> toCopy = Helper.getLibraryEntries(getProject());
+
+ monitor.beginTask(Messages.Builder_copy_libraries, toCopy.size());
+ for (String path : toCopy) {
+ if (predicate == null || predicate.accept(path)) {
+ Helper.copyLibraryToBin(getProject(), path);
+ }
+ monitor.worked(1);
+ }
+ monitor.done();
+ }
+
+ private void buildWebContent(IPath outputLocation, IProgressMonitor monitor) throws CoreException, JavaModelException {
+ IFolder webContentFolder = getProject().getFolder(WebContent);
+ if (webContentFolder.exists()) {
+ buildFilesInFolder(monitor, webContentFolder, ResourcesPlugin.getWorkspace().getRoot().getFolder(outputLocation),
+ Predicate.<IResource> tautology(), true);
+
+ }
+ }
+
+ private void buildMetaInf(IPath outputLocation, IProgressMonitor monitor) throws CoreException, JavaModelException {
+ IProject project = getProject();
+ IFolder infFolder = project.getFolder(META_INF);
+
+ if (!infFolder.exists()) {
+ error(META_INF + " folder not found for project: " + getProject().getName()); //$NON-NLS-1$
+ return;
+ }
+ buildTopLevelFolder(outputLocation, monitor, infFolder, META_INF);
+ }
+
+ private void buildOSGIInf(IPath outputLocation, IProgressMonitor monitor) throws CoreException, JavaModelException {
+ IProject project = getProject();
+ IFolder infFolder = project.getFolder(OSGI_INF);
+
+ if (!infFolder.exists()) {
+ return;
+ }
+ buildTopLevelFolder(outputLocation, monitor, infFolder, OSGI_INF);
+ }
+
+ private void buildTopLevelFolder(IPath outputLocation, IProgressMonitor monitor, IFolder infFolder, String folder) throws CoreException {
+ IFolder binFolder = ResourcesPlugin.getWorkspace().getRoot().getFolder(outputLocation);
+ if (!binFolder.exists()) {
+ binFolder.create(true, true, null);
+ } else {
+ if (!binFolder.isSynchronized(IResource.DEPTH_ONE)) {
+ binFolder.refreshLocal(IResource.DEPTH_ONE, null);
+ }
+ }
+ IFolder binaryInfFolder = binFolder.getFolder(folder);
+ if (!binaryInfFolder.exists()) {
+ binaryInfFolder.create(true, true, null);
+ } else {
+ if (!binaryInfFolder.isSynchronized(IResource.DEPTH_ONE)) {
+ binaryInfFolder.refreshLocal(IResource.DEPTH_ONE, null);
+ }
+ }
+
+ buildFilesInFolder(monitor, infFolder, binaryInfFolder, Predicate.<IResource> tautology(), false);
+ monitor.done();
+ }
+
+ private void buildRootFolder(IPath outputLocation, IProgressMonitor monitor) throws CoreException, JavaModelException {
+ IProject project = getProject();
+ IFolder infFolder = project.getFolder(META_INF);
+
+ if (!infFolder.exists()) {
+ error(META_INF + " folder not found for project: " + getProject().getName()); //$NON-NLS-1$
+ return;
+ }
+
+ IFolder binFolder = ResourcesPlugin.getWorkspace().getRoot().getFolder(outputLocation);
+ if (!binFolder.exists()) {
+ binFolder.create(true, true, null);
+ } else {
+ if (!binFolder.isSynchronized(IResource.DEPTH_ONE)) {
+ binFolder.refreshLocal(IResource.DEPTH_ONE, null);
+ }
+ }
+ IFolder binaryInfFolder = binFolder.getFolder(META_INF);
+ if (!binaryInfFolder.exists()) {
+ binaryInfFolder.create(true, true, null);
+ } else {
+ if (!binaryInfFolder.isSynchronized(IResource.DEPTH_ONE)) {
+ binaryInfFolder.refreshLocal(IResource.DEPTH_ONE, null);
+ }
+ }
+
+ buildFilesInFolder(monitor, infFolder, binaryInfFolder, Predicate.<IResource> tautology(), false);
+ monitor.done();
+ }
+
+ private void buildFilesInFolder(IProgressMonitor monitor, IFolder from, IFolder to, Predicate<IResource> predicate, boolean merge)
+ throws CoreException {
+ IResource[] children = from.members();
+
+ SubMonitor sub = SubMonitor.convert(monitor, children.length);
+
+ sub.beginTask(NLS.bind(Messages.Builder_CopyContent, from.getName()), children.length);
+ for (IResource sourceResource : children) {
+ if (predicate.accept(sourceResource)) {
+ if (!sourceResource.isTeamPrivateMember() && !sourceResource.isDerived()) {
+ IPath targetPath = to.getFullPath().append(sourceResource.getName());
+ IResource targetResource = ResourcesPlugin.getWorkspace().getRoot().findMember(targetPath);
+ if (targetResource != null && targetResource.exists()) {
+ if (DEBUG) {
+ debug(targetResource.getFullPath().toString() + " exists"); //$NON-NLS-1$
+ }
+ targetResource.refreshLocal(IResource.DEPTH_INFINITE, null);
+
+ if (targetResource.getType() == IResource.FILE) {
+ replaceFile(sourceResource, targetResource);
+ } else {
+ recurseInFolder(sourceResource, targetResource, predicate, merge);
+ }
+ } else {
+ // resource did not exist in target folder, just copy
+ sourceResource.copy(targetPath, true, null);
+ if (DEBUG) {
+ debug("Copied " + sourceResource.getFullPath().toString() + " to " + targetPath.toString()); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+ }
+ }
+ sub.worked(1);
+ }
+ }
+ monitor.done();
+ }
+
+ private void recurseInFolder(IResource from, IResource to, Predicate<IResource> predicate, boolean merge) throws CoreException {
+ IPath toPath = to.getFullPath();
+ if (!merge) {
+ to.delete(true, null);
+ from.copy(toPath, true, null);
+ if (DEBUG) {
+ debug("Copied " + from.getFullPath().toString() + " to " + toPath.toString()); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+ } else {
+ buildFilesInFolder(new NullProgressMonitor(), (IFolder) from, (IFolder) to, predicate, true);
+ if (DEBUG) {
+ debug("Merged " + from.getFullPath().toString() + " into " + toPath.toString()); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+ }
+ }
+
+ private void replaceFile(IResource from, IResource to) throws CoreException {
+ to.delete(true, null);
+ if (DEBUG) {
+ debug(to.getFullPath().toString() + " deleted"); //$NON-NLS-1$
+ }
+ from.copy(to.getFullPath(), true, null);
+ if (DEBUG) {
+ debug("Copied " + from.getFullPath().toString() + " to " + to.getFullPath().toString()); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+ }
+
+ private void debug(String string) {
+ Helper.debug(getProject().getName() + " - " + string); //$NON-NLS-1$
+ }
+
+ private void error(String string) {
+ Helper.error(getProject().getName() + " - " + string); //$NON-NLS-1$
+ }
+
+}
diff --git a/org.eclipse.virgo.ide.pde.core/src/org/eclipse/virgo/ide/pde/core/internal/Constants.java b/org.eclipse.virgo.ide.pde.core/src/org/eclipse/virgo/ide/pde/core/internal/Constants.java
new file mode 100644
index 0000000..e9d7bb7
--- /dev/null
+++ b/org.eclipse.virgo.ide.pde.core/src/org/eclipse/virgo/ide/pde/core/internal/Constants.java
@@ -0,0 +1,45 @@
+/*******************************************************************************
+ * Copyright (c) 2015 GianMaria Romanato
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * GianMaria Romanato - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.virgo.ide.pde.core.internal;
+
+/**
+ * Constant values.
+ *
+ */
+public final class Constants {
+
+ /**
+ * Bundle symbolic name.
+ */
+ public static final String PLUGIN_ID = "org.eclipse.virgo.ide.pde.core";//$NON-NLS-1$
+
+ /**
+ * Nature-id.
+ */
+ public static final String NATURE_ID = PLUGIN_ID + ".nature"; //$NON-NLS-1$
+
+ /** Builder-id. */
+ public static final String BUILDER_ID = PLUGIN_ID + ".builder"; //$NON-NLS-1$
+
+ /* debug key */
+ /* package */ static final String DEBUG_KEY = PLUGIN_ID + "/debug"; //$NON-NLS-1$
+
+ // path constants
+ /* package */ static final String META_INF = "META-INF"; //$NON-NLS-1$
+ /* package */ static final String OSGI_INF = "OSGI-INF"; //$NON-NLS-1$
+ /* package */ static final String MANIFEST_MF = "MANIFEST.MF"; //$NON-NLS-1$
+ /* package */ static final String WebContent = "WebContent"; //$NON-NLS-1$
+
+ private Constants() {
+ }
+
+}
diff --git a/org.eclipse.virgo.ide.pde.core/src/org/eclipse/virgo/ide/pde/core/internal/Helper.java b/org.eclipse.virgo.ide.pde.core/src/org/eclipse/virgo/ide/pde/core/internal/Helper.java
new file mode 100644
index 0000000..cefd0c2
--- /dev/null
+++ b/org.eclipse.virgo.ide.pde.core/src/org/eclipse/virgo/ide/pde/core/internal/Helper.java
@@ -0,0 +1,312 @@
+/*******************************************************************************
+ * Copyright (c) 2015 GianMaria Romanato
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * GianMaria Romanato - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.virgo.ide.pde.core.internal;
+
+import static org.eclipse.virgo.ide.pde.core.internal.Constants.MANIFEST_MF;
+import static org.eclipse.virgo.ide.pde.core.internal.Constants.META_INF;
+import static org.eclipse.virgo.ide.pde.core.internal.Constants.PLUGIN_ID;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IFolder;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.ILog;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.core.runtime.QualifiedName;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.jdt.core.IClasspathEntry;
+import org.eclipse.jdt.core.IJavaProject;
+import org.eclipse.jdt.core.JavaCore;
+import org.eclipse.osgi.util.ManifestElement;
+import org.osgi.framework.BundleException;
+import org.osgi.framework.FrameworkUtil;
+
+/**
+ * A Helper class used by the builder.
+ * <p />
+ */
+public class Helper {
+
+ /* package */ static boolean DEBUG = "true".equals(Platform.getDebugOption(Constants.DEBUG_KEY)); //$NON-NLS-1$
+
+ private static ILog log = Platform.getLog(FrameworkUtil.getBundle(Helper.class));
+
+ /* key for the preferred editor persistent property, see org.eclipse.ide.ui.IDE */
+ private static final QualifiedName EDITOR_PROPERTY = new QualifiedName("org.eclipse.ui.internal.registry.ResourceEditorRegistry", //$NON-NLS-1$
+ "EditorProperty"); //$NON-NLS-1$
+
+ /* ID of the PDE plug-in manifest editor, see org.eclipse.pde.internal.ui.IPDEUIConstants */
+ private static final String EDITOR_VALUE = "org.eclipse.pde.ui.manifestEditor"; //$NON-NLS-1$
+
+ /**
+ * emit debug log
+ */
+ /* package */ static void debug(String message) {
+ log.log(new Status(IStatus.OK, PLUGIN_ID, message));
+ }
+
+ /**
+ * emit error log
+ */
+ /* package */ static void error(String message) {
+ log.log(new Status(IStatus.ERROR, PLUGIN_ID, message));
+ }
+
+ /**
+ * Tells whether a META-INF folder exists in the output location that contains a MANIFEST.MF file
+ *
+ * @param outputLocation
+ * @return
+ * @throws CoreException
+ */
+ static boolean checkMETAINFFolder(IProject project) throws CoreException {
+ IPath outputLocation = getOutputLocation(project);
+ IFolder binFolder = ResourcesPlugin.getWorkspace().getRoot().getFolder(outputLocation);
+ if (!binFolder.exists()) {
+ if (DEBUG) {
+ debug("Creating bin folder"); //$NON-NLS-1$
+ }
+ binFolder.create(true, true, null);
+ return false;
+ } else {
+ if (DEBUG) {
+ debug("Refreshing bin folder"); //$NON-NLS-1$
+ }
+ binFolder.refreshLocal(IResource.DEPTH_ONE, null);
+ }
+ IFolder binaryMetaInf = binFolder.getFolder(META_INF);
+ if (!binaryMetaInf.exists()) {
+ if (DEBUG) {
+ debug("Creating bin/META-INF"); //$NON-NLS-1$
+ }
+ binaryMetaInf.create(true, true, null);
+ return false;
+ } else {
+ if (DEBUG) {
+ debug("bin/META-INF already exists, refreshing"); //$NON-NLS-1$
+ }
+ binaryMetaInf.refreshLocal(IResource.DEPTH_INFINITE, null);
+ }
+ IFile binaryManifest = binaryMetaInf.getFile(MANIFEST_MF);
+ if (!binaryManifest.exists()) {
+ if (DEBUG) {
+ debug("bin/META-INF/MANIFEST.MF does not exist"); //$NON-NLS-1$
+ }
+ return false;
+ }
+ return true;
+ }
+
+ /* package */ static java.util.List<String> getLibraryEntries(IProject project) throws CoreException {
+ java.util.List<String> toCopy = getEntries(project);
+ if (DEBUG) {
+ debug("JARS declared in manifest: " + Arrays.toString(toCopy.toArray())); //$NON-NLS-1$
+ }
+ return toCopy;
+ }
+
+ private static java.util.List<String> getEntries(IProject project) throws CoreException {
+ IFolder metaInf = project.getFolder(META_INF);
+ if (!metaInf.exists()) {
+ return Collections.emptyList();
+ }
+
+ IFile manifest = metaInf.getFile(MANIFEST_MF);
+ if (!manifest.exists()) {
+ return Collections.emptyList();
+ }
+
+ HashMap<String, String> manifestEntries = new HashMap<String, String>();
+ try {
+ ManifestElement.parseBundleManifest(manifest.getContents(), manifestEntries);
+ } catch (Exception e) {
+ throw new CoreException(new Status(IStatus.ERROR, PLUGIN_ID, Messages.Helper_ManifestParsingError, e));
+ }
+
+ java.util.List<String> toCopy = new ArrayList<String>();
+
+ String rawValue = manifestEntries.get("Bundle-ClassPath"); //$NON-NLS-1$
+ if (rawValue != null) {
+ String[] classpathEntries = ManifestElement.getArrayFromList(rawValue);
+ for (String classpathEntry : classpathEntries) {
+ if (".".equals(classpathEntry)) { //$NON-NLS-1$
+ continue;
+ } else if (!classpathEntry.toLowerCase().endsWith(".jar")) {
+ continue;
+ } else {
+ toCopy.add(classpathEntry);
+ }
+ }
+ }
+
+ rawValue = manifestEntries.get("Bundle-NativeCode"); //$NON-NLS-1$
+ if (rawValue != null) {
+ ManifestElement[] value;
+ try {
+ value = ManifestElement.parseHeader("Bundle-NativeCode", rawValue); //$NON-NLS-1$
+ } catch (BundleException e) {
+ throw new CoreException(new Status(IStatus.ERROR, PLUGIN_ID, Messages.Helper_ManifestParsingError, e));
+ }
+ for (ManifestElement manifestElement : value) {
+ toCopy.add(manifestElement.getValue());
+ }
+ }
+
+ return toCopy;
+ }
+
+ /**
+ * Gets the output location of the project. Either returns the global output location or the first output location
+ * found for a source folder.
+ *
+ * @return
+ * @throws CoreException
+ */
+ /* package */ static IPath getOutputLocation(IProject project) throws CoreException {
+ IJavaProject jp = (IJavaProject) project.getNature(JavaCore.NATURE_ID);
+ IPath outputLocation = jp.getOutputLocation();
+
+ if (outputLocation == null) {
+ IClasspathEntry[] entries = jp.getRawClasspath();
+
+ for (IClasspathEntry iClasspathEntry : entries) {
+ if (iClasspathEntry.getEntryKind() == IClasspathEntry.CPE_SOURCE) {
+ outputLocation = iClasspathEntry.getOutputLocation();
+ if (outputLocation != null) {
+ break;
+ }
+ }
+ }
+ }
+
+ if (outputLocation == null) {
+ throw new CoreException(new Status(IStatus.ERROR, PLUGIN_ID, Messages.Helper_BinFolderError));
+ }
+ return outputLocation;
+ }
+
+ /**
+ * Copies a library pointed by the given MANIFEST.MF classpath under the outputlocation
+ *
+ * @param project
+ * @param path
+ * @param outputLocation
+ * @throws CoreException
+ */
+ /* package */ static void copyLibraryToBin(IProject project, String path) throws CoreException {
+ IPath outputLocation = getOutputLocation(project);
+ IFolder binFolder = ResourcesPlugin.getWorkspace().getRoot().getFolder(outputLocation);
+
+ IResource target = binFolder.findMember(path);
+
+ if (target != null && target.exists()) {
+ if (DEBUG) {
+ debug(path + " already exists, deleting"); //$NON-NLS-1$
+ }
+ target.delete(true, null);
+ if (DEBUG) {
+ debug(path + " deleted"); //$NON-NLS-1$
+ }
+ }
+ IResource libraryResource = project.findMember(new Path(path));
+ if (libraryResource != null) {
+ IPath destinationPath = binFolder.getFullPath().append(path);
+ IPath binRelativePath = destinationPath.removeFirstSegments(outputLocation.segmentCount());
+ binRelativePath = binRelativePath.removeLastSegments(1);
+ int segmentCount = binRelativePath.segmentCount();
+ if (segmentCount > 0) {
+ for (int i = 0; i < segmentCount; i++) {
+ IFolder aFolder = binFolder.getFolder(binRelativePath.removeLastSegments(segmentCount - 1 - i));
+ if (!aFolder.exists()) {
+ if (DEBUG) {
+ debug("parent folder does not exist: " + aFolder.getFullPath().toString()); //$NON-NLS-1$
+ }
+ aFolder.create(true, true, null);
+ if (DEBUG) {
+ debug("parent folder created"); //$NON-NLS-1$
+ }
+ }
+ }
+ }
+
+ switch (libraryResource.getType()) {
+ case IResource.FILE:
+ IFile libraryFile = project.getFile(new Path(path));
+ libraryFile.copy(destinationPath, true, null);
+ break;
+ case IResource.FOLDER:
+ IFolder libraryFolder = project.getFolder(new Path(path));
+ libraryFolder.copy(destinationPath, true, null);
+ break;
+ }
+ if (DEBUG) {
+ debug("copied " + libraryResource.getFullPath().toString() + " to " + destinationPath.toString()); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+ } else {
+ if (DEBUG) {
+ debug("Manifest contains unexisting library entry: " + path); //$NON-NLS-1$
+ }
+ }
+
+ }
+
+ /* package */ static boolean checkLibraries(IProject project) throws CoreException {
+
+ List<String> entries = getLibraryEntries(project);
+ if (entries.isEmpty()) {
+ return true;
+ }
+ return checkFilesExist(project, entries);
+ }
+
+ private static boolean checkFilesExist(IProject project, List<String> entries) throws CoreException {
+ IPath outputLocation = getOutputLocation(project);
+ for (String string : entries) {
+ if (project.getFile(string).exists()) { // iff the library really exists
+ IPath binFile = outputLocation.append(string);
+ IResource res = ResourcesPlugin.getWorkspace().getRoot().findMember(binFile);
+ if (res == null) {
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+
+ public static void forcePDEEditor(IProject project) {
+ IFolder metaInf = project.getFolder(META_INF);
+ if (metaInf.exists()) {
+ IFile manifest = metaInf.getFile(MANIFEST_MF);
+ if (manifest.exists()) {
+ // quick hack to force Eclipse to use the PDE editor
+ try {
+ manifest.setPersistentProperty(EDITOR_PROPERTY, EDITOR_VALUE);
+ } catch (CoreException e) {
+ if (DEBUG) {
+ log.log(e.getStatus());
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/org.eclipse.virgo.ide.pde.core/src/org/eclipse/virgo/ide/pde/core/internal/Messages.java b/org.eclipse.virgo.ide.pde.core/src/org/eclipse/virgo/ide/pde/core/internal/Messages.java
new file mode 100644
index 0000000..60a9283
--- /dev/null
+++ b/org.eclipse.virgo.ide.pde.core/src/org/eclipse/virgo/ide/pde/core/internal/Messages.java
@@ -0,0 +1,42 @@
+/*******************************************************************************
+ * Copyright (c) 2015 GianMaria Romanato
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * GianMaria Romanato - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.virgo.ide.pde.core.internal;
+
+import org.eclipse.osgi.util.NLS;
+
+/**
+ * Localization support.
+ */
+public class Messages extends NLS {
+
+ public static String Builder_copy_nativecode;
+
+ public static String Builder_IncrementalBuildMessage;
+
+ public static String Builder_FullBuildMessage;
+
+ public static String Builder_copy_libraries;
+
+ public static String Builder_CopyContent;
+
+ public static String Helper_BinFolderError;
+
+ public static String Helper_ManifestParsingError;
+
+ static {
+ // initialize resource bundle
+ NLS.initializeMessages(Messages.class.getName(), Messages.class);
+ }
+
+ private Messages() {
+ }
+}
diff --git a/org.eclipse.virgo.ide.pde.core/src/org/eclipse/virgo/ide/pde/core/internal/Messages.properties b/org.eclipse.virgo.ide.pde.core/src/org/eclipse/virgo/ide/pde/core/internal/Messages.properties
new file mode 100644
index 0000000..6289cac
--- /dev/null
+++ b/org.eclipse.virgo.ide.pde.core/src/org/eclipse/virgo/ide/pde/core/internal/Messages.properties
@@ -0,0 +1,8 @@
+Builder_IncrementalBuildMessage=Incremental build
+Builder_FullBuildMessage=Publishing plug-in resources to binary location
+Builder_copy_libraries=Copying libraries to output folder
+Builder_copy_nativecode=Copying native code to output folder
+Builder_CopyContent=Copying {0} to output folder
+Helper_BinFolderError=Cannot find a binary folder
+Helper_ManifestParsingError=Error parsing manifest
+
diff --git a/org.eclipse.virgo.ide.pde.core/src/org/eclipse/virgo/ide/pde/core/internal/Nature.java b/org.eclipse.virgo.ide.pde.core/src/org/eclipse/virgo/ide/pde/core/internal/Nature.java
new file mode 100644
index 0000000..5fd56bb
--- /dev/null
+++ b/org.eclipse.virgo.ide.pde.core/src/org/eclipse/virgo/ide/pde/core/internal/Nature.java
@@ -0,0 +1,91 @@
+/*******************************************************************************
+ * Copyright (c) 2015 GianMaria Romanato
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * GianMaria Romanato - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.virgo.ide.pde.core.internal;
+
+import org.eclipse.core.resources.ICommand;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IProjectDescription;
+import org.eclipse.core.resources.IProjectNature;
+import org.eclipse.core.runtime.CoreException;
+
+/**
+ * A marker nature that is used to contribute a custom build command, see {@link Builder}
+ *
+ *
+ */
+public class Nature implements IProjectNature {
+
+ private IProject project;
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.core.resources.IProjectNature#configure()
+ */
+ public void configure() throws CoreException {
+ IProjectDescription desc = this.project.getDescription();
+ ICommand[] commands = desc.getBuildSpec();
+
+ for (ICommand command : commands) {
+ if (command.getBuilderName().equals(Constants.BUILDER_ID)) {
+ return;
+ }
+ }
+
+ ICommand[] newCommands = new ICommand[commands.length + 1];
+ System.arraycopy(commands, 0, newCommands, 0, commands.length);
+ ICommand command = desc.newCommand();
+ command.setBuilderName(Constants.BUILDER_ID);
+ newCommands[newCommands.length - 1] = command;
+ desc.setBuildSpec(newCommands);
+ this.project.setDescription(desc, null);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.core.resources.IProjectNature#deconfigure()
+ */
+ public void deconfigure() throws CoreException {
+ IProjectDescription description = getProject().getDescription();
+ ICommand[] commands = description.getBuildSpec();
+ for (int i = 0; i < commands.length; ++i) {
+ if (commands[i].getBuilderName().equals(Constants.BUILDER_ID)) {
+ ICommand[] newCommands = new ICommand[commands.length - 1];
+ System.arraycopy(commands, 0, newCommands, 0, i);
+ System.arraycopy(commands, i + 1, newCommands, i, commands.length - i - 1);
+ description.setBuildSpec(newCommands);
+ this.project.setDescription(description, null);
+ return;
+ }
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.core.resources.IProjectNature#getProject()
+ */
+ public IProject getProject() {
+ return this.project;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.core.resources.IProjectNature#setProject(org.eclipse.core.resources.IProject)
+ */
+ public void setProject(IProject project) {
+ this.project = project;
+ }
+
+}
diff --git a/org.eclipse.virgo.ide.pde.core/src/org/eclipse/virgo/ide/pde/core/internal/cmd/SetupProjectOperation.java b/org.eclipse.virgo.ide.pde.core/src/org/eclipse/virgo/ide/pde/core/internal/cmd/SetupProjectOperation.java
new file mode 100644
index 0000000..49455e3
--- /dev/null
+++ b/org.eclipse.virgo.ide.pde.core/src/org/eclipse/virgo/ide/pde/core/internal/cmd/SetupProjectOperation.java
@@ -0,0 +1,242 @@
+
+package org.eclipse.virgo.ide.pde.core.internal.cmd;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.UnsupportedEncodingException;
+import java.text.MessageFormat;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IFolder;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IProjectDescription;
+import org.eclipse.core.resources.IWorkspaceRunnable;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.jdt.core.IClasspathEntry;
+import org.eclipse.jdt.core.IJavaProject;
+import org.eclipse.jdt.core.JavaCore;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.pde.core.project.IBundleProjectDescription;
+import org.eclipse.pde.core.project.IBundleProjectService;
+import org.eclipse.virgo.ide.facet.core.FacetCorePlugin;
+import org.eclipse.virgo.ide.pde.core.internal.Constants;
+import org.eclipse.wst.common.project.facet.core.IFacetedProject;
+import org.eclipse.wst.common.project.facet.core.ProjectFacetsManager;
+
+/**
+ * SetupProjectOperation updates an existing PDE project to make it a Virgo-PDE project. If a context root is passed, it
+ * is made a Web Bundle PDE project.
+ * <p>
+ * Note that this runnable is meant to adapt for Virgo a newly created PDE project. It is not intended for migrating a
+ * PDE project that has been modified after initial creation.
+ * <p>
+ */
+public class SetupProjectOperation implements IWorkspaceRunnable {
+
+ private static final String WST_FACET_NATURE = org.eclipse.wst.common.project.facet.core.internal.FacetCorePlugin.PLUGIN_ID + ".nature"; //$NON-NLS-1$
+
+ private static final String WEB_CONTENT_FOLDER = "WebContent"; //$NON-NLS-1$
+
+ private static final String BIN_WEB_INF_CLASSES = "bin/WEB-INF/classes"; //$NON-NLS-1$
+
+ private static final String SRC = "src"; //$NON-NLS-1$
+
+ private static final String BIN = "bin"; //$NON-NLS-1$
+
+ private static final String WEB_XML = "web.xml"; //$NON-NLS-1$
+
+ private static final String INDEX_HTML = "index.html"; //$NON-NLS-1$
+
+ private static final String BUILD_PROPERTIES = "build.properties"; //$NON-NLS-1$
+
+ private static final String UTF_8 = "UTF-8"; //$NON-NLS-1$
+
+ private static final String ISO_8859_1 = "ISO-8859-1"; //$NON-NLS-1$
+
+ private static final String CLASS_PATH_VALUE = ".,WEB-INF/classes"; //$NON-NLS-1$
+
+ private static final String SLASH = "/"; //$NON-NLS-1$
+
+ private static final String HEADER_BUNDLE_CLASS_PATH = "Bundle-ClassPath"; //$NON-NLS-1$
+
+ private static final String HEADER_WEB_CONTEXT_PATH = "Web-ContextPath"; //$NON-NLS-1$
+
+ private final IProject project;
+
+ private final String contextRoot;
+
+ private final IBundleProjectService service;
+
+ /**
+ * Creates a new instance.
+ *
+ * @param project a mandatory project resource
+ * @param contextRoot a context root name or <code>null</code> if the project is not a Web project
+ * @param service a {@link IBundleProjectService} instance
+ */
+ public SetupProjectOperation(IProject project, String contextRoot, IBundleProjectService service) {
+ Assert.isNotNull(project, "project cannot be null"); //$NON-NLS-1$
+ Assert.isNotNull(service, "service cannot be null"); //$NON-NLS-1$
+ this.project = project;
+ this.contextRoot = sanitizeContextRoot(contextRoot);
+ this.service = service;
+ }
+
+ private String sanitizeContextRoot(String contextRoot2) {
+ if (contextRoot2 != null) {
+ if (contextRoot2.startsWith(SLASH)) {
+ contextRoot2 = contextRoot2.substring(1);
+ }
+ }
+ return contextRoot2;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void run(IProgressMonitor monitor) throws CoreException {
+ monitor.beginTask("", 4); //$NON-NLS-1$
+
+ org.eclipse.virgo.ide.pde.core.internal.Helper.forcePDEEditor(project);
+ monitor.worked(1);
+
+ addNatures(project);
+ monitor.worked(1);
+
+ if (contextRoot != null && contextRoot.length() > 0) {
+ IPath webContentPath = configureWABClasspath(project);
+
+ createWebXML(contextRoot, webContentPath);
+ createIndexHTML(contextRoot, webContentPath);
+ createBuildProperties();
+
+ IBundleProjectDescription bundleDescription = service.getDescription(project);
+
+ bundleDescription.setHeader(HEADER_WEB_CONTEXT_PATH, SLASH + contextRoot);
+ bundleDescription.setHeader(HEADER_BUNDLE_CLASS_PATH, CLASS_PATH_VALUE);
+ bundleDescription.apply(null);
+ }
+ monitor.worked(1);
+
+ IFacetedProject fProject = ProjectFacetsManager.create(project.getProject(), true, null);
+ fProject.installProjectFacet(ProjectFacetsManager.getProjectFacet(FacetCorePlugin.BUNDLE_FACET_ID).getDefaultVersion(), null, null);
+ monitor.worked(1);
+ monitor.done();
+ }
+
+ private void createBuildProperties() throws CoreException {
+ String template = readResourceFromClassPath(BUILD_PROPERTIES, ISO_8859_1);
+ IFile file = project.getFile(BUILD_PROPERTIES);
+ try {
+ if (!file.exists()) {
+ file.create(new ByteArrayInputStream(template.getBytes(ISO_8859_1)), true, null);
+ } else {
+ file.setContents(new ByteArrayInputStream(template.getBytes(ISO_8859_1)), true, false, null);
+ }
+ } catch (UnsupportedEncodingException e) {
+ throw new CoreException(new Status(IStatus.ERROR, Constants.PLUGIN_ID, e.getMessage(), e));
+ }
+ }
+
+ private void createIndexHTML(String contextRoot, IPath webContentPath) throws CoreException {
+ createFileFromTemplate(contextRoot, webContentPath, INDEX_HTML, UTF_8);
+ }
+
+ private void createWebXML(String contextRoot, IPath webContentPath) throws CoreException {
+ createFileFromTemplate(contextRoot, webContentPath, WEB_XML, UTF_8);
+ }
+
+ private void createFileFromTemplate(String contextRoot, IPath webContentPath, String fileNane, String charset) throws CoreException {
+ IFolder webContentFolder = ResourcesPlugin.getWorkspace().getRoot().getFolder(webContentPath);
+ if (!webContentFolder.exists()) {
+ webContentFolder.create(true, false, null);
+ }
+
+ IFile file = webContentFolder.getFile(fileNane);
+ if (!file.exists()) {
+ String template = readResourceFromClassPath(fileNane, charset);
+ String newWab = MessageFormat.format(template, contextRoot);
+ try {
+ file.create(new ByteArrayInputStream(newWab.getBytes(charset)), true, null);
+ } catch (UnsupportedEncodingException e) {
+ throw new CoreException(new Status(IStatus.ERROR, Constants.PLUGIN_ID, e.getMessage(), e));
+ }
+ }
+ }
+
+ private String readResourceFromClassPath(String path, String charset) throws CoreException {
+ InputStream is = getClass().getResourceAsStream(path);
+ if (is != null) {
+ try {
+ InputStreamReader r = new InputStreamReader(is, charset);
+ StringBuilder sb = new StringBuilder();
+ int c;
+ while ((c = r.read()) != -1) {
+ sb.append((char) c);
+ }
+ return sb.toString();
+ } catch (IOException e) {
+ throw new CoreException(new Status(IStatus.ERROR, Constants.PLUGIN_ID, e.getMessage(), e));
+ } finally {
+ try {
+ is.close();
+ } catch (IOException e) {
+ }
+ }
+ } else {
+ throw new CoreException(new Status(IStatus.ERROR, Constants.PLUGIN_ID, "Template file missing " + path)); //$NON-NLS-1$
+ }
+
+ }
+
+ private IPath configureWABClasspath(IProject project) throws CoreException, JavaModelException {
+ IJavaProject javaProject = (IJavaProject) project.getNature(JavaCore.NATURE_ID);
+ javaProject.setOutputLocation(project.getFullPath().append(BIN), null);
+ IClasspathEntry[] entries = javaProject.getRawClasspath();
+ IClasspathEntry[] newEntries = new IClasspathEntry[entries.length + 1];
+ for (int i = 0; i < entries.length; i++) {
+ IClasspathEntry iClasspathEntry = entries[i];
+ if (iClasspathEntry.getEntryKind() == IClasspathEntry.CPE_SOURCE && iClasspathEntry.getPath().lastSegment().equals(SRC)) {
+ IClasspathEntry newEntry = JavaCore.newSourceEntry(iClasspathEntry.getPath(), iClasspathEntry.getInclusionPatterns(),
+ iClasspathEntry.getExclusionPatterns(), project.getFullPath().append(BIN_WEB_INF_CLASSES));
+ newEntries[i] = newEntry;
+ break;
+ } else {
+ newEntries[i] = entries[i];
+ }
+ }
+
+ IPath webContentPath = project.getFullPath().append(WEB_CONTENT_FOLDER);
+ newEntries[entries.length] = JavaCore.newLibraryEntry(webContentPath, null, null);
+
+ javaProject.setRawClasspath(newEntries, null);
+ return webContentPath;
+ }
+
+ private IProjectDescription addNatures(IProject project) throws CoreException {
+ IProjectDescription description = project.getDescription();
+ String[] natures = description.getNatureIds();
+
+ // Add the natures
+ String[] newNatures = new String[natures.length + 3];
+ System.arraycopy(natures, 0, newNatures, 0, natures.length);
+
+ // <nature>org.eclipse.wst.common.project.facet.core.nature</nature>
+ newNatures[natures.length + 0] = WST_FACET_NATURE;
+ // <nature>org.eclipse.virgo.ide.facet.core.bundlenature</nature> <nature>
+ newNatures[natures.length + 1] = org.eclipse.virgo.ide.facet.core.FacetCorePlugin.BUNDLE_NATURE_ID;
+ newNatures[natures.length + 2] = org.eclipse.virgo.ide.pde.core.internal.Constants.NATURE_ID;
+
+ description.setNatureIds(newNatures);
+ project.setDescription(description, null);
+ return description;
+ }
+}
diff --git a/org.eclipse.virgo.ide.pde.core/src/org/eclipse/virgo/ide/pde/core/internal/cmd/build.properties b/org.eclipse.virgo.ide.pde.core/src/org/eclipse/virgo/ide/pde/core/internal/cmd/build.properties
new file mode 100644
index 0000000..e11abf1
--- /dev/null
+++ b/org.eclipse.virgo.ide.pde.core/src/org/eclipse/virgo/ide/pde/core/internal/cmd/build.properties
@@ -0,0 +1,6 @@
+source.WEB-INF/classes = src/
+output.WEB-INF/classes = bin/
+source..=WebContent
+output..=bin/
+bin.includes = META-INF/,\
+ .
diff --git a/org.eclipse.virgo.ide.pde.core/src/org/eclipse/virgo/ide/pde/core/internal/cmd/index.html b/org.eclipse.virgo.ide.pde.core/src/org/eclipse/virgo/ide/pde/core/internal/cmd/index.html
new file mode 100644
index 0000000..300233f
--- /dev/null
+++ b/org.eclipse.virgo.ide.pde.core/src/org/eclipse/virgo/ide/pde/core/internal/cmd/index.html
@@ -0,0 +1,8 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 3.2//EN">
+<html>
+<head>
+<title>{0} index page</title>
+</head>
+<body>Welcome to Virgo!
+</body>
+</html>
diff --git a/org.eclipse.virgo.ide.pde.core/src/org/eclipse/virgo/ide/pde/core/internal/cmd/web.xml b/org.eclipse.virgo.ide.pde.core/src/org/eclipse/virgo/ide/pde/core/internal/cmd/web.xml
new file mode 100644
index 0000000..b57ec1e
--- /dev/null
+++ b/org.eclipse.virgo.ide.pde.core/src/org/eclipse/virgo/ide/pde/core/internal/cmd/web.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<web-app id="WebApp_{0}" version="3.0"
+ xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
+ <display-name>{0}</display-name>
+ <welcome-file-list>
+ <welcome-file>index.html</welcome-file>
+ </welcome-file-list>
+</web-app>
\ No newline at end of file
diff --git a/org.eclipse.virgo.ide.runtime.ui/META-INF/MANIFEST.MF b/org.eclipse.virgo.ide.runtime.ui/META-INF/MANIFEST.MF
index f30dab9..3244d6e 100644
--- a/org.eclipse.virgo.ide.runtime.ui/META-INF/MANIFEST.MF
+++ b/org.eclipse.virgo.ide.runtime.ui/META-INF/MANIFEST.MF
@@ -38,7 +38,10 @@
org.eclipse.jdt.ui,
org.eclipse.libra.framework.editor.core,
org.eclipse.libra.framework.editor.ui,
- org.eclipse.ui.workbench.texteditor
+ org.eclipse.ui.workbench.texteditor,
+ org.eclipse.virgo.repository,
+ org.eclipse.virgo.medic,
+ org.eclipse.virgo.util.math
Import-Package: org.apache.commons.lang,
org.apache.commons.logging
Bundle-RequiredExecutionEnvironment: J2SE-1.5
diff --git a/org.eclipse.virgo.ide.runtime.ui/icons/full/over08/pde_over.png b/org.eclipse.virgo.ide.runtime.ui/icons/full/over08/pde_over.png
new file mode 100644
index 0000000..8ff612c
--- /dev/null
+++ b/org.eclipse.virgo.ide.runtime.ui/icons/full/over08/pde_over.png
Binary files differ
diff --git a/org.eclipse.virgo.ide.runtime.ui/plugin.properties b/org.eclipse.virgo.ide.runtime.ui/plugin.properties
index 9073f73..712b3e7 100644
--- a/org.eclipse.virgo.ide.runtime.ui/plugin.properties
+++ b/org.eclipse.virgo.ide.runtime.ui/plugin.properties
@@ -1,3 +1,6 @@
pluginName=Eclipse Virgo IDE (Server UI)
providerName=Eclipse.org - Virgo
-
+serverPDEDecorator.label=Server PDE Decorator
+serverPDEDecorator.desc=Decorates Virgo server instances for which a corresponding PDE Target Platform exists.
+projectPDEDecorator.label=Project PDE Decorator
+projectPDEDecorator.desc=Decorates Virgo PDE projects.
\ No newline at end of file
diff --git a/org.eclipse.virgo.ide.runtime.ui/plugin.xml b/org.eclipse.virgo.ide.runtime.ui/plugin.xml
index 8a289cf..d8bbd60 100644
--- a/org.eclipse.virgo.ide.runtime.ui/plugin.xml
+++ b/org.eclipse.virgo.ide.runtime.ui/plugin.xml
@@ -71,12 +71,11 @@
<fragment
id="org.eclipse.virgo.server.runtime.virgo"
typeIds="org.eclipse.virgo.server.runtime.virgo"
- class="org.eclipse.virgo.ide.runtime.internal.ui.VirgoServerRuntimeWizardFragment" />
- <fragment
- class="org.eclipse.virgo.ide.runtime.internal.ui.VirgoServerRuntimeWizardFragment"
- id="org.eclipse.virgo.server.runtime.virgo.35"
- typeIds="org.eclipse.virgo.server.runtime.virgo.35">
- </fragment>
+ class="org.eclipse.virgo.ide.runtime.internal.ui.VirgoServerRuntimeWizardFragment" />
+ <fragment
+ class="org.eclipse.virgo.ide.runtime.internal.ui.VirgoServerRuntimeWizardFragment"
+ id="org.eclipse.virgo.server.runtime.virgo.35"
+ typeIds="org.eclipse.virgo.server.runtime.virgo.35" />
</extension>
<extension point="org.eclipse.wst.common.project.facet.ui.images">
@@ -117,10 +116,17 @@
class="org.eclipse.virgo.ide.runtime.internal.ui.editor.ArtefactOrderEditorSection">
</section>
<section
- id="org.eclipse.virgo.ide.server.ui.configuration.editor.staticresources"
+ id="org.eclipse.virgo.ide.server.ui.configuration.editor.targetplatform"
order="15"
insertionId="org.eclipse.wst.server.editor.overview.left"
typeIds="org.eclipse.virgo.server.virgo,org.eclipse.virgo.server.virgo.35"
+ class="org.eclipse.virgo.ide.runtime.internal.ui.editor.TargetPlatformSection">
+ </section>
+ <section
+ id="org.eclipse.virgo.ide.server.ui.configuration.editor.staticresources"
+ order="20"
+ insertionId="org.eclipse.wst.server.editor.overview.left"
+ typeIds="org.eclipse.virgo.server.virgo,org.eclipse.virgo.server.virgo.35"
class="org.eclipse.virgo.ide.runtime.internal.ui.editor.StaticResourcesEditorSection">
</section>
</extension>
@@ -621,5 +627,40 @@
</and>
</enablement>
</decorator>
+ <decorator
+ adaptable="true"
+ icon="icons/full/over08/virgo_obj.png"
+ id="org.eclipse.virgo.ide.runtime.ui.pde.project.decorator"
+ label="%projectPDEDecorator.label"
+ lightweight="true"
+ location="TOP_LEFT"
+ state="true">
+ <enablement>
+ <and>
+ <objectClass
+ name="org.eclipse.core.resources.IProject">
+ </objectClass>
+ <objectState
+ name="projectNature"
+ value="org.eclipse.virgo.ide.pde.core.nature">
+ </objectState>
+ </and>
+ </enablement>
+ <description>
+ %projectPDEDecorator.desc
+ </description>
+ </decorator>
+ <decorator
+ adaptable="true"
+ class="org.eclipse.virgo.ide.runtime.internal.ui.providers.ServerTargetPlatformDecorator"
+ id="org.eclipse.virgo.ide.runtime.ui.server.targetplatform.decorator"
+ label="%serverPDEDecorator.label"
+ lightweight="true"
+ location="TOP_LEFT"
+ state="true">
+ <description>
+ %serverPDEDecorator.desc
+ </description>
+ </decorator>
</extension>
</plugin>
diff --git a/org.eclipse.virgo.ide.runtime.ui/src/org/eclipse/virgo/ide/runtime/internal/ui/Messages.java b/org.eclipse.virgo.ide.runtime.ui/src/org/eclipse/virgo/ide/runtime/internal/ui/Messages.java
new file mode 100644
index 0000000..37a14f4
--- /dev/null
+++ b/org.eclipse.virgo.ide.runtime.ui/src/org/eclipse/virgo/ide/runtime/internal/ui/Messages.java
@@ -0,0 +1,37 @@
+
+package org.eclipse.virgo.ide.runtime.internal.ui;
+
+import org.eclipse.osgi.util.NLS;
+
+public class Messages extends NLS {
+
+ private static final String BUNDLE_NAME = "org.eclipse.virgo.ide.runtime.internal.ui.messages"; //$NON-NLS-1$
+
+ public static String PDETargetPlatformComposite_add;
+
+ public static String PDETargetPlatformComposite_add_dialog_message;
+
+ public static String PDETargetPlatformComposite_add_dialog_title;
+
+ public static String PDETargetPlatformComposite_edit;
+
+ public static String PDETargetPlatformComposite_edit_dialog_message;
+
+ public static String PDETargetPlatformComposite_edit_dialog_title;
+
+ public static String PDETargetPlatformComposite_enable_checkbox;
+
+ public static String PDETargetPlatformComposite_error_message;
+
+ public static String PDETargetPlatformComposite_note;
+
+ public static String PDETargetPlatformComposite_remove;
+
+ static {
+ // initialize resource bundle
+ NLS.initializeMessages(BUNDLE_NAME, Messages.class);
+ }
+
+ private Messages() {
+ }
+}
diff --git a/org.eclipse.virgo.ide.runtime.ui/src/org/eclipse/virgo/ide/runtime/internal/ui/PDEHelper.java b/org.eclipse.virgo.ide.runtime.ui/src/org/eclipse/virgo/ide/runtime/internal/ui/PDEHelper.java
new file mode 100644
index 0000000..19555f5
--- /dev/null
+++ b/org.eclipse.virgo.ide.runtime.ui/src/org/eclipse/virgo/ide/runtime/internal/ui/PDEHelper.java
@@ -0,0 +1,439 @@
+/*******************************************************************************
+ * Copyright (c) 2015 GianMaria Romanato
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * GianMaria Romanato - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.virgo.ide.runtime.internal.ui;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Properties;
+import java.util.Set;
+
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.MultiStatus;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.jdt.launching.JavaRuntime;
+import org.eclipse.pde.core.target.ITargetDefinition;
+import org.eclipse.pde.core.target.ITargetHandle;
+import org.eclipse.pde.core.target.ITargetLocation;
+import org.eclipse.pde.core.target.ITargetPlatformService;
+import org.eclipse.pde.core.target.LoadTargetDefinitionJob;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.virgo.ide.runtime.core.IServerRuntimeWorkingCopy;
+import org.eclipse.virgo.kernel.osgi.provisioning.tools.NoOpEventLogger;
+import org.eclipse.virgo.medic.eventlog.EventLogger;
+import org.eclipse.virgo.repository.ArtifactBridge;
+import org.eclipse.virgo.repository.ArtifactDescriptor;
+import org.eclipse.virgo.repository.ArtifactGenerationException;
+import org.eclipse.virgo.repository.builder.ArtifactDescriptorBuilder;
+import org.eclipse.virgo.repository.configuration.ExternalStorageRepositoryConfiguration;
+import org.eclipse.virgo.repository.configuration.ManagedStorageRepositoryConfiguration;
+import org.eclipse.virgo.repository.configuration.PropertiesRepositoryConfigurationReader;
+import org.eclipse.virgo.repository.configuration.RepositoryConfiguration;
+import org.eclipse.virgo.repository.configuration.WatchedStorageRepositoryConfiguration;
+import org.eclipse.virgo.util.math.OrderedPair;
+import org.eclipse.wst.server.core.IRuntimeWorkingCopy;
+
+/**
+ * Utilities used for integrating Virgo Tools and PDE Tools.
+ *
+ */
+public final class PDEHelper {
+
+ private static final String DOT = "."; //$NON-NLS-1$
+
+ private static final String PLUGINS = "plugins"; //$NON-NLS-1$
+
+ private static final String CONFIG_FILENAME = "org.eclipse.virgo.repository.properties"; //$NON-NLS-1$
+
+ private static final String CONFIGURATION = "configuration"; //$NON-NLS-1$
+
+ private static final String ANY_JAR = "*.jar"; //$NON-NLS-1$
+
+ private static final String STAR = "*"; //$NON-NLS-1$
+
+ private static final String WATCH_DIRECTORY = ".watchDirectory"; //$NON-NLS-1$
+
+ private static final String TYPE_WATCHED = "watched"; //$NON-NLS-1$
+
+ private static final String REPO_TYPE = ".type"; //$NON-NLS-1$
+
+ private static final String ADDED_BY_VIRGO_TOOLS = "addedByVirgoTools"; //$NON-NLS-1$
+
+ private static final String COMMA = ","; //$NON-NLS-1$
+
+ private static final String CHAIN_PROPERTY = "chain"; //$NON-NLS-1$
+
+ private PDEHelper() {
+ }
+
+ /**
+ * Parses the 'org.eclipse.virgo.repository.properties' configuration file and returns the list of folders that must
+ * be used as the PDE target platform definition. Note that the returned list also includes the $VIRGO_HOME/plugins
+ * folder that, while not listed in the repository configuration file, contains bundles that the container makes
+ * available to deployed applications.
+ *
+ * @param runtime the runtime working copy
+ * @return the list of folders for the target definition
+ */
+ public static List<File> getFoldersForTargetDefinition(IRuntimeWorkingCopy runtime) {
+ Assert.isNotNull(runtime, "runtime cannot be null"); //$NON-NLS-1$
+ List<File> locations = new ArrayList<File>();
+ if (runtime.getLocation() != null) {
+ locations.add(runtime.getLocation().append(PLUGINS).toFile());
+ locations.addAll(getRepositoryChain(runtime).values());
+ }
+ return locations;
+ }
+
+ /**
+ * Returns the list of folders contained in the repository configuration file and their name in the repository
+ * chain.
+ *
+ * @param runtime the runtime working copy
+ * @return the map from repository name to folder directory
+ */
+ private static LinkedHashMap<String, File> getRepositoryChain(IRuntimeWorkingCopy runtime) {
+ Assert.isNotNull(runtime, "runtime cannot be null"); //$NON-NLS-1$
+ LinkedHashMap<String, File> locations = new LinkedHashMap<String, File>();
+ File rootDirectory = runtime.getLocation().toFile();
+ Set<ArtifactBridge> artifactBridges = createArtifactBridges();
+ EventLogger logger = new NoOpEventLogger();
+ File indexDirectory = ServerUiPlugin.getDefault().getStateLocation().append(runtime.getName()).toFile();
+ indexDirectory.mkdirs();
+ PropertiesRepositoryConfigurationReader reader = new PropertiesRepositoryConfigurationReader(indexDirectory, artifactBridges, logger, null,
+ rootDirectory);
+ File configurationFile = getRepositoryFile(runtime);
+ FileInputStream inStream = null;
+ try {
+ inStream = new FileInputStream(configurationFile);
+ Properties p = new Properties();
+ p.load(inStream);
+ OrderedPair<Map<String, RepositoryConfiguration>, List<String>> pair = reader.readConfiguration(p);
+ for (RepositoryConfiguration cfg : pair.getFirst().values()) {
+ if (cfg instanceof WatchedStorageRepositoryConfiguration) {
+ WatchedStorageRepositoryConfiguration c1 = (WatchedStorageRepositoryConfiguration) cfg;
+ locations.put(c1.getName(), c1.getDirectoryToWatch());
+ } else if (cfg instanceof ManagedStorageRepositoryConfiguration) {
+ ManagedStorageRepositoryConfiguration m1 = (ManagedStorageRepositoryConfiguration) cfg;
+ locations.put(m1.getName(), m1.getStorageLocation());
+ } else if (cfg instanceof ExternalStorageRepositoryConfiguration) {
+ ExternalStorageRepositoryConfiguration e1 = (ExternalStorageRepositoryConfiguration) cfg;
+ String patt = e1.getSearchPattern();
+ IPath path = new Path(patt);
+ String lastSegment = path.lastSegment();
+ if (STAR.equals(lastSegment) || ANY_JAR.equals(lastSegment)) {
+ path = path.removeLastSegments(1);
+ if (!path.toOSString().contains(STAR)) {
+ locations.put(e1.getName(), path.toFile());
+ }
+ }
+ }
+ }
+ } catch (Exception e) {
+ } finally {
+ if (inStream != null) {
+ try {
+ inStream.close();
+ } catch (IOException e) {
+ }
+ }
+ }
+
+ return locations;
+ }
+
+ private static File getRepositoryFile(IRuntimeWorkingCopy runtime) {
+ return runtime.getLocation().append(CONFIGURATION).append(CONFIG_FILENAME).toFile();
+ }
+
+ private static Set<ArtifactBridge> createArtifactBridges() {
+ Set<ArtifactBridge> artefactBridges = new HashSet<ArtifactBridge>();
+ artefactBridges.add(new ArtifactBridge() {
+
+ public ArtifactDescriptor generateArtifactDescriptor(File arg0) throws ArtifactGenerationException {
+ return new ArtifactDescriptorBuilder().setUri(arg0.toURI()).setName(arg0.getName()).build();
+ }
+
+ });
+ return artefactBridges;
+ }
+
+ /**
+ * Tells whether a PDE Target Definition with the given name exists or not.
+ *
+ * @param name the target definition name (cannot be null)
+ * @return true if a target definition is found, false otherwise
+ */
+ public static boolean existsTargetDefinition(String name) {
+ Assert.isNotNull(name, "name cannot be null"); //$NON-NLS-1$
+ ITargetPlatformService srv = PlatformUI.getWorkbench().getService(ITargetPlatformService.class);
+ ITargetHandle[] targetplatforms = srv.getTargets(null);
+ for (ITargetHandle iTargetHandle : targetplatforms) {
+ try {
+ if (iTargetHandle.getTargetDefinition().getName().equals(name)) {
+ return true;
+ }
+ } catch (CoreException e) {
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Deletes the target definition(s) with the given name.
+ *
+ * @param name the name (cannot be null)
+ */
+ public static void deleteTargetDefinition(String name) {
+ Assert.isNotNull(name, "name cannot be null"); //$NON-NLS-1$
+ ITargetPlatformService srv = PlatformUI.getWorkbench().getService(ITargetPlatformService.class);
+ ITargetHandle[] targetplatforms = srv.getTargets(null);
+ for (ITargetHandle iTargetHandle : targetplatforms) {
+ try {
+ if (iTargetHandle.getTargetDefinition().getName().equals(name)) {
+ srv.deleteTarget(iTargetHandle);
+ }
+ } catch (CoreException e) {
+ }
+ }
+ }
+
+ /**
+ * Creates a target platform for the given runtime using the given folders.
+ *
+ * @param monitor a monitor for progress reporting
+ * @param runtime the runtime working copy
+ * @param folders the target platform folders
+ * @return a status indicating the operation result
+ */
+ public static Status createTargetDefinition(IProgressMonitor monitor, IRuntimeWorkingCopy runtime, List<File> folders) {
+ Assert.isNotNull(runtime, "runtime cannot be null"); //$NON-NLS-1$
+ if (monitor == null) {
+ monitor = new NullProgressMonitor();
+ }
+ monitor.beginTask("", 2); //$NON-NLS-1$
+ MultiStatus st = new MultiStatus(ServerUiPlugin.PLUGIN_ID, 1, "Error creating target platform", null); //$NON-NLS-1$
+ if (folders != null) {
+ IServerRuntimeWorkingCopy serverRuntimeWorkingCopy = (IServerRuntimeWorkingCopy) runtime.loadAdapter(IServerRuntimeWorkingCopy.class,
+ null);
+ ITargetPlatformService srv = PlatformUI.getWorkbench().getService(ITargetPlatformService.class);
+ ITargetHandle[] handles = srv.getTargets(null);
+ for (ITargetHandle iTargetHandle : handles) {
+ try {
+ if (iTargetHandle.getTargetDefinition().getName().equals(runtime.getName())) {
+ srv.deleteTarget(iTargetHandle);
+ }
+ } catch (CoreException e) {
+ // ignore, in the worst case another target platform is created with the same name and set active
+ }
+ }
+ ITargetDefinition targetplatform = srv.newTarget();
+ targetplatform.setName(runtime.getName());
+ targetplatform.setJREContainer(JavaRuntime.newJREContainerPath(serverRuntimeWorkingCopy.getVMInstall()));
+ ITargetLocation[] locations = new ITargetLocation[folders.size()];
+ int i = 0;
+
+ for (File folder : folders) {
+ try {
+ locations[i++] = srv.newDirectoryLocation(folder.getCanonicalPath());
+ } catch (IOException e) {
+ st.add(new Status(IStatus.ERROR, ServerUiPlugin.PLUGIN_ID, e.getLocalizedMessage(), e));
+ }
+ }
+ if (st.isOK()) {
+ monitor.worked(1);
+ targetplatform.setTargetLocations(locations);
+ try {
+ srv.saveTargetDefinition(targetplatform);
+ LoadTargetDefinitionJob.load(targetplatform);
+ } catch (CoreException e1) {
+ st.add(new Status(IStatus.ERROR, ServerUiPlugin.PLUGIN_ID, "Cannot save target platform definition", e1));
+ }
+ }
+ }
+ monitor.done();
+ return st;
+ }
+
+ /**
+ * Updates the Virgo repository configuration to match the specified list of folders.
+ *
+ * @param runtime the runtime working copy
+ * @param newFolders the new folders
+ * @throws IOException if the file modification fails for some reason
+ */
+ public static void updateRepositoryConfiguration(IRuntimeWorkingCopy runtime, List<File> newFolders) throws IOException {
+ Assert.isNotNull(runtime, "runtime cannot be null"); //$NON-NLS-1$
+ if (runtime.getLocation() != null) {
+ LinkedHashMap<String, File> oldFolders = getRepositoryChain(runtime);
+
+ HashSet<File> oldFoldersSet = new HashSet<File>(oldFolders.values());
+ HashSet<File> newFoldersSet = newFolders != null ? new HashSet<File>(newFolders) : new HashSet<File>();
+
+ newFoldersSet.remove(runtime.getLocation().append(PLUGINS).toFile());
+
+ if (oldFoldersSet.equals(newFoldersSet)) {
+ return;
+ }
+
+ LinkedHashMap<String, File> removed = new LinkedHashMap<String, File>(oldFolders);
+ for (Iterator<Entry<String, File>> eIt = removed.entrySet().iterator(); eIt.hasNext();) {
+ Entry<String, File> e = eIt.next();
+ if (newFoldersSet.remove(e.getValue())) {
+ eIt.remove(); // remove those that still exist
+ }
+ }
+
+ Properties added = new Properties();
+ int count = 0;
+
+ for (File file : newFoldersSet) {
+ added.put(ADDED_BY_VIRGO_TOOLS + count + REPO_TYPE, TYPE_WATCHED);
+ added.put(ADDED_BY_VIRGO_TOOLS + count + WATCH_DIRECTORY, file.getCanonicalPath());
+ count++;
+ }
+
+ File configurationFile = getRepositoryFile(runtime);
+
+ Properties oldProperties = readRepositoryProperties(configurationFile);
+
+ for (Iterator<Entry<Object, Object>> eIt = oldProperties.entrySet().iterator(); eIt.hasNext();) {
+ String entryKey = eIt.next().getKey().toString();
+ for (String removedRepo : removed.keySet()) {
+ if (entryKey.startsWith(removedRepo + DOT)) {
+ eIt.remove();
+ break;
+ }
+ }
+ }
+
+ oldProperties.putAll(added);
+
+ String chain = (String) oldProperties.get(CHAIN_PROPERTY);
+ StringBuilder sb = new StringBuilder();
+ if (chain != null) {
+ String[] chainArray = chain.split(COMMA);
+ for (String string : chainArray) {
+ if (!removed.containsKey(string)) {
+ sb.append(string).append(COMMA);
+ }
+ }
+ }
+
+ for (int i = 0; i < count; i++) {
+ sb.append(ADDED_BY_VIRGO_TOOLS + i).append(COMMA);
+ }
+
+ if (sb.length() > 0) {
+ sb.setLength(sb.length() - 1);
+ }
+
+ chain = sb.toString();
+
+ oldProperties.put(CHAIN_PROPERTY, chain);
+
+ writeRepositoryProperties(configurationFile, oldProperties);
+ }
+
+ }
+
+ private static void writeRepositoryProperties(File configurationFile, Properties properties) throws IOException {
+ File newFile = new File(configurationFile.getCanonicalPath());
+ File backupFile = new File(configurationFile.getCanonicalPath() + ".backup_" + System.currentTimeMillis()); //$NON-NLS-1$
+ if (backupFile.exists()) {
+ backupFile.delete();
+ }
+ configurationFile.renameTo(backupFile);
+ FileOutputStream fos = null;
+ try {
+ fos = new FileOutputStream(newFile);
+ properties.store(fos, "Edited by Virgo Tools"); //$NON-NLS-1$
+ fos.flush();
+ } finally {
+ if (fos != null) {
+ try {
+ fos.close();
+ } catch (IOException e) {
+ }
+ }
+ }
+ }
+
+ private static Properties readRepositoryProperties(File configurationFile) throws IOException {
+ FileInputStream fis = null;
+ Properties properties = new Properties();
+ try {
+ fis = new FileInputStream(configurationFile);
+ properties.load(fis);
+ return properties;
+ } finally {
+ if (fis != null) {
+ try {
+ fis.close();
+ } catch (IOException e) {
+ }
+ }
+ }
+ }
+
+ /**
+ * Refreshes the target definition identified by the given name or does nothing if such a target platform does not
+ * exist.
+ *
+ * @param monitor a monitor for progress reporting
+ * @param name the target definition name;
+ * @return true if a target platform was found and refreshed.
+ * @throws CoreException
+ */
+ public static boolean refreshTargetDefinition(IProgressMonitor monitor, String name) throws CoreException {
+ Assert.isNotNull(name, "name cannot be null"); //$NON-NLS-1$
+ if (monitor == null) {
+ monitor = new NullProgressMonitor();
+ }
+ ITargetPlatformService srv = PlatformUI.getWorkbench().getService(ITargetPlatformService.class);
+ ITargetDefinition def = srv.getWorkspaceTargetDefinition();
+ if (!def.getName().equals(name)) {
+ def = null;
+ ITargetHandle[] handles = srv.getTargets(null);
+ for (ITargetHandle iTargetHandle : handles) {
+ ITargetDefinition def2 = iTargetHandle.getTargetDefinition();
+ if (def2.getName().equals(name)) {
+ def = def2;
+ break;
+ }
+ }
+ }
+
+ if (def != null) {
+ srv.saveTargetDefinition(def);
+ def.resolve(monitor);
+ LoadTargetDefinitionJob.load(def);
+ return true;
+
+ }
+ return false;
+ }
+}
diff --git a/org.eclipse.virgo.ide.runtime.ui/src/org/eclipse/virgo/ide/runtime/internal/ui/PDETargetPlatformComposite.java b/org.eclipse.virgo.ide.runtime.ui/src/org/eclipse/virgo/ide/runtime/internal/ui/PDETargetPlatformComposite.java
new file mode 100644
index 0000000..f49e00c
--- /dev/null
+++ b/org.eclipse.virgo.ide.runtime.ui/src/org/eclipse/virgo/ide/runtime/internal/ui/PDETargetPlatformComposite.java
@@ -0,0 +1,286 @@
+/*******************************************************************************
+ * Copyright (c) 2015 GianMaria Romanato
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * GianMaria Romanato - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.virgo.ide.runtime.internal.ui;
+
+import java.io.File;
+import java.io.IOException;
+import java.lang.reflect.InvocationTargetException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.LinkedHashSet;
+import java.util.List;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.jface.layout.GridDataFactory;
+import org.eclipse.jface.layout.GridLayoutFactory;
+import org.eclipse.jface.operation.IRunnableContext;
+import org.eclipse.jface.operation.IRunnableWithProgress;
+import org.eclipse.jface.viewers.ArrayContentProvider;
+import org.eclipse.jface.viewers.BaseLabelProvider;
+import org.eclipse.jface.viewers.ISelectionChangedListener;
+import org.eclipse.jface.viewers.ITableLabelProvider;
+import org.eclipse.jface.viewers.SelectionChangedEvent;
+import org.eclipse.jface.viewers.TableViewer;
+import org.eclipse.jface.viewers.ViewerSorter;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.DirectoryDialog;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.ui.statushandlers.StatusManager;
+import org.eclipse.virgo.ide.runtime.internal.core.utils.StatusUtil;
+import org.eclipse.wst.server.core.IRuntimeWorkingCopy;
+
+/**
+ * Gather required data for setting up a PDE target platform.
+ */
+public class PDETargetPlatformComposite extends Composite {
+
+ class DirectoryLabelProvider extends BaseLabelProvider implements ITableLabelProvider {
+
+ public Image getColumnImage(Object element, int columnIndex) {
+ return null;
+ }
+
+ public String getColumnText(Object element, int columnIndex) {
+ return element != null ? element.toString() : null;
+ }
+
+ }
+
+ private List<File> folders;
+
+ private final Button enablePDEDevelopmentButton;
+
+ private final TableViewer foldersTableViewer;
+
+ private final Button addButton;
+
+ private final Button removeButton;
+
+ private final Button editButton;
+
+ private final Label comment;
+
+ private final IRunnableContext runnableContext;
+
+ private final IRuntimeWorkingCopy runtimeWorkingCopy;
+
+ private boolean repositoryConfigurationChanged;
+
+ public PDETargetPlatformComposite(Composite parent, IRunnableContext runnableContext, IRuntimeWorkingCopy iRuntimeWorkingCopy) {
+ super(parent, SWT.NONE);
+
+ this.runnableContext = runnableContext;
+ this.runtimeWorkingCopy = iRuntimeWorkingCopy;
+
+ setLayout(GridLayoutFactory.swtDefaults().numColumns(2).create());
+ setLayoutData(GridDataFactory.fillDefaults().grab(true, true).create());
+
+ enablePDEDevelopmentButton = new Button(this, SWT.CHECK);
+ enablePDEDevelopmentButton.setSelection(false);
+ enablePDEDevelopmentButton.setText(Messages.PDETargetPlatformComposite_enable_checkbox);
+ enablePDEDevelopmentButton.setLayoutData(GridDataFactory.swtDefaults().span(2, SWT.DEFAULT).create());
+
+ foldersTableViewer = new TableViewer(this);
+ foldersTableViewer.setContentProvider(ArrayContentProvider.getInstance());
+ foldersTableViewer.setSorter(new ViewerSorter());
+ foldersTableViewer.setLabelProvider(new DirectoryLabelProvider());
+ foldersTableViewer.getTable().setLayoutData(GridDataFactory.fillDefaults().grab(true, true).span(1, 3).create());
+ foldersTableViewer.addSelectionChangedListener(new ISelectionChangedListener() {
+
+ public void selectionChanged(SelectionChangedEvent event) {
+ int size = foldersTableViewer.getStructuredSelection().size();
+ editButton.setEnabled(size == 1);
+ removeButton.setEnabled(size > 0);
+ }
+ });
+
+ addButton = new Button(this, SWT.PUSH);
+ addButton.setLayoutData(GridDataFactory.fillDefaults().create());
+ addButton.setText(Messages.PDETargetPlatformComposite_add);
+ addButton.addSelectionListener(new SelectionAdapter() {
+
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ PDETargetPlatformComposite.this.addPressed(e);
+ }
+ });
+
+ removeButton = new Button(this, SWT.PUSH);
+ removeButton.setText(Messages.PDETargetPlatformComposite_remove);
+ removeButton.setLayoutData(GridDataFactory.fillDefaults().create());
+ removeButton.addSelectionListener(new SelectionAdapter() {
+
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ PDETargetPlatformComposite.this.removePressed(e);
+ }
+ });
+
+ editButton = new Button(this, SWT.PUSH);
+ editButton.setText(Messages.PDETargetPlatformComposite_edit);
+ editButton.setLayoutData(GridDataFactory.fillDefaults().align(SWT.FILL, SWT.TOP).create());
+ editButton.addSelectionListener(new SelectionAdapter() {
+
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ PDETargetPlatformComposite.this.editPressed(e);
+ }
+ });
+
+ comment = new Label(this, SWT.WRAP);
+ comment.setLayoutData(GridDataFactory.fillDefaults().grab(true, false).span(2, SWT.DEFAULT).create());
+ comment.setText(Messages.PDETargetPlatformComposite_note);
+
+ if (PDEHelper.existsTargetDefinition(runtimeWorkingCopy.getName())) {
+ enableTargetPlatform(true);
+ enablePDEDevelopmentButton.setSelection(true);
+ } else {
+ enableTargetPlatform(false);
+ }
+
+ enablePDEDevelopmentButton.addSelectionListener(new SelectionAdapter() {
+
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ PDETargetPlatformComposite.this.enableButtonSelected(e);
+ }
+ });
+ }
+
+ protected void editPressed(SelectionEvent e) {
+ DirectoryDialog dlg = new DirectoryDialog(e.display.getActiveShell());
+ dlg.setText(Messages.PDETargetPlatformComposite_edit_dialog_title);
+ dlg.setMessage(Messages.PDETargetPlatformComposite_edit_dialog_message);
+ String path = dlg.open();
+ if (path != null) {
+ LinkedHashSet<File> folders2 = new LinkedHashSet<File>(getTargetPlatformFolders());
+ folders2.remove(this.foldersTableViewer.getStructuredSelection().getFirstElement());
+ folders2.add(new File(path));
+ List<File> folders3 = new ArrayList<File>(folders2);
+ setTableInput(folders3);
+ repositoryConfigurationChanged = true;
+ }
+ }
+
+ protected void removePressed(SelectionEvent e) {
+ LinkedHashSet<File> folders2 = new LinkedHashSet<File>(getTargetPlatformFolders());
+ folders2.removeAll(this.foldersTableViewer.getStructuredSelection().toList());
+ List<File> folders3 = new ArrayList<File>(folders2);
+ setTableInput(folders3);
+ repositoryConfigurationChanged = true;
+ }
+
+ protected void addPressed(SelectionEvent e) {
+ DirectoryDialog dlg = new DirectoryDialog(e.display.getActiveShell());
+ dlg.setText(Messages.PDETargetPlatformComposite_add_dialog_title);
+ dlg.setMessage(Messages.PDETargetPlatformComposite_add_dialog_message);
+ String path = dlg.open();
+ if (path != null) {
+ LinkedHashSet<File> folders2 = new LinkedHashSet<File>(getTargetPlatformFolders());
+ folders2.add(new File(path));
+ List<File> folders3 = new ArrayList<File>(folders2);
+ setTableInput(folders3);
+ repositoryConfigurationChanged = true;
+ }
+ }
+
+ protected void enableButtonSelected(SelectionEvent e) {
+ enableTargetPlatform(enablePDEDevelopmentButton.getSelection());
+ }
+
+ protected void enableTargetPlatform(boolean enabled) {
+ comment.setEnabled(enabled);
+ foldersTableViewer.getTable().setEnabled(enabled);
+ addButton.setEnabled(enabled);
+ removeButton.setEnabled(enabled);
+ editButton.setEnabled(enabled);
+
+ if (enabled) {
+ try {
+ runnableContext.run(true, false, new IRunnableWithProgress() {
+
+ public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
+ folders = PDEHelper.getFoldersForTargetDefinition(runtimeWorkingCopy);
+ monitor.done();
+ if (foldersTableViewer.getTable() != null && !foldersTableViewer.getTable().isDisposed()) {
+ foldersTableViewer.getTable().getDisplay().asyncExec(new Runnable() {
+
+ public void run() {
+ foldersTableViewer.setInput(folders);
+ }
+ });
+ }
+
+ }
+ });
+ } catch (Exception e) {
+ StatusUtil.error(Messages.PDETargetPlatformComposite_error_message, e, StatusManager.LOG | StatusManager.SHOW);
+ }
+ } else {
+ foldersTableViewer.setInput(Collections.emptyList());
+ }
+ }
+
+ public Button getEnablePDEDevelopmentButton() {
+ return enablePDEDevelopmentButton;
+ }
+
+ public void setTableInput(List<File> targetPlatformFolders) {
+ this.folders = targetPlatformFolders;
+ foldersTableViewer.setInput(targetPlatformFolders);
+ }
+
+ public List<File> getTargetPlatformFolders() {
+ return folders;
+ }
+
+ public boolean isRepositoryConfigurationChanged() {
+ return repositoryConfigurationChanged;
+ }
+
+ public void performFinish(IProgressMonitor monitor) {
+ final List<File> folders = getTargetPlatformFolders();
+ boolean changed = isRepositoryConfigurationChanged();
+
+ Status st = PDEHelper.createTargetDefinition(monitor, runtimeWorkingCopy, folders);
+ if (!st.isOK()) {
+ StatusManager.getManager().handle(st, StatusManager.SHOW | StatusManager.LOG);
+ } else {
+ if (changed) {
+ getDisplay().syncExec(new Runnable() {
+
+ public void run() {
+ boolean applyToRepository = MessageDialog.openQuestion(getShell(),
+ PDEUIMessages.PDETargetPlatformWizardFragment_update_dialog_title,
+ PDEUIMessages.PDETargetPlatformWizardFragment_update_dialog_message);
+ if (applyToRepository) {
+ try {
+ PDEHelper.updateRepositoryConfiguration(runtimeWorkingCopy, folders);
+ } catch (IOException e) {
+ StatusUtil.error(PDEUIMessages.PDETargetPlatformWizardFragment_update_dialog_error, e,
+ StatusManager.SHOW | StatusManager.LOG);
+ }
+ }
+ }
+ });
+ }
+ }
+ }
+
+}
diff --git a/org.eclipse.virgo.ide.runtime.ui/src/org/eclipse/virgo/ide/runtime/internal/ui/PDETargetPlatformWizardFragment.java b/org.eclipse.virgo.ide.runtime.ui/src/org/eclipse/virgo/ide/runtime/internal/ui/PDETargetPlatformWizardFragment.java
new file mode 100644
index 0000000..550eced
--- /dev/null
+++ b/org.eclipse.virgo.ide.runtime.ui/src/org/eclipse/virgo/ide/runtime/internal/ui/PDETargetPlatformWizardFragment.java
@@ -0,0 +1,82 @@
+/*******************************************************************************
+ * Copyright (c) 2015 GianMaria Romanato
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * GianMaria Romanato - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.virgo.ide.runtime.internal.ui;
+
+import java.lang.reflect.InvocationTargetException;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.jface.operation.IRunnableContext;
+import org.eclipse.jface.operation.IRunnableWithProgress;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.wst.server.core.IRuntimeWorkingCopy;
+import org.eclipse.wst.server.core.TaskModel;
+import org.eclipse.wst.server.ui.wizard.IWizardHandle;
+import org.eclipse.wst.server.ui.wizard.WizardFragment;
+
+/**
+ * A {@link WizardFragment} that adds an extra page for setting up the PDE target platform.
+ */
+public class PDETargetPlatformWizardFragment extends WizardFragment {
+
+ private PDETargetPlatformComposite targetPlatformComposite;
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean hasComposite() {
+ return true;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Composite createComposite(Composite parent, final IWizardHandle handle) {
+ handle.setTitle(PDEUIMessages.PDETargetPlatformWizardFragment_title);
+ handle.setDescription(PDEUIMessages.PDETargetPlatformWizardFragment_desc);
+
+ IRunnableContext ctx = new IRunnableContext() {
+
+ public void run(boolean fork, boolean cancelable, IRunnableWithProgress runnable) throws InvocationTargetException, InterruptedException {
+ handle.run(fork, cancelable, runnable);
+ }
+ };
+ targetPlatformComposite = new PDETargetPlatformComposite(parent, ctx, (IRuntimeWorkingCopy) getTaskModel().getObject(TaskModel.TASK_RUNTIME));
+ return targetPlatformComposite;
+
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean isComplete() {
+ return true;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void enter() {
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void performFinish(IProgressMonitor monitor) throws CoreException {
+ targetPlatformComposite.performFinish(monitor);
+ }
+}
diff --git a/org.eclipse.virgo.ide.runtime.ui/src/org/eclipse/virgo/ide/runtime/internal/ui/PDEUIMessages.java b/org.eclipse.virgo.ide.runtime.ui/src/org/eclipse/virgo/ide/runtime/internal/ui/PDEUIMessages.java
new file mode 100644
index 0000000..0c84502
--- /dev/null
+++ b/org.eclipse.virgo.ide.runtime.ui/src/org/eclipse/virgo/ide/runtime/internal/ui/PDEUIMessages.java
@@ -0,0 +1,27 @@
+
+package org.eclipse.virgo.ide.runtime.internal.ui;
+
+import org.eclipse.osgi.util.NLS;
+
+public class PDEUIMessages extends NLS {
+
+ private static final String BUNDLE_NAME = "org.eclipse.virgo.ide.runtime.internal.ui.pdeuimessages"; //$NON-NLS-1$
+
+ public static String PDETargetPlatformWizardFragment_desc;
+
+ public static String PDETargetPlatformWizardFragment_title;
+
+ public static String PDETargetPlatformWizardFragment_update_dialog_error;
+
+ public static String PDETargetPlatformWizardFragment_update_dialog_message;
+
+ public static String PDETargetPlatformWizardFragment_update_dialog_title;
+
+ static {
+ // initialize resource bundle
+ NLS.initializeMessages(BUNDLE_NAME, PDEUIMessages.class);
+ }
+
+ private PDEUIMessages() {
+ }
+}
diff --git a/org.eclipse.virgo.ide.runtime.ui/src/org/eclipse/virgo/ide/runtime/internal/ui/RuntimeListener.java b/org.eclipse.virgo.ide.runtime.ui/src/org/eclipse/virgo/ide/runtime/internal/ui/RuntimeListener.java
new file mode 100644
index 0000000..63937dd
--- /dev/null
+++ b/org.eclipse.virgo.ide.runtime.ui/src/org/eclipse/virgo/ide/runtime/internal/ui/RuntimeListener.java
@@ -0,0 +1,55 @@
+
+package org.eclipse.virgo.ide.runtime.internal.ui;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.ui.progress.UIJob;
+import org.eclipse.ui.progress.WorkbenchJob;
+import org.eclipse.virgo.ide.runtime.internal.core.runtimes.VirgoRuntimeProvider;
+import org.eclipse.wst.server.core.IRuntime;
+import org.eclipse.wst.server.core.IRuntimeLifecycleListener;
+
+public class RuntimeListener implements IRuntimeLifecycleListener {
+
+ private RuntimeListener() {
+ super();
+ }
+
+ private static RuntimeListener self = new RuntimeListener();
+
+ public static RuntimeListener getDefault() {
+ return self;
+ }
+
+ public void runtimeAdded(IRuntime runtime) {
+ }
+
+ public void runtimeChanged(IRuntime runtime) {
+ }
+
+ public void runtimeRemoved(IRuntime runtime) {
+ if (runtime.getRuntimeType().getId().startsWith(VirgoRuntimeProvider.SERVER_VIRGO_BASE)) {
+ final String name = runtime.getName();
+ UIJob job = new WorkbenchJob("RemoveVirgoTargetPlatform") { //$NON-NLS-1$
+
+ @Override
+ public IStatus runInUIThread(IProgressMonitor monitor) {
+ if (PDEHelper.existsTargetDefinition(name)) {
+ boolean delete = MessageDialog.openQuestion(getDisplay().getActiveShell(), "Delete target platform?",
+ "A Virgo Runtime has been deleted. Do you also want to delete the associated PDE Target Platform?");
+ if (delete) {
+ PDEHelper.deleteTargetDefinition(name);
+ }
+ }
+ return Status.OK_STATUS;
+ }
+ };
+
+ job.setUser(true);
+ job.schedule();
+ }
+ }
+
+}
diff --git a/org.eclipse.virgo.ide.runtime.ui/src/org/eclipse/virgo/ide/runtime/internal/ui/ServerUiImages.java b/org.eclipse.virgo.ide.runtime.ui/src/org/eclipse/virgo/ide/runtime/internal/ui/ServerUiImages.java
index f2bae56..ff9f28d 100644
--- a/org.eclipse.virgo.ide.runtime.ui/src/org/eclipse/virgo/ide/runtime/internal/ui/ServerUiImages.java
+++ b/org.eclipse.virgo.ide.runtime.ui/src/org/eclipse/virgo/ide/runtime/internal/ui/ServerUiImages.java
@@ -71,6 +71,8 @@
public static final String IMG_VIRGO_OVER = NAME_PREFIX + "virgo_over.png";
+ public static final String IMG_PDE_OVER = NAME_PREFIX + "pde_over.png";
+
public static final String IMG_OBJ_BUNDLE = NAME_PREFIX + "bundle_obj.gif";
public static final String IMG_OBJ_BUNDLE_SRC = NAME_PREFIX + "bundle_src_obj.gif";
@@ -99,6 +101,8 @@
public static final ImageDescriptor DESC_OBJ_VIRGO_OVER = createManaged(OVER, IMG_OBJ_VIRGO);
+ public static final ImageDescriptor DESC_OBJ_PDE_OVER = createManaged(OVER, IMG_PDE_OVER);
+
public static final ImageDescriptor DESC_OBJ_PORT = createManaged(OBJECT, IMG_OBJ_PORT);
public static final ImageDescriptor DESC_OBJ_VIRGO = createManaged(OBJECT, IMG_OBJ_VIRGO);
diff --git a/org.eclipse.virgo.ide.runtime.ui/src/org/eclipse/virgo/ide/runtime/internal/ui/ServerUiPlugin.java b/org.eclipse.virgo.ide.runtime.ui/src/org/eclipse/virgo/ide/runtime/internal/ui/ServerUiPlugin.java
index 49de687..45e42b8 100644
--- a/org.eclipse.virgo.ide.runtime.ui/src/org/eclipse/virgo/ide/runtime/internal/ui/ServerUiPlugin.java
+++ b/org.eclipse.virgo.ide.runtime.ui/src/org/eclipse/virgo/ide/runtime/internal/ui/ServerUiPlugin.java
@@ -19,6 +19,7 @@
import org.eclipse.jface.resource.ImageRegistry;
import org.eclipse.ui.plugin.AbstractUIPlugin;
import org.eclipse.virgo.ide.runtime.internal.ui.projects.ServerProjectManager;
+import org.eclipse.wst.server.core.ServerCore;
import org.osgi.framework.BundleContext;
/**
@@ -90,6 +91,8 @@
}
plugin.getPreferenceStore().setDefault(PREF_DOWNLOAD_MESSAGE_KEY, false);
+ ServerCore.addRuntimeLifecycleListener(RuntimeListener.getDefault());
+
ServerProjectManager.getInstance().updateProjects();
}
@@ -101,6 +104,7 @@
@Override
public void stop(BundleContext context) throws Exception {
plugin = null;
+ ServerCore.removeRuntimeLifecycleListener(RuntimeListener.getDefault());
super.stop(context);
}
diff --git a/org.eclipse.virgo.ide.runtime.ui/src/org/eclipse/virgo/ide/runtime/internal/ui/VirgoServerRuntimeWizardFragment.java b/org.eclipse.virgo.ide.runtime.ui/src/org/eclipse/virgo/ide/runtime/internal/ui/VirgoServerRuntimeWizardFragment.java
index 76f5399..ab26602 100644
--- a/org.eclipse.virgo.ide.runtime.ui/src/org/eclipse/virgo/ide/runtime/internal/ui/VirgoServerRuntimeWizardFragment.java
+++ b/org.eclipse.virgo.ide.runtime.ui/src/org/eclipse/virgo/ide/runtime/internal/ui/VirgoServerRuntimeWizardFragment.java
@@ -11,6 +11,8 @@
package org.eclipse.virgo.ide.runtime.internal.ui;
+import java.util.List;
+
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.swt.widgets.Composite;
@@ -46,8 +48,8 @@
@Override
public Composite createComposite(Composite parent, IWizardHandle wizard) {
- String wizardTitle = ServerUiPlugin.getResourceString("virgoWizardTitle");
- String wizardDescription = ServerUiPlugin.getResourceString("virgoWizardDescription");
+ String wizardTitle = ServerUiPlugin.getResourceString("virgoWizardTitle"); //$NON-NLS-1$
+ String wizardDescription = ServerUiPlugin.getResourceString("virgoWizardDescription"); //$NON-NLS-1$
this.comp = new ServerRuntimeComposite(parent, wizard, wizardTitle, wizardDescription, ServerUiImages.DESC_WIZB_VIRGO_SERVER);
return this.comp;
}
@@ -65,7 +67,17 @@
IRuntimeWorkingCopy runtime = (IRuntimeWorkingCopy) getTaskModel().getObject(TaskModel.TASK_RUNTIME);
IPath path = runtime.getLocation();
if (runtime.validate(null).getSeverity() != IStatus.ERROR) {
- ServerCorePlugin.setPreference("location" + runtime.getRuntimeType().getId(), path.toString());
+ ServerCorePlugin.setPreference("location" + runtime.getRuntimeType().getId(), path.toString()); //$NON-NLS-1$
}
}
+
+ private PDETargetPlatformWizardFragment childFragment;
+
+ @Override
+ protected void createChildFragments(List<WizardFragment> list) {
+ if (childFragment == null) {
+ childFragment = new PDETargetPlatformWizardFragment();
+ }
+ list.add(childFragment);
+ }
}
diff --git a/org.eclipse.virgo.ide.runtime.ui/src/org/eclipse/virgo/ide/runtime/internal/ui/editor/TargetPlatformEditWizard.java b/org.eclipse.virgo.ide.runtime.ui/src/org/eclipse/virgo/ide/runtime/internal/ui/editor/TargetPlatformEditWizard.java
new file mode 100644
index 0000000..b2e10ae
--- /dev/null
+++ b/org.eclipse.virgo.ide.runtime.ui/src/org/eclipse/virgo/ide/runtime/internal/ui/editor/TargetPlatformEditWizard.java
@@ -0,0 +1,66 @@
+
+package org.eclipse.virgo.ide.runtime.internal.ui.editor;
+
+import java.lang.reflect.InvocationTargetException;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.jface.operation.IRunnableWithProgress;
+import org.eclipse.jface.wizard.Wizard;
+import org.eclipse.jface.wizard.WizardPage;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.ui.statushandlers.StatusManager;
+import org.eclipse.virgo.ide.runtime.internal.ui.PDETargetPlatformComposite;
+import org.eclipse.virgo.ide.runtime.internal.ui.PDEUIMessages;
+import org.eclipse.virgo.ide.ui.ServerIdeUiPlugin;
+import org.eclipse.wst.server.core.IRuntimeWorkingCopy;
+
+public class TargetPlatformEditWizard extends Wizard {
+
+ private final class PDEPage extends WizardPage {
+
+ private PDEPage() {
+ super("main"); //$NON-NLS-1$
+ setTitle("Configure Eclipse PDE Target Platform"); //$NON-NLS-1$
+ setDescription("Define a PDE Target Platform if you intend to develop using PDE Tools"); //$NON-NLS-1$
+ }
+
+ public void createControl(Composite parent) {
+ composite = new PDETargetPlatformComposite(parent, getContainer(), workingCopy);
+ composite.getEnablePDEDevelopmentButton().setEnabled(false);
+ setControl(composite);
+ }
+ }
+
+ private final IRuntimeWorkingCopy workingCopy;
+
+ private PDETargetPlatformComposite composite;
+
+ public TargetPlatformEditWizard(IRuntimeWorkingCopy workingCopy) {
+ super();
+ this.workingCopy = workingCopy;
+ setNeedsProgressMonitor(true);
+ }
+
+ @Override
+ public void addPages() {
+ addPage(new PDEPage());
+ }
+
+ @Override
+ public boolean performFinish() {
+ try {
+ getContainer().run(true, false, new IRunnableWithProgress() {
+
+ public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
+ composite.performFinish(monitor);
+ }
+ });
+ } catch (Exception e) {
+ StatusManager.getManager().handle(new Status(IStatus.ERROR, ServerIdeUiPlugin.PLUGIN_ID, TargetPlatformSectionMessages.TargetPlatformSection_InternalError, e),
+ StatusManager.LOG | StatusManager.SHOW);
+ }
+ return true;
+ }
+}
diff --git a/org.eclipse.virgo.ide.runtime.ui/src/org/eclipse/virgo/ide/runtime/internal/ui/editor/TargetPlatformSection.java b/org.eclipse.virgo.ide.runtime.ui/src/org/eclipse/virgo/ide/runtime/internal/ui/editor/TargetPlatformSection.java
new file mode 100644
index 0000000..3beb052
--- /dev/null
+++ b/org.eclipse.virgo.ide.runtime.ui/src/org/eclipse/virgo/ide/runtime/internal/ui/editor/TargetPlatformSection.java
@@ -0,0 +1,122 @@
+
+package org.eclipse.virgo.ide.runtime.internal.ui.editor;
+
+import java.lang.reflect.InvocationTargetException;
+
+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.jface.dialogs.MessageDialog;
+import org.eclipse.jface.dialogs.ProgressMonitorDialog;
+import org.eclipse.jface.operation.IRunnableWithProgress;
+import org.eclipse.jface.wizard.WizardDialog;
+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.ui.IEditorInput;
+import org.eclipse.ui.IEditorSite;
+import org.eclipse.ui.forms.events.HyperlinkAdapter;
+import org.eclipse.ui.forms.events.HyperlinkEvent;
+import org.eclipse.ui.forms.widgets.ExpandableComposite;
+import org.eclipse.ui.forms.widgets.FormText;
+import org.eclipse.ui.forms.widgets.FormToolkit;
+import org.eclipse.ui.forms.widgets.Section;
+import org.eclipse.ui.statushandlers.StatusManager;
+import org.eclipse.virgo.ide.runtime.core.IServerWorkingCopy;
+import org.eclipse.virgo.ide.runtime.internal.ui.PDEHelper;
+import org.eclipse.virgo.ide.runtime.internal.ui.PDEUIMessages;
+import org.eclipse.virgo.ide.ui.ServerIdeUiPlugin;
+import org.eclipse.wst.server.ui.editor.ServerEditorSection;
+
+public class TargetPlatformSection extends ServerEditorSection {
+
+ private static String FORM_TEXT = TargetPlatformSectionMessages.TargetPlatformSection_form_text;
+
+ private IServerWorkingCopy serverWorkingCopy;
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void createSection(Composite parent) {
+ super.createSection(parent);
+ FormToolkit toolkit = getFormToolkit(parent.getDisplay());
+
+ Section section = toolkit.createSection(parent, ExpandableComposite.TWISTIE | ExpandableComposite.EXPANDED | ExpandableComposite.TITLE_BAR
+ | Section.DESCRIPTION | ExpandableComposite.FOCUS_TITLE);
+ section.setText(TargetPlatformSectionMessages.TargetPlatformSection_title);
+ section.setDescription(TargetPlatformSectionMessages.TargetPlatformSection_description);
+ section.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
+
+ Composite composite = toolkit.createComposite(section);
+ GridLayout layout = new GridLayout();
+ layout.numColumns = 1;
+ composite.setLayout(layout);
+ composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
+ toolkit.paintBordersFor(composite);
+ section.setClient(composite);
+
+ FormText text = toolkit.createFormText(composite, true);
+ text.setText(FORM_TEXT, true, false);
+ text.addHyperlinkListener(new HyperlinkAdapter() {
+
+ @Override
+ public void linkActivated(HyperlinkEvent e) {
+ if (!PDEHelper.existsTargetDefinition(server.getRuntime().getName())) {
+ MessageDialog.openInformation(getShell(), TargetPlatformSectionMessages.TargetPlatformSection_not_configured_title,
+ TargetPlatformSectionMessages.TargetPlatformSection_not_configured_message);
+ return;
+ }
+ if ("refresh".equals(e.getHref())) { //$NON-NLS-1$
+ refreshPressed();
+ return;
+ }
+ if ("edit".equals(e.getHref())) { //$NON-NLS-1$
+ editPressed();
+ return;
+ }
+ }
+ });
+
+ }
+
+ protected void editPressed() {
+ TargetPlatformEditWizard wiz = new TargetPlatformEditWizard(server.getRuntime().createWorkingCopy());
+ wiz.setWindowTitle(PDEUIMessages.PDETargetPlatformWizardFragment_title);
+
+ WizardDialog dlg = new WizardDialog(getShell(), wiz);
+ dlg.setTitle(PDEUIMessages.PDETargetPlatformWizardFragment_title);
+ dlg.open();
+ }
+
+ protected void refreshPressed() {
+ ProgressMonitorDialog dlg = new ProgressMonitorDialog(getShell());
+ try {
+ dlg.run(true, false, new IRunnableWithProgress() {
+
+ public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
+ try {
+ PDEHelper.refreshTargetDefinition(monitor, server.getRuntime().getName());
+ } catch (CoreException e) {
+ StatusManager.getManager().handle(e.getStatus(), StatusManager.SHOW);
+ }
+ }
+ });
+ } catch (Exception e) {
+ StatusManager.getManager().handle(new Status(IStatus.ERROR, ServerIdeUiPlugin.PLUGIN_ID, e.getMessage(), e),
+ StatusManager.SHOW | StatusManager.LOG);
+ }
+
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void init(IEditorSite site, IEditorInput input) {
+ super.init(site, input);
+ }
+
+}
diff --git a/org.eclipse.virgo.ide.runtime.ui/src/org/eclipse/virgo/ide/runtime/internal/ui/editor/TargetPlatformSectionMessages.java b/org.eclipse.virgo.ide.runtime.ui/src/org/eclipse/virgo/ide/runtime/internal/ui/editor/TargetPlatformSectionMessages.java
new file mode 100644
index 0000000..de1e560
--- /dev/null
+++ b/org.eclipse.virgo.ide.runtime.ui/src/org/eclipse/virgo/ide/runtime/internal/ui/editor/TargetPlatformSectionMessages.java
@@ -0,0 +1,29 @@
+
+package org.eclipse.virgo.ide.runtime.internal.ui.editor;
+
+import org.eclipse.osgi.util.NLS;
+
+public class TargetPlatformSectionMessages extends NLS {
+
+ private static final String BUNDLE_NAME = "org.eclipse.virgo.ide.runtime.internal.ui.editor.tpsectionmessages"; //$NON-NLS-1$
+
+ public static String TargetPlatformSection_description;
+
+ public static String TargetPlatformSection_form_text;
+
+ public static String TargetPlatformSection_InternalError;
+
+ public static String TargetPlatformSection_not_configured_message;
+
+ public static String TargetPlatformSection_not_configured_title;
+
+ public static String TargetPlatformSection_title;
+
+ static {
+ // initialize resource bundle
+ NLS.initializeMessages(BUNDLE_NAME, TargetPlatformSectionMessages.class);
+ }
+
+ private TargetPlatformSectionMessages() {
+ }
+}
diff --git a/org.eclipse.virgo.ide.runtime.ui/src/org/eclipse/virgo/ide/runtime/internal/ui/editor/messages.properties b/org.eclipse.virgo.ide.runtime.ui/src/org/eclipse/virgo/ide/runtime/internal/ui/editor/messages.properties
index 4d9b16e..15fcc3d 100644
--- a/org.eclipse.virgo.ide.runtime.ui/src/org/eclipse/virgo/ide/runtime/internal/ui/editor/messages.properties
+++ b/org.eclipse.virgo.ide.runtime.ui/src/org/eclipse/virgo/ide/runtime/internal/ui/editor/messages.properties
@@ -55,7 +55,7 @@
StartupEditorSection_description=Specify startup options. Changing a setting requires a server restart.
StartupEditorSection_maxpermsize_label=-XX:MaxPermSize=
StartupEditorSection_start_with_clean_button=Start server with -clean option
-StartupEditorSection_tail_into_console_button=Tail application trace files into Console view
+StartupEditorSection_tail_into_console_button=Tail deploy events into Console view
StartupEditorSection_title=Server Startup Configuration
StaticResourcesEditorSection_14=<form><p><a href="exportbundle">Restore default</a> filename pattern</p></form>
StaticResourcesEditorSection_add_button=Add
diff --git a/org.eclipse.virgo.ide.runtime.ui/src/org/eclipse/virgo/ide/runtime/internal/ui/editor/tpsectionmessages.properties b/org.eclipse.virgo.ide.runtime.ui/src/org/eclipse/virgo/ide/runtime/internal/ui/editor/tpsectionmessages.properties
new file mode 100644
index 0000000..db757e6
--- /dev/null
+++ b/org.eclipse.virgo.ide.runtime.ui/src/org/eclipse/virgo/ide/runtime/internal/ui/editor/tpsectionmessages.properties
@@ -0,0 +1,6 @@
+TargetPlatformSection_description=Configure a PDE Target Platform definition for developing using PDE.
+TargetPlatformSection_form_text=<form><p><a href="refresh">Reload</a> the current Target Platform definition due to bundle changes or <a href="edit">edit</a> its content.</p></form>
+TargetPlatformSection_InternalError=Internal Error
+TargetPlatformSection_not_configured_message=A PDE Target Platform definition is not configured for this Virgo runtime. Please use the Server Runtime wizard to configure a PDE Target platform definition.
+TargetPlatformSection_not_configured_title=PDE Target Platform not configured
+TargetPlatformSection_title=Target Platform
diff --git a/org.eclipse.virgo.ide.runtime.ui/src/org/eclipse/virgo/ide/runtime/internal/ui/messages.properties b/org.eclipse.virgo.ide.runtime.ui/src/org/eclipse/virgo/ide/runtime/internal/ui/messages.properties
index 663bdf0..7e44e36 100644
--- a/org.eclipse.virgo.ide.runtime.ui/src/org/eclipse/virgo/ide/runtime/internal/ui/messages.properties
+++ b/org.eclipse.virgo.ide.runtime.ui/src/org/eclipse/virgo/ide/runtime/internal/ui/messages.properties
@@ -10,6 +10,16 @@
version=&Virgo Version:
installedJRE=&JRE:
installedJREs=&Installed JREs...
+PDETargetPlatformComposite_add=Add
+PDETargetPlatformComposite_add_dialog_message=Select a directory of bundles to add to the target
+PDETargetPlatformComposite_add_dialog_title=Add directory
+PDETargetPlatformComposite_edit=Edit
+PDETargetPlatformComposite_edit_dialog_message=Select a directory of bundles to add to the target
+PDETargetPlatformComposite_edit_dialog_title=Edit directory
+PDETargetPlatformComposite_enable_checkbox=Enable development using Eclipse PDE Tools
+PDETargetPlatformComposite_error_message=Internal Error
+PDETargetPlatformComposite_note=Note: Virgo external repositories are not supported by PDE Target platform.
+PDETargetPlatformComposite_remove=Remove
selectInstallDir=Select server installation directory.
runtimeDefaultJRE=Workbench default JRE
diff --git a/org.eclipse.virgo.ide.runtime.ui/src/org/eclipse/virgo/ide/runtime/internal/ui/pdeuimessages.properties b/org.eclipse.virgo.ide.runtime.ui/src/org/eclipse/virgo/ide/runtime/internal/ui/pdeuimessages.properties
new file mode 100644
index 0000000..f8720dc
--- /dev/null
+++ b/org.eclipse.virgo.ide.runtime.ui/src/org/eclipse/virgo/ide/runtime/internal/ui/pdeuimessages.properties
@@ -0,0 +1,5 @@
+PDETargetPlatformWizardFragment_desc=Define a PDE Target Platform if you intend to develop using PDE Tools
+PDETargetPlatformWizardFragment_title=Configure Eclipse PDE Target Platform
+PDETargetPlatformWizardFragment_update_dialog_error=Error updating repository configuration
+PDETargetPlatformWizardFragment_update_dialog_message=A PDE Target Platform has been created to include the requested list of directories. Do you want the Virgo repository configuration to be updated accordingly?
+PDETargetPlatformWizardFragment_update_dialog_title=Update Virgo repository configuration?
diff --git a/org.eclipse.virgo.ide.runtime.ui/src/org/eclipse/virgo/ide/runtime/internal/ui/providers/ServerTargetPlatformDecorator.java b/org.eclipse.virgo.ide.runtime.ui/src/org/eclipse/virgo/ide/runtime/internal/ui/providers/ServerTargetPlatformDecorator.java
new file mode 100644
index 0000000..7d787f8
--- /dev/null
+++ b/org.eclipse.virgo.ide.runtime.ui/src/org/eclipse/virgo/ide/runtime/internal/ui/providers/ServerTargetPlatformDecorator.java
@@ -0,0 +1,60 @@
+/*******************************************************************************
+ * Copyright (c) 2015 GianMaria Romanato
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * GianMaria Romanato - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.virgo.ide.runtime.internal.ui.providers;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.jface.viewers.BaseLabelProvider;
+import org.eclipse.jface.viewers.IDecoration;
+import org.eclipse.jface.viewers.ILightweightLabelDecorator;
+import org.eclipse.pde.core.target.ITargetHandle;
+import org.eclipse.pde.core.target.ITargetPlatformService;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.virgo.ide.runtime.core.ServerCorePlugin;
+import org.eclipse.virgo.ide.runtime.internal.ui.ServerUiImages;
+import org.eclipse.wst.server.core.IRuntime;
+import org.eclipse.wst.server.core.IServer;
+
+/**
+ * A lightweight decorator that overlays a decoration on the top left of servers whose runtime has an associated PDE
+ * target platform.
+ */
+public class ServerTargetPlatformDecorator extends BaseLabelProvider implements ILightweightLabelDecorator {
+
+ /**
+ * {@inheritDoc}
+ */
+ public void decorate(Object element, IDecoration decoration) {
+ if (element instanceof IServer) {
+ IServer srv = (IServer) element;
+ if (srv.getServerType().getId().equals(ServerCorePlugin.VIRGO_SERVER_ID)) {
+ IRuntime runtime = srv.getRuntime();
+ String name = runtime.getName();
+ ITargetPlatformService service = PlatformUI.getWorkbench().getService(ITargetPlatformService.class);
+ ITargetHandle handle = null;
+ try {
+ handle = service.getWorkspaceTargetHandle();
+ } catch (CoreException e) {
+ }
+ if (handle != null) {
+ try {
+ String name2 = handle.getTargetDefinition().getName();
+ if (name.equals(name2)) {
+ decoration.addOverlay(ServerUiImages.DESC_OBJ_PDE_OVER, IDecoration.TOP_LEFT);
+ }
+ } catch (CoreException e) {
+ }
+ }
+ }
+ }
+ }
+
+}
diff --git a/org.eclipse.virgo.ide.ui/META-INF/MANIFEST.MF b/org.eclipse.virgo.ide.ui/META-INF/MANIFEST.MF
index 5bb1c5a..d9bcb09 100644
--- a/org.eclipse.virgo.ide.ui/META-INF/MANIFEST.MF
+++ b/org.eclipse.virgo.ide.ui/META-INF/MANIFEST.MF
@@ -40,7 +40,8 @@
org.eclipse.core.filesystem,
org.eclipse.ltk.core.refactoring,
org.eclipse.wst.sse.ui.infopop;bundle-version="1.0.300",
- org.eclipse.ui.navigator
+ org.eclipse.virgo.ide.pde.core,
+ org.eclipse.wst.web
Bundle-RequiredExecutionEnvironment: J2SE-1.5
Bundle-ActivationPolicy: lazy
Export-Package: org.eclipse.virgo.ide.internal.ui,
diff --git a/org.eclipse.virgo.ide.ui/icons/full/obj16/pde_project_obj.png b/org.eclipse.virgo.ide.ui/icons/full/obj16/pde_project_obj.png
new file mode 100644
index 0000000..95b6af1
--- /dev/null
+++ b/org.eclipse.virgo.ide.ui/icons/full/obj16/pde_project_obj.png
Binary files differ
diff --git a/org.eclipse.virgo.ide.ui/plugin.properties b/org.eclipse.virgo.ide.ui/plugin.properties
index 87ca512..9b18382 100644
--- a/org.eclipse.virgo.ide.ui/plugin.properties
+++ b/org.eclipse.virgo.ide.ui/plugin.properties
@@ -1,3 +1,5 @@
pluginName=Eclipse Virgo IDE (UI)
providerName=Eclipse.org - Virgo
+pdeProjectWizard.name=PDE Bundle Project
+pdeProjectWizard.desc=Create a new PDE bundle project
\ No newline at end of file
diff --git a/org.eclipse.virgo.ide.ui/plugin.xml b/org.eclipse.virgo.ide.ui/plugin.xml
index fa82626..ab6a447 100644
--- a/org.eclipse.virgo.ide.ui/plugin.xml
+++ b/org.eclipse.virgo.ide.ui/plugin.xml
@@ -32,6 +32,7 @@
</description>
</wizard>
<wizard
+ canFinishEarly="false"
category="org.eclipse.virgo.ide.ui.category"
class="org.eclipse.virgo.ide.ui.wizards.NewBundleProjectWizard"
finalPerspective="org.eclipse.virgo.ide.runtime.ui.perspective"
@@ -44,6 +45,20 @@
Create a new OSGi bundle project
</description>
</wizard>
+ <wizard
+ category="org.eclipse.virgo.ide.ui.category"
+ class="org.eclipse.virgo.ide.ui.wizards.NewPDEProjectWizard"
+ finalPerspective="org.eclipse.virgo.ide.runtime.ui.perspective"
+ hasPages="true"
+ icon="icons/full/obj16/pde_project_obj.png"
+ id="org.eclipse.virgo.ide.ui.pdeprojectwizard"
+ name="%pdeProjectWizard.name"
+ project="true">
+ <description>
+ %pdeProjectWizard.desc
+ </description>
+ </wizard>
+
</extension>
<extension
@@ -298,17 +313,20 @@
<actionSet
id="org.eclipse.wst.server.ui.new.actionSet">
</actionSet>
- <newWizardShortcut
+ <newWizardShortcut
id="org.eclipse.virgo.ide.ui.wizards.osgiProject">
</newWizardShortcut>
<newWizardShortcut
+ id="org.eclipse.virgo.ide.ui.pdeprojectwizard">
+ </newWizardShortcut>
+ <newWizardShortcut
id="org.eclipse.virgo.ide.ui.wizards.parProject">
</newWizardShortcut>
<newWizardShortcut
id="org.eclipse.wst.server.ui.new.server">
</newWizardShortcut>
- <newWizardShortcut id="org.eclipse.ui.wizards.new.folder"/>
- <newWizardShortcut id="org.eclipse.ui.wizards.new.file"/>
+ <newWizardShortcut id="org.eclipse.ui.wizards.new.folder"/>
+ <newWizardShortcut id="org.eclipse.ui.wizards.new.file"/>
<viewShortcut id="org.eclipse.ui.navigator.ProjectExplorer"/>
@@ -406,7 +424,7 @@
<viewShortcut
id="org.eclipse.virgo.ide.runtime.ui.virgoLog">
</viewShortcut>
- </perspectiveExtension>
+ </perspectiveExtension>
<perspectiveExtension
targetID="org.eclipse.jdt.ui.JavaPerspective">
<perspectiveShortcut
@@ -468,6 +486,26 @@
</or>
</enablement>
</commonWizard>
+ <commonWizard
+ type="new"
+ wizardId="org.eclipse.virgo.ide.ui.pdeprojectwizard">
+ <enablement>
+ <or>
+ <with
+ variable="selection">
+ <count
+ value="0">
+ </count>
+ </with>
+ <instanceof
+ value="org.eclipse.core.resources.IProject">
+ </instanceof>
+ <instanceof
+ value="org.eclipse.core.resources.IWorkspaceRoot">
+ </instanceof>
+</or>
+ </enablement>
+ </commonWizard>
</extension>
<extension
point="org.eclipse.ui.views">
@@ -476,4 +514,20 @@
name="Virgo">
</category>
</extension>
+<extension
+ point="org.eclipse.pde.ui.pluginContent">
+ <wizard
+ class="org.eclipse.virgo.ide.ui.wizards.NewPDEProjectContentWizard"
+ id="org.eclipse.virgo.ide.ui.pdetemplate"
+ java="true"
+ name="Virgo"
+ pureOSGi="true"
+ rcp="false"
+ requiresActivator="false"
+ ui-content="false">
+ <description>
+ This wizard creates new PDE projects that can be deployed to a Virgo test environment.
+ </description>
+ </wizard>
+</extension>
</plugin>
diff --git a/org.eclipse.virgo.ide.ui/src/org/eclipse/virgo/ide/ui/wizards/AbstractPropertiesPage.java b/org.eclipse.virgo.ide.ui/src/org/eclipse/virgo/ide/ui/wizards/AbstractPropertiesPage.java
index e5045a9..8541573 100644
--- a/org.eclipse.virgo.ide.ui/src/org/eclipse/virgo/ide/ui/wizards/AbstractPropertiesPage.java
+++ b/org.eclipse.virgo.ide.ui/src/org/eclipse/virgo/ide/ui/wizards/AbstractPropertiesPage.java
@@ -26,8 +26,8 @@
public AbstractPropertiesPage(String name) {
super(name);
- setTitle("Bundle Properties");
- setDescription("Set the additional properties of the bundle. " + "You can modify the properties at any time in the MANIFEST.MF file.");
+ setTitle(Messages.AbstractPropertiesPage_title);
+ setDescription(Messages.AbstractPropertiesPage_description + Messages.AbstractPropertiesPage_description2);
}
public void createControl(Composite parent) {
diff --git a/org.eclipse.virgo.ide.ui/src/org/eclipse/virgo/ide/ui/wizards/Messages.java b/org.eclipse.virgo.ide.ui/src/org/eclipse/virgo/ide/ui/wizards/Messages.java
new file mode 100644
index 0000000..c5babfd
--- /dev/null
+++ b/org.eclipse.virgo.ide.ui/src/org/eclipse/virgo/ide/ui/wizards/Messages.java
@@ -0,0 +1,91 @@
+
+package org.eclipse.virgo.ide.ui.wizards;
+
+import org.eclipse.osgi.util.NLS;
+
+public class Messages extends NLS {
+
+ private static final String BUNDLE_NAME = "org.eclipse.virgo.ide.ui.wizards.messages"; //$NON-NLS-1$
+
+ public static String AbstractPropertiesPage_description;
+
+ public static String AbstractPropertiesPage_description2;
+
+ public static String AbstractPropertiesPage_title;
+
+ public static String NewBundleInformationPage_Additional_Properties;
+
+ public static String NewBundleInformationPage_Classpath_Management;
+
+ public static String NewBundleInformationPage_enable_container;
+
+ public static String NewBundleInformationPage_WAB;
+
+ public static String NewBundleProjectSettingsPage_DESCRIPTION;
+
+ public static String NewBundleProjectSettingsPage_TITLE;
+
+ public static String NewBundleProjectWizard_title;
+
+ public static String NewParProjectReferencePage_desc;
+
+ public static String NewParProjectReferencePage_title;
+
+ public static String NewParProjectSettingsPage_DESCRIPTION;
+
+ public static String NewParProjectSettingsPage_TITLE;
+
+ public static String NewParProjectWizard_title;
+
+ public static String NewPDEProjectWABPage_context_root;
+
+ public static String NewPDEProjectWABPage_description;
+
+ public static String NewPDEProjectWABPage_title;
+
+ public static String NewPDEProjectWizard_title;
+
+ public static String ProjectContentPageStrings_bundle_content;
+
+ public static String ProjectContentPageStrings_bundle_content_desc;
+
+ public static String ProjectContentPageStrings_bundle_desc;
+
+ public static String ProjectContentPageStrings_bundle_name;
+
+ public static String ProjectContentPageStrings_bundle_plugin;
+
+ public static String ProjectContentPageStrings_bundle_properties;
+
+ public static String ProjectContentPageStrings_bundle_version;
+
+ public static String ProjectContentPageStrings_par_content;
+
+ public static String ProjectContentPageStrings_par_content_desc;
+
+ public static String ProjectContentPageStrings_par_desc;
+
+ public static String ProjectContentPageStrings_par_name;
+
+ public static String ProjectContentPageStrings_par_plugin;
+
+ public static String ProjectContentPageStrings_par_prorperties;
+
+ public static String ProjectContentPageStrings_par_symb_name;
+
+ public static String ProjectContentPageStrings_par_version;
+
+ public static String ProjectContentPageStrings_symb_name;
+
+ public static String WebModulePropertiesPage_context_path;
+
+ public static String WebModulePropertiesPage_text;
+
+ static {
+ // initialize resource bundle
+ NLS.initializeMessages(BUNDLE_NAME, Messages.class);
+ }
+
+ private Messages() {
+ }
+}
diff --git a/org.eclipse.virgo.ide.ui/src/org/eclipse/virgo/ide/ui/wizards/NewBundleInformationPage.java b/org.eclipse.virgo.ide.ui/src/org/eclipse/virgo/ide/ui/wizards/NewBundleInformationPage.java
index e30a9dd..c55ee70 100644
--- a/org.eclipse.virgo.ide.ui/src/org/eclipse/virgo/ide/ui/wizards/NewBundleInformationPage.java
+++ b/org.eclipse.virgo.ide.ui/src/org/eclipse/virgo/ide/ui/wizards/NewBundleInformationPage.java
@@ -79,20 +79,20 @@
Group propertiesGroup = new Group(container, SWT.NONE);
propertiesGroup.setLayout(new GridLayout(3, false));
propertiesGroup.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
- propertiesGroup.setText("Additional Properties");
+ propertiesGroup.setText(Messages.NewBundleInformationPage_Additional_Properties);
this.moduleType = new Button(propertiesGroup, SWT.CHECK);
- this.moduleType.setText("Web Application Bundle");
+ this.moduleType.setText(Messages.NewBundleInformationPage_WAB);
this.moduleType.setSelection(false);
this.moduleType.addSelectionListener(this.moduleTypeListener);
Group classpathGroup = new Group(container, SWT.NONE);
classpathGroup.setLayout(new GridLayout(1, false));
classpathGroup.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
- classpathGroup.setText("Classpath Management");
+ classpathGroup.setText(Messages.NewBundleInformationPage_Classpath_Management);
this.enableClasspathContainer = new Button(classpathGroup, SWT.CHECK);
- this.enableClasspathContainer.setText("Enable Bundle Classpath Container");
+ this.enableClasspathContainer.setText(Messages.NewBundleInformationPage_enable_container);
this.enableClasspathContainer.setSelection(true);
}
diff --git a/org.eclipse.virgo.ide.ui/src/org/eclipse/virgo/ide/ui/wizards/NewBundleProjectSettingsPage.java b/org.eclipse.virgo.ide.ui/src/org/eclipse/virgo/ide/ui/wizards/NewBundleProjectSettingsPage.java
index 42f04c4..37006b9 100644
--- a/org.eclipse.virgo.ide.ui/src/org/eclipse/virgo/ide/ui/wizards/NewBundleProjectSettingsPage.java
+++ b/org.eclipse.virgo.ide.ui/src/org/eclipse/virgo/ide/ui/wizards/NewBundleProjectSettingsPage.java
@@ -19,9 +19,9 @@
*/
public class NewBundleProjectSettingsPage extends NewJavaProjectWizardPageOne {
- private static String NEW_PROJECT_SETTINGS_TITLE = "Create a Bundle project";
+ private static String NEW_PROJECT_SETTINGS_TITLE = Messages.NewBundleProjectSettingsPage_TITLE;
- private static String NEW_PROJECT_SETTINGS_DESCRIPTION = "Create a Bundle project in the workspace or in an external location.";
+ private static String NEW_PROJECT_SETTINGS_DESCRIPTION = Messages.NewBundleProjectSettingsPage_DESCRIPTION;
public NewBundleProjectSettingsPage() {
super();
diff --git a/org.eclipse.virgo.ide.ui/src/org/eclipse/virgo/ide/ui/wizards/NewBundleProjectWizard.java b/org.eclipse.virgo.ide.ui/src/org/eclipse/virgo/ide/ui/wizards/NewBundleProjectWizard.java
index 5626389..068b0c2 100644
--- a/org.eclipse.virgo.ide.ui/src/org/eclipse/virgo/ide/ui/wizards/NewBundleProjectWizard.java
+++ b/org.eclipse.virgo.ide.ui/src/org/eclipse/virgo/ide/ui/wizards/NewBundleProjectWizard.java
@@ -84,7 +84,7 @@
private final IDataModel model;
- private final String title = "New Bundle Project";
+ private final String title = Messages.NewBundleProjectWizard_title;
private Map<String, String> properties;
@@ -93,7 +93,7 @@
public NewBundleProjectWizard() {
super();
setWindowTitle(this.title);
- setDefaultPageImageDescriptor(ServerIdeUiPlugin.getImageDescriptor("full/wizban/wizban-bundle.png"));
+ setDefaultPageImageDescriptor(ServerIdeUiPlugin.getImageDescriptor("full/wizban/wizban-bundle.png")); //$NON-NLS-1$
setNeedsProgressMonitor(true);
this.bundleData = new PluginFieldData();
this.model = DataModelFactory.createDataModel(new BundleFacetInstallDataModelProvider());
@@ -110,8 +110,8 @@
// WST 3.0 only
if (NewBundleProjectWizard.this.model.getBooleanProperty(BundleFacetInstallDataModelProvider.ENABLE_WEB_BUNDLE)) {
- fProject.installProjectFacet(ProjectFacetsManager.getProjectFacet("jst.java").getDefaultVersion(), null, monitor);
- fProject.installProjectFacet(ProjectFacetsManager.getProjectFacet(FacetCorePlugin.WEB_FACET_ID).getVersion("2.5"), null, monitor);
+ fProject.installProjectFacet(ProjectFacetsManager.getProjectFacet("jst.java").getDefaultVersion(), null, monitor); //$NON-NLS-1$
+ fProject.installProjectFacet(ProjectFacetsManager.getProjectFacet(FacetCorePlugin.WEB_FACET_ID).getVersion("2.5"), null, monitor); //$NON-NLS-1$
// wanna uninstall JavaScript facet, but it doesn't seem to
// be there yet
@@ -119,8 +119,8 @@
// .getProjectFacet(FacetCorePlugin.WEB_JS_FACET_ID).getDefaultVersion(),
// null, monitor);
- removeFromClasspath(project, "org.eclipse.jst.j2ee.internal.web.container", monitor);
- removeFromClasspath(project, "org.eclipse.jst.j2ee.internal.module.container", monitor);
+ removeFromClasspath(project, "org.eclipse.jst.j2ee.internal.web.container", monitor); //$NON-NLS-1$
+ removeFromClasspath(project, "org.eclipse.jst.j2ee.internal.module.container", monitor); //$NON-NLS-1$
}
fProject.installProjectFacet(ProjectFacetsManager.getProjectFacet(FacetCorePlugin.BUNDLE_FACET_ID).getDefaultVersion(), null,
@@ -138,10 +138,10 @@
try {
getContainer().run(true, true, oper);
} catch (InvocationTargetException e) {
- StatusManager.getManager().handle(new Status(IStatus.ERROR, ServerIdeUiPlugin.PLUGIN_ID, "Failure opening project facets.", e));
+ StatusManager.getManager().handle(new Status(IStatus.ERROR, ServerIdeUiPlugin.PLUGIN_ID, "Failure opening project facets.", e)); //$NON-NLS-1$
} catch (InterruptedException e) {
StatusManager.getManager().handle(
- new Status(IStatus.WARNING, ServerIdeUiPlugin.PLUGIN_ID, "Interruption while opening project facets.", e));
+ new Status(IStatus.WARNING, ServerIdeUiPlugin.PLUGIN_ID, "Interruption while opening project facets.", e)); //$NON-NLS-1$
}
}
@@ -260,14 +260,14 @@
}
});
- IFile manifestFile = (IFile) project.getProject().findMember("src/META-INF/MANIFEST.MF");
+ IFile manifestFile = (IFile) project.getProject().findMember("src/META-INF/MANIFEST.MF"); //$NON-NLS-1$
if (manifestFile != null) {
IWorkbenchWindow workbenchWindow = getWorkbench().getActiveWorkbenchWindow();
IWorkbenchPage page = workbenchWindow.getActivePage();
try {
page.openEditor(new FileEditorInput(manifestFile), BundleManifestEditor.ID_EDITOR);
} catch (PartInitException e) {
- MessageDialog.openError(workbenchWindow.getShell(), "Error opening editor", e.getMessage());
+ MessageDialog.openError(workbenchWindow.getShell(), "Error opening editor", e.getMessage()); //$NON-NLS-1$
}
}
}
diff --git a/org.eclipse.virgo.ide.ui/src/org/eclipse/virgo/ide/ui/wizards/NewPDEProjectContentWizard.java b/org.eclipse.virgo.ide.ui/src/org/eclipse/virgo/ide/ui/wizards/NewPDEProjectContentWizard.java
new file mode 100644
index 0000000..17400e0
--- /dev/null
+++ b/org.eclipse.virgo.ide.ui/src/org/eclipse/virgo/ide/ui/wizards/NewPDEProjectContentWizard.java
@@ -0,0 +1,75 @@
+/*******************************************************************************
+ * Copyright (c) 2015 GianMaria Romanato
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * GianMaria Romanato - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.virgo.ide.ui.wizards;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.jface.wizard.Wizard;
+import org.eclipse.pde.core.plugin.IPluginModelBase;
+import org.eclipse.pde.core.plugin.IPluginReference;
+import org.eclipse.pde.ui.IFieldData;
+import org.eclipse.pde.ui.IPluginContentWizard;
+
+/**
+ * A content wizard that adds a page for collecting the context root of a WAB. The bundle is assumed to be a WAB if the
+ * contect root is not empty.
+ * <p />
+ */
+public class NewPDEProjectContentWizard extends Wizard implements IPluginContentWizard {
+
+ private NewPDEProjectWABPage wabPage;
+
+ /**
+ * {@inheritDoc}
+ */
+ public void init(IFieldData data) {
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public IPluginReference[] getDependencies(String schemaVersion) {
+ return new IPluginReference[0];
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void addPages() {
+ wabPage = new NewPDEProjectWABPage();
+ addPage(wabPage);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean performFinish(IProject project, IPluginModelBase model, IProgressMonitor monitor) {
+ return true;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean performFinish() {
+ return true;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public String[] getNewFiles() {
+ return new String[0];
+ }
+
+}
diff --git a/org.eclipse.virgo.ide.ui/src/org/eclipse/virgo/ide/ui/wizards/NewPDEProjectWABPage.java b/org.eclipse.virgo.ide.ui/src/org/eclipse/virgo/ide/ui/wizards/NewPDEProjectWABPage.java
new file mode 100644
index 0000000..f5c0827
--- /dev/null
+++ b/org.eclipse.virgo.ide.ui/src/org/eclipse/virgo/ide/ui/wizards/NewPDEProjectWABPage.java
@@ -0,0 +1,127 @@
+/*******************************************************************************
+ * Copyright (c) 2015 GianMaria Romanato
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * GianMaria Romanato - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.virgo.ide.ui.wizards;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.jface.layout.GridDataFactory;
+import org.eclipse.jface.wizard.WizardPage;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.ModifyEvent;
+import org.eclipse.swt.events.ModifyListener;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Text;
+import org.eclipse.wst.project.facet.SimpleWebFacetInstallDataModelProvider;
+
+/**
+ * A wizard page for specifying a Web Bundle context root.
+ * <p />
+ *
+ */
+public class NewPDEProjectWABPage extends WizardPage {
+
+ /**
+ * A subclass created for the purpose of increasing the visibility of the validation method.
+ */
+ private static class WSTValidator extends SimpleWebFacetInstallDataModelProvider {
+
+ @Override
+ public org.eclipse.core.runtime.IStatus validateContextRoot(String contextRoot) {
+ return super.validateContextRoot(contextRoot);
+ };
+ };
+
+ private final WSTValidator validator = new WSTValidator();
+
+ /**
+ * The page name.
+ */
+ public static final String PAGE_NAME = NewPDEProjectWABPage.class.getSimpleName();
+
+ public NewPDEProjectWABPage() {
+ super(PAGE_NAME);
+ setTitle(Messages.NewPDEProjectWABPage_title);
+ setDescription(Messages.NewPDEProjectWABPage_description);
+ }
+
+ private Label contextPathLabel;
+
+ private Text contextPathText;
+
+ private String contextRoot;
+
+ /**
+ * {@inheritDoc}
+ */
+ public void createControl(Composite parent) {
+ Composite container = new Composite(parent, SWT.NONE);
+ container.setLayout(new GridLayout());
+ createContextRootSection(container);
+ setControl(container);
+ }
+
+ /**
+ * Creates the context root text field.
+ *
+ * @param container the parent composite
+ */
+ protected void createContextRootSection(Composite container) {
+ container.setLayout(new GridLayout(3, false));
+ container.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+
+ this.contextPathLabel = new Label(container, SWT.NONE);
+ this.contextPathLabel.setText(Messages.NewPDEProjectWABPage_context_root);
+
+ this.contextPathText = new Text(container, SWT.BORDER | SWT.SINGLE);
+ GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER).grab(true, false).span(2, 1).applyTo(this.contextPathText);
+
+ this.contextPathText.addModifyListener(new ModifyListener() {
+
+ public void modifyText(ModifyEvent e) {
+ NewPDEProjectWABPage.this.modifyText(e);
+ }
+ });
+ }
+
+ /**
+ * Validates the context root.
+ *
+ * @param e the modify event fired by the text widget
+ */
+ protected void modifyText(ModifyEvent e) {
+ contextRoot = null;
+
+ String name = contextPathText.getText();
+ IStatus status = validator.validateContextRoot(name);
+
+ if (!status.isOK()) {
+ setPageComplete(false);
+ setErrorMessage(status.getMessage());
+ return;
+ }
+
+ contextRoot = name;
+ setPageComplete(true);
+ setErrorMessage(null);
+ }
+
+ /**
+ * Returns the value of the context root.
+ *
+ * @return the context root
+ */
+ public String getContextRoot() {
+ return contextRoot;
+ }
+}
diff --git a/org.eclipse.virgo.ide.ui/src/org/eclipse/virgo/ide/ui/wizards/NewPDEProjectWizard.java b/org.eclipse.virgo.ide.ui/src/org/eclipse/virgo/ide/ui/wizards/NewPDEProjectWizard.java
new file mode 100644
index 0000000..964f9d3
--- /dev/null
+++ b/org.eclipse.virgo.ide.ui/src/org/eclipse/virgo/ide/ui/wizards/NewPDEProjectWizard.java
@@ -0,0 +1,90 @@
+/*******************************************************************************
+ * Copyright (c) 2015 GianMaria Romanato
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * GianMaria Romanato - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.virgo.ide.ui.wizards;
+
+import java.lang.reflect.InvocationTargetException;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.ResourcesPlugin;
+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.jface.operation.IRunnableWithProgress;
+import org.eclipse.pde.core.project.IBundleProjectService;
+import org.eclipse.pde.ui.templates.NewPluginProjectFromTemplateWizard;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.dialogs.WizardNewProjectCreationPage;
+import org.eclipse.ui.statushandlers.StatusManager;
+import org.eclipse.virgo.ide.pde.core.internal.cmd.SetupProjectOperation;
+import org.eclipse.virgo.ide.ui.ServerIdeUiPlugin;
+
+/**
+ * A PDE template wizard used to create PDE projects for Virgo tools.
+ * <p />
+ *
+ */
+public class NewPDEProjectWizard extends NewPluginProjectFromTemplateWizard {
+
+ public NewPDEProjectWizard() {
+ super();
+ setWindowTitle(Messages.NewPDEProjectWizard_title);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected String getTemplateID() {
+ return "org.eclipse.virgo.ide.ui.pdetemplate"; //$NON-NLS-1$
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean performFinish() {
+ boolean result = super.performFinish();
+ if (result) {
+ // on finish modify the newly created PDE project
+ WizardNewProjectCreationPage newProjectCreationPage = (WizardNewProjectCreationPage) getPage("main"); //$NON-NLS-1$
+ IProject project = newProjectCreationPage.getProjectHandle();
+ IBundleProjectService service = PlatformUI.getWorkbench().getService(IBundleProjectService.class);
+ String contextRoot = getContextRoot();
+
+ final SetupProjectOperation operation = new SetupProjectOperation(project, contextRoot, service);
+
+ try {
+ getContainer().run(true, false, new IRunnableWithProgress() {
+
+ public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
+ try {
+ ResourcesPlugin.getWorkspace().run(operation, monitor);
+ } catch (CoreException e) {
+ StatusManager.getManager().handle(e.getStatus(), StatusManager.LOG | StatusManager.SHOW);
+ }
+ }
+ });
+ } catch (Exception e) {
+ IStatus s = new Status(IStatus.ERROR, ServerIdeUiPlugin.PLUGIN_ID, e.getMessage(), e);
+ StatusManager.getManager().handle(s, StatusManager.LOG | StatusManager.SHOW);
+ }
+ }
+ return true;
+ }
+
+ private String getContextRoot() {
+ NewPDEProjectWABPage wabPage = (NewPDEProjectWABPage) getPage(NewPDEProjectWABPage.class.getSimpleName());
+ String contextRoot = wabPage.getContextRoot();
+ return contextRoot;
+ }
+}
diff --git a/org.eclipse.virgo.ide.ui/src/org/eclipse/virgo/ide/ui/wizards/NewParProjectReferencePage.java b/org.eclipse.virgo.ide.ui/src/org/eclipse/virgo/ide/ui/wizards/NewParProjectReferencePage.java
index 432ea57..987619e 100644
--- a/org.eclipse.virgo.ide.ui/src/org/eclipse/virgo/ide/ui/wizards/NewParProjectReferencePage.java
+++ b/org.eclipse.virgo.ide.ui/src/org/eclipse/virgo/ide/ui/wizards/NewParProjectReferencePage.java
@@ -22,9 +22,9 @@
*/
public class NewParProjectReferencePage extends WizardNewProjectReferencePage {
- private static String NEW_PROJECT_REFERENCE_TITLE = "Bundle References";
+ private static String NEW_PROJECT_REFERENCE_TITLE = Messages.NewParProjectReferencePage_title;
- private static String NEW_PROJECT_REFERENCE_DESCRIPTION = "Add bundles to PAR project.";
+ private static String NEW_PROJECT_REFERENCE_DESCRIPTION = Messages.NewParProjectReferencePage_desc;
public NewParProjectReferencePage(String pageName) {
super(pageName);
diff --git a/org.eclipse.virgo.ide.ui/src/org/eclipse/virgo/ide/ui/wizards/NewParProjectSettingsPage.java b/org.eclipse.virgo.ide.ui/src/org/eclipse/virgo/ide/ui/wizards/NewParProjectSettingsPage.java
index 8c9ffc2..3f10f4f 100644
--- a/org.eclipse.virgo.ide.ui/src/org/eclipse/virgo/ide/ui/wizards/NewParProjectSettingsPage.java
+++ b/org.eclipse.virgo.ide.ui/src/org/eclipse/virgo/ide/ui/wizards/NewParProjectSettingsPage.java
@@ -22,9 +22,9 @@
*/
public class NewParProjectSettingsPage extends WizardNewProjectCreationPage {
- private static String NEW_PROJECT_SETTINGS_TITLE = "Create a PAR project";
+ private static String NEW_PROJECT_SETTINGS_TITLE = Messages.NewParProjectSettingsPage_TITLE;
- private static String NEW_PROJECT_SETTINGS_DESCRIPTION = "Enter a name and location for the PAR project.";
+ private static String NEW_PROJECT_SETTINGS_DESCRIPTION = Messages.NewParProjectSettingsPage_DESCRIPTION;
private final IStructuredSelection selection;
@@ -38,7 +38,7 @@
@Override
public void createControl(Composite parent) {
super.createControl(parent);
- createWorkingSetGroup((Composite) getControl(), this.selection, new String[] { "org.eclipse.jdt.ui.JavaWorkingSetPage" });
+ createWorkingSetGroup((Composite) getControl(), this.selection, new String[] { "org.eclipse.jdt.ui.JavaWorkingSetPage" }); //$NON-NLS-1$
Dialog.applyDialogFont(getControl());
}
diff --git a/org.eclipse.virgo.ide.ui/src/org/eclipse/virgo/ide/ui/wizards/NewParProjectWizard.java b/org.eclipse.virgo.ide.ui/src/org/eclipse/virgo/ide/ui/wizards/NewParProjectWizard.java
index 0c09d4f..d735b32 100644
--- a/org.eclipse.virgo.ide.ui/src/org/eclipse/virgo/ide/ui/wizards/NewParProjectWizard.java
+++ b/org.eclipse.virgo.ide.ui/src/org/eclipse/virgo/ide/ui/wizards/NewParProjectWizard.java
@@ -72,9 +72,9 @@
*/
public class NewParProjectWizard extends AbstractNewParProjectWizard implements INewWizard {
- private static final String PAR_FILE_NAME = ".settings/org.eclipse.virgo.ide.runtime.core.par.xml";
+ private static final String PAR_FILE_NAME = ".settings/org.eclipse.virgo.ide.runtime.core.par.xml"; //$NON-NLS-1$
- private static final String ENCODING_UTF8 = "UTF-8";
+ private static final String ENCODING_UTF8 = "UTF-8"; //$NON-NLS-1$
private WizardNewProjectCreationPage mainPage;
@@ -88,7 +88,7 @@
private final IDataModel model;
- private final String title = "New PAR Project";
+ private final String title = Messages.NewParProjectWizard_title;
protected ParPackage parPackage = ParPackage.eINSTANCE;
@@ -128,16 +128,16 @@
try {
getContainer().run(true, true, oper);
} catch (InvocationTargetException e) {
- StatusManager.getManager().handle(new Status(IStatus.ERROR, ServerIdeUiPlugin.PLUGIN_ID, "Exception while adding project facets.", e));
+ StatusManager.getManager().handle(new Status(IStatus.ERROR, ServerIdeUiPlugin.PLUGIN_ID, "Exception while adding project facets.", e)); //$NON-NLS-1$
} catch (InterruptedException e) {
StatusManager.getManager().handle(
- new Status(IStatus.WARNING, ServerIdeUiPlugin.PLUGIN_ID, "Interruption while adding project facets.", e));
+ new Status(IStatus.WARNING, ServerIdeUiPlugin.PLUGIN_ID, "Interruption while adding project facets.", e)); //$NON-NLS-1$
}
}
@Override
public void addPages() {
- this.mainPage = new NewParProjectSettingsPage("basicNewProjectPage", getSelection());
+ this.mainPage = new NewParProjectSettingsPage("basicNewProjectPage", getSelection()); //$NON-NLS-1$
setMainPage(this.mainPage);
addPage(this.mainPage);
@@ -161,7 +161,7 @@
// only add page if there are already projects in the workspace
if (ResourcesPlugin.getWorkspace().getRoot().getProjects().length > 0) {
- this.referencePage = new NewParProjectReferencePage("basicReferenceProjectPage");
+ this.referencePage = new NewParProjectReferencePage("basicReferenceProjectPage"); //$NON-NLS-1$
addPage(this.referencePage);
}
}
@@ -244,7 +244,7 @@
getWorkbench().getWorkingSetManager().addToWorkingSets(getNewProject(), workingSets);
}
- IFile manifestFile = (IFile) getNewProject().findMember("META-INF/MANIFEST.MF");
+ IFile manifestFile = (IFile) getNewProject().findMember("META-INF/MANIFEST.MF"); //$NON-NLS-1$
if (manifestFile != null) {
// Select the new file resource in the current view.
//
@@ -266,7 +266,7 @@
try {
page.openEditor(new FileEditorInput(manifestFile), ParManifestEditor.ID_EDITOR);
} catch (PartInitException exception) {
- MessageDialog.openError(workbenchWindow.getShell(), "Error opening editor", exception.getMessage());
+ MessageDialog.openError(workbenchWindow.getShell(), "Error opening editor", exception.getMessage()); //$NON-NLS-1$
}
return true;
}
@@ -298,7 +298,7 @@
@Override
protected void initializeDefaultPageImageDescriptor() {
- setDefaultPageImageDescriptor(ServerIdeUiPlugin.getImageDescriptor("full/wizban/wizban-par.png"));
+ setDefaultPageImageDescriptor(ServerIdeUiPlugin.getImageDescriptor("full/wizban/wizban-par.png")); //$NON-NLS-1$
}
}
diff --git a/org.eclipse.virgo.ide.ui/src/org/eclipse/virgo/ide/ui/wizards/NullPropertiesPage.java b/org.eclipse.virgo.ide.ui/src/org/eclipse/virgo/ide/ui/wizards/NullPropertiesPage.java
index de71d2b..49bd930 100644
--- a/org.eclipse.virgo.ide.ui/src/org/eclipse/virgo/ide/ui/wizards/NullPropertiesPage.java
+++ b/org.eclipse.virgo.ide.ui/src/org/eclipse/virgo/ide/ui/wizards/NullPropertiesPage.java
@@ -21,7 +21,7 @@
*/
public class NullPropertiesPage extends AbstractPropertiesPage {
- protected static String ID_PAGE = "null.properties";
+ protected static String ID_PAGE = "null.properties"; //$NON-NLS-1$
public NullPropertiesPage() {
super(ID_PAGE);
@@ -34,7 +34,7 @@
@Override
public String getModuleType() {
- return "";
+ return ""; //$NON-NLS-1$
}
@Override
diff --git a/org.eclipse.virgo.ide.ui/src/org/eclipse/virgo/ide/ui/wizards/ProjectContentPageStrings.java b/org.eclipse.virgo.ide.ui/src/org/eclipse/virgo/ide/ui/wizards/ProjectContentPageStrings.java
index 0e55744..ae3042e 100644
--- a/org.eclipse.virgo.ide.ui/src/org/eclipse/virgo/ide/ui/wizards/ProjectContentPageStrings.java
+++ b/org.eclipse.virgo.ide.ui/src/org/eclipse/virgo/ide/ui/wizards/ProjectContentPageStrings.java
@@ -19,36 +19,36 @@
public class ProjectContentPageStrings {
// PDEUIMessages (modified)
- public static String Bundle_ContentPage_title = "Bundle Content";
+ public static String Bundle_ContentPage_title = Messages.ProjectContentPageStrings_bundle_content;
- public static String Par_ContentPage_title = "PAR Content";
+ public static String Par_ContentPage_title = Messages.ProjectContentPageStrings_par_content;
- public static String Bundle_ContentPage_desc = "Enter the data required to generate the bundle.";
+ public static String Bundle_ContentPage_desc = Messages.ProjectContentPageStrings_bundle_content_desc;
- public static String Par_ContentPage_desc = "Enter the data required to generate the PAR.";
+ public static String Par_ContentPage_desc = Messages.ProjectContentPageStrings_par_content_desc;
- public static String Bundle_ContentPage_pGroup = "Bundle Properties";
+ public static String Bundle_ContentPage_pGroup = Messages.ProjectContentPageStrings_bundle_properties;
- public static String Par_ContentPage_pGroup = "PAR Properties";
+ public static String Par_ContentPage_pGroup = Messages.ProjectContentPageStrings_par_prorperties;
- public static String Bundle_ContentPage_pid = "Bundle Symbolic Name";
+ public static String Bundle_ContentPage_pid = Messages.ProjectContentPageStrings_symb_name;
- public static String Par_ContentPage_pid = "Application Symbolic Name";
+ public static String Par_ContentPage_pid = Messages.ProjectContentPageStrings_par_symb_name;
- public static String Bundle_ContentPage_pversion = "Bundle Version";
+ public static String Bundle_ContentPage_pversion = Messages.ProjectContentPageStrings_bundle_version;
- public static String Par_ContentPage_pversion = "Application Version";
+ public static String Par_ContentPage_pversion = Messages.ProjectContentPageStrings_par_version;
- public static String Bundle_ContentPage_pname = "Bundle Name";
+ public static String Bundle_ContentPage_pname = Messages.ProjectContentPageStrings_bundle_name;
- public static String Par_ContentPage_pname = "Application Name";
+ public static String Par_ContentPage_pname = Messages.ProjectContentPageStrings_par_name;
- public static String Bundle_ContentPage_pprovider = "Bundle Description";
+ public static String Bundle_ContentPage_pprovider = Messages.ProjectContentPageStrings_bundle_desc;
- public static String Par_ContentPage_pprovider = "Application Description";
+ public static String Par_ContentPage_pprovider = Messages.ProjectContentPageStrings_par_desc;
- public static String Bundle_ContentPage_plugin = "{0} Bundle";
+ public static String Bundle_ContentPage_plugin = Messages.ProjectContentPageStrings_bundle_plugin;
- public static String Par_ContentPage_plugin = "{0} PAR";
+ public static String Par_ContentPage_plugin = Messages.ProjectContentPageStrings_par_plugin;
}
diff --git a/org.eclipse.virgo.ide.ui/src/org/eclipse/virgo/ide/ui/wizards/WebModulePropertiesPage.java b/org.eclipse.virgo.ide.ui/src/org/eclipse/virgo/ide/ui/wizards/WebModulePropertiesPage.java
index ea59bca..0431f05 100644
--- a/org.eclipse.virgo.ide.ui/src/org/eclipse/virgo/ide/ui/wizards/WebModulePropertiesPage.java
+++ b/org.eclipse.virgo.ide.ui/src/org/eclipse/virgo/ide/ui/wizards/WebModulePropertiesPage.java
@@ -29,7 +29,7 @@
*/
public class WebModulePropertiesPage extends AbstractPropertiesPage {
- protected static String ID_PAGE = "web.properties";
+ protected static String ID_PAGE = "web.properties"; //$NON-NLS-1$
private Label contextPathLabel;
@@ -44,10 +44,10 @@
Group propertiesGroup = new Group(container, SWT.NONE);
propertiesGroup.setLayout(new GridLayout(3, false));
propertiesGroup.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
- propertiesGroup.setText("Web Module Properties");
+ propertiesGroup.setText(Messages.WebModulePropertiesPage_text);
this.contextPathLabel = new Label(propertiesGroup, SWT.NONE);
- this.contextPathLabel.setText("Web-ContextPath");
+ this.contextPathLabel.setText(Messages.WebModulePropertiesPage_context_path);
this.contextPathText = new Text(propertiesGroup, SWT.BORDER | SWT.SINGLE);
GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER).grab(true, false).span(2, 1).applyTo(this.contextPathText);
@@ -62,7 +62,7 @@
@Override
public String getModuleType() {
- return "Web";
+ return "Web"; //$NON-NLS-1$
}
}
diff --git a/org.eclipse.virgo.ide.ui/src/org/eclipse/virgo/ide/ui/wizards/messages.properties b/org.eclipse.virgo.ide.ui/src/org/eclipse/virgo/ide/ui/wizards/messages.properties
new file mode 100644
index 0000000..0152f53
--- /dev/null
+++ b/org.eclipse.virgo.ide.ui/src/org/eclipse/virgo/ide/ui/wizards/messages.properties
@@ -0,0 +1,37 @@
+AbstractPropertiesPage_description=Set the additional properties of the bundle.
+AbstractPropertiesPage_description2=You can modify the properties at any time in the MANIFEST.MF file.
+AbstractPropertiesPage_title=Bundle Properties
+NewBundleInformationPage_Additional_Properties=Additional Properties
+NewBundleInformationPage_Classpath_Management=Classpath Management
+NewBundleInformationPage_enable_container=Enable Bundle Classpath Container
+NewBundleInformationPage_WAB=Web Application Bundle
+NewBundleProjectSettingsPage_DESCRIPTION=Create a Bundle project in the workspace or in an external location.
+NewBundleProjectSettingsPage_TITLE=Create a Bundle project
+NewBundleProjectWizard_title=New Bundle Project
+NewParProjectReferencePage_desc=Add bundles to PAR project.
+NewParProjectReferencePage_title=Bundle References
+NewParProjectSettingsPage_DESCRIPTION=Enter a name and location for the PAR project.
+NewParProjectSettingsPage_TITLE=Create a PAR project
+NewParProjectWizard_title=New PAR Project
+NewPDEProjectWABPage_context_root=Context root:
+NewPDEProjectWABPage_description=Specify a Context root if you want the project to be a WAB
+NewPDEProjectWABPage_title=Web Application Bundle
+NewPDEProjectWizard_title=New Virgo PDE Bundle Project
+ProjectContentPageStrings_bundle_content=Bundle Content
+ProjectContentPageStrings_bundle_content_desc=Enter the data required to generate the bundle.
+ProjectContentPageStrings_bundle_desc=Bundle Description
+ProjectContentPageStrings_bundle_name=Bundle Name
+ProjectContentPageStrings_bundle_plugin={0} Bundle
+ProjectContentPageStrings_bundle_properties=Bundle Properties
+ProjectContentPageStrings_bundle_version=Bundle Version
+ProjectContentPageStrings_par_content=PAR Content
+ProjectContentPageStrings_par_content_desc=Enter the data required to generate the PAR.
+ProjectContentPageStrings_par_desc=Application Description
+ProjectContentPageStrings_par_name=Application Name
+ProjectContentPageStrings_par_plugin={0} PAR
+ProjectContentPageStrings_par_prorperties=PAR Properties
+ProjectContentPageStrings_par_symb_name=Application Symbolic Name
+ProjectContentPageStrings_par_version=Application Version
+ProjectContentPageStrings_symb_name=Bundle Symbolic Name
+WebModulePropertiesPage_context_path=Web-ContextPath
+WebModulePropertiesPage_text=Web Module Properties
diff --git a/pom.xml b/pom.xml
index 3d0dc1c..e666c2d 100644
--- a/pom.xml
+++ b/pom.xml
@@ -39,6 +39,7 @@
<module>org.eclipse.virgo.ide.export</module>
<module>org.eclipse.virgo.ide.export.tests</module>
<module>org.eclipse.virgo.ide.facet.core</module>
+ <module>org.eclipse.virgo.ide.pde.core</module>
<module>org.eclipse.virgo.ide.feature</module>
<module>org.eclipse.virgo.ide.jdt.core</module>
<module>org.eclipse.virgo.ide.jdt.ui</module>