Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/plugin manager #24

Merged
merged 6 commits into from
Dec 10, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 10 additions & 12 deletions core/src/main/java/dk/gtz/graphedit/model/ModelEditorSettings.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,9 @@
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

import dk.gtz.graphedit.util.PlatformUtils;
import dk.gtz.graphedit.util.EditorActions;
import dk.gtz.graphedit.viewmodel.ViewModelEditorSettings;

/**
Expand All @@ -23,6 +24,7 @@
* @param showTraceToasts When true, will display toasts on logger.trace calls
* @param lastOpenedProject Filepath to the last opened graphedit project file
* @param recentProjects List of filepaths that have been recently opened
* @param disabledPlugins List of plugin filepaths that are disabled
*/
public record ModelEditorSettings(
double gridSizeX,
Expand All @@ -36,13 +38,14 @@ public record ModelEditorSettings(
boolean showErrorToasts,
boolean showTraceToasts,
String lastOpenedProject,
List<String> recentProjects) {
List<String> recentProjects,
List<String> disabledPlugins) {

/**
* Constructs a ModelEditorSettings instance with default values.
*/
public ModelEditorSettings() {
this(20.0d, 20.0d, true, false, true, false, true, true, true, false, "", new ArrayList<>());
this(20.0d, 20.0d, true, false, true, false, true, true, true, false, "", new ArrayList<>(), new ArrayList<>());
}

/**
Expand All @@ -61,7 +64,9 @@ public ModelEditorSettings(ViewModelEditorSettings viewmodel) {
viewmodel.showErrorToasts().get(),
viewmodel.showTraceToasts().get(),
viewmodel.lastOpenedProject().get(),
new ArrayList<String>(viewmodel.recentProjects().get()));
new ArrayList<String>(viewmodel.recentProjects().get()),
new ArrayList<String>(viewmodel.disabledPlugins().get())
);
}

/**
Expand All @@ -70,13 +75,6 @@ public ModelEditorSettings(ViewModelEditorSettings viewmodel) {
* @return The OS-specific file path to editor settings
*/
public static Path getEditorSettingsFile() {
if(PlatformUtils.isWindows())
return Path.of(System.getenv("AppData") + File.separator + "graphedit-settings.json");
var userHome = System.getProperty("user.home");
if(PlatformUtils.isMac())
userHome += "/Library/Application Support/Graphedit/";
else
userHome += "/.local/graphedit/";
return Path.of(userHome + "graphedit-settings.json");
return Path.of(EditorActions.getConfigDir() + File.separator + "graphedit-settings.json");
}
}
8 changes: 8 additions & 0 deletions core/src/main/java/dk/gtz/graphedit/spi/IPlugin.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,14 @@ public interface IPlugin {
*/
String getName();

/**
* Get a general description of this plugin
* @return A description of what kinds of utilities this plugin provides
*/
default String getDescription() {
return "";
}

/**
* Event called when the plugin is initialized.
* At this point, most things are registered in {@link DI}.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,4 +49,10 @@ public interface IPluginsContainer {
* @return The underlying collection of plugins
*/
Collection<IPlugin> getPlugins();

/**
* Get a collection of plugins filtered such that it only contains the enabled plugins
* @return A collection of the enabled plugins
*/
Collection<IPlugin> getEnabledPlugins();
}
9 changes: 9 additions & 0 deletions core/src/main/java/dk/gtz/graphedit/util/EditorActions.java
Original file line number Diff line number Diff line change
Expand Up @@ -587,4 +587,13 @@ public static ModelProjectResource createNewModel(String modelName) {
var exampleGraph = new ModelGraph("", exampleVertices, exampleEdges);
return new ModelProjectResource(exampleMetaData, exampleGraph);
}

public static String getConfigDir() {
if(PlatformUtils.isWindows())
return String.join(File.separator, System.getenv("AppData"), "graphedit").toString();
var userHome = System.getProperty("user.home");
if(PlatformUtils.isMac())
return String.join(File.separator, userHome, "Library", "Application Support", "Graphedit");
return String.join(File.separator, userHome, ".local", "graphedit");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import dk.gtz.graphedit.spi.IPlugin;
import dk.gtz.graphedit.spi.IPluginPanel;
import dk.gtz.graphedit.spi.IPluginsContainer;
import dk.gtz.graphedit.viewmodel.ViewModelEditorSettings;
import dk.yalibs.yadi.DI;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleObjectProperty;
Expand Down Expand Up @@ -39,13 +40,14 @@ public SidePanelController() {
@FXML
private void initialize() {
var plugins = DI.get(IPluginsContainer.class);
var settings = DI.get(ViewModelEditorSettings.class);
if(plugins.getPlugins().isEmpty()) {
logger.warn("No plugins are loaded, cannot show sidepanel");
return;
}
left.setSpacing(20);
left.setPadding(new Insets(15));
for(var plugin : plugins.getPlugins()) {
for(var plugin : plugins.getEnabledPlugins()) {
try {
initializePluginTab(plugin);
} catch(Exception e) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,8 @@ public record ViewModelEditorSettings(
BooleanProperty showErrorToasts,
BooleanProperty showTraceToasts,
StringProperty lastOpenedProject,
ListProperty<String> recentProjects) {
ListProperty<String> recentProjects,
ListProperty<String> disabledPlugins) {

/**
* Construct a new instance
Expand All @@ -59,9 +60,13 @@ public ViewModelEditorSettings(ModelEditorSettings settings) {
settings.showErrorToasts(),
settings.showTraceToasts(),
settings.lastOpenedProject(),
new SimpleListProperty<String>(FXCollections.observableArrayList()),
new SimpleListProperty<String>(FXCollections.observableArrayList())
);
this.recentProjects.addAll(settings.recentProjects());
if(settings.recentProjects() != null)
this.recentProjects.addAll(settings.recentProjects());
if(settings.disabledPlugins() != null)
this.disabledPlugins.addAll(settings.disabledPlugins());
}

/**
Expand Down Expand Up @@ -91,7 +96,8 @@ public ViewModelEditorSettings(
boolean showErrorToasts,
boolean showTraceToasts,
String lastOpenedProject,
List<String> recentProjects) {
List<String> recentProjects,
List<String> disabledPlugins) {
this(
new SimpleDoubleProperty(gridSizeX),
new SimpleDoubleProperty(gridSizeY),
Expand All @@ -104,8 +110,10 @@ public ViewModelEditorSettings(
new SimpleBooleanProperty(showErrorToasts),
new SimpleBooleanProperty(showTraceToasts),
new SimpleStringProperty(lastOpenedProject),
new SimpleListProperty<String>(FXCollections.observableArrayList()),
new SimpleListProperty<String>(FXCollections.observableArrayList())
);
this.recentProjects.addAll(recentProjects);
this.disabledPlugins.addAll(disabledPlugins);
}
}
14 changes: 2 additions & 12 deletions graphedit/src/main/java/dk/gtz/graphedit/Args.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,23 +5,13 @@

import com.beust.jcommander.Parameter;

import dk.gtz.graphedit.util.PlatformUtils;
import dk.gtz.graphedit.util.EditorActions;

public class Args {
@Parameter(names = { "-h", "--help" }, description = "Show this message")
public Boolean help = false;
@Parameter(names = { "-v", "--verbosity" }, description = "Set verbosity level")
public String verbosity = "INFO";
@Parameter(names = { "-P", "--plugin-dir" }, description = "Set directory to look for plugins in")
public List<String> pluginDirs = List.of("plugins", String.join(File.separator, configDir(), "plugins"));

private static String configDir() {
if(PlatformUtils.isWindows())
return String.join(File.separator, System.getenv("AppData"), "graphedit").toString();
var userHome = System.getProperty("user.home");
if(PlatformUtils.isMac())
return String.join(File.separator, userHome, "Library", "Application Support", "Graphedit");
return String.join(File.separator, userHome, ".local", "graphedit");
}
public List<String> pluginDirs = List.of("plugins", String.join(File.separator, EditorActions.getConfigDir(), "plugins"));
}

17 changes: 12 additions & 5 deletions graphedit/src/main/java/dk/gtz/graphedit/Main.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,11 @@
import dk.gtz.graphedit.serialization.IModelSerializer;
import dk.gtz.graphedit.serialization.JacksonModelSerializer;
import dk.gtz.graphedit.spi.IPluginsContainer;
import dk.gtz.graphedit.util.EditorActions;
import dk.gtz.graphedit.view.GraphEditApplication;
import dk.gtz.graphedit.viewmodel.LanguageServerCollection;
import dk.gtz.graphedit.viewmodel.SyntaxFactoryCollection;
import dk.gtz.graphedit.viewmodel.ViewModelEditorSettings;
import dk.yalibs.yadi.DI;

public class Main {
Expand All @@ -32,29 +34,34 @@ public static void main(String[] argv) throws Exception {
return;
}

DI.add(IModelSerializer.class, new JacksonModelSerializer());
var loader = new PluginLoader(args.pluginDirs, DI.get(IModelSerializer.class)).loadPlugins();
var factories = new SyntaxFactoryCollection();
var servers = new LanguageServerCollection();
DI.add(SyntaxFactoryCollection.class, factories);
DI.add(LanguageServerCollection.class, servers);
DI.add(IModelSerializer.class, new JacksonModelSerializer());
var editorSettings = EditorActions.loadEditorSettings();
DI.add(ViewModelEditorSettings.class, editorSettings);

var loader = new PluginLoader(args.pluginDirs, DI.get(IModelSerializer.class)).loadPlugins();
DI.add(IPluginsContainer.class, loader.getLoadedPlugins());
for(var plugin : loader.getLoadedPlugins().getPlugins())
for(var plugin : loader.getLoadedPlugins().getEnabledPlugins()) {
plugin.onInitialize();
for(var plugin : loader.getLoadedPlugins().getPlugins()) {
}
for(var plugin : loader.getLoadedPlugins().getEnabledPlugins()) {
try {
factories.add(plugin.getSyntaxFactories());
} catch (Exception e) {
logger.error("could not load syntax factories for plugin: {}", plugin.getName(), e);
}
}
for(var plugin : loader.getLoadedPlugins().getPlugins()) {
for(var plugin : loader.getLoadedPlugins().getEnabledPlugins()) {
try {
servers.add(plugin.getLanguageServers());
} catch (Exception e) {
logger.error("could not load language servers for plugin: {}", plugin.getName(), e);
}
}

if(servers.isEmpty())
logger.warn("No language servers loaded. Expect a very simple experience");
if(factories.isEmpty())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,20 @@

import java.util.List;
import java.util.Optional;

import dk.gtz.graphedit.spi.IPlugin;
import dk.gtz.graphedit.spi.IPluginsContainer;
import dk.gtz.graphedit.viewmodel.ViewModelEditorSettings;
import dk.yalibs.yadi.DI;
import javafx.collections.ObservableSet;
import javafx.collections.FXCollections;

public class ObservableSetPluginsContainer implements IPluginsContainer {
private final ObservableSet<IPlugin> plugins;
private final ViewModelEditorSettings settings;

public ObservableSetPluginsContainer() {
plugins = FXCollections.observableSet();
settings = DI.get(ViewModelEditorSettings.class);
}

@Override
Expand Down Expand Up @@ -53,5 +56,9 @@ public Optional<IPlugin> get(String name) {
public ObservableSet<IPlugin> getPlugins() {
return plugins;
}
}

@Override
public List<IPlugin> getEnabledPlugins() {
return plugins.stream().filter(p -> !settings.disabledPlugins().contains(p.getName())).toList();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@
import dk.gtz.graphedit.tool.VertexDeleteTool;
import dk.gtz.graphedit.tool.VertexDragMoveTool;
import dk.gtz.graphedit.tool.ViewTool;
import dk.gtz.graphedit.util.EditorActions;
import dk.gtz.graphedit.util.IObservableUndoSystem;
import dk.gtz.graphedit.util.MouseTracker;
import dk.gtz.graphedit.util.ObservableStackUndoSystem;
Expand Down Expand Up @@ -119,7 +118,6 @@ private void setupApplication() {
DI.add(LintContainer.class, new LintContainer());
ObservableList<ISelectable> selectedElementsList = FXCollections.observableArrayList();
DI.add("selectedElements", selectedElementsList);
DI.add(ViewModelEditorSettings.class, EditorActions.loadEditorSettings());
}

private void setupLSPs(LanguageServerCollection servers, File projectFile, IBufferContainer buffers, LintContainer lints) {
Expand Down Expand Up @@ -172,7 +170,7 @@ private void loadProject() throws Exception {
var settings = DI.get(ViewModelEditorSettings.class);
var projectFilePath = Path.of(settings.lastOpenedProject().get());
if(!projectFilePath.toFile().exists())
throw new Exception("not a valid project file path, will load temp project " + projectFilePath.toString());
throw new Exception("project file path does not exist '" + projectFilePath.toString() + "', loading tmp project instead");
var project = DI.get(IModelSerializer.class).deserializeProject(projectFilePath.toFile());
DI.add(ViewModelProject.class, new ViewModelProject(project, Optional.of(projectFilePath.toFile().getParent())));
setupLSPs(DI.get(LanguageServerCollection.class), projectFilePath.toFile(), DI.get(IBufferContainer.class), DI.get(LintContainer.class));
Expand Down Expand Up @@ -235,6 +233,8 @@ private void setupLogging() {
@Override
public void stop() {
logger.trace("shutting down...");
if(lspThreads == null)
return;
for(var lspThread : lspThreads) {
logger.trace("interrupting lsp thread {}", lspThread.getName());
lspThread.interrupt();
Expand Down
7 changes: 3 additions & 4 deletions std/src/main/java/dk/gtz/graphedit/plugins/LintPanel.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,19 +8,18 @@
import javafx.scene.Node;

public class LintPanel implements IPluginPanel {

@Override
public String getTooltip() {
return "Lints";
return "Lints";
}

@Override
public Node getIcon() {
return new FontIcon(BootstrapIcons.STARS);
return new FontIcon(BootstrapIcons.STARS);
}

@Override
public Node getPanel() {
return new LintPanelController();
return new LintPanelController();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package dk.gtz.graphedit.plugins;

import org.kordamp.ikonli.bootstrapicons.BootstrapIcons;
import org.kordamp.ikonli.javafx.FontIcon;

import dk.gtz.graphedit.plugins.view.PluginManagementPanelController;
import dk.gtz.graphedit.spi.IPluginPanel;
import javafx.scene.Node;

public class PluginManagementPanel implements IPluginPanel {
@Override
public String getTooltip() {
return "Plugins";
}

@Override
public Node getIcon() {
return new FontIcon(BootstrapIcons.PLUG);
}

@Override
public Node getPanel() {
return new PluginManagementPanelController();
}
}
Loading