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();
+ }
+
}