@@ -65,14 +65,15 @@ public enum Status {
6565 private final URL downloadUrl ;
6666
6767 private final File outputFile ;
68- private InputStream stream = null ;
68+ private final boolean allowCache ;
6969 private Exception error ;
7070
71- public FileDownloader (URL url , File file ) {
72- downloadUrl = url ;
73- outputFile = file ;
74- downloaded = 0 ;
75- initialSize = 0 ;
71+ public FileDownloader (URL url , File file , boolean allowCache ) {
72+ this .downloadUrl = url ;
73+ this .outputFile = file ;
74+ this .allowCache = allowCache ;
75+ this .downloaded = 0 ;
76+ this .initialSize = 0 ;
7677 }
7778
7879 public long getInitialSize () {
@@ -118,11 +119,11 @@ public void setStatus(Status status) {
118119 }
119120
120121
121- public void download (boolean noResume , boolean allowCache ) throws InterruptedException {
122+ public void download (boolean noResume ) throws InterruptedException {
122123 if ("file" .equals (downloadUrl .getProtocol ())) {
123124 saveLocalFile ();
124125 } else {
125- downloadFile (noResume , allowCache );
126+ downloadFile (noResume );
126127 }
127128 }
128129
@@ -136,66 +137,109 @@ private void saveLocalFile() {
136137 }
137138 }
138139
139- private void downloadFile (boolean noResume , boolean allowCache ) throws InterruptedException {
140- RandomAccessFile randomAccessOutputFile = null ;
140+ private void downloadFile (boolean noResume ) throws InterruptedException {
141141
142142 try {
143143 setStatus (Status .CONNECTING );
144144
145145 final Optional <FileDownloaderCache .FileCached > fileCached = FileDownloaderCache .getFileCached (downloadUrl );
146-
147146 if (fileCached .isPresent () && fileCached .get ().isNotChange ()) {
148- try {
149- final Optional <File > fileFromCache =
150- fileCached .get ().getFileFromCache ();
151- if (fileFromCache .isPresent ()) {
152- log .info ("No need to download using cached file: {}" , fileCached .get ());
153- FileUtils .copyFile (fileFromCache .get (), outputFile );
154- setStatus (Status .COMPLETE );
155- return ;
147+ final Optional <File > fileFromCache = getFileCached (fileCached .get ());
148+ if (fileFromCache .isPresent ()) {
149+ // Copy the cached file in the destination file
150+ FileUtils .copyFile (fileFromCache .get (), outputFile );
151+ } else {
152+ openConnectionAndFillTheFile (noResume );
153+
154+ if (allowCache ) {
155+ fileCached .get ().updateCacheFile (outputFile );
156156 } else {
157- log .info (
158- "The file in the cache is not in the path or the md5 validation failed: path={}, file exist={}, md5 validation={}" ,
159- fileCached .get ().getLocalPath (), fileCached .get ().exists (), fileCached .get ().md5Check ());
157+ log .info ("The file {} was not cached because allow cache is false" , downloadUrl );
160158 }
161- } catch (Exception e ) {
162- log .warn (
163- "Cannot get the file from the cache, will be downloaded a new one " , e );
164159 }
165- } else {
166- log .info ("The file is change {}" , fileCached );
167160 }
161+ setStatus (Status .COMPLETE );
162+
163+ } catch (InterruptedException e ) {
164+ setStatus (Status .CANCELLED );
165+ // lets InterruptedException go up to the caller
166+ throw e ;
167+
168+ } catch (SocketTimeoutException e ) {
169+ setStatus (Status .CONNECTION_TIMEOUT_ERROR );
170+ setError (e );
171+ log .error ("The request went in socket timeout" , e );
172+
173+ } catch (Exception e ) {
174+ setStatus (Status .ERROR );
175+ setError (e );
176+ log .error ("The request stop" , e );
177+ }
178+
179+ }
168180
169- initialSize = outputFile .length ();
170- if (noResume && initialSize > 0 ) {
171- // delete file and restart downloading
172- Files .deleteIfExists (outputFile .toPath ());
173- initialSize = 0 ;
181+ private Optional <File > getFileCached (FileDownloaderCache .FileCached fileCached ) {
182+
183+ try {
184+ final Optional <File > fileFromCache =
185+ fileCached .getFileFromCache ();
186+ if (fileFromCache .isPresent ()) {
187+ log .info ("No need to download using cached file: {}" , fileCached );
188+ return fileFromCache ;
189+ } else {
190+ log .info (
191+ "The file in the cache is not in the path or the md5 validation failed: path={}, file exist={}, md5 validation={}" ,
192+ fileCached .getLocalPath (), fileCached .exists (), fileCached .md5Check ());
174193 }
194+ } catch (Exception e ) {
195+ log .warn (
196+ "Cannot get the file from the cache, will be downloaded a new one " , e );
197+ }
198+ log .info ("The file is change {}" , fileCached );
199+ return Optional .empty ();
200+ }
201+
202+ private void openConnectionAndFillTheFile (boolean noResume ) throws Exception {
203+ initialSize = outputFile .length ();
204+ if (noResume && initialSize > 0 ) {
205+ // delete file and restart downloading
206+ Files .deleteIfExists (outputFile .toPath ());
207+ initialSize = 0 ;
208+ }
209+
210+ final HttpURLConnection connection = new HttpConnectionManager (downloadUrl )
211+ .makeConnection ((c ) -> setDownloaded (0 ));
212+ final int resp = connection .getResponseCode ();
213+
214+ if (resp < 200 || resp >= 300 ) {
215+ Files .deleteIfExists (outputFile .toPath ());
216+ throw new IOException ("Received invalid http status code from server: " + resp );
217+ }
218+
219+ RandomAccessFile randomAccessOutputFile = null ;
220+ try {
175221 // Open file and seek to the end of it
176222 randomAccessOutputFile = new RandomAccessFile (outputFile , "rw" );
177223 randomAccessOutputFile .seek (initialSize );
224+ readStreamCopyTo (randomAccessOutputFile , connection );
225+ } finally {
226+ IOUtils .closeQuietly (randomAccessOutputFile );
227+ }
178228
179- final HttpURLConnection connection = new HttpConnectionManager (downloadUrl )
180- .makeConnection ((c ) -> setDownloaded (0 ));
181- final int resp = connection .getResponseCode ();
182-
183- if (resp < 200 || resp >= 300 ) {
184- IOUtils .closeQuietly (randomAccessOutputFile );
185- Files .deleteIfExists (outputFile .toPath ());
186- throw new IOException ("Received invalid http status code from server: " + resp );
187- }
229+ }
188230
231+ private void readStreamCopyTo (RandomAccessFile randomAccessOutputFile , HttpURLConnection connection ) throws Exception {
232+ InputStream stream = null ;
233+ try {
189234 // Check for valid content length.
190235 long len = connection .getContentLength ();
191236 if (len >= 0 ) {
192237 setDownloadSize (len );
193238 }
194239 setStatus (Status .DOWNLOADING );
195240
196- synchronized (this ) {
197- stream = connection .getInputStream ();
198- }
241+ stream = connection .getInputStream ();
242+
199243 byte [] buffer = new byte [10240 ];
200244 while (status == Status .DOWNLOADING ) {
201245 int read = stream .read (buffer );
@@ -215,36 +259,8 @@ private void downloadFile(boolean noResume, boolean allowCache) throws Interrupt
215259 if (getDownloaded () < getDownloadSize ())
216260 throw new Exception ("Incomplete download" );
217261 }
218- // Set the cache whe it finish to download the file
219- IOUtils .closeQuietly (randomAccessOutputFile );
220- if (fileCached .isPresent () && allowCache ) {
221- fileCached .get ().updateCacheFile (outputFile );
222- }
223- if (!allowCache ) {
224- log .info ("The file {} was not cached because allow cache is false" , downloadUrl );
225- }
226- setStatus (Status .COMPLETE );
227- } catch (InterruptedException e ) {
228- setStatus (Status .CANCELLED );
229- // lets InterruptedException go up to the caller
230- throw e ;
231-
232- } catch (SocketTimeoutException e ) {
233- setStatus (Status .CONNECTION_TIMEOUT_ERROR );
234- setError (e );
235- log .error ("The request went in socket timeout" , e );
236-
237- } catch (Exception e ) {
238- setStatus (Status .ERROR );
239- setError (e );
240- log .error ("The request stop" , e );
241-
242262 } finally {
243- IOUtils .closeQuietly (randomAccessOutputFile );
244-
245- synchronized (this ) {
246- IOUtils .closeQuietly (stream );
247- }
263+ IOUtils .closeQuietly (stream );
248264 }
249265 }
250266
0 commit comments