Skip to content

Commit

Permalink
devonfw/ide#1309: Improve plugin managment (#229)
Browse files Browse the repository at this point in the history
  • Loading branch information
diiinesh authored May 27, 2024
1 parent 195d40c commit 998ef92
Show file tree
Hide file tree
Showing 3 changed files with 92 additions and 34 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,7 @@

import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
Expand All @@ -23,9 +19,7 @@
*/
public abstract class PluginBasedCommandlet extends LocalToolCommandlet {

private Map<String, PluginDescriptor> pluginsMap;

private Collection<PluginDescriptor> configuredPlugins;
private PluginMaps pluginsMap;

/**
* The constructor.
Expand All @@ -40,10 +34,10 @@ public PluginBasedCommandlet(IdeContext context, String tool, Set<Tag> tags) {
super(context, tool, tags);
}

protected Map<String, PluginDescriptor> getPluginsMap() {
protected PluginMaps getPluginsMap() {

if (this.pluginsMap == null) {
Map<String, PluginDescriptor> map = new HashMap<>();
PluginMaps map = new PluginMaps(context);

// Load project-specific plugins
Path pluginsPath = getPluginsConfigPath();
Expand All @@ -60,16 +54,13 @@ protected Map<String, PluginDescriptor> getPluginsMap() {
return this.pluginsMap;
}

private void loadPluginsFromDirectory(Map<String, PluginDescriptor> map, Path pluginsPath) {
private void loadPluginsFromDirectory(PluginMaps map, Path pluginsPath) {

List<Path> children = this.context.getFileAccess()
.listChildren(pluginsPath, p -> p.getFileName().toString().endsWith(IdeContext.EXT_PROPERTIES));
for (Path child : children) {
PluginDescriptor descriptor = PluginDescriptorImpl.of(child, this.context, isPluginUrlNeeded());
PluginDescriptor duplicate = map.put(descriptor.getName(), descriptor);
if (duplicate != null) {
this.context.info("Plugin {} from project is overridden by {}", descriptor.getName(), child);
}
map.add(descriptor);
}
}

Expand All @@ -94,17 +85,6 @@ private Path getUserHomePluginsConfigPath() {
return this.context.getUserHomeIde().resolve("settings").resolve(this.tool).resolve(IdeContext.FOLDER_PLUGINS);
}

/**
* @return the immutable {@link Collection} of {@link PluginDescriptor}s configured for this IDE tool.
*/
public Collection<PluginDescriptor> getConfiguredPlugins() {

if (this.configuredPlugins == null) {
this.configuredPlugins = Collections.unmodifiableCollection(getPluginsMap().values());
}
return this.configuredPlugins;
}

/**
* @return the {@link Path} where the plugins of this {@link IdeToolCommandlet} shall be installed.
*/
Expand Down Expand Up @@ -152,14 +132,17 @@ public PluginDescriptor getPlugin(String key) {
if (key.endsWith(IdeContext.EXT_PROPERTIES)) {
key = key.substring(0, key.length() - IdeContext.EXT_PROPERTIES.length());
}
PluginDescriptor pluginDescriptor = getPluginsMap().get(key);

PluginMaps pluginMaps = getPluginsMap();
PluginDescriptor pluginDescriptor = pluginMaps.getByName(key);
if (pluginDescriptor == null) {
throw new CliException(
"Could not find plugin " + key + " at " + getPluginsConfigPath().resolve(key) + ".properties");
}
return pluginDescriptor;
}


@Override
protected boolean doInstall(boolean silent) {

Expand All @@ -173,7 +156,8 @@ protected boolean doInstall(boolean silent) {
installPlugins = true;
}
if (installPlugins) {
for (PluginDescriptor plugin : getPluginsMap().values()) {
PluginMaps pluginMaps = getPluginsMap();
for (PluginDescriptor plugin : pluginMaps.getPlugins()) {
if (plugin.isActive()) {
installPlugin(plugin);
} else {
Expand Down
75 changes: 75 additions & 0 deletions cli/src/main/java/com/devonfw/tools/ide/tool/PluginMaps.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
package com.devonfw.tools.ide.tool;

import com.devonfw.tools.ide.context.IdeContext;
import com.devonfw.tools.ide.tool.ide.PluginDescriptor;

import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

/**
* A wrapper class for holding two maps of plugin descriptors: one keyed by plugin ID and the other keyed by plugin name.
*/
public class PluginMaps {
private final Map<String, PluginDescriptor> mapById;
private final Map<String, PluginDescriptor> mapByName;


private final IdeContext context;

/**
* The constructor.
* @param context the {@link IdeContext}.
*/
public PluginMaps(IdeContext context) {
super();
this.context = context;
this.mapById = new HashMap<>();
this.mapByName = new HashMap<>();
}

/**
* @return the {@link PluginDescriptor} for the given {@link PluginDescriptor#getId() ID} or {@code null} if not found.
*/
public PluginDescriptor getById(String id) {
return this.mapById.get(id);
}

/**
* @return the {@link PluginDescriptor} for the given {@link PluginDescriptor#getName() name} or {@code null} if not found.
*/
public PluginDescriptor getByName(String name) {
return this.mapByName.get(name);
}

/**
* @return the immutable {@link Collection} of {@link PluginDescriptor}s configured for this IDE tool.
*/
public Collection<PluginDescriptor> getPlugins() {

Map<String, PluginDescriptor> map = this.mapById;
if (map.isEmpty()) {
map = this.mapByName; // potentially plugins for this tool have no ID
}
return Collections.unmodifiableCollection(map.values());
}

/**
* Registers a {@link PluginDescriptor} to this map.
*/
protected void add(PluginDescriptor descriptor) {
put(descriptor.getName(), descriptor, this.mapByName);
String id = descriptor.getId();
if ((id != null) && !id.isEmpty()) {
put(id, descriptor, this.mapById);
}
}

public void put(String key, PluginDescriptor descriptor, Map<String, PluginDescriptor> map) {
PluginDescriptor duplicate = map.put(key, descriptor);
if (duplicate != null) {
this.context.info("Plugin with key {} was {} but got overridden by {}", key, duplicate, descriptor);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
import com.devonfw.tools.ide.tool.ide.PluginDescriptor;
import org.junit.jupiter.api.Test;

import java.util.Map;
import java.util.Set;

import static org.junit.jupiter.api.Assertions.assertNotNull;
Expand All @@ -24,21 +23,21 @@ void testGetPluginsMap() {
Set<Tag> tags = null;
ExamplePluginBasedCommandlet pluginBasedCommandlet = new ExamplePluginBasedCommandlet(context, tool, tags);

Map<String, PluginDescriptor> pluginsMap = pluginBasedCommandlet.getPluginsMap();
PluginMaps pluginsMap = pluginBasedCommandlet.getPluginsMap();
assertThat(pluginsMap).isNotNull();

assertThat(pluginsMap.containsKey("checkstyle")).isTrue();
assertThat(pluginsMap.containsKey("anyedit")).isTrue();
assertThat(pluginsMap.getByName("checkstyle")).isNotNull();
assertThat(pluginsMap.getByName("anyedit")).isNotNull();

PluginDescriptor plugin1 = pluginsMap.get("checkstyle");
PluginDescriptor plugin1 = pluginsMap.getByName("checkstyle");
assertNotNull(plugin1);
assertThat(plugin1.getName()).isEqualTo("checkstyle");

PluginDescriptor plugin2 = pluginsMap.get("anyedit");
PluginDescriptor plugin2 = pluginsMap.getByName("anyedit");
assertNotNull(plugin2);
assertThat(plugin2.getName()).isEqualTo("anyedit");

// Check if anyedit plugin has value "false" --> value from user directory
assertThat(plugin2.isActive()).isFalse();
}
}
}

0 comments on commit 998ef92

Please sign in to comment.