Author: jflesch
Date: 2006-07-08 01:05:24 +0000 (Sat, 08 Jul 2006)
New Revision: 9499

Added:
   trunk/apps/Thaw/src/thaw/core/FileChooser.java
   trunk/apps/Thaw/src/thaw/fcp/FCPClientGet.java
   trunk/apps/Thaw/src/thaw/fcp/FCPWatchGlobal.java
   trunk/apps/Thaw/src/thaw/plugins/fetchPlugin/KeyFileFilter.java
Modified:
   trunk/apps/Thaw/src/thaw/core/Core.java
   trunk/apps/Thaw/src/thaw/core/Logger.java
   trunk/apps/Thaw/src/thaw/core/NodeConfigPanel.java
   trunk/apps/Thaw/src/thaw/core/PluginManager.java
   trunk/apps/Thaw/src/thaw/fcp/FCPClientHello.java
   trunk/apps/Thaw/src/thaw/fcp/FCPConnection.java
   trunk/apps/Thaw/src/thaw/fcp/FCPMessage.java
   trunk/apps/Thaw/src/thaw/fcp/FCPQuery.java
   trunk/apps/Thaw/src/thaw/fcp/FCPQueryManager.java
   trunk/apps/Thaw/src/thaw/fcp/FCPQueueManager.java
   trunk/apps/Thaw/src/thaw/i18n/thaw.properties
   trunk/apps/Thaw/src/thaw/plugins/FetchPlugin.java
   trunk/apps/Thaw/src/thaw/plugins/QueueWatcher.java
   trunk/apps/Thaw/src/thaw/plugins/fetchPlugin/FetchPanel.java
   trunk/apps/Thaw/src/thaw/plugins/queueWatcher/DetailPanel.java
   trunk/apps/Thaw/src/thaw/plugins/queueWatcher/QueuePanel.java
   trunk/apps/Thaw/src/thaw/plugins/queueWatcher/QueueTableModel.java
Log:
Thaw can now fetch files (but is still unable to resume from global queue)

Modified: trunk/apps/Thaw/src/thaw/core/Core.java
===================================================================
--- trunk/apps/Thaw/src/thaw/core/Core.java     2006-07-08 00:44:01 UTC (rev 
9498)
+++ trunk/apps/Thaw/src/thaw/core/Core.java     2006-07-08 01:05:24 UTC (rev 
9499)
@@ -124,8 +124,10 @@

                try {

-                       if(connection != null && connection.isConnected())
+                       if(connection != null && connection.isConnected()) {
+                               connection.deleteObserver(this);
                                connection.disconnect();
+                       }

                        connection = new 
FCPConnection(config.getValue("nodeAddress"),
                                                       (new 
Integer(config.getValue("nodePort"))).intValue());
@@ -139,23 +141,31 @@
                        }

                        queryManager = new FCPQueryManager(connection);
-                       queueManager = new FCPQueueManager(queryManager,
-                                                          (new 
Integer(config.getValue("maxSimultaneousDownloads"))).intValue(),
-                                                          (new 
Integer(config.getValue("maxSimultaneousInsertions"))).intValue());
+
                        if(connection.isConnected()) {
                                queryManager.startListening();

-                               clientHello = new 
FCPClientHello(config.getValue("thawId"));
+                               clientHello = new FCPClientHello(queryManager, 
config.getValue("thawId"));

-                               if(!clientHello.start(queryManager)) {
+                               if(!clientHello.start(null)) {
                                        new WarningWindow(this, 
I18n.getMessage("thaw.error.idAlreadyUsed"));
                                } else {
                                        Logger.debug(this, "Hello successful");
                                        Logger.debug(this, "Node name    : 
"+clientHello.getNodeName());
                                        Logger.debug(this, "FCP  version : 
"+clientHello.getNodeFCPVersion());
                                        Logger.debug(this, "Node version : 
"+clientHello.getNodeVersion());
+                                       
+                                       queueManager = new 
FCPQueueManager(queryManager,
+                                                                          
config.getValue("thawId"),
+                                                                          (new 
Integer(config.getValue("maxSimultaneousDownloads"))).intValue(),
+                                                                          (new 
Integer(config.getValue("maxSimultaneousInsertions"))).intValue());
+                                       queueManager.startScheduler();
+
+                                       FCPWatchGlobal watchGlobal = new 
FCPWatchGlobal(true);
+                                       watchGlobal.start(queueManager);        
                                
+
                                }
-                               
+                                                                  
                        }

                } catch(Exception e) { /* A little bit not ... "nice" ... */
@@ -178,7 +188,7 @@
                return connection;
        }

-       public FCPQueueManager getQueueManger() {
+       public FCPQueueManager getQueueManager() {
                return queueManager;
        }

@@ -222,9 +232,16 @@
         * End of the world.
         */
        public void exit() {
+               Logger.info(this, "Stopping scheduler ...");
+               queueManager.stopScheduler();
+               
                Logger.info(this, "Stopping plugins ...");
                pluginManager.stopPlugins();

+               Logger.info(this, "Disconnecting ...");
+               connection.deleteObserver(this);
+               connection.disconnect();
+
                Logger.info(this, "Saving configuration ...");
                if(!config.saveConfig()) {
                        Logger.error(this, "Config was not saved correctly !");

Added: trunk/apps/Thaw/src/thaw/core/FileChooser.java
===================================================================
--- trunk/apps/Thaw/src/thaw/core/FileChooser.java      2006-07-08 00:44:01 UTC 
(rev 9498)
+++ trunk/apps/Thaw/src/thaw/core/FileChooser.java      2006-07-08 01:05:24 UTC 
(rev 9499)
@@ -0,0 +1,81 @@
+package thaw.core;
+
+import javax.swing.JFileChooser;
+import java.io.File;
+import java.util.Vector;
+
+/**
+ * FileChooser helps to create and use simple JFileChooser.
+ * Don't block any swing component.
+ */
+public class FileChooser {
+       private JFileChooser fileChooser = null;
+
+       public FileChooser() {
+               fileChooser = new JFileChooser();
+       }
+
+       public void setTitle(String title) {
+               fileChooser.setDialogTitle(title);
+       }
+
+       public void setDirectoryOnly(boolean v) {
+               if(v)
+                       
fileChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
+               else
+                       
fileChooser.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);
+       }
+       
+       /**
+        * @param type JFileChooser.OPEN_DIALOG / JFileChooser.SAVE_DIALOG
+        * @see javax.swing.JFileChooser#setDialogType(int)
+        */
+       public void setDialogType(int type) {
+               fileChooser.setDialogType(type);
+       }
+
+       protected boolean showDialog() {
+               int result = 0;
+
+               if(fileChooser.getDialogType() == JFileChooser.OPEN_DIALOG) {
+                       result = fileChooser.showOpenDialog(null);
+               }
+
+               if(fileChooser.getDialogType() == JFileChooser.SAVE_DIALOG) {
+                       result = fileChooser.showSaveDialog(null);
+               }
+
+               if(result == JFileChooser.APPROVE_OPTION)
+                       return true;
+               else
+                       return false;
+
+       }
+
+       /**
+        * @return null if nothing choosed.
+        */
+       public File askOneFile() {
+               fileChooser.setMultiSelectionEnabled(false);
+
+               if(!showDialog())
+                       return null;
+
+               return fileChooser.getSelectedFile();
+       }
+       
+       /**
+        * @return null if nothing choosed.
+        */
+       public File[] askManyFiles() {
+               fileChooser.setMultiSelectionEnabled(true);
+
+               if(!showDialog())
+                       return null;
+
+               
+
+               return fileChooser.getSelectedFiles();
+       }
+
+}

Modified: trunk/apps/Thaw/src/thaw/core/Logger.java
===================================================================
--- trunk/apps/Thaw/src/thaw/core/Logger.java   2006-07-08 00:44:01 UTC (rev 
9498)
+++ trunk/apps/Thaw/src/thaw/core/Logger.java   2006-07-08 01:05:24 UTC (rev 
9499)
@@ -50,7 +50,7 @@
         */
        public static void notice(Object o, String msg) {
                if(LOG_LEVEL >= 2)
-                       displayErr("[NOTICE ] " +o.getClass().getName()+": 
"+msg);
+                       display("[NOTICE ] " +o.getClass().getName()+": "+msg);
        }



Modified: trunk/apps/Thaw/src/thaw/core/NodeConfigPanel.java
===================================================================
--- trunk/apps/Thaw/src/thaw/core/NodeConfigPanel.java  2006-07-08 00:44:01 UTC 
(rev 9498)
+++ trunk/apps/Thaw/src/thaw/core/NodeConfigPanel.java  2006-07-08 01:05:24 UTC 
(rev 9499)
@@ -79,7 +79,10 @@
                        }

                        /* should reinit the whole connection correctly */
+                       core.getPluginManager().stopPlugins();
                        core.initNodeConnection();
+                       core.getPluginManager().loadPlugins();
+                       core.getPluginManager().runPlugins();
                }



Modified: trunk/apps/Thaw/src/thaw/core/PluginManager.java
===================================================================
--- trunk/apps/Thaw/src/thaw/core/PluginManager.java    2006-07-08 00:44:01 UTC 
(rev 9498)
+++ trunk/apps/Thaw/src/thaw/core/PluginManager.java    2006-07-08 01:05:24 UTC 
(rev 9499)
@@ -37,8 +37,11 @@

        /**
         * Load plugin from config or from default list.
+        * Reload if already loaded.
         */
        public boolean loadPlugins() {
+               plugins = new LinkedHashMap();
+
                Vector pluginNames;

                if(core.getConfig().getPluginNames().size() == 0) {

Added: trunk/apps/Thaw/src/thaw/fcp/FCPClientGet.java
===================================================================
--- trunk/apps/Thaw/src/thaw/fcp/FCPClientGet.java      2006-07-08 00:44:01 UTC 
(rev 9498)
+++ trunk/apps/Thaw/src/thaw/fcp/FCPClientGet.java      2006-07-08 01:05:24 UTC 
(rev 9499)
@@ -0,0 +1,343 @@
+package thaw.fcp;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.util.Observer;
+import java.util.Observable;
+
+import thaw.core.Logger;
+
+/**
+ * notify() only when progress has really changes.
+ */
+public class FCPClientGet extends Observable implements Observer, FCPQuery {
+       private final static String MAX_RETRIES = "3";
+       private final static int PACKET_SIZE = 1024;
+       private final static int BLOCK_SIZE = 32768;
+
+       private FCPQueueManager queueManager;
+
+       private String key = null;
+       private String filename = null; /* Extract from the key */
+       private int priority = 6;
+       private int persistence = 0;
+       private boolean globalQueue = false;
+       private String destinationDir = null;
+
+       private int attempt = 0;
+       private String status;
+
+       private String id;
+
+       private int progress; /* in pourcent */
+       private long fileSize;
+
+       /**
+        * @param persistence 0 = Forever ; 1 = Until node reboot ; 2 = Until 
the app disconnect
+        */
+       public FCPClientGet(String key, int priority,
+                           int persistence, boolean globalQueue,
+                           String destinationDir) {
+
+               if(globalQueue && persistence >= 2)
+                       globalQueue = false; /* else protocol error */
+
+               this.key = key;
+               this.priority = priority;
+               this.persistence = persistence;
+               this.globalQueue = globalQueue;
+               this.destinationDir = destinationDir;
+
+               this.progress = 0;
+               this.fileSize = 0;
+               
+               String cutcut[] = key.split("/");
+               
+               filename = cutcut[cutcut.length-1];
+
+               if(filename.equals("") || filename.indexOf('.') < 0) {
+                       filename = "index.html";
+               }
+               
+               Logger.debug(this, "Getting "+key);
+
+               status = "Waiting";
+
+       }
+
+       public boolean start(FCPQueueManager queueManager) {
+               this.queueManager = queueManager;
+
+               status = "Requesting";
+
+               this.id = queueManager.getAnID();
+
+               Logger.info(this, "Requesting key : "+getFileKey());
+
+               FCPMessage queryMessage = new FCPMessage();
+
+               queryMessage.setMessageName("ClientGet");
+               queryMessage.setValue("URI", getFileKey());
+               queryMessage.setValue("Identifier", id);
+               queryMessage.setValue("Verbosity", "1");
+               queryMessage.setValue("MaxRetries", MAX_RETRIES);
+               queryMessage.setValue("PriorityClass", (new 
Integer(priority)).toString());
+
+               if(persistence == 0)
+                       queryMessage.setValue("Persistence", "forever");
+               if(persistence == 1)
+                       queryMessage.setValue("Persistence", "reboot");
+               if(persistence == 2)
+                       queryMessage.setValue("Persistence", "connection");
+
+               if(globalQueue)
+                       queryMessage.setValue("Global", "true");
+               else
+                       queryMessage.setValue("Global", "false");
+
+               queryMessage.setValue("ReturnType", "direct");
+
+               queueManager.getQueryManager().addObserver(this);
+
+               queueManager.getQueryManager().writeMessage(queryMessage);
+
+               return true;
+       }
+
+       
+       public void update(Observable o, Object arg) {
+               FCPMessage message = (FCPMessage)arg;
+
+               if(message.getValue("Identifier") == null
+                  || !message.getValue("Identifier").equals(id)) {
+                       if(message.getValue("Identifier") != null)
+                               Logger.verbose(this, "Not for us : 
"+message.getValue("Identifier"));
+                       else
+                               Logger.verbose(this, "Not for us");
+                       return;
+               } else {
+                       Logger.verbose(this, "For us for us !");
+               }
+
+               if(message.getMessageName().equals("DataFound")) {
+                       Logger.debug(this, "DataFound!");
+
+                       status = "Fetching";
+                       fileSize = (new 
Long(message.getValue("DataLength"))).longValue();
+
+                       
+                       if(globalQueue) {
+                               FCPMessage getRequestStatus = new FCPMessage();
+                               
+                               
getRequestStatus.setMessageName("GetRequestStatus");
+                               getRequestStatus.setValue("Identifier", id);
+                               if(globalQueue)
+                                       getRequestStatus.setValue("Global", 
"true");
+                               else
+                                       getRequestStatus.setValue("Global", 
"false");
+                               getRequestStatus.setValue("OnlyData", "true");
+                               
+                               
queueManager.getQueryManager().writeMessage(getRequestStatus);
+                       }
+                       
+
+                       setChanged();
+                       notifyObservers();
+
+                       return;
+               }
+
+               if(message.getMessageName().equals("IdentifierCollision")) {
+                       Logger.notice(this, "IdentifierCollision ! Resending 
with another id");
+
+                       start(queueManager);
+                       
+                       setChanged();
+                       notifyObservers();
+
+                       return;
+               }
+               
+               if(message.getMessageName().equals("ProtocolError")) {
+                       Logger.debug(this, "ProtocolError !");
+
+                       status = "Protocol Error";
+                       progress = 100;
+
+                       queueManager.getQueryManager().deleteObserver(this);
+
+                       setChanged();
+                       notifyObservers();
+                       
+                       return;
+               }
+
+               if(message.getMessageName().equals("GetFailed")) {
+                       Logger.debug(this, "GetFailed !");
+
+                       status = "Failed";
+                       progress = 100;
+
+                       queueManager.getQueryManager().deleteObserver(this);
+
+                       setChanged();
+                       notifyObservers();
+
+                       return;
+               }
+
+               if(message.getMessageName().equals("SimpleProgress")) {
+                       Logger.debug(this, "SimpleProgress !");
+
+                       progress = 0;
+
+                       if(message.getValue("Total") != null
+                          && message.getValue("Succeeded") != null) {
+                               fileSize = ((new 
Long(message.getValue("Total"))).longValue())*BLOCK_SIZE;
+                               long required = (new 
Long(message.getValue("Total"))).longValue();
+                               long succeeded = (new 
Long(message.getValue("Succeeded"))).longValue();
+
+                               status = "Fetching";
+
+                               progress = (int)((succeeded * 100) / required);
+
+                               setChanged();
+                               notifyObservers();
+                       }
+
+                       return;
+               }
+
+               if(message.getMessageName().equals("AllData")) {
+                       Logger.debug(this, "AllData !");
+
+                       status = "Loading";
+
+                       fileSize = (new 
Long(message.getValue("DataLength"))).longValue();
+
+                       status = "Available";
+
+                       fetchDirectly(fileSize);
+
+                       progress = 100;
+
+                       queueManager.getQueryManager().deleteObserver(this);
+
+                       return;
+               }
+
+               if(message.getMessageName().equals("PersistentGet")) {
+                       /* Should not bother us */
+                       return;
+               }
+
+               Logger.warning(this, "Unknow message : 
"+message.getMessageName() + " !");
+
+       }
+
+
+       public void fetchDirectly(long size) {
+               FCPConnection connection;
+               File newFile = new File(getPath());
+               FileOutputStream fileWriter;
+
+               connection = queueManager.getQueryManager().getConnection();
+
+               Logger.info(this, "Writing file to disk ...");
+
+               try {
+                       fileWriter = new FileOutputStream(newFile);
+               } catch(java.io.IOException e) {
+                       Logger.error(this, "Unable to write file on disk ... 
perms ? : "+e.toString());
+                       status = "Write error";
+                       return;
+               }
+
+               /* size == bytes remaining on socket */
+               while(size > 0) {
+                       int packet = PACKET_SIZE;
+                       byte[] read;
+                       int amount;
+                       
+                       if(size < (long)packet)
+                               packet = (int)size;
+
+                       read = new byte[packet];
+
+                       amount = connection.read(packet, read);
+
+                       if(amount <= -1) {
+                               Logger.error(this, "Socket closed ?!");
+                               status = "Read error";
+                               break;
+                       }
+
+                       try {
+                               fileWriter.write(read, 0, amount);
+                       } catch(java.io.IOException e) {
+                               Logger.error(this, "Unable to write file on 
disk ... out of space ? : "+e.toString());
+                               status = "Write error";
+                               return;
+                       }
+                       
+                       size = size - amount;
+                       
+               }
+               
+               try {
+                       fileWriter.close();
+               } catch(java.io.IOException e) {
+                       Logger.notice(this, "Unable to close correctly file on 
disk !? : "+e.toString());
+               }
+
+               Logger.info(this, "File written");
+
+       }
+
+
+       public boolean stop(FCPQueueManager queryManager) {
+               Logger.info(this, "*TODO* stop()  *TODO*");
+               /* TODO */
+               return false;
+       }
+
+       public int getThawPriority() {
+               return priority;
+       }
+
+       public int getQueryType() {
+               return 1;
+       }
+       
+       public String getStatus() {
+               return status;
+       }
+
+       public int getProgression() {
+               return progress;
+       }
+
+       public String getFileKey() {
+               return key;
+       }
+
+       public boolean isFinished() {
+               if(progress >= 99)
+                       return true;
+
+               return false;
+       }
+
+       public long getFileSize() {
+               return fileSize;
+       }
+
+       public String getPath() {
+               return destinationDir + File.separator + filename;
+       }
+
+
+       public int getAttempt() {
+               return attempt;
+       }
+}

Modified: trunk/apps/Thaw/src/thaw/fcp/FCPClientHello.java
===================================================================
--- trunk/apps/Thaw/src/thaw/fcp/FCPClientHello.java    2006-07-08 00:44:01 UTC 
(rev 9498)
+++ trunk/apps/Thaw/src/thaw/fcp/FCPClientHello.java    2006-07-08 01:05:24 UTC 
(rev 9499)
@@ -30,8 +30,9 @@
        /**
         * Need to know the id of the application (see FCP specs).
         */
-       public FCPClientHello(String id) {
+       public FCPClientHello(FCPQueryManager queryManager, String id) {
                setID(id);
+               this.queryManager = queryManager;
        }


@@ -67,8 +68,7 @@
        /**
         * Warning: This query is blocking (only this one) !
         */
-       public boolean start(FCPQueryManager queryManager) {
-               this.queryManager = queryManager;
+       public boolean start(FCPQueueManager queueManager) {

                FCPMessage message = new FCPMessage();

@@ -141,8 +141,42 @@
        /**
         * Not used.
         */
-       public boolean stop(FCPQueryManager queryManager) {
+       public boolean stop(FCPQueueManager queueManager) {
                return false;
        }

+
+       public int getQueryType() {
+               return 0;
+       }
+
+       public String getStatus() {
+               return null;
+       }
+
+       public int getProgression() {
+               return 0;
+       }
+
+       public String getFileKey() {
+               return null;
+       }
+
+       public long getFileSize() {
+               return 0;
+       }
+
+       public boolean isFinished() {
+               return false;
+       }
+
+       public String getPath() {
+               return null;
+       }
+
+       public int getAttempt() {
+               return -1;
+       }
+
 }
+

Modified: trunk/apps/Thaw/src/thaw/fcp/FCPConnection.java
===================================================================
--- trunk/apps/Thaw/src/thaw/fcp/FCPConnection.java     2006-07-08 00:44:01 UTC 
(rev 9498)
+++ trunk/apps/Thaw/src/thaw/fcp/FCPConnection.java     2006-07-08 01:05:24 UTC 
(rev 9499)
@@ -3,7 +3,8 @@
 import java.net.Socket;
 import java.io.InputStream;
 import java.io.OutputStream;
-import java.io.BufferedReader;
+/* import java.io.BufferedReader; */
+import java.io.BufferedInputStream;
 import java.io.InputStreamReader;
 import java.util.Observable;

@@ -26,7 +27,7 @@
        private InputStream in = null;
        private OutputStream out = null;

-       private BufferedReader reader = null;
+       private BufferedInputStream reader = null;

        /** If == 1, then will print on stdout
         * all fcp input / output.
@@ -120,7 +121,7 @@
                        return false;
                }

-               reader = new BufferedReader(new InputStreamReader(in));
+               reader = new BufferedInputStream(in);

                setChanged();
                notifyObservers();
@@ -138,7 +139,7 @@



-       public boolean write(String toWrite) {
+       public synchronized boolean write(String toWrite) {
                Logger.asIt(this, "Thaw >>> Node :");
                Logger.asIt(this, toWrite);

@@ -157,6 +158,18 @@
                return true;
        }

+
+       public int read(int lng, byte[] buf) {
+               
+               try {
+                       return reader.read(buf);
+               } catch(java.io.IOException e) {
+                       Logger.warning(this, "IOException while reading on 
socket");
+                       return -1;
+               }
+
+       }
+
        /**
         * Read a line.
         * @return null if error
@@ -164,21 +177,35 @@
        public String readLine() {
                String result;

-               if(in != null && socket != null && socket.isConnected()) {
+               if(in != null && reader != null && socket != null && 
socket.isConnected()) {
                        try {
-                               /*
-                               reader = new BufferedReader(new 
InputStreamReader(in));
-                               result = reader.readLine();
-                               */
+                               result = "";

-                               result = reader.readLine();
+                               /* result = reader.readLine(); */
+                               
+                               int c = 0;

+                               while(c != '\n') {
+                                       c = reader.read();
+
+                                       if(c == -1) {
+                                               Logger.notice(this, "Unable to 
read ? => disconnect ?");
+                                               return null;
+                                       }
+                                       
+                                       if(c == '\n')
+                                               break;
+
+                                       result = result + new String(new byte[] 
{ (byte)c });
+                                       
+                               }
+
                                Logger.asIt(this, "Thaw <<< Node : "+result);

                                return result;

                        } catch (java.io.IOException e) {
-                               Logger.error(this, "Unable to read() on the 
socket ?! : "+e.toString());
+                               Logger.notice(this, "Unable to read() on the 
socket ?! => disconnect ? : "+e.toString());
                                return null;
                        }
                } else {

Modified: trunk/apps/Thaw/src/thaw/fcp/FCPMessage.java
===================================================================
--- trunk/apps/Thaw/src/thaw/fcp/FCPMessage.java        2006-07-08 00:44:01 UTC 
(rev 9498)
+++ trunk/apps/Thaw/src/thaw/fcp/FCPMessage.java        2006-07-08 01:05:24 UTC 
(rev 9499)
@@ -39,8 +39,6 @@

                String[] lines = rawMessage.split("\n");

-               /* TODO : Find why some messages from the node starts with an 
'\n' */
-
                for(i = 0 ; lines[i].equals("");) {
                        i++;
                }
@@ -85,11 +83,6 @@
        }

        public void setValue(String field, String value) {
-               if(field.equals("DataLength")) {
-                       Logger.warning(this, "Trying to add field 'DataLength' 
to a message ! You don't have to !\n");
-                       return;
-               }
-
                fields.put(field, value);
        }


Modified: trunk/apps/Thaw/src/thaw/fcp/FCPQuery.java
===================================================================
--- trunk/apps/Thaw/src/thaw/fcp/FCPQuery.java  2006-07-08 00:44:01 UTC (rev 
9498)
+++ trunk/apps/Thaw/src/thaw/fcp/FCPQuery.java  2006-07-08 01:05:24 UTC (rev 
9499)
@@ -1,17 +1,76 @@
 package thaw.fcp;

-interface FCPQuery {
+/**
+ * This interface was designed for file query (insertions / downloads)
+ * but it's used sometimes for other things.
+ */
+public interface FCPQuery {

-       public boolean start(FCPQueryManager queryManager);
-       public boolean stop(FCPQueryManager queryManager);
+       /**
+        * @param queueManager QueueManager gives access to QueryManager.
+        */
+       public boolean start(FCPQueueManager queueManager);

        /**
+        * @param queueManger QueueManager gives access to QueryManager.
+        */
+       public boolean stop(FCPQueueManager queueManager);
+
+       /**
         * Used by the QueueManager only.
         * Currently these priority are the same
         * as FCP priority, but it can change in the
         * future.
         * -1 = No priority
+        * Always between -1 and 6.
         */
        public int getThawPriority();

+       /**
+        * Tell if the query is a download query or an upload query.
+        * If >= 1 then *must* be Observable.
+        * @return 0 : Meaningless ; 1 : Download ; 2 : Upload
+        */
+       public int getQueryType();
+       
+
+       /**
+        * Informal.
+        * Human readable string describring the
+        * status of the query.
+        * @return can be null (== "Waiting")
+        */
+       public String getStatus();
+
+       /**
+        * Informal.
+        * In pourcents.
+        */
+       public int getProgression();
+
+       /**
+        * Informal.
+        * @return can be null
+        */
+       public String getFileKey();
+
+       /**
+        * Informal. In bytes.
+        * @return can be -1
+        */
+       public long getFileSize();
+
+       /**
+        * Informal.
+        * @return can return null
+        */
+       public String getPath();
+
+       /**
+        * Informal.
+        * @return can return -1
+        */
+       public int getAttempt();
+
+       public boolean isFinished();
 }

Modified: trunk/apps/Thaw/src/thaw/fcp/FCPQueryManager.java
===================================================================
--- trunk/apps/Thaw/src/thaw/fcp/FCPQueryManager.java   2006-07-08 00:44:01 UTC 
(rev 9498)
+++ trunk/apps/Thaw/src/thaw/fcp/FCPQueryManager.java   2006-07-08 01:05:24 UTC 
(rev 9499)
@@ -37,7 +37,7 @@
                return connection;
        }

-       public boolean writeMessage(FCPMessage message) {
+       public synchronized boolean writeMessage(FCPMessage message) {
                return connection.write(message.toString());
        }

@@ -63,7 +63,7 @@
                                break;
                        }

-                       whatsUp = whatsUp + "\n"+ read;
+                       whatsUp = whatsUp + read + "\n";
                }

                Logger.verbose(this, "Parsing message ...");

Modified: trunk/apps/Thaw/src/thaw/fcp/FCPQueueManager.java
===================================================================
--- trunk/apps/Thaw/src/thaw/fcp/FCPQueueManager.java   2006-07-08 00:44:01 UTC 
(rev 9498)
+++ trunk/apps/Thaw/src/thaw/fcp/FCPQueueManager.java   2006-07-08 01:05:24 UTC 
(rev 9499)
@@ -1,19 +1,36 @@
 package thaw.fcp;

+import java.util.Vector;
+import java.util.Iterator;
+
 import thaw.core.Logger;


-public class FCPQueueManager {
+public class FCPQueueManager extends java.util.Observable implements Runnable {

+       private final static int PRIORITY_MIN = 6; /* So 0 to 6 */
+
        private FCPQueryManager queryManager;
        private int maxDownloads, maxInsertions;

+       /* offset in the array == priority */
+       /* Vector contains FCPQuery */
+       private Vector[] pendingQueries = new Vector[PRIORITY_MIN+1];
+       private Vector runningQueries;

+       private Thread scheduler;
+
+       private int lastId;
+       private String thawId;
+
        /**
         * Calls setQueryManager() and then resetQueue().
         */
        public FCPQueueManager(FCPQueryManager queryManager,
+                              String thawId,
                               int maxDownloads, int maxInsertions) {
+               lastId = 0;
+               this.thawId = thawId;
                setMaxDownloads(maxDownloads);
                setMaxInsertions(maxInsertions);

@@ -21,6 +38,13 @@
                resetQueue();
        }

+       /**
+        * Use it if you want to bypass the queue.
+        */
+       public FCPQueryManager getQueryManager() {
+               return queryManager;
+       }
+
        public void setMaxDownloads(int maxDownloads) {
                this.maxDownloads = maxDownloads;
        }
@@ -42,9 +66,191 @@
         * Assume you have already called FCPConnection.connect().
         */
        public void resetQueue() {
+               runningQueries = new Vector();
+               for(int i = 0; i <= PRIORITY_MIN ; i++)
+                       pendingQueries[i] = new Vector();
+               
                /* TODO */
        }
+
+
+       public Vector[] getPendingQueues() {
+               return pendingQueries;
+       }
+
+       public Vector getRunningQueue() {
+               return runningQueries;
+       }
+
+       public void addQueryToThePendingQueue(FCPQuery query) {
+               if(query.getThawPriority() < 0) {
+                       addQueryToTheRunningQueue(query);
+                       return;
+               }
+
+               if(isAlreadyPresent(query)) {
+                       Logger.notice(this, "Key was already in one of the 
queues");
+                       return;
+               }
+
+               Logger.debug(this, "Adding query to the pending queue ...");
+               
+               pendingQueries[query.getThawPriority()].add(query);
+
+               setChanged();
+               notifyObservers(query);
+
+               Logger.debug(this, "Adding done");
+       }
+
+
+       public void addQueryToTheRunningQueue(FCPQuery query) {
+               Logger.debug(this, "Adding query to the running queue ...");
+
+               runningQueries.add(query);
+
+               setChanged();
+               notifyObservers(query);
+
+               query.start(this);
+               
+               Logger.debug(this, "Adding done");
+       }
+

+       public void remove(FCPQuery query) {
+               runningQueries.remove(query);

+               for(int i = 0 ; i <= PRIORITY_MIN ; i++)
+                       pendingQueries[i].remove(query);
+
+               setChanged();
+               notifyObservers(query);
+       }
+
+       /**
+        * Compare using the key.
+        */
+       public boolean isAlreadyPresent(FCPQuery query) {
+               Iterator it;
+
+               for(it = runningQueries.iterator();
+                   it.hasNext(); )
+                       {
+                               FCPQuery plop = (FCPQuery)it.next();
+                               if(plop.getFileKey().equals(query.getFileKey()))
+                                       return true;
+                       }
+
+               for(int i = 0 ; i <= PRIORITY_MIN ; i++) {
+                       for(it = pendingQueries[i].iterator();
+                           it.hasNext(); )
+                               {
+                                       FCPQuery plop = (FCPQuery)it.next();
+                                       
if(plop.getFileKey().equals(query.getFileKey()))
+                                               return true;
+                               }
+               }
+
+               return false;
+       }
+
+
+       public synchronized void ordonnance() {
+               
+                       /* We count the running query to see if there is an 
empty slot */
+
+                       int runningInsertions = 0;
+                       int runningDownloads = 0;
+
+                       for(Iterator it = runningQueries.iterator(); 
it.hasNext(); ) {
+                               FCPQuery query = (FCPQuery)it.next();
+
+                               if(query.getQueryType() == 1 /* Download */
+                                  && !query.isFinished())
+                                       runningDownloads++;
+
+                               if(query.getQueryType() == 2 /* Insertion */
+                                  && !query.isFinished())
+                                       runningInsertions++;
+                       }
+
+
+                       /* We move queries from the pendingQueue to the 
runningQueue until we got our quota */
+                       for(int priority = 0;
+                           priority <= PRIORITY_MIN
+                                   && (runningInsertions < maxInsertions
+                                       || runningDownloads < maxDownloads) ;
+                           priority++) {
+
+                               for(Iterator it = 
pendingQueries[priority].iterator();
+                                   it.hasNext()
+                                           && (runningInsertions < 
maxInsertions
+                                               || runningDownloads < 
maxDownloads); ) {
+                                       
+                                       FCPQuery query = (FCPQuery)it.next();
+                                       
+                                       if( (query.getQueryType() == 1
+                                            && runningDownloads < maxDownloads)
+                                           || (query.getQueryType() == 2
+                                               && runningInsertions < 
maxInsertions) ) {
+                                               
+                                               Logger.debug(this, "Scheduler : 
Moving a query from pendingQueue to the runningQueue");
+                                               
pendingQueries[priority].remove(query);
+                                               
+                                               it = 
pendingQueries[priority].iterator(); /* We reset iterator */
+
+                                               
addQueryToTheRunningQueue(query);
+
+                                               if(query.getQueryType() == 1)
+                                                       runningDownloads++;
+
+                                               if(query.getQueryType() == 2)
+                                                       runningInsertions++;
+                                       }
+
+                                       
+
+                               }
+
+                       }
+
+       }
+
+
+       public void run() {
+
+               while(true) {
+                       try {
+                               Thread.sleep(500);
+                       } catch(java.lang.InterruptedException e) {
+                               /* We don't care */
+                       }
+
+                       ordonnance();
+               }
+
+       }
+
+       public void startScheduler() {
+               scheduler = new Thread(this);
+               scheduler.start();
+       }
+
+       public void stopScheduler() {
+               scheduler.stop(); /* I should find a safer way */
+       }
+
+
+       public String getAnID() {
+               lastId++;
+
+               if(lastId >= 65535) {
+                       lastId = 0;
+               }
+
+               return (thawId+"-"+(new Integer(lastId)).toString());
+       }
+
 }


Added: trunk/apps/Thaw/src/thaw/fcp/FCPWatchGlobal.java
===================================================================
--- trunk/apps/Thaw/src/thaw/fcp/FCPWatchGlobal.java    2006-07-08 00:44:01 UTC 
(rev 9498)
+++ trunk/apps/Thaw/src/thaw/fcp/FCPWatchGlobal.java    2006-07-08 01:05:24 UTC 
(rev 9499)
@@ -0,0 +1,66 @@
+package thaw.fcp;
+
+public class FCPWatchGlobal implements FCPQuery {
+       private boolean watch;
+
+
+       public FCPWatchGlobal(boolean v) {
+               watch = v;
+       }
+
+       public boolean start(FCPQueueManager queueManager) {
+               FCPMessage message = new FCPMessage();
+
+               message.setMessageName("WatchGlobal");
+               if(watch)
+                       message.setValue("Enabled", "true");
+               else
+                       message.setValue("Enabled", "false");
+
+               message.setValue("VerbosityMask", "1");
+
+               queueManager.getQueryManager().writeMessage(message);
+
+               return true;
+       }
+
+       public boolean stop(FCPQueueManager queueManager) {
+               return true;
+       }
+
+       public int getThawPriority() {
+               return -1;
+       }
+
+       public int getQueryType() {
+               return 0;
+       }
+       
+       public String getStatus() {
+               return null;
+       }
+
+       public int getProgression() {
+               return 0;
+       }
+
+       public String getFileKey() {
+               return null;
+       }
+
+       public long getFileSize() {
+               return 0;
+       }
+
+       public String getPath() {
+               return null;
+       }
+
+       public int getAttempt() {
+               return 0;
+       }
+
+       public boolean isFinished() {
+               return true;
+       }
+}

Modified: trunk/apps/Thaw/src/thaw/i18n/thaw.properties
===================================================================
--- trunk/apps/Thaw/src/thaw/i18n/thaw.properties       2006-07-08 00:44:01 UTC 
(rev 9498)
+++ trunk/apps/Thaw/src/thaw/i18n/thaw.properties       2006-07-08 01:05:24 UTC 
(rev 9499)
@@ -27,9 +27,9 @@

 thaw.common.selectFiles=Select file(s)

-thaw.common.persistence=Keep inserting:
+thaw.common.persistence=Keep inserting
+thaw.common.persistenceForever=Until the transfer completes
 thaw.common.persistenceReboot=Until the freenode reboots
-thaw.common.persistenceForever=Until insertion completes
 thaw.common.persistenceConnection=Until Thaw is closed

 thaw.common.globalQueue=Global queue

Modified: trunk/apps/Thaw/src/thaw/plugins/FetchPlugin.java
===================================================================
--- trunk/apps/Thaw/src/thaw/plugins/FetchPlugin.java   2006-07-08 00:44:01 UTC 
(rev 9498)
+++ trunk/apps/Thaw/src/thaw/plugins/FetchPlugin.java   2006-07-08 01:05:24 UTC 
(rev 9499)
@@ -6,6 +6,7 @@
 import thaw.i18n.I18n;
 import thaw.plugins.fetchPlugin.*;

+import thaw.fcp.*;

 public class FetchPlugin implements thaw.core.Plugin {
        private Core core;
@@ -23,7 +24,7 @@

                Logger.info(this, "Starting plugin \"FetchPlugin\" ...");

-               fetchPanel = new FetchPanel();
+               fetchPanel = new FetchPanel(core, this);

                
core.getMainWindow().addTab(I18n.getMessage("thaw.common.download"), 
fetchPanel.getPanel());

@@ -43,4 +44,19 @@
                return I18n.getMessage("thaw.common.download");
        }

+
+       public void fetchFiles(String[] keys, int priority,
+                              int persistence, boolean globalQueue,
+                              String destination) {
+
+               for(int i = 0 ; i < keys.length ; i++) {
+                       core.getQueueManager().addQueryToThePendingQueue(new 
FCPClientGet(keys[i],
+                                                                               
          priority,
+                                                                               
          persistence,
+                                                                               
          globalQueue,
+                                                                               
          destination));
+               }
+
+       }
+
 }

Modified: trunk/apps/Thaw/src/thaw/plugins/QueueWatcher.java
===================================================================
--- trunk/apps/Thaw/src/thaw/plugins/QueueWatcher.java  2006-07-08 00:44:01 UTC 
(rev 9498)
+++ trunk/apps/Thaw/src/thaw/plugins/QueueWatcher.java  2006-07-08 01:05:24 UTC 
(rev 9499)
@@ -6,13 +6,18 @@
 import java.awt.BorderLayout;
 import javax.swing.JPanel;
 import javax.swing.JButton;
+import java.util.Observer;
+import java.util.Observable;
+import java.util.Vector;
+import java.util.Iterator;

 import thaw.core.*;
 import thaw.i18n.I18n;
 import thaw.plugins.queueWatcher.*;

+import thaw.fcp.*;

-public class QueueWatcher implements thaw.core.Plugin {
+public class QueueWatcher implements thaw.core.Plugin, Observer {
        private Core core;

        private JPanel mainPanel;
@@ -35,10 +40,11 @@

                mainPanel.setLayout(new BorderLayout());

-               queuePanels[0] = new QueuePanel(core, false); /* download */
-               queuePanels[1] = new QueuePanel(core, true); /* upload */
                detailPanel = new DetailPanel(core);

+               queuePanels[0] = new QueuePanel(core, detailPanel, false); /* 
download */
+               queuePanels[1] = new QueuePanel(core, detailPanel, true); /* 
upload */
+
                panel = new JPanel();

                GridLayout layout = new GridLayout(2, 1);
@@ -60,6 +66,8 @@

                
core.getMainWindow().addTab(I18n.getMessage("thaw.common.status"), mainPanel);

+               core.getQueueManager().addObserver(this);
+
                return true;
        }

@@ -67,8 +75,8 @@
        public boolean stop() {
                Logger.info(this, "Stopping plugin \"QueueWatcher\" ...");

-               core.getMainWindow().removeTab(panel);
-
+               core.getMainWindow().removeTab(mainPanel);
+               
                return true;
        }

@@ -76,4 +84,37 @@
                return I18n.getMessage("thaw.common.status");
        }

+       protected void addToPanels(Vector queries) {
+
+               for(Iterator it = queries.iterator();
+                   it.hasNext();) {
+
+                       FCPQuery query = (FCPQuery)it.next();
+
+                       if(query.getQueryType() == 1)
+                               queuePanels[0].addToTable(query);
+
+                       if(query.getQueryType() == 2)
+                               queuePanels[1].addToTable(query);
+
+               }
+
+       }
+
+       public void update(Observable o, Object arg) {
+
+               FCPQueueManager manager = (FCPQueueManager)o;
+
+               queuePanels[0].resetTable();
+               queuePanels[1].resetTable();
+
+               addToPanels(manager.getRunningQueue());
+
+               Vector[] pendings = manager.getPendingQueues();
+
+               for(int i = 0;i < pendings.length ; i++)
+                       addToPanels(pendings[i]);
+               
+       }
+
 }

Modified: trunk/apps/Thaw/src/thaw/plugins/fetchPlugin/FetchPanel.java
===================================================================
--- trunk/apps/Thaw/src/thaw/plugins/fetchPlugin/FetchPanel.java        
2006-07-08 00:44:01 UTC (rev 9498)
+++ trunk/apps/Thaw/src/thaw/plugins/fetchPlugin/FetchPanel.java        
2006-07-08 01:05:24 UTC (rev 9499)
@@ -13,14 +13,20 @@
 import javax.swing.JTextArea;
 import javax.swing.JScrollPane;
 import java.awt.Dimension;
+import javax.swing.JFileChooser;

+import java.io.File;
+import java.util.Vector;
+import java.util.Iterator;
+
 import thaw.core.*;
+import thaw.plugins.FetchPlugin;
 import thaw.i18n.I18n;

-public class FetchPanel {
+public class FetchPanel implements java.awt.event.ActionListener {

        private JPanel mainPanel = null;
-       private JPanel leftPart = null; /* (right part = validation button) */
+       private JPanel centeredPart = null; /* (below is the validation button) 
*/
        private JButton validationButton = null;

        private JPanel filePanel = null;
@@ -36,28 +42,50 @@
        private String[] priorities = null;
        private JComboBox prioritySelecter = null;

+       private JPanel persistencePanel = null;
+       private JLabel persistenceLabel = null;
+       private String[] persistences = null;
+       private JComboBox persistenceSelecter = null;
+
        private JLabel destinationLabel = null;
        private JPanel dstChoosePanel = null; /* 3 x 1 */
        private JTextField destinationField = null;
        private JButton destinationButton = null;

+       private JPanel queuePanel = null;
+       private JLabel queueLabel = null;
+       private String[] queues = null;
+       private JComboBox queueSelecter = null;

-       public FetchPanel() {
+       private Core core;
+       private FetchPlugin fetchPlugin;
+
+       public FetchPanel(Core core, FetchPlugin fetchPlugin) {
+               this.core = core;
+               this.fetchPlugin = fetchPlugin;
+
                mainPanel = new JPanel();
                mainPanel.setLayout(new BorderLayout(20, 20));

-               leftPart = new JPanel();
-               leftPart.setLayout(new BorderLayout(10, 10));
+               centeredPart = new JPanel();
+               centeredPart.setLayout(new BorderLayout(10, 10));

                validationButton = new 
JButton(I18n.getMessage("thaw.common.fetch"));
                validationButton.setPreferredSize(new Dimension(300, 40));

+               validationButton.addActionListener(this);
+
                filePanel = new JPanel();
                filePanel.setLayout(new BorderLayout());

+
+               /* FILE LIST */
+
                fileList = new JTextArea();
                fileLabel = new 
JLabel(I18n.getMessage("thaw.plugin.fetch.keyList"));
+
                loadListButton = new 
JButton(I18n.getMessage("thaw.plugin.fetch.loadKeyListFromFile"));
+               loadListButton.addActionListener(this);

                filePanel.add(fileLabel, BorderLayout.NORTH);
                filePanel.add(new JScrollPane(fileList), BorderLayout.CENTER);
@@ -65,8 +93,10 @@


                belowPanel = new JPanel();
-               belowPanel.setLayout(new GridLayout(1, 2, 10, 10));
+               belowPanel.setLayout(new GridLayout(2, 2, 10, 10));

+
+               /* PRIORITY */
                priorityPanel = new JPanel();
                priorityPanel.setLayout(new GridLayout(2, 1, 5, 5));

@@ -87,6 +117,36 @@
                priorityPanel.add(priorityLabel);
                priorityPanel.add(prioritySelecter);

+               /* PERSISTENCE */
+               persistencePanel = new JPanel();
+               persistencePanel.setLayout(new GridLayout(2, 1, 5, 5));
+
+               persistenceLabel = new 
JLabel(I18n.getMessage("thaw.common.persistence"));
+               persistences = new String[] {
+                       I18n.getMessage("thaw.common.persistenceReboot"),
+                       I18n.getMessage("thaw.common.persistenceForever"),
+                       I18n.getMessage("thaw.common.persistenceConnection")
+               };
+               persistenceSelecter = new JComboBox(persistences);
+
+               persistencePanel.add(persistenceLabel);
+               persistencePanel.add(persistenceSelecter);
+
+               /* QUEUE */
+               queuePanel = new JPanel();
+               queuePanel.setLayout(new GridLayout(2, 1, 5, 5));
+               
+               queueLabel = new 
JLabel(I18n.getMessage("thaw.common.globalQueue"));
+               queues = new String [] {
+                       I18n.getMessage("thaw.common.true"),
+                       I18n.getMessage("thaw.common.false"),
+               };
+               queueSelecter = new JComboBox(queues);
+
+               queuePanel.add(queueLabel);
+               queuePanel.add(queueSelecter);
+
+               /* DESTINATION */
                destinationLabel = new 
JLabel(I18n.getMessage("thaw.plugin.fetch.destinationDirectory"));

                dstChoosePanel = new JPanel();
@@ -96,19 +156,22 @@
                destinationField.setEditable(false);

                destinationButton = new 
JButton(I18n.getMessage("thaw.plugin.fetch.chooseDestination"));
+               destinationButton.addActionListener(this);

                dstChoosePanel.add(destinationLabel);
                dstChoosePanel.add(destinationField);
                dstChoosePanel.add(destinationButton);

                belowPanel.add(priorityPanel);
+               belowPanel.add(persistencePanel);
+               belowPanel.add(queuePanel);
                belowPanel.add(dstChoosePanel);


-               leftPart.add(filePanel, BorderLayout.CENTER);
-               leftPart.add(belowPanel, BorderLayout.SOUTH);
+               centeredPart.add(filePanel, BorderLayout.CENTER);
+               centeredPart.add(belowPanel, BorderLayout.SOUTH);

-               mainPanel.add(leftPart, BorderLayout.CENTER);
+               mainPanel.add(centeredPart, BorderLayout.CENTER);
                mainPanel.add(validationButton, BorderLayout.SOUTH);
        }

@@ -117,5 +180,94 @@
                return mainPanel;
        }

+       
+       public void actionPerformed(java.awt.event.ActionEvent e) {
+               if(e.getSource() == validationButton) {
+                       int priority = 6;
+                       int persistence = 0;
+                       boolean globalQueue = true;
+
+                       
if(((String)persistenceSelecter.getSelectedItem()).equals(I18n.getMessage("thaw.common.persistenceForever")))
+                               persistence = 0;
+                       
if(((String)persistenceSelecter.getSelectedItem()).equals(I18n.getMessage("thaw.common.persistenceReboot")))
+                               persistence = 1;
+                       
if(((String)persistenceSelecter.getSelectedItem()).equals(I18n.getMessage("thaw.common.persistenceConnection")))
+                               persistence = 2;
+
+                       
if(((String)queueSelecter.getSelectedItem()).equals(I18n.getMessage("thaw.common.false")))
+                               globalQueue = false;
+
+
+                       for(int i = 0; i < priorities.length ; i++) {
+                               
if(((String)prioritySelecter.getSelectedItem()).equals(I18n.getMessage("thaw.plugin.priority.p"+i)))
+                                       priority = i;
+                       }
+
+                       if(destinationField.getText() == null || 
destinationField.getText().equals("")) {
+                               new thaw.core.WarningWindow(core, "You must 
choose a destination");
+                               return;
+                       }
+
+                       fetchPlugin.fetchFiles(fileList.getText().split("\n"),
+                                              priority, persistence, 
globalQueue,
+                                              destinationField.getText());
+
+                       fileList.setText("");
+               }
+
+
+               if(e.getSource() == destinationButton) {
+                       FileChooser fileChooser = new FileChooser();
+                       File dir = null;
+
+                       
fileChooser.setTitle(I18n.getMessage("thaw.plugin.fetch.destinationDirectory"));
+                       fileChooser.setDirectoryOnly(true);
+                       fileChooser.setDialogType(JFileChooser.SAVE_DIALOG);
+
+                       dir = fileChooser.askOneFile();
+
+                       if(dir == null) {
+                               Logger.info(this, "Selection canceled");
+                               return;
+                       }
+
+                       destinationField.setText(dir.getPath());
+               }
+
+               if(e.getSource() == loadListButton) {
+                       FileChooser fileChooser = new FileChooser();
+                       File toParse = null;
+
+                       
fileChooser.setTitle(I18n.getMessage("thaw.plugin.fetch.loadKeyListFromFile"));
+                       fileChooser.setDirectoryOnly(false);
+                       fileChooser.setDialogType(JFileChooser.OPEN_DIALOG);
+                       
+                       toParse = fileChooser.askOneFile();
+
+                       if(toParse == null) {
+                               Logger.info(this, "Nothing to parse");
+                               return;
+                       }
+                       
+                       Vector keys = KeyFileFilter.extractKeys(toParse);
+
+                       if(keys == null || keys.size() <= 0) {
+                               new WarningWindow(core, "No key found !");
+                               return;
+                       }
+
+
+                       String result = fileList.getText();
+
+                       for(Iterator i = keys.iterator(); i.hasNext() ;) {
+                               String key = (String)i.next();
+
+                               result = result + key + "\n";
+                       }
+                       
+                       fileList.setText(result);
+
+               }
+       }
 }


Added: trunk/apps/Thaw/src/thaw/plugins/fetchPlugin/KeyFileFilter.java
===================================================================
--- trunk/apps/Thaw/src/thaw/plugins/fetchPlugin/KeyFileFilter.java     
2006-07-08 00:44:01 UTC (rev 9498)
+++ trunk/apps/Thaw/src/thaw/plugins/fetchPlugin/KeyFileFilter.java     
2006-07-08 01:05:24 UTC (rev 9499)
@@ -0,0 +1,64 @@
+package thaw.plugins.fetchPlugin;
+
+import java.awt.event.ActionListener;
+import java.awt.event.ActionEvent;
+
+import java.util.Vector;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.BufferedReader;
+import java.io.InputStreamReader;
+
+import thaw.core.*;
+
+public class KeyFileFilter {
+
+       /**
+        * Only used to be able to call correctly functions of thaw.core.Logger
+        */
+       public KeyFileFilter() {
+
+       }
+
+
+       /**
+        * @return Vector of Strings
+        */
+       public static Vector extractKeys(File file) {
+               Vector result = new Vector();
+
+               FileInputStream fstream = null;
+
+               try {
+                       fstream = new FileInputStream(file);
+               } catch(java.io.FileNotFoundException e) {
+                       Logger.warning(new KeyFileFilter(), "File not found 
exception for "+file.getPath());
+                       return null;
+               }
+
+
+
+               BufferedReader in = new BufferedReader(new 
InputStreamReader(fstream));
+
+               try {
+                       String line = null;
+
+                       while((line = in.readLine()) != null) {
+                               String[] pieces = 
line.split("[^-.a-zA-Z0-9,~%@/_]");
+                               
+                               for(int i = 0 ; i < pieces.length ; i++) {
+                                       if(pieces[i].matches(".{3}@.*,.*"))
+                                               result.add(pieces[i]);
+                               }
+
+                       }
+
+               } catch(java.io.IOException e) {
+                       Logger.warning(new KeyFileFilter(), "IOException while 
reading '"+file.getPath()+"' !");
+                       return result;
+               }
+
+               return result;
+       }
+
+}

Modified: trunk/apps/Thaw/src/thaw/plugins/queueWatcher/DetailPanel.java
===================================================================
--- trunk/apps/Thaw/src/thaw/plugins/queueWatcher/DetailPanel.java      
2006-07-08 00:44:01 UTC (rev 9498)
+++ trunk/apps/Thaw/src/thaw/plugins/queueWatcher/DetailPanel.java      
2006-07-08 01:05:24 UTC (rev 9499)
@@ -8,12 +8,15 @@
 import javax.swing.JProgressBar;
 import javax.swing.JComponent;

+import java.util.Observer;
+import java.util.Observable;
+
 import thaw.core.*;
 import thaw.i18n.I18n;
+import thaw.fcp.*;

+public class DetailPanel implements Observer {

-public class DetailPanel {
-
        private Core core;

        private JPanel subPanel;
@@ -27,8 +30,12 @@
        private JTextField priority = new JTextField();
        private JTextField attempt  = new JTextField();

+       private FCPQuery query = null;
+
+
        private final static Dimension dim = new Dimension(300, 275);

+
        public DetailPanel(Core core) {
                this.core = core;

@@ -65,7 +72,7 @@
                                case(4): field = path; path.setEditable(false); 
break;
                                case(5): field = priority; 
priority.setEditable(false); break;
                                case(6): field = attempt; 
attempt.setEditable(false); break;
-                               default: Logger.warning(this, "Gouli goula ? 
... is going to crash :p"); break;
+                               default: Logger.error(this, "Gouli goula ? ... 
is going to crash :p"); break;
                                }

                                subPanel.add(field);
@@ -83,4 +90,58 @@
        public JPanel getPanel() {
                return panel;
        }
+
+       
+       public void setQuery(FCPQuery query) {
+               if(this.query != null)
+                       ((Observable)this.query).deleteObserver(this);
+
+               this.query = query;
+               
+               if(this.query != null)
+                       ((Observable)this.query).addObserver(this);
+
+               refreshAll();
+       }
+
+       public void update(Observable o, Object arg) {
+               refresh();
+       }
+
+
+       public void refresh() {
+               if(query != null) {
+                       progress.setValue(query.getProgression());
+                       progress.setString((new 
Integer(query.getProgression())).toString() + "%");
+               } else {
+                       progress.setValue(0);
+                       progress.setString("");
+               }
+       }
+
+       public void refreshAll() {
+               refresh();
+
+               if(query != null) {
+
+                       String[] plop = query.getFileKey().split("/");
+                       
+                       file.setText(plop[plop.length-1]);
+                       size.setText((new 
Long(query.getFileSize())).toString()+" B");
+                       
+                       key.setText(query.getFileKey());
+                       path.setText(query.getPath());
+                       priority.setText((new 
Integer(query.getThawPriority())).toString());
+                       attempt.setText((new 
Integer(query.getAttempt())).toString());
+               } else {
+                       file.setText("");
+                       size.setText("");
+                       key.setText("");
+                       path.setText("");
+                       priority.setText("");
+                       attempt.setText("");
+               }
+
+       }
+
 }

Modified: trunk/apps/Thaw/src/thaw/plugins/queueWatcher/QueuePanel.java
===================================================================
--- trunk/apps/Thaw/src/thaw/plugins/queueWatcher/QueuePanel.java       
2006-07-08 00:44:01 UTC (rev 9498)
+++ trunk/apps/Thaw/src/thaw/plugins/queueWatcher/QueuePanel.java       
2006-07-08 01:05:24 UTC (rev 9499)
@@ -4,26 +4,40 @@
 import javax.swing.JTable;
 import javax.swing.JLabel;
 import javax.swing.JScrollPane;
+import javax.swing.event.TableModelEvent;
 import java.awt.BorderLayout;
 import java.util.Vector;

+import java.awt.event.MouseListener;
+import java.awt.event.MouseEvent;
+
 import thaw.core.*;
 import thaw.i18n.I18n;

+import thaw.fcp.*;

-public class QueuePanel {
+public class QueuePanel implements MouseListener {
        private Core core;

        private JLabel label;
+
        private JTable table = null;
+
        private JPanel panel;

+       private QueueTableModel tableModel;
+       private DetailPanel detailPanel;

-       public QueuePanel(Core core, boolean isForInsertionQueue) {
+       private int lastRowSelected = -1;
+
+       public QueuePanel(Core core, DetailPanel detailPanel, boolean 
isForInsertionQueue) {
                this.core = core;
+               this.detailPanel = detailPanel;

-               table = new JTable(new QueueTableModel(isForInsertionQueue));
+               tableModel = new QueueTableModel(isForInsertionQueue);

+               table = new JTable(tableModel);
+
                table.setShowGrid(true);

                if(isForInsertionQueue) {
@@ -37,10 +51,55 @@

                panel.add(label, BorderLayout.NORTH);
                panel.add(new JScrollPane(table), BorderLayout.CENTER);
+
+               tableModel.addTableModelListener(table);
+               table.addMouseListener(this);
        }

+       public void resetTable() {
+               tableModel.resetTable();
+       }
+
+       public void addToTable(FCPQuery query) {
+               tableModel.addQuery(query);
+       }
+
+       public void refresh() {
+               int selected = table.getSelectedRow();
+
+               if(lastRowSelected != selected) {
+                       lastRowSelected = selected;
+                       
+                       if(selected != -1)
+                               
detailPanel.setQuery(tableModel.getQuery(selected));
+               }
+               
+       }
+
        public JPanel getPanel() {
                return panel;
        }
+
+
+       public void mouseClicked(MouseEvent e) {
+               refresh();
+       }
+
+       public void mouseEntered(MouseEvent e) {
+
+       }
+
+       public void mouseExited(MouseEvent e) {
+
+       }
+
+       public void mousePressed(MouseEvent e) {
+
+       }
+
+       public void mouseReleased(MouseEvent e) {
+
+       }
+
 }


Modified: trunk/apps/Thaw/src/thaw/plugins/queueWatcher/QueueTableModel.java
===================================================================
--- trunk/apps/Thaw/src/thaw/plugins/queueWatcher/QueueTableModel.java  
2006-07-08 00:44:01 UTC (rev 9498)
+++ trunk/apps/Thaw/src/thaw/plugins/queueWatcher/QueueTableModel.java  
2006-07-08 01:05:24 UTC (rev 9499)
@@ -1,15 +1,24 @@
 package thaw.plugins.queueWatcher;

-
 import java.util.Vector;
+import java.util.Iterator;
+import java.util.Observable;
+import java.util.Observer;

+import javax.swing.event.TableModelListener;
+import javax.swing.event.TableModelEvent;
+
 import thaw.core.*;
 import thaw.i18n.I18n;
+import thaw.fcp.*;

+public class QueueTableModel extends javax.swing.table.AbstractTableModel 
implements Observer {
+       private static final long serialVersionUID = 20060707;

-public class QueueTableModel extends javax.swing.table.AbstractTableModel {
-       Vector columnNames = new Vector();
+       private Vector columnNames = new Vector();

+       private Vector queries = null;
+
        public QueueTableModel(boolean isForInsertions) {
                super();

@@ -17,11 +26,16 @@
                columnNames.add(I18n.getMessage("thaw.common.size"));
                columnNames.add(I18n.getMessage("thaw.common.status"));
                columnNames.add(I18n.getMessage("thaw.common.progress"));
+
+               resetTable();
        }


        public int getRowCount() {
-               return 0;
+               if(queries != null)
+                       return queries.size();
+               else
+                       return 0;
        }

        public int getColumnCount() {
@@ -33,12 +47,72 @@
        }

        public Object getValueAt(int row, int column) {
+               if(row >= queries.size())
+                       return null;
+
+               FCPQuery query = (FCPQuery)queries.get(row);
+               
+               if(column == 0) {
+                       String[] plop = query.getFileKey().split("/");
+                       return plop[plop.length-1];
+               }
+
+               if(column == 1) {
+                       return ((new Long(query.getFileSize())).toString() + " 
B");
+               }
+
+               if(column == 2) {
+                       return query.getStatus();
+               }
+
+               if(column == 3) {
+                       return (new Integer(query.getProgression())).toString() 
+ "%";
+               }
+
                return null;
        }

        public boolean isCellEditable(int row, int column) {
-                       return false;
+               return false;
        }

+       public void resetTable() {
+               if(queries != null) {
+                       for(Iterator it = queries.iterator();
+                           it.hasNext();) {
+                               Observable query = (Observable)it.next();
+                               query.deleteObserver(this);
+                       }
+               }
+
+               queries = new Vector();
+
+               notifyObservers();
+       }
+
+       public void addQuery(FCPQuery query) {
+               ((Observable)query).addObserver(this);
+
+               queries.add(query);
+
+               notifyObservers();
+       }
+
+       public FCPQuery getQuery(int row) {
+               return (FCPQuery)queries.get(row);
+       }
+
+       public void notifyObservers() {
+               TableModelListener[] listeners = getTableModelListeners();
+
+               for(int i = 0 ; i < listeners.length ; i++) {
+                       listeners[i].tableChanged(new TableModelEvent(this));
+               }
+       }
+
+       public void update(Observable o, Object arg) {
+               notifyObservers();
+       }
+
 }



Reply via email to