From: plaa Date: Mon, 18 Jun 2012 19:58:58 +0000 (+0000) Subject: Potential plugin structure X-Git-Tag: upstream/12.09^2~170 X-Git-Url: https://git.gag.com/?a=commitdiff_plain;h=ee2fda33d737bbf4396bf9b9f5275d08ab46aaa6;p=debian%2Fopenrocket Potential plugin structure git-svn-id: https://openrocket.svn.sourceforge.net/svnroot/openrocket/trunk@789 180e2498-e6e9-4542-8430-84ac67f01cd8 --- diff --git a/core/src/net/sf/openrocket/gui/plugin/DoSomethingPlugin.java b/core/src/net/sf/openrocket/gui/plugin/DoSomethingPlugin.java new file mode 100644 index 00000000..d238c4eb --- /dev/null +++ b/core/src/net/sf/openrocket/gui/plugin/DoSomethingPlugin.java @@ -0,0 +1,16 @@ +package net.sf.openrocket.gui.plugin; + +import javax.swing.Action; + +import net.sf.openrocket.document.OpenRocketDocument; +import net.sf.openrocket.gui.main.BasicFrame; + +public class DoSomethingPlugin extends OpenRocketSwingMenuPlugin { + + @Override + public Action getAction(BasicFrame frame, OpenRocketDocument document) { + // TODO Auto-generated method stub + return null; + } + +} diff --git a/core/src/net/sf/openrocket/gui/plugin/OpenRocketSwingMenuPlugin.java b/core/src/net/sf/openrocket/gui/plugin/OpenRocketSwingMenuPlugin.java new file mode 100644 index 00000000..e76e64a2 --- /dev/null +++ b/core/src/net/sf/openrocket/gui/plugin/OpenRocketSwingMenuPlugin.java @@ -0,0 +1,22 @@ +package net.sf.openrocket.gui.plugin; + +import java.util.List; + +import net.sf.openrocket.plugin.framework.Service; + +public abstract class OpenRocketSwingMenuPlugin implements Service, SwingMenuPlugin { + + @Override + public String[] getMenuPosition() { + // TODO Auto-generated method stub + return null; + } + + + @Override + public List getPlugins(Class type, Object... args) { + // TODO Auto-generated method stub + return null; + } + +} diff --git a/core/src/net/sf/openrocket/gui/plugin/SwingMenuPlugin.java b/core/src/net/sf/openrocket/gui/plugin/SwingMenuPlugin.java new file mode 100644 index 00000000..e27b78ac --- /dev/null +++ b/core/src/net/sf/openrocket/gui/plugin/SwingMenuPlugin.java @@ -0,0 +1,40 @@ +package net.sf.openrocket.gui.plugin; + +import javax.swing.Action; + +import net.sf.openrocket.document.OpenRocketDocument; +import net.sf.openrocket.gui.main.BasicFrame; + +/** + * A plugin that provides a menu item to the Swing GUI menus. + * This may open a dialog window or perform some other action on + * the current document. + *

+ * During plugin discovery, the BasicFrame and OpenRocketDocument + * objects are passed to the plugin. + * + * @author Sampo Niskanen + */ +public interface SwingMenuPlugin { + + /** + * Return the menu position where the action is placed. + * The first string in the array indicates the menu to place + * the item in, the second is the sub-menu, the third is the + * sub-sub-menu etc. + *

+ * The strings are translated menu names. + * + * @return the menu position for the action + */ + public String[] getMenuPosition(); + + /** + * Return the Action that the menu item performs. This contains + * the menu item text and may contain an icon. + * + * @return the action to perform on the menu item. + */ + public Action getAction(BasicFrame frame, OpenRocketDocument document); + +} diff --git a/core/src/net/sf/openrocket/plugin/AbstractService.java b/core/src/net/sf/openrocket/plugin/AbstractService.java deleted file mode 100644 index 02719646..00000000 --- a/core/src/net/sf/openrocket/plugin/AbstractService.java +++ /dev/null @@ -1,45 +0,0 @@ -package net.sf.openrocket.plugin; - -import java.util.Collections; -import java.util.List; - -import net.sf.openrocket.util.BugException; - -/** - * An abstract service implementation that returns plugins of type P. - * - * @param

the plugin type that this service returns. - * @author Sampo Niskanen - */ -public abstract class AbstractService

implements Service { - - private final Class

type; - - protected AbstractService(Class

type) { - this.type = type; - } - - @SuppressWarnings("unchecked") - @Override - public List getPlugins(Class e, Object... args) { - - if (e != type) { - return Collections.emptyList(); - } - - List

plugins = getPlugins(args); - - // Check list content types to avoid mysterious bugs later on - for (P p : plugins) { - if (!type.isInstance(p)) { - throw new BugException("Requesting plugins of type " + type + " but received " + - ((p != null) ? p.getClass() : "null")); - } - } - - return (List) plugins; - } - - protected abstract List

getPlugins(Object... args); - -} diff --git a/core/src/net/sf/openrocket/plugin/Configurable.java b/core/src/net/sf/openrocket/plugin/Configurable.java new file mode 100644 index 00000000..b8ebf6e2 --- /dev/null +++ b/core/src/net/sf/openrocket/plugin/Configurable.java @@ -0,0 +1,29 @@ +package net.sf.openrocket.plugin; + +public interface Configurable { + + + /** + * Return the plugin ID. This is a text string uniquely identifying this plugin. + * The recommended format is similar to the fully-qualified class name of the + * plugin, though a shorter format starting with the developer's domain name + * is also possible for future compatibility. + * + * @return the plugin ID + */ + public String getPluginID(); + + /** + * Test whether this plugin provides functionality corresponding to the specified + * plugin ID. This provides backwards compatibility if the plugin ID should change. + * + * @param pluginID the plugin ID to test + * @return whether this plugin provides the requested functionality + */ + public boolean isCompatible(String pluginID); + + public void loadFromXML(Object... objects); + + public void saveToXML(Object... objects); + +} diff --git a/core/src/net/sf/openrocket/plugin/JSPFPluginFactory.java b/core/src/net/sf/openrocket/plugin/JSPFPluginFactory.java deleted file mode 100644 index 6b598b69..00000000 --- a/core/src/net/sf/openrocket/plugin/JSPFPluginFactory.java +++ /dev/null @@ -1,50 +0,0 @@ -package net.sf.openrocket.plugin; - -import java.net.URI; -import java.net.URISyntaxException; -import java.util.ArrayList; -import java.util.List; - -import net.sf.openrocket.util.BugException; -import net.xeoh.plugins.base.Plugin; -import net.xeoh.plugins.base.PluginManager; -import net.xeoh.plugins.base.impl.PluginManagerFactory; -import net.xeoh.plugins.base.util.JSPFProperties; -import net.xeoh.plugins.base.util.PluginManagerUtil; - -public class JSPFPluginFactory implements PluginFactory { - - private final PluginManager pluginManager; - - public JSPFPluginFactory() { - - final JSPFProperties props = new JSPFProperties(); - - // props.setProperty(PluginManager.class, "cache.enabled", "true"); - // props.setProperty(PluginManager.class, "cache.mode", "weak"); //optional - // props.setProperty(PluginManager.class, "cache.file", "jspf.cache"); - - try { - pluginManager = PluginManagerFactory.createPluginManager(props); - pluginManager.addPluginsFrom(new URI("classpath://*")); - } catch (URISyntaxException e) { - throw new BugException(e); - } - } - - @Override - public List getPlugins(Class e, Object... args) { - - List plugins = new ArrayList(); - - PluginManagerUtil pluginManagerUtil = new PluginManagerUtil(pluginManager); - plugins.addAll(pluginManagerUtil.getPlugins(e)); - - for (Service s : pluginManagerUtil.getPlugins(Service.class)) { - plugins.addAll(s.getPlugins(e, args)); - } - - return plugins; - - } -} diff --git a/core/src/net/sf/openrocket/plugin/PluginFactory.java b/core/src/net/sf/openrocket/plugin/PluginFactory.java deleted file mode 100644 index babf01da..00000000 --- a/core/src/net/sf/openrocket/plugin/PluginFactory.java +++ /dev/null @@ -1,11 +0,0 @@ -package net.sf.openrocket.plugin; - -import java.util.List; - -import net.xeoh.plugins.base.Plugin; - -public interface PluginFactory { - - public List getPlugins(Class e, Object... args); - -} diff --git a/core/src/net/sf/openrocket/plugin/Service.java b/core/src/net/sf/openrocket/plugin/Service.java deleted file mode 100644 index f19c6b16..00000000 --- a/core/src/net/sf/openrocket/plugin/Service.java +++ /dev/null @@ -1,13 +0,0 @@ -package net.sf.openrocket.plugin; - -import java.util.List; - -import net.xeoh.plugins.base.Plugin; - -public interface Service extends Plugin { - - - public List getPlugins(Class e, Object... args); - - -} diff --git a/core/src/net/sf/openrocket/plugin/SwingConfigurator.java b/core/src/net/sf/openrocket/plugin/SwingConfigurator.java new file mode 100644 index 00000000..86ba323e --- /dev/null +++ b/core/src/net/sf/openrocket/plugin/SwingConfigurator.java @@ -0,0 +1,37 @@ +package net.sf.openrocket.plugin; + +import java.awt.Component; + +import net.xeoh.plugins.base.Plugin; + +/** + * Interface that defined a Swing configurator for a plugin. + * The implemeting class should be a plugin that provides the + * capability ":config" where is the + * plugin ID of the plugin to configure. + *

+ * + * @param

The plugin class that is being configured + * @author Sampo Niskanen + */ +public interface SwingConfigurator

extends Plugin { + + /** + * Return whether this plugin is configurable or not. + * + * @param plugin the plugin to test. + * @return whether the plugin has a configuration component. + */ + public boolean isConfigurable(P plugin); + + /** + * Return the configuration component for configuring the + * provided plugin. + * + * @param plugin the plugin to configure. + * @return a Swing component for configuring the plugin. + */ + public Component getConfigurationComponent(P plugin); + + +} diff --git a/core/src/net/sf/openrocket/plugin/example/AirStartSimulationExtension.java b/core/src/net/sf/openrocket/plugin/example/AirStartSimulationExtension.java new file mode 100644 index 00000000..7d14f5fd --- /dev/null +++ b/core/src/net/sf/openrocket/plugin/example/AirStartSimulationExtension.java @@ -0,0 +1,42 @@ +package net.sf.openrocket.plugin.example; + +import java.awt.Component; + +public class AirStartSimulationExtension extends OpenRocketSimulationListener { + + @Override + public String getName() { + return "Air-start"; + } + + @Override + public String[] getMenuPosition() { + return null; + } + + @Override + public void loadFromXML(Object... objects) { + // TODO Auto-generated method stub + + } + + @Override + public void saveToXML(Object... objects) { + // TODO Auto-generated method stub + + } + + @Override + public boolean isConfigurable() { + // TODO Auto-generated method stub + return false; + } + + @Override + public Component getConfigurationComponent() { + // TODO Auto-generated method stub + return null; + } + + +} diff --git a/core/src/net/sf/openrocket/plugin/example/ExampleMain.java b/core/src/net/sf/openrocket/plugin/example/ExampleMain.java index c45afee2..aea94be6 100644 --- a/core/src/net/sf/openrocket/plugin/example/ExampleMain.java +++ b/core/src/net/sf/openrocket/plugin/example/ExampleMain.java @@ -1,7 +1,7 @@ package net.sf.openrocket.plugin.example; -import net.sf.openrocket.plugin.JSPFPluginFactory; -import net.sf.openrocket.plugin.PluginFactory; +import net.sf.openrocket.plugin.framework.JSPFPluginFactory; +import net.sf.openrocket.plugin.framework.PluginFactory; public class ExampleMain { diff --git a/core/src/net/sf/openrocket/plugin/example/ExampleService.java b/core/src/net/sf/openrocket/plugin/example/ExampleService.java index 9960bcda..8a6317b3 100644 --- a/core/src/net/sf/openrocket/plugin/example/ExampleService.java +++ b/core/src/net/sf/openrocket/plugin/example/ExampleService.java @@ -3,7 +3,7 @@ package net.sf.openrocket.plugin.example; import java.util.ArrayList; import java.util.List; -import net.sf.openrocket.plugin.AbstractService; +import net.sf.openrocket.plugin.framework.AbstractService; import net.xeoh.plugins.base.annotations.PluginImplementation; @PluginImplementation diff --git a/core/src/net/sf/openrocket/plugin/example/OpenRocketSimulationListener.java b/core/src/net/sf/openrocket/plugin/example/OpenRocketSimulationListener.java new file mode 100644 index 00000000..ea178c09 --- /dev/null +++ b/core/src/net/sf/openrocket/plugin/example/OpenRocketSimulationListener.java @@ -0,0 +1,88 @@ +package net.sf.openrocket.plugin.example; + +import java.awt.Component; +import java.util.Arrays; +import java.util.List; + +import net.sf.openrocket.plugin.Configurable; +import net.sf.openrocket.plugin.SwingConfigurator; +import net.sf.openrocket.plugin.framework.Service; +import net.sf.openrocket.simulation.listeners.AbstractSimulationListener; +import net.sf.openrocket.util.BugException; +import net.xeoh.plugins.base.Plugin; +import net.xeoh.plugins.base.annotations.Capabilities; + +public abstract class OpenRocketSimulationListener extends AbstractSimulationListener + implements Plugin, Service, SwingConfigurator, Configurable { + + private final String[] ids; + private final String[] capabilities; + + public OpenRocketSimulationListener(String... ids) { + if (ids.length == 0) { + ids = new String[] { this.getClass().getCanonicalName() }; + } + + this.ids = ids.clone(); + this.capabilities = new String[ids.length * 2]; + for (int i = 0; i < ids.length; i++) { + capabilities[i * 2] = ids[i] + ":service"; + capabilities[i * 2 + 1] = ids[i] + ":config"; + } + + } + + @Capabilities + public String[] capabilities() { + return capabilities.clone(); + } + + @SuppressWarnings("unchecked") + @Override + public List getPlugins(Class e, Object... args) { + if (e != this.getClass()) { + throw new BugException("Attempting to get plugin of type " + e + " but I am of type " + this.getClass()); + } + try { + return (List) Arrays.asList(this.getClass().newInstance()); + } catch (IllegalAccessException e1) { + throw new BugException("Could not instantiate new object of type " + this.getClass(), e1); + } catch (InstantiationException e2) { + throw new BugException("Could not instantiate new object of type " + this.getClass(), e2); + } + } + + + @Override + public boolean isConfigurable(OpenRocketSimulationListener plugin) { + return plugin.isConfigurable(); + } + + @Override + public Component getConfigurationComponent(OpenRocketSimulationListener plugin) { + return plugin.getConfigurationComponent(); + } + + public abstract boolean isConfigurable(); + + public abstract Component getConfigurationComponent(); + + + + @Override + public String getPluginID() { + return ids[0]; + } + + @Override + public boolean isCompatible(String pluginID) { + for (String id : ids) { + if (pluginID.equals(id)) { + return true; + } + } + return false; + } + + +} diff --git a/core/src/net/sf/openrocket/plugin/example/stuff.txt b/core/src/net/sf/openrocket/plugin/example/stuff.txt new file mode 100644 index 00000000..e4a4fc3c --- /dev/null +++ b/core/src/net/sf/openrocket/plugin/example/stuff.txt @@ -0,0 +1,135 @@ + + + +Plugin: + +foo() +bar() +getValue() +setValue() + + + +Service: + +getPlugins(args...) +capabilities() -> "pluginid:service" + + + +SwingConfigurator: + +getConfigurationComponent(plugin) +capabilities() -> "pluginid:config" + + + + +OpenRocketSimulationListener extends SimulationListener implements Service, SwingConfigurator: + + +constructor: + pluginid = class name + + +getPlugins(): + return new this + +capabilities: pluginid:service, pluginid:config + +getConfigurationComponent(plugin) + plugin.getConfigurationComponent() + +abstract getConfigurationComponent() + + + + + +Types of plugins: + + +AtmosphericModel + - Name -> dropdown + - Config component -> dialog window (or button) + - stateful, non-dynamic + - stored + + +SimulationListener + - Name + menu position -> Add extension menu + - Config component -> dialog after edit button + - stateful, (dynamic?) + - stored + + +OptimizationModifier + - contains its own name, description, related object + - config N/A + - stateful, dynamic + - not stored + + +OptimizationParameter + - name + - config N/A + - stateful, (dynamic?) + - not stored + + +PluginDialogWindow + - name + menu position -> Menu + - stateful, non-dynamic + - not stored + + +Motor + - Name -> Config tab + - Config component -> tab contents ???? + - or a separate configuration interface? + - stored + + + +Name is common - out, instead have name separately in plugin interfaces? +Menu position used twice - out + +Leave common configuration out + -> :config supported by those that make sense + -> may have separate interface from SwingConfigurator (e.g. SwingMotorConfigurator) + +Motor + -> :loader separately? for injecting placeholders + or store data and call loaders later + + + + + + 100.0 + + Gold + bulk + 16000 + + + + + + 100.0 + + Gold + bulk + 16000 + + + + + + + + + + + + diff --git a/core/src/net/sf/openrocket/plugin/framework/AbstractService.java b/core/src/net/sf/openrocket/plugin/framework/AbstractService.java new file mode 100644 index 00000000..eca8a2a0 --- /dev/null +++ b/core/src/net/sf/openrocket/plugin/framework/AbstractService.java @@ -0,0 +1,45 @@ +package net.sf.openrocket.plugin.framework; + +import java.util.Collections; +import java.util.List; + +import net.sf.openrocket.util.BugException; + +/** + * An abstract service implementation that returns plugins of type P. + * + * @param

the plugin type that this service returns. + * @author Sampo Niskanen + */ +public abstract class AbstractService

implements Service { + + private final Class

type; + + protected AbstractService(Class

type) { + this.type = type; + } + + @SuppressWarnings("unchecked") + @Override + public List getPlugins(Class e, Object... args) { + + if (e != type) { + return Collections.emptyList(); + } + + List

plugins = getPlugins(args); + + // Check list content types to avoid mysterious bugs later on + for (P p : plugins) { + if (!type.isInstance(p)) { + throw new BugException("Requesting plugins of type " + type + " but received " + + ((p != null) ? p.getClass() : "null")); + } + } + + return (List) plugins; + } + + protected abstract List

getPlugins(Object... args); + +} diff --git a/core/src/net/sf/openrocket/plugin/framework/JSPFPluginFactory.java b/core/src/net/sf/openrocket/plugin/framework/JSPFPluginFactory.java new file mode 100644 index 00000000..f75cf36c --- /dev/null +++ b/core/src/net/sf/openrocket/plugin/framework/JSPFPluginFactory.java @@ -0,0 +1,50 @@ +package net.sf.openrocket.plugin.framework; + +import java.net.URI; +import java.net.URISyntaxException; +import java.util.ArrayList; +import java.util.List; + +import net.sf.openrocket.util.BugException; +import net.xeoh.plugins.base.Plugin; +import net.xeoh.plugins.base.PluginManager; +import net.xeoh.plugins.base.impl.PluginManagerFactory; +import net.xeoh.plugins.base.util.JSPFProperties; +import net.xeoh.plugins.base.util.PluginManagerUtil; + +public class JSPFPluginFactory implements PluginFactory { + + private final PluginManager pluginManager; + + public JSPFPluginFactory() { + + final JSPFProperties props = new JSPFProperties(); + + // props.setProperty(PluginManager.class, "cache.enabled", "true"); + // props.setProperty(PluginManager.class, "cache.mode", "weak"); //optional + // props.setProperty(PluginManager.class, "cache.file", "jspf.cache"); + + try { + pluginManager = PluginManagerFactory.createPluginManager(props); + pluginManager.addPluginsFrom(new URI("classpath://*")); + } catch (URISyntaxException e) { + throw new BugException(e); + } + } + + @Override + public List getPlugins(Class e, Object... args) { + + List plugins = new ArrayList(); + + PluginManagerUtil pluginManagerUtil = new PluginManagerUtil(pluginManager); + plugins.addAll(pluginManagerUtil.getPlugins(e)); + + for (Service s : pluginManagerUtil.getPlugins(Service.class)) { + plugins.addAll(s.getPlugins(e, args)); + } + + return plugins; + + } +} diff --git a/core/src/net/sf/openrocket/plugin/framework/PluginFactory.java b/core/src/net/sf/openrocket/plugin/framework/PluginFactory.java new file mode 100644 index 00000000..25b6cbfd --- /dev/null +++ b/core/src/net/sf/openrocket/plugin/framework/PluginFactory.java @@ -0,0 +1,11 @@ +package net.sf.openrocket.plugin.framework; + +import java.util.List; + +import net.xeoh.plugins.base.Plugin; + +public interface PluginFactory { + + public List getPlugins(Class e, Object... args); + +} diff --git a/core/src/net/sf/openrocket/plugin/framework/Service.java b/core/src/net/sf/openrocket/plugin/framework/Service.java new file mode 100644 index 00000000..ee56b8e4 --- /dev/null +++ b/core/src/net/sf/openrocket/plugin/framework/Service.java @@ -0,0 +1,30 @@ +package net.sf.openrocket.plugin.framework; + +import java.util.List; + +import net.xeoh.plugins.base.Plugin; + +/** + * A discovery service that returns plugins of a specified type with + * provided arguments. + * + * @author Sampo Niskanen + */ +public interface Service extends Plugin { + + /** + * Return the plugins that match the provided type and are applicable + * for the arguments. The arguments depend on the class type. + *

+ * This method may return different plugins for different arguments. + * For example, if the arguments contain the OpenRocketDocument, the + * service may return only plugins applicable for the specified document. + * + * @param type the plugin interface type + * @param args arguments for the interface. + * @return the plugin instances applicable. + */ + public List getPlugins(Class type, Object... args); + + +}