Author: jflesch
Date: 2006-06-14 11:28:59 +0000 (Wed, 14 Jun 2006)
New Revision: 9194

Added:
   trunk/apps/Thaw/readme.txt
   trunk/apps/Thaw/src/thaw/core/Config.java
   trunk/apps/Thaw/src/thaw/core/ConfigWindow.java
   trunk/apps/Thaw/src/thaw/core/Core.java
   trunk/apps/Thaw/src/thaw/core/Logger.java
   trunk/apps/Thaw/src/thaw/core/Main.java
   trunk/apps/Thaw/src/thaw/core/MainWindow.java
   trunk/apps/Thaw/src/thaw/core/NodeConfigPanel.java
   trunk/apps/Thaw/src/thaw/core/Plugin.java
   trunk/apps/Thaw/src/thaw/core/PluginConfigPanel.java
   trunk/apps/Thaw/src/thaw/core/PluginManager.java
   trunk/apps/Thaw/src/thaw/i18n/
   trunk/apps/Thaw/src/thaw/i18n/I18n.java
   trunk/apps/Thaw/src/thaw/i18n/thaw.properties
   trunk/apps/Thaw/src/thaw/plugins/QueueWatcher.java
Modified:
   trunk/apps/Thaw/build.xml
Log:
(Really) basic user interface + plugin manager

Modified: trunk/apps/Thaw/build.xml
===================================================================
--- trunk/apps/Thaw/build.xml   2006-06-14 10:18:18 UTC (rev 9193)
+++ trunk/apps/Thaw/build.xml   2006-06-14 11:28:59 UTC (rev 9194)
@@ -16,13 +16,29 @@
     <mkdir dir="${bin.dir}" />

     <javac srcdir="${src.dir}" destdir="${bin.dir}" debug="false" 
optimize="true">
+
+      <compilerarg value="-Xlint" />
+
       <classpath>
         <pathelement location="${hsqldb.location}"/>
       </classpath>
+
     </javac>
+
+    <copy todir="${bin.dir}">
+      <fileset dir="${src.dir}">
+        <include name="**/*.properties" />
+      </fileset>
+    </copy>
+
   </target>


+  <target name="run" depends="compile">
+    <java classname="thaw.core.Main" classpath="lib/hsqldb.jar:build" 
dir="build" fork="true" />
+  </target>
+
+
   <target name="jar" depends="compile" description="Make the Jar" >
     <jar jarfile="${lib.dir}/Thaw.jar" basedir="${bin.dir}">


Added: trunk/apps/Thaw/readme.txt
===================================================================
--- trunk/apps/Thaw/readme.txt  2006-06-14 10:18:18 UTC (rev 9193)
+++ trunk/apps/Thaw/readme.txt  2006-06-14 11:28:59 UTC (rev 9194)
@@ -0,0 +1,40 @@
+
+LICENSE
+=======
+
+Thaw is distributed under the GPLv2 license. You can find it in a file
+called "gpl.txt" and joined with every copy of Thaw.
+
+
+COMPILATION
+===========
+
+In order to compile Thaw, you need to obtain the latest version of hsqldb.jar.
+
+Here is a link to the current (06/11/2006) version of hsqldb:
+http://switch.dl.sourceforge.net/sourceforge/hsqldb/hsqldb_1_8_0_4.zip
+
+Extract the zip, and copy "hsqldb/lib/hsqldb.jar" to "Thaw/lib".
+
+To compile:
+  $ ant
+
+To build the jar file:
+  $ ant jar
+
+To build the javadoc:
+  $ ant javadoc
+
+
+RUNNING
+=======
+
+On Unix / Linux / etc:
+$ cd lib ; java -jar Thaw.jar
+or
+$ ant run
+
+
+On Windows:
+err ... we will see that later ...
+

Added: trunk/apps/Thaw/src/thaw/core/Config.java
===================================================================
--- trunk/apps/Thaw/src/thaw/core/Config.java   2006-06-14 10:18:18 UTC (rev 
9193)
+++ trunk/apps/Thaw/src/thaw/core/Config.java   2006-06-14 11:28:59 UTC (rev 
9194)
@@ -0,0 +1,134 @@
+package thaw.core;
+
+import java.util.HashMap;
+import java.util.Vector;
+import java.io.File;
+
+
+/**
+ * This class the thaw config.
+ *
+ * @author <a href="mailto:jflesch at nerim.net">Jerome Flesch</a>
+ */
+public class Config {
+
+       private File configFile = new File("thaw.conf.xml"); /* Default name */
+
+       private HashMap parameters = null; /* String (param) -> String (value) 
*/
+       private Vector pluginNames = null; /* String (plugin names) */
+
+
+       public Config() {
+               this(null);
+       }
+
+       public Config(String filename) {
+               if(filename != null)
+                       configFile = new File(filename);
+
+               parameters = new HashMap();
+               pluginNames = new Vector();
+       }
+
+       /**
+        * Returns the corresponding value
+        * @return null if the value doesn't exit in the config.
+        */
+       public String getValue(String key) {
+               try {
+                       return ((String)parameters.get(key));
+               } catch(Exception e) { /* I should see for the correct 
exception */
+                       Logger.notice(this, "Unknow key in configuration: 
'"+key+"'");
+                       return null;
+               }
+       }
+
+       /**
+        * Set the value in the config.
+        */
+       public void setValue(String key, String value) {
+               if(value != null)
+                       Logger.info(this, "Setting value '"+key+"' to 
'"+value+"'");
+               else
+                       Logger.info(this, "Setting value '"+key+"' to null");
+               parameters.put(key, value);
+       }
+
+       /**
+        * Add the plugin at the end of the plugin list.
+        */
+       public void addPlugin(String name) {
+               pluginNames.add(name);
+       }
+
+       /**
+        * Add the plugin at the end of the given position (shifting already 
existing).
+        */
+       public void addPlugin(String name, int position) {
+               pluginNames.add(position, name);
+       }
+
+       /**
+        * Give a vector containing the whole list of plugins.
+        */
+       public Vector getPluginNames() {
+               return pluginNames;
+       }
+
+       /**
+        * Remove the given plugin.
+        */
+       public void removePlugin(String name) {
+               for(int i = 0; i < pluginNames.size() ; i++) {
+                       String currentPlugin = (String)pluginNames.get(i);
+
+                       if(currentPlugin.equals(name))
+                               pluginNames.remove(i);
+               }
+       }
+
+
+       /**
+        * Load the configuration.
+        * @return true if success, else false.
+        */
+       public boolean loadConfig() {
+               if(configFile == null) {
+                       Logger.error(this, "loadConfig(): No file specified !");
+                       return false;
+               }
+
+               if(!configFile.exists() || !configFile.canRead()) {
+                       Logger.notice(this, "Unable to read config file 
'"+configFile.getPath()+"'");
+                       return false;
+               }
+
+               
+               /* TODO */
+
+               return true;
+       }
+
+
+       /**
+        * Save the configuration.
+        * @return true if success, else false.
+        */
+       public boolean saveConfig() {
+               if(configFile == null) {
+                       Logger.error(this, "saveConfig(): No file specified !");
+                       return false;
+               }
+
+               if(!configFile.exists() || !configFile.canWrite()) {
+                       Logger.warning(this, "Unable to write config file 
'"+configFile.getPath()+"'");
+                       return false;
+               }
+               
+               
+               /* TODO */
+
+               return true;    
+       }
+
+}

Added: trunk/apps/Thaw/src/thaw/core/ConfigWindow.java
===================================================================
--- trunk/apps/Thaw/src/thaw/core/ConfigWindow.java     2006-06-14 10:18:18 UTC 
(rev 9193)
+++ trunk/apps/Thaw/src/thaw/core/ConfigWindow.java     2006-06-14 11:28:59 UTC 
(rev 9194)
@@ -0,0 +1,157 @@
+package thaw.core;
+
+import javax.swing.JFrame;
+import javax.swing.JPanel;
+import javax.swing.JTabbedPane;
+import java.awt.BorderLayout;
+import java.awt.event.ActionEvent;
+import java.awt.event.WindowEvent;
+import java.awt.event.ActionListener;
+import javax.swing.JButton;
+import java.util.Observable;
+import java.awt.GridLayout;
+
+import thaw.core.i18n.I18n;
+
+
+/**
+ * ConfigWindow. Create the window used by user to config everything.
+ * Composed by a tabbed pane containing a NodeConfigPanel and a 
PluginConfigPanel, and below the tabbed pane,
+ *   a JButton to validate.
+ * Notify observer when a button (Ok / Cancel) is clicked (gives the button in 
arg).
+ */
+public class ConfigWindow extends Observable implements ActionListener, 
java.awt.event.WindowListener {
+       private JFrame configWin;
+       private JTabbedPane tabs;
+
+       private JPanel buttons;
+       private JButton okButton;
+       private JButton cancelButton;
+
+       private NodeConfigPanel nodeConfigPanel;
+       private PluginConfigPanel pluginConfigPanel;
+
+       private Core core;
+
+
+       public ConfigWindow(Core core) {
+               this.core = core;
+
+               configWin = new 
JFrame(I18n.getMessage("thaw.config.windowName"));
+
+               tabs = new JTabbedPane();
+
+               buttons = new JPanel();
+               buttons.setLayout(new GridLayout(1, 2));
+
+               okButton = new JButton(I18n.getMessage("thaw.config.okButton"));
+               cancelButton = new 
JButton(I18n.getMessage("thaw.config.cancelButton"));
+
+               buttons.add(okButton);
+               buttons.add(cancelButton);
+
+               nodeConfigPanel = new NodeConfigPanel(this, core);
+               pluginConfigPanel = new PluginConfigPanel(this, core);
+
+               tabs.add(I18n.getMessage("thaw.common.node"), 
nodeConfigPanel.getPanel());
+               tabs.add(I18n.getMessage("thaw.common.plugins"), 
pluginConfigPanel.getPanel());
+
+
+               BorderLayout borderLayout = new BorderLayout();
+               borderLayout.setVgap(20);
+               borderLayout.setVgap(20);
+               configWin.setLayout(borderLayout);
+               configWin.add(tabs, BorderLayout.CENTER);
+               configWin.add(buttons, BorderLayout.SOUTH);
+
+               tabs.setSize(600, 350);
+               okButton.setSize(100, 50);
+
+               configWin.setSize(600, 400);
+               configWin.setResizable(false);
+
+               okButton.addActionListener(this);
+               cancelButton.addActionListener(this);
+
+               configWin.addWindowListener(this);
+       }
+
+
+       /**
+        * Make [dis]appear the config window.
+        */
+       public void setVisible(boolean v) {
+               configWin.setVisible(v);
+       }
+
+
+       /**
+        * Get a ref to the JFrame.
+        */
+       public JFrame getFrame() {
+               return configWin;
+       }
+
+       /**
+        * Get a ref to validation button.
+        */
+       public JButton getOkButton() {
+               return okButton;
+       }
+
+
+       /**
+        * Get a ref to cancel button.
+        */
+       public JButton getCancelButton() {
+               return cancelButton;
+       }
+
+       /**
+        * Called when apply button is pressed.
+        */
+       public void actionPerformed(ActionEvent e) {
+               if(e.getSource() == okButton
+                  || e.getSource() == cancelButton) {
+
+                       setChanged();
+                       notifyObservers(e.getSource());
+
+                       setVisible(false);
+               }
+       }
+
+
+
+       public void windowActivated(WindowEvent e) {
+
+       }
+
+       public void windowClosing(WindowEvent e) {
+               setChanged();
+               notifyObservers(cancelButton); /* Equivalent to a click on the 
cancel button */
+       }
+
+       public void windowClosed(WindowEvent e) {
+               // add potential warnings here
+       }
+
+       public void windowDeactivated(WindowEvent e) {
+               // C'est pas comme si on en avait quelque chose ? foutre :p
+       }
+
+       public void windowDeiconified(WindowEvent e) {
+               // idem
+       }
+
+       public void windowIconified(WindowEvent e) {
+               // idem
+       }
+
+       public void windowOpened(WindowEvent e) {
+               // idem
+       }
+
+
+
+}

Added: trunk/apps/Thaw/src/thaw/core/Core.java
===================================================================
--- trunk/apps/Thaw/src/thaw/core/Core.java     2006-06-14 10:18:18 UTC (rev 
9193)
+++ trunk/apps/Thaw/src/thaw/core/Core.java     2006-06-14 11:28:59 UTC (rev 
9194)
@@ -0,0 +1,145 @@
+
+package thaw.core;
+
+
+import thaw.core.i18n.I18n;
+
+/**
+ * A "core" contains references to all the main parts of Thaw.
+ *
+ */
+public class Core {
+       private MainWindow mainWindow = null;
+       private Config config = null;
+       private PluginManager pluginManager = null;
+       private ConfigWindow configWindow = null;
+
+
+       /**
+        * Creates a core, but do nothing else (no initialization).
+        */
+       public Core() {
+               Logger.info(this, "Thaw, version "+Main.VERSION, true);
+               Logger.info(this, "2006(c) Freenet project", true);
+               Logger.info(this, "under GPL license (see gpl.txt joined)", 
true);
+       }
+
+       /**
+        * Gives a ref to the object containing the config.
+        */
+       public Config getConfig() {
+               return config;
+       }
+
+       /**
+        * Gives a ref to the object managing the main window.
+        */
+       public MainWindow getMainWindow() {
+               return mainWindow;
+       }
+
+       /**
+        * Gives a ref to the object managing the config window.
+        */
+       public ConfigWindow getConfigWindow() {
+               return configWindow;
+       }
+
+       /**
+        * Gives a ref to the plugin manager.
+        */
+       public PluginManager getPluginManager() {
+               return pluginManager;
+       }
+
+
+       /**
+        * Here really start the program.
+        * @return true is success, false if not
+        */
+       public boolean initAll() {
+               if(!initI18n())
+                       return false;
+
+               if(!initConfig())
+                       return false;
+
+               if(!initGraphics())
+                       return false;
+
+               
mainWindow.setStatus(I18n.getMessage("thaw.statusBar.initPlugins"));
+
+               if(!initPluginManager())
+                       return false;
+
+
+               mainWindow.setStatus(I18n.getMessage("thaw.statusBar.ready"));
+
+               return true;
+       }
+
+
+       /** 
+        * Init I18n with default values.
+        */
+       public boolean initI18n() {
+               // Hum, nothing to do ?
+
+               return true;
+       }
+
+
+       /**
+        * Init configuration. May re-set I18n.
+        */
+       public boolean initConfig() {
+               config = new Config();
+               config.loadConfig();
+               
+               return true;
+       }
+
+
+       /**
+        * Init graphics.
+        */
+       public boolean initGraphics() {
+               mainWindow = new MainWindow(this);
+               mainWindow.setVisible(true);
+
+               configWindow = new ConfigWindow(this);
+               configWindow.setVisible(false);
+
+               return true;
+       }
+
+       /**
+        * Init plugin manager.
+        */
+       public boolean initPluginManager() {
+               pluginManager = new PluginManager(this);
+
+               if(!pluginManager.loadPlugins())
+                       return false;
+               
+               if(!pluginManager.runPlugins())
+                       return false;
+
+               return true;
+       }
+
+
+       /**
+        * End of the world.
+        */
+       public void exit() {
+               Logger.info(this, "Stopping plugins ...");
+               pluginManager.stopPlugins();
+
+               Logger.info(this, "Exiting");
+               System.exit(0);
+       }
+
+
+
+}

Added: trunk/apps/Thaw/src/thaw/core/Logger.java
===================================================================
--- trunk/apps/Thaw/src/thaw/core/Logger.java   2006-06-14 10:18:18 UTC (rev 
9193)
+++ trunk/apps/Thaw/src/thaw/core/Logger.java   2006-06-14 11:28:59 UTC (rev 
9194)
@@ -0,0 +1,87 @@
+package thaw.core;
+
+
+/**
+ * Manage all log message.
+ * @author Jflesch
+ */
+public class Logger {
+
+
+       /* 0 = Errors only
+        * 1 = Errors + warnings
+        * 2 = Errors + warnings + notices
+        * 3 = Errors + warnings + notices + infos
+        * 4 = Errors + warnings + notices + infos + debug
+        * 5 = [...] + horrible things that only God could understand easily.
+        *             (or maybe someone having the FCPv2 doc :)
+        *
+        * 3 or more is recommanded.
+        * 5 is never logged in a file, only on stdout.
+        */
+       private final static int LOG_LEVEL = 3;
+
+
+       protected static void displayErr(String msg) {
+               // TODO : Log to a file
+               System.err.println(msg);
+       }
+
+       protected static void display(String msg) {
+               // TODO : Log to a file
+               System.out.println(msg);
+       }
+
+       /**
+        * Errors.
+        */
+       public static void error(Object o, String message) {
+               displayErr("[ ERROR ] "+o.getClass().getName()+": "+message);
+       }
+
+       /**
+        * Warnings.
+        */
+       public static void warning(Object o, String message) {
+               if(LOG_LEVEL >= 1)
+                       displayErr("[WARNING] "+o.getClass().getName()+": 
"+message);
+       }
+
+       /**
+        * Notices.
+        */
+       public static void notice(Object o, String msg) {
+               if(LOG_LEVEL >= 2)
+                       displayErr("[NOTICE ] " +o.getClass().getName()+": 
"+msg);
+       }
+       
+
+       public static void info(Object o, String msg) {
+               info(o, msg, false);
+       }
+
+       /**
+        * Infos.
+        */
+       public static void info(Object o, String msg, boolean manda) {
+               if(LOG_LEVEL >= 3 || manda)
+                       display("[ INFO  ] "+o.getClass().getName()+": "+msg);
+       }
+
+       /**
+        * Debug.
+        */
+       public static void debug(Object o, String msg) {
+               if(LOG_LEVEL >= 4)
+                       display("[ DEBUG ] "+o.getClass().getName()+": "+msg);
+       }
+
+
+       /** 
+        * Verbose. Too Verbose.
+        */
+       public static void verbose(Object o, String msg) {
+               if(LOG_LEVEL >= 5)
+                       System.out.println(o.getClass().getName()+": "+msg);
+       }
+}

Added: trunk/apps/Thaw/src/thaw/core/Main.java
===================================================================
--- trunk/apps/Thaw/src/thaw/core/Main.java     2006-06-14 10:18:18 UTC (rev 
9193)
+++ trunk/apps/Thaw/src/thaw/core/Main.java     2006-06-14 11:28:59 UTC (rev 
9194)
@@ -0,0 +1,25 @@
+package thaw.core;
+
+/**
+ * Main class. Only used to display some informations and init the core.
+ *
+ * @author <a href="mailto:jflesch at nerim.net">Jerome Flesch</a>
+ */
+public class Main {
+
+       public final static String VERSION="0.1 WIP";
+       
+
+       /**
+        * Used to start the program
+        *
+        * @param args Arguments given to the program.
+        */
+       public static void main(String[] args) {
+               Core core;
+
+               core = new Core();
+               core.initAll();
+       }
+}
+

Added: trunk/apps/Thaw/src/thaw/core/MainWindow.java
===================================================================
--- trunk/apps/Thaw/src/thaw/core/MainWindow.java       2006-06-14 10:18:18 UTC 
(rev 9193)
+++ trunk/apps/Thaw/src/thaw/core/MainWindow.java       2006-06-14 11:28:59 UTC 
(rev 9194)
@@ -0,0 +1,182 @@
+package thaw.core;
+
+import javax.swing.JFrame;
+import javax.swing.JMenuBar;
+import javax.swing.JTabbedPane;
+import javax.swing.JLabel;
+import java.awt.BorderLayout;
+import javax.swing.JMenu;
+import javax.swing.JMenuItem;
+import java.awt.event.ActionEvent;
+import java.awt.event.WindowEvent;
+
+import thaw.core.i18n.I18n;
+
+
+/**
+ * MainWindow. This class create the main window.
+ *
+ * Main window is divided in three parts:
+ *
+ * ------------------------------------
+ * |?MenuBar                          |
+ * ------------------------------------
+ * | Tabbed Pane                      |
+ * |?                                 |
+ * |?                                 |
+ * |                                  |
+ * ------------------------------------
+ * |?JLabel (status)                  |
+ * ------------------------------------
+ *
+ *
+ * @author <a href="mailto:jflesch at nerim.net">Jerome Flesch</a>
+ */
+public class MainWindow implements java.awt.event.ActionListener, 
java.awt.event.WindowListener {
+       private JFrame mainWindow = null;
+
+       private JMenuBar menuBar = null;
+       private JMenu fileMenu = null;
+       
+       private JMenuItem optionsFileMenuItem = null;
+       private JMenuItem quitFileMenuItem = null;
+
+       private JTabbedPane tabbedPane = null;
+       private JLabel statusBar = null;
+
+       private Core core = null; /* core is called back when exit() */
+
+
+       /**
+        * Creates a new <code>MainWindow</code> instance, and so a new Swing 
window.
+        * @param core a <code>Core</code> value
+        */
+       public MainWindow(Core core) {
+               this.core = core;
+
+               mainWindow = new JFrame("Thaw");
+               
+               menuBar = new JMenuBar();
+               fileMenu = new JMenu(I18n.getMessage("thaw.menu.file"));
+               optionsFileMenuItem = new 
JMenuItem(I18n.getMessage("thaw.menu.item.options"));
+               quitFileMenuItem = new 
JMenuItem(I18n.getMessage("thaw.menu.item.quit"));
+               
+               optionsFileMenuItem.addActionListener(this);
+               quitFileMenuItem.addActionListener(this);
+
+               fileMenu.add(optionsFileMenuItem);
+               fileMenu.add(quitFileMenuItem);
+               menuBar.add(fileMenu);
+
+               tabbedPane = new JTabbedPane();
+
+               statusBar = new JLabel();
+               setStatus(null);
+               statusBar.setSize(500, 30);
+
+               mainWindow.setLayout(new BorderLayout());
+               mainWindow.add(menuBar, BorderLayout.NORTH);
+               mainWindow.add(tabbedPane, BorderLayout.CENTER);
+               mainWindow.add(statusBar, BorderLayout.SOUTH);
+
+               mainWindow.setSize(700, 500);
+               
+               mainWindow.addWindowListener(this);
+       }
+
+
+       /**
+        * Make the window visible or not.
+        */
+       public void setVisible(boolean v) {
+               mainWindow.setVisible(v);
+       }
+
+
+       /** 
+        * Used by plugins to add their own tab.
+        */
+       public JTabbedPane getTabbedPane() {
+               return tabbedPane;
+       }
+
+       
+       /**
+        * Used by plugins to add their own menu.
+        */
+       public JMenuBar getMenuBar() {
+               return menuBar;
+       }
+
+
+       /**
+        * Called when an element from the menu is called.
+        */
+       public void actionPerformed(ActionEvent e) {
+               if(e.getSource() == optionsFileMenuItem) {
+                       core.getConfigWindow().setVisible(true);
+               }
+
+               
+               if(e.getSource() == quitFileMenuItem) {
+                       endOfTheWorld();
+               }
+
+       }
+
+       /**
+        * Called when window is closed or 'quit' is choosed is the menu.
+        */
+       public void endOfTheWorld() {
+               if(core == null) {
+                       Logger.error(this, "Warning, no ref to core, exiting 
brutaly");
+                       System.exit(0);
+               } else {
+                       core.exit();
+               }       
+       }
+
+
+       /**
+        * Change text in the status bar.
+        * @param status Null is accepted.
+        */
+       public void setStatus(String status) {
+               if(status != null)
+                       statusBar.setText(status);
+               else
+                       statusBar.setText(" ");/* not empty else the status bar 
disappear */
+       }
+
+       
+       public void windowActivated(WindowEvent e) {
+
+       }
+
+       public void windowClosing(WindowEvent e) {
+               /* Should be in windowClosed(), but doesn't seem to work */
+               if(e.getSource() == mainWindow)
+                       endOfTheWorld();
+       }
+
+       public void windowClosed(WindowEvent e) {
+               // add potential warnings here
+       }
+
+       public void windowDeactivated(WindowEvent e) {
+               // C'est pas comme si on en avait quelque chose ? foutre :p
+       }
+
+       public void windowDeiconified(WindowEvent e) {
+               // idem
+       }
+
+       public void windowIconified(WindowEvent e) {
+               // idem
+       }
+
+       public void windowOpened(WindowEvent e) {
+               // idem
+       }
+
+}

Added: trunk/apps/Thaw/src/thaw/core/NodeConfigPanel.java
===================================================================
--- trunk/apps/Thaw/src/thaw/core/NodeConfigPanel.java  2006-06-14 10:18:18 UTC 
(rev 9193)
+++ trunk/apps/Thaw/src/thaw/core/NodeConfigPanel.java  2006-06-14 11:28:59 UTC 
(rev 9194)
@@ -0,0 +1,87 @@
+package thaw.core;
+
+import javax.swing.JPanel;
+import javax.swing.JTabbedPane;
+import java.awt.GridLayout;
+import java.awt.event.ActionEvent;
+import java.awt.event.WindowEvent;
+import java.awt.event.ActionListener;
+import javax.swing.JTextField;
+import javax.swing.JLabel;
+
+import java.util.Observer;
+import java.util.Observable;
+
+import thaw.core.i18n.I18n;
+
+
+/**
+ * NodeConfigPanel. Creates and manages the panel containing all the things to 
configure
+ *  the settings to access the node.
+ */
+public class NodeConfigPanel implements Observer {
+       private Core core;
+       private JPanel nodeConfigPanel = null;
+
+
+       private final static String[] paramNames = { 
+               I18n.getMessage("thaw.config.nodeAddress"),
+               I18n.getMessage("thaw.config.nodePort")
+       };
+       private final static String[] configNames = {
+               "nodeAddress",
+               "nodePort"
+       };
+       private JLabel[] paramLabels = { null, null };
+       private JTextField[] paramFields = { null, null };
+
+       
+
+       public NodeConfigPanel(ConfigWindow configWindow, Core core) {
+               this.core = core;
+
+               nodeConfigPanel = new JPanel();
+               nodeConfigPanel.setLayout(new GridLayout(15, 1));
+               
+               for(int i=0; i < paramNames.length ; i++) {
+                       String value;
+                       
+                       if( (value = core.getConfig().getValue(configNames[i])) 
== null)
+                               value = "";
+
+                       paramLabels[i] = new JLabel(paramNames[i]);
+                       paramFields[i] = new JTextField(value);
+                       
+                       nodeConfigPanel.add(paramLabels[i]);
+                       nodeConfigPanel.add(paramFields[i]);
+               }
+
+               configWindow.addObserver(this);
+       }
+
+       public JPanel getPanel() {
+               return nodeConfigPanel;
+       }
+
+       
+       public void update(Observable o, Object arg) {
+               if(arg == core.getConfigWindow().getOkButton()) {
+                       for(int i=0;i < paramNames.length;i++) {
+                               core.getConfig().setValue(configNames[i], 
paramFields[i].getText());
+                       }
+               }
+
+
+               if(arg == core.getConfigWindow().getCancelButton()) {
+                       for(int i=0;i < paramNames.length;i++) {
+                               String value;
+
+                               if( (value = 
core.getConfig().getValue(configNames[i])) == null)
+                                       value = "";
+
+                               paramFields[i].setText(value);
+                       }
+               }
+       }
+
+}

Added: trunk/apps/Thaw/src/thaw/core/Plugin.java
===================================================================
--- trunk/apps/Thaw/src/thaw/core/Plugin.java   2006-06-14 10:18:18 UTC (rev 
9193)
+++ trunk/apps/Thaw/src/thaw/core/Plugin.java   2006-06-14 11:28:59 UTC (rev 
9194)
@@ -0,0 +1,23 @@
+package thaw.core;
+
+/**
+ * Define what methods a plugin must implements.
+ */
+public interface Plugin {
+
+       /*
+        * Plugin constructor must not take any argument.
+        */
+
+
+       /**
+        * Called when the plugin is runned.
+        * @param core A ref to the core of the program.
+        */
+       public boolean run(Core core);
+
+       /**
+        * Called when the plugin is stopped (often at the end of the program).
+        */
+       public boolean stop();
+}

Added: trunk/apps/Thaw/src/thaw/core/PluginConfigPanel.java
===================================================================
--- trunk/apps/Thaw/src/thaw/core/PluginConfigPanel.java        2006-06-14 
10:18:18 UTC (rev 9193)
+++ trunk/apps/Thaw/src/thaw/core/PluginConfigPanel.java        2006-06-14 
11:28:59 UTC (rev 9194)
@@ -0,0 +1,133 @@
+package thaw.core;
+
+import javax.swing.JPanel;
+import javax.swing.JLabel;
+import javax.swing.JList;
+import javax.swing.JDialog;
+import javax.swing.JTextField;
+import javax.swing.JTabbedPane;
+import java.awt.BorderLayout;
+import java.awt.GridLayout;
+import java.awt.event.ActionEvent;
+import java.awt.event.WindowEvent;
+import java.awt.event.ActionListener;
+import javax.swing.JButton;
+import javax.swing.JOptionPane;
+
+import java.util.Observer;
+import java.util.Observable;
+import java.util.Vector;
+
+import thaw.core.i18n.I18n;
+
+
+/**
+ * PluginConfigPanel. Creates and manages the panel containing all the things 
to configure
+ *  the list of plugins.
+ */
+public class PluginConfigPanel implements Observer, ActionListener {
+       private Core core;
+       private JPanel pluginConfigPanel = null;
+
+       private JLabel pluginsLoaded = null;
+       private JList pluginList = null;
+       
+       private JPanel buttonPanel = null;
+       private JButton removeButton = null;
+
+       private JPanel subButtonPanel = null;
+       private JTextField pluginToAdd = null;
+       private JButton addButton = null;
+
+
+       public PluginConfigPanel(ConfigWindow configWindow, Core core) {
+               Vector pluginNames;
+
+               this.core = core;
+
+               pluginConfigPanel = new JPanel();
+
+               pluginConfigPanel.setLayout(new BorderLayout());
+
+               pluginsLoaded = new 
JLabel(I18n.getMessage("thaw.config.pluginsLoaded"));
+               
+               pluginNames = core.getConfig().getPluginNames();
+               pluginList = new JList();
+               pluginList.setListData(core.getConfig().getPluginNames());
+               
+               
+               pluginToAdd = new JTextField("", 30);
+               
+               buttonPanel = new JPanel();
+               buttonPanel.setLayout(new GridLayout(2, 1));
+               
+               subButtonPanel = new JPanel();
+               subButtonPanel.setLayout(new GridLayout(1, 2));
+
+               addButton = new JButton(I18n.getMessage("thaw.common.add"));
+               removeButton = new 
JButton(I18n.getMessage("thaw.common.remove"));
+
+               addButton.addActionListener(this);
+               removeButton.addActionListener(this);
+               
+               buttonPanel.add(removeButton);
+
+               subButtonPanel.add(pluginToAdd);
+               subButtonPanel.add(addButton);
+               buttonPanel.add(subButtonPanel);
+               
+               pluginConfigPanel.add(pluginsLoaded, BorderLayout.NORTH);
+               pluginConfigPanel.add(pluginList, BorderLayout.CENTER);
+               pluginConfigPanel.add(buttonPanel, BorderLayout.SOUTH);
+
+               configWindow.addObserver(this);
+       }
+
+
+       public JPanel getPanel() {
+               return pluginConfigPanel;
+       }
+
+       /**
+        * In fact, it's not used here, because config is immediatly updated 
when
+        * user change something.
+        */
+       public void update(Observable o, Object arg) {
+
+       }
+
+
+       public void actionPerformed(ActionEvent e) {
+               if(e.getSource() == addButton) {
+                       
if(core.getPluginManager().loadPlugin(pluginToAdd.getText())
+                          && 
core.getPluginManager().runPlugin(pluginToAdd.getText())) {
+
+                               
core.getConfig().addPlugin(pluginToAdd.getText());
+                               
pluginList.setListData(core.getConfig().getPluginNames());
+
+                       } else {
+                               Logger.error(this, "Unable to load 
'"+pluginToAdd.getText()+"'");
+                               
JOptionPane.showMessageDialog(core.getConfigWindow().getFrame(),
+                                                             "Unable to load 
plugin '"+pluginToAdd.getText()+"'",
+                                                             "Unable to load 
plugin",
+                                                             
JOptionPane.ERROR_MESSAGE);
+                       }
+               }
+
+
+               if(e.getSource() == removeButton) {
+                       
if(core.getPluginManager().stopPlugin((String)pluginList.getSelectedValue())
+                          && 
core.getPluginManager().unloadPlugin((String)pluginList.getSelectedValue())) {
+                               
+                               
core.getConfig().removePlugin((String)pluginList.getSelectedValue());
+                               
pluginList.setListData(core.getConfig().getPluginNames());
+                       } else {
+                               Logger.error(this, "Unable to unload 
'"+pluginToAdd.getText()+"'");
+                               
JOptionPane.showMessageDialog(core.getConfigWindow().getFrame(),
+                                                             "Unable to unload 
plugin '"+pluginToAdd.getText()+"'",
+                                                             "Unable to unload 
plugin",
+                                                             
JOptionPane.ERROR_MESSAGE);
+                       }
+               }
+       }
+}

Added: trunk/apps/Thaw/src/thaw/core/PluginManager.java
===================================================================
--- trunk/apps/Thaw/src/thaw/core/PluginManager.java    2006-06-14 10:18:18 UTC 
(rev 9193)
+++ trunk/apps/Thaw/src/thaw/core/PluginManager.java    2006-06-14 11:28:59 UTC 
(rev 9194)
@@ -0,0 +1,185 @@
+package thaw.core;
+
+import java.util.HashMap;
+import java.util.Vector;
+import java.util.Iterator;
+
+/**
+ * Manages plugins :)
+ */
+public class PluginManager {
+       private final static String[] defaultPlugins = 
{"thaw.plugins.QueueWatcher"};
+
+       private Core core = null;
+
+       private HashMap plugins = null; // String (pluginName) -> Plugin
+
+
+       /**
+        * Need a ref to the core to pass it to the plugins (and to access 
config)
+        */
+       public PluginManager(Core core) {
+               this.core = core;
+               this.plugins = new HashMap();
+       }
+
+
+       /**
+        * Load plugin from config or from default list.
+        */
+       public boolean loadPlugins() {
+               Vector pluginNames;
+
+               if(core.getConfig().getPluginNames().size() == 0) {
+                       /* Then we load the config with the default plugins */
+                       for(int i = 0 ; i < defaultPlugins.length ; i++) {
+                               core.getConfig().addPlugin(defaultPlugins[i]);
+                       }
+               }
+
+               pluginNames = core.getConfig().getPluginNames();
+
+               for(int i=0 ; i < pluginNames.size(); i++) {
+                       loadPlugin((String)pluginNames.get(i));
+               }
+
+               return true;
+       }
+
+       /** 
+        * Start plugins.
+        */
+       public boolean runPlugins() {
+               Iterator pluginIt;
+               
+               try {
+                       pluginIt = plugins.values().iterator();
+                       
+                       while(pluginIt.hasNext()) {
+                               Plugin plugin = (Plugin)pluginIt.next();
+
+                               try {
+                                       plugin.run(core);
+                               } catch(Exception e) {
+                                       Logger.error(this, "Unable to run the 
plugin '"+plugin.getClass().getName()+"'");
+                               }
+
+
+                       }
+               } catch(NullPointerException e) {
+                       Logger.notice(this, "No plugin to run");
+                       return false;
+               }
+               
+
+               return true;
+       }
+
+
+       /**
+        * Stop all plugins.
+        */
+       public boolean stopPlugins() {
+               Iterator pluginIt;
+               
+               try {
+                       pluginIt = plugins.values().iterator();
+                       
+                       while(pluginIt.hasNext()) {
+                               Plugin plugin = (Plugin)pluginIt.next();
+                               
+                               try {
+                                       plugin.stop();
+                               } catch(Exception e) {
+                                       Logger.error(this, "Unable to run the 
plugin '"+plugin.getClass().getName()+"'");
+                               }
+
+
+                       }
+               } catch(NullPointerException e) {
+                       Logger.notice(this, "No plugin to load");
+                       return false;
+               }
+               
+
+               return true;
+       }
+
+
+       /**
+        * Load a given plugin (without adding it to the config or running it).
+        */
+       public boolean loadPlugin(String className) {
+               try {
+                       if(plugins.get(className) != null) {
+                               Logger.warning(this, "loadPlugin(): Plugin 
'"+className+"' already loaded");
+                               return false;
+                       }
+
+                       plugins.put(className, 
Class.forName(className).newInstance());
+                       
+               } catch(Exception e) {
+                       Logger.warning(this, "loadPlugin('"+className+"'): 
Exception: "+e);
+                       return false;
+               }
+
+               return true;
+       }
+
+
+       /**
+        * Run a given plugin.
+        */
+       public boolean runPlugin(String className) {
+               try {
+                       ((Plugin)plugins.get(className)).run(core);
+                       
+               } catch(Exception e) {
+                       Logger.warning(this, "runPlugin('"+className+"'): 
Exception: "+e);
+                       return false;
+               }
+
+               return true;
+       }
+       
+
+       /**
+        * Stop a given plugin.
+        */
+       public boolean stopPlugin(String className) {
+               try {
+                       ((Plugin)plugins.get(className)).stop();
+                       
+               } catch(Exception e) {
+                       Logger.warning(this, "runPlugin('"+className+"'): 
Exception: "+e);
+                       return false;
+               }
+
+               return true;
+       }
+
+
+       /**
+        * Unload a given plugin (without adding it to the config or running 
it).
+        */
+       public boolean unloadPlugin(String className) {
+               try {
+                       if(plugins.get(className) == null) {
+                               Logger.warning(this, "unloadPlugin(): Plugin 
'"+className+"' already unloaded");
+                               return false;
+                       }
+
+                       plugins.put(className, null);
+                       
+               } catch(Exception e) {
+                       Logger.warning(this, "unloadPlugin('"+className+"'): 
Exception: "+e);
+                       return false;
+               }
+
+               return true;
+       }
+
+       public Plugin getPlugin(String className) {
+               return (Plugin)plugins.get(className);
+       }
+}

Added: trunk/apps/Thaw/src/thaw/i18n/I18n.java
===================================================================
--- trunk/apps/Thaw/src/thaw/i18n/I18n.java     2006-06-14 10:18:18 UTC (rev 
9193)
+++ trunk/apps/Thaw/src/thaw/i18n/I18n.java     2006-06-14 11:28:59 UTC (rev 
9194)
@@ -0,0 +1,74 @@
+/*
+ * Thaw - A tool to insert and fetch files on freenet
+ * by Jerome Flesch
+ * 2006(c) Freenet project
+ * ==================================================
+ *
+ * This file was originally created by David Roden and next adapted to Thaw by 
Jerome Flesch.
+ *
+ * Copyright (C) 2006 David Roden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+package thaw.core.i18n;
+
+import java.util.Locale;
+import java.util.ResourceBundle;
+
+import thaw.core.Logger;
+
+/**
+ * @author David Roden &lt;droden at gmail.com&gt;
+ * @version $Id: I18n.java 355 2006-03-24 15:04:11Z bombe $
+ */
+public class I18n {
+
+       private static Locale currentLocale;
+
+       public I18n() {
+
+       }
+
+       public static Locale getLocale() {
+               if (currentLocale == null)
+                       currentLocale = Locale.getDefault();
+               return currentLocale;
+       }
+
+       public static void setLocale(Locale locale) {
+               currentLocale = locale;
+               Locale.setDefault(locale);
+       }
+
+       public static ResourceBundle getResourceBundle() {
+               return getResourceBundle(getLocale());
+       }
+
+       public static ResourceBundle getResourceBundle(Locale locale) {
+               return ResourceBundle.getBundle("thaw.i18n.thaw", getLocale());
+       }
+
+       public static String getMessage(String key) {
+               try {
+                       return getResourceBundle().getString(key);
+               } catch(Exception e) {
+                       Logger.warning(new I18n(),/* we need a ref -> random 
ref -> this is *bad* */
+                                      "Unable to find translation for 
'"+key+"'");
+                       return key;
+               }
+       }
+
+}

Added: trunk/apps/Thaw/src/thaw/i18n/thaw.properties
===================================================================
--- trunk/apps/Thaw/src/thaw/i18n/thaw.properties       2006-06-14 10:18:18 UTC 
(rev 9193)
+++ trunk/apps/Thaw/src/thaw/i18n/thaw.properties       2006-06-14 11:28:59 UTC 
(rev 9194)
@@ -0,0 +1,27 @@
+# English, by Jerome Flesch, for Thaw
+# 2006(c)
+
+## Commons
+thaw.common.node=Node
+thaw.common.plugins=Plugins
+thaw.common.add=Add
+thaw.common.remove=Remove
+
+## Menus
+thaw.menu.file=File
+thaw.menu.item.options=Options
+thaw.menu.item.quit=Quit
+
+## Status bar
+thaw.statusBar.initPlugins=Loading plugins ...
+thaw.statusBar.ready=Ready
+
+## Config
+thaw.config.windowName=Configuration
+thaw.config.okButton=Apply
+thaw.config.cancelButton=Cancel
+
+thaw.config.nodeAddress=Node address
+thaw.config.nodePort=Node port (FCP)
+
+thaw.config.pluginsLoaded=Plugins loaded:
\ No newline at end of file

Added: trunk/apps/Thaw/src/thaw/plugins/QueueWatcher.java
===================================================================
--- trunk/apps/Thaw/src/thaw/plugins/QueueWatcher.java  2006-06-14 10:18:18 UTC 
(rev 9193)
+++ trunk/apps/Thaw/src/thaw/plugins/QueueWatcher.java  2006-06-14 11:28:59 UTC 
(rev 9194)
@@ -0,0 +1,23 @@
+package thaw.plugins;
+
+import thaw.core.*;
+
+public class QueueWatcher implements thaw.core.Plugin {
+
+       public QueueWatcher() {
+
+       }
+
+
+       public boolean run(Core core) {
+
+               return true;
+       }
+
+
+       public boolean stop() {
+
+               return true;
+       }
+
+}


Reply via email to