Update of /cvsroot/mailsomething/mailsomething/src/net/sf/mailsomething/mail/actions In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv20946/net/sf/mailsomething/mail/actions Added Files: AppendMessageAction.java MoveMailboxAction.java AbstractMailAction.java UpdateMailboxesAction.java DeleteMessageAction.java GetMessagesAction.java GetMessageBodyAction.java RenameMailboxAction.java DeleteMailboxAction.java StoreMessageAction.java MoveMessageAction.java CopyMessageAction.java CreateMailboxAction.java Log Message: --- NEW FILE: GetMessagesAction.java --- package net.sf.mailsomething.mail.actions; import java.text.DateFormat; import java.text.FieldPosition; import java.text.SimpleDateFormat; import java.util.Date; import java.util.Locale; import java.util.Vector; import net.sf.mailsomething.mail.MailAccount; import net.sf.mailsomething.mail.MailService; import net.sf.mailsomething.mail.MailUtils; import net.sf.mailsomething.mail.Mailbox; import net.sf.mailsomething.mail.Message; import net.sf.mailsomething.mail.MessageConstants; import net.sf.mailsomething.mail.MessageHolder; import net.sf.mailsomething.mail.ObjectHandler; import net.sf.mailsomething.mail.parsers.ImapController; import net.sf.mailsomething.mail.parsers.PopController; /** * @author Stig tanggaard * @since 2005-03-19 * **/ public class GetMessagesAction extends AbstractMailAction { // for getting unseen messages public static final int UNSEEN = 1; //for getting recent messages public static final int RECENT = 2; //to get messages based on messageid-comparision public static final int MESSAGEID = 3; //to get messages based on date, ie, all mails since the last we have recieved public static final int DATE = 4; //to get all messages. This probably shouldnt be used. public static final int ALL = 5; //neither this public static final int SYNC = 6; //for using the default mechanisme (first time: date search, and after: unseen). public static final int DEFAULT = 7; private MailAccount mailAccount; private PopController controller; private MessageHolder mailbox; private ImapController imapControll; private int type; /* (non-Javadoc) * @see net.sf.mailsomething.mail.MailAction#invoke() */ public void invoke() { // TODO Auto-generated method stub } /* (non-Javadoc) * @see net.sf.mailsomething.mail.MailAction#undo() */ public void undo() { // TODO Auto-generated method stub } /* (non-Javadoc) * @see net.sf.mailsomething.mail.MailAction#setMailAccount(net.sf.mailsomething.mail.MailAccount) */ public void setMailAccount(MailAccount account) { // TODO Auto-generated method stub } protected void pop3Invoke() { //if (r.getFlag() == 6) // return; controller.clearUidBuffer(); MessageHolder mailbox = mailAccount.getStandardMailbox(Mailbox.INBOX); PopController.UIDMarker[] uids = controller.searchUid(); if (uids == null) return; Vector nmessages = new Vector(); int max = mailAccount.getMaxMessagesToFetch(); int startfrom = 0; /** * We dont call either notifyMessagesFound since we dont know * how many NEW messages is actually found. */ if (max < uids.length) { startfrom = uids.length - max; notifyWorkStarted(max); } else notifyWorkStarted(uids.length); int[] sizes = null; for (int i = startfrom; i < uids.length; i++) { if (uids[i] != null) { //problem here. if (!mailbox.existsUid(uids[i].getUID())) { //dont get the message sizes untill we have a new message if (sizes == null) sizes = controller.getSizeList(); //int size = controller.getMessageSize(uids[i].getIndex()); if (sizes[uids[i].getIndex() - 1] > mailAccount.getMaxMessageSize()) { Message m = MailService.createMessage(); m.setUID(uids[i].getUID()); m.setField(MessageConstants.SUBJECT, "unknown"); m.setField(MessageConstants.FROM, "unknown"); String message = "The size of this message is bigger than limit," + "either change sizelimit or ignore this message" + "completely. Some time in future it will be possible" + "to fetch the message anyways"; m.setObject(message.getBytes()); m.setRemote(true); m.setSize(sizes[uids[i].getIndex() - 1]); mailbox.addMessage(m); nmessages.add(m); //notifyMessagesFetched(mailbox, new Message[] { m }); } else { Message m = controller.getMessage(uids[i].getIndex()); m.setRemote(true); m.setUID(uids[i].getUID()); m.setBodyFetched(true); m.setSize(sizes[uids[i].getIndex() - 1]); mailbox.addMessage(m); nmessages.add(m); //notifyMessagesFetched(mailbox, new Message[] { m }); } } } notifyWorkProgress(i - startfrom + 1); } notifyWorkStopped(); controller.logof(); } protected void imapInvoke() { String path = mailbox.getPath(); String[] seqenceNumbers = null; /** * This is a special situation where we just ignore any * request specification. Reason - this way of getting all * sequencenumbers should be stable with all server implementations * and furthermore its the fastest of them all (when we havent * got any messages yet). * * */ if (mailbox.getMessageCount() == 0) { seqenceNumbers = getSequencesBySelection(path); } else { /** * The reason not all the types are equivalent with controller-methods * is a design issue. * FetchUnseen & FetchRecent are natural controller methods, * while fetchDate or fetchMessageid * isnt.... or maybe they are, but they dont fetch messages. */ switch (type) { case UNSEEN : seqenceNumbers = imapControll.searchUnseen(path); /*checkedMailboxes.put( path, new Integer(controller.getExists()));*/ break; case RECENT : seqenceNumbers = imapControll.searchRecent(path); /*checkedMailboxes.put( path, new Integer(controller.getExists()));*/ break; case MESSAGEID : synchronizeMessages(mailbox); return; case DATE : //this is wrong... the search command doesnt returns uid´s //but message sequence numbers seqenceNumbers = getSequencesByDate(mailbox, path); /*checkedMailboxes.put( path, new Integer(controller.getExists()));*/ break; case ALL : synchronizeMessages(mailbox); return; //This should be called default, instead, but I dont wanna //disturb serializing right now. case SYNC : synchronizeMessages(mailbox); return; } } getMessages(mailbox, seqenceNumbers); } /** * * Synchronizes the specific mailbox. Currently that means that we * fetch any messages in the mailbox we dont have allready, based * on uids of messages. Secondly, if we have some messages locally * which doesnt exists at server we mark them as local. We dont * delete them automaticly, I think that should be a useroption. * * @param mailbox */ protected void synchronizeMessages(MessageHolder mailbox) { //to get a fresh exists count imapControll.searchUnseen(mailbox.getPath()); //first make sure we select the right mailbox //There is an issue here, when the selected mailbox is the //same as the one currently selected, then we dont get an update //of the exists count, ie if some messages has been deleted //we will get a higher exists count. Because of the controller //implementation. SOlution - do a controller.getUnseen first //see above. String[] seqenceNumbers = getSequencesBySelection(mailbox.getPath()); //get the exists value, then we have sequence 0 to exists int endIndex = imapControll.getExists(); //get all uids for this sequence (which is all uids available) String[] uids = imapControll.fetchUID(1, endIndex); Vector buffer = new Vector(); //check if the uid exists for (int i = 0; i < uids.length; i++) { if (!mailbox.existsUid(uids[i])) { buffer.add("" + (i+1)); } } //get those messages we dont have. getMessages(mailbox, (String[])buffer.toArray(new String[]{})); //next is to check for all local messages, if they exists or //not at server, and delete them if not. This means, that a //locally created message should be marked with a flag if it //had been appended or not, if this flag is set to not, it should //ofcourse not be deleted, but appended. Message[] messages = mailbox.getMessages(); for(int i = 0; i < messages.length; i++) { String uid = messages[i].getUID(); if(uid != null) { boolean isRemote = false; for(int j = 0; j < uids.length; j++) { if(uids[j].equals(uid)) { isRemote = true; break; } } if(!isRemote) { messages[i].setRemote(false); //if this message does not exists at server and its //marked for delition, then we can just remove it. //actually the message dont need to be marked deleted //to be removed, this is just a choice I have made //so far. Maybe it should be a useroption. if(messages[i].isMarkedDeleted()) { mailbox.removeMessage(messages[i]); } } else { if(messages[i].isMarkedDeleted()) { //here theres 2 possibilities 1. request the //message to be deleted, or 2. unmark the deletion. //I will choose the last and let it be up to the //user to delete it again. //int flags = //messages[i].setFlag() //doesnt seem to be possible :) } } } } } protected String[] getSequencesBySelection(String path) { imapControll.selectMailbox(path); int exists = imapControll.getExists(); String[] sequenceNumbers = new String[exists]; for (int i = 0; i < exists; i++) { sequenceNumbers[i] = "" + (i + 1); } return sequenceNumbers; } /** * To get all messages by date. I have been using this to get * all messages of a mailbox the first time a connection is * made. Also to get all the messages since last connection (by * searching by the date of the last message). * I wont use it to get all the message anymore. Turns out some * servers dont like a * search 01-01-1970 * Instead use getMessagesBySelection * * @param m * @param path * @return */ protected String[] getSequencesByDate(MessageHolder m, String path) { String[] sequenceNumbers; Message mm = MailUtils.getLastMessage(m.getMessages()); Date date; if (mm == null || mm.getDate() == null) { long l = 1000; date = new Date(l); } else date = mm.getDate(); SimpleDateFormat format = new SimpleDateFormat("dd-MMM-yyyy", Locale.ENGLISH); StringBuffer buffer = format.format( date, new StringBuffer(), new FieldPosition(DateFormat.FULL)); //System.out.println(buffer.toString()); sequenceNumbers = imapControll.searchDate(path, buffer.toString()); //if length is 0 just return the empty array. if (sequenceNumbers.length == 0) return sequenceNumbers; /** * TODO: This is BAD design. The idea by returning sequencenumbers * is to actually return those we dont have. So instead of * just returning the last ones, we should furthermore check * if we allready have those. * * Okay im changing it now, with no garanties it will work * properly. It should though. * */ try { int startIndex = Integer.parseInt(sequenceNumbers[0]); int endIndex = Integer.parseInt(sequenceNumbers[sequenceNumbers.length - 1]); String[] uids = imapControll.fetchUID(startIndex, endIndex); //some error have happened return empty array if (uids == null) return new String[] { }; Vector temp = new Vector(); for (int i = 0; i < uids.length; i++) { //System.out.println("uids found " + uids[i]); if (!m.existsUid(uids[i])) { temp.add(sequenceNumbers[i]); } } return (String[]) temp.toArray(new String[] { }); } catch (NumberFormatException f) { //TODO: better errorhandling here return new String[] { }; } } /** * I have extracted this into its own method. Seems more appropiate, * and the updatemessages method was getting to big. * * * @param mailbox * @param seqenceNumbers */ protected void getMessages( MessageHolder mailbox, String[] seqenceNumbers) { if (seqenceNumbers == null) { //System.out.println("notifying progress imapaccount"); //this is a hack to display some false activity. notifyWorkStarted(0); //notifyWorkProgress(); notifyWorkStopped(); return; } int max = mailAccount.getMaxMessagesToFetch(); int startfrom = 0; /** * We dont call either notifyMessagesFound since we dont know * how many NEW messages is actually found. */ if (max < seqenceNumbers.length) { startfrom = seqenceNumbers.length - max; notifyWorkStarted(max); } else notifyWorkStarted(seqenceNumbers.length); //Vector nmessages = new Vector(); //notifyWorkStarted(uid.length+1); /** * TODO * The following is wrong. We need to look at the sequence * numbers first, to determine if the are in the right order, * and those in the right order should be fetched (header/body) * at same time. Which means we need to supply a new method * in the imapcontroller taking and startindex and an endindex. * Its very likely (for many instances) that all sequence numbers * are in the same row. * * */ int[] numbers = new int[seqenceNumbers.length]; if (numbers.length == 0) { notifyWorkStopped(); return; } for (int i = 0; i < seqenceNumbers.length; i++) { try { numbers[i] = Integer.parseInt(seqenceNumbers[i]); System.out.print(" " + numbers[i]); } catch (NumberFormatException f) { } } int[][] sequences = getSequences(numbers); // create a handler HeaderFetchedHandler handler = new HeaderFetchedHandler((Mailbox) mailbox); for (int i = 0; i < sequences.length; i++) { //get the messages imapControll.getHeader( handler, mailbox.getPath(), sequences[i][0], sequences[i][sequences[i].length - 1]); } handler.start(); notifyWorkStopped(); } /** * * Method for traversing a sequence number array (where the sequences * may have 'jumps' at more than 1) and putting those numbers into * arrays containing numbers which follows on a row by 1 as jump. Ie, * an argument of 2,3,4,7,8,9,10,12,13,14 would return 3 arrays of * 2,3,4 * 7,8,9,10 * 12,13,14 * * @param sequenceNumbers * @return a 2 dimensionel array with each array containing a sequence of * numbers */ public int[][] getSequences(int[] sequenceNumbers) { Vector temp = new Vector(); int lastNumber = sequenceNumbers[0]; int startIndex = 0; for (int i = 1; i < sequenceNumbers.length; i++) { if (sequenceNumbers[i] != lastNumber + 1) { int[] array = new int[i - startIndex]; int index = 0; for(int j = startIndex; j < i; j++) { array[index] = sequenceNumbers[j]; index++; } temp.add(array); startIndex = i; } lastNumber = sequenceNumbers[i]; } if (startIndex < sequenceNumbers.length) { int[] array = new int[sequenceNumbers.length - startIndex]; int index = 0; for (int j = startIndex; j < sequenceNumbers.length; j++) { array[index] = sequenceNumbers[j]; index++; } temp.add(array); } int[][] seqs = new int[temp.size()][]; for(int i = 0; i < temp.size(); i++) { int[] array = (int[])temp.elementAt(i); seqs[i] = new int[array.length]; for(int j = 0; j < array.length; j++) { seqs[i][j] = array[j]; } } return seqs; } class HeaderFetchedHandler extends Thread implements ObjectHandler { Vector fetchedMessages = new Vector(); Mailbox mailbox; int index = 0; int indexOfMessageLoaded = 0; //boolean public HeaderFetchedHandler(Mailbox mailbox) { this.mailbox = mailbox; //Runtime.getRuntime().addShutdownHook(this); } /** * After being called this fires a messagefetchedevent. Which * means the class/method using the HeaderFetchedHandler should * not do this too. * * @see net.sf.mailsomething.mail.ObjectHandler#handle(java.lang.Object) */ public void handle(Object o) { if (o == null) return; Message message = (Message) o; message.setRemote(true); message.setBodyFetched(false); index++; //because the messageid havent been parsed yet it is not //possible to check if message exists based on messageid, //which means we need to check for UID. if (mailbox.existsUid(message.getUID())) { notifyWorkProgress(index); return; } if (message.getField(MessageConstants.MESSAGE_ID) == null) message.setField( MessageConstants.MESSAGE_ID, MailUtils.getUniqeID()); fetchedMessages.add(message); notifyWorkProgress(index); } public void run() { int pause = 0; if (fetchedMessages.size() > 20) { mailbox.disableListeners(true); } while (indexOfMessageLoaded < fetchedMessages.size()) { //pause++; Message m = (Message) fetchedMessages.elementAt(indexOfMessageLoaded); if (!m.isLoaded()) m.load(); mailbox.addMessage(m); //notifyMessagesFetched(mailbox, new Message[] { (Message) fetchedMessages // .elementAt(indexOfMessageLoaded) }); indexOfMessageLoaded++; } //moved this here to have a better firing of events. //notifyMessagesFetched(mailbox, (Message[])fetchedMessages.toArray(new Message[] {})); if (fetchedMessages.size() > 20) { mailbox.disableListeners(false); } } } /** * @param mailbox The mailbox to set. */ public void setMailbox(MessageHolder mailbox) { this.mailbox = mailbox; } /** * @param type The type to set. */ public void setType(int type) { this.type = type; } } --- NEW FILE: MoveMessageAction.java --- package net.sf.mailsomething.mail.actions; import net.sf.mailsomething.mail.Message; import net.sf.mailsomething.mail.MessageHolder; /** * @author Stig tanggaard * @since 2005-03-20 * **/ public class MoveMessageAction extends CopyMessageAction { public MoveMessageAction(MessageHolder srcMailbox, MessageHolder destMailbox, Message message) { super(srcMailbox, destMailbox, message); } /* (non-Javadoc) * @see net.sf.mailsomething.mail.actions.CopyMessageAction#invoke() */ public void invoke() { // TODO Auto-generated method stub super.invoke(); srcMailbox.removeMessage(message); } } --- NEW FILE: GetMessageBodyAction.java --- package net.sf.mailsomething.mail.actions; import net.sf.mailsomething.mail.ImapAccount; import net.sf.mailsomething.mail.MailAccount; import net.sf.mailsomething.mail.Message; import net.sf.mailsomething.mail.MessageHolder; import net.sf.mailsomething.util.ProgressListener; /** * @author Stig tanggaard * @since 2005-03-19 * **/ public class GetMessageBodyAction extends AbstractMailAction { MessageHolder mailbox; Message message; ImapAccount mailAccount; public GetMessageBodyAction(MessageHolder mailbox, Message message) { this.mailbox = mailbox; this.message = message; } /* (non-Javadoc) * @see net.sf.mailsomething.mail.MailAction#invoke() */ public void invoke() { if (message.isBodyFetched()) return; mailAccount.getController().selectMailbox(mailbox.getPath()); /** * The following - get index of message could just as well * be implemented in the getbody method. * */ int index = mailAccount.getController().getIndexOfMessage(message.getUID()); if (index == -1) { System.out.println("fetch body index = -1"); return; } mailAccount.getController().getBody(null, index, message, getProgressListener()); message.setBodyFetched(true); } /** * @return */ private ProgressListener getProgressListener() { if(progressListeners.size() > 0 ) return (ProgressListener)progressListeners.elementAt(0); return null; } /* (non-Javadoc) * @see net.sf.mailsomething.mail.MailAction#undo() */ public void undo() { // TODO Auto-generated method stub } /* (non-Javadoc) * @see net.sf.mailsomething.mail.MailAction#setMailAccount(net.sf.mailsomething.mail.MailAccount) */ public void setMailAccount(MailAccount account) { // TODO Auto-generated method stub } /* (non-Javadoc) * @see net.sf.mailsomething.mail.MailAction#addProgressListener(net.sf.mailsomething.util.ProgressListener) */ public void addProgressListener(ProgressListener l) { // TODO Auto-generated method stub } } --- NEW FILE: CreateMailboxAction.java --- package net.sf.mailsomething.mail.actions; import net.sf.mailsomething.mail.Hierachy; import net.sf.mailsomething.mail.ImapAccount; import net.sf.mailsomething.mail.MailAccount; import net.sf.mailsomething.mail.MailAction; import net.sf.mailsomething.mail.parsers.ImapController; import net.sf.mailsomething.util.ProgressListener; /** * @author Stig tanggaard * @since 2005-03-17 * **/ public class CreateMailboxAction implements MailAction { private Hierachy mailbox; private MailAccount mailAccount; private ImapController controller; public CreateMailboxAction(Hierachy mailbox) { this.mailbox = mailbox; } public void addProgressListener(ProgressListener l) { } /* (non-Javadoc) * @see net.sf.mailsomething.mail.MailAction#invoke() */ public void invoke() { if (mailbox.isRemote() == false && mailAccount instanceof ImapAccount) { if (mailbox.isRemote() == false) { if (controller.createMailbox(mailbox.getPath())) mailbox.setRemote(true); } } } /* (non-Javadoc) * @see net.sf.mailsomething.mail.MailAction#undo() */ public void undo() { // TODO Auto-generated method stub } /* (non-Javadoc) * @see net.sf.mailsomething.mail.MailAction#setMailAccount() */ public void setMailAccount(MailAccount account) { } } --- NEW FILE: AbstractMailAction.java --- package net.sf.mailsomething.mail.actions; import java.util.Vector; import net.sf.mailsomething.mail.MailAction; import net.sf.mailsomething.util.ProgressListener; /** * @author Stig tanggaard * @since 2005-03-19 * */ public abstract class AbstractMailAction implements MailAction { protected Vector progressListeners; /** * To add a progresslistener to the mailaccount. A progresslistener recieves * notification of 'work' happening, but with no details about the actual * sort of work. * * @param l */ public void addProgressListener(ProgressListener l) { if (progressListeners == null) progressListeners = new Vector(); progressListeners.add(l); } /** * Use this to notify progresslisteners that work is starting, and the * estimated length of the work happening. * * @param length */ protected void notifyWorkStarted(int length) { if (progressListeners != null) for (int i = 0; i < progressListeners.size(); i++) { ProgressListener l = (ProgressListener) progressListeners .elementAt(i); l.workStarted(length); } } /** * Use this to notify progresslistener of the progress in work happening. * Use notifyWorkStarted before calling this, and notifyWorkedStopped when * the work is finished. * * @param index */ protected void notifyWorkProgress(int index) { if (progressListeners != null) for (int i = 0; i < progressListeners.size(); i++) { ProgressListener l = (ProgressListener) progressListeners .elementAt(i); l.workProgress(index); } } protected void notifyWorkProgress(int index, int length) { if (progressListeners != null) for (int i = 0; i < progressListeners.size(); i++) { ProgressListener l = (ProgressListener) progressListeners .elementAt(i); l.workProgress(index, length); } } /** * To notify progresslistener that the work is stopped. */ protected void notifyWorkStopped() { if (progressListeners != null) for (int i = 0; i < progressListeners.size(); i++) { ProgressListener l = (ProgressListener) progressListeners .elementAt(i); l.workStopped(); } } } --- NEW FILE: CopyMessageAction.java --- package net.sf.mailsomething.mail.actions; import net.sf.mailsomething.mail.ImapAccount; import net.sf.mailsomething.mail.MailAccount; import net.sf.mailsomething.mail.MailAction; import net.sf.mailsomething.mail.Message; import net.sf.mailsomething.mail.MessageHolder; import net.sf.mailsomething.mail.PopAccount; import net.sf.mailsomething.util.ProgressListener; /** * @author Stig tanggaard * @since 2005-03-20 * **/ public class CopyMessageAction implements MailAction { MessageHolder srcMailbox, destMailbox; Message message; ImapAccount mailAccount; PopAccount popAccount; public CopyMessageAction(MessageHolder srcMailbox, MessageHolder destMailbox, Message message) { this.srcMailbox = srcMailbox; this.destMailbox = destMailbox; this.message = message; } public void invoke() { if(mailAccount != null) imapInvoke(); else if(popAccount != null) popInvoke(); } public void popInvoke() { Message clone = (Message) message.clone(); destMailbox.addMessage(clone); //System.out.println("popaccount: clone isremote " + clone.isRemote()); } /* (non-Javadoc) * @see net.sf.mailsomething.mail.MailAction#invoke() */ public void imapInvoke() { //copy the message mailAccount.getController().copyMessage(message.getUID(), srcMailbox.getPath(), destMailbox.getPath()); //clone the message Message copiedMessage = (Message) message.clone(); destMailbox.addMessage(copiedMessage); //in order to change the uid of the message //(since its changed when moved to another mailbox). mailAccount.getController().selectMailbox(destMailbox.getPath()); //this is maybe a bad way to do this, and currently im not //sure the uid value is used at all. int exists = mailAccount.getController().getExists(); String uid = mailAccount.getController().getUid(exists); copiedMessage.setUID(uid); } /* (non-Javadoc) * @see net.sf.mailsomething.mail.MailAction#undo() */ public void undo() { // TODO Auto-generated method stub } /* (non-Javadoc) * @see net.sf.mailsomething.mail.MailAction#setMailAccount(net.sf.mailsomething.mail.MailAccount) */ public void setMailAccount(MailAccount account) { if(account instanceof ImapAccount) mailAccount = (ImapAccount)account; else if(account instanceof PopAccount) popAccount = (PopAccount)account; } /* (non-Javadoc) * @see net.sf.mailsomething.mail.MailAction#addProgressListener(net.sf.mailsomething.util.ProgressListener) */ public void addProgressListener(ProgressListener l) { // TODO Auto-generated method stub } } --- NEW FILE: StoreMessageAction.java --- package net.sf.mailsomething.mail.actions; import net.sf.mailsomething.mail.ImapAccount; import net.sf.mailsomething.mail.MailAccount; import net.sf.mailsomething.mail.MailAction; import net.sf.mailsomething.mail.Message; import net.sf.mailsomething.mail.MessageHolder; import net.sf.mailsomething.util.ProgressListener; /** * @author Stig tanggaard * @since 2005-03-19 * **/ public class StoreMessageAction implements MailAction { private ImapAccount mailAccount; private Message message; private MessageHolder mailbox; public StoreMessageAction(MessageHolder mailbox, Message message) { this.mailbox = mailbox; this.message = message; } /* (non-Javadoc) * @see net.sf.mailsomething.mail.MailAction#invoke() */ public void invoke() { if (message.isRemote()) { mailAccount.getController().deleteMessage(mailbox.getPath(), message.getUID()); message.setRemote(false); } mailAccount.getController().appendMessage(message, mailbox.getPath()); message.setRemote(true); } /* (non-Javadoc) * @see net.sf.mailsomething.mail.MailAction#undo() */ public void undo() { // TODO Auto-generated method stub } /* (non-Javadoc) * @see net.sf.mailsomething.mail.MailAction#setMailAccount(net.sf.mailsomething.mail.MailAccount) */ public void setMailAccount(MailAccount account) { if(account instanceof ImapAccount) mailAccount = (ImapAccount)account; } /* (non-Javadoc) * @see net.sf.mailsomething.mail.MailAction#addProgressListener(net.sf.mailsomething.util.ProgressListener) */ public void addProgressListener(ProgressListener l) { // TODO Auto-generated method stub } } --- NEW FILE: DeleteMailboxAction.java --- package net.sf.mailsomething.mail.actions; import net.sf.mailsomething.mail.ImapAccount; import net.sf.mailsomething.mail.MailAccount; import net.sf.mailsomething.mail.MailAction; import net.sf.mailsomething.mail.Mailbox; import net.sf.mailsomething.mail.MailboxHolder; import net.sf.mailsomething.mail.PopAccount; import net.sf.mailsomething.util.ProgressListener; /** * @author Stig tanggaard * @since 2005-03-19 * **/ public class DeleteMailboxAction implements MailAction { Mailbox mailbox; MailboxHolder parent; ImapAccount mailAccount; PopAccount popAccount; public DeleteMailboxAction(MailboxHolder parent, Mailbox todelete) { } /* (non-Javadoc) * @see net.sf.mailsomething.mail.MailAction#invoke() */ public void invoke() { if(mailAccount != null) imapInvoke(); else if(popAccount != null) popInvoke(); } public void popInvoke() { if (mailbox.getParent() != null) { if (mailbox.getParent().equals("")) { popAccount.removeMailbox(mailbox); } else { MailboxHolder parent = mailbox.getParentMailbox(); parent.removeMailbox(mailbox); } } else { String path = mailbox.getPath(); Mailbox parent = popAccount.getMailbox( mailbox.getPath().substring( 0, mailbox.getPath().lastIndexOf( popAccount.getDelimiter()))); parent.removeMailbox(mailbox); } } /* (non-Javadoc) * @see net.sf.mailsomething.mail.MailAction#invoke() */ public void imapInvoke() { if (mailbox.isRemote() == true) { //we only delete the mailbox if the command returns true if (mailAccount.getController().deleteMailbox(mailbox.getPath())) { mailbox.setRemote(false); parent.removeMailbox(mailbox); } } else { if (parent != null) //maybe one could do a checkup here, to see if there exists //a mailbox with that name at server (which means remote //is actual true. parent.removeMailbox(mailbox); } } /* (non-Javadoc) * @see net.sf.mailsomething.mail.MailAction#undo() */ public void undo() { // TODO Auto-generated method stub } /* (non-Javadoc) * @see net.sf.mailsomething.mail.MailAction#setMailAccount(net.sf.mailsomething.mail.MailAccount) */ public void setMailAccount(MailAccount account) { if(account instanceof ImapAccount) { mailAccount = (ImapAccount)account; } } /* (non-Javadoc) * @see net.sf.mailsomething.mail.MailAction#addProgressListener(net.sf.mailsomething.util.ProgressListener) */ public void addProgressListener(ProgressListener l) { // TODO Auto-generated method stub } } --- NEW FILE: DeleteMessageAction.java --- package net.sf.mailsomething.mail.actions; import net.sf.mailsomething.mail.ImapAccount; import net.sf.mailsomething.mail.MailAccount; import net.sf.mailsomething.mail.MailAction; import net.sf.mailsomething.mail.Mailbox; import net.sf.mailsomething.mail.Message; import net.sf.mailsomething.mail.MessageHolder; import net.sf.mailsomething.mail.PopAccount; import net.sf.mailsomething.mail.parsers.ImapController; import net.sf.mailsomething.mail.parsers.PopController; import net.sf.mailsomething.util.ProgressListener; /** * @author Stig tanggaard * @since 2005-03-17 * */ public class DeleteMessageAction implements MailAction { private MailAccount mailAccount; private MessageHolder mailbox; private Message message; private ImapController controller; private PopController popControll; /** * */ public DeleteMessageAction(MessageHolder mailbox, Message message) { this.mailbox = mailbox; this.message = message; // TODO Auto-generated constructor stub } /* * (non-Javadoc) * * @see net.sf.mailsomething.mail.MailAction#invoke() */ public void invoke() { if (mailAccount instanceof PopAccount) { pop3Invoke(); } else if(mailAccount instanceof ImapAccount) { imapInvoke(); } } /* * (non-Javadoc) * * @see net.sf.mailsomething.mail.MailAction#undo() */ public void undo() { // TODO Auto-generated method stub } /* * (non-Javadoc) * * @see net.sf.mailsomething.mail.MailAction#setMailAccount() */ public void setMailAccount(MailAccount account) { mailAccount = account; if(account instanceof PopAccount) { popControll = ((PopAccount)account).getController(); } else if(account instanceof ImapAccount) { controller = ((ImapAccount)account).getController(); } } public void addProgressListener(ProgressListener l) { } private void imapInvoke() { if (message.isRemote()) { controller.deleteMessage(mailbox.getPath(), message.getUID()); message.setRemote(false); mailbox.removeMessage(message); if(mailAccount.getStandardMailbox(Mailbox.TRASH) != null && mailAccount.getStandardMailbox(Mailbox.TRASH) != mailbox) { message.clearFlag(Message.DELETED); mailAccount.getStandardMailbox(Mailbox.TRASH).addMessage(message); } } else { //this should never be called, since this method is called //as a response to a request by a mailbox. The mailbox should //not send such a request if the message is not remote. mailbox.removeMessage(message); } } private void pop3Invoke() { //this is a stupid way to decide this. if (!mailbox.isRemote()) { MessageHolder trash = mailAccount.getStandardMailbox(Mailbox.TRASH); if (trash == null) return; //should have a public field TRASH with name of mailbox //and a boolean value: deleteFully if (mailbox.equals(trash)) { //here should be a check, if the setting //deleteWhenDeletedFromTrash //is true, and if so, check if the message exists //at server, and then delete it. return; } else { trash.addMessage(message); return; } } else { String myUID = message.getUID(); //get the uid-markers (uidmarker = uid + index) PopController.UIDMarker[] uids = popControll.searchUid(); for (int i = 0; i < uids.length; i++) { //System.out.println(uids[i]); if (uids[i] != null) { if (uids[i].getUID().equals(myUID)) popControll.deleteMessage(uids[i].getIndex()); } } message.setRemote(false); mailbox.removeMessage(message); MessageHolder trash = mailAccount.getStandardMailbox(Mailbox.TRASH); if (trash != null) trash.addMessage(message); } } } --- NEW FILE: UpdateMailboxesAction.java --- package net.sf.mailsomething.mail.actions; import net.sf.mailsomething.mail.ImapAccount; import net.sf.mailsomething.mail.MailAccount; import net.sf.mailsomething.mail.Mailbox; import net.sf.mailsomething.mail.MailboxHolder; import net.sf.mailsomething.mail.parsers.ImapController; /** * @author Stig tanggaard * @since 2005-03-20 * **/ public class UpdateMailboxesAction extends AbstractMailAction { private MailboxHolder rootMailbox; private ImapAccount mailAccount; private int workProgress; /** * */ public UpdateMailboxesAction(MailboxHolder root) { rootMailbox = root; // TODO Auto-generated constructor stub } /* (non-Javadoc) * @see net.sf.mailsomething.mail.MailAction#invoke() */ public void invoke() { updateMailboxes(rootMailbox); notifyWorkStopped(); } /* (non-Javadoc) * @see net.sf.mailsomething.mail.MailAction#invoke() */ public void updateMailboxes(MailboxHolder mailbox) { if (workProgress == 0) notifyWorkStarted(-1); String[] mailboxNames; ImapController.MailboxListResult result = mailAccount.getController().listMailboxes(mailbox.getPath()); /**for synchronization purposes; first set all to local, then get * all at server, * and if a mailbox isnt at server it keeps the local value */ Mailbox[] currentMailboxes = mailbox.getMailboxes(); /** * This just seem like plain bad design. Maybe we should * check the mailboxes against the mailboxnames recieved * from server, instead. * */ if (currentMailboxes != null) { for (int i = 0; i < currentMailboxes.length; i++) { boolean exists = false; for (int j = 0; j < result.getMailboxNames().length; j++) { if (result .getMailboxNames()[j] .equals(currentMailboxes[i].getName())) { exists = true; break; } } //if the mailbox allready exists, based on name //comparison, set it to remote (just to be sure) if (exists) currentMailboxes[i].setRemote(true); //if it doesnt exists, try create it else { if (mailAccount.getController() .createMailbox(currentMailboxes[i].getPath())) currentMailboxes[i].setRemote(true); else currentMailboxes[i].setRemote(false); } } } workProgress += result.getMailboxNames().length; notifyWorkProgress(workProgress); //notify for (int i = 0; i < result.getMailboxNames().length; i++) { //this is a check for the returned name. I am doing this //here coz I have some problem with an imapd which returns //the name of the mailbox and a delimiter from a listcommand, ie //C: LIST "" mailboxname/% //S: LIST (\NoSelect) "/" mailboxname/ //which I just dont understand :) if (result.getMailboxNames()[i].trim().equals("") || result.getMailboxNames()[i].trim().equals("/")) continue; //System.out.println("+" + result.getMailboxNames()[i] + "+"); if (mailbox.getMailbox(result.getMailboxNames()[i]) == null) { //System.out.println(mailboxNames[i]); Mailbox n = new Mailbox(result.getMailboxNames()[i], mailAccount); n = mailbox.addMailbox(n); if (n != null) { n.setRemote(true); //if the mailboxname starts with a . we assume its hidden //and we wont get the mailboxes in this mailbox. if (result.getMailboxNames()[i].startsWith(".")) { n.setState(n.getState() | Mailbox.HIDDEN); } else { /** * If this mailbox has children we create a * request to update this new mailbox. * */ if (result.hasChildren(i)) { /*Request rr = new Request(Request.UPDATE_MAILBOXES, n, null); rr.setDismissable(r.isDismissable());*/ updateMailboxes(n); } } } } } //notifyWorkStopped(); } /* (non-Javadoc) * @see net.sf.mailsomething.mail.MailAction#undo() */ public void undo() { // No implementation here, u cannot redo an update } /* (non-Javadoc) * @see net.sf.mailsomething.mail.MailAction#setMailAccount(net.sf.mailsomething.mail.MailAccount) */ public void setMailAccount(MailAccount account) { if(account instanceof ImapAccount) mailAccount = (ImapAccount)account; } } --- NEW FILE: MoveMailboxAction.java --- package net.sf.mailsomething.mail.actions; import net.sf.mailsomething.mail.ImapAccount; import net.sf.mailsomething.mail.MailAccount; import net.sf.mailsomething.mail.MailAction; import net.sf.mailsomething.mail.Mailbox; import net.sf.mailsomething.mail.MailboxHolder; import net.sf.mailsomething.util.ProgressListener; /** * @author Stig tanggaard * @since 2005-03-19 * **/ public class MoveMailboxAction implements MailAction { private char delimiter = '/'; Mailbox toMove; MailboxHolder target; ImapAccount mailAccount; /* (non-Javadoc) * @see net.sf.mailsomething.mail.MailAction#invoke() */ public void invoke() { MailboxHolder source = toMove.getParentMailbox(); if (toMove.isRemote()) { if (mailAccount.getController() .renameMailbox( toMove.getPath(), target.getPath() + delimiter + toMove.getName())) { toMove.setParent(target.getPath()); source.removeMailbox(toMove); } else { source.removeMailbox(toMove); } } } /* (non-Javadoc) * @see net.sf.mailsomething.mail.MailAction#undo() */ public void undo() { // TODO Auto-generated method stub } /* (non-Javadoc) * @see net.sf.mailsomething.mail.MailAction#setMailAccount(net.sf.mailsomething.mail.MailAccount) */ public void setMailAccount(MailAccount account) { // TODO Auto-generated method stub } /* (non-Javadoc) * @see net.sf.mailsomething.mail.MailAction#addProgressListener(net.sf.mailsomething.util.ProgressListener) */ public void addProgressListener(ProgressListener l) { // TODO Auto-generated method stub } } --- NEW FILE: RenameMailboxAction.java --- package net.sf.mailsomething.mail.actions; import net.sf.mailsomething.mail.ImapAccount; import net.sf.mailsomething.mail.MailAccount; import net.sf.mailsomething.mail.MailAction; import net.sf.mailsomething.mail.Mailbox; import net.sf.mailsomething.util.ProgressListener; /** * @author Stig tanggaard * @since 2005-03-20 * **/ public class RenameMailboxAction implements MailAction { Mailbox mailbox; String nPath, nName; ImapAccount mailAccount; public RenameMailboxAction(Mailbox mailbox, String nName) { this.mailbox = mailbox; this.nName = nName; this.nPath = mailbox.getParentMailbox().getPath() + '/' + nName; } /* (non-Javadoc) * @see net.sf.mailsomething.mail.MailAction#invoke() */ public void invoke() { int selectResult = mailAccount.getController().selectMailbox(mailbox.getPath()); /** * Check if we can select the old mailbox. If we cant * select it, there is something wrong (mailbox doesnt * exists or similar). * */ if (selectResult == -1) { selectResult = mailAccount.getController().selectMailbox(nPath); if (selectResult == 1) { //we can select the new mailbox, everything is //then fine return; } //we cant select the new, we cant select the old //we have a problem... TODO return; } selectResult = mailAccount.getController().selectMailbox(nPath); if (selectResult == 1) { //we can select the old mailbox, and we can //select the new mailbox, ie, a rename cant be done /*String oldname = oldpath.substring(oldpath.lastIndexOf(delimiter) + 1); m.rename(oldname);*/ //TODO: should fetch the new mailbox. Or check if it //allready exists. return; } //if theres an error renaming, we revert the name. if (mailAccount.getController().renameMailbox(mailbox.getPath(), nPath)) { mailbox.rename(nName); } } /* (non-Javadoc) * @see net.sf.mailsomething.mail.MailAction#undo() */ public void undo() { // TODO Auto-generated method stub } /* (non-Javadoc) * @see net.sf.mailsomething.mail.MailAction#setMailAccount(net.sf.mailsomething.mail.MailAccount) */ public void setMailAccount(MailAccount account) { // TODO Auto-generated method stub } /* (non-Javadoc) * @see net.sf.mailsomething.mail.MailAction#addProgressListener(net.sf.mailsomething.util.ProgressListener) */ public void addProgressListener(ProgressListener l) { // TODO Auto-generated method stub } } --- NEW FILE: AppendMessageAction.java --- package net.sf.mailsomething.mail.actions; import net.sf.mailsomething.mail.ImapAccount; import net.sf.mailsomething.mail.MailAccount; import net.sf.mailsomething.mail.MailAction; import net.sf.mailsomething.mail.Message; import net.sf.mailsomething.mail.MessageHolder; import net.sf.mailsomething.util.ProgressListener; /** * @author Stig tanggaard * @since 2005-03-19 * **/ public class AppendMessageAction implements MailAction { private Message message; private MessageHolder mailbox; private ImapAccount mailAccount; /** * */ public AppendMessageAction(MessageHolder mailbox, Message message) { this.mailbox = mailbox; this.message = message; } /* (non-Javadoc) * @see net.sf.mailsomething.mail.MailAction#invoke() */ public void invoke() { //Message message = mailbox.getMessage(messageid); if (message != null) { message.setRemote(true); mailAccount.getController().appendMessage(message, mailbox.getPath()); } } /* (non-Javadoc) * @see net.sf.mailsomething.mail.MailAction#undo() */ public void undo() { // TODO Auto-generated method stub } /* (non-Javadoc) * @see net.sf.mailsomething.mail.MailAction#setMailAccount(net.sf.mailsomething.mail.MailAccount) */ public void setMailAccount(MailAccount account) { if(account instanceof ImapAccount) { mailAccount = (ImapAccount)account; } } /* (non-Javadoc) * @see net.sf.mailsomething.mail.MailAction#addProgressListener(net.sf.mailsomething.util.ProgressListener) */ public void addProgressListener(ProgressListener l) { // TODO Auto-generated method stub } } |