KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > columba > ristretto > pop3 > POP3DownloadThread


1 /* ***** BEGIN LICENSE BLOCK *****
2  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
3  *
4  * The contents of this file are subject to the Mozilla Public License Version
5  * 1.1 (the "License"); you may not use this file except in compliance with
6  * the License. You may obtain a copy of the License at
7  * http://www.mozilla.org/MPL/
8  *
9  * Software distributed under the License is distributed on an "AS IS" basis,
10  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
11  * for the specific language governing rights and limitations under the
12  * License.
13  *
14  * The Original Code is Ristretto Mail API.
15  *
16  * The Initial Developers of the Original Code are
17  * Timo Stich and Frederik Dietz.
18  * Portions created by the Initial Developers are Copyright (C) 2004
19  * All Rights Reserved.
20  *
21  * Contributor(s):
22  *
23  * Alternatively, the contents of this file may be used under the terms of
24  * either the GNU General Public License Version 2 or later (the "GPL"), or
25  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
26  * in which case the provisions of the GPL or the LGPL are applicable instead
27  * of those above. If you wish to allow use of your version of this file only
28  * under the terms of either the GPL or the LGPL, and not to allow others to
29  * use your version of this file under the terms of the MPL, indicate your
30  * decision by deleting the provisions above and replace them with the notice
31  * and other provisions required by the GPL or the LGPL. If you do not delete
32  * the provisions above, a recipient may use your version of this file under
33  * the terms of any one of the MPL, the GPL or the LGPL.
34  *
35  * ***** END LICENSE BLOCK ***** */

36 package org.columba.ristretto.pop3;
37
38 import java.io.File JavaDoc;
39 import java.io.FileInputStream JavaDoc;
40 import java.io.FileOutputStream JavaDoc;
41 import java.io.IOException JavaDoc;
42 import java.io.InputStream JavaDoc;
43 import java.io.OutputStream JavaDoc;
44 import java.util.logging.Logger JavaDoc;
45
46 import org.columba.ristretto.concurrency.Mutex;
47 import org.columba.ristretto.io.AsyncInputStream;
48 import org.columba.ristretto.io.MemBuffer;
49 import org.columba.ristretto.io.MemBufferInputStream;
50 import org.columba.ristretto.io.MemBufferOutputStream;
51 import org.columba.ristretto.io.TempSourceFactory;
52
53 /**
54  * Thread that is used to asynchronously download
55  * mails from a POP3 server.
56  *
57  * @author Timo Stich <tstich@users.sourceforge.net>
58  */

59 public class POP3DownloadThread implements Runnable JavaDoc {
60     private static final int BUFFER_SIZE = 1024;
61     
62     /** JDK 1.4+ logging framework logger, used for logging. */
63     private static final Logger JavaDoc LOG = Logger.getLogger("org.columba.ristretto.pop3.protocol");
64
65     private AsyncInputStream partner;
66
67     private InputStream JavaDoc source;
68     private OutputStream JavaDoc out;
69
70     private byte[] buffer = new byte[BUFFER_SIZE];
71
72     private int size;
73     private int read;
74
75     private Mutex mutex;
76
77
78     /**
79      * @see java.lang.Runnable#run()
80      */

81     public void run() {
82         int lastRead;
83         long startTime = System.currentTimeMillis();
84         
85         
86         try {
87             lastRead = source.read(buffer);
88             while( lastRead != -1 ) {
89                 
90                 if( read + lastRead > size ) {
91                     // message is bigger than expected
92
partner.setSize( read + lastRead);
93                     LOG.warning("message should be " + size + " but is " + (read + lastRead) + " bytes");
94                 }
95                 
96                 out.write(buffer, 0, lastRead);
97                 partner.grow(lastRead);
98                 read += lastRead;
99
100                 lastRead = source.read(buffer);
101             }
102         } catch (IOException JavaDoc e) {
103             partner.exceptionOccured(e);
104             // This unblocks the waiting reader
105
partner.grow(size - read);
106         }
107
108         
109         if( read < size ) {
110             // message is smaller than expected
111
partner.setSize(read);
112
113             // unlock a potentially waiting reader
114
partner.grow(1);
115
116             LOG.warning("message should be " + size + " but is " + read + " bytes");
117         }
118         
119         LOG.finer("Needed " + (System.currentTimeMillis() - startTime) + " ms for downloading " + size + " bytes.");
120         
121         if( mutex!= null ) {
122             mutex.release();
123         }
124     }
125     /**
126      * Constructs the DownloadThread.java.
127      *
128      * @param partner
129      * @param source
130      * @param size
131      */

132     private POP3DownloadThread(AsyncInputStream partner, InputStream JavaDoc source,
133             OutputStream JavaDoc out, int size, Mutex mutex) {
134         this.partner = partner;
135         this.source = source;
136         this.size = size;
137         this.out = out;
138         this.mutex = mutex;
139     }
140     
141     
142     /**
143      * Starts the asynchrounous download from the POP3 server.
144      *
145      * @param source the socket InputStream
146      * @param size the estimated size of the mail or -1 if unknown
147      * @param mutex Mutex that is released after the mail was downloaded
148      * @return InputStream of the mail
149      * @throws IOException
150      */

151     public static AsyncInputStream asyncDownload(InputStream JavaDoc source, int size, Mutex mutex) throws IOException JavaDoc {
152         InputStream JavaDoc literalSource;
153         OutputStream JavaDoc out;
154         
155         if( TempSourceFactory.useMemoryTemp(size)) {
156             MemBuffer literalBuffer = new MemBuffer(size);
157             out = new MemBufferOutputStream(literalBuffer);
158             literalSource = new MemBufferInputStream(literalBuffer);
159         } else {
160             File JavaDoc tempFile = TempSourceFactory.createTempFile();
161             
162             // First create file that has correct size
163
byte[] zeros = new byte[10000];
164             out = new FileOutputStream JavaDoc(tempFile);
165             try {
166                 int i;
167                 for( i=0; i<size; i+=10000) {
168                     out.write(zeros);
169                 }
170                 out.write(zeros,0,size % 10000);
171             } finally {
172                 out.close();
173             }
174             
175             literalSource = new FileInputStream JavaDoc(tempFile);
176             out = new FileOutputStream JavaDoc(tempFile);
177         }
178
179         
180         AsyncInputStream asyncStream = new AsyncInputStream(literalSource, size);
181      
182         POP3DownloadThread thread = new POP3DownloadThread( asyncStream, source, out, size, mutex );
183         
184         new Thread JavaDoc( thread ).start();
185         
186         return asyncStream;
187     }
188 }
189
Popular Tags