KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > modules > autoupdate > Downloader


1 /*
2  * The contents of this file are subject to the terms of the Common Development
3  * and Distribution License (the License). You may not use this file except in
4  * compliance with the License.
5  *
6  * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
7  * or http://www.netbeans.org/cddl.txt.
8  *
9  * When distributing Covered Code, include this CDDL Header Notice in each file
10  * and include the License file at http://www.netbeans.org/cddl.txt.
11  * If applicable, add the following below the CDDL Header, with the fields
12  * enclosed by brackets [] replaced by your own identifying information:
13  * "Portions Copyrighted [year] [name of copyright owner]"
14  *
15  * The Original Software is NetBeans. The Initial Developer of the Original
16  * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
17  * Microsystems, Inc. All Rights Reserved.
18  */

19
20 package org.netbeans.modules.autoupdate;
21
22 import java.io.*;
23 import java.net.URLConnection JavaDoc;
24 import java.text.MessageFormat JavaDoc;
25 import java.util.Iterator JavaDoc;
26 import java.util.List JavaDoc;
27 import java.util.logging.Level JavaDoc;
28 import java.util.logging.Logger JavaDoc;
29 import org.netbeans.api.progress.ProgressHandle;
30 import org.netbeans.api.progress.ProgressHandleFactory;
31 import org.netbeans.updater.UpdateTracking;
32
33 import org.openide.DialogDisplayer;
34 import org.openide.util.Lookup;
35
36 import org.openide.util.NbBundle;
37 import org.openide.NotifyDescriptor;
38 import org.openide.util.RequestProcessor;
39
40 /** This class downloads modules and verifies the digital signatures
41  * this class also copyies the downloaded modules.
42  * @author phrebejk
43  */

44 class Downloader extends Object JavaDoc {
45
46     /** The update check progress panel */
47     DownloadProgressPanel progressDialog;
48     /** Total size of the download */
49     private int downloadSize;
50     /** KBytes downloaded */
51     private int totalDownloaded;
52     /** KBytes downloaded */
53     private int moduleDownloaded;
54     /** Number of modules to downaload */
55     private long modulesCount;
56     /** Shoud internet download be performed */
57     private boolean urlDownload;
58     
59     static private int TIME_TO_CONNECTION_CHECK = 20000;
60
61     /** Extension of the distribution files */
62     private static final String JavaDoc NBM_EXTENSION = "nbm"; // NOI18N
63

64     /** Wizard validator, enables the Next button in wizard */
65     private Wizard.Validator validator;
66     
67     private static final Logger JavaDoc err = Logger.getLogger("org.netbeans.modules.autoupdate.Downloader"); // NOI18N
68

69     private static RequestProcessor.Task READ_TIMEOUT_CHECKER;
70     private static RequestProcessor.Task DOWNLOAD_TASK;
71     private static RequestProcessor AU_REQUEST_PROCESSOR = null;
72     
73     private static int DOWNLOADER_IS_INIT = -1;
74     private static int DOWNLOADER_RUNNING = 0;
75     private static int DOWNLOADER_WAITING = 1;
76     private static int DOWNLOADER_CANCELED = 2;
77     private static int DOWNLOADER_STOPPED = 3;
78     private static int DOWNLOADER_FINISHED = 4;
79     private static int DOWNLOADER_VERIFIED = 5;
80     
81     private int downloadStatus = DOWNLOADER_IS_INIT;
82     
83     // progress
84
ProgressHandle partialHandle;
85     ProgressHandle overallHandle;
86
87     /** Creates new Downloader */
88     public Downloader (DownloadProgressPanel progressDialog, Wizard.Validator validator, boolean urlDownload) {
89         this.validator = validator;
90         this.progressDialog = (DownloadProgressPanel)progressDialog;
91         this.urlDownload = urlDownload;
92     }
93     
94     private static RequestProcessor getAutoupdateRequestProcessor () {
95         if (AU_REQUEST_PROCESSOR == null) {
96             AU_REQUEST_PROCESSOR = new RequestProcessor ("org-netbeans-modules-autoupdate", 10, true); // NOI18N
97
}
98         return AU_REQUEST_PROCESSOR;
99     }
100
101     void doDownload() {
102         if (READ_TIMEOUT_CHECKER != null) {
103             READ_TIMEOUT_CHECKER.cancel ();
104         }
105         
106         assert READ_TIMEOUT_CHECKER == null || READ_TIMEOUT_CHECKER.isFinished () : "Only one READ_TIMEOUT_CHECKER can be active";
107         
108         // if the task isn't finished -> interrupt and left it
109
if (DOWNLOAD_TASK != null) {
110             DOWNLOAD_TASK.cancel ();
111             DOWNLOAD_TASK = null;
112         }
113
114         assert DOWNLOAD_TASK == null || DOWNLOAD_TASK.isFinished () : "Only one DOWNLOAD_TASK can be active";
115         
116         downloadSize = getTotalDownloadSize();
117         
118         progressDialog.setPartialLabel (""); // NOI18N
119
progressDialog.setOverallLabel (""); // NOI18N
120
progressDialog.setExtraLabel (""); // NOI18N
121

122         Runnable JavaDoc task = new Runnable JavaDoc () {
123                             public void run() {
124
125                                 progressDialog.setPartialLabel (getBundle( "CTL_PreparingDownload_Label")); // NOI18N
126

127                                 err.log(Level.FINE,
128                                         "Start downloading " + modulesCount +
129                                         " modules [" + downloadSize + "]");
130                                 
131                                 downloadAll();
132                                 
133                                 if (DOWNLOADER_STOPPED == getStatus ()) {
134                                     return ;
135                                 }
136
137                                 progressDialog.setExtraLabel (getBundle ("DownloadProgressPanel.jLabel1.doneText")); // NOI18N
138

139                                 validator.setValid( true );
140                             }
141                         };
142
143         DOWNLOAD_TASK = getAutoupdateRequestProcessor ().post( task );
144     }
145     
146     /** Total size of download in KBytes */
147     private int getTotalDownloadSize( ) {
148         long result = 0L;
149         modulesCount = 0;
150
151         Iterator JavaDoc it = Wizard.getAllModules().iterator();
152
153         while( it.hasNext() ) {
154             ModuleUpdate mu = (ModuleUpdate)it.next();
155
156             if ( mu.isSelected() && !mu.isDownloadOK() ) {
157                 result += mu.getDownloadSize();
158                 modulesCount++;
159             }
160         }
161         return (int) result;
162     }
163
164
165     /** Downloads the modules from web */
166     private void downloadAll() {
167
168         // show fake component during the real length is obtained from connection
169
getPartialHandle (1);
170         overallHandle = getOverallHandle (downloadSize);
171
172         int currentModule = 0;
173         totalDownloaded = 0;
174
175         Iterator JavaDoc it = Wizard.getAllModules().iterator();
176
177         while( it.hasNext() ) {
178
179             if (DOWNLOADER_STOPPED == getStatus ()) {
180                 return;
181             }
182
183             ModuleUpdate mu = (ModuleUpdate)it.next();
184             if ( mu.isSelected() && !mu.isDownloadOK() ) {
185                 progressDialog.setPartialLabel (mu.getName () + " [" + (currentModule + 1) + "/" + modulesCount + "]"); // NOI18N
186
if ( urlDownload ) {
187                     if (DOWNLOADER_FINISHED == getStatus () || DOWNLOADER_IS_INIT == getStatus ()) {
188                         err.log(Level.FINE, "Do download " + mu.getName());
189                         setStatus (DOWNLOADER_IS_INIT);
190                         downloadModule (mu);
191                         err.log(Level.FINE,
192                                 "Download of " + mu.getName() +
193                                 " ends with status " + getStatus());
194                     } else {
195                         err.log(Level.FINE,
196                                 "Don\'t download " + mu.getName() +
197                                 " due to incorrect status " + getStatus());
198                     }
199                 } else {
200                     downloadModuleFromLocal (mu);
201                 }
202                 updateOverall ();
203                 if (partialHandle != null && mu.isDownloadOK ()) {
204                     partialHandle.finish ();
205                     currentModule++;
206                 }
207             }
208         }
209         
210         if (DOWNLOADER_STOPPED == getStatus ()) {
211             return ;
212         }
213
214         overallHandle.progress (downloadSize);
215         overallHandle.finish ();
216         String JavaDoc mssgTotal = MessageFormat.format( getBundle( "FMT_DownloadedTotal" ), // NOI18N
217
new Object JavaDoc[] { new Integer JavaDoc( downloadSize / 1024 ),
218                                           new Integer JavaDoc( downloadSize / 1024 ) } );
219         progressDialog.setOverallLabel (mssgTotal);
220         progressDialog.setEnableStop (false);
221         
222         runVerifier ();
223     }
224     
225     private void runVerifier () {
226         
227         err.log(Level.FINE, "Prepare SignVerifier.");
228         if (DOWNLOADER_VERIFIED == getStatus ()) {
229             err.log(Level.FINE, "Error: SignVerifier has run before.");
230             return ;
231         }
232
233         SignVerifier signVerifier = new SignVerifier (progressDialog, validator);
234         progressDialog.setExtraLabel (getBundle("DownloadProgressPanel.jLabel1.securityText")); // NOI18N
235
signVerifier.doVerify();
236         
237         setStatus (DOWNLOADER_VERIFIED);
238     }
239     
240     private int getStatus () {
241         return downloadStatus;
242     }
243     
244     private void setStatus (int status) {
245         downloadStatus = status;
246     }
247     
248     private void ioCopy (BufferedInputStream in, BufferedOutputStream out, int flen) throws IOException {
249         int c;
250         
251         try {
252             
253             if (DOWNLOADER_IS_INIT == getStatus ()) {
254                 setStatus (DOWNLOADER_RUNNING);
255             }
256             
257             while ((DOWNLOADER_RUNNING == getStatus () || DOWNLOADER_WAITING == getStatus ()) && ( c = in.read () ) != -1 ) {
258
259                 if (READ_TIMEOUT_CHECKER.getDelay () == 0) {
260                     READ_TIMEOUT_CHECKER.waitFinished ();
261                 } else if (READ_TIMEOUT_CHECKER.getDelay () < TIME_TO_CONNECTION_CHECK) {
262                     READ_TIMEOUT_CHECKER.schedule (TIME_TO_CONNECTION_CHECK * 2);
263                 }
264
265                 out.write( c );
266
267                 moduleDownloaded++;
268                 totalDownloaded++;
269
270                 if ( moduleDownloaded % 4096 == 0 ) {
271                     updateOverall();
272                     partialHandle.progress (moduleDownloaded < flen ? moduleDownloaded : flen);
273                 }
274             }
275             
276             if (DOWNLOADER_RUNNING == getStatus ()) {
277                 setStatus (DOWNLOADER_FINISHED);
278             }
279             
280         } finally {
281             if (in != null) in.close();
282             if (out != null) out.close();
283         }
284         
285     }
286
287     /** Downloads a .NBM file into download directory
288     */

289     private void downloadModule (final ModuleUpdate moduleUpdate) {
290         int flen = 0;
291
292         final File destFile = getNBM( moduleUpdate );
293
294         try {
295
296             moduleDownloaded = 0;
297             partialHandle = getPartialHandle (1);
298
299             moduleUpdate.setDownloadStarted( true );
300             progressDialog.setEnableStop (true);
301
302             err.log(Level.FINE,
303                     "Setup checker of download " + moduleUpdate.getName());
304             READ_TIMEOUT_CHECKER = getAutoupdateRequestProcessor ().post (new Runnable JavaDoc () {
305                 public void run () {
306                     confirmConnectionFailed (moduleUpdate);
307                 }
308             }, TIME_TO_CONNECTION_CHECK * 4);
309
310             err.log(Level.FINE,
311                     "Try to estabilish a conncetion to " +
312                     moduleUpdate.getDistribution());
313             progressDialog.setExtraLabel (getBundle ("DownloadProgressPanel.jLabel1.Establish")); // NOI18N
314

315             URLConnection JavaDoc distrConnection = moduleUpdate.getDistribution().openConnection();
316             moduleUpdate.setRemoteDistributionFilename(distrConnection);
317
318             final BufferedInputStream bsrc = new BufferedInputStream (distrConnection.getInputStream ());
319             BufferedOutputStream bdest = new BufferedOutputStream( new FileOutputStream( destFile ) );
320
321             flen = distrConnection.getContentLength();
322             // #65099: some servers/proxies can forbid to say content length of URLConnection
323
if (flen == -1) {
324                 flen = (int) moduleUpdate.getDownloadSize ();
325             }
326             assert flen > 0 : "Content of distrConnection of update " + moduleUpdate.getName () + " must be known and more then 0, but was " + flen;
327             partialHandle = getPartialHandle (flen);
328             progressDialog.setExtraLabel (getBundle ("DownloadProgressPanel.jLabel1.downloadText")); //NOI18N
329

330             try {
331                 
332                 ioCopy (bsrc, bdest, flen);
333                 
334                 if (DOWNLOADER_FINISHED == getStatus ()) {
335                     moduleUpdate.setDownloadOK (true);
336                     err.log(Level.FINE,
337                             moduleUpdate.getName() +
338                             " was downloaded correctly.");
339                 } else {
340                     moduleUpdate.setDownloadOK (false);
341                     err.log(Level.FINE,
342                             moduleUpdate.getName() +
343                             " wasn\'t download correctly.");
344                     moduleUpdate.setSecurity (SignVerifier.BAD_DOWNLOAD);
345                 }
346                 
347                 moduleUpdate.setDownloadStarted (false);
348                 READ_TIMEOUT_CHECKER.cancel ();
349                 
350             } finally {
351                 if (DOWNLOADER_FINISHED != getStatus ()) {
352                     getNBM (moduleUpdate).delete ();
353                 }
354             }
355         } catch ( IOException e ) {
356             if (DOWNLOADER_STOPPED == getStatus ()) {
357                 return ;
358             }
359
360             // cannot decrease count of downloaded bytes due Progress API
361
// totalDownloaded-=moduleDownloaded;
362

363             validator.setValid (false);
364
365             err.log(Level.INFO, null, e);
366
367             // Download failed
368
confirmConnectionFailed (moduleUpdate);
369         }
370         
371         return;
372     }
373     
374     private void confirmConnectionFailed (ModuleUpdate moduleUpdate) {
375         if (DOWNLOADER_RUNNING != getStatus () && DOWNLOADER_IS_INIT != getStatus ()) {
376             return;
377         }
378         err.log(Level.FINE,
379                 "Connection failed during download " + moduleUpdate.getName());
380         setStatus (DOWNLOADER_WAITING);
381         String JavaDoc mssg = NbBundle.getMessage( Downloader.class, "FMT_DownloadFailed", // NOI18N
382
moduleUpdate.getName() );
383         NotifyDescriptor nd = new NotifyDescriptor.Confirmation (mssg,
384                               getBundle ("CTL_DownloadFailed"), // NOI18N
385
NotifyDescriptor.YES_NO_CANCEL_OPTION);
386         DialogDisplayer.getDefault().notify( nd );
387
388         if ( nd.getValue().equals( NotifyDescriptor.CANCEL_OPTION ) ) {
389             err.log(Level.FINE,
390                     "Confirm of the failed connection was canceled, continue downloading.");
391             
392             // set status RUNNING back
393
setStatus (DOWNLOADER_RUNNING);
394             
395             moduleUpdate.setDownloadStarted (true);
396             moduleUpdate.setSecurity (SignVerifier.BAD_DOWNLOAD);
397             if (READ_TIMEOUT_CHECKER != null) {
398                 READ_TIMEOUT_CHECKER.cancel ();
399                 READ_TIMEOUT_CHECKER.schedule (TIME_TO_CONNECTION_CHECK * 2);
400             }
401             validator.setValid (false);
402             return ;
403         } else if (nd.getValue ().equals (NotifyDescriptor.NO_OPTION)) {
404             err.log(Level.FINE,
405                     "Interrupt download of " + moduleUpdate.getName());
406             validator.setValid (true);
407             setStatus (DOWNLOADER_CANCELED);
408             moduleUpdate.setDownloadOK (false);
409             moduleUpdate.setDownloadStarted (false);
410             progressDialog.setExtraLabel (getBundle ("DownloadProgressPanel.jLabel1.Broken")); //NOI18N
411
moduleUpdate.setSecurity (SignVerifier.BAD_DOWNLOAD);
412
413             // cannot decrease count of downloaded bytes due Progress API
414
// totalDownloaded-=moduleDownloaded;
415

416             DOWNLOAD_TASK.cancel ();
417             READ_TIMEOUT_CHECKER.cancel ();
418             
419             runVerifier ();
420             
421             return ;
422         }
423         
424         READ_TIMEOUT_CHECKER.cancel ();
425         DOWNLOAD_TASK.cancel ();
426         setStatus (DOWNLOADER_STOPPED);
427         
428         // try again
429

430         moduleUpdate.setDownloadStarted (false);
431         err.log(Level.FINE,
432                 "Failed connection was confirmed, start download " +
433                 moduleUpdate.getName() + " again.");
434         progressDialog.setExtraLabel (getBundle ("DownloadProgressPanel.jLabel1.Restart")); // NOI18N
435
RequestProcessor.getDefault ().post (new Runnable JavaDoc () {
436            public void run () {
437                new Downloader (progressDialog, validator, urlDownload).doDownload ();
438            }
439         }, 100);
440         
441         return ;
442     }
443     
444     private void downloadModuleFromLocal (ModuleUpdate moduleUpdate) {
445         partialHandle = getPartialHandle (1);
446         if (downloadFromLocal (moduleUpdate)) {
447             totalDownloaded += moduleUpdate.getDownloadSize();
448         }
449         updateOverall();
450     }
451     
452     private void updateOverall() {
453         String JavaDoc mssgTotal = NbBundle.getMessage( Downloader.class, "FMT_DownloadedTotal", // NOI18N
454
new Object JavaDoc[] { new Integer JavaDoc( (int)(totalDownloaded / 1024) ),
455                                           new Integer JavaDoc( (int)(downloadSize / 1024) ) } );
456
457         // ignore higher sizes then planned downloadSize
458
overallHandle.progress (downloadSize > totalDownloaded ? totalDownloaded : downloadSize);
459         progressDialog.setOverallLabel (mssgTotal);
460     }
461
462     private ProgressHandle getPartialHandle (int units) {
463         assert units >= 0 : "Count of units " + units + " must be positive.";
464         assert progressDialog != null;
465         ProgressHandle handle = ProgressHandleFactory.createHandle (getBundle ("DownloadProgressPanel_partialHandle_name")); // NOI18N
466
handle.setInitialDelay (0);
467         progressDialog.setPartialProgressComponent (handle);
468         handle.start (units);
469         return handle;
470     }
471     
472     private ProgressHandle getOverallHandle (int units) {
473         assert units >= 0 : "Count of units " + units + " must be positive.";
474         assert progressDialog != null;
475         ProgressHandle handle = ProgressHandleFactory.createHandle (getBundle ("DownloadProgressPanel_overallHandle_name")); // NOI18N
476
handle.setInitialDelay (0);
477         progressDialog.setOverallProgressComponent (handle);
478         handle.start (units);
479         return handle;
480     }
481     
482     // utility methods
483
// TODO: could be moved in a utility class ?
484

485     void cancelDownload() {
486         setStatus (DOWNLOADER_STOPPED);
487         validator.setValid (false);
488     }
489     
490     /** Copies the external NBM file into the appropriate location where
491      * Downloader can work with.
492      *
493      * @param moduleUpdate moduleupdate for local nbm
494      * @return false if there was a problem
495      */

496     /*no private due to unit test*/
497     static boolean downloadFromLocal (ModuleUpdate moduleUpdate) {
498         if ( tryCopy( moduleUpdate.getDistributionFile(), getNBM( moduleUpdate ) ) ) {
499             moduleUpdate.setDownloadOK( true );
500             return true;
501         }
502         else {
503             getNBM( moduleUpdate ).delete();
504             return false;
505         }
506     }
507     
508     static File getNBM( ModuleUpdate mu ) {
509         File destFile = new File( Autoupdater.Support.getDownloadDirectory (null), mu.getDistributionFilename() );
510         return destFile;
511     }
512     
513     static File getMovedNBM( ModuleUpdate mu ) {
514         File destFile = null;
515         if (mu.isToInstallDir ())
516             destFile = Autoupdater.Support.getDownloadDirectory (mu.findInstallDirectory ());
517         else
518             destFile = Autoupdater.Support.getDownloadDirectory (null);
519         
520         return new File (destFile, mu.getDistributionFilename());
521     }
522
523     static boolean tryMove( ModuleUpdate mu ) {
524         File toCluster = mu.findInstallDirectory();
525         
526         boolean existingCluster = false;
527         for (Iterator JavaDoc it = UpdateTracking.clusters(true).iterator(); it.hasNext(); ) {
528             File f = (File)it.next();
529             if (f.equals(toCluster)) {
530                 existingCluster = true;
531                 break;
532             }
533         }
534         
535         DO_CLUSTER: if (!existingCluster) {
536             for (Iterator JavaDoc it = Lookup.getDefault().lookupAll(AutoupdateClusterCreator.class).iterator(); it.hasNext(); ) {
537                 AutoupdateClusterCreator a = (AutoupdateClusterCreator)it.next();
538                 
539                 if (toCluster.equals(a.findCluster(toCluster.getName()))) {
540                         File[] allClusters;
541                         try {
542                             allClusters = a.registerCluster(toCluster.getName(), toCluster);
543                         } catch (IOException ex) {
544                             return false;
545                         }
546                     
547                     StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
548                     String JavaDoc sep = "";
549                     for (int i = 0; i < allClusters.length; i++) {
550                         sb.append(sep);
551                         sb.append(allClusters[i].getPath());
552                         sep = File.pathSeparator;
553                     }
554                     System.setProperty("netbeans.dirs", sb.toString()); // NOI18N
555

556                     break DO_CLUSTER;
557                 }
558             }
559             assert false;
560         }
561             
562         
563         
564         
565         File inst = new File (
566             Autoupdater.Support.getDownloadDirectory (mu.findInstallDirectory ()),
567             mu.getDistributionFilename()
568         );
569         
570         boolean ok = getNBM( mu ).renameTo( inst );
571         if ( ok )
572             return true;
573         
574         // issue 21607
575
ok = tryCopy( getNBM( mu ), inst );
576         if ( ok )
577             getNBM( mu ).delete();
578         
579         return ok;
580     }
581     
582     static void saveCopy( ModuleUpdate mu, File target ) {
583         tryCopy( getNBM( mu ), target );
584     }
585     
586     private static boolean tryCopy( File src, File dest ) {
587         BufferedInputStream bsrc = null;
588         BufferedOutputStream bdest = null;
589
590         try {
591             try {
592                 bsrc = new BufferedInputStream( new FileInputStream( src ), 4096 );
593                 bdest = new BufferedOutputStream( new FileOutputStream( dest ), 4096 );
594
595                 int c;
596                 while( ( c = bsrc.read() ) != -1 ) {
597                     bdest.write( c );
598                 }
599             }
600             finally {
601                 // workaround #39006, don't close a not opened stream
602
if (bsrc != null) bsrc.close();
603                 if (bdest != null) bdest.close();
604             }
605         }
606         catch ( IOException e ) {
607             return false;
608         }
609         return true;
610     }
611     
612     static void deleteModuleNBM( ModuleUpdate mu ) {
613         getNBM( mu ).delete();
614     }
615
616     // Deletes all files in download directory
617
static void deleteDownload() {
618         boolean noTestPrepared = true;
619         PreparedModules prepared = null;
620         
621         List JavaDoc/*<File>*/ clusters = UpdateTracking.clusters (true);
622         assert clusters != null : "Clusters cannot be empty."; // NOI18N
623
Iterator JavaDoc it = clusters.iterator ();
624         while (it.hasNext ()) {
625             if (Autoupdater.Support.getInstall_Later ((File)it.next ()).exists ()) {
626                 noTestPrepared = false;
627                 prepared = PreparedModules.getPrepared();
628             }
629         }
630         
631         File[] nbms = getNBMFiles();
632
633         for( int i = 0; i < nbms.length; i++ ) {
634             if ( noTestPrepared || !prepared.hasNBM( nbms[i].getName() ) )
635                 nbms[i].delete();
636         }
637     }
638     
639     static boolean bannedWriteToInstall(ModuleUpdate mu) {
640         File f = mu.findInstallDirectory ();
641         
642         return f == null || !f.canWrite();
643     }
644
645     private static File[] getNBMFiles() {
646         File dirList[] = Autoupdater.Support.getDownloadDirectory (null).listFiles( new FilenameFilter() {
647                              public boolean accept( File dir, String JavaDoc name ) {
648                                  return name.endsWith( NBM_EXTENSION );
649                              }
650                          });
651
652         return dirList;
653     }
654
655     private String JavaDoc getBundle( String JavaDoc key ) {
656         return NbBundle.getMessage( Downloader.class, key );
657     }
658     
659 }
660
Popular Tags