Author: jflesch
Date: 2007-07-29 00:34:10 +0000 (Sun, 29 Jul 2007)
New Revision: 14416
Added:
trunk/apps/Thaw/src/thaw/plugins/miniFrost/DraftPanel.java
Modified:
trunk/apps/Thaw/src/frost/util/XMLTools.java
trunk/apps/Thaw/src/thaw/gui/IconBox.java
trunk/apps/Thaw/src/thaw/i18n/source.thaw_fr.properties
trunk/apps/Thaw/src/thaw/i18n/thaw.properties
trunk/apps/Thaw/src/thaw/i18n/thaw_fr.properties
trunk/apps/Thaw/src/thaw/plugins/miniFrost/MessagePanel.java
trunk/apps/Thaw/src/thaw/plugins/miniFrost/MessageTreeTable.java
trunk/apps/Thaw/src/thaw/plugins/miniFrost/MiniFrostPanel.java
trunk/apps/Thaw/src/thaw/plugins/miniFrost/frostKSK/KSKAttachment.java
trunk/apps/Thaw/src/thaw/plugins/miniFrost/frostKSK/KSKBoard.java
trunk/apps/Thaw/src/thaw/plugins/miniFrost/frostKSK/KSKBoardAttachment.java
trunk/apps/Thaw/src/thaw/plugins/miniFrost/frostKSK/KSKDraft.java
trunk/apps/Thaw/src/thaw/plugins/miniFrost/frostKSK/KSKFileAttachment.java
trunk/apps/Thaw/src/thaw/plugins/miniFrost/frostKSK/KSKMessage.java
trunk/apps/Thaw/src/thaw/plugins/miniFrost/frostKSK/KSKMessageParser.java
trunk/apps/Thaw/src/thaw/plugins/miniFrost/interfaces/Draft.java
trunk/apps/Thaw/src/thaw/plugins/signatures/SigConfigTab.java
Log:
miniFrost can now post signed and unsigned messages
Modified: trunk/apps/Thaw/src/frost/util/XMLTools.java
===================================================================
--- trunk/apps/Thaw/src/frost/util/XMLTools.java 2007-07-28 21:10:18 UTC
(rev 14415)
+++ trunk/apps/Thaw/src/frost/util/XMLTools.java 2007-07-29 00:34:10 UTC
(rev 14416)
@@ -20,10 +20,18 @@
import java.io.*;
import java.util.*;
+import thaw.core.Logger;
import java.util.logging.*;
import javax.xml.parsers.*;
+import javax.xml.transform.stream.StreamResult;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.OutputKeys;
+
+
import org.apache.xml.serialize.*;
import org.w3c.dom.*;
import org.xml.sax.*;
@@ -33,8 +41,6 @@
*/
public class XMLTools {
- private static final Logger logger =
Logger.getLogger(XMLTools.class.getName());
-
private static DocumentBuilderFactory validatingFactory =
DocumentBuilderFactory.newInstance();
private static DocumentBuilderFactory nonValidatingFactory =
DocumentBuilderFactory.newInstance();
@@ -77,7 +83,7 @@
writeXmlFile(doc, tmp.getPath());
result = FileAccess.readByteArray(tmp);
} catch (Throwable t) {
- logger.log(Level.SEVERE, "Exception thrown in
getRawXMLDocument(XMLizable element)", t);
+ Logger.error(t, "Exception thrown in getRawXMLDocument(XMLizable
element): "+ t.toString());
}
tmp.delete();
return result;
@@ -95,7 +101,7 @@
FileAccess.writeFile(content, tmp);
result = XMLTools.parseXmlFile(tmp, validating);
} catch(Throwable t) {
- logger.log(Level.SEVERE, "Exception thrown in parseXmlContent", t);
+ Logger.error(t, "Exception thrown in parseXmlContent: "+
t.toString());
}
tmp.delete();
return result;
@@ -133,25 +139,19 @@
return builder.parse(file);
} catch (SAXException e) {
// A parsing error occurred; the xml input is not valid
- logger.log(
- Level.SEVERE,
- "Parsing of xml file failed (send badfile.xml to a dev for
analysis) - " +
- "File name: '" + file.getName() + "'",
- e);
+ Logger.error(e,
+ "Parsing of xml file failed (send badfile.xml to a
dev for analysis) - " +
+ "File name: '" + file.getName() + "':
"+e.toString());
file.renameTo(new File("badfile.xml"));
throw new IllegalArgumentException();
} catch (ParserConfigurationException e) {
- logger.log(
- Level.SEVERE,
- "Exception thrown in parseXmlFile(File file, boolean
validating) - " +
- "File name: '" + file.getName() + "'",
- e);
+ Logger.error(e, "Exception thrown in parseXmlFile(File file,
boolean validating) - " +
+ "File name: '" + file.getName() + "': "+
+ e.toString());
} catch (IOException e) {
- logger.log(
- Level.SEVERE,
- "Exception thrown in parseXmlFile(File file, boolean
validating) - " +
- "File name: '" + file.getName() + "'",
- e);
+ Logger.error(e,
+ "Exception thrown in parseXmlFile(File file, boolean
validating) - " +
+ "File name: '" + file.getName() + "': "+e);
}
return null;
}
@@ -167,22 +167,45 @@
* This method writes a DOM document to a file.
*/
public static boolean writeXmlFile(Document doc, File file) {
- try {
- OutputFormat format = new OutputFormat(doc, "UTF-8", false);
- format.setLineSeparator(LineSeparator.Windows);
- //format.setIndenting(true);
- format.setLineWidth(0);
- format.setPreserveSpace(true);
- OutputStreamWriter writer = new OutputStreamWriter(new
FileOutputStream(file), "UTF-8");
- XMLSerializer serializer = new XMLSerializer(writer, format);
- serializer.asDOMSerializer();
- serializer.serialize(doc);
- writer.close(); //this also flushes
- return true;
- } catch (Exception ex) {
- logger.log(Level.SEVERE, "Exception thrown in
writeXmlFile(Document doc, String filename)", ex);
- }
- return false;
+ /* This method didn't work for me, so I replaced it by mine */
+ try {
+ FileOutputStream out = new FileOutputStream(file);
+ StreamResult streamResult;
+
+ streamResult = new StreamResult(out);
+
+
+ final DocumentBuilderFactory xmlFactory =
DocumentBuilderFactory.newInstance();
+ DocumentBuilder xmlBuilder;
+
+ xmlBuilder = xmlFactory.newDocumentBuilder();
+
+ final DOMImplementation impl =
xmlBuilder.getDOMImplementation();
+
+ /* Serialization */
+ final DOMSource domSource = new DOMSource(doc);
+ final TransformerFactory transformFactory =
TransformerFactory.newInstance();
+
+ Transformer serializer;
+
+ serializer = transformFactory.newTransformer();
+
+ serializer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
+ serializer.setOutputProperty(OutputKeys.INDENT, "yes");
+
+
+ serializer.transform(domSource, streamResult);
+
+ return true;
+ } catch(final javax.xml.transform.TransformerException e) {
+ Logger.error(e, "Unable to generate XML because:
"+e.toString());
+ } catch(java.io.FileNotFoundException e) {
+ Logger.error(e, "File not found exception ?!");
+ } catch(final javax.xml.parsers.ParserConfigurationException e) {
+ Logger.error(e, "Unable to generate XML because :
"+e.toString());
+ }
+
+ return false;
}
/**
@@ -195,7 +218,7 @@
Document doc = builder.newDocument();
return doc;
} catch (ParserConfigurationException e) {
- logger.log(Level.SEVERE, "Exception thrown in
createDomDocument()", e);
+ Logger.error(e, "Exception thrown in createDomDocument():
"+e.toString());
}
return null;
}
Modified: trunk/apps/Thaw/src/thaw/gui/IconBox.java
===================================================================
--- trunk/apps/Thaw/src/thaw/gui/IconBox.java 2007-07-28 21:10:18 UTC (rev
14415)
+++ trunk/apps/Thaw/src/thaw/gui/IconBox.java 2007-07-29 00:34:10 UTC (rev
14416)
@@ -162,6 +162,10 @@
public static ImageIcon attachment;
public static ImageIcon minAttachment;
+ public static ImageIcon windowNew;
+ public static ImageIcon minWindowNew;
+
+
/**
* Not really used
*/
@@ -297,6 +301,8 @@
IconBox.minRight =
IconBox.loadIcon("min-go-next.png");
IconBox.attachment =
IconBox.loadIcon("mail-attachment.png");
IconBox.minAttachment =
IconBox.loadIcon("min-mail-attachment.png");
+ IconBox.windowNew =
IconBox.loadIcon("window-new.png");
+ IconBox.minWindowNew =
IconBox.loadIcon("min-window-new.png");
}
}
Modified: trunk/apps/Thaw/src/thaw/i18n/source.thaw_fr.properties
===================================================================
--- trunk/apps/Thaw/src/thaw/i18n/source.thaw_fr.properties 2007-07-28
21:10:18 UTC (rev 14415)
+++ trunk/apps/Thaw/src/thaw/i18n/source.thaw_fr.properties 2007-07-29
00:34:10 UTC (rev 14416)
@@ -536,6 +536,8 @@
thaw.plugin.miniFrost.rawMessage=MESSAGE BRUTE
+thaw.plugin.miniFrost.newMessage=Nouveau message
+
thaw.plugin.miniFrost.archivate=Archiver
thaw.plugin.miniFrost.unarchivate=D?archiver
Modified: trunk/apps/Thaw/src/thaw/i18n/thaw.properties
===================================================================
--- trunk/apps/Thaw/src/thaw/i18n/thaw.properties 2007-07-28 21:10:18 UTC
(rev 14415)
+++ trunk/apps/Thaw/src/thaw/i18n/thaw.properties 2007-07-29 00:34:10 UTC
(rev 14416)
@@ -562,6 +562,8 @@
thaw.plugin.miniFrost.goBack=Go back to the message list
thaw.plugin.miniFrost.nextUnread=Next unread message on this board
+thaw.plugin.miniFrost.newMessage=New Message
+
thaw.plugin.miniFrost.selectAll=Select all
thaw.plugin.miniFrost.selectNone=Select none
@@ -580,3 +582,5 @@
thaw.plugin.miniFrost.hideStatusBelow=Hide status lower than:
thaw.plugin.miniFrost.seeUnsigned=See unsigned messages
+
+thaw.plugin.miniFrost.anonymous=Anonymous
Modified: trunk/apps/Thaw/src/thaw/i18n/thaw_fr.properties
===================================================================
--- trunk/apps/Thaw/src/thaw/i18n/thaw_fr.properties 2007-07-28 21:10:18 UTC
(rev 14415)
+++ trunk/apps/Thaw/src/thaw/i18n/thaw_fr.properties 2007-07-29 00:34:10 UTC
(rev 14416)
@@ -536,6 +536,8 @@
thaw.plugin.miniFrost.rawMessage=MESSAGE BRUTE
+thaw.plugin.miniFrost.newMessage=Nouveau message
+
thaw.plugin.miniFrost.archivate=Archiver
thaw.plugin.miniFrost.unarchivate=D\u00e9archiver
Added: trunk/apps/Thaw/src/thaw/plugins/miniFrost/DraftPanel.java
===================================================================
--- trunk/apps/Thaw/src/thaw/plugins/miniFrost/DraftPanel.java
(rev 0)
+++ trunk/apps/Thaw/src/thaw/plugins/miniFrost/DraftPanel.java 2007-07-29
00:34:10 UTC (rev 14416)
@@ -0,0 +1,182 @@
+package thaw.plugins.miniFrost;
+
+import java.awt.GridLayout;
+import java.awt.BorderLayout;
+
+import javax.swing.JPanel;
+import javax.swing.JComboBox;
+import javax.swing.JTextField;
+import javax.swing.JTextArea;
+import javax.swing.JLabel;
+import javax.swing.JScrollPane;
+import javax.swing.JButton;
+
+import java.util.Iterator;
+import java.util.Vector;
+
+import java.awt.event.ActionListener;
+import java.awt.event.ActionEvent;
+
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+import thaw.core.I18n;
+
+import thaw.plugins.signatures.Identity;
+
+import thaw.plugins.miniFrost.interfaces.Draft;
+
+
+
+public class DraftPanel implements ActionListener {
+
+ private Draft draft;
+ private JPanel panel;
+
+ private MiniFrostPanel mainPanel;
+
+ private JComboBox authorBox;
+ private JTextField subjectField;
+ private JTextArea textArea;
+ private JButton cancelButton;
+ private JButton sendButton;
+
+
+ public DraftPanel(MiniFrostPanel mainPanel) {
+ this.mainPanel = mainPanel;
+
+ panel = new JPanel(new BorderLayout(5, 5));
+
+ Vector ids = new Vector();
+ ids.add(I18n.getMessage("thaw.plugin.miniFrost.anonymous"));
+ ids.addAll(Identity.getYourIdentities(mainPanel.getDb()));
+
+ authorBox = new JComboBox();
+ authorBox.setEditable(true);
+
+ subjectField = new JTextField("");
+ subjectField.setEditable(true);
+
+ textArea = new JTextArea("");
+ textArea.setEditable(true);
+ textArea.setLineWrap(true);
+ textArea.setWrapStyleWord(true);
+
+
+ JPanel northPanel = new JPanel(new BorderLayout(5, 5));
+
+ JPanel headersPanel = new JPanel(new GridLayout(2, 1));
+ headersPanel.add(new
JLabel(I18n.getMessage("thaw.plugin.miniFrost.author")+": "));
+ headersPanel.add(new
JLabel(I18n.getMessage("thaw.plugin.miniFrost.subject")+": "));
+
+ JPanel valuesPanel = new JPanel(new GridLayout(2, 1));
+ valuesPanel.add(authorBox);
+ valuesPanel.add(subjectField);
+
+ northPanel.add(headersPanel, BorderLayout.WEST);
+ northPanel.add(valuesPanel, BorderLayout.CENTER);
+
+
+ JPanel southPanel = new JPanel(new GridLayout(1, 2));
+
+ cancelButton = new
JButton(I18n.getMessage("thaw.common.cancel"));
+ sendButton = new JButton(I18n.getMessage("thaw.common.ok"));
+ cancelButton.addActionListener(this);
+ sendButton.addActionListener(this);
+
+ southPanel.add(cancelButton);
+ southPanel.add(sendButton);
+
+ panel.add(northPanel, BorderLayout.NORTH );
+ panel.add(new JScrollPane(textArea), BorderLayout.CENTER);
+ panel.add(southPanel, BorderLayout.SOUTH );
+ }
+
+
+ public void setDraft(Draft draft) {
+ this.draft = draft;
+ refresh();
+
+ Vector ids = new Vector();
+ ids.add(I18n.getMessage("thaw.plugin.miniFrost.anonymous"));
+ ids.addAll(Identity.getYourIdentities(mainPanel.getDb()));
+
+ authorBox.removeAllItems();
+
+ for (Iterator it = ids.iterator(); it.hasNext();)
+ authorBox.addItem(it.next());
+
+ subjectField.setText(draft.getInitialSubject());
+
+ String txt = draft.getInitialText();
+
+ textArea.setText(draft.getInitialText());
+ }
+
+
+ public void refresh() {
+ /* we don't want to erase by accident the current draft
+ * => we do nothing
+ */
+ }
+
+ public void hided() {
+
+ }
+
+ public void redisplayed() {
+ textArea.requestFocus();
+ }
+
+ public JPanel getPanel() {
+ return panel;
+ }
+
+
+ public void actionPerformed(ActionEvent e) {
+ if (e.getSource() == sendButton) {
+ Date date = new Date();
+ SimpleDateFormat dateFormat = new
SimpleDateFormat("yyyy.MM.dd - HH:mm:ss");
+
+ /* author */
+
+ if (authorBox.getSelectedItem() instanceof Identity) {
+
draft.setAuthor(authorBox.getSelectedItem().toString(),
+
(Identity)authorBox.getSelectedItem());
+ } else {
+ String nick =
authorBox.getSelectedItem().toString();
+ nick = nick.replaceAll("@", "_");
+
+ draft.setAuthor(nick, null);
+ }
+
+ /* subject */
+
+ draft.setSubject(subjectField.getText());
+
+ /* text */
+
+ String txt = textArea.getText();
+
+ txt = txt.replaceAll("\\$sender\\$",
authorBox.getSelectedItem().toString());
+
+ String dateStr = dateFormat.format(date).toString();
+ txt = txt.replaceAll("\\$dateAndTime\\$", dateStr);
+
+ draft.setText(txt);
+
+
+ /* date */
+ draft.setDate(date);
+
+
+ /* POST */
+
draft.post(mainPanel.getPluginCore().getCore().getQueueManager());
+
+ } if (e.getSource() == cancelButton) {
+
+ }
+
+ mainPanel.displayMessageTable();
+ }
+}
Modified: trunk/apps/Thaw/src/thaw/plugins/miniFrost/MessagePanel.java
===================================================================
--- trunk/apps/Thaw/src/thaw/plugins/miniFrost/MessagePanel.java
2007-07-28 21:10:18 UTC (rev 14415)
+++ trunk/apps/Thaw/src/thaw/plugins/miniFrost/MessagePanel.java
2007-07-29 00:34:10 UTC (rev 14416)
@@ -32,6 +32,7 @@
import thaw.plugins.miniFrost.interfaces.Message;
import thaw.plugins.miniFrost.interfaces.SubMessage;
import thaw.plugins.miniFrost.interfaces.Attachment;
+import thaw.plugins.miniFrost.interfaces.Draft;
public class MessagePanel
@@ -481,7 +482,9 @@
} else if (sel == 3) { /* reply */
- /* TODO */
+ Draft draft = msg.getBoard().getDraft(msg);
+ mainPanel.getDraftPanel().setDraft(draft);
+ mainPanel.displayDraftPanel();
} else if (sel == 4 || sel == 5) { /* (un)fold */
boolean retracted = (sel == 5);
Modified: trunk/apps/Thaw/src/thaw/plugins/miniFrost/MessageTreeTable.java
===================================================================
--- trunk/apps/Thaw/src/thaw/plugins/miniFrost/MessageTreeTable.java
2007-07-28 21:10:18 UTC (rev 14415)
+++ trunk/apps/Thaw/src/thaw/plugins/miniFrost/MessageTreeTable.java
2007-07-29 00:34:10 UTC (rev 14416)
@@ -57,6 +57,7 @@
import thaw.plugins.miniFrost.interfaces.Board;
import thaw.plugins.miniFrost.interfaces.BoardFactory;
import thaw.plugins.miniFrost.interfaces.Message;
+import thaw.plugins.miniFrost.interfaces.Draft;
public class MessageTreeTable implements Observer,
@@ -80,7 +81,8 @@
I18n.getMessage("thaw.plugin.miniFrost.markAsRead"),
I18n.getMessage("thaw.plugin.miniFrost.markAsNonRead"),
I18n.getMessage("thaw.plugin.miniFrost.archivate"),
- I18n.getMessage("thaw.plugin.miniFrost.unarchivate")
+ I18n.getMessage("thaw.plugin.miniFrost.unarchivate"),
+ I18n.getMessage("thaw.plugin.miniFrost.newMessage")
};
@@ -204,7 +206,7 @@
minTrustLevelInt = Integer.parseInt(minTrustLvlStr);
- JPanel minTrustLevelPanel = new JPanel(new BorderLayout(3, 3));
+ JPanel minTrustLevelPanel = new JPanel(new BorderLayout(5, 5));
minTrustLevelPanel.add(new
JLabel(I18n.getMessage("thaw.plugin.miniFrost.hideStatusBelow")),
BorderLayout.WEST);
minTrustLevel = new JComboBox(Identity.trustLevelUserStr);
minTrustLevel.setSelectedItem(Identity.getTrustLevelStr(minTrustLevelInt));
@@ -569,6 +571,10 @@
boolean select = (sel == 1);
model.setSelectedAll(select);
model.refresh();
+ } else if (sel == 7) { /* new message */
+ Draft draft = targetBoard.getDraft(null);
+ mainPanel.getDraftPanel().setDraft(draft);
+ mainPanel.displayDraftPanel();
}
actions.setSelectedIndex(0);
Modified: trunk/apps/Thaw/src/thaw/plugins/miniFrost/MiniFrostPanel.java
===================================================================
--- trunk/apps/Thaw/src/thaw/plugins/miniFrost/MiniFrostPanel.java
2007-07-28 21:10:18 UTC (rev 14415)
+++ trunk/apps/Thaw/src/thaw/plugins/miniFrost/MiniFrostPanel.java
2007-07-29 00:34:10 UTC (rev 14416)
@@ -27,8 +27,11 @@
private Config config;
private Hsqldb db;
private BoardTree boardTree;
+
private MessageTreeTable messageTreeTable;
private MessagePanel messagePanel;
+ private DraftPanel draftPanel;
+
private MiniFrost pluginCore;
private JSplitPane mainSplit;
@@ -42,17 +45,38 @@
boardTree = new BoardTree(this);
messageTreeTable = new MessageTreeTable(this);
messagePanel = new MessagePanel(this);
+ draftPanel = new DraftPanel(this);
boardTree.addObserver(this);
- mainSplit = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, /* so
it will be vertical ... don't ask me why ... */
+ /* so it will be vertical ... don't ask me why ... */
+ mainSplit = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT,
boardTree.getPanel(),
messageTreeTable.getPanel());
}
+
+ public void displayDraftPanel() {
+ saveState();
+
+ messagePanel.hided();
+ messageTreeTable.hided();
+
+ mainSplit.setRightComponent(draftPanel.getPanel());
+ mainSplit.validate();
+
+ draftPanel.redisplayed();
+
+ loadState();
+ }
+
+
public void displayMessageTable() {
saveState();
+
messagePanel.hided();
+ draftPanel.hided();
+
mainSplit.setRightComponent(messageTreeTable.getPanel());
mainSplit.validate();
@@ -63,7 +87,10 @@
public void displayMessage() {
saveState();
+
messageTreeTable.hided();
+ draftPanel.hided();
+
mainSplit.setRightComponent(messagePanel.getPanel());
messagePanel.redisplayed();
mainSplit.validate();
@@ -129,6 +156,10 @@
return messagePanel;
}
+ public DraftPanel getDraftPanel() {
+ return draftPanel;
+ }
+
public void loadState() {
String val;
Modified: trunk/apps/Thaw/src/thaw/plugins/miniFrost/frostKSK/KSKAttachment.java
===================================================================
--- trunk/apps/Thaw/src/thaw/plugins/miniFrost/frostKSK/KSKAttachment.java
2007-07-28 21:10:18 UTC (rev 14415)
+++ trunk/apps/Thaw/src/thaw/plugins/miniFrost/frostKSK/KSKAttachment.java
2007-07-29 00:34:10 UTC (rev 14416)
@@ -1,14 +1,93 @@
package thaw.plugins.miniFrost.frostKSK;
import java.util.Vector;
+import org.w3c.dom.*;
+
import thaw.plugins.Hsqldb;
-public interface KSKAttachment
- extends thaw.plugins.miniFrost.interfaces.Attachment {
+public abstract class KSKAttachment
+ implements thaw.plugins.miniFrost.interfaces.Attachment {
- public void insert(Hsqldb db, int messageId);
+ public abstract String getType();
+ public abstract String getPrintableType();
- public StringBuffer getSignedStr();
+ public abstract String[] getProperties();
+
+ /**
+ * @return an array with the same size than the one of getProperties()
+ */
+ public abstract String[] getValues();
+
+ public abstract String getValue(String property);
+ public abstract void setValue(String property, String value);
+
+ /**
+ * Provides the XML tag name containing the properties
+ * @return null if none
+ */
+ public abstract String getContainer();
+
+ /**
+ * Name to display
+ * (the exact display will be: "[getPrintableType()]: [toString()]")
+ */
+ public abstract String toString();
+
+ public abstract String[] getActions();
+ public abstract void apply(Hsqldb db, thaw.fcp.FCPQueueManager
queueManager,
+ String action);
+
+ public abstract void insert(Hsqldb db, int messageId);
+ public abstract StringBuffer getSignedStr();
+
+
+ /* why ? nobody knows. */
+ public final static String[] CDATA_EXCEPTIONS = new String[] {
+ "key", "size"
+ };
+
+
+ public Element getXML(org.w3c.dom.Document doc) {
+ Element root = doc.createElement("Attachment");
+ root.setAttribute("type", getType());
+
+ Element subRoot;
+
+ if (getContainer() != null)
+ /* why ? nobody knows. */
+ subRoot = doc.createElement(getContainer());
+ else
+ subRoot = root;
+
+ String[] properties = getProperties();
+ String[] values = getValues();
+
+ for (int i = 0 ; i < properties.length ; i++) {
+ Element el = doc.createElement(properties[i]);
+
+ boolean inCdata = true;
+
+ for (int j = 0; j < CDATA_EXCEPTIONS.length ; j++)
+ if (CDATA_EXCEPTIONS[j].equals(properties[i]))
+ inCdata = false;
+
+ if (inCdata) {
+ CDATASection cdata =
doc.createCDATASection(values[i]);
+ el.appendChild(cdata);
+ } else {
+ Text txt = doc.createTextNode(values[i]);
+ el.appendChild(txt);
+ }
+
+ subRoot.appendChild(el);
+ }
+
+
+ if (subRoot != root)
+ root.appendChild(subRoot);
+
+ return root;
+ }
}
Modified: trunk/apps/Thaw/src/thaw/plugins/miniFrost/frostKSK/KSKBoard.java
===================================================================
--- trunk/apps/Thaw/src/thaw/plugins/miniFrost/frostKSK/KSKBoard.java
2007-07-28 21:10:18 UTC (rev 14415)
+++ trunk/apps/Thaw/src/thaw/plugins/miniFrost/frostKSK/KSKBoard.java
2007-07-29 00:34:10 UTC (rev 14416)
@@ -21,6 +21,7 @@
public class KSKBoard
+ extends Observable
implements Board, Runnable, Observer {
public final static int MAX_DOWNLOADS_AT_THE_SAME_TIME = 5;
@@ -301,6 +302,9 @@
private int lastSuccessfulRev;
private int failed;
+ private int maxDaysInThePast;
+
+
/* we keep the failed one in this queue as long as no other succeed */
/* sync() on it ! */
private KSKMessage runningDownloads[] = new
KSKMessage[MAX_DOWNLOADS_AT_THE_SAME_TIME];
@@ -397,6 +401,8 @@
protected void notifyChange() {
factory.getPlugin().getPanel().notifyChange(this);
+ setChanged();
+ notifyObservers();
}
protected void endOfRefresh() {
@@ -531,7 +537,7 @@
lastRev = -1;
lastSuccessfulRev = 0;
- Date maxInPast = new Date(new
Date().getTime() - (MAX_DAYS_IN_THE_PAST * 24*60*60*1000));
+ Date maxInPast = new Date(new
Date().getTime() - ((maxDaysInThePast+1) * 24*60*60*1000));
Date lastUpdatePast = ((lastUpdate ==
null) ? null :
new
Date(lastUpdate.getTime() - (DAYS_BEFORE_THE_LAST_REFRESH * 24*60*60*1000)));
@@ -560,13 +566,21 @@
}
public void refresh() {
+ refresh(MAX_DAYS_IN_THE_PAST);
+ }
+
+ public void refresh(int maxDaysInThePast) {
if (refreshing) {
Logger.warning(this, "Already refreshing");
return;
}
+ this.maxDaysInThePast = maxDaysInThePast;
+
refreshing = true;
+ notifyChange();
+
Thread th = new Thread(this);
th.start();
}
Modified:
trunk/apps/Thaw/src/thaw/plugins/miniFrost/frostKSK/KSKBoardAttachment.java
===================================================================
--- trunk/apps/Thaw/src/thaw/plugins/miniFrost/frostKSK/KSKBoardAttachment.java
2007-07-28 21:10:18 UTC (rev 14415)
+++ trunk/apps/Thaw/src/thaw/plugins/miniFrost/frostKSK/KSKBoardAttachment.java
2007-07-29 00:34:10 UTC (rev 14416)
@@ -11,7 +11,7 @@
public class KSKBoardAttachment
- implements KSKAttachment {
+ extends KSKAttachment {
private String boardName;
private String publicKey;
@@ -245,4 +245,5 @@
return buf;
}
+
}
Modified: trunk/apps/Thaw/src/thaw/plugins/miniFrost/frostKSK/KSKDraft.java
===================================================================
--- trunk/apps/Thaw/src/thaw/plugins/miniFrost/frostKSK/KSKDraft.java
2007-07-28 21:10:18 UTC (rev 14415)
+++ trunk/apps/Thaw/src/thaw/plugins/miniFrost/frostKSK/KSKDraft.java
2007-07-29 00:34:10 UTC (rev 14416)
@@ -1,37 +1,197 @@
package thaw.plugins.miniFrost.frostKSK;
+import java.util.Observer;
+import java.util.Observable;
+import java.util.Date;
+
import thaw.fcp.*;
import thaw.plugins.signatures.Identity;
+import thaw.core.Logger;
+import thaw.plugins.miniFrost.interfaces.Board;
+
public class KSKDraft
- implements thaw.plugins.miniFrost.interfaces.Draft {
+ implements thaw.plugins.miniFrost.interfaces.Draft, Observer {
+ private KSKMessage inReplyTo;
+ private KSKBoard board;
+
+ private String subject;
+ private String txt;
+ private String nick;
+ private Identity identity;
+ private Date date;
+
+
public KSKDraft(KSKBoard board, KSKMessage inReplyTo) {
+ this.board = board;
+ this.inReplyTo = inReplyTo;
+ }
+ public String getInitialSubject() {
+ if (inReplyTo != null) {
+ String subject = inReplyTo.getSubject();
+ if (subject.indexOf("Re: ") == 0)
+ return subject;
+ return "Re: "+subject;
+ }
+
+ return "";
}
public String getInitialText() {
- return "";
+ String txt = "";
+
+ if (inReplyTo != null) {
+ txt = inReplyTo.getRawMessage();
+ if (txt == null) txt = "";
+ else txt = (txt.trim() + "\n\n");
+ }
+
+ txt += "----- $sender$ ----- $dateAndTime$GMT -----\n\n";
+
+ return txt;
}
public boolean allowUnsignedPost() {
return true;
}
+ public void setSubject(String txt) {
+ subject = txt;
+ }
public void setText(String txt) {
-
+ this.txt = txt;
}
/**
* @param identity if null, unsigned post
*/
public void setAuthor(String nick, Identity identity) {
+ this.nick = nick;
+ this.identity = identity;
+ }
+ public void setDate(Date date) {
+ this.date = date;
}
+ public boolean addAttachment(java.io.File file) {
+ return true;
+ }
+
+ public boolean addAttachment(Board board) {
+ return true;
+ }
+
+ public boolean removeAttachment(java.io.File file) {
+ return true;
+ }
+
+ public boolean removeAttachment(Board board) {
+ return true;
+ }
+
+
+ private java.io.File fileToInsert;
+ private FCPQueueManager queueManager;
+ private int revUsed;
+
+
public void post(FCPQueueManager queueManager) {
+ this.queueManager = queueManager;
+ /* we start immediatly a board refresh (we will need it) */
+ synchronized(board) {
+ board.addObserver(this);
+ board.refresh(1 /* until today */);
+
+ KSKMessageParser generator = new KSKMessageParser(
((inReplyTo != null) ?
+
inReplyTo.getMsgId() :
+
null),
+ nick,
+
subject,
+ date,
+ null,
/* recipient */
+
board.getName(),
+ txt,
+
((identity != null) ?
+
identity.getPublicKey() :
+
null),
+ null,
+
identity);
+
+ fileToInsert = generator.generateXML();
+ fileToInsert.deleteOnExit();
+ }
}
+
+
+ private String getKey(Date date, int rev) {
+ java.text.SimpleDateFormat formatter = new
java.text.SimpleDateFormat("yyyy.M.d");
+ formatter.setTimeZone(java.util.TimeZone.getTimeZone("GMT"));
+
+ StringBuffer keyBuf = new StringBuffer(KSKMessage.KEY_HEADER);
+
+ keyBuf = formatter.format(date, keyBuf, new
java.text.FieldPosition(0));
+ keyBuf.append("-"+board.getName()+"-");
+ keyBuf.append(Integer.toString(rev));
+ keyBuf.append(".xml");
+
+ return keyBuf.toString();
+ }
+
+ private void startInsertion() {
+ String key = getKey(date, revUsed);
+
+ Logger.info(this, "Inserting : KSK@"+key);
+
+ FCPClientPut clientPut = new FCPClientPut(fileToInsert,
+
FCPClientPut.KEY_TYPE_KSK,
+ -1, /* rev : we
specify it ouselves in the key name */
+ key,
+ null, /* privateKey */
+ 2, /* priority */
+ false,
+
FCPClientPut.PERSISTENCE_FOREVER);
+ clientPut.addObserver(this);
+ queueManager.addQueryToTheRunningQueue(clientPut);
+ }
+
+
+ public void update(Observable o, Object param) {
+ if (o instanceof Board) {
+ synchronized(board) {
+ if (fileToInsert == null ||
board.isRefreshing())
+ return;
+ revUsed = board.getNextNonDownloadedRev(date,
-1);
+ }
+
+ startInsertion();
+ }
+
+ if (o instanceof FCPClientPut) {
+ FCPClientPut put = (FCPClientPut)o;
+
+ if (put.isFinished() && put.isSuccessful()) {
+ put.deleteObserver(this);
+ put.stop(queueManager);
+ queueManager.remove(put);
+
+ fileToInsert.delete();
+
+ } else if (put.isFinished() && !put.isSuccessful()) {
+ put.deleteObserver(this);
+ put.stop(queueManager);
+ queueManager.remove(put);
+
+ revUsed = board.getNextNonDownloadedRev(date,
revUsed);
+ startInsertion();
+
+ }
+ }
+
+ }
}
Modified:
trunk/apps/Thaw/src/thaw/plugins/miniFrost/frostKSK/KSKFileAttachment.java
===================================================================
--- trunk/apps/Thaw/src/thaw/plugins/miniFrost/frostKSK/KSKFileAttachment.java
2007-07-28 21:10:18 UTC (rev 14415)
+++ trunk/apps/Thaw/src/thaw/plugins/miniFrost/frostKSK/KSKFileAttachment.java
2007-07-29 00:34:10 UTC (rev 14416)
@@ -14,7 +14,7 @@
public class KSKFileAttachment
- implements KSKAttachment, Runnable {
+ extends KSKAttachment implements Runnable {
private String filename;
private long size;
@@ -265,4 +265,5 @@
return buf;
}
+
}
Modified: trunk/apps/Thaw/src/thaw/plugins/miniFrost/frostKSK/KSKMessage.java
===================================================================
--- trunk/apps/Thaw/src/thaw/plugins/miniFrost/frostKSK/KSKMessage.java
2007-07-28 21:10:18 UTC (rev 14415)
+++ trunk/apps/Thaw/src/thaw/plugins/miniFrost/frostKSK/KSKMessage.java
2007-07-29 00:34:10 UTC (rev 14416)
@@ -36,7 +36,7 @@
public final static int FCP_MAX_SIZE = 32*1024;
/* for example KSK at frost|message|news|2007.7.21-boards-47.xml */
- public final static String KEY_HEADER = "KSK at frost|message|news|";
+ public final static String KEY_HEADER = /* "KSK@" +
*/"frost|message|news|";
/* content is not kept in memory (at least not here) */
@@ -71,8 +71,9 @@
downloading = true;
java.text.SimpleDateFormat formatter = new
java.text.SimpleDateFormat("yyyy.M.d");
+ formatter.setTimeZone(java.util.TimeZone.getTimeZone("GMT"));
- StringBuffer keyBuf = new StringBuffer(KEY_HEADER);
+ StringBuffer keyBuf = new StringBuffer("KSK@"+KEY_HEADER);
keyBuf = formatter.format(date, keyBuf, new
java.text.FieldPosition(0));
keyBuf.append("-"+board.getName()+"-");
@@ -125,7 +126,8 @@
if (parser.loadFile(new File(get.getPath()))
&& parser.checkSignature(db)
- && parser.insert(db, board.getId(), rev,
board.getName())) {
+ && parser.insert(db, board.getId(),
+ date, rev, board.getName())) {
new File(get.getPath()).delete();
@@ -281,6 +283,7 @@
protected Vector parseMessage(final String fullMsg) {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy.MM.dd -
HH:mm:ss");
+ sdf.setTimeZone(java.util.TimeZone.getTimeZone("GMT"));
Vector v = new Vector();
@@ -331,7 +334,62 @@
}
+ protected String getMsgId() {
+ try {
+ Hsqldb db = board.getFactory().getDb();
+ synchronized(db.dbLock) {
+
+ PreparedStatement st;
+
+ st =
db.getConnection().prepareStatement("SELECT msgId "+
+ "FROM
frostKSKMessages "+
+ "WHERE
id = ? "+
+ "LIMIT
1");
+ st.setInt(1, id);
+
+ ResultSet set = st.executeQuery();
+
+ if (!set.next())
+ return null;
+
+ return set.getString("msgId");
+ }
+ } catch(SQLException e) {
+ Logger.error(this, "Error while getting the messages :
"+e.toString());
+ return null;
+ }
+ }
+
+
+ public String getRawMessage() {
+ try {
+ Hsqldb db = board.getFactory().getDb();
+
+ synchronized(db.dbLock) {
+
+ PreparedStatement st;
+
+ st =
db.getConnection().prepareStatement("SELECT content "+
+ "FROM
frostKSKMessages "+
+ "WHERE
id = ? "+
+ "LIMIT
1");
+ st.setInt(1, id);
+
+ ResultSet set = st.executeQuery();
+
+ if (!set.next())
+ return null;
+
+ return set.getString("content");
+ }
+ } catch(SQLException e) {
+ Logger.error(this, "Error while getting the messages :
"+e.toString());
+ return null;
+ }
+ }
+
+
/** no caching */
public Vector getSubMessages() {
@@ -357,8 +415,6 @@
content = set.getString("content");
nick = set.getString("nick");
-
- /* TODO signature */
}
} catch(SQLException e) {
Logger.error(this, "Error while getting the messages :
"+e.toString());
Modified:
trunk/apps/Thaw/src/thaw/plugins/miniFrost/frostKSK/KSKMessageParser.java
===================================================================
--- trunk/apps/Thaw/src/thaw/plugins/miniFrost/frostKSK/KSKMessageParser.java
2007-07-28 21:10:18 UTC (rev 14415)
+++ trunk/apps/Thaw/src/thaw/plugins/miniFrost/frostKSK/KSKMessageParser.java
2007-07-29 00:34:10 UTC (rev 14416)
@@ -13,6 +13,7 @@
import java.util.List;
import frost.util.XMLTools;
+import frost.crypt.FrostCrypt;
import thaw.plugins.signatures.Identity;
@@ -47,7 +48,65 @@
private Identity identity;
+ private static FrostCrypt frostCrypt;
+
+
+ public KSKMessageParser(String inReplyTo,
+ String from,
+ String subject,
+ java.util.Date dateUtil,
+ String recipient,
+ String board,
+ String body,
+ String publicKey,
+ Vector attachments,
+ Identity identity) {
+
+ SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy.M.d
HH:mm:ss");
+ dateFormat.setTimeZone(java.util.TimeZone.getTimeZone("GMT"));
+
+ this.messageId = ""; /* will be generated from the SHA1 of the
content */
+ this.inReplyTo = inReplyTo;
+ this.from = from;
+ this.subject = subject;
+
+ String[] date = dateFormat.format(dateUtil).toString().split("
");
+ this.date = date[0];
+ this.time = date[1];
+
+ this.recipient = null;
+
+ this.board = board;
+ this.body = body;
+ this.publicKey = publicKey;
+ this.idLinePos = "0";
+ this.idLineLen = "0";
+
+ this.attachments = attachments;
+
+ this.identity = identity;
+
+ if (frostCrypt == null)
+ frostCrypt = new FrostCrypt();
+
+ /* frost want a SHA256 hash, but can't check from what is comes
:p */
+ this.messageId =
frostCrypt.computeChecksumSHA256(getSignedContent());
+
+ if (identity == null)
+ signature = null;
+ else {
+ signature = identity.sign(getSignedContent());
+ }
+ }
+
+
private boolean alreadyInTheDb(Hsqldb db, String msgId) {
+ if (msgId == null) {
+ Logger.notice(this, "no message id => ignoring this
message by supposing it "
+ +"already in the db");
+ return true;
+ }
+
try {
synchronized(db.dbLock) {
PreparedStatement st;
@@ -71,7 +130,7 @@
public boolean insert(Hsqldb db,
- int boardId, int rev,
+ int boardId, java.util.Date boardDate, int rev,
String boardNameExpected) {
if (boardNameExpected == null) {
Logger.error(this, "Board name expected == null ?!");
@@ -89,7 +148,9 @@
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy.M.d
HH:mm:ss");
- time = time.replaceAll("GMT", "").trim();
+ time = time.trim();
+
+ /*
date = date.trim();
date += " "+time;
@@ -101,8 +162,9 @@
date = "(null)";
Logger.warning(this, "Unable to parse the date ?! :
"+date);
}
+ */
- java.sql.Timestamp dateSql = new
java.sql.Timestamp(dateUtil.getTime());
+ java.sql.Timestamp dateSql = new
java.sql.Timestamp(boardDate.getTime());
int replyToId = -1;
@@ -185,7 +247,7 @@
}
}
} catch(SQLException e) {
- Logger.error(this, "Can't insert the message into the
db because : "+e.toString());
+ Logger.warning(this, "Can't insert the message into the
db because : "+e.toString());
return false;
}
@@ -199,7 +261,7 @@
final StringBuilder allContent = new StringBuilder();
allContent.append(date).append(SIGNATURE_ELEMENTS_SEPARATOR);
- allContent.append(time).append(SIGNATURE_ELEMENTS_SEPARATOR);
+
allContent.append(time+"GMT").append(SIGNATURE_ELEMENTS_SEPARATOR);
allContent.append(board).append(SIGNATURE_ELEMENTS_SEPARATOR);
allContent.append(from).append(SIGNATURE_ELEMENTS_SEPARATOR);
allContent.append(messageId).append(SIGNATURE_ELEMENTS_SEPARATOR);
@@ -252,6 +314,7 @@
subject = XMLTools.getChildElementsCDATAValue(root,
"Subject");
date = XMLTools.getChildElementsCDATAValue(root,
"Date");
time = XMLTools.getChildElementsCDATAValue(root,
"Time");
+ time = time.replaceAll("GMT", "");
recipient = XMLTools.getChildElementsCDATAValue(root,
"recipient");
board = XMLTools.getChildElementsCDATAValue(root,
"Board");
body = XMLTools.getChildElementsCDATAValue(root,
"Body");
@@ -313,6 +376,88 @@
}
}
+ public Element makeText(Document doc, String tagName, String content) {
+ if (content == null || tagName == null)
+ return null;
+ Text txt;
+ Element current;
+ current = doc.createElement(tagName);
+ txt = doc.createTextNode(content);
+ current.appendChild(txt);
+
+ return current;
+ }
+
+
+ public Element makeCDATA(Document doc, String tagName, String content) {
+ if (content == null || tagName == null)
+ return null;
+
+ CDATASection cdata;
+ Element current;
+
+ current = doc.createElement(tagName);
+ cdata = doc.createCDATASection(content);
+ current.appendChild(cdata);
+
+ return current;
+ }
+
+
+ public Element getXMLTree(Document doc) {
+ Element root = doc.createElement("FrostMessage");
+
+ Element el;
+
+ if ((el = makeText( doc, "client", "Thaw
"+thaw.core.Main.VERSION)) != null)
+ root.appendChild(el);
+ if ((el = makeCDATA(doc, "MessageId", messageId)) != null)
root.appendChild(el);
+ if ((el = makeCDATA(doc, "InReplyTo", inReplyTo)) != null)
root.appendChild(el);
+ if ((el = makeText( doc, "IdLinePos", idLinePos)) != null)
root.appendChild(el);
+ if ((el = makeText( doc, "IdLineLen", idLineLen)) != null)
root.appendChild(el);
+ if ((el = makeCDATA(doc, "From", from)) != null)
root.appendChild(el);
+ if ((el = makeCDATA(doc, "Subject", subject)) != null)
root.appendChild(el);
+ if ((el = makeCDATA(doc, "Date", date)) != null)
root.appendChild(el);
+ if ((el = makeCDATA(doc, "Time", time+"GMT")) != null)
root.appendChild(el);
+ if ((el = makeCDATA(doc, "Body", body)) != null)
root.appendChild(el);
+ if ((el = makeCDATA(doc, "Board", board)) != null)
root.appendChild(el);
+ if ((el = makeCDATA(doc, "pubKey", publicKey)) != null)
root.appendChild(el);
+ if ((el = makeCDATA(doc, "recipient", recipient)) != null)
root.appendChild(el);
+ if ((el = makeCDATA(doc, "SignatureV2", signature)) != null)
root.appendChild(el);
+
+ if (attachments != null) {
+ el = doc.createElement("AttachmentList");
+
+ for (Iterator it = attachments.iterator();
+ it.hasNext();) {
+
el.appendChild(((KSKAttachment)it.next()).getXML(doc));
+ }
+
+ root.appendChild(el);
+ }
+
+ return root;
+ }
+
+
+ public File generateXML() {
+ File tmpFile;
+
+ try {
+ tmpFile = File.createTempFile("thaw-", "-message.xml");
+ tmpFile.deleteOnExit();
+ } catch(java.io.IOException e) {
+ Logger.error(this, "Can't create temporary file because
: "+e.toString());
+ return null;
+ }
+
+ Document doc = XMLTools.createDomDocument();
+
+ doc.appendChild(getXMLTree(doc));
+
+ return (XMLTools.writeXmlFile(doc, tmpFile.getPath()) ? tmpFile
: null);
+ }
+
}
Modified: trunk/apps/Thaw/src/thaw/plugins/miniFrost/interfaces/Draft.java
===================================================================
--- trunk/apps/Thaw/src/thaw/plugins/miniFrost/interfaces/Draft.java
2007-07-28 21:10:18 UTC (rev 14415)
+++ trunk/apps/Thaw/src/thaw/plugins/miniFrost/interfaces/Draft.java
2007-07-29 00:34:10 UTC (rev 14416)
@@ -5,11 +5,17 @@
public interface Draft {
+ public String getInitialSubject();
+
+ /**
+ * Returned result may contains $sender$, $dateAndTime$.
+ * They will be replaced.
+ */
public String getInitialText();
public boolean allowUnsignedPost();
-
+ public void setSubject(String txt);
public void setText(String txt);
/**
@@ -17,6 +23,15 @@
*/
public void setAuthor(String nick, Identity identity);
+ /**
+ * @param date don't forget to GMT-ize it when formatting it
+ */
+ public void setDate(java.util.Date date);
+ public boolean addAttachment(java.io.File file);
+ public boolean addAttachment(Board board);
+ public boolean removeAttachment(java.io.File file);
+ public boolean removeAttachment(Board board);
+
public void post(thaw.fcp.FCPQueueManager queueManager);
}
Modified: trunk/apps/Thaw/src/thaw/plugins/signatures/SigConfigTab.java
===================================================================
--- trunk/apps/Thaw/src/thaw/plugins/signatures/SigConfigTab.java
2007-07-28 21:10:18 UTC (rev 14415)
+++ trunk/apps/Thaw/src/thaw/plugins/signatures/SigConfigTab.java
2007-07-29 00:34:10 UTC (rev 14416)
@@ -412,7 +412,7 @@
public OtherIdentitiesPanel() {
dialog = new JDialog(configWindow.getFrame(),
-
I18n.getMessage("thaw.plugin.signature.dialogTitle.yourIdentities"));
+
I18n.getMessage("thaw.plugin.signature.dialogTitle.otherIdentities"));
dialog.getContentPane().setLayout(new BorderLayout(5,
5));