001: /*
002: * NewsGroupSummary.java
003: *
004: * Copyright (C) 2000-2003 Peter Graves
005: * $Id: NewsGroupSummary.java,v 1.10 2003/06/25 18:38:53 piso Exp $
006: *
007: * This program is free software; you can redistribute it and/or
008: * modify it under the terms of the GNU General Public License
009: * as published by the Free Software Foundation; either version 2
010: * of the License, or (at your option) any later version.
011: *
012: * This program is distributed in the hope that it will be useful,
013: * but WITHOUT ANY WARRANTY; without even the implied warranty of
014: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
015: * GNU General Public License for more details.
016: *
017: * You should have received a copy of the GNU General Public License
018: * along with this program; if not, write to the Free Software
019: * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
020: */
021:
022: package org.armedbear.j.mail;
023:
024: import java.io.BufferedWriter;
025: import java.io.IOException;
026: import java.io.OutputStreamWriter;
027: import java.util.HashMap;
028: import java.util.Vector;
029: import javax.swing.Icon;
030: import javax.swing.SwingUtilities;
031: import org.armedbear.j.Editor;
032: import org.armedbear.j.EditorIterator;
033: import org.armedbear.j.FastStringBuffer;
034: import org.armedbear.j.FastStringReader;
035: import org.armedbear.j.File;
036: import org.armedbear.j.InputDialog;
037: import org.armedbear.j.Line;
038: import org.armedbear.j.Log;
039: import org.armedbear.j.MessageDialog;
040: import org.armedbear.j.Position;
041: import org.armedbear.j.ProgressNotifier;
042: import org.armedbear.j.StatusBarProgressNotifier;
043: import org.armedbear.j.Utilities;
044: import org.armedbear.j.View;
045:
046: public final class NewsGroupSummary extends Mailbox {
047: private final NntpSession session;
048: private final String groupName;
049: private final HashMap map = new HashMap();
050:
051: private ProgressNotifier progressNotifier;
052: private String errorText;
053: private int numberToGet;
054:
055: public NewsGroupSummary(NntpSession session, String groupName) {
056: super ();
057: this .session = session;
058: this .groupName = groupName;
059: supportsUndo = false;
060: type = TYPE_MAILBOX;
061: mode = NewsGroupSummaryMode.getMode();
062: formatter = mode.getFormatter(this );
063: readOnly = true;
064: title = groupName;
065: progressNotifier = new StatusBarProgressNotifier(this );
066: setInitialized(true);
067: }
068:
069: public final NntpSession getSession() {
070: return session;
071: }
072:
073: public final String getName() {
074: return groupName;
075: }
076:
077: public int load() {
078: setBusy(true);
079: new Thread(loadRunnable).start();
080: setLoaded(true);
081: return LOAD_COMPLETED;
082: }
083:
084: private Runnable loadRunnable = new Runnable() {
085: public void run() {
086: if (!session.connect()) {
087: errorText = session.getErrorText();
088: SwingUtilities.invokeLater(errorRunnable);
089: return;
090: }
091: if (!selectGroup()) {
092: errorText = "No group \"" + groupName + '\"';
093: SwingUtilities.invokeLater(errorRunnable);
094: return;
095: }
096: final int count = session.getCount();
097: if (count == 0) {
098: errorText = "No articles";
099: SwingUtilities.invokeLater(errorRunnable);
100: return;
101: }
102: if (count > 100) {
103: Runnable confirmRunnable = new Runnable() {
104: public void run() {
105: Editor editor = Editor.currentEditor();
106: editor.setDefaultCursor();
107: String prompt = "How many headers would you like?";
108: String defaultValue = String.valueOf(count);
109: String response = InputDialog
110: .showInputDialog(editor, prompt,
111: groupName, defaultValue);
112: editor.setWaitCursor();
113: numberToGet = 0;
114: if (response != null && response.length() > 0) {
115: try {
116: numberToGet = Integer
117: .parseInt(response);
118: } catch (NumberFormatException e) {
119: Log.error(e);
120: }
121: }
122: }
123: };
124: try {
125: SwingUtilities.invokeAndWait(confirmRunnable);
126: } catch (Exception e) {
127: Log.error(e);
128: }
129: } else
130: numberToGet = count;
131: if (numberToGet == 0) {
132: SwingUtilities.invokeLater(errorRunnable);
133: return;
134: }
135: getHeaders();
136: if (entries != null && entries.size() > 0) {
137: addEntriesToBuffer();
138: SwingUtilities.invokeLater(updateDisplayRunnable);
139: } else {
140: errorText = "No articles";
141: SwingUtilities.invokeLater(errorRunnable);
142: }
143: }
144: };
145:
146: private Runnable updateDisplayRunnable = new Runnable() {
147: public void run() {
148: setBusy(false);
149: invalidate();
150: for (EditorIterator it = new EditorIterator(); it.hasNext();) {
151: Editor ed = it.nextEditor();
152: if (ed.getBuffer() == NewsGroupSummary.this ) {
153: ed.setDot(getInitialDotPos());
154: ed.moveCaretToDotCol();
155: ed.setTopLine(getFirstLine());
156: ed.setUpdateFlag(REPAINT);
157: ed.updateDisplay();
158: }
159: }
160: }
161: };
162:
163: private Runnable errorRunnable = new Runnable() {
164: public void run() {
165: Editor editor = Editor.currentEditor();
166: editor.setDefaultCursor();
167: if (errorText != null)
168: MessageDialog.showMessageDialog(errorText, "Error");
169: if (Editor.getBufferList().contains(NewsGroupSummary.this ))
170: kill();
171: for (EditorIterator it = new EditorIterator(); it.hasNext();)
172: it.nextEditor().updateDisplay();
173: }
174: };
175:
176: public void readArticle(Editor editor, Line line,
177: boolean useOtherWindow) {
178: if (line instanceof MailboxLine) {
179: editor.setMark(null);
180: NewsGroupSummaryEntry entry = (NewsGroupSummaryEntry) ((MailboxLine) line)
181: .getMailboxEntry();
182: NewsGroupMessageBuffer mb = new NewsGroupMessageBuffer(
183: this , entry);
184: activateMessageBuffer(editor, mb, useOtherWindow);
185: }
186: }
187:
188: public String getArticle(int articleNumber,
189: ProgressNotifier progressNotifier) {
190: String key = String.valueOf(articleNumber);
191: String filename = (String) map.get(key);
192: if (filename != null) {
193: File file = File.getInstance(filename);
194: if (file != null) {
195: try {
196: MailReader reader = new MailReader(file
197: .getInputStream());
198: long length = file.length();
199: FastStringBuffer sb = new FastStringBuffer(
200: (int) length);
201: String s;
202: while ((s = reader.readLine()) != null) {
203: sb.append(s);
204: sb.append('\n');
205: }
206: return sb.toString();
207: } catch (IOException e) {
208: Log.error(e);
209: }
210: }
211: }
212: String text = session.getArticle(articleNumber,
213: progressNotifier);
214: if (text != null) {
215: File file = Utilities.getTempFile();
216: try {
217: FastStringReader reader = new FastStringReader(text);
218: BufferedWriter writer = new BufferedWriter(
219: new OutputStreamWriter(file.getOutputStream(),
220: "ISO-8859-1"));
221: String s;
222: while ((s = reader.readLine()) != null) {
223: writer.write(s);
224: writer.write('\n');
225: }
226: writer.flush();
227: writer.close();
228: } catch (IOException e) {
229: Log.error(e);
230: }
231: map.put(key, file.canonicalPath());
232: }
233: return text;
234: }
235:
236: private void addEntriesToBuffer() {
237: if (entries != null) {
238: try {
239: lockWrite();
240: } catch (InterruptedException e) {
241: Log.error(e);
242: return;
243: }
244: try {
245: int limit = entries.size();
246: for (int i = 0; i < limit; i++)
247: appendLine((NewsGroupSummaryEntry) entries.get(i));
248: renumber();
249: } finally {
250: unlockWrite();
251: }
252: }
253: }
254:
255: public Position getInitialDotPos() {
256: return getFirstLine() != null ? new Position(getFirstLine(), 0)
257: : null;
258: }
259:
260: private boolean selectGroup() {
261: return session.selectGroup(groupName);
262: }
263:
264: private void getHeaders() {
265: int last = session.getLast();
266: int first = session.getFirst();
267: if (last <= first)
268: return;
269: if (last - first > numberToGet)
270: first = last - numberToGet;
271: entries = new Vector();
272: if (session.writeLine("XOVER " + first + "-" + last)) {
273: String s = session.readLine();
274: if (s.startsWith("224")) {
275: progressNotifier.progressStart();
276: int count = 0;
277: while (true) {
278: s = session.readLine();
279: if (s == null)
280: break;
281: if (s.equals("."))
282: break;
283: NewsGroupSummaryEntry entry = NewsGroupSummaryEntry
284: .parseOverviewEntry(s);
285: if (entry != null)
286: entries.add(entry);
287: ++count;
288: progressNotifier.progress("Received " + count
289: + " headers");
290: }
291: progressNotifier.progressStop();
292: } else
293: Log.error("XOVER response = " + s);
294: }
295: }
296:
297: public void dispose() {
298: if (session != null) {
299: Runnable r = new Runnable() {
300: public void run() {
301: session.disconnect();
302: }
303: };
304: new Thread(r).start();
305: }
306: }
307:
308: // For the buffer list.
309: public Icon getIcon() {
310: return Utilities.getIconFromFile("mailbox.png");
311: }
312:
313: public void getNewMessages() {
314: }
315:
316: public void readMessage(Line line) {
317: }
318:
319: public void createFolder() {
320: }
321:
322: public void deleteFolder() {
323: }
324:
325: public void saveToFolder() {
326: }
327:
328: public void moveToFolder() {
329: }
330:
331: public void delete() {
332: }
333:
334: public void undelete() {
335: }
336:
337: public void markRead() {
338: }
339:
340: public void markUnread() {
341: }
342:
343: public void setAnsweredFlag(MailboxEntry entry) {
344: }
345:
346: public void expunge() {
347: }
348:
349: public int getMessageCount() {
350: return 0;
351: }
352:
353: public void saveView(Editor editor) {
354: final View view = saveViewInternal(editor);
355: editor.setView(this, view);
356: setLastView(view);
357: }
358: }
|