-
Notifications
You must be signed in to change notification settings - Fork 33
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
Browse the repository at this point in the history
- Loading branch information
Showing
8 changed files
with
292 additions
and
3 deletions.
There are no files selected for viewing
198 changes: 198 additions & 0 deletions
198
cli/src/main/java/com/devonfw/tools/ide/tool/PluginBasedCommandlet.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,198 @@ | ||
package com.devonfw.tools.ide.tool; | ||
|
||
import java.io.IOException; | ||
import java.nio.file.Files; | ||
import java.nio.file.Path; | ||
import java.nio.file.Paths; | ||
import java.util.Collection; | ||
import java.util.Collections; | ||
import java.util.HashMap; | ||
import java.util.Iterator; | ||
import java.util.Map; | ||
import java.util.Set; | ||
import java.util.stream.Stream; | ||
|
||
import com.devonfw.tools.ide.cli.CliException; | ||
import com.devonfw.tools.ide.common.Tag; | ||
import com.devonfw.tools.ide.context.IdeContext; | ||
import com.devonfw.tools.ide.io.FileAccess; | ||
import com.devonfw.tools.ide.tool.ide.IdeToolCommandlet; | ||
import com.devonfw.tools.ide.tool.ide.PluginDescriptor; | ||
import com.devonfw.tools.ide.tool.ide.PluginDescriptorImpl; | ||
|
||
public abstract class PluginBasedCommandlet extends LocalToolCommandlet { | ||
|
||
private Map<String, PluginDescriptor> pluginsMap; | ||
|
||
private Collection<PluginDescriptor> configuredPlugins; | ||
|
||
/** | ||
* The constructor. | ||
* | ||
* @param context the {@link IdeContext}. | ||
* @param tool the {@link #getName() tool name}. | ||
* @param tags the {@link #getTags() tags} classifying the tool. Should be created via {@link Set#of(Object) Set.of} | ||
* method. | ||
*/ | ||
public PluginBasedCommandlet(IdeContext context, String tool, Set<Tag> tags) { | ||
|
||
super(context, tool, tags); | ||
} | ||
|
||
protected Map<String, PluginDescriptor> getPluginsMap() { | ||
|
||
if (this.pluginsMap == null) { | ||
Map<String, PluginDescriptor> map = new HashMap<>(); | ||
|
||
// Load project-specific plugins | ||
Path pluginsPath = getPluginsConfigPath(); | ||
loadPluginsFromDirectory(map, pluginsPath); | ||
|
||
// Load user-specific plugins | ||
Path userPluginsPath = getUserHomePluginsConfigPath(); | ||
loadPluginsFromDirectory(map, userPluginsPath); | ||
|
||
this.pluginsMap = map; | ||
} | ||
|
||
return this.pluginsMap; | ||
} | ||
|
||
private void loadPluginsFromDirectory(Map<String, PluginDescriptor> map, Path pluginsPath) { | ||
if (Files.isDirectory(pluginsPath)) { | ||
try (Stream<Path> childStream = Files.list(pluginsPath)) { | ||
Iterator<Path> iterator = childStream.iterator(); | ||
while (iterator.hasNext()) { | ||
Path child = iterator.next(); | ||
String filename = child.getFileName().toString(); | ||
if (filename.endsWith(IdeContext.EXT_PROPERTIES) && Files.exists(child)) { | ||
PluginDescriptor descriptor = PluginDescriptorImpl.of(child, this.context, isPluginUrlNeeded()); | ||
|
||
// Priority to user-specific plugins | ||
map.put(descriptor.getName(), descriptor); | ||
} | ||
} | ||
} catch (IOException e) { | ||
throw new IllegalStateException("Failed to list children of directory " + pluginsPath, e); | ||
} | ||
} | ||
} | ||
|
||
/** | ||
* @return {@code true} if {@link PluginDescriptor#getUrl() plugin URL} property is needed, {@code false} otherwise. | ||
*/ | ||
protected boolean isPluginUrlNeeded() { | ||
|
||
return false; | ||
} | ||
|
||
protected Path getPluginsConfigPath() { | ||
|
||
return this.context.getSettingsPath().resolve(this.tool).resolve(IdeContext.FOLDER_PLUGINS); | ||
} | ||
|
||
private Path getUserHomePluginsConfigPath() { | ||
|
||
return context.getUserHome().resolve(Paths.get(".ide", "settings", this.tool, 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. | ||
*/ | ||
public Path getPluginsInstallationPath() { | ||
|
||
return this.context.getPluginsPath().resolve(this.tool); | ||
} | ||
|
||
/** | ||
* @param plugin the {@link PluginDescriptor} to install. | ||
*/ | ||
public abstract void installPlugin(PluginDescriptor plugin); | ||
|
||
/** | ||
* @param plugin the {@link PluginDescriptor} to uninstall. | ||
*/ | ||
public void uninstallPlugin(PluginDescriptor plugin) { | ||
|
||
Path pluginsPath = getPluginsInstallationPath(); | ||
if (!Files.isDirectory(pluginsPath)) { | ||
this.context.debug("Omitting to uninstall plugin {} ({}) as plugins folder does not exist at {}", | ||
plugin.getName(), plugin.getId(), pluginsPath); | ||
return; | ||
} | ||
FileAccess fileAccess = this.context.getFileAccess(); | ||
Path match = fileAccess.findFirst(pluginsPath, p -> p.getFileName().toString().startsWith(plugin.getId()), false); | ||
if (match == null) { | ||
this.context.debug("Omitting to uninstall plugin {} ({}) as plugins folder does not contain a match at {}", | ||
plugin.getName(), plugin.getId(), pluginsPath); | ||
return; | ||
} | ||
fileAccess.delete(match); | ||
} | ||
|
||
/** | ||
* @param key the filename of the properties file configuring the requested plugin (typically excluding the | ||
* ".properties" extension). | ||
* @return the {@link PluginDescriptor} for the given {@code key}. | ||
*/ | ||
public PluginDescriptor getPlugin(String key) { | ||
|
||
if (key == null) { | ||
return null; | ||
} | ||
if (key.endsWith(IdeContext.EXT_PROPERTIES)) { | ||
key = key.substring(0, key.length() - IdeContext.EXT_PROPERTIES.length()); | ||
} | ||
PluginDescriptor pluginDescriptor = getPluginsMap().get(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) { | ||
|
||
boolean newlyInstalled = super.doInstall(silent); | ||
// post installation... | ||
boolean installPlugins = newlyInstalled; | ||
Path pluginsInstallationPath = getPluginsInstallationPath(); | ||
if (newlyInstalled) { | ||
this.context.getFileAccess().delete(pluginsInstallationPath); | ||
} else if (!Files.isDirectory(pluginsInstallationPath)) { | ||
installPlugins = true; | ||
} | ||
if (installPlugins) { | ||
for (PluginDescriptor plugin : getPluginsMap().values()) { | ||
if (plugin.isActive()) { | ||
installPlugin(plugin); | ||
} else { | ||
handleInstall4InactivePlugin(plugin); | ||
} | ||
} | ||
} | ||
return newlyInstalled; | ||
} | ||
|
||
/** | ||
* @param plugin the in{@link PluginDescriptor#isActive() active} {@link PluginDescriptor} that is skipped for regular | ||
* plugin installation. | ||
*/ | ||
protected void handleInstall4InactivePlugin(PluginDescriptor plugin) { | ||
|
||
this.context.debug("Omitting installation of inactive plugin {} ({}).", plugin.getName(), plugin.getId()); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
1 change: 0 additions & 1 deletion
1
cli/src/test/java/com/devonfw/tools/ide/commandlet/EnvironmentCommandletTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
27 changes: 27 additions & 0 deletions
27
cli/src/test/java/com/devonfw/tools/ide/tool/ExamplePluginBasedCommandlet.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
package com.devonfw.tools.ide.tool; | ||
|
||
import java.util.Set; | ||
|
||
import com.devonfw.tools.ide.common.Tag; | ||
import com.devonfw.tools.ide.context.IdeContext; | ||
import com.devonfw.tools.ide.tool.ide.PluginDescriptor; | ||
|
||
public class ExamplePluginBasedCommandlet extends PluginBasedCommandlet { | ||
/** | ||
* The constructor. | ||
* | ||
* @param context the {@link IdeContext}. | ||
* @param tool the {@link #getName() tool name}. | ||
* @param tags the {@link #getTags() tags} classifying the tool. Should be created via {@link Set#of(Object) Set.of} | ||
* method. | ||
*/ | ||
public ExamplePluginBasedCommandlet(IdeContext context, String tool, Set<Tag> tags) { | ||
|
||
super(context, tool, tags); | ||
} | ||
|
||
@Override | ||
public void installPlugin(PluginDescriptor plugin) { | ||
|
||
} | ||
} |
41 changes: 41 additions & 0 deletions
41
cli/src/test/java/com/devonfw/tools/ide/tool/PluginBasedCommandletTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
package com.devonfw.tools.ide.tool; | ||
|
||
import static org.junit.jupiter.api.Assertions.*; | ||
|
||
import java.util.Map; | ||
import java.util.Set; | ||
|
||
import org.junit.jupiter.api.Test; | ||
|
||
import com.devonfw.tools.ide.common.Tag; | ||
import com.devonfw.tools.ide.context.AbstractIdeContextTest; | ||
import com.devonfw.tools.ide.context.IdeTestContext; | ||
import com.devonfw.tools.ide.tool.ide.PluginDescriptor; | ||
|
||
public class PluginBasedCommandletTest extends AbstractIdeContextTest { | ||
|
||
@Test | ||
void testGetPluginsMap() { | ||
IdeTestContext context = newContext(PROJECT_BASIC, "", true); | ||
String tool = "eclipse"; | ||
Set<Tag> tags = null; | ||
ExamplePluginBasedCommandlet pluginBasedCommandlet = new ExamplePluginBasedCommandlet(context, tool, tags); | ||
|
||
Map<String, PluginDescriptor> pluginsMap = pluginBasedCommandlet.getPluginsMap(); | ||
assertNotNull(pluginsMap); | ||
|
||
assertTrue(pluginsMap.containsKey("checkstyle")); | ||
assertTrue(pluginsMap.containsKey("anyedit")); | ||
|
||
PluginDescriptor plugin1 = pluginsMap.get("checkstyle"); | ||
assertNotNull(plugin1); | ||
assertEquals("checkstyle", plugin1.getName()); | ||
|
||
PluginDescriptor plugin2 = pluginsMap.get("anyedit"); | ||
assertNotNull(plugin2); | ||
assertEquals("anyedit", plugin2.getName()); | ||
|
||
// Check if anyedit plugin has value "false" --> value from user directory | ||
assertEquals(false, plugin2.isActive()); | ||
} | ||
} |
3 changes: 3 additions & 0 deletions
3
...c/test/resources/ide-projects/basic/home/.ide/settings/eclipse/plugins/anyedit.properties
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
plugin_url=https://raw.githubusercontent.com/iloveeclipse/plugins/latest/ | ||
plugin_id=AnyEditTools.feature.group | ||
plugin_active=false |
3 changes: 3 additions & 0 deletions
3
cli/src/test/resources/ide-projects/basic/settings/eclipse/plugins/anyedit.properties
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
plugin_url=https://raw.githubusercontent.com/iloveeclipse/plugins/latest/ | ||
plugin_id=AnyEditTools.feature.group | ||
plugin_active=true |
3 changes: 3 additions & 0 deletions
3
cli/src/test/resources/ide-projects/basic/settings/eclipse/plugins/checkstyle.properties
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
plugin_url=https://checkstyle.org/eclipse-cs-update-site | ||
plugin_id=net.sf.eclipsecs.feature.group | ||
plugin_active=true |