001: //The contents of this file are subject to the Mozilla Public License Version 1.1
002: //(the "License"); you may not use this file except in compliance with the
003: //License. You may obtain a copy of the License at http://www.mozilla.org/MPL/
004: //
005: //Software distributed under the License is distributed on an "AS IS" basis,
006: //WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
007: //for the specific language governing rights and
008: //limitations under the License.
009: //
010: //The Original Code is "The Columba Project"
011: //
012: //The Initial Developers of the Original Code are Frederik Dietz and Timo
013: // Stich.
014: //Portions created by Frederik Dietz and Timo Stich are Copyright (C) 2003.
015: //
016: //All Rights Reserved.
017:
018: package org.columba.mail.spam.command;
019:
020: import java.io.IOException;
021: import java.util.ArrayList;
022:
023: import org.columba.api.command.ICommandReference;
024: import org.columba.api.command.IWorkerStatusController;
025: import org.columba.core.command.Command;
026: import org.columba.core.command.StatusObservableImpl;
027: import org.columba.core.logging.Logging;
028: import org.columba.mail.command.IMailFolderCommandReference;
029: import org.columba.mail.command.MailFolderCommandReference;
030: import org.columba.mail.config.AccountItem;
031: import org.columba.mail.filter.plugins.AddressbookFilter;
032: import org.columba.mail.folder.IMailbox;
033: import org.columba.mail.folder.command.MarkMessageCommand;
034: import org.columba.mail.spam.SpamController;
035:
036: /**
037: * Score selected messages as spam, meaning calculate the likelyhood that the
038: * message is spam.
039: *
040: * @author fdietz
041: */
042: public class ScoreMessageCommand extends Command {
043:
044: private Object[] uids;
045:
046: private IMailbox srcFolder;
047:
048: private MarkMessageCommand markAsSpamCommand;
049:
050: private MarkMessageCommand markAsNotSpamCommand;
051:
052: /**
053: * @param references
054: */
055: public ScoreMessageCommand(ICommandReference reference) {
056: super (reference);
057: }
058:
059: public void updateGUI() throws Exception {
060: // update table
061: if (markAsSpamCommand != null) {
062: markAsSpamCommand.updateGUI();
063: }
064: if (markAsNotSpamCommand != null) {
065: markAsNotSpamCommand.updateGUI();
066: }
067: }
068:
069: /**
070: * @see org.columba.api.command.Command#execute(org.columba.api.command.Worker)
071: */
072: public void execute(IWorkerStatusController worker)
073: throws Exception {
074: // get source reference
075: IMailFolderCommandReference r = (IMailFolderCommandReference) getReference();
076:
077: // get array of message UIDs
078: uids = r.getUids();
079:
080: // get source folder
081: srcFolder = (IMailbox) r.getSourceFolder();
082:
083: // register for status events
084: ((StatusObservableImpl) srcFolder.getObservable())
085: .setWorker(worker);
086:
087: // update status message
088: // TODO (@author fdietz): i18n
089: worker.setDisplayText("Scoring messages ...");
090: worker.setProgressBarMaximum(uids.length);
091:
092: ArrayList spamList = new ArrayList();
093: ArrayList nonspamList = new ArrayList();
094:
095: for (int j = 0; j < uids.length; j++) {
096: if (worker.cancelled()) {
097: return;
098: }
099:
100: try {
101:
102: // score message
103: boolean result = scoreMessage(j);
104:
105: // if message is spam
106: if (result) {
107: // mark message as spam
108: spamList.add(uids[j]);
109: } else {
110: // mark message as *not* spam
111: nonspamList.add(uids[j]);
112: }
113:
114: // train message as spam or non spam
115: trainMessage(j, result);
116:
117: worker.setProgressBarValue(j);
118:
119: if (worker.cancelled()) {
120: break;
121: }
122: } catch (Exception e) {
123: if (Logging.DEBUG) {
124: e.printStackTrace();
125: }
126: }
127: }
128:
129: // mark spam messages
130: if (spamList.size() != 0) {
131: MailFolderCommandReference ref = new MailFolderCommandReference(
132: srcFolder, spamList.toArray());
133: ref.setMarkVariant(MarkMessageCommand.MARK_AS_SPAM);
134: markAsSpamCommand = new MarkMessageCommand(ref);
135: markAsSpamCommand.execute(worker);
136: }
137:
138: // mark non spam messages
139: if (nonspamList.size() != 0) {
140: MailFolderCommandReference ref = new MailFolderCommandReference(
141: srcFolder, nonspamList.toArray());
142: ref.setMarkVariant(MarkMessageCommand.MARK_AS_NOTSPAM);
143: markAsNotSpamCommand = new MarkMessageCommand(ref);
144: markAsNotSpamCommand.execute(worker);
145: }
146:
147: }
148:
149: /**
150: * Score message, meaning decide if message is spam or non spam.
151: *
152: * @param j
153: * message UID index
154: * @return true, if spam. False, otherwise.
155: * @throws Exception
156: * @throws IOException
157: */
158: private boolean scoreMessage(int j) throws Exception, IOException {
159:
160: // calculate message score
161: boolean result = SpamController.getInstance().scoreMessage(
162: srcFolder, uids[j]);
163:
164: // message belongs to which account?
165: AccountItem item = CommandHelper.retrieveAccountItem(srcFolder,
166: uids[j]);
167:
168: if (item.getSpamItem().checkAddressbook()) {
169: // check if sender is already in addressbook
170: boolean isInAddressbook = new AddressbookFilter().process(
171: srcFolder, uids[j]);
172: result = result && !isInAddressbook;
173: }
174:
175: return result;
176: }
177:
178: /**
179: * Train selected message as spam or non spam.
180: *
181: * @param j
182: * UID index
183: * @param result
184: * true, if spam. False, otherwise.
185: * @throws Exception
186: */
187: private void trainMessage(int j, boolean result) throws Exception {
188:
189: // add this message to frequency database
190: if (result) {
191: SpamController.getInstance().trainMessageAsSpam(srcFolder,
192: uids[j]);
193: } else {
194: SpamController.getInstance().trainMessageAsHam(srcFolder,
195: uids[j]);
196: }
197:
198: }
199: }
|