diff --git a/build.sh b/build.sh
old mode 100755
new mode 100644
diff --git a/cobigen-cli/cli/pom.xml b/cobigen-cli/cli/pom.xml
index 185117cc1c..c168fe1627 100644
--- a/cobigen-cli/cli/pom.xml
+++ b/cobigen-cli/cli/pom.xml
@@ -13,6 +13,7 @@
false
+ 18
@@ -24,6 +25,10 @@
com.devonfw.cobigen
core-api
+
+ com.devonfw.cobigen
+ gui
+
${project.groupId}
core-externalprocess-api
@@ -52,6 +57,16 @@
google-java-format
1.10.0
+
+ org.openjfx
+ javafx-controls
+ ${javafx.version}
+
+
+ org.openjfx
+ javafx-fxml
+ ${javafx.version}
+
diff --git a/cobigen-cli/cli/src/main/java/com/devonfw/cobigen/cli/commands/CobiGenCommand.java b/cobigen-cli/cli/src/main/java/com/devonfw/cobigen/cli/commands/CobiGenCommand.java
index 785687e380..e58e97f9a1 100644
--- a/cobigen-cli/cli/src/main/java/com/devonfw/cobigen/cli/commands/CobiGenCommand.java
+++ b/cobigen-cli/cli/src/main/java/com/devonfw/cobigen/cli/commands/CobiGenCommand.java
@@ -11,7 +11,7 @@
@Command(description = MessagesConstants.WELCOME_MESSAGE, name = "cobigen", aliases = {
"cg" }, mixinStandardHelpOptions = true, subcommands = { GenerateCommand.class, UpdateCommand.class,
-AdaptTemplatesCommand.class }, versionProvider = CobiGenVersionProvider.class)
+AdaptTemplatesCommand.class, ManageCommand.class }, versionProvider = CobiGenVersionProvider.class)
public class CobiGenCommand implements Runnable {
@Override
diff --git a/cobigen-cli/cli/src/main/java/com/devonfw/cobigen/cli/commands/ManageCommand.java b/cobigen-cli/cli/src/main/java/com/devonfw/cobigen/cli/commands/ManageCommand.java
new file mode 100644
index 0000000000..15fc2717cb
--- /dev/null
+++ b/cobigen-cli/cli/src/main/java/com/devonfw/cobigen/cli/commands/ManageCommand.java
@@ -0,0 +1,44 @@
+package com.devonfw.cobigen.cli.commands;
+
+import java.util.concurrent.TimeUnit;
+
+import com.devonfw.cobigen.gui.AppLauncher;
+
+import picocli.CommandLine.Command;
+
+/**
+ * This class handles the manage template sets command
+ */
+@Command(description = "Opens GUI for Template Set Management", name = "manage", aliases = {
+"m" }, mixinStandardHelpOptions = true)
+public class ManageCommand extends CommandCommons {
+
+ public AppLauncher launcher;
+
+ /**
+ * Constructor needed for Picocli
+ */
+ public ManageCommand() {
+
+ super();
+ }
+
+ @Override
+ public synchronized Integer doAction() throws Exception {
+
+ System.out.println("You just called the GUI");
+ this.launcher = new AppLauncher();
+ try {
+ wait(1337);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+
+ while (this.launcher.app.window.isShowing()) {
+ TimeUnit.SECONDS.sleep(1);
+ }
+
+ return 0;
+ }
+
+}
diff --git a/cobigen-eclipse/cobigen-eclipse-feature/pom.xml b/cobigen-eclipse/cobigen-eclipse-feature/pom.xml
index 01e23da9bd..706e825c4a 100644
--- a/cobigen-eclipse/cobigen-eclipse-feature/pom.xml
+++ b/cobigen-eclipse/cobigen-eclipse-feature/pom.xml
@@ -11,4 +11,9 @@
eclipse-parent
${revision}
+
+
+ false
+
+
diff --git a/cobigen-eclipse/cobigen-eclipse-test/pom.xml b/cobigen-eclipse/cobigen-eclipse-test/pom.xml
index 8fc4f9cf42..7feeaf8fd4 100644
--- a/cobigen-eclipse/cobigen-eclipse-test/pom.xml
+++ b/cobigen-eclipse/cobigen-eclipse-test/pom.xml
@@ -12,7 +12,6 @@
${surefireArgLineIntegration} -Xms512m -Xmx2048m -XX:+DisableExplicitGC
- true
@@ -24,6 +23,10 @@
com.devonfw.cobigen
core-api
+
+ com.devonfw.cobigen
+ gui
+
ch.qos.logback
logback-classic
diff --git a/cobigen-eclipse/cobigen-eclipse-test/src/main/java/com/devonfw/cobigen/eclipse/test/OpenGUITest.java b/cobigen-eclipse/cobigen-eclipse-test/src/main/java/com/devonfw/cobigen/eclipse/test/OpenGUITest.java
new file mode 100644
index 0000000000..bea75c98c4
--- /dev/null
+++ b/cobigen-eclipse/cobigen-eclipse-test/src/main/java/com/devonfw/cobigen/eclipse/test/OpenGUITest.java
@@ -0,0 +1,59 @@
+package com.devonfw.cobigen.eclipse.test;
+
+import java.io.File;
+
+import org.apache.commons.io.FileUtils;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.jdt.core.IJavaProject;
+import org.eclipse.swtbot.swt.finder.junit.SWTBotJunit4ClassRunner;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import com.devonfw.cobigen.eclipse.test.common.SystemTest;
+import com.devonfw.cobigen.eclipse.test.common.utils.EclipseCobiGenUtils;
+import com.devonfw.cobigen.eclipse.test.common.utils.EclipseUtils;
+
+/**
+ * Class for testing Manage Template Sets with a click on the Home Button
+ *
+ */
+@RunWith(SWTBotJunit4ClassRunner.class)
+public class OpenGUITest extends SystemTest {
+
+ /** Root path of the Test Resources */
+ private static final String resourcesRootPath = "src/main/resources/OpenAPITest/";
+
+ /**
+ * Setup workbench appropriately for tests
+ *
+ * @throws Exception test fails
+ */
+ @BeforeClass
+ public static void setupClass() throws Exception {
+
+ EclipseUtils.cleanWorkspace(bot, true);
+ }
+
+ /**
+ * Testing to open the Template Set Management GUI and clicking Home Button
+ *
+ * @throws Exception test fails
+ */
+ @Test
+ public void testOpenTemplateSetManagementGUI() throws Exception {
+
+ // copy sample project to external location and import it into the workspace
+ String testProjName = "ExtTestProj";
+ IJavaProject project = this.tmpMavenProjectRule.createProject(testProjName);
+ FileUtils.copyFile(new File(resourcesRootPath + "input/adapt-templates.yml"),
+ project.getUnderlyingResource().getLocation().append("adapt-templates.yml").toFile());
+ project.getProject().refreshLocal(IResource.DEPTH_INFINITE, new NullProgressMonitor());
+ this.tmpMavenProjectRule.updateProject();
+
+ // open GUI
+ EclipseCobiGenUtils.runAndCaptureManageTemplateSets(bot);
+ }
+
+}
diff --git a/cobigen-eclipse/cobigen-eclipse-test/src/main/java/com/devonfw/cobigen/eclipse/test/common/utils/EclipseCobiGenUtils.java b/cobigen-eclipse/cobigen-eclipse-test/src/main/java/com/devonfw/cobigen/eclipse/test/common/utils/EclipseCobiGenUtils.java
index 992b7cbb56..0c1ad313e4 100644
--- a/cobigen-eclipse/cobigen-eclipse-test/src/main/java/com/devonfw/cobigen/eclipse/test/common/utils/EclipseCobiGenUtils.java
+++ b/cobigen-eclipse/cobigen-eclipse-test/src/main/java/com/devonfw/cobigen/eclipse/test/common/utils/EclipseCobiGenUtils.java
@@ -402,6 +402,28 @@ public static void runAndCaptureAdaptTemplates(SWTWorkbenchBot bot) throws Excep
informationDialog.bot().button("Ok").click();
}
+ /**
+ * Checks the CobiGen Manage Template Sets and takes screenshots of it.
+ *
+ * @param bot to process the Manage Template Sets command
+ * @throws Exception test fails
+ */
+ public static void runAndCaptureManageTemplateSets(SWTWorkbenchBot bot) throws Exception {
+
+ ResourcesPlugin.getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, new NullProgressMonitor());
+ bot.waitUntil(new AllJobsAreFinished(), DEFAULT_TIMEOUT); // build might take some time
+
+ SWTBotView view = bot.viewById(JavaUI.ID_PACKAGES);
+ view.bot().tree().contextMenu("CobiGen").menu("Manage Template Sets...").click();
+
+ // TODO
+ // bot.waitUntil(new AnyShellIsActive("Template Set Manager"), DEFAULT_TIMEOUT);
+ // takeScreenshot(bot, "Template Set Manager");
+ // SWTBotShell gui = bot.shell("Template Set Manager");
+ // gui.bot().button("#homeButton").click();
+
+ }
+
/**
* Takes a screenshot (*.jpeg) of the current screen encoding test method and class and appends the given identifier
* to the file name
diff --git a/cobigen-eclipse/cobigen-eclipse/build.properties b/cobigen-eclipse/cobigen-eclipse/build.properties
index 4415ea671c..82304223d5 100644
--- a/cobigen-eclipse/cobigen-eclipse/build.properties
+++ b/cobigen-eclipse/cobigen-eclipse/build.properties
@@ -53,4 +53,13 @@ bin.includes = .,\
lib/plexus-utils.jar,\
lib/slf4j-api.jar,\
lib/txw2.jar,\
- lib/zt-exec.jar
+ lib/zt-exec.jar,\
+ lib/gui.jar,\
+ lib/javafx-base.jar,\
+ lib/javafx-base-win.jar,\
+ lib/javafx-controls.jar,\
+ lib/javafx-controls-win.jar,\
+ lib/javafx-fxml.jar,\
+ lib/javafx-fxml-win.jar,\
+ lib/javafx-graphics.jar,\
+ lib/javafx-graphics-win.jar
diff --git a/cobigen-eclipse/cobigen-eclipse/plugin.xml b/cobigen-eclipse/cobigen-eclipse/plugin.xml
index 647a2dbdb7..d8d6e14612 100644
--- a/cobigen-eclipse/cobigen-eclipse/plugin.xml
+++ b/cobigen-eclipse/cobigen-eclipse/plugin.xml
@@ -19,6 +19,10 @@
id="com.devonfw.cobigen.eclipseplugin.adapt_template"
name="Adapt Template">
+
+
@@ -38,6 +42,10 @@
class="com.devonfw.cobigen.eclipse.workbenchcontrol.handler.AdaptTemplatesHandler"
commandId="com.devonfw.cobigen.eclipseplugin.adapt_template">
+
+
@@ -70,6 +78,11 @@
label="Adapt Templates..."
style="push">
+
+
+
+
+
+
diff --git a/cobigen-eclipse/cobigen-eclipse/pom.xml b/cobigen-eclipse/cobigen-eclipse/pom.xml
index 97648bc5b6..eff89f5c1a 100644
--- a/cobigen-eclipse/cobigen-eclipse/pom.xml
+++ b/cobigen-eclipse/cobigen-eclipse/pom.xml
@@ -24,6 +24,10 @@
com.devonfw.cobigen
core-externalprocess-api
+
+ com.devonfw.cobigen
+ gui
+
com.devonfw.cobigen
javaplugin-model
diff --git a/cobigen-eclipse/cobigen-eclipse/src/com/devonfw/cobigen/eclipse/workbenchcontrol/handler/ManageTemplateSetsHandler.java b/cobigen-eclipse/cobigen-eclipse/src/com/devonfw/cobigen/eclipse/workbenchcontrol/handler/ManageTemplateSetsHandler.java
new file mode 100644
index 0000000000..aa88164524
--- /dev/null
+++ b/cobigen-eclipse/cobigen-eclipse/src/com/devonfw/cobigen/eclipse/workbenchcontrol/handler/ManageTemplateSetsHandler.java
@@ -0,0 +1,52 @@
+package com.devonfw.cobigen.eclipse.workbenchcontrol.handler;
+
+import java.util.concurrent.TimeUnit;
+
+import org.eclipse.core.commands.AbstractHandler;
+import org.eclipse.core.commands.ExecutionEvent;
+import org.eclipse.core.commands.ExecutionException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.devonfw.cobigen.gui.AppLauncher;
+
+/**
+ * Handler for the Package-Explorer Event
+ *
+ */
+public class ManageTemplateSetsHandler extends AbstractHandler {
+
+ /**
+ * Assigning logger to ManageTemplateSetsHandler
+ */
+ private static final Logger LOG = LoggerFactory.getLogger(ManageTemplateSetsHandler.class);
+
+ /**
+ * Launcher for GUI
+ */
+ public AppLauncher launcher;
+
+ @Override
+ public Object execute(ExecutionEvent event) throws ExecutionException {
+
+ System.out.println("You just called the GUI");
+ this.launcher = new AppLauncher();
+ try {
+ wait(1337);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+
+ while (this.launcher.app.window.isShowing()) {
+ try {
+ TimeUnit.SECONDS.sleep(1);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ }
+
+ return null;
+
+ }
+
+}
diff --git a/cobigen/cobigen-core-api/src/main/java/com/devonfw/cobigen/api/constants/ConfigurationConstants.java b/cobigen/cobigen-core-api/src/main/java/com/devonfw/cobigen/api/constants/ConfigurationConstants.java
index ce21d5eafc..70d56141b0 100644
--- a/cobigen/cobigen-core-api/src/main/java/com/devonfw/cobigen/api/constants/ConfigurationConstants.java
+++ b/cobigen/cobigen-core-api/src/main/java/com/devonfw/cobigen/api/constants/ConfigurationConstants.java
@@ -134,4 +134,6 @@ public class ConfigurationConstants {
*/
public static final String CONFIG_PROPERTY_TEMPLATE_SETS_DEFAULT_VERSION = "2021.12.007";
+ public static final String TEMPLATE_SET_ARTIFACT_CACHE_FOLDER = "template-set-list";
+
}
diff --git a/cobigen/cobigen-core-api/src/main/java/com/devonfw/cobigen/api/util/MavenCoordinate.java b/cobigen/cobigen-core-api/src/main/java/com/devonfw/cobigen/api/util/MavenCoordinate.java
index 96f51f2c43..6d19bf3312 100644
--- a/cobigen/cobigen-core-api/src/main/java/com/devonfw/cobigen/api/util/MavenCoordinate.java
+++ b/cobigen/cobigen-core-api/src/main/java/com/devonfw/cobigen/api/util/MavenCoordinate.java
@@ -1,11 +1,12 @@
package com.devonfw.cobigen.api.util;
+import java.util.Arrays;
import java.util.Objects;
/**
* This MavenCoordinate class is just a dataholder with maven coordinates.
*/
-public class MavenCoordinate {
+public class MavenCoordinate implements Comparable {
/**
* the groupId of the maven artifact
@@ -86,4 +87,22 @@ public boolean equals(Object obj) {
&& Objects.equals(this.version, other.version);
}
+ @Override
+ public int compareTo(MavenCoordinate other) {
+
+ if (!this.artifactId.equals(other.artifactId)) {
+ throw new ClassCastException("The artifactID of the comprarable should be the same");
+ // TODO
+ }
+ int[] versionNumbersCurrent = Arrays.stream(this.version.split("\\.")).mapToInt(Integer::parseInt).toArray();
+ int[] versionNumbersOther = Arrays.stream(other.getVersion().split("\\.")).mapToInt(Integer::parseInt).toArray();
+ for (int i = 0; i < versionNumbersCurrent.length; i++) {
+ if (versionNumbersCurrent[i] > versionNumbersOther[i]) {
+ return 1;
+ } else if (versionNumbersCurrent[i] < versionNumbersOther[i])
+ return -1;
+ }
+ return 0;
+ }
+
}
diff --git a/cobigen/cobigen-core-api/src/test/java/com/devonfw/cobigen/api/TemplatesJarUtilTest.java b/cobigen/cobigen-core-api/src/test/java/com/devonfw/cobigen/api/TemplatesJarUtilTest.java
new file mode 100644
index 0000000000..5e80f34f14
--- /dev/null
+++ b/cobigen/cobigen-core-api/src/test/java/com/devonfw/cobigen/api/TemplatesJarUtilTest.java
@@ -0,0 +1,40 @@
+package com.devonfw.cobigen.api;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+import java.nio.file.Path;
+import java.nio.file.Paths;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TemporaryFolder;
+
+import com.devonfw.cobigen.api.constants.ConfigurationConstants;
+import com.devonfw.cobigen.api.util.TemplatesJarUtil;
+
+public class TemplatesJarUtilTest {
+ /**
+ * Temp folder for test execution
+ */
+ @Rule
+ public TemporaryFolder temp = new TemporaryFolder();
+
+ /** Testdata root path */
+ private static final String testdataRoot = "src/test/resources/testdata/unittest/MavenUtilTest";
+
+ /**
+ * Tests to check if a correct cache will be validated right
+ *
+ * @throws Exception
+ */
+ @Test
+ public void testDownloadFile() throws Exception {
+
+ Path tempFolder = this.temp.newFolder(ConfigurationConstants.TEMPLATE_SETS_FOLDER).toPath();
+ String test = TemplatesJarUtil.downloadJarFromURL(
+ "https://repo1.maven.org/maven2/com/devonfw/cobigen/templates-devon4j/2021.12.006/templates-devon4j-2021.12.006.pom",
+ tempFolder);
+ assertThat(Paths.get(test)).exists();
+
+ }
+}
diff --git a/cobigen/cobigen-core/src/main/java/com/devonfw/cobigen/impl/util/ArtifactRetrieverUtil.java b/cobigen/cobigen-core/src/main/java/com/devonfw/cobigen/impl/util/ArtifactRetrieverUtil.java
new file mode 100644
index 0000000000..22f77f2112
--- /dev/null
+++ b/cobigen/cobigen-core/src/main/java/com/devonfw/cobigen/impl/util/ArtifactRetrieverUtil.java
@@ -0,0 +1,125 @@
+package com.devonfw.cobigen.impl.util;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.URL;
+import java.nio.file.DirectoryStream;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.devonfw.cobigen.api.constants.ConfigurationConstants;
+import com.devonfw.cobigen.api.util.CobiGenPaths;
+import com.devonfw.cobigen.api.util.TemplatesJarUtil;
+import com.devonfw.cobigen.impl.config.entity.io.TemplateSetConfiguration;
+import com.devonfw.cobigen.impl.config.reader.TemplateSetConfigurationReader;
+
+public class ArtifactRetrieverUtil {
+
+ private static final Logger LOG = LoggerFactory.getLogger(ArtifactRetrieverUtil.class);
+
+ /** Path to artifact cache folder **/
+ private static Path artifactCachePath = CobiGenPaths.getTemplateSetsFolderPath()
+ .resolve(ConfigurationConstants.TEMPLATE_SET_ARTIFACT_CACHE_FOLDER);
+
+ /**
+ * Downloads template set artifacts from given URLs
+ *
+ * @param artifactUrls List of URLs
+ * @return List of artifact Paths
+ */
+ public static List downloadArtifactsFromUrls(List artifactUrls) {
+
+ List artifactPaths = new ArrayList<>();
+ for (URL url : artifactUrls) {
+ artifactPaths.add(Paths.get(TemplatesJarUtil.downloadJarFromURL(url.toString(), artifactCachePath)));
+
+ }
+
+ return artifactPaths;
+ }
+
+ /**
+ * Retrieves the artifact cache path
+ *
+ * @return Path to artifact cache folder
+ */
+ public static Path retrieveArtifactCachePath() {
+
+ Path artifactCacheFolder = CobiGenPaths.getTemplateSetsFolderPath()
+ .resolve(ConfigurationConstants.TEMPLATE_SET_ARTIFACT_CACHE_FOLDER);
+ return artifactCacheFolder;
+ }
+
+ /**
+ * Checks is a directory is empty
+ *
+ * @param path directory to check
+ * @return true if empty, false if not
+ * @throws IOException
+ */
+ private static boolean isEmpty(Path path) throws IOException {
+
+ if (Files.isDirectory(path)) {
+ try (DirectoryStream directory = Files.newDirectoryStream(path)) {
+ return !directory.iterator().hasNext();
+ } catch (IOException e) {
+ LOG.debug("An error occurred while checking if the directory {} was empty", path, e);
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * Retrieves a list of {@link TemplateSetConfiguration} from the template set artifact cache
+ *
+ * @param cachedArtifacts List of template set artifact paths
+ *
+ * @return List of {@link TemplateSetConfiguration}
+ */
+ public static List retrieveArtifactsFromCache(List cachedArtifacts) {
+
+ List templateSetConfigurations = new ArrayList<>();
+
+ if (cachedArtifacts == null) {
+
+ Path artifactCacheFolder = retrieveArtifactCachePath();
+ try {
+ if (!Files.exists(artifactCacheFolder) || isEmpty(artifactCacheFolder)) {
+ return null;
+ }
+ } catch (IOException e) {
+ LOG.error("An error occurred while checking the artifact cache directory {}", artifactCacheFolder, e);
+ return null;
+ }
+
+ List artfactList = Arrays.asList(artifactCacheFolder.toFile().listFiles());
+ for (File file : artfactList) {
+ TemplateSetConfigurationReader reader = new TemplateSetConfigurationReader(file.toPath());
+ reader.readConfiguration(file.toPath());
+
+ TemplateSetConfiguration templateSetConfiguration = reader.getTemplateSetConfiguration();
+ templateSetConfigurations.add(templateSetConfiguration);
+ }
+ return templateSetConfigurations;
+ }
+
+ for (Path file : cachedArtifacts) {
+ TemplateSetConfigurationReader reader = new TemplateSetConfigurationReader(file);
+ reader.readConfiguration(file);
+
+ TemplateSetConfiguration templateSetConfiguration = reader.getTemplateSetConfiguration();
+ templateSetConfigurations.add(templateSetConfiguration);
+ }
+
+ return templateSetConfigurations;
+
+ }
+}
diff --git a/cobigen/cobigen-core/src/test/java/com/devonfw/cobigen/unittest/templates/TemplateJarDownloaderTest.java b/cobigen/cobigen-core/src/test/java/com/devonfw/cobigen/unittest/templates/TemplateJarDownloaderTest.java
index 87ed5329af..ebbfa21dc1 100644
--- a/cobigen/cobigen-core/src/test/java/com/devonfw/cobigen/unittest/templates/TemplateJarDownloaderTest.java
+++ b/cobigen/cobigen-core/src/test/java/com/devonfw/cobigen/unittest/templates/TemplateJarDownloaderTest.java
@@ -149,7 +149,7 @@ public void testDownloadTemplatesWithLATEST() {
public void testDownloadTemplates() throws Exception {
// preparation
- File adapted = this.tempFolder.newFolder("templateLocation/adapted");
+ File adapted = this.tempFolder.newFolder("templateLocation", "adapted");
this.mavenCoordinatesList.add(new MavenCoordinate("com.group", "artifact-id", "1.0"));
this.mavenCoordinatesList.add(new MavenCoordinate("some.group", "some-artifact", "2.01"));
this.mavenCoordinatesList.add(createMavenCoordinateForDevon4jTemplates(null));
@@ -173,7 +173,7 @@ public void testDownloadTemplates() throws Exception {
public void testDownloadTemplatesAlreadyAdapted() throws Exception {
// preparation
- File adapted = this.tempFolder.newFolder("templateLocation/adapted");
+ File adapted = this.tempFolder.newFolder("templateLocation", "adapted");
this.mavenCoordinatesList.add(new MavenCoordinate("com.group", "artifact-id", "1.0"));
this.mavenCoordinatesList.add(new MavenCoordinate("some.group", "some-artifact", "2.01"));
this.mavenCoordinatesList.add(new MavenCoordinate("com.com", "app-app", "87"));
diff --git a/cobigen/core-artifact-retriever/pom.xml b/cobigen/core-artifact-retriever/pom.xml
index e25d97998f..e22bb295bd 100644
--- a/cobigen/core-artifact-retriever/pom.xml
+++ b/cobigen/core-artifact-retriever/pom.xml
@@ -77,5 +77,7 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/x
core-api
+
+
\ No newline at end of file
diff --git a/cobigen/core-artifact-retriever/src/main/java/com/devonfw/cobigen/retriever/ArtifactRetriever.java b/cobigen/core-artifact-retriever/src/main/java/com/devonfw/cobigen/retriever/ArtifactRetriever.java
index 170d6ed1b7..a3363fd6bb 100644
--- a/cobigen/core-artifact-retriever/src/main/java/com/devonfw/cobigen/retriever/ArtifactRetriever.java
+++ b/cobigen/core-artifact-retriever/src/main/java/com/devonfw/cobigen/retriever/ArtifactRetriever.java
@@ -65,7 +65,7 @@ public static List retrieveTemplateSetJarDownloadURLs(List group
* @return list of maven artifact download URLs
*
*/
- protected static List retrieveTemplateSetXmlDownloadLinks(List groupIdsList, String mavenSettings) {
+ public static List retrieveTemplateSetXmlDownloadLinks(List groupIdsList, String mavenSettings) {
List downloadLinks = new ArrayList<>();
@@ -99,9 +99,7 @@ protected static List retrieveTemplateSetXmlDownloadLinks(List grou
downloadLinks.addAll(
retrieveArtifactsFromRepository(groupIdsList, null, null, new ArrayList()));
}
-
return downloadLinks;
-
}
/**
diff --git a/cobigen/gui/pom.xml b/cobigen/gui/pom.xml
new file mode 100644
index 0000000000..6cb4ff1acf
--- /dev/null
+++ b/cobigen/gui/pom.xml
@@ -0,0 +1,115 @@
+
+ 4.0.0
+ gui
+ jar
+
+
+ com.devonfw.cobigen
+ core-parent
+ ${revision}
+
+
+
+ false
+ UTF-8
+ 11
+ 11
+ 19
+ 0.0.6
+
+
+
+
+ org.openjfx
+ javafx-controls
+ ${javafx.version}
+
+
+ org.openjfx
+ javafx-fxml
+ ${javafx.version}
+
+
+ junit
+ junit
+ 4.13.1
+
+
+ org.testfx
+ testfx-core
+ 4.0.16-alpha
+ test
+
+
+ org.testfx
+ testfx-junit
+ 4.0.15-alpha
+ test
+
+
+ org.assertj
+ assertj-core
+ 3.13.2
+ test
+
+
+ org.kordamp.ikonli
+ ikonli-javafx
+ 11.3.5
+
+
+ org.kordamp.ikonli
+ ikonli-materialdesign-pack
+ 11.3.5
+
+
+ com.devonfw.cobigen
+ core-artifact-retriever
+ ${revision}
+
+
+ com.devonfw.cobigen
+ core
+ ${revision}
+
+
+ com.github.stefanbirkner
+ system-lambda
+ 1.2.0
+ test
+
+
+ com.devonfw.cobigen
+ core-test
+ test
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+
+ ${maven.compiler.release}
+
+
+
+ org.openjfx
+ javafx-maven-plugin
+ ${javafx.maven.plugin.version}
+
+ com.devonfw.cobigen.gui.App
+
+
+
+ org.apache.maven.plugins
+ maven-surefire-plugin
+
+
+ false
+
+
+
+
+
\ No newline at end of file
diff --git a/cobigen/gui/src/main/java/com/devonfw/cobigen/gui/App.java b/cobigen/gui/src/main/java/com/devonfw/cobigen/gui/App.java
new file mode 100644
index 0000000000..b499cc3b84
--- /dev/null
+++ b/cobigen/gui/src/main/java/com/devonfw/cobigen/gui/App.java
@@ -0,0 +1,91 @@
+package com.devonfw.cobigen.gui;
+
+import java.io.IOException;
+import java.util.concurrent.CountDownLatch;
+
+import javafx.application.Application;
+import javafx.fxml.FXMLLoader;
+import javafx.scene.Parent;
+import javafx.scene.Scene;
+import javafx.scene.image.Image;
+import javafx.stage.Stage;
+import javafx.stage.StageStyle;
+
+/**
+ * TODO nneuhaus This type ...
+ *
+ */
+public class App extends Application {
+
+ /**
+ * latch for waiting for the app
+ */
+ public static final CountDownLatch latch = new CountDownLatch(1);
+
+ /**
+ * The app itself
+ */
+ public static App app = null;
+
+ /**
+ * The scene to set in the window
+ */
+ private static Scene scene;
+
+ /**
+ * The window to show in the app
+ */
+ public Stage window;
+
+ /**
+ * @return the app when it is ready
+ */
+ public static App waitForApp() {
+
+ try {
+ latch.await();
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ return app;
+ }
+
+ /**
+ * Sets the given app as the general app
+ *
+ * @param app0 gets set as the app
+ */
+ public static void setApp(App app0) {
+
+ app = app0;
+ latch.countDown();
+ }
+
+ /**
+ * The constructor.
+ */
+ public App() {
+
+ setApp(this);
+ }
+
+ @Override
+ public void start(Stage primaryStage) throws IOException {
+
+ this.window = new Stage();
+ Parent root = FXMLLoader.load(getClass().getResource("fxml/Primary.fxml"));
+
+ App.scene = new Scene(root);
+ App.scene.getStylesheets().add(getClass().getResource("styles.css").toExternalForm());
+
+ Image image = new Image(App.class.getResource("icons/devon-icon.jpg").toExternalForm());
+ this.window.setTitle("Template Set Manager");
+ this.window.getIcons().add(image);
+ this.window.initStyle(StageStyle.TRANSPARENT);
+ this.window.setResizable(true);
+
+ this.window.setScene(App.scene);
+ this.window.showAndWait();
+ }
+
+}
diff --git a/cobigen/gui/src/main/java/com/devonfw/cobigen/gui/AppLauncher.java b/cobigen/gui/src/main/java/com/devonfw/cobigen/gui/AppLauncher.java
new file mode 100644
index 0000000000..f2fcf3ecdd
--- /dev/null
+++ b/cobigen/gui/src/main/java/com/devonfw/cobigen/gui/AppLauncher.java
@@ -0,0 +1,35 @@
+package com.devonfw.cobigen.gui;
+
+/**
+ * TODO nneuhaus This type ...
+ *
+ */
+public class AppLauncher {
+
+ public App app;
+
+ public AppLauncher() {
+
+ new Thread() {
+ @Override
+ public void run() {
+
+ javafx.application.Application.launch(App.class);
+ }
+ }.start();
+ this.app = App.waitForApp();
+ }
+
+ public static void main(String[] args) {
+
+ new Thread() {
+ @Override
+ public void run() {
+
+ javafx.application.Application.launch(App.class);
+ }
+ }.start();
+ App app = App.waitForApp();
+ }
+
+}
diff --git a/cobigen/gui/src/main/java/com/devonfw/cobigen/gui/Controller.java b/cobigen/gui/src/main/java/com/devonfw/cobigen/gui/Controller.java
new file mode 100644
index 0000000000..a9272bfca3
--- /dev/null
+++ b/cobigen/gui/src/main/java/com/devonfw/cobigen/gui/Controller.java
@@ -0,0 +1,200 @@
+package com.devonfw.cobigen.gui;
+
+import java.io.IOException;
+import java.net.URL;
+import java.util.List;
+import java.util.ResourceBundle;
+
+import com.devonfw.cobigen.gui.controllers.DetailsController;
+import com.devonfw.cobigen.gui.controllers.HomeController;
+import com.devonfw.cobigen.gui.controllers.MenuController;
+import com.devonfw.cobigen.gui.services.TreeViewBuilder;
+import com.devonfw.cobigen.impl.config.entity.io.Increment;
+import com.devonfw.cobigen.impl.config.entity.io.TemplateSetConfiguration;
+
+import javafx.event.ActionEvent;
+import javafx.fxml.FXML;
+import javafx.fxml.Initializable;
+import javafx.scene.Parent;
+import javafx.scene.control.Button;
+import javafx.scene.input.MouseEvent;
+import javafx.scene.layout.AnchorPane;
+import javafx.scene.layout.Pane;
+import javafx.stage.Stage;
+
+/**
+ * Controller for the Template Set Management GUI
+ */
+public class Controller implements Initializable {
+ /*
+ * home Controller to show home page
+ */
+ @FXML
+ private Parent home;
+
+ /*
+ * Details Controller for template set details
+ */
+ @FXML
+ private Parent details;
+
+ @FXML
+ public MenuController menuController;
+
+ @FXML
+ private HomeController homeController;
+
+ @FXML
+ public DetailsController detailsController;
+
+ // deals with menu.fxml
+ @FXML
+ private AnchorPane leftPane;
+
+ @FXML
+ private AnchorPane searchPane;
+
+ @FXML
+ private AnchorPane rightPane;
+
+ @FXML
+ private AnchorPane detailsPane;
+
+ // top bit of the gui
+ @FXML
+ private Pane topPane;
+
+ @FXML
+ private Button closeButton;
+
+ @FXML
+ private Button minButton;
+
+ @FXML
+ private Button minMaxButton;
+
+ private double xOffset = 0;
+
+ private double yOffset = 0;
+
+ /**
+ * Initial View
+ */
+ @Override
+ public void initialize(URL arg0, ResourceBundle arg1) {
+
+ this.menuController.injectController(this);
+ }
+
+ /**
+ * @param actionEvent
+ * @throws IOException
+ */
+ @FXML
+ public void loadHome(javafx.event.ActionEvent actionEvent) throws IOException {
+
+ this.details.setVisible(false);
+ this.home.setVisible(true);
+ this.menuController.clearSearchResults();
+ this.menuController.searchResultsView.getSelectionModel().clearSelection();
+ }
+
+ /**
+ * Load increment from selected template-set from observable list
+ *
+ * @throws IOException
+ */
+ public void loadDetails() throws IOException {
+
+ // selected from observable list
+ TemplateSetConfiguration selectedItem = this.menuController.searchResultsView.getSelectionModel().getSelectedItem();
+ // changing visibility between scenes
+ if (selectedItem == null) {
+ this.home.setVisible(true);
+ this.details.setVisible(false);
+ } else {
+ this.home.setVisible(false);
+ this.details.setVisible(true);
+
+ // Getting the tree view of increments of selected template set
+
+ // Extract all increments from selected templateSet in list
+ List templatesetIncrements = selectedItem.getTemplatesConfiguration().getIncrements().getIncrement();
+
+ // shows the tree view of increments of selected template set
+ this.detailsController.showTreeView(TreeViewBuilder.buildTreeView(templatesetIncrements));
+
+ // TODO
+ this.detailsController.showName(selectedItem.getVersion().toString());
+
+ // retrieving template-Set selected and pass it to details Controller
+ this.detailsController
+ .setTemplateSet(this.menuController.searchResultsView.getSelectionModel().getSelectedItem());
+
+ // updates the install button text
+ this.detailsController.updateTemplateSetInstallStatus();
+
+ }
+
+ }
+
+ /**
+ * @param event: click on the x Button
+ */
+ @FXML
+ protected void handleCloseAction(ActionEvent event) {
+
+ // get the current stage
+ Stage stage = (Stage) this.closeButton.getScene().getWindow();
+ // close the window
+ stage.close();
+ }
+
+ /**
+ * @param event : click on the Button to switch window view
+ */
+ @FXML
+ protected void handleMinMaxAction(ActionEvent event) {
+
+ // get the current stage
+ Stage stage = (Stage) this.minMaxButton.getScene().getWindow();
+ // if window is full screen, make it smaller
+ // if it is a small window, make it full screen
+ if (stage.isMaximized()) {
+ stage.setMaximized(false);
+ } else {
+ stage.setMaximized(true);
+ }
+
+ }
+
+ /**
+ * @param event : click on the minimize Button
+ */
+ @FXML
+ protected void handleMinAction(ActionEvent event) {
+
+ // this minimizes the window, can be reopened by clicking in the icon in the task bar
+ // TODO: fix animation if possible?
+ Stage stage = (Stage) this.minButton.getScene().getWindow();
+ stage.setIconified(true);
+
+ }
+
+ @FXML
+ protected void handleClickAction(MouseEvent event) {
+
+ Stage stage = (Stage) this.topPane.getScene().getWindow();
+ this.xOffset = stage.getX() - event.getScreenX();
+ this.yOffset = stage.getY() - event.getScreenY();
+ }
+
+ @FXML
+ protected void handleMovementAction(MouseEvent event) {
+
+ Stage stage = (Stage) this.topPane.getScene().getWindow();
+
+ stage.setX(event.getScreenX() + this.xOffset);
+ stage.setY(event.getScreenY() + this.yOffset);
+ }
+}
diff --git a/cobigen/gui/src/main/java/com/devonfw/cobigen/gui/controllers/DetailsController.java b/cobigen/gui/src/main/java/com/devonfw/cobigen/gui/controllers/DetailsController.java
new file mode 100644
index 0000000000..50558dfa92
--- /dev/null
+++ b/cobigen/gui/src/main/java/com/devonfw/cobigen/gui/controllers/DetailsController.java
@@ -0,0 +1,215 @@
+package com.devonfw.cobigen.gui.controllers;
+
+import java.net.URL;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.ResourceBundle;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.devonfw.cobigen.api.constants.ConfigurationConstants;
+import com.devonfw.cobigen.api.util.CobiGenPaths;
+import com.devonfw.cobigen.api.util.MavenCoordinate;
+import com.devonfw.cobigen.api.util.TemplatesJarUtil;
+import com.devonfw.cobigen.impl.config.entity.io.TemplateSetConfiguration;
+import com.devonfw.cobigen.retriever.ArtifactRetriever;
+
+import javafx.fxml.FXML;
+import javafx.fxml.Initializable;
+import javafx.scene.control.Alert;
+import javafx.scene.control.Alert.AlertType;
+import javafx.scene.control.Button;
+import javafx.scene.control.Label;
+import javafx.scene.control.TreeView;
+import javafx.scene.layout.AnchorPane;
+import javafx.scene.text.Text;
+
+/**
+ * TODO nneuhaus This type ...
+ *
+ */
+public class DetailsController implements Initializable {
+
+ private static final Logger LOG = LoggerFactory.getLogger(ArtifactRetriever.class);
+
+ // TODO: getIncrements()
+ private List INCREMENTS = new ArrayList<>();
+
+ private TemplateSetConfiguration templateSet;
+
+ @FXML
+ Label titleLabel;
+
+ @FXML
+ Text descriptionText;
+
+ @FXML
+ Button installButton;
+
+ @FXML
+ AnchorPane treeViewPane;
+
+ @Override
+ public void initialize(URL location, ResourceBundle resources) {
+
+ // increment section of the gui
+ showVersion();
+ // showTreeView(TreeViewBuilder.buildTreeView(TreeViewBuilder.transformIncrementsToArray(this.INCREMENTS)));
+
+ }
+
+ /**
+ * Sets text of install button to Installed
+ */
+ public void updateTemplateSetInstallStatus() {
+
+ Path templateSetPath = retrieveJarPathFromTemplateSet();
+ if (Files.exists(templateSetPath)) {
+ this.installButton.setText("Installed");
+ } else {
+ this.installButton.setText("Install");
+ }
+
+ }
+
+ /**
+ * returns an instance of selected template Set to be operated on
+ *
+ * @return templateSet
+ */
+ public TemplateSetConfiguration getTemplateSet() {
+
+ return this.templateSet;
+ }
+
+ /**
+ * Set the instance of selected template Set
+ *
+ * @param templateSet new value of {@link #gettemplateSet}.
+ */
+ public void setTemplateSet(TemplateSetConfiguration templateSet) {
+
+ this.templateSet = templateSet;
+ }
+
+ /**
+ *
+ */
+ public void showName(String name) {
+
+ this.titleLabel.setText(name);
+
+ }
+
+ /**
+ *
+ */
+ private void showVersion() {
+
+ // is it the version used in templateSet or the snapshot version?
+ // TODO: getVersion()
+
+ }
+
+ /**
+ * @param treeView
+ */
+ public void showTreeView(TreeView treeView) {
+
+ treeView.setId("treeView");
+ AnchorPane.setTopAnchor(treeView, 0.0);
+ AnchorPane.setRightAnchor(treeView, 0.0);
+ AnchorPane.setBottomAnchor(treeView, 0.0);
+ AnchorPane.setLeftAnchor(treeView, 0.0);
+ this.treeViewPane.getChildren().add(treeView);
+ }
+
+ /**
+ * Retrieves the jar file path from the selected template set
+ *
+ * @return Path to template set jar
+ */
+ private Path retrieveJarPathFromTemplateSet() {
+
+ // Retrieve template set name information from trigger
+ String triggerName = this.templateSet.getContextConfiguration().getTrigger().get(0).getId();
+ String mavenArtfifactId = triggerName.replace("_", "-");
+ String templateSetVersion = this.templateSet.getVersion().toString();
+ Path templateSetsPath = CobiGenPaths.getTemplateSetsFolderPath();
+
+ // Adjust file name
+ String FileName = mavenArtfifactId + "-" + templateSetVersion + ".jar";
+ Path jarFilePath = templateSetsPath.resolve(ConfigurationConstants.DOWNLOADED_FOLDER).resolve(FileName);
+
+ return jarFilePath;
+ }
+
+ /**
+ * Installs a template set into the template-sets/downloaded folder
+ *
+ * @param actionEvent the action event
+ */
+ @FXML
+ public void installTemplateSet(javafx.event.ActionEvent actionEvent) {
+
+ // Retrieve template set name information from trigger
+ String triggerName = this.templateSet.getContextConfiguration().getTrigger().get(0).getId();
+ String mavenArtfifactId = triggerName.replace("_", "-");
+ String templateSetVersion = this.templateSet.getVersion().toString();
+
+ // Adjust file name
+ String FileName = mavenArtfifactId + "-" + templateSetVersion + ".jar";
+
+ Path templateSetsPath = CobiGenPaths.getTemplateSetsFolderPath();
+
+ // prepare MavenCoordinate list for download
+ MavenCoordinate mavenCoordinate = new MavenCoordinate(
+ ConfigurationConstants.CONFIG_PROPERTY_TEMPLATE_SETS_DEFAULT_GROUPID, mavenArtfifactId, templateSetVersion);
+ List mavenCoordinateList = new ArrayList<>();
+ mavenCoordinateList.add(mavenCoordinate);
+
+ Path expectedJarFilePath = templateSetsPath.resolve(ConfigurationConstants.DOWNLOADED_FOLDER).resolve(FileName);
+
+ if (!Files.exists(expectedJarFilePath)) {
+ // Download template set class file into downloaded folder
+ TemplatesJarUtil.downloadTemplatesByMavenCoordinates(
+ templateSetsPath.resolve(ConfigurationConstants.DOWNLOADED_FOLDER), mavenCoordinateList);
+ // TODO: update installButton title to Installed and save this state
+ updateTemplateSetInstallStatus();
+ } else {
+ // Alert window if the file is already installed
+ Alert alert = new Alert(AlertType.CONFIRMATION);
+ alert.setTitle("Confirmation");
+ alert.setHeaderText("The selected template-set is already installed!");
+ alert.show();
+ }
+ }
+
+ /**
+ * @param actionEvent
+ */
+ @FXML
+ public void updateTemplateSet(javafx.event.ActionEvent actionEvent) {
+
+ // what model is previous and whats the new one
+ // new version rein packen
+
+ // TODO
+ }
+
+ /**
+ * @param actionEvent
+ */
+ @FXML
+ public void uninstallTemplateSet(javafx.event.ActionEvent actionEvent) {
+
+ // what is referred to by the word uninstall.
+ // Delete template set from user ordenr
+
+ // TODO
+ }
+
+}
diff --git a/cobigen/gui/src/main/java/com/devonfw/cobigen/gui/controllers/HomeController.java b/cobigen/gui/src/main/java/com/devonfw/cobigen/gui/controllers/HomeController.java
new file mode 100644
index 0000000000..b3f491848e
--- /dev/null
+++ b/cobigen/gui/src/main/java/com/devonfw/cobigen/gui/controllers/HomeController.java
@@ -0,0 +1,85 @@
+package com.devonfw.cobigen.gui.controllers;
+
+import java.awt.Desktop;
+import java.io.IOException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.util.ResourceBundle;
+
+import com.devonfw.cobigen.gui.App;
+
+import javafx.fxml.FXML;
+import javafx.fxml.Initializable;
+import javafx.scene.Scene;
+import javafx.scene.control.MenuButton;
+import javafx.scene.layout.AnchorPane;
+
+/**
+ * TODO nneuhaus This type ...
+ *
+ */
+public class HomeController implements Initializable {
+
+ @FXML
+ AnchorPane homePane;
+
+ @FXML
+ AnchorPane treeViewPane;
+
+ @FXML
+ MenuButton settings;
+
+ private String[] EXAMPLE_LIST = { "Title of Increment 1", "Description of Increment 1", "Title of Increment 2",
+ "Description of Increment 2", "Title of Increment 3", "Description of Increment 3" };
+
+ private String lightTheme = App.class.getResource("styles.css").toExternalForm();
+
+ private String darkTheme = App.class.getResource("dark_theme.css").toExternalForm();
+
+ @Override
+ public void initialize(URL location, ResourceBundle resources) {
+
+ // Increment increment1 = new Increment();
+ // increment1.setName("Title of Increment 1");
+ // increment1.setDescription("Description of Increment 1");
+ // Increment increment2 = new Increment();
+ // increment2.setName("Title of Increment 2");
+ // increment2.setDescription("Description of Increment 2");
+ // Increment increment3 = new Increment();
+ // increment3.setName("Title of Increment 3");
+ // increment3.setDescription("Description of Increment 3");
+ // // Build the tree view
+ // TreeView treeView = TreeViewBuilder.buildTreeView(this.EXAMPLE_LIST);
+ // treeView.setId("treeView");
+ // AnchorPane.setTopAnchor(treeView, 0.0);
+ // AnchorPane.setRightAnchor(treeView, 0.0);
+ // AnchorPane.setBottomAnchor(treeView, 0.0);
+ // AnchorPane.setLeftAnchor(treeView, 0.0);
+ // this.treeViewPane.getChildren().add(treeView);
+ }
+
+ /**
+ * @param actionEvent
+ * @throws IOException
+ * @throws URISyntaxException
+ */
+ @FXML
+ public void openWiki(javafx.event.ActionEvent actionEvent) throws IOException, URISyntaxException {
+
+ Desktop.getDesktop().browse(new URI("https://github.com/devonfw/cobigen/wiki"));
+ }
+
+ public void changeTheme(javafx.event.ActionEvent actionEvent) throws IOException {
+
+ Scene scene = this.treeViewPane.getScene();
+
+ if (scene.getStylesheets().contains(this.lightTheme)) {
+ scene.getStylesheets().remove(this.lightTheme);
+ scene.getStylesheets().add(this.darkTheme);
+ } else {
+ scene.getStylesheets().remove(this.darkTheme);
+ scene.getStylesheets().add(this.lightTheme);
+ }
+ }
+}
diff --git a/cobigen/gui/src/main/java/com/devonfw/cobigen/gui/controllers/MenuController.java b/cobigen/gui/src/main/java/com/devonfw/cobigen/gui/controllers/MenuController.java
new file mode 100644
index 0000000000..45523bfe91
--- /dev/null
+++ b/cobigen/gui/src/main/java/com/devonfw/cobigen/gui/controllers/MenuController.java
@@ -0,0 +1,253 @@
+package com.devonfw.cobigen.gui.controllers;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.URL;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.ListIterator;
+import java.util.ResourceBundle;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.devonfw.cobigen.api.constants.ConfigurationConstants;
+import com.devonfw.cobigen.api.util.CobiGenPaths;
+import com.devonfw.cobigen.api.util.MavenCoordinate;
+import com.devonfw.cobigen.api.util.MavenUtil;
+import com.devonfw.cobigen.gui.Controller;
+import com.devonfw.cobigen.gui.model.TemplateSetModel;
+import com.devonfw.cobigen.gui.services.TemplateSetCell;
+import com.devonfw.cobigen.impl.config.entity.io.TemplateSetConfiguration;
+import com.devonfw.cobigen.impl.util.ArtifactRetrieverUtil;
+import com.devonfw.cobigen.retriever.ArtifactRetriever;
+
+import javafx.collections.FXCollections;
+import javafx.collections.ObservableList;
+import javafx.collections.transformation.FilteredList;
+import javafx.fxml.FXML;
+import javafx.fxml.Initializable;
+import javafx.scene.control.Button;
+import javafx.scene.control.ListView;
+import javafx.scene.control.TextField;
+
+/**
+ * TODO nneuhaus This type ...
+ *
+ */
+public class MenuController implements Initializable {
+
+ /** Logger instance */
+ private static final Logger LOG = LoggerFactory.getLogger(MenuController.class);
+
+ @FXML
+ private Controller controller;
+
+ @FXML
+ public Button homeButton;
+
+ @FXML
+ public TextField searchBar;
+
+ @FXML
+ public Button clearSearchResultsButton;
+
+ @FXML
+ public Button goSearch;
+
+ @FXML
+ public ListView searchResultsView;
+
+ /**
+ * The constructor.
+ */
+ public MenuController() {
+
+ // Where do we need tags
+ // List tagsList = new ArrayList<>();
+ // tagsList.addAll(templateSet.getTemplateSetConfiguration().getContextConfiguration().getTags().getTagsList());
+ }
+
+ /**
+ * Method to get a reference to the main controller
+ */
+ public void injectController(Controller controller) {
+
+ this.controller = controller;
+ }
+
+ /**
+ * Initial method when controller gets activated
+ */
+ @Override
+ public void initialize(URL location, ResourceBundle resources) {
+
+ // the line below sets up the template set cells in observable list
+ this.searchResultsView.setCellFactory(resultsView -> new TemplateSetCell());
+
+ this.homeButton.setOnAction(event -> {
+ try {
+ this.controller.loadHome(event);
+ } catch (IOException e) {
+ LOG.error("An error occurred while loading the home page", e);
+ }
+ });
+
+ Path artifactCachePath = CobiGenPaths.getTemplateSetsFolderPath()
+ .resolve(ConfigurationConstants.TEMPLATE_SET_ARTIFACT_CACHE_FOLDER);
+ List cachedArtifacts = new ArrayList<>();
+ if (!Files.exists(artifactCachePath)) {
+ try {
+ Files.createDirectory(artifactCachePath);
+ } catch (IOException e) {
+ LOG.error("An error occurred while creating the artifact cache directory", e);
+ }
+ } else {
+
+ for (File artifact : Arrays.asList(artifactCachePath.toFile().listFiles())) {
+ cachedArtifacts.add(artifact.toPath());
+ }
+ }
+
+ // TODO: read CobiGen properties
+ refresh();
+
+ // Load increments of selected template set
+ // call back functions
+ this.searchResultsView.setOnMouseClicked(event -> {
+
+ try {
+ MenuController.this.controller.loadDetails();
+ } catch (IOException e) {
+ LOG.error("An error occurred while loading the details page", e);
+ }
+
+ });
+
+ // Initialize filtered List
+
+ ObservableList listCopy = TemplateSetModel.getInstance().getTemplateSetObservableList();
+ FilteredList filteredData = new FilteredList<>(
+ TemplateSetModel.getInstance().getTemplateSetObservableList(), b -> true);
+
+ // look after the searched text in search bar
+ this.searchBar.textProperty().addListener((observable, oldValue, newValue) -> {
+ filteredData.setPredicate(templateSets -> {
+ // if no search value, then display all records or whatever records it currently has, no changes
+ if (newValue.isEmpty() || newValue.isBlank() || newValue == null) {
+ return true;
+ }
+
+ String searchKeyword = newValue.toLowerCase();
+ // found a match in the name
+ // if (templateSets.getName().toLowerCase().indexOf(searchKeyword) > -1) {
+ // return true;
+ // }
+ // add more if statements of this form
+ // if more search relevant attributes are added to the TemplateSet Class!
+
+ // else
+ return false;
+ });
+
+ this.searchResultsView.setItems(filteredData);
+
+ });
+
+ }
+
+ /**
+ * Update list view of template sets and their installation status
+ */
+ @FXML
+ public void refresh() {
+ // check if clear the list is needed
+
+ Path artifactCachePath = CobiGenPaths.getTemplateSetsFolderPath()
+ .resolve(ConfigurationConstants.TEMPLATE_SET_ARTIFACT_CACHE_FOLDER);
+ List cachedArtifacts = new ArrayList<>();
+ if (!Files.exists(artifactCachePath)) {
+ try {
+ Files.createDirectory(artifactCachePath);
+ } catch (IOException e) {
+ LOG.error("An error occurred while creating the artifact cache directory", e);
+ }
+ } else {
+
+ for (File artifact : Arrays.asList(artifactCachePath.toFile().listFiles())) {
+ cachedArtifacts.add(artifact.toPath());
+ }
+ }
+
+ // TODO: read CobiGen properties
+ List groupIds = Arrays.asList(ConfigurationConstants.CONFIG_PROPERTY_TEMPLATE_SETS_DEFAULT_GROUPID);
+ List urlList = ArtifactRetriever.retrieveTemplateSetXmlDownloadLinks(groupIds,
+ MavenUtil.determineMavenSettings());
+
+ // check for Update
+ // TODO error handling with replace all and maybe jar is corrupted just replace it
+ // also try to export this to other functions
+ List cachedMavenCoordinates = new ArrayList<>();
+ for (Path p : cachedArtifacts) {
+ String version = p.getFileName().toString().replaceAll("-template-set.xml", "")
+ .replaceAll("^(([a-zA-z]+[\\w]-)+)", "");
+ String artifactID = p.getFileName().toString().replaceAll("-template-set.xml", "").replaceAll("-" + version, "");
+ cachedMavenCoordinates.add(new MavenCoordinate(null, artifactID, version));
+ }
+ ListIterator iterator = urlList.listIterator();
+ while (iterator.hasNext()) {
+ String maven = iterator.next().getFile().replaceAll("-template-set.xml", "");
+ String version = maven.replaceAll("^(([a-zA-z]+[\\w]-)+)", "");
+ String artifactID = maven.replaceAll("-" + version, "");
+ MavenCoordinate repo = new MavenCoordinate(null, artifactID, version);
+ for (MavenCoordinate cached : cachedMavenCoordinates) {
+ if (cached.getArtifactId().equals(repo.getArtifactId())) {
+ int result = cached.compareTo(repo);
+ if (result <= 0) {
+ // no download needed
+ iterator.remove();
+ } else {
+ // download needed ccan be removed, leave it for debugging pruposes
+ }
+ }
+ }
+ }
+
+ List downloadedArtifacts = ArtifactRetrieverUtil.downloadArtifactsFromUrls(urlList);
+
+ List templateSetConfigurations;
+ if (downloadedArtifacts.isEmpty()) {
+ templateSetConfigurations = ArtifactRetrieverUtil.retrieveArtifactsFromCache(null);
+ } else {
+ templateSetConfigurations = ArtifactRetrieverUtil.retrieveArtifactsFromCache(downloadedArtifacts);
+ }
+ ObservableList observableList = FXCollections.observableArrayList();
+
+ if (templateSetConfigurations != null) {
+ observableList.addAll(templateSetConfigurations);
+ this.searchResultsView.setItems(observableList);
+ }
+
+ }
+
+ /**
+ * Called when clearSearchResultsButton is clicked
+ */
+ @FXML
+ public void clearSearchResults() {
+
+ this.searchBar.clear();
+
+ // TODO: Should we show the Home Page when clearSearchResultsButton is clicked?
+ // try {
+ // this.controller.loadHome(null);
+ // } catch (IOException e) {
+ // // TODO Auto-generated catch block
+ // e.printStackTrace();
+ // }
+ }
+
+}
diff --git a/cobigen/gui/src/main/java/com/devonfw/cobigen/gui/model/TemplateSetModel.java b/cobigen/gui/src/main/java/com/devonfw/cobigen/gui/model/TemplateSetModel.java
new file mode 100644
index 0000000000..d4ae5b23bc
--- /dev/null
+++ b/cobigen/gui/src/main/java/com/devonfw/cobigen/gui/model/TemplateSetModel.java
@@ -0,0 +1,52 @@
+package com.devonfw.cobigen.gui.model;
+
+import com.devonfw.cobigen.impl.config.entity.io.TemplateSetConfiguration;
+
+import javafx.collections.FXCollections;
+import javafx.collections.ObservableList;
+
+/**
+ * Singleton Model Class
+ *
+ */
+public class TemplateSetModel {
+ private static TemplateSetModel tsModel;
+
+ private final ObservableList templateSetObservableList;
+
+ private TemplateSetModel() {
+
+ this.templateSetObservableList = FXCollections.observableArrayList();
+ }
+
+ public static TemplateSetModel getInstance() {
+
+ if (tsModel == null) {
+ tsModel = new TemplateSetModel();
+ }
+
+ // returns the singleton object
+ return tsModel;
+ }
+
+ /**
+ * @return templateSetObservableList
+ */
+ public ObservableList getTemplateSetObservableList() {
+
+ return this.templateSetObservableList;
+ }
+
+ public void loadAllAvailableTemplateSets() {
+
+ // Load all template set artifacts
+ // List templateSetConfigurations = ArtifactRetriever.retrieveArtifactsFromCache();
+
+ // pass TemplateSetConfigurations to GUI
+ // for (TemplateSetConfiguration configuration : templateSetConfigurations) {
+ // this.templateSetObservableList.addAll(configuration);
+ // }
+
+ }
+
+}
diff --git a/cobigen/gui/src/main/java/com/devonfw/cobigen/gui/services/TemplateSetCell.java b/cobigen/gui/src/main/java/com/devonfw/cobigen/gui/services/TemplateSetCell.java
new file mode 100644
index 0000000000..cafbdc0760
--- /dev/null
+++ b/cobigen/gui/src/main/java/com/devonfw/cobigen/gui/services/TemplateSetCell.java
@@ -0,0 +1,63 @@
+package com.devonfw.cobigen.gui.services;
+
+import java.io.IOException;
+
+import com.devonfw.cobigen.impl.config.entity.io.TemplateSetConfiguration;
+
+import javafx.fxml.FXML;
+import javafx.fxml.FXMLLoader;
+import javafx.scene.control.Button;
+import javafx.scene.control.Label;
+import javafx.scene.control.ListCell;
+import javafx.scene.layout.GridPane;
+
+/**
+ * TODO nneuhaus This type ...
+ *
+ */
+public class TemplateSetCell extends ListCell {
+
+ FXMLLoader loader;
+
+ @FXML
+ private GridPane gridPane;
+
+ @FXML
+ private Label titleLabel;
+
+ @FXML
+ private Button installButton;
+
+ // when this method suppose to be called
+ @Override
+ protected void updateItem(TemplateSetConfiguration templateSet, boolean empty) {
+
+ super.updateItem(templateSet, empty);
+ if (empty || templateSet == null) {
+ setText("");
+ setGraphic(null);
+ setPrefHeight(45.0);
+ } else {
+ if (this.loader == null) {
+ this.loader = new FXMLLoader(
+ getClass().getClassLoader().getResource("com/devonfw/cobigen/gui/fxml/TemplateSetCell.fxml"));
+ this.loader.setController(this);
+
+ try {
+ this.loader.load();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+ // name of template set. should not happen here
+ this.titleLabel.setText(templateSet.getContextConfiguration().getTrigger().get(0).getId());
+ this.installButton.setOnAction(event -> {
+ System.out.println("INSTALLIEREN!!!");
+ });
+
+ setText(null);
+ setGraphic(this.gridPane);
+ }
+ }
+
+}
diff --git a/cobigen/gui/src/main/java/com/devonfw/cobigen/gui/services/TemplateSetCellFactory.java b/cobigen/gui/src/main/java/com/devonfw/cobigen/gui/services/TemplateSetCellFactory.java
new file mode 100644
index 0000000000..af739982d0
--- /dev/null
+++ b/cobigen/gui/src/main/java/com/devonfw/cobigen/gui/services/TemplateSetCellFactory.java
@@ -0,0 +1,22 @@
+package com.devonfw.cobigen.gui.services;
+
+import com.devonfw.cobigen.impl.config.entity.io.TemplateSetConfiguration;
+
+import javafx.scene.control.ListCell;
+import javafx.scene.control.ListView;
+import javafx.util.Callback;
+
+/**
+ * TODO nneuhaus This type ...
+ *
+ */
+public class TemplateSetCellFactory
+ implements Callback, ListCell> {
+
+ @Override
+ public ListCell call(ListView param) {
+
+ return new TemplateSetCell();
+ }
+
+}
diff --git a/cobigen/gui/src/main/java/com/devonfw/cobigen/gui/services/TreeViewBuilder.java b/cobigen/gui/src/main/java/com/devonfw/cobigen/gui/services/TreeViewBuilder.java
new file mode 100644
index 0000000000..88620c12d2
--- /dev/null
+++ b/cobigen/gui/src/main/java/com/devonfw/cobigen/gui/services/TreeViewBuilder.java
@@ -0,0 +1,36 @@
+package com.devonfw.cobigen.gui.services;
+
+import java.util.List;
+
+import com.devonfw.cobigen.impl.config.entity.io.Increment;
+
+import javafx.scene.control.TreeItem;
+import javafx.scene.control.TreeView;
+
+/**
+ * Service class to build Tree Views
+ *
+ */
+public class TreeViewBuilder {
+
+ /**
+ * @param arrayOfItems to transform to tree
+ * @return the complete TreeView
+ */
+ public static TreeView buildTreeView(List arrayOfItems) {
+
+ TreeItem rootItem = new TreeItem<>("Increments");
+ rootItem.setExpanded(true);
+
+ for (Increment i : arrayOfItems) {
+ TreeItem increment = new TreeItem<>(i.getName());
+ TreeItem incrementDescription = new TreeItem<>(i.getDescription());
+ increment.getChildren().add(incrementDescription);
+ rootItem.getChildren().add(increment);
+ }
+
+ TreeView tree = new TreeView<>(rootItem);
+ return tree;
+ }
+
+}
diff --git a/cobigen/gui/src/main/resources/com/devonfw/cobigen/gui/dark_theme.css b/cobigen/gui/src/main/resources/com/devonfw/cobigen/gui/dark_theme.css
new file mode 100644
index 0000000000..ba790880b8
--- /dev/null
+++ b/cobigen/gui/src/main/resources/com/devonfw/cobigen/gui/dark_theme.css
@@ -0,0 +1,105 @@
+.root {
+ -fx-accent: #1e74c6;
+ -fx-body-color : white;
+ -fx-outer-border : black;
+ -fx-focus-color: transparent;
+ -fx-faint-focus-color: transparent;
+ -fx-base: black;
+ -fx-accent: #0070AD;
+ -fx-control-inner-background: derive(-fx-base, 35.0%);
+ -fx-control-inner-background-alt: -fx-control-inner-background;
+}
+
+.split-pane:horizontal > .split-pane-divider {
+ -fx-background-color: transparent;
+ -fx-padding: 0;
+}
+.split-pane:vertical > .split-pane-divider {
+
+ -fx-padding: 0.5;
+}
+
+/* Text */
+Text {
+ -fx-font: 12px Ubuntu;
+ -fx-fill: white;
+ -fx-font-weight: 200;
+ -fx-font-smoothing-type: lcd;
+}
+.header {
+ -fx-font-weight: 400;
+ -fx-font-size: 16.0px;
+}
+.subheader {
+ -fx-font-weight: 300;
+ -fx-font-size: 14.0px;
+}
+
+/* Components */
+.label{
+ -fx-text-fill: lightgray;
+}
+
+.text-field {
+ -fx-background-color: -fx-text-box-border, -fx-background ;
+ -fx-background-insets: 0, 0 0 0 0 ;
+ -fx-background-radius: 0 ;
+ -fx-prompt-text-fill: gray;
+}
+.text-field:focused {
+ -fx-background-color: -fx-focus-color, -fx-background ;
+}
+
+.button{
+ -fx-focus-traversable: false;
+ -fx-background-color: -fx-control-inner-background, -fx-control-inner-background, -fx-control-inner-background;
+}
+#togglebutton{
+ -fx-background-color: transparent;
+}
+#filterMenuButton{
+ -fx-background-color: -fx-control-inner-background;
+}
+ .titleBarButtons{
+ -fx-background-color: transparent
+ }
+
+.icons{
+ -fx-icon-color: -fx-body-color;
+}
+.button:default {
+ -fx-base: -fx-accent ;
+}
+
+.button:hover{
+ -fx-text-fill: white;
+}
+
+.separator *.line {
+ -fx-background-color: #3C3C3C;
+ -fx-border-style: solid;
+ -fx-border-width: 1.0px;
+}
+
+.scroll-bar {
+ -fx-background-color: derive(-fx-base,45.0%);
+ -fx-block-increment: 1.0;
+}
+
+.list-cell:even,
+.list-cell:odd {
+ -fx-control-inner-background: derive(-fx-base, 15.0%);
+}
+
+.list-cell:empty {
+ -fx-background-color: transparent;
+}
+
+.list-cell {
+ -fx-border-color: transparent;
+ -fx-table-cell-border-color:transparent;
+}
+
+#menuBarPane{
+ -fx-background-color: -fx-control-inner-background;
+}
\ No newline at end of file
diff --git a/cobigen/gui/src/main/resources/com/devonfw/cobigen/gui/fxml/Details.fxml b/cobigen/gui/src/main/resources/com/devonfw/cobigen/gui/fxml/Details.fxml
new file mode 100644
index 0000000000..a77e379f95
--- /dev/null
+++ b/cobigen/gui/src/main/resources/com/devonfw/cobigen/gui/fxml/Details.fxml
@@ -0,0 +1,55 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/cobigen/gui/src/main/resources/com/devonfw/cobigen/gui/fxml/Home.fxml b/cobigen/gui/src/main/resources/com/devonfw/cobigen/gui/fxml/Home.fxml
new file mode 100644
index 0000000000..cfce1ece9f
--- /dev/null
+++ b/cobigen/gui/src/main/resources/com/devonfw/cobigen/gui/fxml/Home.fxml
@@ -0,0 +1,56 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/cobigen/gui/src/main/resources/com/devonfw/cobigen/gui/fxml/Menu.fxml b/cobigen/gui/src/main/resources/com/devonfw/cobigen/gui/fxml/Menu.fxml
new file mode 100644
index 0000000000..40c94eb90a
--- /dev/null
+++ b/cobigen/gui/src/main/resources/com/devonfw/cobigen/gui/fxml/Menu.fxml
@@ -0,0 +1,82 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/cobigen/gui/src/main/resources/com/devonfw/cobigen/gui/fxml/Primary.fxml b/cobigen/gui/src/main/resources/com/devonfw/cobigen/gui/fxml/Primary.fxml
new file mode 100644
index 0000000000..65bbfb5b29
--- /dev/null
+++ b/cobigen/gui/src/main/resources/com/devonfw/cobigen/gui/fxml/Primary.fxml
@@ -0,0 +1,45 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/cobigen/gui/src/main/resources/com/devonfw/cobigen/gui/fxml/TemplateSetCell.fxml b/cobigen/gui/src/main/resources/com/devonfw/cobigen/gui/fxml/TemplateSetCell.fxml
new file mode 100644
index 0000000000..69e9396c6f
--- /dev/null
+++ b/cobigen/gui/src/main/resources/com/devonfw/cobigen/gui/fxml/TemplateSetCell.fxml
@@ -0,0 +1,33 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/cobigen/gui/src/main/resources/com/devonfw/cobigen/gui/icons/devon-icon.jpg b/cobigen/gui/src/main/resources/com/devonfw/cobigen/gui/icons/devon-icon.jpg
new file mode 100644
index 0000000000..b6867b41e6
Binary files /dev/null and b/cobigen/gui/src/main/resources/com/devonfw/cobigen/gui/icons/devon-icon.jpg differ
diff --git a/cobigen/gui/src/main/resources/com/devonfw/cobigen/gui/styles.css b/cobigen/gui/src/main/resources/com/devonfw/cobigen/gui/styles.css
new file mode 100644
index 0000000000..b52ec4d159
--- /dev/null
+++ b/cobigen/gui/src/main/resources/com/devonfw/cobigen/gui/styles.css
@@ -0,0 +1,157 @@
+/* JavaFX CSS - Leave this comment until you have at least create one rule which uses -fx-Property */
+
+/* makes button and filter option white and borderless*/
+.root {
+ -fx-body-color : white;
+ -fx-outer-border : white;
+
+}
+.root * {
+ -fx-font: 11.0px Ubuntu;
+ -fx-focus-color: transparent;
+ -fx-faint-focus-color: transparent;
+ -fx-base: white;
+ -fx-accent: #0070AD;
+ -fx-control-inner-background: derive(-fx-base, 35.0%);
+ -fx-control-inner-background-alt: -fx-control-inner-background;
+}
+
+.split-pane:horizontal > .split-pane-divider {
+ -fx-background-color: transparent;
+ -fx-padding: 0.0;
+}
+.split-pane:vertical > .split-pane-divider {
+ -fx-padding: 0.5;
+}
+
+.scroll-bar {
+ -fx-background-color: white;
+ -fx-block-increment: 1.0;
+}
+
+/* Text */
+Text {
+ -fx-font: 12.0px Ubuntu;
+ -fx-fill: black;
+ -fx-font-weight: 200;
+ -fx-font-smoothing-type: lcd;
+}
+.header {
+ -fx-font-size: 16.0px;
+ -fx-font-weight: 400;
+}
+.subheader {
+ -fx-font-weight: 300;
+ -fx-font-size: 14.0px;
+}
+
+.text-field {
+ -fx-background-color: -fx-text-box-border, -fx-background ;
+ -fx-background-insets: 0.0, 0.0 0.0 1.0 0.0 ;
+ -fx-background-radius: 0.0 ;
+ -fx-prompt-text-fill: gray;
+}
+.text-field:focused {
+ -fx-background-color: -fx-focus-color, -fx-background ;
+}
+
+/* sets the color when cursor hovers over button*/
+color-picker:hover,
+.date-picker:hover > .arrow-button,
+.combo-box:hover,.choice-box:hover,
+.number-button:hover,.left-arrow-button:hover,.right-arrow-button:hover,
+.button:hover,.menu-button:hover,.toggle-button:hover,
+.font-menu-button:hover,
+.split-menu-button > .label:hover, .split-menu-button > .arrow-button:hover {
+ -fx-background-color: #ececec;
+
+}
+
+ /*pressed selected*/
+.color-picker:pressed,.color-picker:selected,
+.number-button:pressed,.number-button:selected,
+.date-picker:pressed > .arrow-button,
+.combo-box:pressed > .arrow-button,.combo-box:selected > .arrow-button,
+.choice-box:pressed > .arrow-button,.choice-box:selected > .arrow-button,
+.font-menu-button:pressed,.font-menu-button:selected,
+.left-arrow-button:pressed,.left-arrow-button:selected,
+.right-arrow-button:pressed,.right-arrow-button:selected,
+.button:pressed, .button:selected,.menu-button:pressed,.menu-button:selected
+,.toggle-button:pressed,.toggle-button:selected,
+.split-menu-button:pressed > .label, .split-menu-button > .arrow-button:pressed {
+ -fx-background-color: #D3D3D3
+ }
+
+ #menuBarPane{
+ -fx-background-color: white;
+ }
+
+ #templateSetsLabel{
+ -fx-background-color: transparent;
+
+ }
+
+ #homeButtonIcon{
+ -fx-scale-x: 0.1;
+ -fx-scale-y: 0.1;
+ }
+
+ .menuButtons{
+ -fx-background-color: #0070AD
+ }
+
+ .titleBarButtons{
+ -fx-background-color: transparent
+ }
+
+ #clearSearchButton{
+ -fx-background-color: transparent
+ }
+
+ /* Items in the search panel*/
+.list-cell:filled:selected:focused, .list-cell:filled:selected {
+ -fx-background-color: #0070AD;
+ -fx-text-fill: white;
+}
+
+.list-cell:even { /* <=== changed to even */
+ -fx-background-color: white;
+}
+
+.list-cell:filled:hover {
+ -fx-background-color: #12B3DB;
+ -fx-text-fill: white;
+}
+
+list-view {
+ -fx-background-color: white;
+}
+
+.list-cell:odd {
+-fx-background-color: white;
+
+}
+
+.split-menu-button {
+ -fx-background-color: #0070AD, #0070AD;
+
+}
+.split-menu-button > .label {
+ -fx-text-fill: white;
+ -fx-background-color: #0070AD, #0070AD;
+}
+.split-menu-button > .arrow-button {
+ -fx-background-color: #0070AD, #0070AD;
+
+}
+.split-menu-button:hover {
+ -fx-background-color: #0070AD;
+}
+.split-menu-button:hover > .label {
+ -fx-background-color: #0070AD, #0070AD, transparent, #0070AD;
+
+}
+.split-menu-button:hover > .arrow-button {
+ -fx-background-color: #ececec, #ececec, #ececec, #ececec;
+
+}
diff --git a/cobigen/gui/src/test/java/com/devonfw/cobigen/gui/FilterTest.java b/cobigen/gui/src/test/java/com/devonfw/cobigen/gui/FilterTest.java
new file mode 100644
index 0000000000..a8c044d07e
--- /dev/null
+++ b/cobigen/gui/src/test/java/com/devonfw/cobigen/gui/FilterTest.java
@@ -0,0 +1,73 @@
+package com.devonfw.cobigen.gui;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+import org.junit.Test;
+
+/**
+ * TODO nneuhaus This type ...
+ *
+ */
+public class FilterTest extends TestFXBase {
+
+ /**
+ *
+ */
+ @Test
+ public void testAdaptedView() {
+
+ // TODO
+ assertThat(false).isTrue();
+ }
+
+ /**
+ *
+ */
+ @Test
+ public void testInstalledView() {
+
+ // TODO
+ assertThat(false).isTrue();
+ }
+
+ /**
+ *
+ */
+ @Test
+ public void testCheckForUpdates() {
+
+ // TODO
+ assertThat(false).isTrue();
+ }
+
+ /**
+ *
+ */
+ @Test
+ public void showsAllTags() {
+
+ // TODO
+ assertThat(false).isTrue();
+ }
+
+ /**
+ *
+ */
+ @Test
+ public void selectAndDeselectTag() {
+
+ // TODO
+ assertThat(false).isTrue();
+ }
+
+ /**
+ *
+ */
+ @Test
+ public void selectMultipleTags() {
+
+ // TODO
+ assertThat(false).isTrue();
+ }
+
+}
diff --git a/cobigen/gui/src/test/java/com/devonfw/cobigen/gui/HomePageTest.java b/cobigen/gui/src/test/java/com/devonfw/cobigen/gui/HomePageTest.java
new file mode 100644
index 0000000000..bd1f533d87
--- /dev/null
+++ b/cobigen/gui/src/test/java/com/devonfw/cobigen/gui/HomePageTest.java
@@ -0,0 +1,91 @@
+package com.devonfw.cobigen.gui;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+import org.junit.Test;
+import org.testfx.api.FxRobotException;
+
+import javafx.collections.ObservableList;
+import javafx.fxml.FXML;
+import javafx.scene.control.Hyperlink;
+import javafx.scene.control.TreeItem;
+import javafx.scene.control.TreeView;
+
+/**
+ * Tests for the home page
+ *
+ */
+public class HomePageTest extends TestFXBase {
+
+ @FXML
+ private Hyperlink wikilink;
+
+ @FXML
+ private TreeView incrementsTreeView;
+
+ /**
+ * Test if exception is thrown, when the bot tries to click a not existing element
+ */
+ @Test(expected = FxRobotException.class)
+ public void clickOnBogusElement() {
+
+ clickOn("#NotExisting");
+ }
+
+ /**
+ * Test if home page is shown when GUI is started
+ */
+ @Test
+ public void ensureHomePageIsShownOnStartUp() {
+
+ assertThat(this.home);
+ }
+
+ /**
+ * Test if home page is shown when Home Button gets clicked
+ */
+ // @Test
+ // public void ensureHomePageIsShownOnHomeButtonClicked() {
+ //
+ // this.searchResultsView.getSelectionModel().select(0);
+ // assertThat(this.searchResultsView.getSelectionModel().getSelectedIndex() == 0);
+ // assertThat(this.details.isVisible());
+ // assertThat(!this.home.isVisible());
+ // // Switch back to Home
+ // clickOn("#homeButton");
+ // assertThat(this.home.isVisible());
+ // assertThat(!this.details.isVisible());
+ // }
+
+ /**
+ * Test if link to Cobigen Wiki works
+ */
+ @Test
+ public void testLinkToCobigenWiki() {
+
+ String COBIGEN_WIKI_LINK = "#wikilink";
+ this.wikilink = find(COBIGEN_WIKI_LINK);
+ assertThat(!this.wikilink.isPressed());
+ clickOn(COBIGEN_WIKI_LINK);
+ assertThat(this.wikilink.isPressed());
+ }
+
+ /**
+ * Test if the example tree view is interactive
+ */
+ @Test
+ public void testFoldingIncrementTreeView() {
+
+ String TREEVIEW = "#treeView";
+ this.incrementsTreeView = (TreeView) this.mainRoot.lookup(TREEVIEW);
+ TreeItem root = this.incrementsTreeView.getRoot();
+ assertThat(root.isExpanded());
+ ObservableList> children = root.getChildren();
+ for (int i = 0; i < children.size(); i++) {
+ TreeItem child = children.get(i);
+ assertThat(!child.isExpanded());
+ assertThat(child.getChildren().get(0).isLeaf());
+ }
+ }
+
+}
diff --git a/cobigen/gui/src/test/java/com/devonfw/cobigen/gui/ProcessTemplateSetTest.java b/cobigen/gui/src/test/java/com/devonfw/cobigen/gui/ProcessTemplateSetTest.java
new file mode 100644
index 0000000000..20b91375cc
--- /dev/null
+++ b/cobigen/gui/src/test/java/com/devonfw/cobigen/gui/ProcessTemplateSetTest.java
@@ -0,0 +1,207 @@
+package com.devonfw.cobigen.gui;
+
+import static com.github.stefanbirkner.systemlambda.SystemLambda.withEnvironmentVariable;
+import static org.assertj.core.api.Assertions.assertThat;
+
+import java.io.File;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.nio.file.StandardCopyOption;
+
+import org.apache.commons.io.FileUtils;
+import org.junit.Test;
+import org.testfx.util.WaitForAsyncUtils;
+
+import com.devonfw.cobigen.api.constants.ConfigurationConstants;
+import com.devonfw.cobigen.api.util.CobiGenPaths;
+
+import javafx.scene.control.Button;
+
+/**
+ * TODO
+ *
+ */
+public class ProcessTemplateSetTest extends TestFXBase {
+
+ /**
+ * Root path to all resources used in this test case
+ */
+ private final static Path TEST_FILE_ROOT_PATH = Paths
+ .get("src/test/resources/testdata/integrationtests/ProcessTemplateSetTest");
+
+ @Test
+ public void testGetAllTemplateSetsAdapted() throws Exception {
+
+ // TODO:
+ this.tmpFolder.newFolder(ConfigurationConstants.TEMPLATE_SETS_FOLDER);
+ this.tmpFolder.newFolder(ConfigurationConstants.TEMPLATE_SETS_FOLDER, ConfigurationConstants.ADAPTED_FOLDER);
+
+ }
+
+ /**
+ * Tests if a selected template set can be installed (template-set class jar file gets added to
+ * template-sets/downloaded folder) and the text of the install button changed from Install to Installed
+ *
+ * @throws Exception Test fails
+ */
+ @Test
+ public void testInstallTemplateSet() throws Exception {
+
+ // preparation
+ File downloaded = this.tmpFolder.newFolder("UserHome", ConfigurationConstants.TEMPLATE_SETS_FOLDER,
+ ConfigurationConstants.DOWNLOADED_FOLDER);
+
+ // simulate template-set-list folder for downloaded template-set.xml files to be used in GUI
+ File artifactCacheFolder = this.tmpFolder.newFolder("UserHome", "template-sets", "template-set-list");
+
+ Path templateSetXmlFile1 = TEST_FILE_ROOT_PATH.resolve("crud-java-server-app-2021.12.007-template-set.xml");
+ Files.copy(templateSetXmlFile1,
+ artifactCacheFolder.toPath().resolve("crud-java-server-app-2021.12.007-template-set.xml"),
+ StandardCopyOption.REPLACE_EXISTING);
+ Path templateSetXmlFile2 = TEST_FILE_ROOT_PATH.resolve("crud-openapi-server-app-2021.12.007-template-set.xml");
+ Files.copy(templateSetXmlFile2,
+ artifactCacheFolder.toPath().resolve("crud-openapi-server-app-2021.12.007-template-set.xml"),
+ StandardCopyOption.REPLACE_EXISTING);
+
+ Button refreshButton = find("#refreshButton");
+ clickOn(refreshButton);
+
+ WaitForAsyncUtils.waitForFxEvents();
+
+ // clicks on first element of searchResultsView
+ clickOn(this.searchResultsView.getItems().get(0).getContextConfiguration().getTrigger().get(0).getId());
+
+ Button installButton = find("#installButton");
+ String installButtonText = installButton.getText();
+
+ sleep(1000);
+
+ clickOn("Install");
+
+ WaitForAsyncUtils.waitForFxEvents();
+
+ assertThat(downloaded.toPath().resolve("crud-java-server-app-2021.12.007.jar")).exists();
+
+ assertThat(installButtonText).isEqualTo("Installed");
+
+ }
+
+ @Test
+ public void testGetAllTemplateSetsDownloaded() throws Exception {
+
+ // preparation
+ File userHome = this.tmpFolder.newFolder("UserHome");
+
+ Path templateSetPath = TEST_FILE_ROOT_PATH.resolve("downloaded_template_sets/template-sets");
+
+ FileUtils.copyDirectory(templateSetPath.toFile(), userHome.toPath().resolve("template-sets").toFile());
+
+ withEnvironmentVariable(ConfigurationConstants.CONFIG_ENV_HOME, userHome.getAbsolutePath()).execute(() -> {
+ Path downloadedPath = CobiGenPaths.getTemplateSetsFolderPath().resolve(ConfigurationConstants.DOWNLOADED_FOLDER);
+
+ });
+
+ }
+
+ @Test
+ public void testGetAllTemplateSetsInstalled() throws Exception {
+
+ File userHome = this.tmpFolder.newFolder("user-home");
+
+ // List templateSets = ArtifactRetriever.retrieveTemplateSetData();
+
+ }
+
+ @Test
+ public void testGetAllTemplateSetsInfo() {
+
+ }
+
+ // TODO: WireMock
+ // ConfigurationUtilTest
+ @Test
+ public void testGetAllTemplateSetsFromRepo() {
+
+ }
+
+ /**
+ *
+ */
+ @Test
+ public void testAllTemplateSetsAreShownWithTrueStatus() {
+
+ // TODO
+ assertThat(false).isTrue();
+ }
+
+ /**
+ *
+ */
+ @Test
+ public void testInstallTemplateSetThroughDetails() {
+
+ // TODO
+ assertThat(false).isTrue();
+ }
+
+ /**
+ *
+ */
+ @Test
+ public void testUpdateTemplateSetThroughDetails() {
+
+ // TODO
+ assertThat(false).isTrue();
+ }
+
+ /**
+ *
+ */
+ @Test
+ public void testUpdateTemplateSetToCertainVersion() {
+
+ // TODO
+ assertThat(false).isTrue();
+ }
+
+ /**
+ *
+ */
+ @Test
+ public void testUninstallTemplateSetThroughDetails() {
+
+ // TODO
+ assertThat(false).isTrue();
+ }
+
+ /**
+ *
+ */
+ @Test
+ public void testInstallTemplateSetThroughSearchResultCell() {
+
+ // TODO
+ assertThat(false).isTrue();
+ }
+
+ /**
+ *
+ */
+ @Test
+ public void testUpdateTemplateSetThroughSearchResultCell() {
+
+ // TODO
+ assertThat(false).isTrue();
+ }
+
+ /**
+ *
+ */
+ @Test
+ public void testUninstallTemplateSetThroughSearchResultCell() {
+
+ // TODO
+ assertThat(false).isTrue();
+ }
+}
diff --git a/cobigen/gui/src/test/java/com/devonfw/cobigen/gui/SearchTest.java b/cobigen/gui/src/test/java/com/devonfw/cobigen/gui/SearchTest.java
new file mode 100644
index 0000000000..31e9d2d0af
--- /dev/null
+++ b/cobigen/gui/src/test/java/com/devonfw/cobigen/gui/SearchTest.java
@@ -0,0 +1,147 @@
+package com.devonfw.cobigen.gui;
+
+import org.junit.Test;
+
+import javafx.scene.control.Label;
+import javafx.scene.control.TextField;
+
+/**
+ * Tests for the search function
+ *
+ */
+public class SearchTest extends TestFXBase {
+
+ /**
+ * Tests if search results list view has the correct list cells
+ */
+ @Test
+ public void hasListCell() {
+
+ // assertThat(this.searchResultsView).hasListCell(this.templateSetObservableList.get(0));
+ }
+
+ /**
+ * Tests that error is thrown when asked for null list cell
+ */
+ @Test
+ public void hasListCellFailsWithNull() {
+
+ // assertThatThrownBy(() -> assertThat(this.searchResultsView).hasListCell(null))
+ // .isExactlyInstanceOf(AssertionError.class);
+ }
+
+ /**
+ * Tests that error is thrown when asked for bogus list cell
+ */
+ @Test
+ public void hasListCellFailsWithBogus() {
+
+ // assertThatThrownBy(() -> assertThat(this.searchResultsView).hasListCell(this.BOGUS))
+ // .isExactlyInstanceOf(AssertionError.class);
+ }
+
+ /**
+ * Tests that the search results have no bogus list cell
+ */
+ @Test
+ public void doesNotHaveListCell() {
+
+ // assertThat(this.searchResultsView).doesNotHaveListCell(this.BOGUS);
+ }
+
+ /**
+ * Tests that the amount of elements in the list are shown in the search results
+ */
+ @Test
+ public void hasExactlyNumItems() {
+
+ // assertThat(this.searchResultsView).hasExactlyNumItems(this.templateSetObservableList.size());
+ }
+
+ /**
+ * Tests that error is thrown when asked for wrong count of items
+ */
+ @Test
+ public void hasExactlyNumItems_fails() {
+
+ // assertThatThrownBy(() -> assertThat(this.searchResultsView).hasExactlyNumItems(1))
+ // .isExactlyInstanceOf(AssertionError.class).hasMessage(
+ // "Expected: ListView has exactly 1 item\n " + "but: was " + this.templateSetObservableList.size());
+ }
+
+ /**
+ * Tests that correct items are shown in the search results before the search
+ */
+ @Test
+ public void preSearchTest() {
+
+ // int i = 0;
+ // for (TemplateSet ts : this.templateSetObservableList) {
+ // clickOn("#searchResultsView");
+ // assertThat(this.searchResultsView.getSelectionModel().getSelectedIndex() == i);
+ // assertThat(ts.equals(this.searchResultsView.getItems().get(i))).isTrue();
+ // i++;
+ // }
+ }
+
+ /**
+ * Tests that each template set is the only search result when searched for its exact name
+ */
+ @Test
+ public void ensureAllTemplateSetsAreFound() {
+
+ String titleOfTemplateSet;
+ TextField searchBar = find("#searchBar");
+ // for (TemplateSet ts : this.templateSetObservableList) {
+ // clickOn("#searchBar");
+ // titleOfTemplateSet = ts.getName();
+ // eraseText(titleOfTemplateSet.length());
+ // write(titleOfTemplateSet);
+ // clickOn("#searchResultsView");
+ // assertThat(titleOfTemplateSet.equals(this.searchResultsView.getItems().get(0).getName()));
+ // assertThat(this.searchResultsView).hasExactlyNumItems(1);
+ }
+
+ /**
+ * Tests that there are no search results shown with a bogus search term
+ */
+ @Test
+ public void ensureSearchResultsEmptyWithBogusSearchTerm() {
+
+ clickOn("#searchBar");
+ write(this.BOGUS);
+ // assertThat(this.searchResultsView).hasExactlyNumItems(0);
+ }
+
+ /**
+ * Tests functionality of the clearSearchResultsButton
+ */
+ @Test
+ public void testClearSearchResultsButton() {
+
+ //
+ // int originalItemCount = this.searchResultsView.getItems().size();
+ // TextField searchBar = find("#searchBar");
+ // clickOn("#searchBar");
+ // write(this.templateSetObservableList.get(0).getName());
+ // assertThat(this.searchResultsView).hasExactlyNumItems(1);
+ // clickOn("#clearSearchResultsButton");
+ // assertThat(searchBar.getText().length() == 0);
+ // assertThat(this.searchResultsView).hasExactlyNumItems(originalItemCount);
+ }
+
+ /**
+ * Selects all items in the search results and tests if the correct template set details page is shown
+ */
+ @Test
+ public void testSelectionOfTemplateSet() {
+
+ Label titleLabel;
+ // for (int i = 0; i < this.templateSetObservableList.size(); i++) {
+ // this.searchResultsView.getSelectionModel().select(i);
+ // titleLabel = find("#titleLabel");
+ // assertThat(titleLabel.getText() == this.searchResultsView.getSelectionModel().getSelectedItem().getName());
+ // }
+ }
+
+}
diff --git a/cobigen/gui/src/test/java/com/devonfw/cobigen/gui/TemplateSetDetailsTest.java b/cobigen/gui/src/test/java/com/devonfw/cobigen/gui/TemplateSetDetailsTest.java
new file mode 100644
index 0000000000..79f93d10dc
--- /dev/null
+++ b/cobigen/gui/src/test/java/com/devonfw/cobigen/gui/TemplateSetDetailsTest.java
@@ -0,0 +1,135 @@
+package com.devonfw.cobigen.gui;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+import java.nio.file.Path;
+import java.nio.file.Paths;
+
+import org.junit.Test;
+
+import com.devonfw.cobigen.impl.config.entity.io.TemplateSetConfiguration;
+import com.devonfw.cobigen.impl.config.reader.TemplateSetConfigurationReader;
+
+import javafx.collections.FXCollections;
+
+/**
+ * TODO
+ *
+ */
+public class TemplateSetDetailsTest extends TestFXBase {
+
+ /**
+ * Root path to all resources used in this test case
+ */
+ private final static Path TEST_FILE_ROOT_PATH = Paths
+ .get("src/test/resources/testdata/unittests/TemplateSetDetailsTest");
+
+ /**
+ *
+ */
+ @Test
+ public void testVisibilityOnStartUp() {
+
+ // TODO
+ assertThat(false).isTrue();
+ }
+
+ /**
+ *
+ */
+ @Test
+ public void testVisibilityAfterSearchAndSelect() {
+
+ // TODO
+ assertThat(false).isTrue();
+ }
+
+ /**
+ * Tests if a loaded template set is displaying the correct name in the list view
+ */
+ @Test
+ public void testTemplateSetNameIsShownCorrectly() {
+
+ Path templateSetXmlFile = TEST_FILE_ROOT_PATH.resolve("template-set.xml");
+
+ // initialize template set reader
+ TemplateSetConfigurationReader reader = new TemplateSetConfigurationReader(templateSetXmlFile);
+
+ // read template set xml file/files
+ reader.readConfiguration(templateSetXmlFile);
+
+ TemplateSetConfiguration templateSetConfiguration = reader.getTemplateSetConfiguration();
+
+ // adds template set to GUI
+ this.templateSetObservableList = FXCollections.observableArrayList();
+ this.templateSetObservableList.addAll(templateSetConfiguration);
+
+ this.searchResultsView.setItems(this.templateSetObservableList);
+
+ String triggerName = templateSetConfiguration.getContextConfiguration().getTrigger().get(0).getId();
+ String templateSetNameInMenu = this.searchResultsView.getItems().get(0).getContextConfiguration().getTrigger()
+ .get(0).getId();
+
+ assertThat(templateSetNameInMenu).isEqualTo(triggerName);
+ }
+
+ /**
+ *
+ */
+ @Test
+ public void testTemplateSetDescriptionIsShownCorrectly() {
+
+ // TODO
+ assertThat(false).isTrue();
+ }
+
+ /**
+ *
+ */
+ @Test
+ public void testTemplateSetStatusIsShownCorrectly() {
+
+ // TODO
+ assertThat(false).isTrue();
+ }
+
+ /**
+ *
+ */
+ @Test
+ public void testTemplateSetVersionIsShownCorrectly() {
+
+ // TODO
+ assertThat(false).isTrue();
+ }
+
+ /**
+ *
+ */
+ @Test
+ public void testSelectableVersionsAreShownCorrectly() {
+
+ // TODO
+ assertThat(false).isTrue();
+ }
+
+ /**
+ *
+ */
+ @Test
+ public void testInstallButtonDisabledForInstalledTemplateSet() {
+
+ // TODO
+ assertThat(false).isTrue();
+ }
+
+ /**
+ *
+ */
+ @Test
+ public void testTemplateSetStructureIsShownCorrectly() {
+
+ // TODO
+ assertThat(false).isTrue();
+ }
+}
diff --git a/cobigen/gui/src/test/java/com/devonfw/cobigen/gui/TestFXBase.java b/cobigen/gui/src/test/java/com/devonfw/cobigen/gui/TestFXBase.java
new file mode 100644
index 0000000000..a832de631e
--- /dev/null
+++ b/cobigen/gui/src/test/java/com/devonfw/cobigen/gui/TestFXBase.java
@@ -0,0 +1,137 @@
+package com.devonfw.cobigen.gui;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.ResourceBundle;
+import java.util.concurrent.TimeoutException;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.rules.TemporaryFolder;
+import org.testfx.api.FxToolkit;
+import org.testfx.framework.junit.ApplicationTest;
+
+import com.devonfw.cobigen.api.util.CobiGenPaths;
+import com.devonfw.cobigen.gui.controllers.DetailsController;
+import com.devonfw.cobigen.gui.controllers.MenuController;
+import com.devonfw.cobigen.impl.config.entity.io.TemplateSetConfiguration;
+
+import javafx.collections.ObservableList;
+import javafx.fxml.FXMLLoader;
+import javafx.scene.Node;
+import javafx.scene.Parent;
+import javafx.scene.Scene;
+import javafx.scene.control.ListView;
+import javafx.scene.input.KeyCode;
+import javafx.scene.input.MouseButton;
+import javafx.scene.layout.Pane;
+import javafx.stage.Stage;
+
+/**
+ * Base Test
+ *
+ */
+public class TestFXBase extends ApplicationTest {
+
+ final String BOGUS = "NOT EXISTING TEMPLATE SET";
+
+ Pane mainRoot;
+
+ Stage mainStage;
+
+ Controller controller;
+
+ Parent home;
+
+ Parent details;
+
+ MenuController menuController;
+
+ DetailsController detailsController;
+
+ ListView searchResultsView;
+
+ ObservableList templateSetObservableList;
+
+ protected static ResourceBundle bundle;
+
+ /** Temporary files rule to create temporary folders or files */
+ @Rule
+ public TemporaryFolder tmpFolder = new TemporaryFolder();
+
+ public static File userHome = null;
+
+ /**
+ * Set up headless testing
+ *
+ * @throws IOException
+ */
+ @Before
+ public void setupHeadlessMode() throws IOException {
+
+ userHome = this.tmpFolder.newFolder("UserHome");
+ this.tmpFolder.newFolder("UserHome", "template-sets");
+ CobiGenPaths.setCobiGenHomeTestPath(userHome.toPath().toAbsolutePath());
+
+ if (Boolean.getBoolean("headless")) {
+ System.setProperty("testfx.robot", "glass");
+ System.setProperty("testfx.headless", "true");
+ System.setProperty("prism.order", "sw");
+ System.setProperty("prism.text", "t2k");
+ System.setProperty("java.awt.headless", "true");
+ }
+
+ // bundle = ResourceBundle.getBundle("Bundle");
+ }
+
+ /**
+ * Start the GUI and set everything up
+ */
+ @Override
+ public void start(Stage stage) throws Exception {
+
+ this.mainStage = stage;
+ FXMLLoader loader = new FXMLLoader(getClass().getResource("fxml/Primary.fxml"));
+ this.mainRoot = loader.load();
+ this.controller = loader.getController();
+ stage.setScene(new Scene(this.mainRoot));
+ stage.show();
+ stage.toFront();
+
+ this.home = find("#home");
+ this.details = find("#details");
+ this.menuController = this.controller.menuController;
+ this.detailsController = this.controller.detailsController;
+ this.searchResultsView = find("#searchResultsView");
+ // this.templateSetObservableList = this.menuController.templateSetObservableList;
+ }
+
+ /**
+ * @throws TimeoutException
+ */
+ @After
+ public void afterEachTest() throws TimeoutException {
+
+ FxToolkit.hideStage();
+ release(new KeyCode[] {});
+ release(new MouseButton[] {});
+ }
+
+ /**
+ * Helper method to retrieve Java FX GUI components
+ *
+ * @param
+ * @param query
+ * @return
+ */
+ @SuppressWarnings("unchecked")
+ public T find(final String query) {
+
+ // temporary 'fix' because lookup(#home)... throws error
+ return (T) this.mainStage.getScene().lookup(query);
+
+ // return (T) lookup(query).queryAll().iterator().next();
+ }
+
+}
diff --git a/cobigen/gui/src/test/resources/template-set.xml b/cobigen/gui/src/test/resources/template-set.xml
new file mode 100644
index 0000000000..3b7e837efa
--- /dev/null
+++ b/cobigen/gui/src/test/resources/template-set.xml
@@ -0,0 +1,69 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/cobigen/gui/src/test/resources/testdata/integrationtests/ProcessTemplateSetTest/crud-java-server-app-2021.12.007-template-set.xml b/cobigen/gui/src/test/resources/testdata/integrationtests/ProcessTemplateSetTest/crud-java-server-app-2021.12.007-template-set.xml
new file mode 100644
index 0000000000..7790a68bbf
--- /dev/null
+++ b/cobigen/gui/src/test/resources/testdata/integrationtests/ProcessTemplateSetTest/crud-java-server-app-2021.12.007-template-set.xml
@@ -0,0 +1,39 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/cobigen/gui/src/test/resources/testdata/integrationtests/ProcessTemplateSetTest/crud-openapi-server-app-2021.12.007-template-set.xml b/cobigen/gui/src/test/resources/testdata/integrationtests/ProcessTemplateSetTest/crud-openapi-server-app-2021.12.007-template-set.xml
new file mode 100644
index 0000000000..6a7e091ee8
--- /dev/null
+++ b/cobigen/gui/src/test/resources/testdata/integrationtests/ProcessTemplateSetTest/crud-openapi-server-app-2021.12.007-template-set.xml
@@ -0,0 +1,39 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/cobigen/gui/src/test/resources/testdata/unittests/TemplateSetDetailsTest/template-set.xml b/cobigen/gui/src/test/resources/testdata/unittests/TemplateSetDetailsTest/template-set.xml
new file mode 100644
index 0000000000..c80976b27b
--- /dev/null
+++ b/cobigen/gui/src/test/resources/testdata/unittests/TemplateSetDetailsTest/template-set.xml
@@ -0,0 +1,39 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/cobigen/pom.xml b/cobigen/pom.xml
index 2c2b6d5a7f..f13661d83e 100644
--- a/cobigen/pom.xml
+++ b/cobigen/pom.xml
@@ -18,5 +18,6 @@
cobigen-core-systemtest
core-externalprocess-api
core-artifact-retriever
+ gui
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index e0f14f7dbf..42392412d9 100644
--- a/pom.xml
+++ b/pom.xml
@@ -1,5 +1,5 @@
-
+
4.0.0
com.devonfw.cobigen
master-parent
@@ -213,6 +213,11 @@
core-test
${revision}
+
+ com.devonfw.cobigen
+ gui
+ ${revision}
+
com.devonfw.cobigen
javaplugin