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 <droden at gmail.com>
+ * @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;
+ }
+
+}