Skip to content

Commit

Permalink
Merge pull request #1216 from turkeylurkey/issue-1202
Browse files Browse the repository at this point in the history
Search for Liberty modules to use in Run/Debug config
  • Loading branch information
turkeylurkey authored Jan 16, 2025
2 parents 75d3bf7 + f54d739 commit 034fa10
Show file tree
Hide file tree
Showing 6 changed files with 167 additions and 135 deletions.
127 changes: 24 additions & 103 deletions src/main/java/io/openliberty/tools/intellij/LibertyExplorer.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2020, 2024 IBM Corporation.
* Copyright (c) 2020, 2025 IBM Corporation.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
Expand All @@ -20,7 +20,6 @@
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.SimpleToolWindowPanel;
import com.intellij.openapi.util.Computable;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.ui.DoubleClickListener;
import com.intellij.ui.PopupHandler;
import com.intellij.ui.components.JBScrollPane;
Expand All @@ -30,18 +29,15 @@
import io.openliberty.tools.intellij.actions.LibertyToolbarActionGroup;
import io.openliberty.tools.intellij.util.*;
import org.jetbrains.annotations.NotNull;
import org.xml.sax.SAXException;

import javax.swing.*;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeCellRenderer;
import javax.swing.tree.TreePath;
import javax.xml.parsers.ParserConfigurationException;
import java.awt.*;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseEvent;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;

Expand Down Expand Up @@ -106,115 +102,40 @@ public static ActionToolbar buildActionToolbar(Tree tree) {
* @return Tree object of all valid Liberty Gradle and Liberty Maven projects
*/
public static Tree buildTree(Project project, Color backgroundColor) {
LibertyModules libertyModules = LibertyModules.getInstance();
// clear all stored Liberty modules for current project
libertyModules.removeForProject(project);
DefaultMutableTreeNode top = new DefaultMutableTreeNode("Root node");

ArrayList<BuildFile> mavenBuildFiles;
ArrayList<BuildFile> gradleBuildFiles;
HashMap<String, ArrayList<Object>> map = new HashMap<>();
try {
mavenBuildFiles = LibertyProjectUtil.getMavenBuildFiles(project);
gradleBuildFiles = LibertyProjectUtil.getGradleBuildFiles(project);
} catch (IOException | SAXException | ParserConfigurationException e) {
LOGGER.warn("Could not find Liberty Maven or Gradle projects in workspace",
e);
LibertyModules libertyModules = LibertyModules.getInstance().scanLibertyModules(project);
// This singleton may contain entries from old projects if you close a project and open another
if (libertyModules.getLibertyModules(project).isEmpty()) {
return null;
}
DefaultMutableTreeNode top = new DefaultMutableTreeNode("Root node");
HashMap<String, ArrayList<Object>> projectMap = new HashMap<>();

if (mavenBuildFiles.isEmpty() && gradleBuildFiles.isEmpty()) {
return null;
}

for (BuildFile buildFile : mavenBuildFiles) {
// create a new Liberty project
VirtualFile virtualFile = buildFile.getBuildFile();
String projectName = null;
if (virtualFile == null) {
LOGGER.error(String.format("Could not resolve current Maven project %s", virtualFile));
break;
}
LibertyModuleNode node;
try {
projectName = LibertyMavenUtil.getProjectNameFromPom(virtualFile);
} catch (Exception e) {
LOGGER.warn(String.format("Could not resolve project name from build file: %s", virtualFile), e);
}
if (projectName == null) {
if (virtualFile.getParent() != null) {
projectName = virtualFile.getParent().getName();
} else {
projectName = project.getName();
}
}

boolean validContainerVersion = buildFile.isValidContainerVersion();
LibertyModule module = libertyModules.addLibertyModule(new LibertyModule(project, virtualFile, projectName, Constants.LIBERTY_MAVEN_PROJECT, validContainerVersion));
node = new LibertyModuleNode(module);
for (LibertyModule libertyModule : libertyModules.getLibertyModules(project)) {
LibertyModuleNode node = new LibertyModuleNode(libertyModule);

top.add(node);
ArrayList<Object> settings = new ArrayList<Object>();
settings.add(virtualFile);
settings.add(Constants.LIBERTY_MAVEN_PROJECT);
map.put(projectName, settings);
settings.add(libertyModule.getBuildFile());
settings.add(libertyModule.getProjectType());
projectMap.put(libertyModule.getName(), settings);

// ordered to align with IntelliJ's right-click menu
node.add(new LibertyActionNode(Constants.LIBERTY_DEV_START, module));
// check if Liberty Maven Plugin is 3.3-M1+
node.add(new LibertyActionNode(Constants.LIBERTY_DEV_START, libertyModule));
// check if Liberty Maven Plugin is 3.3-M1+ or Liberty Gradle Plugin is 3.1-M1+
// if version is not specified in pom, assume latest version as downloaded from maven central
boolean validContainerVersion = libertyModule.isValidContainerVersion();
if (validContainerVersion) {
node.add(new LibertyActionNode(Constants.LIBERTY_DEV_START_CONTAINER, module));
node.add(new LibertyActionNode(Constants.LIBERTY_DEV_START_CONTAINER, libertyModule));
}
node.add(new LibertyActionNode(Constants.LIBERTY_DEV_CUSTOM_START, module));
node.add(new LibertyActionNode(Constants.LIBERTY_DEV_STOP, module));
node.add(new LibertyActionNode(Constants.LIBERTY_DEV_TESTS, module));
node.add(new LibertyActionNode(Constants.VIEW_INTEGRATION_TEST_REPORT, module));
node.add(new LibertyActionNode(Constants.VIEW_UNIT_TEST_REPORT, module));
}

for (BuildFile buildFile : gradleBuildFiles) {
VirtualFile virtualFile = buildFile.getBuildFile();
String projectName = null;
if (virtualFile == null) {
LOGGER.error(String.format("Could not resolve current Gradle project %s", buildFile));
break;
}
LibertyModuleNode node;
try {
projectName = LibertyGradleUtil.getProjectName(virtualFile);
} catch (Exception e) {
LOGGER.warn(String.format("Could not resolve project name for project %s", virtualFile), e);
}
if (projectName == null) {
if (virtualFile.getParent() != null) {
projectName = virtualFile.getParent().getName();
} else {
projectName = project.getName();
}
}

boolean validContainerVersion = buildFile.isValidContainerVersion();
LibertyModule module = libertyModules.addLibertyModule(new LibertyModule(project, virtualFile, projectName, Constants.LIBERTY_GRADLE_PROJECT, validContainerVersion));
node = new LibertyModuleNode(module);

top.add(node);
ArrayList<Object> settings = new ArrayList<Object>();
settings.add(virtualFile);
settings.add(Constants.LIBERTY_GRADLE_PROJECT);
map.put(projectName, settings);

// ordered to align with IntelliJ's right-click menu
node.add(new LibertyActionNode(Constants.LIBERTY_DEV_START, module));
// check if Liberty Gradle Plugin is 3.1-M1+
// TODO: handle version specified in a gradle.settings file
if (buildFile.isValidContainerVersion()) {
node.add(new LibertyActionNode(Constants.LIBERTY_DEV_START_CONTAINER, module));
node.add(new LibertyActionNode(Constants.LIBERTY_DEV_CUSTOM_START, libertyModule));
node.add(new LibertyActionNode(Constants.LIBERTY_DEV_STOP, libertyModule));
node.add(new LibertyActionNode(Constants.LIBERTY_DEV_TESTS, libertyModule));
if (libertyModule.getProjectType().equals(Constants.LIBERTY_MAVEN_PROJECT)) {
node.add(new LibertyActionNode(Constants.VIEW_INTEGRATION_TEST_REPORT, libertyModule));
node.add(new LibertyActionNode(Constants.VIEW_UNIT_TEST_REPORT, libertyModule));
} else if (libertyModule.getProjectType().equals(Constants.LIBERTY_GRADLE_PROJECT)) {
node.add(new LibertyActionNode(Constants.VIEW_GRADLE_TEST_REPORT, libertyModule));
}
node.add(new LibertyActionNode(Constants.LIBERTY_DEV_CUSTOM_START, module));
node.add(new LibertyActionNode(Constants.LIBERTY_DEV_STOP, module));
node.add(new LibertyActionNode(Constants.LIBERTY_DEV_TESTS, module));
node.add(new LibertyActionNode(Constants.VIEW_GRADLE_TEST_REPORT, module));
}

Tree tree = new Tree(top);
Expand All @@ -224,7 +145,7 @@ public static Tree buildTree(Project project, Color backgroundColor) {
DataManager.registerDataProvider(tree, newDataProvider);
TreeDataProvider treeDataProvider = (TreeDataProvider) DataManager.getDataProvider(tree);

treeDataProvider.setProjectMap(map);
treeDataProvider.setProjectMap(projectMap);

tree.addTreeSelectionListener(e -> {
Object node = e.getPath().getLastPathComponent();
Expand Down
87 changes: 86 additions & 1 deletion src/main/java/io/openliberty/tools/intellij/LibertyModules.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2022 IBM Corporation.
* Copyright (c) 2022, 2025 IBM Corporation.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
Expand All @@ -10,17 +10,23 @@

package io.openliberty.tools.intellij;

import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.VfsUtil;
import com.intellij.openapi.vfs.VirtualFile;
import io.openliberty.tools.intellij.util.*;
import org.xml.sax.SAXException;

import javax.xml.parsers.ParserConfigurationException;
import java.io.IOException;
import java.nio.file.Paths;
import java.util.*;

/**
* Singleton to save the Liberty modules in the open project
*/
public class LibertyModules {
private final static Logger LOGGER = Logger.getInstance(LibertyModules.class);

private static LibertyModules instance = null;

Expand All @@ -38,6 +44,67 @@ public synchronized static LibertyModules getInstance() {
return instance;
}

/**
* Remove existing data and scan the project for the modules that are Liberty apps.
* @return this singleton, the list will be empty if there are no Liberty modules
*/
public LibertyModules scanLibertyModules(Project project) {
synchronized (libertyModules) {
removeForProject(project); // remove previous data, if any
return rescanLibertyModules(project);
}
}

/**
* Scan the project for the modules that are Liberty apps and update any existing entries.
* @return this singleton, the list will be empty if there are no Liberty modules
*/
public LibertyModules rescanLibertyModules(Project project) {
synchronized (libertyModules) {
ArrayList<BuildFile> buildFiles = new ArrayList<>();
try {
buildFiles.addAll(LibertyProjectUtil.getMavenBuildFiles(project));
} catch (IOException | SAXException | ParserConfigurationException e) {
LOGGER.error("I/O error or error parsing Liberty Maven projects in workspace", e);
}
try { // search for Gradle files even if Maven files experience error
buildFiles.addAll(LibertyProjectUtil.getGradleBuildFiles(project));
} catch (IOException | SAXException | ParserConfigurationException e) {
LOGGER.error("I/O error or error parsing Liberty Gradle projects in workspace", e);
}

for (BuildFile buildFile : buildFiles) {
// create a new Liberty Module object for this project
VirtualFile virtualFile = buildFile.getBuildFile();
String projectName = null;
if (virtualFile == null) {
LOGGER.error(String.format("Could not resolve current project %s", virtualFile));
break;
}
try {
if (buildFile.getProjectType().equals(Constants.LIBERTY_MAVEN_PROJECT)) {
projectName = LibertyMavenUtil.getProjectNameFromPom(virtualFile);
} else {
projectName = LibertyGradleUtil.getProjectName(virtualFile);
}
} catch (Exception e) {
LOGGER.warn(String.format("Could not resolve project name from build file: %s", virtualFile), e);
}
if (projectName == null) {
if (virtualFile.getParent() != null) {
projectName = virtualFile.getParent().getName();
} else {
projectName = project.getName();
}
}

boolean validContainerVersion = buildFile.isValidContainerVersion();
addLibertyModule(new LibertyModule(project, virtualFile, projectName, buildFile.getProjectType(), validContainerVersion));
}
}
return getInstance();
}

/**
* Add tracked Liberty project to workspace, update project,
* projectType, name and validContainerVersion if already tracked.
Expand Down Expand Up @@ -101,6 +168,24 @@ public List<String> getLibertyBuildFilesAsString(Project project) {
return sBuildFiles;
}

/**
* Returns all Liberty modules for the given project
*
* @param project
* @return Liberty modules for the given project
*/
public List<LibertyModule> getLibertyModules(Project project) {
ArrayList<LibertyModule> supportedLibertyModules = new ArrayList<>();
synchronized (libertyModules) {
libertyModules.values().forEach(libertyModule -> {
if (project.equals(libertyModule.getProject())) {
supportedLibertyModules.add(libertyModule);
}
});
}
return supportedLibertyModules;
}

/**
* Returns all Liberty modules with the supported project type(s) for the given project
* ex. all Liberty Maven projects
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2022, 2024 IBM Corporation.
* Copyright (c) 2022, 2025 IBM Corporation.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
Expand Down Expand Up @@ -39,13 +39,13 @@ public class LibertyRunConfiguration extends ModuleBasedConfiguration<RunConfigu
protected static Logger LOGGER = Logger.getInstance(LibertyRunConfiguration.class);

private final LibertyModules libertyModules;
private LibertyModule libertyModule;
@NonNls
private static final String RUN_IN_CONTAINER_TAG = "RUN_IN_CONTAINER";

public LibertyRunConfiguration(Project project, ConfigurationFactory factory, String name) {
super(name, getRunConfigurationModule(project), factory);
this.libertyModules = LibertyModules.getInstance();
// Find Liberty modules here to populate config field called "build file" and avoid NPE
this.libertyModules = LibertyModules.getInstance().rescanLibertyModules(project);
}

@NotNull
Expand Down Expand Up @@ -117,6 +117,7 @@ public SettingsEditor<? extends RunConfiguration> getConfigurationEditor() {
@Nullable
@Override
public RunProfileState getState(@NotNull Executor executor, @NotNull ExecutionEnvironment environment) throws ExecutionException {
LibertyModule libertyModule;
try {
libertyModule = libertyModules.getLibertyProjectFromString(getBuildFile());
} catch (NullPointerException e) {
Expand Down
11 changes: 8 additions & 3 deletions src/main/java/io/openliberty/tools/intellij/util/BuildFile.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2020, 2024 IBM Corporation.
* Copyright (c) 2020, 2025 IBM Corporation.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
Expand All @@ -25,7 +25,14 @@ public String getProjectType() {
return projectType;
}

/**
* Liberty project type must be Gradle or Maven.
* @param projectType
*/
public void setProjectType(String projectType) {
if (!Constants.LIBERTY_GRADLE_PROJECT.equals(projectType) && !Constants.LIBERTY_MAVEN_PROJECT.equals(projectType)) {
throw new IllegalArgumentException("Only Gradle and Maven project types are supported: " + projectType);
}
this.projectType = projectType;
}

Expand Down Expand Up @@ -58,6 +65,4 @@ public String getProjectName() {
public void setProjectName(String projectName) {
this.projectName = projectName;
}


}
Loading

0 comments on commit 034fa10

Please sign in to comment.