Bug 573076 - PDE should provide a generic "test report" view
A JUnit Plugin test runner client for Unit Test View bundle.
Change-Id: I50da75952c84c02a878b72e452fbd9574b8b6561
Signed-off-by: Victor Rubezhny <vrubezhny@redhat.com>
Reviewed-on: https://git.eclipse.org/r/c/pde/eclipse.pde.ui/+/179677
Tested-by: PDE Bot <pde-bot@eclipse.org>
Tested-by: Vikas Chandra <Vikas.Chandra@in.ibm.com>
Reviewed-by: Vikas Chandra <Vikas.Chandra@in.ibm.com>
diff --git a/features/org.eclipse.pde.unittest.junit-feature/.project b/features/org.eclipse.pde.unittest.junit-feature/.project
new file mode 100644
index 0000000..46f6e44
--- /dev/null
+++ b/features/org.eclipse.pde.unittest.junit-feature/.project
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>org.eclipse.pde.unittest.junit-feature</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.pde.FeatureBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.pde.FeatureNature</nature>
+ </natures>
+</projectDescription>
diff --git a/features/org.eclipse.pde.unittest.junit-feature/.settings/org.eclipse.core.resources.prefs b/features/org.eclipse.pde.unittest.junit-feature/.settings/org.eclipse.core.resources.prefs
new file mode 100644
index 0000000..99f26c0
--- /dev/null
+++ b/features/org.eclipse.pde.unittest.junit-feature/.settings/org.eclipse.core.resources.prefs
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+encoding/<project>=UTF-8
diff --git a/features/org.eclipse.pde.unittest.junit-feature/.settings/org.eclipse.core.runtime.prefs b/features/org.eclipse.pde.unittest.junit-feature/.settings/org.eclipse.core.runtime.prefs
new file mode 100644
index 0000000..5a0ad22
--- /dev/null
+++ b/features/org.eclipse.pde.unittest.junit-feature/.settings/org.eclipse.core.runtime.prefs
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+line.separator=\n
diff --git a/features/org.eclipse.pde.unittest.junit-feature/build.properties b/features/org.eclipse.pde.unittest.junit-feature/build.properties
new file mode 100644
index 0000000..3b0a539
--- /dev/null
+++ b/features/org.eclipse.pde.unittest.junit-feature/build.properties
@@ -0,0 +1,16 @@
+###############################################################################
+# Copyright (c) 2021 Red Hat, Inc. and others.
+#
+# This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License 2.0
+# which accompanies this distribution, and is available at
+# https://www.eclipse.org/legal/epl-2.0/
+#
+# SPDX-License-Identifier: EPL-2.0
+#
+# Contributors:
+# Red Hat, Inc. - initial API and implementation
+###############################################################################
+bin.includes=\
+feature.xml,\
+feature.properties
diff --git a/features/org.eclipse.pde.unittest.junit-feature/feature.properties b/features/org.eclipse.pde.unittest.junit-feature/feature.properties
new file mode 100644
index 0000000..f966d8c
--- /dev/null
+++ b/features/org.eclipse.pde.unittest.junit-feature/feature.properties
@@ -0,0 +1,42 @@
+###############################################################################
+# Copyright (c) 2021 Red Hat, Inc. and others.
+#
+# This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License 2.0
+# which accompanies this distribution, and is available at
+# https://www.eclipse.org/legal/epl-2.0/
+#
+# SPDX-License-Identifier: EPL-2.0
+#
+# Contributors:
+# Red Hat, Inc. - initial API and implementation
+###############################################################################
+# feature.properties
+# contains externalized strings for feature.xml
+# "%foo" in feature.xml corresponds to the key "foo" in this file
+# java.io.Properties file (ISO 8859-1 with "\" escapes)
+# This file should be translated.
+
+# "featureName" property - name of the feature
+featureName=Eclipse Plug-in Test runner client for UnitTest View (Experimental)
+
+# "providerName" property - name of the company that provides the feature
+providerName=Eclipse.org
+
+# "description" property - description of the feature
+description=Eclipse plug-in test runner client for UnitTest View.
+
+# "copyright" property - text of the "Feature Update Copyright"
+copyright=\
+Copyright (c) 2021 Red Hat, Inc. and others.\n\
+\n\
+This program and the accompanying materials\n\
+are made available under the terms of the Eclipse Public License 2.0\n\
+which accompanies this distribution, and is available at\n\
+https://www.eclipse.org/legal/epl-2.0/\n\
+\n\
+SPDX-License-Identifier: EPL-2.0\n\
+\n\
+Contributors:\n\
+ Red Hat, Inc. - initial API and implementation\n
+################ end of copyright property ####################################
diff --git a/features/org.eclipse.pde.unittest.junit-feature/feature.xml b/features/org.eclipse.pde.unittest.junit-feature/feature.xml
new file mode 100644
index 0000000..485aace
--- /dev/null
+++ b/features/org.eclipse.pde.unittest.junit-feature/feature.xml
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<feature
+ id="org.eclipse.pde.unittest.junit"
+ label="%featureName"
+ version="1.0.0.qualifier"
+ provider-name="%providerName"
+ license-feature="org.eclipse.license"
+ license-feature-version="0.0.0">
+
+ <description>
+ %description
+ </description>
+
+ <copyright>
+ %copyright
+ </copyright>
+
+ <license url="%licenseURL">
+ %license
+ </license>
+
+ <requires>
+ <import plugin="org.eclipse.unittest.ui"/>
+ <import plugin="org.eclipse.pde.ui"/>
+ <import plugin="org.eclipse.jdt.ui.unittest.junit"/>
+ <import plugin="org.eclipse.ui"/>
+ <import plugin="org.eclipse.debug.ui"/>
+ <import plugin="org.eclipse.jdt.core"/>
+ <import plugin="org.eclipse.core.runtime"/>
+ <import plugin="org.eclipse.core.variables"/>
+ <import plugin="org.eclipse.jdt.debug.ui"/>
+ <import plugin="org.eclipse.jdt.launching"/>
+ <import plugin="org.eclipse.jdt.junit"/>
+ </requires>
+
+ <plugin
+ id="org.eclipse.pde.unittest.junit"
+ download-size="0"
+ install-size="0"
+ version="0.0.0"
+ unpack="false"/>
+
+</feature>
diff --git a/features/org.eclipse.pde.unittest.junit-feature/pom.xml b/features/org.eclipse.pde.unittest.junit-feature/pom.xml
new file mode 100644
index 0000000..f05e305
--- /dev/null
+++ b/features/org.eclipse.pde.unittest.junit-feature/pom.xml
@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (c) 2012, 2019 Eclipse Foundation and others.
+ All rights reserved. This program and the accompanying materials
+ are made available under the terms of the Eclipse Distribution License v1.0
+ which accompanies this distribution, and is available at
+ http://www.eclipse.org/org/documents/edl-v10.php
+
+ Contributors:
+ Igor Fedorenko - initial implementation
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <artifactId>eclipse.pde.ui</artifactId>
+ <groupId>eclipse.pde.ui</groupId>
+ <version>4.20.0-SNAPSHOT</version>
+ <relativePath>../../</relativePath>
+ </parent>
+ <groupId>org.eclipse.pde.unittest.junit.feature</groupId>
+ <artifactId>org.eclipse.pde.unittest.junit</artifactId>
+ <version>1.0.0-SNAPSHOT</version>
+ <packaging>eclipse-feature</packaging>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.eclipse.tycho</groupId>
+ <artifactId>tycho-source-plugin</artifactId>
+ <version>${tycho.version}</version>
+ <executions>
+ <execution>
+ <phase>package</phase>
+ <id>feature-source</id>
+ <goals>
+ <goal>feature-source</goal>
+ </goals>
+ <configuration>
+ <excludes>
+ <plugin id="org.eclipse.pde"/>
+ <plugin id="org.eclipse.pde.doc.user"/>
+ </excludes>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.eclipse.tycho</groupId>
+ <artifactId>tycho-p2-plugin</artifactId>
+ <version>${tycho.version}</version>
+ <executions>
+ <execution>
+ <id>attach-p2-metadata</id>
+ <phase>package</phase>
+ <goals>
+ <goal>p2-metadata</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+</project>
diff --git a/features/org.eclipse.pde.unittest.junit-feature/sourceTemplateFeature/feature.properties b/features/org.eclipse.pde.unittest.junit-feature/sourceTemplateFeature/feature.properties
new file mode 100644
index 0000000..01d7dd4
--- /dev/null
+++ b/features/org.eclipse.pde.unittest.junit-feature/sourceTemplateFeature/feature.properties
@@ -0,0 +1,42 @@
+###############################################################################
+# Copyright (c) 2021 Red Hat, Inc. and others.
+#
+# This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License 2.0
+# which accompanies this distribution, and is available at
+# https://www.eclipse.org/legal/epl-2.0/
+#
+# SPDX-License-Identifier: EPL-2.0
+#
+# Contributors:
+# Red Hat Inc. - initial API and implementation
+###############################################################################
+# feature.properties
+# contains externalized strings for feature.xml
+# "%foo" in feature.xml corresponds to the key "foo" in this file
+# java.io.Properties file (ISO 8859-1 with "\" escapes)
+# This file should be translated.
+
+# "featureName" property - name of the feature
+featureName=Eclipse PDE Plug-in Developer Unit Test support Resources
+
+# "providerName" property - name of the company that provides the feature
+providerName=Eclipse.org
+
+# "description" property - description of the feature
+description=Eclipse plug-in development environment Unit Test support, including documentation and source code zips.
+
+# "copyright" property - text of the "Feature Update Copyright"
+copyright=\
+Copyright (c) 2021 Red Hat, Inc. and others.\n\
+\n\
+This program and the accompanying materials\n\
+are made available under the terms of the Eclipse Public License 2.0\n\
+which accompanies this distribution, and is available at\n\
+https://www.eclipse.org/legal/epl-2.0/\n\
+\n\
+SPDX-License-Identifier: EPL-2.0\n\
+\n\
+Contributors:\n\
+ Red Hat Inc. - initial API and implementation\n
+################ end of copyright property ####################################
diff --git a/pom.xml b/pom.xml
index 2048294..bc7281f 100644
--- a/pom.xml
+++ b/pom.xml
@@ -78,6 +78,8 @@
<module>ui/org.eclipse.ui.trace</module>
<module>ui/org.eclipse.pde.genericeditor.extension</module>
<module>ui/org.eclipse.pde.genericeditor.extension.tests</module>
+ <module>ui/org.eclipse.pde.unittest.junit</module>
<module>features/org.eclipse.pde-feature</module>
+ <module>features/org.eclipse.pde.unittest.junit-feature</module>
</modules>
</project>
diff --git a/ui/org.eclipse.pde.core/META-INF/MANIFEST.MF b/ui/org.eclipse.pde.core/META-INF/MANIFEST.MF
index f6b64d0..8f6a2a2 100644
--- a/ui/org.eclipse.pde.core/META-INF/MANIFEST.MF
+++ b/ui/org.eclipse.pde.core/META-INF/MANIFEST.MF
@@ -21,7 +21,8 @@
org.eclipse.pde.ua.ui,
org.eclipse.pde.ds.ui,
org.eclipse.pde.ua.core,
- org.eclipse.pde.api.tools.tests",
+ org.eclipse.pde.api.tools.tests,
+ org.eclipse.pde.unittest.junit",
org.eclipse.pde.internal.core.build;x-friends:="org.eclipse.pde.ui,org.eclipse.pde.ds.ui,org.eclipse.pde.ua.ui",
org.eclipse.pde.internal.core.builders;x-friends:="org.eclipse.pde.ui,org.eclipse.pde.launching,org.eclipse.pde.ds.core",
org.eclipse.pde.internal.core.bundle;x-friends:="org.eclipse.pde.ui,org.eclipse.pde.ds.ui",
@@ -73,7 +74,8 @@
org.eclipse.pde.ds.core,
org.eclipse.pde.ds.ui,
org.eclipse.pde.ua.core,
- org.eclipse.pde.api.tools",
+ org.eclipse.pde.api.tools,
+ org.eclipse.pde.unittest.junit",
org.eclipse.pde.internal.core.variables;x-internal:=true
Require-Bundle:
org.eclipse.core.runtime;bundle-version="[3.14.0,4.0.0)",
diff --git a/ui/org.eclipse.pde.launching/META-INF/MANIFEST.MF b/ui/org.eclipse.pde.launching/META-INF/MANIFEST.MF
index a2946f2..d53cecb 100644
--- a/ui/org.eclipse.pde.launching/META-INF/MANIFEST.MF
+++ b/ui/org.eclipse.pde.launching/META-INF/MANIFEST.MF
@@ -16,8 +16,10 @@
org.eclipse.jdt.debug;bundle-version="[3.2.0,4.0.0)",
org.eclipse.core.filesystem;bundle-version="[1.0.0,2.0.0)"
Bundle-Activator: org.eclipse.pde.internal.launching.PDELaunchingPlugin
-Export-Package: org.eclipse.pde.internal.launching;x-friends:="org.eclipse.pde.ui",
- org.eclipse.pde.internal.launching.launcher;x-friends:="org.eclipse.pde.ui",
+Export-Package: org.eclipse.pde.internal.launching;x-friends:="org.eclipse.pde.ui,
+ org.eclipse.pde.unittest.junit",
+ org.eclipse.pde.internal.launching.launcher;x-friends:="org.eclipse.pde.ui,
+ org.eclipse.pde.unittest.junit",
org.eclipse.pde.internal.launching.sourcelookup;x-internal:=true,
org.eclipse.pde.launching
Bundle-ActivationPolicy: lazy
diff --git a/ui/org.eclipse.pde.unittest.junit/.classpath b/ui/org.eclipse.pde.unittest.junit/.classpath
new file mode 100644
index 0000000..685a699
--- /dev/null
+++ b/ui/org.eclipse.pde.unittest.junit/.classpath
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-11">
+ <attributes>
+ <attribute name="module" value="true"/>
+ </attributes>
+ </classpathentry>
+ <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+ <classpathentry kind="src" path="src"/>
+ <classpathentry kind="output" path="target/classes"/>
+</classpath>
diff --git a/ui/org.eclipse.pde.unittest.junit/.project b/ui/org.eclipse.pde.unittest.junit/.project
new file mode 100644
index 0000000..5756547
--- /dev/null
+++ b/ui/org.eclipse.pde.unittest.junit/.project
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>org.eclipse.pde.unittest.junit</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>
+ <buildCommand>
+ <name>org.eclipse.pde.api.tools.apiAnalysisBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.m2e.core.maven2Builder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.m2e.core.maven2Nature</nature>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ <nature>org.eclipse.pde.PluginNature</nature>
+ <nature>org.eclipse.pde.api.tools.apiAnalysisNature</nature>
+ </natures>
+</projectDescription>
diff --git a/ui/org.eclipse.pde.unittest.junit/.settings/org.eclipse.core.resources.prefs b/ui/org.eclipse.pde.unittest.junit/.settings/org.eclipse.core.resources.prefs
new file mode 100644
index 0000000..99f26c0
--- /dev/null
+++ b/ui/org.eclipse.pde.unittest.junit/.settings/org.eclipse.core.resources.prefs
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+encoding/<project>=UTF-8
diff --git a/ui/org.eclipse.pde.unittest.junit/.settings/org.eclipse.core.runtime.prefs b/ui/org.eclipse.pde.unittest.junit/.settings/org.eclipse.core.runtime.prefs
new file mode 100644
index 0000000..5a0ad22
--- /dev/null
+++ b/ui/org.eclipse.pde.unittest.junit/.settings/org.eclipse.core.runtime.prefs
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+line.separator=\n
diff --git a/ui/org.eclipse.pde.unittest.junit/.settings/org.eclipse.jdt.core.prefs b/ui/org.eclipse.pde.unittest.junit/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..6bdfa2d
--- /dev/null
+++ b/ui/org.eclipse.pde.unittest.junit/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,538 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.builder.cleanOutputFolder=clean
+org.eclipse.jdt.core.builder.duplicateResourceTask=warning
+org.eclipse.jdt.core.builder.invalidClasspath=abort
+org.eclipse.jdt.core.builder.recreateModifiedClassFileInOutputFolder=ignore
+org.eclipse.jdt.core.builder.resourceCopyExclusionFilter=*.launch
+org.eclipse.jdt.core.circularClasspath=error
+org.eclipse.jdt.core.classpath.exclusionPatterns=enabled
+org.eclipse.jdt.core.classpath.multipleOutputLocations=enabled
+org.eclipse.jdt.core.classpath.outputOverlappingAnotherSource=error
+org.eclipse.jdt.core.codeComplete.argumentPrefixes=
+org.eclipse.jdt.core.codeComplete.argumentSuffixes=
+org.eclipse.jdt.core.codeComplete.fieldPrefixes=f
+org.eclipse.jdt.core.codeComplete.fieldSuffixes=
+org.eclipse.jdt.core.codeComplete.localPrefixes=
+org.eclipse.jdt.core.codeComplete.localSuffixes=
+org.eclipse.jdt.core.codeComplete.staticFieldPrefixes=fg
+org.eclipse.jdt.core.codeComplete.staticFieldSuffixes=
+org.eclipse.jdt.core.codeComplete.staticFinalFieldPrefixes=
+org.eclipse.jdt.core.codeComplete.staticFinalFieldSuffixes=
+org.eclipse.jdt.core.compiler.annotation.inheritNullAnnotations=disabled
+org.eclipse.jdt.core.compiler.annotation.missingNonNullByDefaultAnnotation=ignore
+org.eclipse.jdt.core.compiler.annotation.nonnull=org.eclipse.jdt.annotation.NonNull
+org.eclipse.jdt.core.compiler.annotation.nonnull.secondary=
+org.eclipse.jdt.core.compiler.annotation.nonnullbydefault=org.eclipse.jdt.annotation.NonNullByDefault
+org.eclipse.jdt.core.compiler.annotation.nonnullbydefault.secondary=
+org.eclipse.jdt.core.compiler.annotation.nullable=org.eclipse.jdt.annotation.Nullable
+org.eclipse.jdt.core.compiler.annotation.nullable.secondary=
+org.eclipse.jdt.core.compiler.annotation.nullanalysis=disabled
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=11
+org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
+org.eclipse.jdt.core.compiler.compliance=11
+org.eclipse.jdt.core.compiler.debug.lineNumber=generate
+org.eclipse.jdt.core.compiler.debug.localVariable=generate
+org.eclipse.jdt.core.compiler.debug.sourceFile=generate
+org.eclipse.jdt.core.compiler.doc.comment.support=enabled
+org.eclipse.jdt.core.compiler.maxProblemPerUnit=100
+org.eclipse.jdt.core.compiler.problem.APILeak=warning
+org.eclipse.jdt.core.compiler.problem.annotatedTypeArgumentToUnannotated=info
+org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.autoboxing=info
+org.eclipse.jdt.core.compiler.problem.comparingIdentical=warning
+org.eclipse.jdt.core.compiler.problem.deadCode=error
+org.eclipse.jdt.core.compiler.problem.deprecation=warning
+org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled
+org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=enabled
+org.eclipse.jdt.core.compiler.problem.discouragedReference=warning
+org.eclipse.jdt.core.compiler.problem.emptyStatement=warning
+org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.problem.explicitlyClosedAutoCloseable=warning
+org.eclipse.jdt.core.compiler.problem.fallthroughCase=warning
+org.eclipse.jdt.core.compiler.problem.fatalOptionalError=disabled
+org.eclipse.jdt.core.compiler.problem.fieldHiding=warning
+org.eclipse.jdt.core.compiler.problem.finalParameterBound=error
+org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning
+org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
+org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=error
+org.eclipse.jdt.core.compiler.problem.includeNullInfoFromAsserts=disabled
+org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=error
+org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=error
+org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=warning
+org.eclipse.jdt.core.compiler.problem.invalidJavadoc=warning
+org.eclipse.jdt.core.compiler.problem.invalidJavadocTags=enabled
+org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsDeprecatedRef=disabled
+org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsNotVisibleRef=enabled
+org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsVisibility=private
+org.eclipse.jdt.core.compiler.problem.localVariableHiding=warning
+org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=error
+org.eclipse.jdt.core.compiler.problem.missingDefaultCase=info
+org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=warning
+org.eclipse.jdt.core.compiler.problem.missingEnumCaseDespiteDefault=enabled
+org.eclipse.jdt.core.compiler.problem.missingHashCodeMethod=error
+org.eclipse.jdt.core.compiler.problem.missingJavadocComments=ignore
+org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsOverriding=enabled
+org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsVisibility=public
+org.eclipse.jdt.core.compiler.problem.missingJavadocTagDescription=all_standard_tags
+org.eclipse.jdt.core.compiler.problem.missingJavadocTags=warning
+org.eclipse.jdt.core.compiler.problem.missingJavadocTagsMethodTypeParameters=disabled
+org.eclipse.jdt.core.compiler.problem.missingJavadocTagsOverriding=disabled
+org.eclipse.jdt.core.compiler.problem.missingJavadocTagsVisibility=private
+org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=warning
+org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotationForInterfaceMethodImplementation=enabled
+org.eclipse.jdt.core.compiler.problem.missingSerialVersion=warning
+org.eclipse.jdt.core.compiler.problem.missingSynchronizedOnInheritedMethod=error
+org.eclipse.jdt.core.compiler.problem.noEffectAssignment=error
+org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=error
+org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=warning
+org.eclipse.jdt.core.compiler.problem.nonnullParameterAnnotationDropped=warning
+org.eclipse.jdt.core.compiler.problem.nonnullTypeVariableFromLegacyInvocation=warning
+org.eclipse.jdt.core.compiler.problem.nullAnnotationInferenceConflict=error
+org.eclipse.jdt.core.compiler.problem.nullReference=error
+org.eclipse.jdt.core.compiler.problem.nullSpecViolation=error
+org.eclipse.jdt.core.compiler.problem.nullUncheckedConversion=warning
+org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=error
+org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore
+org.eclipse.jdt.core.compiler.problem.pessimisticNullAnalysisForFreeTypeVariables=warning
+org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=error
+org.eclipse.jdt.core.compiler.problem.potentialNullReference=info
+org.eclipse.jdt.core.compiler.problem.potentiallyUnclosedCloseable=info
+org.eclipse.jdt.core.compiler.problem.rawTypeReference=warning
+org.eclipse.jdt.core.compiler.problem.redundantNullAnnotation=warning
+org.eclipse.jdt.core.compiler.problem.redundantNullCheck=warning
+org.eclipse.jdt.core.compiler.problem.redundantSpecificationOfTypeArguments=warning
+org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=info
+org.eclipse.jdt.core.compiler.problem.reportMethodCanBePotentiallyStatic=ignore
+org.eclipse.jdt.core.compiler.problem.reportMethodCanBeStatic=ignore
+org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning
+org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled
+org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=error
+org.eclipse.jdt.core.compiler.problem.suppressOptionalErrors=disabled
+org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled
+org.eclipse.jdt.core.compiler.problem.suppressWarningsNotFullyAnalysed=info
+org.eclipse.jdt.core.compiler.problem.syntacticNullAnalysisForFields=disabled
+org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore
+org.eclipse.jdt.core.compiler.problem.terminalDeprecation=warning
+org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning
+org.eclipse.jdt.core.compiler.problem.unavoidableGenericTypeProblems=disabled
+org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning
+org.eclipse.jdt.core.compiler.problem.unclosedCloseable=warning
+org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=info
+org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning
+org.eclipse.jdt.core.compiler.problem.unlikelyCollectionMethodArgumentType=warning
+org.eclipse.jdt.core.compiler.problem.unlikelyCollectionMethodArgumentTypeStrict=disabled
+org.eclipse.jdt.core.compiler.problem.unlikelyEqualsArgumentType=info
+org.eclipse.jdt.core.compiler.problem.unnecessaryElse=ignore
+org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=error
+org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore
+org.eclipse.jdt.core.compiler.problem.unstableAutoModuleName=warning
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=warning
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionExemptExceptionAndThrowable=enabled
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionIncludeDocCommentReference=enabled
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled
+org.eclipse.jdt.core.compiler.problem.unusedExceptionParameter=ignore
+org.eclipse.jdt.core.compiler.problem.unusedImport=error
+org.eclipse.jdt.core.compiler.problem.unusedLabel=warning
+org.eclipse.jdt.core.compiler.problem.unusedLocal=warning
+org.eclipse.jdt.core.compiler.problem.unusedObjectAllocation=info
+org.eclipse.jdt.core.compiler.problem.unusedParameter=warning
+org.eclipse.jdt.core.compiler.problem.unusedParameterIncludeDocCommentReference=enabled
+org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled
+org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled
+org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning
+org.eclipse.jdt.core.compiler.problem.unusedTypeParameter=warning
+org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning
+org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning
+org.eclipse.jdt.core.compiler.release=enabled
+org.eclipse.jdt.core.compiler.source=11
+org.eclipse.jdt.core.formatter.align_assignment_statements_on_columns=false
+org.eclipse.jdt.core.formatter.align_fields_grouping_blank_lines=2147483647
+org.eclipse.jdt.core.formatter.align_type_members_on_columns=false
+org.eclipse.jdt.core.formatter.align_variable_declarations_on_columns=false
+org.eclipse.jdt.core.formatter.align_with_spaces=false
+org.eclipse.jdt.core.formatter.alignment_for_additive_operator=16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation=0
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant=16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call=16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation=16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression=16
+org.eclipse.jdt.core.formatter.alignment_for_assertion_message=16
+org.eclipse.jdt.core.formatter.alignment_for_assignment=0
+org.eclipse.jdt.core.formatter.alignment_for_bitwise_operator=16
+org.eclipse.jdt.core.formatter.alignment_for_compact_if=16
+org.eclipse.jdt.core.formatter.alignment_for_compact_loops=16
+org.eclipse.jdt.core.formatter.alignment_for_conditional_expression=80
+org.eclipse.jdt.core.formatter.alignment_for_conditional_expression_chain=0
+org.eclipse.jdt.core.formatter.alignment_for_enum_constants=16
+org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer=16
+org.eclipse.jdt.core.formatter.alignment_for_expressions_in_for_loop_header=0
+org.eclipse.jdt.core.formatter.alignment_for_logical_operator=16
+org.eclipse.jdt.core.formatter.alignment_for_method_declaration=0
+org.eclipse.jdt.core.formatter.alignment_for_module_statements=16
+org.eclipse.jdt.core.formatter.alignment_for_multiple_fields=16
+org.eclipse.jdt.core.formatter.alignment_for_multiplicative_operator=16
+org.eclipse.jdt.core.formatter.alignment_for_parameterized_type_references=0
+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_record_components=16
+org.eclipse.jdt.core.formatter.alignment_for_relational_operator=0
+org.eclipse.jdt.core.formatter.alignment_for_resources_in_try=80
+org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation=16
+org.eclipse.jdt.core.formatter.alignment_for_shift_operator=0
+org.eclipse.jdt.core.formatter.alignment_for_string_concatenation=16
+org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_record_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_type_arguments=0
+org.eclipse.jdt.core.formatter.alignment_for_type_parameters=0
+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_last_class_body_declaration=0
+org.eclipse.jdt.core.formatter.blank_lines_after_package=1
+org.eclipse.jdt.core.formatter.blank_lines_before_abstract_method=1
+org.eclipse.jdt.core.formatter.blank_lines_before_field=0
+org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration=0
+org.eclipse.jdt.core.formatter.blank_lines_before_imports=1
+org.eclipse.jdt.core.formatter.blank_lines_before_member_type=1
+org.eclipse.jdt.core.formatter.blank_lines_before_method=1
+org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk=1
+org.eclipse.jdt.core.formatter.blank_lines_before_package=0
+org.eclipse.jdt.core.formatter.blank_lines_between_import_groups=1
+org.eclipse.jdt.core.formatter.blank_lines_between_statement_group_in_switch=0
+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_record_constructor=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_record_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.align_tags_descriptions_grouped=true
+org.eclipse.jdt.core.formatter.comment.align_tags_names_descriptions=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.count_line_length_from_starting_position=true
+org.eclipse.jdt.core.formatter.comment.format_block_comments=true
+org.eclipse.jdt.core.formatter.comment.format_header=false
+org.eclipse.jdt.core.formatter.comment.format_html=true
+org.eclipse.jdt.core.formatter.comment.format_javadoc_comments=true
+org.eclipse.jdt.core.formatter.comment.format_line_comments=true
+org.eclipse.jdt.core.formatter.comment.format_source_code=true
+org.eclipse.jdt.core.formatter.comment.indent_parameter_description=false
+org.eclipse.jdt.core.formatter.comment.indent_root_tags=false
+org.eclipse.jdt.core.formatter.comment.indent_tag_description=false
+org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags=insert
+org.eclipse.jdt.core.formatter.comment.insert_new_line_between_different_tags=do not insert
+org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter=do not insert
+org.eclipse.jdt.core.formatter.comment.line_length=80
+org.eclipse.jdt.core.formatter.comment.new_lines_at_block_boundaries=true
+org.eclipse.jdt.core.formatter.comment.new_lines_at_javadoc_boundaries=true
+org.eclipse.jdt.core.formatter.comment.preserve_white_space_between_code_and_line_comments=false
+org.eclipse.jdt.core.formatter.compact_else_if=true
+org.eclipse.jdt.core.formatter.continuation_indentation=2
+org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer=2
+org.eclipse.jdt.core.formatter.disabling_tag=@formatter\:off
+org.eclipse.jdt.core.formatter.enabling_tag=@formatter\:on
+org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line=false
+org.eclipse.jdt.core.formatter.format_line_comment_starting_on_first_column=false
+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header=true
+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header=true
+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header=true
+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_record_header=true
+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header=true
+org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases=true
+org.eclipse.jdt.core.formatter.indent_empty_lines=false
+org.eclipse.jdt.core.formatter.indent_statements_compare_to_block=true
+org.eclipse.jdt.core.formatter.indent_statements_compare_to_body=true
+org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases=true
+org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch=false
+org.eclipse.jdt.core.formatter.indentation.size=4
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_enum_constant=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_method=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_package=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_type=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_label=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_type_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_annotation_declaration=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_after_additive_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter=insert
+org.eclipse.jdt.core.formatter.insert_space_after_arrow_in_switch_case=insert
+org.eclipse.jdt.core.formatter.insert_space_after_arrow_in_switch_default=insert
+org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_bitwise_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters=insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block=insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_record_components=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_switch_case_expressions=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters=insert
+org.eclipse.jdt.core.formatter.insert_space_after_ellipsis=insert
+org.eclipse.jdt.core.formatter.insert_space_after_lambda_arrow=insert
+org.eclipse.jdt.core.formatter.insert_space_after_logical_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_after_multiplicative_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_after_not_operator=do not 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_record_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_try=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional=insert
+org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_relational_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for=insert
+org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_try_resources=insert
+org.eclipse.jdt.core.formatter.insert_space_after_shift_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_after_string_concatenation=insert
+org.eclipse.jdt.core.formatter.insert_space_after_unary_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_additive_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter=insert
+org.eclipse.jdt.core.formatter.insert_space_before_arrow_in_switch_case=insert
+org.eclipse.jdt.core.formatter.insert_space_before_arrow_in_switch_default=insert
+org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_bitwise_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer=insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_record_declaration=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_record_components=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_switch_case_expressions=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_ellipsis=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_lambda_arrow=insert
+org.eclipse.jdt.core.formatter.insert_space_before_logical_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_before_multiplicative_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_record_constructor=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_record_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_record_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_try=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while=insert
+org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return=insert
+org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw=insert
+org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional=insert
+org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_relational_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_before_semicolon=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_try_resources=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_shift_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_before_string_concatenation=insert
+org.eclipse.jdt.core.formatter.insert_space_before_unary_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation=do not insert
+org.eclipse.jdt.core.formatter.join_lines_in_comments=true
+org.eclipse.jdt.core.formatter.join_wrapped_lines=true
+org.eclipse.jdt.core.formatter.keep_annotation_declaration_on_one_line=one_line_never
+org.eclipse.jdt.core.formatter.keep_anonymous_type_declaration_on_one_line=one_line_never
+org.eclipse.jdt.core.formatter.keep_code_block_on_one_line=one_line_never
+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_enum_constant_declaration_on_one_line=one_line_never
+org.eclipse.jdt.core.formatter.keep_enum_declaration_on_one_line=one_line_never
+org.eclipse.jdt.core.formatter.keep_if_then_body_block_on_one_line=one_line_never
+org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line=false
+org.eclipse.jdt.core.formatter.keep_lambda_body_block_on_one_line=one_line_never
+org.eclipse.jdt.core.formatter.keep_loop_body_block_on_one_line=one_line_never
+org.eclipse.jdt.core.formatter.keep_method_body_on_one_line=one_line_never
+org.eclipse.jdt.core.formatter.keep_record_constructor_on_one_line=one_line_never
+org.eclipse.jdt.core.formatter.keep_record_declaration_on_one_line=one_line_never
+org.eclipse.jdt.core.formatter.keep_simple_do_while_body_on_same_line=false
+org.eclipse.jdt.core.formatter.keep_simple_for_body_on_same_line=false
+org.eclipse.jdt.core.formatter.keep_simple_getter_setter_on_one_line=false
+org.eclipse.jdt.core.formatter.keep_simple_while_body_on_same_line=false
+org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line=false
+org.eclipse.jdt.core.formatter.keep_type_declaration_on_one_line=one_line_never
+org.eclipse.jdt.core.formatter.lineSplit=120
+org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column=false
+org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column=false
+org.eclipse.jdt.core.formatter.number_of_blank_lines_after_code_block=0
+org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_code_block=0
+org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body=0
+org.eclipse.jdt.core.formatter.number_of_blank_lines_at_end_of_code_block=0
+org.eclipse.jdt.core.formatter.number_of_blank_lines_at_end_of_method_body=0
+org.eclipse.jdt.core.formatter.number_of_blank_lines_before_code_block=0
+org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve=1
+org.eclipse.jdt.core.formatter.parentheses_positions_in_annotation=common_lines
+org.eclipse.jdt.core.formatter.parentheses_positions_in_catch_clause=common_lines
+org.eclipse.jdt.core.formatter.parentheses_positions_in_enum_constant_declaration=common_lines
+org.eclipse.jdt.core.formatter.parentheses_positions_in_for_statment=common_lines
+org.eclipse.jdt.core.formatter.parentheses_positions_in_if_while_statement=common_lines
+org.eclipse.jdt.core.formatter.parentheses_positions_in_lambda_declaration=common_lines
+org.eclipse.jdt.core.formatter.parentheses_positions_in_method_delcaration=common_lines
+org.eclipse.jdt.core.formatter.parentheses_positions_in_method_invocation=common_lines
+org.eclipse.jdt.core.formatter.parentheses_positions_in_record_declaration=common_lines
+org.eclipse.jdt.core.formatter.parentheses_positions_in_switch_statement=common_lines
+org.eclipse.jdt.core.formatter.parentheses_positions_in_try_clause=common_lines
+org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line=true
+org.eclipse.jdt.core.formatter.tabulation.char=tab
+org.eclipse.jdt.core.formatter.tabulation.size=4
+org.eclipse.jdt.core.formatter.text_block_indentation=0
+org.eclipse.jdt.core.formatter.use_on_off_tags=false
+org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations=false
+org.eclipse.jdt.core.formatter.wrap_before_additive_operator=true
+org.eclipse.jdt.core.formatter.wrap_before_assertion_message_operator=true
+org.eclipse.jdt.core.formatter.wrap_before_assignment_operator=false
+org.eclipse.jdt.core.formatter.wrap_before_bitwise_operator=true
+org.eclipse.jdt.core.formatter.wrap_before_conditional_operator=true
+org.eclipse.jdt.core.formatter.wrap_before_logical_operator=true
+org.eclipse.jdt.core.formatter.wrap_before_multiplicative_operator=true
+org.eclipse.jdt.core.formatter.wrap_before_or_operator_multicatch=true
+org.eclipse.jdt.core.formatter.wrap_before_relational_operator=true
+org.eclipse.jdt.core.formatter.wrap_before_shift_operator=true
+org.eclipse.jdt.core.formatter.wrap_before_string_concatenation=true
+org.eclipse.jdt.core.formatter.wrap_outer_expressions_when_nested=true
+org.eclipse.jdt.core.incompatibleJDKLevel=ignore
+org.eclipse.jdt.core.incompleteClasspath=error
+org.eclipse.jdt.core.javaFormatter=org.eclipse.jdt.core.defaultJavaFormatter
diff --git a/ui/org.eclipse.pde.unittest.junit/.settings/org.eclipse.jdt.ui.prefs b/ui/org.eclipse.pde.unittest.junit/.settings/org.eclipse.jdt.ui.prefs
new file mode 100644
index 0000000..724c757
--- /dev/null
+++ b/ui/org.eclipse.pde.unittest.junit/.settings/org.eclipse.jdt.ui.prefs
@@ -0,0 +1,86 @@
+cleanup_settings_version=2
+eclipse.preferences.version=1
+editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true
+formatter_profile=org.eclipse.jdt.ui.default.eclipse_profile
+formatter_settings_version=20
+org.eclipse.jdt.ui.exception.name=e
+org.eclipse.jdt.ui.gettersetter.use.is=true
+org.eclipse.jdt.ui.ignorelowercasenames=true
+org.eclipse.jdt.ui.importorder=java;javax;sun;com;org;org.apache;org.w3c;org.eclipse;org.eclipse.swt;org.eclipse.core;org.eclipse.core.runtime;org.eclipse.core.resources;org.eclipse.core.filebuffers;org.eclipse.text;org.eclipse.jface;org.eclipse.jface.text;org.eclipse.ui;org.eclipse.ui.workbench.texteditor;org.eclipse.ui.texteditor;org.eclipse.ui.editors;org.eclipse.compare;org.eclipse.debug;org.eclipse.debug.ui;org.eclipse.search;org.eclipse.search2;org.eclipse.ltk;org.eclipse.jdt.core;org.eclipse.jdt.internal;org.eclipse.jdt.launching;org.eclipse.jdt.ui;org.eclipse.jdt.internal.ui;
+org.eclipse.jdt.ui.keywordthis=false
+org.eclipse.jdt.ui.ondemandthreshold=99
+org.eclipse.jdt.ui.overrideannotation=true
+org.eclipse.jdt.ui.staticondemandthreshold=99
+org.eclipse.jdt.ui.text.custom_code_templates=
+sp_cleanup.add_default_serial_version_id=true
+sp_cleanup.add_generated_serial_version_id=false
+sp_cleanup.add_missing_annotations=true
+sp_cleanup.add_missing_deprecated_annotations=true
+sp_cleanup.add_missing_methods=false
+sp_cleanup.add_missing_nls_tags=false
+sp_cleanup.add_missing_override_annotations=true
+sp_cleanup.add_missing_override_annotations_interface_methods=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_functional_interfaces=true
+sp_cleanup.convert_to_enhanced_for_loop=true
+sp_cleanup.convert_to_enhanced_for_loop_if_loop_var_used=false
+sp_cleanup.correct_indentation=false
+sp_cleanup.format_source_code=true
+sp_cleanup.format_source_code_changes_only=false
+sp_cleanup.insert_inferred_type_arguments=false
+sp_cleanup.lazy_logical_operator=false
+sp_cleanup.make_local_variable_final=true
+sp_cleanup.make_parameters_final=false
+sp_cleanup.make_private_fields_final=true
+sp_cleanup.make_type_abstract_if_missing_method=false
+sp_cleanup.make_variable_declarations_final=false
+sp_cleanup.merge_conditional_blocks=false
+sp_cleanup.never_use_blocks=false
+sp_cleanup.never_use_parentheses_in_expressions=true
+sp_cleanup.number_suffix=false
+sp_cleanup.objects_equals=false
+sp_cleanup.on_save_use_additional_actions=true
+sp_cleanup.organize_imports=true
+sp_cleanup.precompile_regex=true
+sp_cleanup.push_down_negation=false
+sp_cleanup.qualify_static_field_accesses_with_declaring_class=false
+sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true
+sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true
+sp_cleanup.qualify_static_member_accesses_with_declaring_class=false
+sp_cleanup.qualify_static_method_accesses_with_declaring_class=false
+sp_cleanup.remove_private_constructors=true
+sp_cleanup.remove_redundant_modifiers=true
+sp_cleanup.remove_redundant_semicolons=true
+sp_cleanup.remove_redundant_type_arguments=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_array_creation=true
+sp_cleanup.remove_unnecessary_casts=true
+sp_cleanup.remove_unnecessary_nls_tags=false
+sp_cleanup.remove_unused_imports=false
+sp_cleanup.remove_unused_local_variables=false
+sp_cleanup.remove_unused_private_fields=true
+sp_cleanup.remove_unused_private_members=false
+sp_cleanup.remove_unused_private_methods=true
+sp_cleanup.remove_unused_private_types=true
+sp_cleanup.simplify_lambda_expression_and_method_ref=true
+sp_cleanup.sort_members=false
+sp_cleanup.sort_members_all=false
+sp_cleanup.use_anonymous_class_creation=false
+sp_cleanup.use_autoboxing=false
+sp_cleanup.use_blocks=false
+sp_cleanup.use_blocks_only_for_return_and_throw=false
+sp_cleanup.use_directly_map_method=true
+sp_cleanup.use_lambda=true
+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
+sp_cleanup.use_unboxing=false
+sp_cleanup.use_var=false
diff --git a/ui/org.eclipse.pde.unittest.junit/.settings/org.eclipse.m2e.core.prefs b/ui/org.eclipse.pde.unittest.junit/.settings/org.eclipse.m2e.core.prefs
new file mode 100644
index 0000000..f897a7f
--- /dev/null
+++ b/ui/org.eclipse.pde.unittest.junit/.settings/org.eclipse.m2e.core.prefs
@@ -0,0 +1,4 @@
+activeProfiles=
+eclipse.preferences.version=1
+resolveWorkspaceProjects=true
+version=1
diff --git a/ui/org.eclipse.pde.unittest.junit/.settings/org.eclipse.pde.api.tools.prefs b/ui/org.eclipse.pde.unittest.junit/.settings/org.eclipse.pde.api.tools.prefs
new file mode 100644
index 0000000..9d6e2dc
--- /dev/null
+++ b/ui/org.eclipse.pde.unittest.junit/.settings/org.eclipse.pde.api.tools.prefs
@@ -0,0 +1,102 @@
+ANNOTATION_ELEMENT_TYPE_ADDED_FIELD=Error
+ANNOTATION_ELEMENT_TYPE_ADDED_METHOD_WITHOUT_DEFAULT_VALUE=Error
+ANNOTATION_ELEMENT_TYPE_CHANGED_TYPE_CONVERSION=Error
+ANNOTATION_ELEMENT_TYPE_REMOVED_FIELD=Error
+ANNOTATION_ELEMENT_TYPE_REMOVED_METHOD=Error
+ANNOTATION_ELEMENT_TYPE_REMOVED_TYPE_MEMBER=Error
+API_COMPONENT_ELEMENT_TYPE_REMOVED_API_TYPE=Error
+API_COMPONENT_ELEMENT_TYPE_REMOVED_REEXPORTED_API_TYPE=Error
+API_COMPONENT_ELEMENT_TYPE_REMOVED_REEXPORTED_TYPE=Error
+API_COMPONENT_ELEMENT_TYPE_REMOVED_TYPE=Error
+API_USE_SCAN_FIELD_SEVERITY=Error
+API_USE_SCAN_METHOD_SEVERITY=Error
+API_USE_SCAN_TYPE_SEVERITY=Error
+CLASS_ELEMENT_TYPE_ADDED_FIELD=Error
+CLASS_ELEMENT_TYPE_ADDED_METHOD=Error
+CLASS_ELEMENT_TYPE_ADDED_RESTRICTIONS=Error
+CLASS_ELEMENT_TYPE_ADDED_TYPE_PARAMETER=Error
+CLASS_ELEMENT_TYPE_CHANGED_CONTRACTED_SUPERINTERFACES_SET=Error
+CLASS_ELEMENT_TYPE_CHANGED_DECREASE_ACCESS=Error
+CLASS_ELEMENT_TYPE_CHANGED_NON_ABSTRACT_TO_ABSTRACT=Error
+CLASS_ELEMENT_TYPE_CHANGED_NON_FINAL_TO_FINAL=Error
+CLASS_ELEMENT_TYPE_CHANGED_TYPE_CONVERSION=Error
+CLASS_ELEMENT_TYPE_REMOVED_CONSTRUCTOR=Error
+CLASS_ELEMENT_TYPE_REMOVED_FIELD=Error
+CLASS_ELEMENT_TYPE_REMOVED_METHOD=Error
+CLASS_ELEMENT_TYPE_REMOVED_SUPERCLASS=Error
+CLASS_ELEMENT_TYPE_REMOVED_TYPE_MEMBER=Error
+CLASS_ELEMENT_TYPE_REMOVED_TYPE_PARAMETER=Error
+CONSTRUCTOR_ELEMENT_TYPE_ADDED_TYPE_PARAMETER=Error
+CONSTRUCTOR_ELEMENT_TYPE_CHANGED_DECREASE_ACCESS=Error
+CONSTRUCTOR_ELEMENT_TYPE_CHANGED_VARARGS_TO_ARRAY=Error
+CONSTRUCTOR_ELEMENT_TYPE_REMOVED_TYPE_PARAMETER=Error
+ENUM_ELEMENT_TYPE_CHANGED_CONTRACTED_SUPERINTERFACES_SET=Error
+ENUM_ELEMENT_TYPE_CHANGED_TYPE_CONVERSION=Error
+ENUM_ELEMENT_TYPE_REMOVED_ENUM_CONSTANT=Error
+ENUM_ELEMENT_TYPE_REMOVED_FIELD=Error
+ENUM_ELEMENT_TYPE_REMOVED_METHOD=Error
+ENUM_ELEMENT_TYPE_REMOVED_TYPE_MEMBER=Error
+FIELD_ELEMENT_TYPE_ADDED_VALUE=Error
+FIELD_ELEMENT_TYPE_CHANGED_DECREASE_ACCESS=Error
+FIELD_ELEMENT_TYPE_CHANGED_FINAL_TO_NON_FINAL_STATIC_CONSTANT=Error
+FIELD_ELEMENT_TYPE_CHANGED_NON_FINAL_TO_FINAL=Error
+FIELD_ELEMENT_TYPE_CHANGED_NON_STATIC_TO_STATIC=Error
+FIELD_ELEMENT_TYPE_CHANGED_STATIC_TO_NON_STATIC=Error
+FIELD_ELEMENT_TYPE_CHANGED_TYPE=Error
+FIELD_ELEMENT_TYPE_CHANGED_VALUE=Error
+FIELD_ELEMENT_TYPE_REMOVED_TYPE_ARGUMENT=Error
+FIELD_ELEMENT_TYPE_REMOVED_VALUE=Error
+ILLEGAL_EXTEND=Warning
+ILLEGAL_IMPLEMENT=Warning
+ILLEGAL_INSTANTIATE=Warning
+ILLEGAL_OVERRIDE=Warning
+ILLEGAL_REFERENCE=Warning
+INTERFACE_ELEMENT_TYPE_ADDED_DEFAULT_METHOD=Error
+INTERFACE_ELEMENT_TYPE_ADDED_FIELD=Error
+INTERFACE_ELEMENT_TYPE_ADDED_METHOD=Error
+INTERFACE_ELEMENT_TYPE_ADDED_RESTRICTIONS=Error
+INTERFACE_ELEMENT_TYPE_ADDED_SUPER_INTERFACE_WITH_METHODS=Error
+INTERFACE_ELEMENT_TYPE_ADDED_TYPE_PARAMETER=Error
+INTERFACE_ELEMENT_TYPE_CHANGED_CONTRACTED_SUPERINTERFACES_SET=Error
+INTERFACE_ELEMENT_TYPE_CHANGED_TYPE_CONVERSION=Error
+INTERFACE_ELEMENT_TYPE_REMOVED_FIELD=Error
+INTERFACE_ELEMENT_TYPE_REMOVED_METHOD=Error
+INTERFACE_ELEMENT_TYPE_REMOVED_TYPE_MEMBER=Error
+INTERFACE_ELEMENT_TYPE_REMOVED_TYPE_PARAMETER=Error
+INVALID_ANNOTATION=Ignore
+INVALID_JAVADOC_TAG=Ignore
+INVALID_REFERENCE_IN_SYSTEM_LIBRARIES=Ignore
+LEAK_EXTEND=Warning
+LEAK_FIELD_DECL=Warning
+LEAK_IMPLEMENT=Warning
+LEAK_METHOD_PARAM=Warning
+LEAK_METHOD_RETURN_TYPE=Warning
+METHOD_ELEMENT_TYPE_ADDED_RESTRICTIONS=Error
+METHOD_ELEMENT_TYPE_ADDED_TYPE_PARAMETER=Error
+METHOD_ELEMENT_TYPE_CHANGED_DECREASE_ACCESS=Error
+METHOD_ELEMENT_TYPE_CHANGED_NON_ABSTRACT_TO_ABSTRACT=Error
+METHOD_ELEMENT_TYPE_CHANGED_NON_FINAL_TO_FINAL=Error
+METHOD_ELEMENT_TYPE_CHANGED_NON_STATIC_TO_STATIC=Error
+METHOD_ELEMENT_TYPE_CHANGED_STATIC_TO_NON_STATIC=Error
+METHOD_ELEMENT_TYPE_CHANGED_VARARGS_TO_ARRAY=Error
+METHOD_ELEMENT_TYPE_REMOVED_ANNOTATION_DEFAULT_VALUE=Error
+METHOD_ELEMENT_TYPE_REMOVED_TYPE_PARAMETER=Error
+MISSING_EE_DESCRIPTIONS=Warning
+TYPE_PARAMETER_ELEMENT_TYPE_ADDED_CLASS_BOUND=Error
+TYPE_PARAMETER_ELEMENT_TYPE_ADDED_INTERFACE_BOUND=Error
+TYPE_PARAMETER_ELEMENT_TYPE_CHANGED_CLASS_BOUND=Error
+TYPE_PARAMETER_ELEMENT_TYPE_CHANGED_INTERFACE_BOUND=Error
+TYPE_PARAMETER_ELEMENT_TYPE_REMOVED_CLASS_BOUND=Error
+TYPE_PARAMETER_ELEMENT_TYPE_REMOVED_INTERFACE_BOUND=Error
+UNUSED_PROBLEM_FILTERS=Warning
+automatically_removed_unused_problem_filters=false
+changed_execution_env=Error
+eclipse.preferences.version=1
+incompatible_api_component_version=Error
+incompatible_api_component_version_report_major_without_breaking_change=Error
+incompatible_api_component_version_report_minor_without_api_change=Error
+invalid_since_tag_version=Error
+malformed_since_tag=Error
+missing_since_tag=Error
+report_api_breakage_when_major_version_incremented=Disabled
+report_resolution_errors_api_component=Warning
diff --git a/ui/org.eclipse.pde.unittest.junit/.settings/org.eclipse.pde.prefs b/ui/org.eclipse.pde.unittest.junit/.settings/org.eclipse.pde.prefs
new file mode 100644
index 0000000..0eb6933
--- /dev/null
+++ b/ui/org.eclipse.pde.unittest.junit/.settings/org.eclipse.pde.prefs
@@ -0,0 +1,36 @@
+compilers.f.unresolved-features=1
+compilers.f.unresolved-plugins=1
+compilers.incompatible-environment=0
+compilers.p.build=1
+compilers.p.build.bin.includes=1
+compilers.p.build.encodings=2
+compilers.p.build.java.compiler=2
+compilers.p.build.java.compliance=1
+compilers.p.build.missing.output=2
+compilers.p.build.output.library=1
+compilers.p.build.source.library=1
+compilers.p.build.src.includes=1
+compilers.p.deprecated=1
+compilers.p.discouraged-class=1
+compilers.p.exec-env-too-low=1
+compilers.p.internal=1
+compilers.p.missing-packages=2
+compilers.p.missing-version-export-package=2
+compilers.p.missing-version-import-package=2
+compilers.p.missing-version-require-bundle=2
+compilers.p.no-required-att=0
+compilers.p.no.automatic.module=1
+compilers.p.not-externalized-att=1
+compilers.p.service.component.without.lazyactivation=1
+compilers.p.unknown-attribute=0
+compilers.p.unknown-class=0
+compilers.p.unknown-element=0
+compilers.p.unknown-identifier=0
+compilers.p.unknown-resource=0
+compilers.p.unresolved-ex-points=0
+compilers.p.unresolved-import=0
+compilers.s.create-docs=false
+compilers.s.doc-folder=doc
+compilers.s.open-tags=1
+compilers.use-project=true
+eclipse.preferences.version=1
diff --git a/ui/org.eclipse.pde.unittest.junit/META-INF/MANIFEST.MF b/ui/org.eclipse.pde.unittest.junit/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..d52f6ce
--- /dev/null
+++ b/ui/org.eclipse.pde.unittest.junit/META-INF/MANIFEST.MF
@@ -0,0 +1,23 @@
+Manifest-Version: 1.0
+Automatic-Module-Name: org.eclipse.pde.unittest.junit
+Bundle-ManifestVersion: 2
+Bundle-Name: %pluginName
+Bundle-SymbolicName: org.eclipse.pde.unittest.junit;singleton:=true
+Bundle-Version: 1.0.0.qualifier
+Bundle-Activator: org.eclipse.pde.unittest.junit.JUnitPluginTestPlugin
+Bundle-ActivationPolicy: lazy
+Bundle-Vendor: %providerName
+Bundle-Localization: plugin
+Require-Bundle:
+ org.eclipse.unittest.ui,
+ org.eclipse.pde.ui,
+ org.eclipse.jdt.ui.unittest.junit,
+ org.eclipse.ui;bundle-version="[3.5.0,4.0.0)",
+ org.eclipse.debug.ui;bundle-version="[3.5.0,4.0.0)",
+ org.eclipse.jdt.core;bundle-version="[3.18.0,4.0.0)",
+ org.eclipse.core.runtime;bundle-version="[3.11.0,4.0.0)",
+ org.eclipse.jdt.launching;bundle-version="[3.5.0,4.0.0)",
+ org.eclipse.jdt.debug.ui;bundle-version="[3.3.0,4.0.0)",
+ org.eclipse.core.variables;bundle-version="[3.2.200,4.0.0)",
+ org.eclipse.jdt.junit;bundle-version="3.11.0"
+Bundle-RequiredExecutionEnvironment: JavaSE-11
diff --git a/ui/org.eclipse.pde.unittest.junit/about.html b/ui/org.eclipse.pde.unittest.junit/about.html
new file mode 100644
index 0000000..164f781
--- /dev/null
+++ b/ui/org.eclipse.pde.unittest.junit/about.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
+<title>About</title>
+</head>
+<body lang="EN-US">
+ <h2>About This Content</h2>
+
+ <p>November 30, 2017</p>
+ <h3>License</h3>
+
+ <p>
+ The Eclipse Foundation makes available all content in this plug-in
+ ("Content"). Unless otherwise indicated below, the Content
+ is provided to you under the terms and conditions of the Eclipse
+ Public License Version 2.0 ("EPL"). A copy of the EPL is
+ available at <a href="http://www.eclipse.org/legal/epl-2.0">http://www.eclipse.org/legal/epl-2.0</a>.
+ For purposes of the EPL, "Program" will mean the Content.
+ </p>
+
+ <p>
+ If you did not receive this Content directly from the Eclipse
+ Foundation, the Content is being redistributed by another party
+ ("Redistributor") and different terms and conditions may
+ apply to your use of any object code in the Content. Check the
+ Redistributor's license that was provided with the Content. If no such
+ license exists, contact the Redistributor. Unless otherwise indicated
+ below, the terms and conditions of the EPL still apply to any source
+ code in the Content and such source code may be obtained at <a
+ href="http://www.eclipse.org/">http://www.eclipse.org</a>.
+ </p>
+
+</body>
+</html>
\ No newline at end of file
diff --git a/ui/org.eclipse.pde.unittest.junit/build.properties b/ui/org.eclipse.pde.unittest.junit/build.properties
new file mode 100644
index 0000000..5105873
--- /dev/null
+++ b/ui/org.eclipse.pde.unittest.junit/build.properties
@@ -0,0 +1,25 @@
+###############################################################################
+# Copyright (c) 2000, 2021 IBM Corporation and others.
+#
+# This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License 2.0
+# which accompanies this distribution, and is available at
+# https://www.eclipse.org/legal/epl-2.0/
+#
+# SPDX-License-Identifier: EPL-2.0
+#
+# Contributors:
+# IBM Corporation - initial API and implementation
+###############################################################################
+bin.includes = plugin.xml,\
+ about.html,\
+ icons/,\
+ plugin.properties,\
+ .,\
+ META-INF/
+
+source.. = src/
+
+src.includes = about.html
+
+javacWarnings..=-unavoidableGenericProblems
diff --git a/ui/org.eclipse.pde.unittest.junit/icons/full/obj16/julaunchpgn.png b/ui/org.eclipse.pde.unittest.junit/icons/full/obj16/julaunchpgn.png
new file mode 100644
index 0000000..502b922
--- /dev/null
+++ b/ui/org.eclipse.pde.unittest.junit/icons/full/obj16/julaunchpgn.png
Binary files differ
diff --git a/ui/org.eclipse.pde.unittest.junit/icons/full/obj16/julaunchpgn@2x.png b/ui/org.eclipse.pde.unittest.junit/icons/full/obj16/julaunchpgn@2x.png
new file mode 100644
index 0000000..854e56b
--- /dev/null
+++ b/ui/org.eclipse.pde.unittest.junit/icons/full/obj16/julaunchpgn@2x.png
Binary files differ
diff --git a/ui/org.eclipse.pde.unittest.junit/icons/full/obj16/test.png b/ui/org.eclipse.pde.unittest.junit/icons/full/obj16/test.png
new file mode 100644
index 0000000..c95f6b5
--- /dev/null
+++ b/ui/org.eclipse.pde.unittest.junit/icons/full/obj16/test.png
Binary files differ
diff --git a/ui/org.eclipse.pde.unittest.junit/icons/full/obj16/test@2x.png b/ui/org.eclipse.pde.unittest.junit/icons/full/obj16/test@2x.png
new file mode 100644
index 0000000..c404f65
--- /dev/null
+++ b/ui/org.eclipse.pde.unittest.junit/icons/full/obj16/test@2x.png
Binary files differ
diff --git a/ui/org.eclipse.pde.unittest.junit/plugin.properties b/ui/org.eclipse.pde.unittest.junit/plugin.properties
new file mode 100644
index 0000000..2669ae7
--- /dev/null
+++ b/ui/org.eclipse.pde.unittest.junit/plugin.properties
@@ -0,0 +1,29 @@
+#################################################################################
+# Copyright (c) 2021 Red Hat, Inc.
+#
+# This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License 2.0
+# which accompanies this distribution, and is available at
+# https://www.eclipse.org/legal/epl-2.0/
+#
+# SPDX-License-Identifier: EPL-2.0
+#
+# Contributors:
+# Red Hat Inc. - initial API and implementation
+#################################################################################
+pluginName=Plug-in Development Unit Test support
+providerName=Eclipse.org
+
+JUnitPluginLaunchDelegate.name=Eclipse JUnit Plug-in Unit Test Launcher
+JUnitPluginLaunchDelegate.description=The Eclipse JUnit Plug-in Unit Test Launcher supports running and debugging Unit test suites for plug-in projects
+
+RunJUnitPluginLaunchShortcut.description=Runs a set of Unit tests
+DebugJUnitPluginLaunchShortcut.description=Debugs a set of Unit tests
+
+Launch.label= JUnit Plug-in Test (generic Test view)
+
+JUnitPluginTestShortcut.label= JUnit Plug-in Test (generic Test view)
+
+JUnitPluginTabGroup.description.debug= Create a configuration that will launch a Unit test in debug mode.
+JUnitPluginTabGroup.description.run= Create a configuration that will launch a Unit test.
+
diff --git a/ui/org.eclipse.pde.unittest.junit/plugin.xml b/ui/org.eclipse.pde.unittest.junit/plugin.xml
new file mode 100644
index 0000000..7c40da0
--- /dev/null
+++ b/ui/org.eclipse.pde.unittest.junit/plugin.xml
@@ -0,0 +1,93 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.0"?>
+<plugin>
+
+ <extension
+ point="org.eclipse.debug.ui.launchConfigurationTypeImages">
+ <launchConfigurationTypeImage
+ icon="$nl$/icons/full/obj16/julaunchpgn.png"
+ configTypeID="org.eclipse.pde.unittest.junit.launchConfiguration"
+ id="org.eclipse.unittest.launchimage">
+ </launchConfigurationTypeImage>
+ </extension>
+
+ <extension
+ point="org.eclipse.debug.ui.launchConfigurationTabGroups">
+ <launchConfigurationTabGroup
+ class="org.eclipse.pde.unittest.junit.internal.launcher.JUnitPluginTabGroup"
+ helpContextId="org.eclipse.pde.doc.user.launcher_junit_plugin"
+ id="org.eclipse.pde.ui.launcher.JUnitPluginTabGroup"
+ type="org.eclipse.pde.unittest.junit.launchConfiguration">
+ <launchMode
+ description="%JUnitPluginTabGroup.description.debug"
+ perspective="org.eclipse.debug.ui.DebugPerspective"
+ mode="debug">
+ </launchMode>
+ <launchMode
+ description="%JUnitPluginTabGroup.description.run"
+ mode="run">
+ </launchMode>
+ </launchConfigurationTabGroup>
+ </extension>
+
+ <extension
+ point="org.eclipse.debug.core.launchConfigurationTypes">
+ <launchConfigurationType
+ allowCommandLine="true"
+ delegate="org.eclipse.pde.unittest.junit.launcher.AdvancedJUnitPluginLaunchConfigurationDelegate"
+ delegateDescription="%JUnitPluginLaunchDelegate.description"
+ delegateName="%JUnitPluginLaunchDelegate.name"
+ id="org.eclipse.pde.unittest.junit.launchConfiguration"
+ migrationDelegate="org.eclipse.pde.internal.launching.launcher.PDEMigrationDelegate"
+ modes="run, debug"
+ name="%Launch.label"
+ sourceLocatorId="org.eclipse.pde.ui.launcher.PDESourceLookupDirector"
+ sourcePathComputerId="org.eclipse.jdt.launching.sourceLookup.javaSourcePathComputer">
+ </launchConfigurationType>
+ </extension>
+
+ <extension
+ point="org.eclipse.debug.ui.launchShortcuts">
+ <shortcut
+ class="org.eclipse.pde.unittest.junit.launcher.JUnitPluginLaunchShortcut"
+ helpContextId="org.eclipse.pde.doc.user.launcher_junit_plugin"
+ icon="$nl$/icons/full/obj16/julaunchpgn.png"
+ id="org.eclipse.pde.ui.junitWorkbenchShortcut"
+ label="%JUnitPluginTestShortcut.label"
+ modes="run, debug">
+ <contextualLaunch>
+ <enablement>
+ <with variable="selection">
+ <count value="1"/>
+ <iterate>
+ <adapt type="org.eclipse.jdt.core.IJavaElement">
+ <test property="org.eclipse.jdt.core.isInJavaProjectWithNature" value="org.eclipse.pde.PluginNature"/>
+ <test property="org.eclipse.jdt.core.hasTypeOnClasspath" value="junit.framework.Test"/>
+ <test property="org.eclipse.jdt.junit.canLaunchAsJUnit" forcePluginActivation="true"/>
+ </adapt>
+ </iterate>
+ </with>
+ </enablement>
+ </contextualLaunch>
+ <configurationType
+ id="org.eclipse.pde.unittest.junit.launchConfiguration">
+ </configurationType>
+ <description
+ description="%RunJUnitPluginLaunchShortcut.description"
+ mode="run">
+ </description>
+ <description
+ description="%DebugJUnitPluginLaunchShortcut.description"
+ mode="debug">
+ </description>
+ </shortcut>
+ </extension>
+
+ <extension
+ point="org.eclipse.unittest.ui.unittestViewSupport">
+ <viewSupport
+ class="org.eclipse.pde.unittest.junit.ui.JUnitPluginTestViewSupport"
+ id="org.eclipse.pde.unittest.junit">
+ </viewSupport>
+ </extension>
+</plugin>
diff --git a/ui/org.eclipse.pde.unittest.junit/pom.xml b/ui/org.eclipse.pde.unittest.junit/pom.xml
new file mode 100644
index 0000000..5034e6e
--- /dev/null
+++ b/ui/org.eclipse.pde.unittest.junit/pom.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (c) 2012, 2021 Eclipse Foundation and others.
+ All rights reserved. This program and the accompanying materials
+ are made available under the terms of the Eclipse Distribution License v1.0
+ which accompanies this distribution, and is available at
+ http://www.eclipse.org/org/documents/edl-v10.php
+
+ Contributors:
+ Igor Fedorenko - initial implementation
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <artifactId>eclipse.pde.ui</artifactId>
+ <groupId>eclipse.pde.ui</groupId>
+ <version>4.20.0-SNAPSHOT</version>
+ <relativePath>../../</relativePath>
+ </parent>
+ <groupId>org.eclipse.pde</groupId>
+ <artifactId>org.eclipse.pde.unittest.junit</artifactId>
+ <version>1.0.0-SNAPSHOT</version>
+ <packaging>eclipse-plugin</packaging>
+ <properties>
+ <skipAPIAnalysis>true</skipAPIAnalysis>
+ </properties>
+</project>
\ No newline at end of file
diff --git a/ui/org.eclipse.pde.unittest.junit/src/org/eclipse/pde/unittest/junit/JUnitPluginTestPlugin.java b/ui/org.eclipse.pde.unittest.junit/src/org/eclipse/pde/unittest/junit/JUnitPluginTestPlugin.java
new file mode 100644
index 0000000..570fe51
--- /dev/null
+++ b/ui/org.eclipse.pde.unittest.junit/src/org/eclipse/pde/unittest/junit/JUnitPluginTestPlugin.java
@@ -0,0 +1,187 @@
+/*******************************************************************************
+ * Copyright (c) 2021 Red Hat Inc. and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * Red Hat Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.pde.unittest.junit;
+
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceReference;
+import org.osgi.service.packageadmin.PackageAdmin;
+
+import org.eclipse.swt.widgets.Shell;
+
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.core.runtime.Status;
+
+import org.eclipse.ui.IWorkbench;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.plugin.AbstractUIPlugin;
+
+/**
+ * The plug-in runtime class for the JUnit Plugin Unit Test plug-in.
+ */
+@SuppressWarnings("deprecation")
+public class JUnitPluginTestPlugin extends AbstractUIPlugin {
+
+ /**
+ * The single instance of this plug-in runtime class.
+ */
+ private static JUnitPluginTestPlugin fgPlugin = null;
+
+ public static final String PLUGIN_ID = "org.eclipse.pde.unittest.junit"; //$NON-NLS-1$
+
+ public static final String UNIT_TEST_VIEW_SUPPORT_ID = "org.eclipse.pde.unittest.junit"; //$NON-NLS-1$
+
+ private BundleContext fBundleContext;
+
+ public JUnitPluginTestPlugin() {
+ fgPlugin = this;
+ }
+
+ public static JUnitPluginTestPlugin getDefault() {
+ return fgPlugin;
+ }
+
+ public static String getPluginId() {
+ return PLUGIN_ID;
+ }
+
+ public static void log(Throwable e) {
+ log(new Status(IStatus.ERROR, getPluginId(), IStatus.ERROR, "Error", e)); //$NON-NLS-1$
+ }
+
+ public static void log(IStatus status) {
+ getDefault().getLog().log(status);
+ }
+
+ @Override
+ public void start(BundleContext context) throws Exception {
+ super.start(context);
+ fBundleContext = context;
+ }
+
+ @Override
+ public void stop(BundleContext context) throws Exception {
+ super.stop(context);
+ fBundleContext = null;
+ }
+
+ /**
+ * Returns a service with the specified name or <code>null</code> if none.
+ *
+ * @param serviceName name of service
+ * @return service object or <code>null</code> if none
+ */
+ public Object getService(String serviceName) {
+ ServiceReference<?> reference = fBundleContext.getServiceReference(serviceName);
+ if (reference == null)
+ return null;
+ return fBundleContext.getService(reference);
+ }
+
+ /**
+ * Returns the bundle for a given bundle name, regardless whether the bundle is
+ * resolved or not.
+ *
+ * @param bundleName the bundle name
+ * @return the bundle
+ */
+ public Bundle getBundle(String bundleName) {
+ Bundle[] bundles = getBundles(bundleName, null);
+ if (bundles != null && bundles.length > 0)
+ return bundles[0];
+ return null;
+ }
+
+ /**
+ * Returns the bundles for a given bundle name,
+ *
+ * @param bundleName the bundle name
+ * @param version the version of the bundle
+ * @return the bundles of the given name
+ */
+ public Bundle[] getBundles(String bundleName, String version) {
+ Bundle[] bundles = Platform.getBundles(bundleName, version);
+ if (bundles != null)
+ return bundles;
+
+ // Accessing unresolved bundle
+ ServiceReference<PackageAdmin> serviceRef = fBundleContext.getServiceReference(PackageAdmin.class);
+ PackageAdmin admin = fBundleContext.getService(serviceRef);
+ bundles = admin.getBundles(bundleName, version);
+ if (bundles != null && bundles.length > 0)
+ return bundles;
+ return null;
+ }
+
+ /**
+ * Returns this workbench window's shell.
+ *
+ * @return the shell containing this window's controls or <code>null</code> if
+ * the shell has not been created yet or if the window has been closed
+ */
+ public static Shell getActiveWorkbenchShell() {
+ IWorkbenchWindow workBenchWindow = getActiveWorkbenchWindow();
+ if (workBenchWindow == null)
+ return null;
+ return workBenchWindow.getShell();
+ }
+
+ /**
+ * Returns the active workbench window
+ *
+ * @return the active workbench window, or <code>null</code> if there is no
+ * active workbench window or if called from a non-UI thread
+ */
+ public static IWorkbenchWindow getActiveWorkbenchWindow() {
+ if (fgPlugin == null)
+ return null;
+ IWorkbench workBench = PlatformUI.getWorkbench();
+ if (workBench == null)
+ return null;
+ return workBench.getActiveWorkbenchWindow();
+ }
+
+ /**
+ * Returns the currently active page for this workbench window.
+ *
+ * @return the active page, or <code>null</code> if none
+ */
+ public static IWorkbenchPage getActivePage() {
+ IWorkbenchWindow activeWorkbenchWindow = getActiveWorkbenchWindow();
+ if (activeWorkbenchWindow == null)
+ return null;
+ return activeWorkbenchWindow.getActivePage();
+ }
+
+ /**
+ * Activates UnitTestBundle. Eclipse uses lazy bundle loading by default, which
+ * means a bundle will not be loaded in many cases until some of its class is
+ * used. This method allows the clients to instantiate the Unit Test bundle in
+ * order to make it setup its launch listeners that are used to create and
+ * activate Unit Test View. The Unit Test client bundles must call this method
+ * before a Unit Test launch is created (preferably right before creation of the
+ * launch in order to not make Eclipse to load the Unit Test bundle when it is
+ * not really required), To load the Unit Test bundle the clients, for example,
+ * might call this method inside their
+ * 'ILaunchConfigurationDelegate2.getLaunch(ILaunchConfiguration, String)'
+ * method of their launch configuration implementation.
+ */
+ public static void activateUnitTestCoreBundle() {
+ Assert.isNotNull(Platform.getBundle("org.eclipse.unittest.ui")); //$NON-NLS-1$
+ }
+}
\ No newline at end of file
diff --git a/ui/org.eclipse.pde.unittest.junit/src/org/eclipse/pde/unittest/junit/internal/launcher/JUnitPluginTabGroup.java b/ui/org.eclipse.pde.unittest.junit/src/org/eclipse/pde/unittest/junit/internal/launcher/JUnitPluginTabGroup.java
new file mode 100644
index 0000000..9422fb3
--- /dev/null
+++ b/ui/org.eclipse.pde.unittest.junit/src/org/eclipse/pde/unittest/junit/internal/launcher/JUnitPluginTabGroup.java
@@ -0,0 +1,62 @@
+/*******************************************************************************
+ * Copyright (c) 2021 Red Hat Inc. and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * Red Hat Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.pde.unittest.junit.internal.launcher;
+
+import org.eclipse.jdt.debug.ui.launchConfigurations.JavaArgumentsTab;
+import org.eclipse.pde.ui.launcher.AbstractPDELaunchConfigurationTabGroup;
+import org.eclipse.pde.ui.launcher.ConfigurationTab;
+import org.eclipse.pde.ui.launcher.PluginJUnitMainTab;
+import org.eclipse.pde.ui.launcher.PluginsTab;
+import org.eclipse.pde.ui.launcher.TracingTab;
+import org.eclipse.pde.unittest.junit.launcher.JUnitPluginTestTab;
+
+import org.eclipse.core.runtime.CoreException;
+
+import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
+
+import org.eclipse.debug.ui.CommonTab;
+import org.eclipse.debug.ui.EnvironmentTab;
+import org.eclipse.debug.ui.ILaunchConfigurationDialog;
+import org.eclipse.debug.ui.ILaunchConfigurationTab;
+
+import org.eclipse.jdt.internal.junit.launcher.AssertionVMArg;
+
+import org.eclipse.jdt.launching.IJavaLaunchConfigurationConstants;
+
+public class JUnitPluginTabGroup extends AbstractPDELaunchConfigurationTabGroup {
+
+ @Override
+ public void createTabs(ILaunchConfigurationDialog dialog, String mode) {
+ ILaunchConfigurationTab[] tabs = null;
+ tabs = new ILaunchConfigurationTab[] { new JUnitPluginTestTab(), new PluginJUnitMainTab(),
+ new JavaArgumentsTab(), new PluginsTab(), new ConfigurationTab(true), new TracingTab(),
+ new EnvironmentTab(), new CommonTab() };
+ setTabs(tabs);
+ }
+
+ @Override
+ public void setDefaults(ILaunchConfigurationWorkingCopy configuration) {
+ super.setDefaults(configuration);
+
+ String vmArgs;
+ try {
+ vmArgs = configuration.getAttribute(IJavaLaunchConfigurationConstants.ATTR_VM_ARGUMENTS, ""); //$NON-NLS-1$
+ } catch (CoreException e) {
+ vmArgs = ""; //$NON-NLS-1$
+ }
+ vmArgs = AssertionVMArg.enableAssertInArgString(vmArgs);
+ if (vmArgs.length() > 0)
+ configuration.setAttribute(IJavaLaunchConfigurationConstants.ATTR_VM_ARGUMENTS, vmArgs);
+ }
+}
diff --git a/ui/org.eclipse.pde.unittest.junit/src/org/eclipse/pde/unittest/junit/launcher/AdvancedJUnitPluginLaunchConfigurationDelegate.java b/ui/org.eclipse.pde.unittest.junit/src/org/eclipse/pde/unittest/junit/launcher/AdvancedJUnitPluginLaunchConfigurationDelegate.java
new file mode 100644
index 0000000..8526daa
--- /dev/null
+++ b/ui/org.eclipse.pde.unittest.junit/src/org/eclipse/pde/unittest/junit/launcher/AdvancedJUnitPluginLaunchConfigurationDelegate.java
@@ -0,0 +1,30 @@
+/*******************************************************************************
+ * Copyright (c) 2021 Red Hat Inc. and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * Red Hat Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.pde.unittest.junit.launcher;
+
+/**
+ * Launch configuration delegate for a JUnit test as a Java application with
+ * advanced source lookup support.
+ *
+ * @provisional This is part of work in progress and can be changed, moved or
+ * removed without notice
+ */
+public class AdvancedJUnitPluginLaunchConfigurationDelegate extends JUnitPluginLaunchConfigurationDelegate {
+
+ public AdvancedJUnitPluginLaunchConfigurationDelegate() {
+ super();
+ allowAdvancedSourcelookup();
+ }
+
+}
diff --git a/ui/org.eclipse.pde.unittest.junit/src/org/eclipse/pde/unittest/junit/launcher/JUnitPluginLaunchConfigurationDelegate.java b/ui/org.eclipse.pde.unittest.junit/src/org/eclipse/pde/unittest/junit/launcher/JUnitPluginLaunchConfigurationDelegate.java
new file mode 100644
index 0000000..61a06cc
--- /dev/null
+++ b/ui/org.eclipse.pde.unittest.junit/src/org/eclipse/pde/unittest/junit/launcher/JUnitPluginLaunchConfigurationDelegate.java
@@ -0,0 +1,1265 @@
+/*******************************************************************************
+ * Copyright (c) 2021 Red Hat Inc. and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * Red Hat Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.pde.unittest.junit.launcher;
+
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStreamWriter;
+import java.net.MalformedURLException;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.nio.charset.StandardCharsets;
+import java.text.MessageFormat;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.osgi.framework.Bundle;
+import org.osgi.framework.Constants;
+import org.osgi.framework.Version;
+
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.pde.core.plugin.IFragmentModel;
+import org.eclipse.pde.core.plugin.IPluginModelBase;
+import org.eclipse.pde.core.plugin.PluginRegistry;
+import org.eclipse.pde.core.plugin.TargetPlatform;
+import org.eclipse.pde.internal.core.ClasspathHelper;
+import org.eclipse.pde.internal.core.ICoreConstants;
+import org.eclipse.pde.internal.core.PDECore;
+import org.eclipse.pde.internal.core.TargetPlatformHelper;
+import org.eclipse.pde.internal.core.util.CoreUtility;
+import org.eclipse.pde.internal.core.util.VersionUtil;
+import org.eclipse.pde.internal.launching.IPDEConstants;
+import org.eclipse.pde.internal.launching.launcher.BundleLauncherHelper;
+import org.eclipse.pde.internal.launching.launcher.EclipsePluginValidationOperation;
+import org.eclipse.pde.internal.launching.launcher.LaunchArgumentsHelper;
+import org.eclipse.pde.internal.launching.launcher.LaunchConfigurationHelper;
+import org.eclipse.pde.internal.launching.launcher.LaunchPluginValidator;
+import org.eclipse.pde.internal.launching.launcher.LauncherUtils;
+import org.eclipse.pde.internal.launching.launcher.VMHelper;
+import org.eclipse.pde.launching.IPDELauncherConstants;
+import org.eclipse.pde.launching.PDESourcePathProvider;
+import org.eclipse.pde.unittest.junit.JUnitPluginTestPlugin;
+
+import org.eclipse.core.variables.VariablesPlugin;
+
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.FileLocator;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.core.runtime.SubMonitor;
+import org.eclipse.core.runtime.URIUtil;
+
+import org.eclipse.core.resources.IProject;
+
+import org.eclipse.debug.core.DebugPlugin;
+import org.eclipse.debug.core.ILaunch;
+import org.eclipse.debug.core.ILaunchConfiguration;
+import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
+import org.eclipse.debug.core.ILaunchManager;
+
+import org.eclipse.jdt.core.IClasspathAttribute;
+import org.eclipse.jdt.core.IClasspathEntry;
+import org.eclipse.jdt.core.IJavaElement;
+import org.eclipse.jdt.core.IJavaProject;
+import org.eclipse.jdt.core.IMember;
+import org.eclipse.jdt.core.IMethod;
+import org.eclipse.jdt.core.IPackageFragment;
+import org.eclipse.jdt.core.IPackageFragmentRoot;
+import org.eclipse.jdt.core.IType;
+import org.eclipse.jdt.core.JavaCore;
+import org.eclipse.jdt.core.JavaModelException;
+
+import org.eclipse.jdt.internal.junit.launcher.ITestKind;
+import org.eclipse.jdt.internal.junit.launcher.JUnitLaunchConfigurationConstants;
+import org.eclipse.jdt.internal.junit.launcher.JUnitRuntimeClasspathEntry;
+import org.eclipse.jdt.internal.junit.launcher.TestKindRegistry;
+
+import org.eclipse.jdt.launching.AbstractJavaLaunchConfigurationDelegate;
+import org.eclipse.jdt.launching.ExecutionArguments;
+import org.eclipse.jdt.launching.IJavaLaunchConfigurationConstants;
+import org.eclipse.jdt.launching.IVMInstall;
+import org.eclipse.jdt.launching.IVMRunner;
+import org.eclipse.jdt.launching.JavaRuntime;
+import org.eclipse.jdt.launching.SocketUtil;
+import org.eclipse.jdt.launching.VMRunnerConfiguration;
+
+import org.eclipse.jdt.ui.unittest.junit.JUnitTestPlugin;
+import org.eclipse.jdt.ui.unittest.junit.JUnitTestPlugin.JUnitVersion;
+
+/**
+ * Launch configuration delegate for a JUnit test as a Java application.
+ *
+ * <p>
+ * Clients can instantiate and extend this class.
+ * </p>
+ */
+public class JUnitPluginLaunchConfigurationDelegate extends AbstractJavaLaunchConfigurationDelegate {
+
+ // This needs to be differnet from JunitLaunchConfigurationConstants.ATTR_PORT
+ // or the "legacy" view handles it first
+ public static final String ATTR_PORT = JUnitPluginTestPlugin.PLUGIN_ID + ".PORT"; //$NON-NLS-1$
+
+ private boolean fKeepAlive = false;
+ private int fPort;
+ private IJavaElement[] fTestElements;
+
+ private static final String DEFAULT = "<default>"; //$NON-NLS-1$
+
+ @Override
+ public ILaunch getLaunch(ILaunchConfiguration configuration, String mode) throws CoreException {
+ JUnitPluginTestPlugin.activateUnitTestCoreBundle();
+ return super.getLaunch(configuration, mode);
+ }
+
+ @Override
+ public String showCommandLine(ILaunchConfiguration configuration, String mode, ILaunch launch,
+ IProgressMonitor monitor) throws CoreException {
+ launch.setAttribute(PDE_JUNIT_SHOW_COMMAND, "true"); //$NON-NLS-1$
+
+ if (monitor == null) {
+ monitor = new NullProgressMonitor();
+ }
+ try {
+ VMRunnerConfiguration runConfig = getVMRunnerConfiguration(configuration, launch, mode, monitor);
+ if (runConfig == null) {
+ return ""; //$NON-NLS-1$
+ }
+ IVMRunner runner = getVMRunner(configuration, mode);
+ String cmdLine = runner.showCommandLine(runConfig, launch, monitor);
+
+ // check for cancellation
+ if (monitor.isCanceled()) {
+ return ""; //$NON-NLS-1$
+ }
+ return cmdLine;
+ } finally {
+ monitor.done();
+ }
+ }
+
+ private VMRunnerConfiguration getVMRunnerConfiguration(ILaunchConfiguration configuration, ILaunch launch,
+ String mode, IProgressMonitor monitor) throws CoreException {
+ VMRunnerConfiguration runConfig = null;
+ monitor.beginTask(MessageFormat.format("{0}...", configuration.getName()), 5); //$NON-NLS-1$
+ // check for cancellation
+ if (monitor.isCanceled()) {
+ return null;
+ }
+
+ try {
+ if (mode.equals(JUnitLaunchConfigurationConstants.MODE_RUN_QUIETLY_MODE)) {
+ launch.setAttribute(JUnitLaunchConfigurationConstants.ATTR_NO_DISPLAY, "true"); //$NON-NLS-1$
+ mode = ILaunchManager.RUN_MODE;
+ }
+
+ monitor.subTask(Messages.JUnitPluginLaunchConfigurationDelegate_verifying_attriburtes_description);
+
+ try {
+ preLaunchCheck(configuration, launch, SubMonitor.convert(monitor, 2));
+ } catch (CoreException e) {
+ if (e.getStatus().getSeverity() == IStatus.CANCEL) {
+ monitor.setCanceled(true);
+ return null;
+ }
+ throw e;
+ }
+ // check for cancellation
+ if (monitor.isCanceled()) {
+ return null;
+ }
+
+ fKeepAlive = mode.equals(ILaunchManager.DEBUG_MODE)
+ && configuration.getAttribute(JUnitLaunchConfigurationConstants.ATTR_KEEPRUNNING, false);
+ fPort = evaluatePort();
+ launch.setAttribute(ATTR_PORT, String.valueOf(fPort));
+
+ JUnitVersion junitVersion = getJUnitVersion(configuration);
+ IJavaProject javaProject = getJavaProject(configuration);
+ if (junitVersion == JUnitVersion.JUNIT3 || junitVersion == JUnitVersion.JUNIT4) {
+ fTestElements = evaluateTests(configuration, SubMonitor.convert(monitor, 1));
+ } else {
+ IJavaElement testTarget = getTestTarget(configuration, javaProject);
+ if (testTarget instanceof IPackageFragment || testTarget instanceof IPackageFragmentRoot
+ || testTarget instanceof IJavaProject) {
+ fTestElements = new IJavaElement[] { testTarget };
+ } else {
+ fTestElements = evaluateTests(configuration, SubMonitor.convert(monitor, 1));
+ }
+ }
+
+ String mainTypeName = verifyMainTypeName(configuration);
+
+ File workingDir = verifyWorkingDirectory(configuration);
+ String workingDirName = null;
+ if (workingDir != null) {
+ workingDirName = workingDir.getAbsolutePath();
+ }
+
+ // Environment variables
+ String[] envp = getEnvironment(configuration);
+
+ ArrayList<String> vmArguments = new ArrayList<>();
+ ArrayList<String> programArguments = new ArrayList<>();
+ collectExecutionArguments(configuration, vmArguments, programArguments);
+ vmArguments.addAll(Arrays.asList(DebugPlugin.parseArguments(getVMArguments(configuration, mode))));
+ if (JavaRuntime.isModularProject(javaProject)) {
+ vmArguments.add("--add-modules=ALL-MODULE-PATH"); //$NON-NLS-1$
+ }
+
+ // VM-specific attributes
+
+ Map<String, Object> vmAttributesMap = getVMSpecificAttributesMap(configuration);
+
+ // Classpath and modulepath
+ String[][] classpathAndModulepath = getClasspathAndModulepath(configuration);
+ String[] classpath = classpathAndModulepath[0];
+ String[] modulepath = classpathAndModulepath[1];
+
+ if (junitVersion == JUnitVersion.JUNIT5) {
+ if (!configuration.getAttribute(
+ JUnitLaunchConfigurationConstants.ATTR_DONT_ADD_MISSING_JUNIT5_DEPENDENCY, false)) {
+ if (!Arrays.stream(classpath).anyMatch(
+ s -> s.contains("junit-platform-launcher") || s.contains("org.junit.platform.launcher"))) { //$NON-NLS-1$ //$NON-NLS-2$
+ try {
+ JUnitRuntimeClasspathEntry x = new JUnitRuntimeClasspathEntry("org.junit.platform.launcher", //$NON-NLS-1$
+ null);
+ String entryString = new ClasspathLocalizer(Platform.inDevelopmentMode()).entryString(x);
+ int length = classpath.length;
+ System.arraycopy(classpath, 0, classpath = new String[length + 1], 0, length);
+ classpath[length] = entryString;
+ } catch (IOException | URISyntaxException e) {
+ throw new CoreException(
+ new Status(IStatus.ERROR, JUnitPluginTestPlugin.PLUGIN_ID, IStatus.ERROR, "", e)); //$NON-NLS-1$
+ }
+ }
+ }
+ }
+
+ // Create VM config
+ runConfig = new VMRunnerConfiguration(mainTypeName, classpath);
+ runConfig.setVMArguments(vmArguments.toArray(new String[vmArguments.size()]));
+ runConfig.setProgramArguments(programArguments.toArray(new String[programArguments.size()]));
+ runConfig.setEnvironment(envp);
+ runConfig.setWorkingDirectory(workingDirName);
+ runConfig.setVMSpecificAttributesMap(vmAttributesMap);
+ runConfig.setPreviewEnabled(supportsPreviewFeatures(configuration));
+
+ if (!JavaRuntime.isModularConfiguration(configuration)) {
+ // Bootpath
+ runConfig.setBootClassPath(getBootpath(configuration));
+ } else {
+ // module path
+ runConfig.setModulepath(modulepath);
+ if (!configuration.getAttribute(IJavaLaunchConfigurationConstants.ATTR_DEFAULT_MODULE_CLI_OPTIONS,
+ true)) {
+ runConfig.setOverrideDependencies(
+ configuration.getAttribute(IJavaLaunchConfigurationConstants.ATTR_MODULE_CLI_OPTIONS, "")); //$NON-NLS-1$
+ } else {
+ runConfig.setOverrideDependencies(getModuleCLIOptions(configuration));
+ }
+ }
+
+ // check for cancellation
+ if (monitor.isCanceled()) {
+ return null;
+ }
+ } finally {
+ // done the verification phase
+ monitor.worked(1);
+ }
+ return runConfig;
+ }
+
+ static JUnitVersion getJUnitVersion(ILaunchConfiguration configuration) {
+ try {
+ String junitTestKindId = configuration.getAttribute(JUnitLaunchConfigurationConstants.ATTR_TEST_RUNNER_KIND,
+ ""); //$NON-NLS-1$
+ if (!junitTestKindId.isEmpty()) {
+ return JUnitVersion.fromJUnitTestKindId(junitTestKindId);
+ }
+ } catch (Exception ex) {
+ JUnitPluginTestPlugin.log(ex);
+ }
+ IJavaProject javaProject = JUnitLaunchConfigurationConstants.getJavaProject(configuration);
+ if (javaProject != null) {
+ return JUnitTestPlugin.getJUnitVersion(javaProject);
+ }
+ return JUnitVersion.JUNIT3;
+ }
+
+ @Override
+ public synchronized void launch(ILaunchConfiguration configuration, String mode, ILaunch launch,
+ IProgressMonitor monitor) throws CoreException {
+ if (monitor == null) {
+ monitor = new NullProgressMonitor();
+ }
+
+ try {
+
+ VMRunnerConfiguration runConfig = getVMRunnerConfiguration(configuration, launch, mode, monitor);
+ if (monitor.isCanceled() || runConfig == null) {
+ return;
+ }
+ IVMRunner runner = getVMRunner(configuration, mode);
+ monitor.subTask(Messages.JUnitPluginLaunchConfigurationDelegate_create_source_locator_description);
+ // set the default source locator if required
+ setDefaultSourceLocator(launch, configuration);
+ monitor.worked(1);
+
+ // Launch the configuration - 1 unit of work
+ runner.run(runConfig, launch, monitor);
+ } finally {
+ fTestElements = null;
+ monitor.done();
+ }
+ }
+
+ private int evaluatePort() throws CoreException {
+ int port = SocketUtil.findFreePort();
+ if (port == -1) {
+ abort(Messages.JUnitPluginLaunchConfigurationDelegate_error_no_socket, null,
+ IJavaLaunchConfigurationConstants.ERR_NO_SOCKET_AVAILABLE);
+ }
+ return port;
+ }
+
+ /**
+ * Performs a check on the launch configuration's attributes. If an attribute
+ * contains an invalid value, a {@link CoreException} with the error is thrown.
+ *
+ * @param configuration the launch configuration to verify
+ * @param launch the launch to verify
+ * @param monitor the progress monitor to use
+ * @throws CoreException an exception is thrown when the verification fails
+ */
+ protected void preLaunchCheck(ILaunchConfiguration configuration, ILaunch launch, IProgressMonitor monitor)
+ throws CoreException {
+ fWorkspaceLocation = null;
+ fConfigDir = null;
+ fModels = BundleLauncherHelper.getMergedBundleMap(configuration, false);
+ fAllBundles = new LinkedHashMap<>(fModels.size());
+ Iterator<IPluginModelBase> iter = fModels.keySet().iterator();
+ while (iter.hasNext()) {
+ IPluginModelBase model = iter.next();
+ fAllBundles.put(model.getPluginBase().getId(), model);
+ }
+
+ // implicitly add the plug-ins required for JUnit testing if necessary
+ String[] requiredPlugins = getRequiredPlugins(configuration);
+ for (String requiredPlugin : requiredPlugins) {
+ String id = requiredPlugin;
+ if (!fAllBundles.containsKey(id)) {
+ IPluginModelBase model = findRequiredPluginInTargetOrHost(id);
+ fAllBundles.put(id, model);
+ fModels.put(model, "default:default"); //$NON-NLS-1$
+ }
+ }
+ String attribute = launch.getAttribute(PDE_JUNIT_SHOW_COMMAND);
+ boolean isShowCommand = false;
+ if (attribute != null) {
+ isShowCommand = attribute.equals("true"); //$NON-NLS-1$
+ }
+ boolean autoValidate = configuration.getAttribute(IPDELauncherConstants.AUTOMATIC_VALIDATE, false);
+ SubMonitor subMonitor = SubMonitor.convert(monitor, autoValidate ? 3 : 4);
+ if (isShowCommand == false) {
+ if (autoValidate)
+ validatePluginDependencies(configuration, subMonitor.split(1));
+ validateProjectDependencies(configuration, subMonitor.split(1));
+ LauncherUtils.setLastLaunchMode(launch.getLaunchMode());
+ clear(configuration, subMonitor.split(1));
+ }
+ launch.setAttribute(PDE_JUNIT_SHOW_COMMAND, "false"); //$NON-NLS-1$
+ launch.setAttribute(IPDELauncherConstants.CONFIG_LOCATION, getConfigurationDirectory(configuration).toString());
+ synchronizeManifests(configuration, subMonitor.split(1));
+ }
+
+ @Override
+ public String getJavaProjectName(ILaunchConfiguration configuration) throws CoreException {
+ return configuration.getAttribute(IJavaLaunchConfigurationConstants.ATTR_PROJECT_NAME, (String) null);
+ }
+
+ @Override
+ public String getMainTypeName(ILaunchConfiguration configuration) throws CoreException {
+ String mainType = configuration.getAttribute(IJavaLaunchConfigurationConstants.ATTR_MAIN_TYPE_NAME,
+ (String) null);
+ if (mainType == null) {
+ return null;
+ }
+ return VariablesPlugin.getDefault().getStringVariableManager().performStringSubstitution(mainType);
+ }
+
+ @Override
+ public String verifyMainTypeName(ILaunchConfiguration configuration) throws CoreException {
+ if (TargetPlatformHelper.getTargetVersion() >= 3.3)
+ return "org.eclipse.equinox.launcher.Main"; //$NON-NLS-1$
+ return "org.eclipse.core.launcher.Main"; //$NON-NLS-1$
+ }
+
+ /**
+ * Evaluates all test elements selected by the given launch configuration. The
+ * elements are of type {@link IType} or {@link IMethod}. At the moment it is
+ * only possible to run a single method or a set of types, but not mixed or more
+ * than one method at a time.
+ *
+ * @param configuration the launch configuration to inspect
+ * @param monitor the progress monitor
+ * @return returns all types or methods that should be ran
+ * @throws CoreException an exception is thrown when the search for tests failed
+ */
+ protected IMember[] evaluateTests(ILaunchConfiguration configuration, IProgressMonitor monitor)
+ throws CoreException {
+ IJavaProject javaProject = getJavaProject(configuration);
+
+ IJavaElement testTarget = getTestTarget(configuration, javaProject);
+ String testMethodName = configuration.getAttribute(JUnitLaunchConfigurationConstants.ATTR_TEST_NAME, ""); //$NON-NLS-1$
+ if (testMethodName.length() > 0) {
+ if (testTarget instanceof IType) {
+ // If parameters exist, testMethodName is followed by a comma-separated list of
+ // fully qualified parameter type names in parentheses.
+ // The testMethodName is required in this format by #collectExecutionArguments,
+ // hence it will be used as it is with the handle-only method IType#getMethod
+ // here.
+ return new IMember[] { ((IType) testTarget).getMethod(testMethodName, new String[0]) };
+ }
+ }
+ HashSet<IType> result = new HashSet<>();
+ org.eclipse.jdt.internal.junit.launcher.ITestKind junitTestKind = getJUnitVersion(configuration)
+ .getJUnitTestKind();
+ junitTestKind.getFinder().findTestsInContainer(testTarget, result, monitor);
+ if (result.isEmpty()) {
+ String msg = MessageFormat.format(Messages.JUnitPluginLaunchConfigurationDelegate_error_notests_kind,
+ junitTestKind.getDisplayName());
+ abort(msg, null, IJavaLaunchConfigurationConstants.ERR_UNSPECIFIED_MAIN_TYPE);
+ }
+ return result.toArray(new IMember[result.size()]);
+ }
+
+ /**
+ * Collects all VM and program arguments. Implementors can modify and add
+ * arguments.
+ *
+ * @param configuration the configuration to collect the arguments for
+ * @param vmArguments a {@link List} of {@link String} representing the
+ * resulting VM arguments
+ * @param programArgs a {@link List} of {@link String} representing the
+ * resulting program arguments
+ * @exception CoreException if unable to collect the execution arguments
+ */
+ protected void collectExecutionArguments(ILaunchConfiguration configuration, List<String> vmArguments,
+ List<String> programArgs) throws CoreException {
+ internalCollectExecutionArguments(configuration, vmArguments, programArgs);
+
+ // Specify the JUnit Plug-in test application to launch
+ programArgs.add("-application"); //$NON-NLS-1$
+ String application = getApplication(configuration);
+
+ programArgs.add(application);
+
+ // If a product is specified, then add it to the program args
+ if (configuration.getAttribute(IPDELauncherConstants.USE_PRODUCT, false)) {
+ programArgs.add("-product"); //$NON-NLS-1$
+ programArgs.add(configuration.getAttribute(IPDELauncherConstants.PRODUCT, "")); //$NON-NLS-1$
+ } else {
+ // Specify the application to test
+ String defaultApplication = TargetPlatform.getDefaultApplication();
+ if (IPDEConstants.CORE_TEST_APPLICATION.equals(application)) {
+ // If we are launching the core test application we don't need a test app
+ defaultApplication = null;
+ } else if (IPDEConstants.NON_UI_THREAD_APPLICATION.equals(application)) {
+ // When running in a non-UI thread, run the core test app to avoid opening the
+ // workbench
+ defaultApplication = IPDEConstants.CORE_TEST_APPLICATION;
+ }
+
+ String testApplication = configuration.getAttribute(IPDELauncherConstants.APP_TO_TEST, defaultApplication);
+ if (testApplication != null) {
+ programArgs.add("-testApplication"); //$NON-NLS-1$
+ programArgs.add(testApplication);
+ }
+ }
+
+ // Specify the location of the runtime workbench
+ if (fWorkspaceLocation == null) {
+ fWorkspaceLocation = LaunchArgumentsHelper.getWorkspaceLocation(configuration);
+ }
+ if (fWorkspaceLocation.length() > 0) {
+ programArgs.add("-data"); //$NON-NLS-1$
+ programArgs.add(fWorkspaceLocation);
+ }
+
+ // Create the platform configuration for the runtime workbench
+ String productID = LaunchConfigurationHelper.getProductID(configuration);
+ LaunchConfigurationHelper.createConfigIniFile(configuration, productID, fAllBundles, fModels,
+ getConfigurationDirectory(configuration));
+ TargetPlatformHelper.checkPluginPropertiesConsistency(fAllBundles, getConfigurationDirectory(configuration));
+
+ programArgs.add("-configuration"); //$NON-NLS-1$
+ programArgs.add("file:" //$NON-NLS-1$
+ + new Path(getConfigurationDirectory(configuration).getPath()).addTrailingSeparator().toString());
+
+ // Specify the output folder names
+ programArgs.add("-dev"); //$NON-NLS-1$
+ programArgs.add(ClasspathHelper.getDevEntriesProperties(
+ getConfigurationDirectory(configuration).toString() + "/dev.properties", fAllBundles)); //$NON-NLS-1$
+
+ // Create the .options file if tracing is turned on
+ if (configuration.getAttribute(IPDELauncherConstants.TRACING, false) && !IPDELauncherConstants.TRACING_NONE
+ .equals(configuration.getAttribute(IPDELauncherConstants.TRACING_CHECKED, (String) null))) {
+ programArgs.add("-debug"); //$NON-NLS-1$
+ String path = getConfigurationDirectory(configuration).getPath() + IPath.SEPARATOR
+ + ICoreConstants.OPTIONS_FILENAME;
+ programArgs.add(LaunchArgumentsHelper.getTracingFileArgument(configuration, path));
+ }
+
+ // add the program args specified by the user
+ String[] userArgs = LaunchArgumentsHelper.getUserProgramArgumentArray(configuration);
+ for (String userArg : userArgs) {
+ // be forgiving if people have tracing turned on and forgot
+ // to remove the -debug from the program args field.
+ if (userArg.equals("-debug") && programArgs.contains("-debug")) //$NON-NLS-1$ //$NON-NLS-2$
+ continue;
+ programArgs.add(userArg);
+ }
+
+ if (!configuration.getAttribute(IPDEConstants.APPEND_ARGS_EXPLICITLY, false)) {
+ if (!programArgs.contains("-os")) { //$NON-NLS-1$
+ programArgs.add("-os"); //$NON-NLS-1$
+ programArgs.add(TargetPlatform.getOS());
+ }
+ if (!programArgs.contains("-ws")) { //$NON-NLS-1$
+ programArgs.add("-ws"); //$NON-NLS-1$
+ programArgs.add(TargetPlatform.getWS());
+ }
+ if (!programArgs.contains("-arch")) { //$NON-NLS-1$
+ programArgs.add("-arch"); //$NON-NLS-1$
+ programArgs.add(TargetPlatform.getOSArch());
+ }
+ }
+
+ programArgs.add("-testpluginname"); //$NON-NLS-1$
+ programArgs.add(getTestPluginId(configuration));
+ IVMInstall launcher = VMHelper.createLauncher(configuration);
+ boolean isModular = JavaRuntime.isModularJava(launcher);
+ if (isModular) {
+ String modAllSystem = "--add-modules=ALL-SYSTEM"; //$NON-NLS-1$
+ if (!vmArguments.contains(modAllSystem))
+ vmArguments.add(modAllSystem);
+ }
+ // if element is a test class annotated with @RunWith(JUnitPlatform.class, we
+ // add this in program arguments
+ if (configuration.getAttribute(JUnitLaunchConfigurationConstants.ATTR_RUN_WITH_JUNIT_PLATFORM_ANNOTATION,
+ false)) {
+ programArgs.add("-runasjunit5"); //$NON-NLS-1$
+ }
+ }
+
+ private void internalCollectExecutionArguments(ILaunchConfiguration configuration, List<String> vmArguments,
+ List<String> programArguments) throws CoreException {
+
+ // add program & VM arguments provided by getProgramArguments and getVMArguments
+ String pgmArgs = getProgramArguments(configuration);
+ String vmArgs = getVMArguments(configuration);
+ ExecutionArguments execArgs = new ExecutionArguments(vmArgs, pgmArgs);
+ vmArguments.addAll(Arrays.asList(execArgs.getVMArgumentsArray()));
+ programArguments.addAll(Arrays.asList(execArgs.getProgramArgumentsArray()));
+
+ boolean isModularProject = JavaRuntime.isModularProject(getJavaProject(configuration));
+ String addOpensTargets;
+ if (isModularProject) {
+ if (getJUnitVersion(configuration) == JUnitVersion.JUNIT5) {
+ if (isOnModulePath(getJavaProject(configuration), "org.junit.jupiter.api.Test")) { //$NON-NLS-1$
+ addOpensTargets = "org.junit.platform.commons,ALL-UNNAMED"; //$NON-NLS-1$
+ } else {
+ addOpensTargets = "ALL-UNNAMED"; //$NON-NLS-1$
+ }
+ } else {
+ if (isOnModulePath(getJavaProject(configuration), "junit.framework.TestCase")) { //$NON-NLS-1$
+ addOpensTargets = "junit,ALL-UNNAMED"; //$NON-NLS-1$
+ } else {
+ addOpensTargets = "ALL-UNNAMED"; //$NON-NLS-1$
+ }
+ }
+ } else {
+ addOpensTargets = null;
+ }
+ List<String> addOpensVmArgs = new ArrayList<>();
+
+ /*
+ * The "-version" "3" arguments don't make sense and should eventually be
+ * removed. But we keep them for now, since users may want to run with older
+ * releases of org.eclipse.jdt.junit[4].runtime, where this is still read by
+ * org.eclipse.jdt.internal.junit.runner.RemoteTestRunner#defaultInit(String[])
+ * and used in
+ * org.eclipse.jdt.internal.junit.runner.DefaultClassifier#isComparisonFailure(
+ * Throwable). The JUnit4 equivalent of the latter method is already
+ * version-agnostic:
+ * org.eclipse.jdt.internal.junit4.runner.JUnit4TestListener#testFailure(
+ * Failure, boolean)
+ */
+ programArguments.add("-version"); //$NON-NLS-1$
+ programArguments.add("3"); //$NON-NLS-1$
+
+ programArguments.add("-port"); //$NON-NLS-1$
+ programArguments.add(String.valueOf(fPort));
+
+ if (fKeepAlive)
+ programArguments.add(0, "-keepalive"); //$NON-NLS-1$
+
+ ITestKind testRunnerKind = getJUnitVersion(configuration).getJUnitTestKind();
+
+ programArguments.add("-testLoaderClass"); //$NON-NLS-1$
+ programArguments.add(testRunnerKind.getLoaderClassName());
+ programArguments.add("-loaderpluginname"); //$NON-NLS-1$
+ programArguments.add(testRunnerKind.getLoaderPluginId());
+
+ // Enable Debugging mode:
+ // programArguments.add("-debugging"); //$NON-NLS-1$
+
+ IJavaElement[] testElements = fTestElements;
+
+ if (testElements.length == 1) { // a test name was specified just run the single test, or a test container was
+ // specified
+ IJavaElement testElement = testElements[0];
+ if (testElement instanceof IMethod) {
+ IMethod method = (IMethod) testElement;
+ programArguments.add("-test"); //$NON-NLS-1$
+ programArguments.add(method.getDeclaringType().getFullyQualifiedName() + ':' + method.getElementName());
+ collectAddOpensVmArgs(addOpensTargets, addOpensVmArgs, method, configuration);
+ } else if (testElement instanceof IType) {
+ IType type = (IType) testElement;
+ programArguments.add("-classNames"); //$NON-NLS-1$
+ programArguments.add(type.getFullyQualifiedName());
+ collectAddOpensVmArgs(addOpensTargets, addOpensVmArgs, type, configuration);
+ } else if (testElement instanceof IPackageFragment || testElement instanceof IPackageFragmentRoot
+ || testElement instanceof IJavaProject) {
+ Set<String> pkgNames = new HashSet<>();
+ String fileName = createPackageNamesFile(testElement, testRunnerKind, pkgNames);
+ programArguments.add("-packageNameFile"); //$NON-NLS-1$
+ programArguments.add(fileName);
+ for (String pkgName : pkgNames) {
+ if (!DEFAULT.equals(pkgName)) { // skip --add-opens for default package
+ collectAddOpensVmArgs(addOpensTargets, addOpensVmArgs, pkgName, configuration);
+ }
+ }
+ } else {
+ abort(Messages.JUnitPluginLaunchConfigurationDelegate_error_wrong_input, null,
+ IJavaLaunchConfigurationConstants.ERR_UNSPECIFIED_MAIN_TYPE);
+ }
+ } else if (testElements.length > 1) {
+ String fileName = createTestNamesFile(testElements);
+ programArguments.add("-testNameFile"); //$NON-NLS-1$
+ programArguments.add(fileName);
+ for (IJavaElement testElement : testElements) {
+ collectAddOpensVmArgs(addOpensTargets, addOpensVmArgs, testElement, configuration);
+ }
+ }
+
+ String testFailureNames = configuration.getAttribute(JUnitLaunchConfigurationConstants.ATTR_FAILURES_NAMES, ""); //$NON-NLS-1$
+ if (testFailureNames.length() > 0) {
+ programArguments.add("-testfailures"); //$NON-NLS-1$
+ programArguments.add(testFailureNames);
+ }
+
+ String uniqueId = configuration.getAttribute(JUnitLaunchConfigurationConstants.ATTR_TEST_UNIQUE_ID, ""); //$NON-NLS-1$
+ if (!uniqueId.trim().isEmpty()) {
+ programArguments.add("-uniqueId"); //$NON-NLS-1$
+ programArguments.add(uniqueId);
+ }
+
+ boolean hasIncludeTags = configuration
+ .getAttribute(JUnitLaunchConfigurationConstants.ATTR_TEST_HAS_INCLUDE_TAGS, false);
+ if (hasIncludeTags) {
+ String includeTags = configuration.getAttribute(JUnitLaunchConfigurationConstants.ATTR_TEST_INCLUDE_TAGS,
+ ""); //$NON-NLS-1$
+ if (includeTags != null && !includeTags.trim().isEmpty()) {
+ String[] tags = includeTags.split(","); //$NON-NLS-1$
+ for (String tag : tags) {
+ programArguments.add("--include-tag"); //$NON-NLS-1$
+ programArguments.add(tag.trim());
+ }
+ }
+ }
+
+ boolean hasExcludeTags = configuration
+ .getAttribute(JUnitLaunchConfigurationConstants.ATTR_TEST_HAS_EXCLUDE_TAGS, false);
+ if (hasExcludeTags) {
+ String excludeTags = configuration.getAttribute(JUnitLaunchConfigurationConstants.ATTR_TEST_EXCLUDE_TAGS,
+ ""); //$NON-NLS-1$
+ if (excludeTags != null && !excludeTags.trim().isEmpty()) {
+ String[] tags = excludeTags.split(","); //$NON-NLS-1$
+ for (String tag : tags) {
+ programArguments.add("--exclude-tag"); //$NON-NLS-1$
+ programArguments.add(tag.trim());
+ }
+ }
+ }
+
+ if (addOpensTargets != null) {
+ vmArguments.addAll(addOpensVmArgs);
+ }
+ }
+
+ private static boolean isOnModulePath(IJavaProject javaProject, String typeToCheck) {
+ try {
+ IType type = javaProject.findType(typeToCheck);
+ if (type == null)
+ return false;
+ IPackageFragmentRoot packageFragmentRoot = (IPackageFragmentRoot) type.getPackageFragment().getParent();
+ IClasspathEntry resolvedClasspathEntry = packageFragmentRoot.getResolvedClasspathEntry();
+ return Arrays.stream(resolvedClasspathEntry.getExtraAttributes())
+ .anyMatch(p -> p.getName().equals(IClasspathAttribute.MODULE) && p.getValue().equals("true")); //$NON-NLS-1$
+ } catch (JavaModelException e) {
+ // if anything goes wrong, assume true (in the worst case, user get a warning
+ // because of a redundant add-opens)
+ return true;
+ }
+ }
+
+ private void collectAddOpensVmArgs(String addOpensTargets, List<String> addOpensVmArgs, IJavaElement javaElem,
+ ILaunchConfiguration configuration) throws CoreException {
+ if (addOpensTargets != null) {
+ IPackageFragment pkg = getParentPackageFragment(javaElem);
+ if (pkg != null) {
+ String pkgName = pkg.getElementName();
+ collectAddOpensVmArgs(addOpensTargets, addOpensVmArgs, pkgName, configuration);
+ }
+ }
+ }
+
+ private void collectAddOpensVmArgs(String addOpensTargets, List<String> addOpensVmArgs, String pkgName,
+ ILaunchConfiguration configuration) throws CoreException {
+ if (addOpensTargets != null) {
+ IJavaProject javaProject = getJavaProject(configuration);
+ String sourceModuleName = javaProject.getModuleDescription().getElementName();
+ addOpensVmArgs.add("--add-opens"); //$NON-NLS-1$
+ addOpensVmArgs.add(sourceModuleName + "/" + pkgName + "=" + addOpensTargets); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+ }
+
+ private IPackageFragment getParentPackageFragment(IJavaElement element) {
+ IJavaElement parent = element.getParent();
+ while (parent != null) {
+ if (parent instanceof IPackageFragment) {
+ return (IPackageFragment) parent;
+ }
+ parent = parent.getParent();
+ }
+ return null;
+ }
+
+ private String createPackageNamesFile(IJavaElement testContainer, ITestKind testRunnerKind, Set<String> pkgNames)
+ throws CoreException {
+ try {
+ File file = File.createTempFile("packageNames", ".txt"); //$NON-NLS-1$ //$NON-NLS-2$
+ file.deleteOnExit();
+
+ try (BufferedWriter bw = new BufferedWriter(
+ new OutputStreamWriter(new FileOutputStream(file), StandardCharsets.UTF_8))) {
+ if (testContainer instanceof IPackageFragment) {
+ pkgNames.add(getPackageName(testContainer.getElementName()));
+ } else if (testContainer instanceof IPackageFragmentRoot) {
+ addAllPackageFragments((IPackageFragmentRoot) testContainer, pkgNames);
+ } else if (testContainer instanceof IJavaProject) {
+ for (IPackageFragmentRoot pkgFragmentRoot : ((IJavaProject) testContainer)
+ .getPackageFragmentRoots()) {
+ if (!pkgFragmentRoot.isExternal() && !pkgFragmentRoot.isArchive()) {
+ addAllPackageFragments(pkgFragmentRoot, pkgNames);
+ }
+ }
+ } else {
+ abort(Messages.JUnitPluginLaunchConfigurationDelegate_error_wrong_input, null,
+ IJavaLaunchConfigurationConstants.ERR_UNSPECIFIED_MAIN_TYPE);
+ }
+ if (pkgNames.isEmpty()) {
+ String msg = MessageFormat.format(
+ Messages.JUnitPluginLaunchConfigurationDelegate_error_notests_kind,
+ testRunnerKind.getDisplayName());
+ abort(msg, null, IJavaLaunchConfigurationConstants.ERR_UNSPECIFIED_MAIN_TYPE);
+ } else {
+ for (String pkgName : pkgNames) {
+ bw.write(pkgName);
+ bw.newLine();
+ }
+ }
+ }
+ return file.getAbsolutePath();
+ } catch (IOException | JavaModelException e) {
+ throw new CoreException(new Status(IStatus.ERROR, JUnitPluginTestPlugin.PLUGIN_ID, IStatus.ERROR, "", e)); //$NON-NLS-1$
+ }
+ }
+
+ private Set<String> addAllPackageFragments(IPackageFragmentRoot pkgFragmentRoot, Set<String> pkgNames)
+ throws JavaModelException {
+ for (IJavaElement child : pkgFragmentRoot.getChildren()) {
+ if (child instanceof IPackageFragment && ((IPackageFragment) child).hasChildren()) {
+ pkgNames.add(getPackageName(child.getElementName()));
+ }
+ }
+ return pkgNames;
+ }
+
+ private String getPackageName(String elementName) {
+ if (elementName.isEmpty()) {
+ return DEFAULT;
+ }
+ return elementName;
+ }
+
+ private String createTestNamesFile(IJavaElement[] testElements) throws CoreException {
+ try {
+ File file = File.createTempFile("testNames", ".txt"); //$NON-NLS-1$ //$NON-NLS-2$
+ file.deleteOnExit();
+ try (BufferedWriter bw = new BufferedWriter(
+ new OutputStreamWriter(new FileOutputStream(file), StandardCharsets.UTF_8));) {
+ for (IJavaElement testElement : testElements) {
+ if (testElement instanceof IType) {
+ IType type = (IType) testElement;
+ String testName = type.getFullyQualifiedName();
+ bw.write(testName);
+ bw.newLine();
+ } else {
+ abort(Messages.JUnitPluginLaunchConfigurationDelegate_error_wrong_input, null,
+ IJavaLaunchConfigurationConstants.ERR_UNSPECIFIED_MAIN_TYPE);
+ }
+ }
+ }
+ return file.getAbsolutePath();
+ } catch (IOException e) {
+ throw new CoreException(new Status(IStatus.ERROR, JUnitPluginTestPlugin.PLUGIN_ID, IStatus.ERROR, "", e)); //$NON-NLS-1$
+ }
+ }
+
+ @Override
+ public String[][] getClasspathAndModulepath(ILaunchConfiguration configuration) throws CoreException {
+ String[] classpath = LaunchArgumentsHelper.constructClasspath(configuration);
+ if (classpath == null) {
+ abort(Messages.JUnitPluginLaunchConfigurationDelegate_error_noStartup, null, IStatus.OK);
+ }
+ String[][] cpmp = internalGetClasspathAndModulepath(configuration);
+ cpmp[0] = classpath;
+ return cpmp;
+ }
+
+ public String[][] internalGetClasspathAndModulepath(ILaunchConfiguration configuration) throws CoreException {
+ String[][] cpmp = super.getClasspathAndModulepath(configuration);
+ String[] cp = cpmp[0];
+
+ List<String> junitEntries = new ClasspathLocalizer(Platform.inDevelopmentMode())
+ .localizeClasspath(getJUnitVersion(configuration));
+
+ String[] classPath = new String[cp.length + junitEntries.size()];
+ Object[] jea = junitEntries.toArray();
+ System.arraycopy(cp, 0, classPath, 0, cp.length);
+ System.arraycopy(jea, 0, classPath, cp.length, jea.length);
+
+ cpmp[0] = classPath;
+
+ return cpmp;
+ }
+
+ private static class ClasspathLocalizer {
+
+ private boolean fInDevelopmentMode;
+
+ public ClasspathLocalizer(boolean inDevelopmentMode) {
+ fInDevelopmentMode = inDevelopmentMode;
+ }
+
+ public List<String> localizeClasspath(JUnitVersion junitVersion) {
+ JUnitRuntimeClasspathEntry[] entries = junitVersion.getJUnitTestKind().getClasspathEntries();
+ List<String> junitEntries = new ArrayList<>();
+
+ for (JUnitRuntimeClasspathEntry entrie : entries) {
+ try {
+ addEntry(junitEntries, entrie);
+ } catch (IOException | URISyntaxException e) {
+ Assert.isTrue(false, entrie.getPluginId() + " is available (required JAR)"); //$NON-NLS-1$
+ }
+ }
+ return junitEntries;
+ }
+
+ private void addEntry(List<String> junitEntries, final JUnitRuntimeClasspathEntry entry)
+ throws IOException, MalformedURLException, URISyntaxException {
+ String entryString = entryString(entry);
+ if (entryString != null)
+ junitEntries.add(entryString);
+ }
+
+ private String entryString(final JUnitRuntimeClasspathEntry entry)
+ throws IOException, MalformedURLException, URISyntaxException {
+ if (inDevelopmentMode()) {
+ try {
+ return localURL(entry.developmentModeEntry());
+ } catch (IOException e3) {
+ // fall through and try default
+ }
+ }
+ return localURL(entry);
+ }
+
+ private boolean inDevelopmentMode() {
+ return fInDevelopmentMode;
+ }
+
+ private String localURL(JUnitRuntimeClasspathEntry jar)
+ throws IOException, MalformedURLException, URISyntaxException {
+ Bundle bundle = JUnitPluginTestPlugin.getDefault().getBundle(jar.getPluginId());
+ URL url;
+ if (jar.getPluginRelativePath() == null) {
+ String bundleClassPath = bundle.getHeaders().get(Constants.BUNDLE_CLASSPATH);
+ url = bundleClassPath != null ? bundle.getEntry(bundleClassPath) : null;
+ if (url == null) {
+ url = bundle.getEntry("/"); //$NON-NLS-1$
+ }
+ } else {
+ url = bundle.getEntry(jar.getPluginRelativePath());
+ }
+
+ if (url == null)
+ throw new IOException();
+ return URIUtil.toFile(URIUtil.toURI(FileLocator.toFileURL(url))).getAbsolutePath(); // See bug 503050
+ }
+ }
+
+ private final IJavaElement getTestTarget(ILaunchConfiguration configuration, IJavaProject javaProject)
+ throws CoreException {
+ String containerHandle = configuration.getAttribute(JUnitLaunchConfigurationConstants.ATTR_TEST_CONTAINER, ""); //$NON-NLS-1$
+ if (containerHandle.length() != 0) {
+ IJavaElement element = JavaCore.create(containerHandle);
+ if (element == null || !element.exists()) {
+ abort(Messages.JUnitPluginLaunchConfigurationDelegate_error_input_element_deosn_not_exist, null,
+ IJavaLaunchConfigurationConstants.ERR_UNSPECIFIED_MAIN_TYPE);
+ }
+ return element;
+ }
+ String testTypeName = getMainTypeName(configuration);
+ if (testTypeName != null && testTypeName.length() != 0) {
+ IType type = javaProject.findType(testTypeName);
+ if (type != null && type.exists()) {
+ return type;
+ }
+ }
+ abort(Messages.JUnitPluginLaunchConfigurationDelegate_input_type_does_not_exist, null,
+ IJavaLaunchConfigurationConstants.ERR_UNSPECIFIED_MAIN_TYPE);
+ return null; // not reachable
+ }
+
+ @Override
+ protected void abort(String message, Throwable exception, int code) throws CoreException {
+ throw new CoreException(new Status(IStatus.ERROR, JUnitPluginTestPlugin.PLUGIN_ID, code, message, exception));
+ }
+
+ // PDE JUnit delegate
+ /**
+ * To avoid duplicating variable substitution (and duplicate prompts) this
+ * variable will store the substituted workspace location.
+ */
+ private String fWorkspaceLocation;
+
+ /**
+ * Caches the configuration directory when a launch is started
+ */
+ protected File fConfigDir = null;
+
+ // used to generate the dev classpath entries
+ // key is bundle ID, value is a model
+ private Map<String, IPluginModelBase> fAllBundles;
+
+ // key is a model, value is startLevel:autoStart
+ private Map<IPluginModelBase, String> fModels;
+
+ private static final String PDE_JUNIT_SHOW_COMMAND = "pde.junit.showcommandline"; //$NON-NLS-1$
+
+ @Override
+ public IVMRunner getVMRunner(ILaunchConfiguration configuration, String mode) throws CoreException {
+ IVMInstall launcher = VMHelper.createLauncher(configuration);
+ return launcher.getVMRunner(mode);
+ }
+
+ private String getTestPluginId(ILaunchConfiguration configuration) throws CoreException {
+ IJavaProject javaProject = getJavaProject(configuration);
+ IPluginModelBase model = PluginRegistry.findModel(javaProject.getProject());
+ if (model == null) {
+ abort(NLS.bind(Messages.JUnitPluginLaunchConfigurationDelegate_error_notaplugin,
+ javaProject.getProject().getName()), null, IStatus.OK);
+ return null;
+ }
+ if (model instanceof IFragmentModel)
+ return ((IFragmentModel) model).getFragment().getPluginId();
+
+ return model.getPluginBase().getId();
+ }
+
+ @Override
+ public String getModuleCLIOptions(ILaunchConfiguration configuration) throws CoreException {
+ // The JVM options should be specified in target platform, see getVMArguments()
+ return ""; //$NON-NLS-1$
+ }
+
+ /**
+ * Returns the application to launch plug-in tests with
+ *
+ * @since 3.5
+ *
+ * @param configuration The launch configuration in which the application is
+ * specified.
+ * @return the application
+ */
+ protected String getApplication(ILaunchConfiguration configuration) {
+ String application = null;
+
+ boolean shouldRunInUIThread = true;
+ try {
+ shouldRunInUIThread = configuration.getAttribute(IPDELauncherConstants.RUN_IN_UI_THREAD, true);
+ } catch (CoreException e) {
+ // Ignore
+ }
+
+ if (!shouldRunInUIThread) {
+ return IPDEConstants.NON_UI_THREAD_APPLICATION;
+ }
+
+ try {
+ // if application is set, it must be a headless app.
+ application = configuration.getAttribute(IPDELauncherConstants.APPLICATION, (String) null);
+ } catch (CoreException e) {
+ // Ignore
+ }
+
+ // launch the UI test application
+ if (application == null)
+ application = IPDEConstants.UI_TEST_APPLICATION;
+ return application;
+ }
+
+ private IPluginModelBase findRequiredPluginInTargetOrHost(String id) throws CoreException {
+ IPluginModelBase model = PluginRegistry.findModel(id);
+ if (model == null) {
+ model = PDECore.getDefault().findPluginInHost(id);
+ }
+ if (model == null) {
+ abort(NLS.bind(Messages.JUnitPluginLaunchConfigurationDelegate_error_missingPlugin, id), null, IStatus.OK);
+ }
+ return model;
+ }
+
+ @Override
+ public String getProgramArguments(ILaunchConfiguration configuration) throws CoreException {
+ return LaunchArgumentsHelper.getUserProgramArguments(configuration);
+ }
+
+ @Override
+ public String getVMArguments(ILaunchConfiguration configuration) throws CoreException {
+ String vmArgs = LaunchArgumentsHelper.getUserVMArguments(configuration);
+
+ // necessary for PDE to know how to load plugins when target platform = host
+ // platform
+ IPluginModelBase base = fAllBundles.get(PDECore.PLUGIN_ID);
+ if (base != null && VersionUtil.compareMacroMinorMicro(base.getBundleDescription().getVersion(),
+ new Version("3.3.1")) >= 0) { //$NON-NLS-1$
+ vmArgs = concatArg(vmArgs, "-Declipse.pde.launch=true"); //$NON-NLS-1$
+ }
+ // For p2 target, add "-Declipse.p2.data.area=@config.dir/p2" unless already
+ // specified by user
+ if (fAllBundles.containsKey("org.eclipse.equinox.p2.core")) { //$NON-NLS-1$
+ if (!vmArgs.contains("-Declipse.p2.data.area=")) { //$NON-NLS-1$
+ vmArgs = concatArg(vmArgs, "-Declipse.p2.data.area=@config.dir" + File.separator + "p2"); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+ }
+ return vmArgs;
+ }
+
+ /**
+ * Returns the result of concatenating the given argument to the specified
+ * vmArgs.
+ *
+ * @param vmArgs existing VM arguments
+ * @param arg argument to concatenate
+ * @return result of concatenation
+ */
+ private String concatArg(String vmArgs, String arg) {
+ if (vmArgs.length() > 0 && !vmArgs.endsWith(" ")) //$NON-NLS-1$
+ vmArgs = vmArgs.concat(" "); //$NON-NLS-1$
+ return vmArgs.concat(arg);
+ }
+
+ @Override
+ public String[] getEnvironment(ILaunchConfiguration configuration) throws CoreException {
+ return DebugPlugin.getDefault().getLaunchManager().getEnvironment(configuration);
+ }
+
+ @Deprecated
+ @Override
+ public String[] getClasspath(ILaunchConfiguration configuration) throws CoreException {
+ String[] classpath = LaunchArgumentsHelper.constructClasspath(configuration);
+ if (classpath == null) {
+ abort(Messages.JUnitPluginLaunchConfigurationDelegate_error_noStartup, null, IStatus.OK);
+ }
+ return classpath;
+ }
+
+ @Override
+ public File getWorkingDirectory(ILaunchConfiguration configuration) throws CoreException {
+ return LaunchArgumentsHelper.getWorkingDirectory(configuration);
+ }
+
+ @Override
+ public Map<String, Object> getVMSpecificAttributesMap(ILaunchConfiguration configuration) throws CoreException {
+ return LaunchArgumentsHelper.getVMSpecificAttributesMap(configuration);
+ }
+
+ @Override
+ protected void setDefaultSourceLocator(ILaunch launch, ILaunchConfiguration configuration) throws CoreException {
+ ILaunchConfigurationWorkingCopy wc = null;
+ if (configuration.isWorkingCopy()) {
+ wc = (ILaunchConfigurationWorkingCopy) configuration;
+ } else {
+ wc = configuration.getWorkingCopy();
+ }
+ String id = configuration.getAttribute(IJavaLaunchConfigurationConstants.ATTR_SOURCE_PATH_PROVIDER,
+ (String) null);
+ if (!PDESourcePathProvider.ID.equals(id)) {
+ wc.setAttribute(IJavaLaunchConfigurationConstants.ATTR_SOURCE_PATH_PROVIDER, PDESourcePathProvider.ID);
+ wc.doSave();
+ }
+
+ manageLaunch(launch);
+ }
+
+ /**
+ * Returns the location of the configuration area
+ *
+ * @param configuration the launch configuration
+ * @return a directory where the configuration area is located
+ */
+ protected File getConfigurationDirectory(ILaunchConfiguration configuration) {
+ if (fConfigDir == null)
+ fConfigDir = LaunchConfigurationHelper.getConfigurationArea(configuration);
+ return fConfigDir;
+ }
+
+ @Override
+ protected IProject[] getBuildOrder(ILaunchConfiguration configuration, String mode) throws CoreException {
+ return computeBuildOrder(LaunchPluginValidator.getAffectedProjects(configuration));
+ }
+
+ @Override
+ protected IProject[] getProjectsForProblemSearch(ILaunchConfiguration configuration, String mode)
+ throws CoreException {
+ return LaunchPluginValidator.getAffectedProjects(configuration);
+ }
+
+ /**
+ * Adds a listener to the launch to be notified at interesting launch lifecycle
+ * events such as when the launch terminates.
+ *
+ * @param launch the launch
+ */
+ protected void manageLaunch(ILaunch launch) {
+// PDELaunchingPlugin.getDefault().getLaunchListener().manage(launch);
+ }
+
+ private String[] getRequiredPlugins(ILaunchConfiguration configuration) {
+ // if we are using JUnit4, we need to include the junit4 specific bundles
+ ITestKind testKind = JUnitLaunchConfigurationConstants.getTestRunnerKind(configuration);
+ if (TestKindRegistry.JUNIT4_TEST_KIND_ID.equals(testKind.getId()))
+ return new String[] { "org.junit", "org.eclipse.jdt.junit.runtime", "org.eclipse.pde.junit.runtime", //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$
+ "org.eclipse.jdt.junit4.runtime" }; //$NON-NLS-1$
+ return new String[] { "org.junit", "org.eclipse.jdt.junit.runtime", "org.eclipse.pde.junit.runtime" }; //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$
+ }
+
+ /**
+ * Checks for old-style plugin.xml files that have become stale since the last
+ * launch. For any stale plugin.xml files found, the corresponding MANIFEST.MF
+ * is deleted from the runtime configuration area so that it gets regenerated
+ * upon startup.
+ *
+ * @param configuration the launch configuration
+ * @param monitor the progress monitor
+ */
+ protected void synchronizeManifests(ILaunchConfiguration configuration, IProgressMonitor monitor) {
+ LaunchConfigurationHelper.synchronizeManifests(configuration, getConfigurationDirectory(configuration));
+ monitor.done();
+ }
+
+ /**
+ * Clears the workspace prior to launching if the workspace exists and the
+ * option to clear it is turned on. Also clears the configuration area if that
+ * option is chosen.
+ *
+ * @param configuration the launch configuration
+ * @param monitor the progress monitor
+ * @throws CoreException if unable to retrieve launch attribute values
+ * @since 3.3
+ */
+ protected void clear(ILaunchConfiguration configuration, IProgressMonitor monitor) throws CoreException {
+ if (fWorkspaceLocation == null) {
+ fWorkspaceLocation = LaunchArgumentsHelper.getWorkspaceLocation(configuration);
+ }
+
+ SubMonitor subMon = SubMonitor.convert(monitor, 50);
+
+ // Clear workspace and prompt, if necessary
+ LauncherUtils.clearWorkspace(configuration, fWorkspaceLocation, subMon.split(25));
+
+ subMon.setWorkRemaining(25);
+
+ // clear config area, if necessary
+ if (configuration.getAttribute(IPDELauncherConstants.CONFIG_CLEAR_AREA, false)) {
+ CoreUtility.deleteContent(getConfigurationDirectory(configuration), subMon.split(25));
+ }
+
+ subMon.done();
+ }
+
+ /**
+ * Checks if the Automated Management of Dependencies option is turned on. If
+ * so, it makes aure all manifests are updated with the correct dependencies.
+ *
+ * @param configuration the launch configuration
+ * @param monitor a progress monitor
+ */
+ protected void validateProjectDependencies(ILaunchConfiguration configuration, IProgressMonitor monitor) {
+ LauncherUtils.validateProjectDependencies(configuration, monitor);
+ }
+
+ /**
+ * Validates inter-bundle dependencies automatically prior to launching if that
+ * option is turned on.
+ *
+ * @param configuration the launch configuration
+ * @param monitor a progress monitor
+ * @throws CoreException if unable to validate the dependencies
+ */
+ protected void validatePluginDependencies(ILaunchConfiguration configuration, IProgressMonitor monitor)
+ throws CoreException {
+ EclipsePluginValidationOperation op = new EclipsePluginValidationOperation(configuration);
+ LaunchPluginValidator.runValidationOperation(op, monitor);
+ }
+}
diff --git a/ui/org.eclipse.pde.unittest.junit/src/org/eclipse/pde/unittest/junit/launcher/JUnitPluginLaunchShortcut.java b/ui/org.eclipse.pde.unittest.junit/src/org/eclipse/pde/unittest/junit/launcher/JUnitPluginLaunchShortcut.java
new file mode 100644
index 0000000..5429638
--- /dev/null
+++ b/ui/org.eclipse.pde.unittest.junit/src/org/eclipse/pde/unittest/junit/launcher/JUnitPluginLaunchShortcut.java
@@ -0,0 +1,46 @@
+/*******************************************************************************
+ * Copyright (c) 2021 Red Hat Inc. and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * Red Hat Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.pde.unittest.junit.launcher;
+
+import org.eclipse.pde.ui.launcher.JUnitWorkbenchLaunchShortcut;
+import org.eclipse.pde.unittest.junit.JUnitPluginTestPlugin;
+import org.eclipse.unittest.ui.ConfigureViewerSupport;
+
+import org.eclipse.core.runtime.CoreException;
+
+import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
+
+import org.eclipse.jdt.core.IJavaElement;
+
+/**
+ * The launch shortcut to launch JUnit Plug-in tests.
+ *
+ * <p>
+ * This class may be instantiated and subclassed.
+ * </p>
+ */
+public class JUnitPluginLaunchShortcut extends JUnitWorkbenchLaunchShortcut {
+
+ @Override
+ protected String getLaunchConfigurationTypeId() {
+ return JUnitPluginTestPlugin.PLUGIN_ID + ".launchConfiguration"; //$NON-NLS-1$
+ }
+
+ @Override
+ protected ILaunchConfigurationWorkingCopy createLaunchConfiguration(IJavaElement element) throws CoreException {
+ ILaunchConfigurationWorkingCopy wc = super.createLaunchConfiguration(element);
+ new ConfigureViewerSupport(JUnitPluginTestPlugin.UNIT_TEST_VIEW_SUPPORT_ID).apply(wc);
+ return wc;
+ }
+}
diff --git a/ui/org.eclipse.pde.unittest.junit/src/org/eclipse/pde/unittest/junit/launcher/JUnitPluginTestTab.java b/ui/org.eclipse.pde.unittest.junit/src/org/eclipse/pde/unittest/junit/launcher/JUnitPluginTestTab.java
new file mode 100644
index 0000000..50f9119
--- /dev/null
+++ b/ui/org.eclipse.pde.unittest.junit/src/org/eclipse/pde/unittest/junit/launcher/JUnitPluginTestTab.java
@@ -0,0 +1,32 @@
+/*******************************************************************************
+ * Copyright (c) 2021 Red Hat Inc. and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * Red Hat Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.pde.unittest.junit.launcher;
+
+import org.eclipse.pde.ui.launcher.TestTab;
+import org.eclipse.pde.unittest.junit.JUnitPluginTestPlugin;
+import org.eclipse.unittest.ui.ConfigureViewerSupport;
+
+import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
+
+public class JUnitPluginTestTab extends TestTab {
+
+ @Override
+ public void performApply(ILaunchConfigurationWorkingCopy config) {
+ // TODO Auto-generated method stub
+ super.performApply(config);
+
+ new ConfigureViewerSupport(JUnitPluginTestPlugin.UNIT_TEST_VIEW_SUPPORT_ID).apply(config);
+
+ }
+}
diff --git a/ui/org.eclipse.pde.unittest.junit/src/org/eclipse/pde/unittest/junit/launcher/Messages.java b/ui/org.eclipse.pde.unittest.junit/src/org/eclipse/pde/unittest/junit/launcher/Messages.java
new file mode 100644
index 0000000..dfe84b3
--- /dev/null
+++ b/ui/org.eclipse.pde.unittest.junit/src/org/eclipse/pde/unittest/junit/launcher/Messages.java
@@ -0,0 +1,40 @@
+/*******************************************************************************
+ * Copyright (c) 2021 Red Hat Inc. and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * Red Hat Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.pde.unittest.junit.launcher;
+
+import org.eclipse.osgi.util.NLS;
+
+public final class Messages extends NLS {
+
+ private static final String BUNDLE_NAME = "org.eclipse.pde.unittest.junit.launcher.Messages";//$NON-NLS-1$
+
+ public static String JUnitPluginLaunchConfigurationDelegate_create_source_locator_description;
+ public static String JUnitPluginLaunchConfigurationDelegate_error_input_element_deosn_not_exist;
+ public static String JUnitPluginLaunchConfigurationDelegate_error_no_socket;
+ public static String JUnitPluginLaunchConfigurationDelegate_error_notests_kind;
+ public static String JUnitPluginLaunchConfigurationDelegate_error_wrong_input;
+ public static String JUnitPluginLaunchConfigurationDelegate_input_type_does_not_exist;
+ public static String JUnitPluginLaunchConfigurationDelegate_verifying_attriburtes_description;
+ public static String JUnitPluginLaunchConfigurationDelegate_error_notaplugin;
+ public static String JUnitPluginLaunchConfigurationDelegate_error_noStartup;
+ public static String JUnitPluginLaunchConfigurationDelegate_error_missingPlugin;
+
+ static {
+ NLS.initializeMessages(BUNDLE_NAME, Messages.class);
+ }
+
+ private Messages() {
+ // Do not instantiate
+ }
+}
diff --git a/ui/org.eclipse.pde.unittest.junit/src/org/eclipse/pde/unittest/junit/launcher/Messages.properties b/ui/org.eclipse.pde.unittest.junit/src/org/eclipse/pde/unittest/junit/launcher/Messages.properties
new file mode 100644
index 0000000..6280672
--- /dev/null
+++ b/ui/org.eclipse.pde.unittest.junit/src/org/eclipse/pde/unittest/junit/launcher/Messages.properties
@@ -0,0 +1,23 @@
+#################################################################################
+# Copyright (c) 2021 Red Hat, Inc.
+#
+# This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License 2.0
+# which accompanies this distribution, and is available at
+# https://www.eclipse.org/legal/epl-2.0/
+#
+# SPDX-License-Identifier: EPL-2.0
+#
+# Contributors:
+# Red Hat Inc. - initial API and implementation
+#################################################################################
+JUnitPluginLaunchConfigurationDelegate_verifying_attriburtes_description=Verifying launch attributes...
+JUnitPluginLaunchConfigurationDelegate_create_source_locator_description=Creating source locator...
+JUnitPluginLaunchConfigurationDelegate_error_no_socket=No socket available
+JUnitPluginLaunchConfigurationDelegate_error_notests_kind=No tests found with test runner ''{0}''.
+JUnitPluginLaunchConfigurationDelegate_error_wrong_input=Can only run types or single method
+JUnitPluginLaunchConfigurationDelegate_error_input_element_deosn_not_exist=The input element of the launch configuration does not exist
+JUnitPluginLaunchConfigurationDelegate_input_type_does_not_exist=The input type of the launch configuration does not exist
+JUnitPluginLaunchConfigurationDelegate_error_notaplugin = Could not launch the JUnit plug-in tests because project ''{0}'' is not a plug-in project.
+JUnitPluginLaunchConfigurationDelegate_error_noStartup = Launching failed. Bootstrap code cannot be found.
+JUnitPluginLaunchConfigurationDelegate_error_missingPlugin = Required plug-in ''{0}'' could not be found.
diff --git a/ui/org.eclipse.pde.unittest.junit/src/org/eclipse/pde/unittest/junit/ui/JUnitPluginTestViewSupport.java b/ui/org.eclipse.pde.unittest.junit/src/org/eclipse/pde/unittest/junit/ui/JUnitPluginTestViewSupport.java
new file mode 100644
index 0000000..a82a2ed
--- /dev/null
+++ b/ui/org.eclipse.pde.unittest.junit/src/org/eclipse/pde/unittest/junit/ui/JUnitPluginTestViewSupport.java
@@ -0,0 +1,226 @@
+/*******************************************************************************
+ * Copyright (c) 2021 Red Hat Inc. and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * Red Hat Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.pde.unittest.junit.ui;
+
+import org.eclipse.pde.unittest.junit.launcher.JUnitPluginLaunchConfigurationDelegate;
+import org.eclipse.unittest.launcher.ITestRunnerClient;
+import org.eclipse.unittest.model.ITestRunSession;
+
+import org.eclipse.jdt.ui.unittest.junit.ui.JUnitTestViewSupport;
+
+public class JUnitPluginTestViewSupport extends JUnitTestViewSupport {
+ @Override
+ public String getDisplayName() {
+ return "JUnit Plugin"; //$NON-NLS-1$
+ }
+
+ @Override
+ public ITestRunnerClient newTestRunnerClient(ITestRunSession session) {
+ String portAsString = session.getLaunch().getAttribute(JUnitPluginLaunchConfigurationDelegate.ATTR_PORT);
+ return new org.eclipse.jdt.ui.unittest.junit.launcher.JUnitRemoteTestRunnerClient(
+ portAsString != null ? Integer.parseInt(portAsString) : -1, session);
+ }
+}
+/*
+ * implements ITestViewSupport {
+ *
+ * public static final String FRAME_LINE_PREFIX = "at "; //$NON-NLS-1$
+ *
+ * @Override public Collection<StringMatcher> getTraceExclusionFilterPatterns()
+ * { return Arrays
+ * .stream(JUnitPreferencesConstants.parseList(Platform.getPreferencesService().
+ * getString( JUnitCorePlugin.CORE_PLUGIN_ID,
+ * JUnitPreferencesConstants.PREF_ACTIVE_FILTERS_LIST, "", null))) //$NON-NLS-1$
+ * .filter(Predicate.not(String::isBlank)) // .map(pattern -> new
+ * StringMatcher(pattern, true, false)) // .collect(Collectors.toList()); }
+ *
+ * @Override public IAction getOpenTestAction(Shell shell, ITestCaseElement
+ * testCase) { return new OpenTestAction(shell, testCase,
+ * getParameterTypes(testCase)); }
+ *
+ * @Override public IAction getOpenTestAction(Shell shell, ITestSuiteElement
+ * testSuite) { String testName = testSuite.getTestName(); List<? extends
+ * ITestElement> children = testSuite.getChildren(); if
+ * (testName.startsWith("[") && testName.endsWith("]") && !children.isEmpty()
+ * //$NON-NLS-1$ //$NON-NLS-2$ && children.get(0) instanceof ITestCaseElement) {
+ * // a group of parameterized tests return new OpenTestAction(shell,
+ * (ITestCaseElement) children.get(0), null); }
+ *
+ * int index = testName.indexOf('('); // test factory method if (index > 0) {
+ * return new OpenTestAction(shell, testSuite.getTestName(),
+ * testName.substring(0, index), getParameterTypes(testSuite), true,
+ * testSuite.getTestRunSession()); }
+ *
+ * // regular test class return new OpenTestAction(shell, testName,
+ * testSuite.getTestRunSession());
+ *
+ * }
+ *
+ * @Override public IAction createOpenEditorAction(Shell shell, ITestElement
+ * failure, String traceLine) { try { String testName = traceLine; int
+ * indexOfFramePrefix = testName.indexOf(FRAME_LINE_PREFIX); if
+ * (indexOfFramePrefix == -1) { return null; } testName =
+ * testName.substring(indexOfFramePrefix); testName =
+ * testName.substring(FRAME_LINE_PREFIX.length(),
+ * testName.lastIndexOf('(')).trim(); int indexOfModuleSeparator =
+ * testName.lastIndexOf('/'); if (indexOfModuleSeparator != -1) { testName =
+ * testName.substring(indexOfModuleSeparator + 1); } testName =
+ * testName.substring(0, testName.lastIndexOf('.')); int innerSeparatorIndex =
+ * testName.indexOf('$'); if (innerSeparatorIndex != -1) testName =
+ * testName.substring(0, innerSeparatorIndex);
+ *
+ * String lineNumber = traceLine; lineNumber =
+ * lineNumber.substring(lineNumber.indexOf(':') + 1,
+ * lineNumber.lastIndexOf(')')); int line; try { line =
+ * Integer.parseInt(lineNumber); } catch (NumberFormatException e) { // In some
+ * cases the line number can be omitted from a stack trace line line = 1; }
+ * return new OpenEditorAtLineAction(shell, testName, line,
+ * failure.getTestRunSession()); } catch (IndexOutOfBoundsException e) {
+ * JUnitPluginTestPlugin.log(e); } return null; }
+ *
+ * @Override public Runnable
+ * createShowStackTraceInConsoleViewActionDelegate(ITestElement failedTest) {
+ * return new ShowStackTraceInConsoleViewActionDelegate(failedTest); }
+ *
+ * @Override public ILaunchConfiguration
+ * getRerunLaunchConfiguration(List<ITestElement> tests) { if (tests.size() > 1)
+ * { MessageDialog.openInformation(Display.getDefault().getActiveShell(),
+ * JUnitMessages.JUnitCantRunMultipleTests,
+ * JUnitMessages.JUnitCantRunMultipleTests); return null; } ITestElement
+ * testSuite = tests.get(0); String testMethodName = null; // test method name
+ * is null when re-running a regular test class String testName =
+ * testSuite.getTestName();
+ *
+ * ILaunchConfiguration launchConfiguration =
+ * testSuite.getTestRunSession().getLaunch().getLaunchConfiguration(); ITestKind
+ * junitKind; try { junitKind = JUnitVersion
+ * .fromJUnitTestKindId(launchConfiguration
+ * .getAttribute(JUnitLaunchConfigurationConstants.ATTR_TEST_RUNNER_KIND, ""))
+ * //$NON-NLS-1$ .getJUnitTestKind(); } catch (CoreException e) {
+ * JUnitPluginTestPlugin.log(e); return null; }
+ *
+ * IJavaProject project = JUnitLaunchConfigurationConstants
+ * .getJavaProject(testSuite.getTestRunSession().getLaunch().
+ * getLaunchConfiguration()); if (project == null) { return null; }
+ *
+ * String qualifiedName = null; IType testType = findTestClass(testSuite,
+ * junitKind.getFinder(), project, true); if (testType != null) { qualifiedName
+ * = testType.getFullyQualifiedName();
+ *
+ * if (!qualifiedName.equals(testName)) { int index = testName.indexOf('('); if
+ * (index > 0) { // test factory method testMethodName = testName.substring(0,
+ * index); } } String[] parameterTypes = getParameterTypes(testSuite); if
+ * (testMethodName != null && parameterTypes != null) { String paramTypesStr =
+ * Arrays.stream(parameterTypes).collect(Collectors.joining(",")); //$NON-NLS-1$
+ * testMethodName = testMethodName + "(" + paramTypesStr + ")"; //$NON-NLS-1$
+ * //$NON-NLS-2$ } } else { // see bug 443498 testType =
+ * findTestClass(testSuite.getParent(), junitKind.getFinder(), project, false);
+ * if (testType != null && testSuite instanceof ITestSuiteElement) {
+ * qualifiedName = testType.getFullyQualifiedName();
+ *
+ * String className = getClassName(testSuite); if
+ * (!qualifiedName.equals(className)) { testMethodName = testName; } } }
+ *
+ * ILaunchConfigurationWorkingCopy res; try { res =
+ * launchConfiguration.copy(launchConfiguration.getName() + " - rerun");
+ * //$NON-NLS-1$
+ * res.setAttribute(JUnitLaunchConfigurationConstants.ATTR_TEST_METHOD_NAME,
+ * testMethodName); return res; } catch (CoreException e) {
+ * JUnitPluginTestPlugin.log(e); return null; }
+ *
+ * }
+ */
+/*
+ * Returns the element's test class or the next container's test class, which
+ * exists, and for which ITestFinder.isTest() is true.
+ */
+/*
+ * private IType findTestClass(ITestElement element, ITestFinder finder,
+ * IJavaProject project, boolean checkOnlyCurrentElement) { ITestElement current
+ * = element; while (current != null) { try { String className = null; if
+ * (current instanceof ITestRunSession) { ILaunch launch =
+ * element.getTestRunSession().getLaunch(); if (launch != null) {
+ * ILaunchConfiguration configuration = launch.getLaunchConfiguration(); if
+ * (configuration != null) { className = configuration
+ * .getAttribute(IJavaLaunchConfigurationConstants.ATTR_MAIN_TYPE_NAME, (String)
+ * null); } } } else { className = getClassName(current); }
+ *
+ * if (className != null) { IType type = project.findType(className); if (type
+ * != null && finder.isTest(type)) { return type; } else if
+ * (checkOnlyCurrentElement) { return null; } } } catch (CoreException e) {
+ * JUnitPluginTestPlugin.log(e); } current = current.getParent(); } return null;
+ * }
+ *
+ * @Override public String getDisplayName() { return "JUnit Plugin";
+ * //$NON-NLS-1$ }
+ *
+ * @Override public ITestRunnerClient newTestRunnerClient(ITestRunSession
+ * session) { String portAsString =
+ * session.getLaunch().getAttribute(JUnitPluginLaunchConfigurationDelegate.
+ * ATTR_PORT); return new JUnitRemoteTestRunnerClient(portAsString != null ?
+ * Integer.parseInt(portAsString) : -1, session); }
+ */
+/**
+ * Returns the parameter types specified for this test element
+ *
+ * @param test test
+ * @return a parameter type array
+ */
+/*
+ * private String[] getParameterTypes(ITestElement test) { String testName =
+ * test.getDisplayName(); if (testName != null) { int index =
+ * testName.lastIndexOf("method:"); //$NON-NLS-1$ if (index != -1) { index =
+ * testName.indexOf('(', index); if (index > 0) { int closeIndex =
+ * testName.indexOf(')', index); if (closeIndex > 0) { String params =
+ * testName.substring(index + 1, closeIndex); return params.split(",");
+ * //$NON-NLS-1$ } } } } return null; }
+ */
+/**
+ * Returns the type/class of the test element
+ *
+ * @param test test
+ * @return return the type/class name
+ */
+/*
+ * public static String getClassName(ITestElement test) { return
+ * extractClassName(test.getTestName()); }
+ *
+ * private static String extractClassName(String testNameString) {
+ * testNameString = extractRawClassName(testNameString); testNameString =
+ * testNameString.replace('$', '.'); // see bug 178503 return testNameString; }
+ */
+/**
+ * Extracts and returns a raw class name from a test element name
+ *
+ * @param testNameString a test element name
+ *
+ * @return an extracted raw class name
+ */
+/*
+ * public static String extractRawClassName(String testNameString) { if
+ * (testNameString.startsWith("[") && testNameString.endsWith("]")) {
+ * //$NON-NLS-1$ //$NON-NLS-2$ // a group of parameterized tests, see //
+ * https://bugs.eclipse.org/bugs/show_bug.cgi?id=102512 return testNameString; }
+ * int index = testNameString.lastIndexOf('('); if (index < 0) return
+ * testNameString; int end = testNameString.lastIndexOf(')'); return
+ * testNameString.substring(index + 1, end > index ? end :
+ * testNameString.length()); }
+ *
+ * public static String getTestMethodName(ITestElement test) { String testName =
+ * test.getTestName(); int index = testName.lastIndexOf('('); if (index > 0)
+ * return testName.substring(0, index); index = testName.indexOf('@'); if (index
+ * > 0) return testName.substring(0, index); return testName; }
+ *
+ * }
+ */
\ No newline at end of file