001 package com.croftsoft.apps.agoracast.c2p;
002
003 import java.awt.*;
004 import java.awt.event.*;
005 import java.io.*;
006 import java.util.*;
007 import javax.swing.*;
008 import javax.swing.table.*;
009
010 import com.croftsoft.core.gui.ButtonPanel2;
011 import com.croftsoft.core.gui.LabeledFieldsPanel2;
012 import com.croftsoft.core.lang.NullArgumentException;
013 import com.croftsoft.core.lang.Pair;
014 import com.croftsoft.core.lang.StringLib;
015 import com.croftsoft.core.net.news.Newsgroup;
016 import com.croftsoft.core.net.news.NntpConstants;
017 import com.croftsoft.core.net.news.NntpSocket;
018 import com.croftsoft.core.net.news.UsenetMessage;
019 import com.croftsoft.core.text.DateFormatLib;
020 import com.croftsoft.core.util.log.Log;
021
022 /*********************************************************************
023 *
024 * <p />
025 *
026 * @version
027 * 2001-08-13
028 * @since
029 * 2001-07-31
030 * @author
031 * <a href="http://croftsoft.com/">David Wallace Croft</a>
032 *********************************************************************/
033
034 public final class AgoracastSourcePanel
035 extends JPanel
036 implements ActionListener, Log, Runnable
037 //////////////////////////////////////////////////////////////////////
038 //////////////////////////////////////////////////////////////////////
039 {
040
041 private final AgoracastMediator agoracastMediator;
042
043 private final AgoracastBrowsePanel agoracastBrowsePanel;
044
045 private final JTextArea jTextArea;
046
047 private final JButton cancelButton;
048
049 //
050
051 private AgoracastData agoracastData;
052
053 private NntpSocket nntpSocket;
054
055 //////////////////////////////////////////////////////////////////////
056 //////////////////////////////////////////////////////////////////////
057
058 public AgoracastSourcePanel (
059 AgoracastMediator agoracastMediator,
060 AgoracastBrowsePanel agoracastBrowsePanel )
061 //////////////////////////////////////////////////////////////////////
062 {
063 super ( new BorderLayout ( ), true ); // isDoubleBuffered
064
065 NullArgumentException.check (
066 this.agoracastMediator = agoracastMediator );
067
068 NullArgumentException.check (
069 this.agoracastBrowsePanel = agoracastBrowsePanel );
070
071 AgoracastLib.setColor ( this, agoracastMediator );
072
073 add ( new JScrollPane (
074 jTextArea = new JTextArea ( ) ), BorderLayout.CENTER );
075
076 jTextArea.setFont ( AgoracastConstants.LOG_FONT );
077
078 cancelButton = new JButton ( "Cancel" );
079
080 cancelButton.addActionListener ( this );
081
082 add ( cancelButton, BorderLayout.SOUTH );
083 }
084
085 //////////////////////////////////////////////////////////////////////
086 //////////////////////////////////////////////////////////////////////
087
088 public synchronized void viewSource ( AgoracastData agoracastData )
089 //////////////////////////////////////////////////////////////////////
090 {
091 this.agoracastData = agoracastData;
092
093 new Thread ( this ).start ( );
094 }
095
096 public synchronized void run ( )
097 //////////////////////////////////////////////////////////////////////
098 {
099 try
100 {
101 String articleId = agoracastData.getArticleId ( );
102
103 jTextArea.setText (
104 DateFormatLib.toIsoDateFormat ( new Date ( ) )
105 + " Downloading article " + articleId + "..." );
106
107 cancelButton.setText ( "Cancel" );
108
109 // should we get this from the agoracastData instead?
110
111 String server = agoracastMediator.getServer ( );
112
113 String newsgroupName = agoracastData.getNewsgroup ( );
114
115 nntpSocket = new NntpSocket ( server, this );
116
117 // 200 server ready - posting allowed
118 // 201 server ready - no posting allowed
119
120 if ( nntpSocket.getResponseCode ( ).startsWith ( "20" ) )
121 {
122 String responseCode = nntpSocket.command (
123 NntpConstants.COMMAND_GROUP + " " + newsgroupName );
124
125 if ( responseCode.startsWith ( "480" ) )
126 {
127 // 480 Authentication Required
128
129 AgoracastLib.authenticate ( nntpSocket, agoracastMediator );
130
131 // throws SecurityException if it fails
132
133 responseCode = nntpSocket.command (
134 NntpConstants.COMMAND_GROUP + " " + newsgroupName );
135 }
136
137 // 211 n f l s group selected
138 // (n = estimated number of articles in group,
139 // f = first article number in the group,
140 // l = last article number in the group,
141 // s = name of the group.)
142 // 411 no such news group
143
144 if ( responseCode.startsWith ( "211" ) )
145 {
146 responseCode = nntpSocket.command (
147 NntpConstants.COMMAND_ARTICLE + " " + articleId );
148
149 // 220 n <a> article retrieved - head and body follow
150 // (n = article number, <a> = message-id)
151 // 221 n <a> article retrieved - head follows
152 // 222 n <a> article retrieved - body follows
153 // 223 n <a> article retrieved - request text separately
154 // 412 no newsgroup has been selected
155 // 420 no current article has been selected
156 // 423 no such article number in this group
157 // 430 no such article found
158
159 if ( responseCode.startsWith ( "220" ) )
160 {
161 BufferedReader bufferedReader
162 = nntpSocket.getBufferedReader ( );
163
164 String line;
165
166 while ( true )
167 {
168 line = bufferedReader.readLine ( );
169
170 if ( ".".equals ( line )
171 || ( line == null ) )
172 {
173 break;
174 }
175
176 record ( line );
177 }
178 }
179 }
180 }
181
182 nntpSocket.command ( NntpConstants.COMMAND_QUIT );
183 }
184 catch ( Exception ex )
185 {
186 record ( ex );
187 }
188 finally
189 {
190 if ( nntpSocket != null )
191 {
192 try
193 {
194 nntpSocket.close ( );
195
196 }
197 catch ( Exception ex )
198 {
199 record ( ex );
200 }
201 }
202
203 cancelButton.setText ( "Done" );
204 }
205 }
206
207 public void actionPerformed ( ActionEvent actionEvent )
208 //////////////////////////////////////////////////////////////////////
209 {
210 try
211 {
212 Object source = actionEvent.getSource ( );
213
214 if ( source == cancelButton )
215 {
216 if ( nntpSocket != null )
217 {
218 // Is this hanging?
219
220 nntpSocket.close ( );
221 }
222
223 agoracastBrowsePanel.showTable ( );
224 }
225 }
226 catch ( Exception ex )
227 {
228 record ( ex );
229 }
230 }
231
232 //////////////////////////////////////////////////////////////////////
233 //////////////////////////////////////////////////////////////////////
234
235 // cut-and-paste from AgoracastSendPanel and AgoracastDownloadPanel,
236 // make reusable, see LogPanel
237
238 public synchronized void record ( String message )
239 //////////////////////////////////////////////////////////////////////
240 {
241 jTextArea.append ( '\n' + message );
242
243 String text = jTextArea.getText ( );
244
245 int textLength = text.length ( );
246
247 if ( textLength > AgoracastConstants.LOG_TEXT_LENGTH_MAX )
248 {
249 jTextArea.setText ( text.substring (
250 textLength - AgoracastConstants.LOG_TEXT_LENGTH_MAX ) );
251 }
252 }
253
254 public synchronized void record ( Throwable throwable )
255 //////////////////////////////////////////////////////////////////////
256 {
257 record ( '\n' + throwable.toString ( ) );
258 }
259
260
261 public synchronized void record (
262 String message, Throwable throwable )
263 //////////////////////////////////////////////////////////////////////
264 {
265 record ( '\n' + message + '\n' + throwable.toString ( ) );
266 }
267
268 //////////////////////////////////////////////////////////////////////
269 //////////////////////////////////////////////////////////////////////
270 }