package thaw.plugins.miniFrost.frostKSK; import java.util.Observer; import java.util.Observable; import java.util.Date; import java.util.Vector; import java.util.Iterator; import thaw.fcp.*; import thaw.plugins.signatures.Identity; import thaw.core.Logger; import thaw.plugins.miniFrost.interfaces.Board; import thaw.plugins.miniFrost.interfaces.Attachment; import thaw.core.I18n; import thaw.core.ThawRunnable; import thaw.core.ThawThread; public class KSKDraft implements thaw.plugins.miniFrost.interfaces.Draft, Observer { private KSKMessage inReplyTo = null; private KSKBoard board = null; private String subject = null; private String txt = null; private String nick = null; private Identity identity = null; private Identity recipient = null; private Date date = null; private int idLinePos = 0; private int idLineLen = 0; private Vector attachments; public KSKDraft(KSKBoard board, KSKMessage inReplyTo) { this.board = board; this.inReplyTo = inReplyTo; attachments = null; if (inReplyTo != null && inReplyTo.encryptedFor() != null && inReplyTo.getSender() != null && inReplyTo.getSender().getIdentity() != null) { recipient = inReplyTo.getSender().getIdentity(); } } public String getSubject() { if (subject != null) return subject; if (inReplyTo != null) { String subject = inReplyTo.getSubject(); if (subject.indexOf("Re: ") == 0) return subject; return "Re: "+subject; } return ""; } public String getText() { if (txt != null) return txt; 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 Identity getAuthorIdentity() { return identity; } public String getAuthorNick() { return nick; } public void setRecipient(Identity id) { this.recipient = id; } public Identity getRecipient() { return recipient; } public void setDate(Date date) { this.date = date; } public Date getDate() { return date; } private java.io.File fileToInsert; private FCPQueueManager queueManager; private int revUsed; private boolean waiting; private boolean posting; public void notifyPlugin() { board.getFactory().getPlugin().getPanel().update(this); } public boolean isWaiting() { return waiting; } public boolean isPosting() { return posting; } public void setIdLinePos(int i) { idLinePos = i; } public void setIdLineLen(int i) { idLineLen = i; } private boolean initialInsertion = false; public void post(FCPQueueManager queueManager) { this.queueManager = queueManager; initialInsertion = false; waiting = true; posting = false; notifyPlugin(); /* we start immediatly a board refresh (we will need it) */ synchronized(board) { board.addObserver(this); board.refresh(2 /* until yesterday ; just to be sure because of the GMT conversion etc */); } /* first check */ update(board, null); } private class InsertionStarter implements ThawRunnable { private boolean forceStop; public InsertionStarter() { forceStop = false; } public void run() { boolean ready = false; while(!ready && attachments != null && !forceStop) { ready = true; for (Iterator it = attachments.iterator(); it.hasNext();) { KSKAttachment a = (KSKAttachment)it.next(); if (!a.isReady()) ready = false; } if (!ready) { try { Thread.sleep(500); } catch(InterruptedException e) { /* \_o< */ } } } if (!forceStop) startInsertion(); } public void stop() { forceStop = true; } } private void startInsertion() { /* we generate first the XML message */ KSKMessageParser generator = new KSKMessageParser(board.getFactory().getDb(), ((inReplyTo != null) ? inReplyTo.getMsgId() : null), nick, subject, date, recipient, /* recipient */ board.getName(), txt, ((identity != null) ? identity.getPublicKey() : null), attachments, identity, idLinePos, idLineLen, board.getFactory().getWoT().getTrustListPublicKeyFor(identity)); fileToInsert = generator.generateXML(board.getFactory().getDb() /* gruick */); waiting = false; posting = true; notifyPlugin(); String privateKey = board.getPrivateKey(); String name = board.getNameForInsertion(date, revUsed); int keyType = board.getKeyType(); if (keyType == FCPClientPut.KEY_TYPE_KSK) Logger.info(this, "Inserting : KSK@"+name); else Logger.info(this, "Insertion : SSK@"+privateKey+name); FCPClientPut clientPut = new FCPClientPut(fileToInsert, keyType, -1, /* rev : we specify it ouselves in the key name */ name, privateKey, /* privateKey */ 2, /* priority */ false, FCPClientPut.PERSISTENCE_FOREVER, true, /* doCompress */ -1); /* compression codec */ clientPut.addObserver(this); queueManager.addQueryToTheRunningQueue(clientPut); } private boolean isBoardUpToDateForToday() { if (!board.isRefreshing() || (board.getCurrentlyRefreshedDate() != null && (KSKBoard.getMidnight(board.getCurrentlyRefreshedDate()).getTime() < KSKBoard.getMidnight(date).getTime()) )) { //Logger.info(this, "Board: "+Long.toString(KSKBoard.getMidnight(board.getCurrentlyRefreshedDate()).getTime())); Logger.info(this, "Draft: "+KSKBoard.getMidnight(date).getTime()); return true; } return false; } public void update(Observable o, Object param) { if (o instanceof Board) { synchronized(board) { /* just to be sure we don't insert the message many times */ if (initialInsertion) return; if (!isBoardUpToDateForToday()) return; initialInsertion = true; board.deleteObserver(this); revUsed = board.getNextNonDownloadedAndValidRev(date, -1); ThawThread th = new ThawThread(new InsertionStarter(), "Frost message insertion starter"); th.start(); } } if (o instanceof FCPClientPut) { FCPClientPut put = (FCPClientPut)o; if (put.isFinished() && put.isSuccessful()) { posting = false; waiting = false; notifyPlugin(); put.deleteObserver(this); put.stop(queueManager); queueManager.remove(put); fileToInsert.delete(); Logger.info(this, "Message sent."); String announce = I18n.getMessage("thaw.plugin.miniFrost.messageSent"); announce = announce.replaceAll("X", board.toString()); thaw.plugins.TrayIcon.popMessage(board.getFactory().getCore().getPluginManager(), "MiniFrost", announce); } else if (put.isFinished() && !put.isSuccessful()) { if (put.getPutFailedCode() != 9) { /* !Collision */ put.deleteObserver(this); if (put.getPutFailedCode() < 0) Logger.warning(this, "message insertion on the board '"+ board.toString()+"' cancelled"); else Logger.error(this, "Can't insert the message on the board '"+ board.toString()+"' ; Code: "+Integer.toString(put.getPutFailedCode())); waiting = false; posting = false; notifyPlugin(); return; } String announce = I18n.getMessage("thaw.plugin.miniFrost.collision"); announce = announce.replaceAll("X", board.toString()); thaw.plugins.TrayIcon.popMessage(board.getFactory().getCore().getPluginManager(), "MiniFrost", announce, thaw.gui.SysTrayIcon.MSG_WARNING); put.deleteObserver(this); put.stop(queueManager); queueManager.remove(put); //revUsed = board.getNextNonDownloadedRev(date, revUsed); revUsed = board.getNextNonDownloadedAndValidRev(date, revUsed); startInsertion(); } } } public Board getBoard() { return board; } public Vector getAttachments() { return attachments; } public boolean addAttachment(java.io.File file) { return addAttachment(new KSKFileAttachment(board.getFactory().getCore().getQueueManager(), file)); } public boolean addAttachment(Board board) { return addAttachment(new KSKBoardAttachment(board)); } public boolean addAttachment(thaw.plugins.index.Index index) { return false; } protected boolean addAttachment(KSKAttachment attachment) { if (attachments == null) attachments = new Vector(); attachments.add(attachment); return true; } public boolean removeAttachment(Attachment attachment) { if (attachments == null) return false; attachments.remove(attachment); return false; } }