Potential plugin structure
authorplaa <plaa@180e2498-e6e9-4542-8430-84ac67f01cd8>
Mon, 18 Jun 2012 19:58:58 +0000 (19:58 +0000)
committerplaa <plaa@180e2498-e6e9-4542-8430-84ac67f01cd8>
Mon, 18 Jun 2012 19:58:58 +0000 (19:58 +0000)
git-svn-id: https://openrocket.svn.sourceforge.net/svnroot/openrocket/trunk@789 180e2498-e6e9-4542-8430-84ac67f01cd8

18 files changed:
core/src/net/sf/openrocket/gui/plugin/DoSomethingPlugin.java [new file with mode: 0644]
core/src/net/sf/openrocket/gui/plugin/OpenRocketSwingMenuPlugin.java [new file with mode: 0644]
core/src/net/sf/openrocket/gui/plugin/SwingMenuPlugin.java [new file with mode: 0644]
core/src/net/sf/openrocket/plugin/AbstractService.java [deleted file]
core/src/net/sf/openrocket/plugin/Configurable.java [new file with mode: 0644]
core/src/net/sf/openrocket/plugin/JSPFPluginFactory.java [deleted file]
core/src/net/sf/openrocket/plugin/PluginFactory.java [deleted file]
core/src/net/sf/openrocket/plugin/Service.java [deleted file]
core/src/net/sf/openrocket/plugin/SwingConfigurator.java [new file with mode: 0644]
core/src/net/sf/openrocket/plugin/example/AirStartSimulationExtension.java [new file with mode: 0644]
core/src/net/sf/openrocket/plugin/example/ExampleMain.java
core/src/net/sf/openrocket/plugin/example/ExampleService.java
core/src/net/sf/openrocket/plugin/example/OpenRocketSimulationListener.java [new file with mode: 0644]
core/src/net/sf/openrocket/plugin/example/stuff.txt [new file with mode: 0644]
core/src/net/sf/openrocket/plugin/framework/AbstractService.java [new file with mode: 0644]
core/src/net/sf/openrocket/plugin/framework/JSPFPluginFactory.java [new file with mode: 0644]
core/src/net/sf/openrocket/plugin/framework/PluginFactory.java [new file with mode: 0644]
core/src/net/sf/openrocket/plugin/framework/Service.java [new file with mode: 0644]

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 (file)
index 0000000..d238c4e
--- /dev/null
@@ -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 (file)
index 0000000..e76e64a
--- /dev/null
@@ -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 <E> List<E> getPlugins(Class<E> 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 (file)
index 0000000..e27b78a
--- /dev/null
@@ -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.
+ * <p>
+ * During plugin discovery, the BasicFrame and OpenRocketDocument
+ * objects are passed to the plugin.
+ * 
+ * @author Sampo Niskanen <sampo.niskanen@iki.fi>
+ */
+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.
+        * <p>
+        * 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 (file)
index 0271964..0000000
+++ /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 <P>  the plugin type that this service returns.
- * @author Sampo Niskanen <sampo.niskanen@iki.fi>
- */
-public abstract class AbstractService<P> implements Service {
-       
-       private final Class<P> type;
-       
-       protected AbstractService(Class<P> type) {
-               this.type = type;
-       }
-       
-       @SuppressWarnings("unchecked")
-       @Override
-       public <E> List<E> getPlugins(Class<E> e, Object... args) {
-               
-               if (e != type) {
-                       return Collections.emptyList();
-               }
-               
-               List<P> 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<E>) plugins;
-       }
-       
-       protected abstract List<P> 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 (file)
index 0000000..b8ebf6e
--- /dev/null
@@ -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 (file)
index 6b598b6..0000000
+++ /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 <E extends Plugin> List<E> getPlugins(Class<E> e, Object... args) {
-               
-               List<E> plugins = new ArrayList<E>();
-               
-               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 (file)
index babf01d..0000000
+++ /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 <E extends Plugin> List<E> getPlugins(Class<E> 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 (file)
index f19c6b1..0000000
+++ /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 <E> List<E> getPlugins(Class<E> 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 (file)
index 0000000..86ba323
--- /dev/null
@@ -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 "<pluginID>:config" where <pluginID> is the
+ * plugin ID of the plugin to configure.
+ * <p>
+ * 
+ * @param <P> The plugin class that is being configured
+ * @author Sampo Niskanen <sampo.niskanen@iki.fi>
+ */
+public interface SwingConfigurator<P> 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 (file)
index 0000000..7d14f5f
--- /dev/null
@@ -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;
+       }
+       
+       
+}
index c45afee29621c95b12b23fdae98c20015eb40dac..aea94be689768938a800baffe0859957ac92ea33 100644 (file)
@@ -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 {
        
index 9960bcdab0188e0baf08f5130542ddf3f49f5206..8a6317b38b1342fc48e443c27eb1d29ef159f783 100644 (file)
@@ -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 (file)
index 0000000..ea178c0
--- /dev/null
@@ -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<OpenRocketSimulationListener>, 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 <E> List<E> getPlugins(Class<E> 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<E>) 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 (file)
index 0000000..e4a4fc3
--- /dev/null
@@ -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
+
+
+
+
+<extension pluginid="com.example.MyFancyExtension">
+  <param type="double" key="altitude">100.0</param>
+  <param type="material" key="mat">
+    <name>Gold</name>
+    <type>bulk</type>
+    <density>16000</density>
+  </param>
+</extension>
+
+
+<extension pluginid="com.example.MyFancyExtension">
+  <param type="double" key="altitude">100.0</param>
+  <param type="material" key="mat">
+    <name>Gold</name>
+    <type>bulk</type>
+    <density>16000</density>
+  </param>
+</extension>
+
+
+<extension pluginid="com.example.MyFancyExtension">
+</extension>
+
+
+<extension pluginid="com.example.MyFancyExtension">
+</extension>
+
+
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 (file)
index 0000000..eca8a2a
--- /dev/null
@@ -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 <P>  the plugin type that this service returns.
+ * @author Sampo Niskanen <sampo.niskanen@iki.fi>
+ */
+public abstract class AbstractService<P> implements Service {
+       
+       private final Class<P> type;
+       
+       protected AbstractService(Class<P> type) {
+               this.type = type;
+       }
+       
+       @SuppressWarnings("unchecked")
+       @Override
+       public <E> List<E> getPlugins(Class<E> e, Object... args) {
+               
+               if (e != type) {
+                       return Collections.emptyList();
+               }
+               
+               List<P> 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<E>) plugins;
+       }
+       
+       protected abstract List<P> 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 (file)
index 0000000..f75cf36
--- /dev/null
@@ -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 <E extends Plugin> List<E> getPlugins(Class<E> e, Object... args) {
+               
+               List<E> plugins = new ArrayList<E>();
+               
+               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 (file)
index 0000000..25b6cbf
--- /dev/null
@@ -0,0 +1,11 @@
+package net.sf.openrocket.plugin.framework;
+
+import java.util.List;
+
+import net.xeoh.plugins.base.Plugin;
+
+public interface PluginFactory {
+       
+       public <E extends Plugin> List<E> getPlugins(Class<E> 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 (file)
index 0000000..ee56b8e
--- /dev/null
@@ -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 <sampo.niskanen@iki.fi>
+ */
+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.
+        * <p>
+        * 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 <E> List<E> getPlugins(Class<E> type, Object... args);
+       
+       
+}