001: // The contents of this file are subject to the Mozilla Public License Version
002: //1.1
003: //(the "License"); you may not use this file except in compliance with the
004: //License. You may obtain a copy of the License at http://www.mozilla.org/MPL/
005: //
006: //Software distributed under the License is distributed on an "AS IS" basis,
007: //WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
008: //for the specific language governing rights and
009: //limitations under the License.
010: //
011: //The Original Code is "The Columba Project"
012: //
013: //The Initial Developers of the Original Code are Frederik Dietz and Timo
014: //Stich.
015: //Portions created by Frederik Dietz and Timo Stich are Copyright (C) 2003.
016: //
017: //All Rights Reserved.
018: package org.columba.mail.folder.command;
019:
020: import java.util.ArrayList;
021: import java.util.List;
022:
023: import org.columba.api.command.ICommand;
024: import org.columba.api.command.ICommandReference;
025: import org.columba.api.command.IWorkerStatusController;
026: import org.columba.core.command.Command;
027: import org.columba.core.command.CommandProcessor;
028: import org.columba.core.command.StatusObservableImpl;
029: import org.columba.core.command.Worker;
030: import org.columba.mail.command.IMailFolderCommandReference;
031: import org.columba.mail.command.MailFolderCommandReference;
032: import org.columba.mail.config.AccountItem;
033: import org.columba.mail.folder.IMailFolder;
034: import org.columba.mail.folder.IMailbox;
035: import org.columba.mail.folder.RootFolder;
036: import org.columba.mail.gui.tree.FolderTreeModel;
037: import org.columba.mail.spam.command.CommandHelper;
038: import org.columba.mail.spam.command.LearnMessageAsHamCommand;
039: import org.columba.mail.spam.command.LearnMessageAsSpamCommand;
040: import org.columba.ristretto.message.Flags;
041:
042: /**
043: * Toggle flag.
044: * <p>
045: * Creates two sets of messages and uses {@link MarkMessageCommand}, which does
046: * the flag change.
047: * <p>
048: * Additionally, if message is marked as spam or non-spam the bayesian filter is
049: * trained.
050: *
051: * @see MarkMessageCommand
052: * @author fdietz
053: */
054: public class ToggleMarkCommand extends Command {
055:
056: private static final java.util.logging.Logger LOG = java.util.logging.Logger
057: .getLogger("org.columba.mail.folder.command"); //$NON-NLS-1$
058:
059: private IWorkerStatusController worker;
060:
061: private List<MarkMessageCommand> commandList;
062:
063: /**
064: * Constructor for ToggleMarkCommand.
065: *
066: * @param frameMediator
067: * @param references
068: */
069: public ToggleMarkCommand(ICommandReference reference) {
070: super (reference);
071:
072: commandList = new ArrayList<MarkMessageCommand>();
073: }
074:
075: /**
076: * @see org.columba.api.command.Command#execute(Worker)
077: */
078: public void execute(IWorkerStatusController worker)
079: throws Exception {
080: this .worker = worker;
081:
082: /*
083: * // use wrapper class for easier handling of references array adapter =
084: * new FolderCommandAdapter( (MailFolderCommandReference[])
085: * getReferences());
086: * // get array of source references MailFolderCommandReference[] r =
087: * adapter.getSourceFolderReferences();
088: */
089: IMailFolderCommandReference r = (IMailFolderCommandReference) getReference();
090:
091: // get array of message UIDs
092: Object[] uids = r.getUids();
093:
094: // get source folder
095: IMailbox srcFolder = (IMailbox) r.getSourceFolder();
096:
097: // register for status events
098: ((StatusObservableImpl) srcFolder.getObservable())
099: .setWorker(worker);
100:
101: // which kind of mark?
102: int markVariant = r.getMarkVariant();
103:
104: // create one list containing the marked items, which have to be "unmarked"
105: // and another list containing the items remained to be marked
106: List<Object> list1 = new ArrayList<Object>();
107: List<Object> list2 = new ArrayList<Object>();
108:
109: for (int j = 0; j < uids.length; j++) {
110: Flags flags = srcFolder.getFlags(uids[j]);
111:
112: boolean result = false;
113: if (markVariant == MarkMessageCommand.MARK_AS_READ) {
114: if (flags.getSeen())
115: result = true;
116: } else if (markVariant == MarkMessageCommand.MARK_AS_FLAGGED) {
117: if (flags.getFlagged())
118: result = true;
119: } else if (markVariant == MarkMessageCommand.MARK_AS_EXPUNGED) {
120: if (flags.getDeleted())
121: result = true;
122: } else if (markVariant == MarkMessageCommand.MARK_AS_ANSWERED) {
123: if (flags.getAnswered())
124: result = true;
125: } else if (markVariant == MarkMessageCommand.MARK_AS_DRAFT) {
126: if (flags.getDraft())
127: result = true;
128: } else if (markVariant == MarkMessageCommand.MARK_AS_SPAM) {
129: boolean spam = ((Boolean) srcFolder.getAttribute(
130: uids[j], "columba.spam")).booleanValue();
131: if (spam)
132: result = true;
133: }
134:
135: if (result)
136: list1.add(uids[j]);
137: else
138: list2.add(uids[j]);
139: }
140:
141: MailFolderCommandReference ref = null;
142:
143: // un-mark messages
144: if (list1.size() > 0) {
145: ref = new MailFolderCommandReference(srcFolder, list1
146: .toArray());
147: ref.setMarkVariant(-markVariant);
148: MarkMessageCommand c = new MarkMessageCommand(ref);
149: commandList.add(c);
150: c.execute(worker);
151:
152: // train bayesian filter
153: if ((markVariant == MarkMessageCommand.MARK_AS_SPAM)
154: || (markVariant == MarkMessageCommand.MARK_AS_NOTSPAM)) {
155: processSpamFilter(uids, srcFolder, -markVariant);
156: }
157: }
158:
159: // mark messages
160: if (list2.size() > 0) {
161: ref = new MailFolderCommandReference(srcFolder, list2
162: .toArray());
163: ref.setMarkVariant(markVariant);
164: MarkMessageCommand c = new MarkMessageCommand(ref);
165: commandList.add(c);
166: c.execute(worker);
167:
168: // train bayesian filter
169: if ((markVariant == MarkMessageCommand.MARK_AS_SPAM)
170: || (markVariant == MarkMessageCommand.MARK_AS_NOTSPAM)) {
171: processSpamFilter(uids, srcFolder, markVariant);
172: }
173: }
174:
175: }
176:
177: /**
178: * Train spam filter.
179: * <p>
180: * Move message to specified folder or delete message immediately based on
181: * account configuration.
182: *
183: * @param uids
184: * message uid
185: * @param srcFolder
186: * source folder
187: * @param markVariant
188: * mark variant (spam/not spam)
189: * @throws Exception
190: */
191: private void processSpamFilter(Object[] uids, IMailbox srcFolder,
192: int markVariant) throws Exception {
193:
194: // update status message
195: worker.setDisplayText("Training messages...");
196: worker.setProgressBarMaximum(uids.length);
197:
198: // mark as spam /as not spam
199: // for each message
200: for (int j = 0; j < uids.length; j++) {
201:
202: worker.setDisplayText("Training messages...");
203: worker.setProgressBarMaximum(uids.length);
204: // increase progressbar value
205: worker.setProgressBarValue(j);
206:
207: // cancel here if user requests
208: if (worker.cancelled()) {
209: break;
210: }
211:
212: // message belongs to which account?
213: AccountItem item = CommandHelper.retrieveAccountItem(
214: srcFolder, uids[j]);
215: // skip if account information is not available
216: if (item == null)
217: continue;
218:
219: // if spam filter is not enabled -> return
220: if (item.getSpamItem().isEnabled() == false)
221: continue;
222:
223: LOG.info("learning uid=" + uids[j]); //$NON-NLS-1$
224:
225: // create reference
226: IMailFolderCommandReference ref = new MailFolderCommandReference(
227: srcFolder, new Object[] { uids[j] });
228:
229: // create command
230: ICommand c = null;
231: if (markVariant == MarkMessageCommand.MARK_AS_SPAM)
232: c = new LearnMessageAsSpamCommand(ref);
233: else
234: c = new LearnMessageAsHamCommand(ref);
235:
236: // execute command
237: c.execute(worker);
238:
239: // skip if message is *not* marked as spam
240: if (markVariant == MarkMessageCommand.MARK_AS_NOTSPAM)
241: continue;
242:
243: // skip if user didn't enable this option
244: if (item.getSpamItem().isMoveMessageWhenMarkingEnabled() == false)
245: continue;
246:
247: if (item.getSpamItem().isMoveTrashSelected() == false) {
248: // move message to user-configured folder (generally "Junk"
249: // folder)
250: IMailFolder destFolder = FolderTreeModel.getInstance()
251: .getFolder(
252: item.getSpamItem()
253: .getMoveCustomFolder());
254:
255: // create reference
256: MailFolderCommandReference ref2 = new MailFolderCommandReference(
257: srcFolder, destFolder, new Object[] { uids[j] });
258: CommandProcessor.getInstance().addOp(
259: new MoveMessageCommand(ref2));
260:
261: } else {
262: // move message to trash
263: IMailbox trash = (IMailbox) ((RootFolder) srcFolder
264: .getRootFolder()).getTrashFolder();
265:
266: // create reference
267: MailFolderCommandReference ref2 = new MailFolderCommandReference(
268: srcFolder, trash, new Object[] { uids[j] });
269:
270: CommandProcessor.getInstance().addOp(
271: new MoveMessageCommand(ref2));
272:
273: }
274:
275: }
276: }
277: }
|