~motu-torrent/azureus/upstream-stable

« back to all changes in this revision

Viewing changes to org/gudy/azureus2/update/CoreUpdateChecker.java

  • Committer: John Dong
  • Date: 2007-10-22 04:54:13 UTC
  • Revision ID: john.dong@gmail.com-20071022045413-3ovb11u82rrcokxx
Commit 3.0.3.4

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 * Created on 20-May-2004
3
 
 * Created by Paul Gardner
4
 
 * Copyright (C) 2004, 2005, 2006 Aelitis, All Rights Reserved.
5
 
 *
6
 
 * This program is free software; you can redistribute it and/or
7
 
 * modify it under the terms of the GNU General Public License
8
 
 * as published by the Free Software Foundation; either version 2
9
 
 * of the License, or (at your option) any later version.
10
 
 * This program is distributed in the hope that it will be useful,
11
 
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 
 * GNU General Public License for more details.
14
 
 * You should have received a copy of the GNU General Public License
15
 
 * along with this program; if not, write to the Free Software
16
 
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
17
 
 * 
18
 
 * AELITIS, SAS au capital de 46,603.30 euros
19
 
 * 8 Allee Lenotre, La Grille Royale, 78600 Le Mesnil le Roi, France.
20
 
 *
21
 
 */
22
 
 
23
 
package org.gudy.azureus2.update;
24
 
 
25
 
/**
26
 
 * @author parg
27
 
 *
28
 
 */
29
 
 
30
 
import java.util.*;
31
 
import java.net.*;
32
 
import java.io.*;
33
 
 
34
 
import org.gudy.azureus2.core3.util.*;
35
 
import org.gudy.azureus2.core3.logging.*;
36
 
import org.gudy.azureus2.core3.logging.Logger;
37
 
import org.gudy.azureus2.core3.config.*;
38
 
import org.gudy.azureus2.core3.html.*;
39
 
 
40
 
import org.gudy.azureus2.plugins.*;
41
 
import org.gudy.azureus2.plugins.logging.*;
42
 
import org.gudy.azureus2.plugins.update.*;
43
 
import org.gudy.azureus2.plugins.utils.resourcedownloader.*;
44
 
 
45
 
import com.aelitis.azureus.core.versioncheck.*;
46
 
 
47
 
 
48
 
public class 
49
 
CoreUpdateChecker
50
 
        implements Plugin, UpdatableComponent
51
 
{               
52
 
        public static final String      LATEST_VERSION_PROPERTY = "latest_version";
53
 
        public static final String      MESSAGE_PROPERTY                = "message";
54
 
        
55
 
        public static final int RD_GET_DETAILS_RETRIES  = 3;
56
 
        public static final int RD_GET_MIRRORS_RETRIES  = 3;
57
 
        
58
 
        public static final int RD_SIZE_RETRIES = 3;
59
 
        public static final int RD_SIZE_TIMEOUT = 10000;
60
 
 
61
 
        protected static CoreUpdateChecker              singleton;
62
 
        
63
 
        protected PluginInterface                               plugin_interface;
64
 
        protected ResourceDownloaderFactory     rdf;
65
 
        protected LoggerChannel                                 log;
66
 
        protected ResourceDownloaderListener    rd_logger;
67
 
        
68
 
        protected boolean                                               first_check             = true;
69
 
        
70
 
        public static void
71
 
        doUsageStats()
72
 
        {
73
 
                singleton.doUsageStatsSupport();
74
 
        }
75
 
        
76
 
        public
77
 
        CoreUpdateChecker()
78
 
        {
79
 
                singleton       = this;
80
 
        }
81
 
        
82
 
        protected void
83
 
        doUsageStatsSupport()
84
 
        {
85
 
                try{
86
 
                        Map decoded = VersionCheckClient.getSingleton().getVersionCheckInfo(
87
 
                                                first_check?VersionCheckClient.REASON_UPDATE_CHECK_START:VersionCheckClient.REASON_UPDATE_CHECK_PERIODIC);
88
 
          
89
 
                        displayUserMessage( decoded );
90
 
                        
91
 
                }finally{
92
 
                        
93
 
                          first_check   = false;
94
 
                }
95
 
        }
96
 
 
97
 
        
98
 
        public void
99
 
        initialize(
100
 
                PluginInterface         _plugin_interface )
101
 
        {
102
 
                plugin_interface        = _plugin_interface;
103
 
                
104
 
                plugin_interface.getPluginProperties().setProperty( "plugin.name", "Core Updater" );
105
 
                
106
 
                log     = plugin_interface.getLogger().getChannel("CoreUpdater");
107
 
                
108
 
                rd_logger =
109
 
                        new ResourceDownloaderAdapter()
110
 
                        {
111
 
                                public void
112
 
                                reportActivity(
113
 
                                        ResourceDownloader      downloader,
114
 
                                        String                          activity )
115
 
                                {
116
 
                                        log.log( activity );
117
 
                                }
118
 
                        };
119
 
                        
120
 
                Properties      props = plugin_interface.getPluginProperties();
121
 
                                                        
122
 
                props.setProperty( "plugin.version", plugin_interface.getAzureusVersion());
123
 
                
124
 
                rdf = plugin_interface.getUtilities().getResourceDownloaderFactory();
125
 
        
126
 
                plugin_interface.getUpdateManager().registerUpdatableComponent( this, true );
127
 
        }
128
 
        
129
 
        public String
130
 
        getName()
131
 
        {
132
 
                return( "Azureus Core" );
133
 
        }
134
 
        
135
 
        public int
136
 
        getMaximumCheckTime()
137
 
        {
138
 
                return( ( RD_SIZE_RETRIES * RD_SIZE_TIMEOUT )/1000);
139
 
        }       
140
 
 
141
 
        public void
142
 
        checkForUpdate(
143
 
                final UpdateChecker     checker )
144
 
        {
145
 
                try{                    
146
 
                        String  current_version = plugin_interface.getAzureusVersion();
147
 
                        
148
 
                        log.log( "Update check starts: current = " + current_version );
149
 
                                                                                                        
150
 
                        Map     decoded = VersionCheckClient.getSingleton().getVersionCheckInfo(
151
 
                                        first_check?VersionCheckClient.REASON_UPDATE_CHECK_START:VersionCheckClient.REASON_UPDATE_CHECK_PERIODIC);
152
 
 
153
 
      
154
 
                        displayUserMessage( decoded );
155
 
                        
156
 
                        String latest_version;
157
 
                        String latest_file_name;
158
 
                        
159
 
                        byte[] b_version = (byte[])decoded.get("version");
160
 
                        
161
 
                        if ( b_version != null ){
162
 
                        
163
 
                                latest_version = new String( b_version );
164
 
                                
165
 
                                plugin_interface.getPluginProperties().setProperty( LATEST_VERSION_PROPERTY, latest_version );
166
 
                                
167
 
                        }else{
168
 
                                
169
 
                                throw( new Exception( "No version found in reply" ));
170
 
                        }
171
 
                        
172
 
                        byte[] b_filename = (byte[]) decoded.get("filename");
173
 
                        
174
 
                        if ( b_filename != null ){
175
 
                        
176
 
                                latest_file_name = new String( b_filename );
177
 
                                
178
 
                        }else{
179
 
                                
180
 
                                throw( new Exception( "No update file details in reply" ));
181
 
                        }
182
 
                        
183
 
                        //latest_version                = "3.0.0.3";
184
 
                        //latest_file_name      = "http://torrents.aelitis.com:88/torrents/Azureus2.5.0.0.jar.torrent";
185
 
                        //latest_file_name      = "Azureus2.5.0.0.jar.torrent";
186
 
                        
187
 
                        String  msg = "Core: latest_version = '" + latest_version + "', file = '" + latest_file_name + "'";
188
 
                        
189
 
                        URL             full_download_url;
190
 
                        
191
 
                                // since 2501 we support a full download URL, falling back to SF mirrors if this
192
 
                                // fails. 
193
 
                                        
194
 
                        if ( latest_file_name.startsWith( "http" )){
195
 
                                
196
 
                                try{
197
 
                                        full_download_url       = new URL( latest_file_name );
198
 
                                        
199
 
                                }catch( Throwable e ){
200
 
                                        
201
 
                                        full_download_url = null;
202
 
                                        
203
 
                                        log.log( e );
204
 
                                }
205
 
                                
206
 
                                int     pos = latest_file_name.lastIndexOf( '/' );
207
 
                                
208
 
                                latest_file_name = latest_file_name.substring( pos+1 );
209
 
                                
210
 
                        }else{
211
 
                                
212
 
                                full_download_url       = null;
213
 
                        }
214
 
                        
215
 
                        checker.reportProgress( msg );
216
 
                        
217
 
                        log.log( msg );
218
 
                        
219
 
                        if ( !shouldUpdate( current_version, latest_version )){
220
 
                                
221
 
                                return;
222
 
                        }
223
 
                                
224
 
                        final String    f_latest_version        = latest_version;
225
 
                        final String    f_latest_file_name      = latest_file_name;
226
 
                        
227
 
                        ResourceDownloader      top_downloader;
228
 
                        
229
 
                        if ( full_download_url == null ){
230
 
                                
231
 
                                ResourceDownloader[]    primary_mirrors;
232
 
                                        
233
 
                                primary_mirrors = getPrimaryDownloaders( latest_file_name );
234
 
        
235
 
                                        // the download hierarchy is primary mirrors first (randomised alternate)
236
 
                                        // then backup mirrors (randomised alternate)
237
 
                                
238
 
                                        // we don't want to load the backup mirrors until the primary mirrors fail
239
 
                                
240
 
                                ResourceDownloader              random_primary_mirrors = rdf.getRandomDownloader( primary_mirrors );
241
 
                                
242
 
                                ResourceDownloader              backup_downloader =
243
 
                                        rdf.create(
244
 
                                                new ResourceDownloaderDelayedFactory()
245
 
                                                {
246
 
                                                        public ResourceDownloader
247
 
                                                        create()
248
 
                                                        {
249
 
                                                                ResourceDownloader[]    backup_mirrors = getBackupDownloaders( f_latest_file_name );
250
 
                                                        
251
 
                                                                return( rdf.getRandomDownloader( backup_mirrors ));
252
 
                                                        }
253
 
                                                });
254
 
                                                                
255
 
                                top_downloader = 
256
 
                                        rdf.getAlternateDownloader( 
257
 
                                                        new ResourceDownloader[]
258
 
                                                                {
259
 
                                                                        random_primary_mirrors,
260
 
                                                                        backup_downloader,
261
 
                                                                });
262
 
 
263
 
                        }else{
264
 
                                
265
 
                                ResourceDownloader full_rd = rdf.create( full_download_url );
266
 
                                
267
 
                                full_rd = rdf.getSuffixBasedDownloader( full_rd );
268
 
                                
269
 
                                ResourceDownloader              primary_downloader =
270
 
                                        rdf.create(
271
 
                                                new ResourceDownloaderDelayedFactory()
272
 
                                                {
273
 
                                                        public ResourceDownloader
274
 
                                                        create()
275
 
                                                        {
276
 
                                                                ResourceDownloader[]    primary_mirrors = getPrimaryDownloaders( f_latest_file_name );
277
 
                                                        
278
 
                                                                return( rdf.getRandomDownloader( primary_mirrors ));
279
 
                                                        }
280
 
                                                });
281
 
                                        
282
 
                                ResourceDownloader              backup_downloader =
283
 
                                        rdf.create(
284
 
                                                new ResourceDownloaderDelayedFactory()
285
 
                                                {
286
 
                                                        public ResourceDownloader
287
 
                                                        create()
288
 
                                                        {
289
 
                                                                ResourceDownloader[]    backup_mirrors = getBackupDownloaders( f_latest_file_name );
290
 
                                                        
291
 
                                                                return( rdf.getRandomDownloader( backup_mirrors ));
292
 
                                                        }
293
 
                                                });
294
 
                                
295
 
                                
296
 
                                top_downloader = 
297
 
                                        rdf.getAlternateDownloader( 
298
 
                                                        new ResourceDownloader[]
299
 
                                                                {
300
 
                                                                        full_rd,
301
 
                                                                        primary_downloader,
302
 
                                                                        backup_downloader,
303
 
                                                                });
304
 
                        }
305
 
                        
306
 
                        top_downloader.addListener( rd_logger );
307
 
                        
308
 
                                // get size so it is cached
309
 
                        
310
 
                        top_downloader.getSize();               
311
 
                                                        
312
 
 
313
 
                        byte[]  info_b = (byte[])decoded.get( "info" );
314
 
                        
315
 
                        String  info = null;
316
 
                        
317
 
                        if ( info_b != null ){
318
 
                        
319
 
                                try{
320
 
                                        info = new String( info_b );
321
 
                                
322
 
                                }catch( Throwable e ){
323
 
                                        
324
 
                                        Debug.printStackTrace( e );
325
 
                                }
326
 
                        }
327
 
                        
328
 
                        String[]        desc;
329
 
                        
330
 
                        if ( info == null ){
331
 
                                
332
 
                                desc = new String[]{"Core Azureus Version" };
333
 
                                
334
 
                        }else{
335
 
                                
336
 
                                desc = new String[]{"Core Azureus Version", info };
337
 
                        }
338
 
                        
339
 
                        final Update update = 
340
 
                                checker.addUpdate(
341
 
                                                "Core Azureus Version",
342
 
                                                desc,
343
 
                                                latest_version,
344
 
                                                top_downloader,
345
 
                                                Update.RESTART_REQUIRED_YES );
346
 
                        
347
 
                        top_downloader.addListener( 
348
 
                                        new ResourceDownloaderAdapter()
349
 
                                        {
350
 
                                                public boolean
351
 
                                                completed(
352
 
                                                        final ResourceDownloader        downloader,
353
 
                                                        InputStream                                     data )
354
 
                                                {       
355
 
                                                        installUpdate( checker, update, downloader, f_latest_version, data );
356
 
                                                                        
357
 
                                                        return( true );
358
 
                                                }
359
 
                                        });
360
 
                }catch( Throwable e ){
361
 
                        
362
 
                        log.log( e );
363
 
                        
364
 
                        Debug.printStackTrace( e );
365
 
                        
366
 
                        checker.failed();
367
 
                        
368
 
                }finally{
369
 
                        
370
 
                        checker.completed();
371
 
                        
372
 
                        first_check = false;
373
 
                }
374
 
        }
375
 
        
376
 
      
377
 
  
378
 
  
379
 
  /**
380
 
   * Log and display a user message if contained within reply.
381
 
   * @param reply from server
382
 
   */
383
 
  private void displayUserMessage( Map reply ) {
384
 
    //  pick up any user message in the reply
385
 
    
386
 
    try{
387
 
      byte[]  message = (byte[])reply.get( "message" );
388
 
          
389
 
      if ( message != null && message.length > 0 ){
390
 
        
391
 
        String  s_message = new String(message);
392
 
        
393
 
        String  last = COConfigurationManager.getStringParameter( "CoreUpdateChecker.lastmessage", "" );
394
 
        
395
 
        if ( !s_message.equals( last )){
396
 
          
397
 
          byte[]        signature = (byte[])reply.get( "message_sig" );
398
 
          
399
 
          if ( signature == null ){
400
 
                  
401
 
                  Logger.log( new LogEvent( LogIDs.LOGGER, "Signature missing from message" ));
402
 
                  
403
 
                  return;
404
 
          }
405
 
          
406
 
          try{
407
 
                  AEVerifier.verifyData( s_message, signature );
408
 
                  
409
 
          }catch( Throwable e ){
410
 
                  
411
 
                  Logger.log( new LogEvent( LogIDs.LOGGER, "Message signature check failed", e  ));
412
 
                      
413
 
                  return;
414
 
          }
415
 
          
416
 
          int   alert_type    = LogAlert.AT_WARNING;
417
 
          String  alert_text    = s_message;
418
 
          
419
 
          if ( alert_text.startsWith("i:" )){
420
 
          
421
 
            alert_type = LogAlert.AT_INFORMATION;
422
 
            
423
 
            alert_text = alert_text.substring(2);
424
 
          }
425
 
          
426
 
          plugin_interface.getPluginProperties().setProperty( MESSAGE_PROPERTY, alert_text );
427
 
 
428
 
 
429
 
          Logger.log(new LogAlert(LogAlert.UNREPEATABLE, alert_type, alert_text));
430
 
          
431
 
          COConfigurationManager.setParameter( "CoreUpdateChecker.lastmessage", s_message );
432
 
          
433
 
          COConfigurationManager.save();
434
 
        }
435
 
      }
436
 
    }catch( Throwable e ){
437
 
      
438
 
      Debug.printStackTrace( e );
439
 
    }
440
 
  } 
441
 
        
442
 
        protected ResourceDownloader[]
443
 
        getPrimaryDownloaders(
444
 
                String          latest_file_name )
445
 
        {
446
 
                log.log( "Downloading primary mirrors" );
447
 
                
448
 
                List    res = new ArrayList();
449
 
 
450
 
                try{
451
 
                        if ( latest_file_name == null ){
452
 
                
453
 
                                        // very old method, non-mirror based
454
 
                                
455
 
                                res.add( new URL( Constants.SF_WEB_SITE + "Azureus2.jar" ));
456
 
                                                                
457
 
                        }else{
458
 
                
459
 
                                URL mirrors_url = new URL("http://prdownloads.sourceforge.net/azureus/" + latest_file_name + "?download");
460
 
                                
461
 
                                ResourceDownloader      rd = rdf.create( mirrors_url );
462
 
                                
463
 
                                rd = rdf.getRetryDownloader( rd, RD_GET_MIRRORS_RETRIES );
464
 
                                
465
 
                                rd.addListener( rd_logger );
466
 
                                
467
 
                                String  page = HTMLPageFactory.loadPage( rd.download()).getContent();
468
 
                                
469
 
                                String pattern = "/azureus/" + latest_file_name + "?use_mirror=";
470
 
             
471
 
                                int position = page.indexOf(pattern);
472
 
                                
473
 
                                while ( position > 0 ){
474
 
                                        
475
 
                                        int end = page.indexOf(">", position);
476
 
                                        
477
 
                                        if (end < 0) {
478
 
                                                
479
 
                                                position = -1;
480
 
                                                
481
 
                                        }else{
482
 
                                                
483
 
                                                String mirror = page.substring(position, end);
484
 
                                                
485
 
                                                if ( mirror.endsWith("\"")){
486
 
                                                        
487
 
                                                        mirror = mirror.substring(0,mirror.length()-1);
488
 
                                                }
489
 
                                                
490
 
                                                try{
491
 
                                                        res.add( new URL( "http://prdownloads.sourceforge.net" + mirror ));
492
 
                                                        
493
 
                                                }catch( Throwable e ){
494
 
                                                        
495
 
                                                        log.log( "Invalid URL read:" + mirror, e );
496
 
                                                }
497
 
                  
498
 
                                                position = page.indexOf(pattern, position + 1);
499
 
                                        }
500
 
                                }
501
 
                        }
502
 
                }catch( Throwable e ){
503
 
                        
504
 
                        log.log( "Failed to read primary mirror list", e );
505
 
                }
506
 
                
507
 
                ResourceDownloader[]    dls = new ResourceDownloader[res.size()];
508
 
                                
509
 
                for (int i=0;i<res.size();i++){
510
 
                        
511
 
                        URL     url =(URL)res.get(i);
512
 
                        
513
 
                        log.log( "    Primary mirror:" +url.toString());
514
 
                        
515
 
                        ResourceDownloader dl = rdf.create( url );
516
 
                        
517
 
                        dl = rdf.getMetaRefreshDownloader( dl );
518
 
                        
519
 
                                // add in a layer to do torrent based downloads if url ends with .torrent
520
 
                        
521
 
                        dl = rdf.getSuffixBasedDownloader( dl );
522
 
                        
523
 
                        dls[i] = dl;
524
 
                }
525
 
                
526
 
                return( dls );
527
 
        }
528
 
        
529
 
        protected ResourceDownloader[]
530
 
        getBackupDownloaders(
531
 
                String  latest_file_name )
532
 
        {
533
 
                List    res = new ArrayList();
534
 
        
535
 
                try{
536
 
                        if ( latest_file_name != null ){
537
 
                                                        
538
 
                                log.log( "Downloading backup mirrors" );
539
 
                                
540
 
                                URL mirrors_url = new URL("http://azureus.sourceforge.net/mirrors.php");
541
 
                                
542
 
                                ResourceDownloader      rd = rdf.create( mirrors_url );
543
 
                                
544
 
                                rd = rdf.getRetryDownloader( rd, RD_GET_MIRRORS_RETRIES );
545
 
                                
546
 
                                rd.addListener( rd_logger );
547
 
                                
548
 
                                BufferedInputStream     data = new BufferedInputStream(rd.download());
549
 
                                
550
 
                                Map decoded = BDecoder.decode(data);
551
 
                                
552
 
                                data.close();
553
 
                                
554
 
                                List mirrors = (List)decoded.get("mirrors");
555
 
                
556
 
                                for (int i=0;i<mirrors.size();i++){
557
 
                                        
558
 
                                        String mirror = new String( (byte[])mirrors.get(i));
559
 
                                        
560
 
                                        try{
561
 
                                                
562
 
                                                res.add( new URL( mirror + latest_file_name ));
563
 
                                                // res.add( new URL( "http://torrents.aelitis.com:88/torrents/Azureus2.4.0.2_signed.jar.torrent" ));
564
 
                                                
565
 
                                        }catch(Throwable e){
566
 
                                                
567
 
                                                log.log( "Invalid URL read:" + mirror, e );
568
 
                                        }
569
 
                                }
570
 
                        }
571
 
                }catch( Throwable e ){
572
 
                        
573
 
                        log.log( "Failed to read backup mirror list", e );
574
 
                }
575
 
                
576
 
                ResourceDownloader[]    dls = new ResourceDownloader[res.size()];
577
 
                
578
 
                for (int i=0;i<res.size();i++){
579
 
                        
580
 
                        URL     url =(URL)res.get(i);
581
 
                        
582
 
                        log.log( "    Backup mirror:" +url.toString());
583
 
                        
584
 
                        ResourceDownloader dl = rdf.create( url );
585
 
 
586
 
                                // add in .torrent decoder if appropriate
587
 
                        
588
 
                        dl = rdf.getSuffixBasedDownloader( dl );
589
 
 
590
 
                        dls[i] = dl;
591
 
                }
592
 
                
593
 
                return( dls );
594
 
        }               
595
 
 
596
 
        protected void
597
 
        installUpdate(
598
 
                UpdateChecker           checker,
599
 
                Update                          update,
600
 
                ResourceDownloader      rd,
601
 
                String                          version,
602
 
                InputStream                     data )
603
 
        {
604
 
                try{
605
 
                        data = update.verifyData( data, true );
606
 
 
607
 
                        rd.reportActivity( "Data verified successfully" );
608
 
                        
609
 
                        String  temp_jar_name   = "Azureus2_" + version + ".jar";
610
 
                        String  target_jar_name = "Azureus2.jar";
611
 
                        
612
 
                        UpdateInstaller installer = checker.createInstaller();
613
 
                        
614
 
                        installer.addResource( temp_jar_name, data );
615
 
                        
616
 
                        if ( Constants.isOSX ){
617
 
                                
618
 
                                installer.addMoveAction( 
619
 
                                        temp_jar_name,
620
 
                                        installer.getInstallDir() + "/" + SystemProperties.getApplicationName() + ".app/Contents/Resources/Java/" + target_jar_name );        
621
 
                        }else{
622
 
                                
623
 
                                installer.addMoveAction( 
624
 
                                        temp_jar_name,
625
 
                                        installer.getInstallDir() + File.separator + target_jar_name );
626
 
                        }
627
 
                }catch( Throwable e ){
628
 
                        
629
 
                        rd.reportActivity("Update install failed:" + e.getMessage());
630
 
                }
631
 
        }
632
 
        
633
 
        protected static boolean
634
 
        shouldUpdate(
635
 
                String  current_version,
636
 
                String  latest_version )
637
 
        {
638
 
                String  current_base    = Constants.getBaseVersion( current_version );
639
 
                int             current_inc             = Constants.getIncrementalBuild( current_version );
640
 
 
641
 
                String  latest_base     = Constants.getBaseVersion( latest_version );
642
 
                int             latest_inc      = Constants.getIncrementalBuild( latest_version );
643
 
                        
644
 
                        // currently we upgrade from, for example
645
 
                        //  1) 2.4.0.0     -> 2.4.0.2
646
 
                        //      2) 2.4.0.1_CVS -> 2.4.0.2
647
 
                        //      3) 2.4.0.1_B12 -> 2.4.0.2  and 2.4.0.1_B14
648
 
                
649
 
                        // but NOT
650
 
                        //  1) 2.4.0.0     -> 2.4.0.1_CVS or 2.4.0.1_B23
651
 
                        //  2) 2.4.0.1_CVS -> 2.4.0.1_B23
652
 
                
653
 
                        // for inc values: 0 = not CVS, -1 = _CVS, > 0 = Bnn
654
 
 
655
 
                int     major_comp = Constants.compareVersions( current_base, latest_base );
656
 
                
657
 
                if ( major_comp < 0 && latest_inc == 0 ){
658
 
                        
659
 
                        return( true );         // latest is higher version and not CVS
660
 
                }
661
 
                
662
 
                        // same version, both are B versions and latest B is more recent
663
 
                
664
 
                return( major_comp == 0 && current_inc > 0 && latest_inc > 0 && latest_inc > current_inc );
665
 
        }
666
 
        
667
 
        public static void
668
 
        main(
669
 
                String[]        args )
670
 
        {
671
 
                String[][]      tests = {
672
 
                                { "2.4.0.0",            "2.4.0.2",              "true" },
673
 
                                { "2.4.0.1_CVS",        "2.4.0.2",              "true" },
674
 
                                { "2.4.0.1_B12",        "2.4.0.2",              "true" },
675
 
                                { "2.4.0.1_B12",        "2.4.0.1_B34",  "true" },
676
 
                                { "2.4.0.1_B12",        "2.4.0.1_B6",   "false" },
677
 
                                { "2.4.0.0",            "2.4.0.1_CVS",  "false" },
678
 
                                { "2.4.0.0",            "2.4.0.1_B12",  "false" },
679
 
                                { "2.4.0.0",            "2.4.0.0"       ,       "false" },
680
 
                                { "2.4.0.1_CVS",        "2.4.0.1_CVS",  "false" },
681
 
                                { "2.4.0.1_B2",         "2.4.0.1_B2",   "false" },
682
 
                                { "2.4.0.1_CVS",        "2.4.0.1_B2",   "false" },
683
 
                                { "2.4.0.1_B2",         "2.4.0.1_CVS",  "false" },
684
 
 
685
 
                };
686
 
 
687
 
                for (int i=0;i<tests.length;i++){
688
 
                        
689
 
                        System.out.println( shouldUpdate(tests[i][0],tests[i][1]) + " / " + tests[i][2] );
690
 
                }
691
 
                
692
 
                /*
693
 
                AEDiagnostics.startup();
694
 
                
695
 
                CoreUpdateChecker       checker = new CoreUpdateChecker();
696
 
                
697
 
                checker.log = new LoggerImpl(null).getTimeStampedChannel("");
698
 
                checker.rdf     = new ResourceDownloaderFactoryImpl();
699
 
                checker.rd_logger = 
700
 
                        new ResourceDownloaderAdapter()
701
 
                        {
702
 
                                public void
703
 
                                reportActivity(
704
 
                                        ResourceDownloader      downloader,
705
 
                                        String                          activity )
706
 
                                {
707
 
                                        System.out.println( activity );
708
 
                                }
709
 
                                
710
 
                                public void
711
 
                                reportPercentComplete(
712
 
                                        ResourceDownloader      downloader,
713
 
                                        int                                     percentage )
714
 
                                {
715
 
                                        System.out.println( "    % = " + percentage );
716
 
                                }
717
 
                        };
718
 
                        
719
 
                ResourceDownloader[]    primaries = checker.getPrimaryDownloaders( "Azureus-2.0.3.0.jar" );
720
 
                
721
 
                for (int i=0;i<primaries.length;i++){
722
 
                        
723
 
                        System.out.println( "primary: " + primaries[i].getName());
724
 
                }
725
 
                
726
 
                try{
727
 
                        ResourceDownloader      rd = primaries[0];
728
 
                        
729
 
                        rd.addListener( checker.rd_logger );
730
 
                        
731
 
                        rd.download();
732
 
                        
733
 
                        System.out.println( "done" );
734
 
                        
735
 
                }catch( Throwable e ){
736
 
                        
737
 
                        e.printStackTrace();
738
 
                }
739
 
                */
740
 
        }
741
 
}
 
1
/*
 
2
 * Created on 20-May-2004
 
3
 * Created by Paul Gardner
 
4
 * Copyright (C) 2004, 2005, 2006 Aelitis, All Rights Reserved.
 
5
 *
 
6
 * This program is free software; you can redistribute it and/or
 
7
 * modify it under the terms of the GNU General Public License
 
8
 * as published by the Free Software Foundation; either version 2
 
9
 * of the License, or (at your option) any later version.
 
10
 * This program is distributed in the hope that it will be useful,
 
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
13
 * GNU General Public License for more details.
 
14
 * You should have received a copy of the GNU General Public License
 
15
 * along with this program; if not, write to the Free Software
 
16
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 
17
 * 
 
18
 * AELITIS, SAS au capital de 46,603.30 euros
 
19
 * 8 Allee Lenotre, La Grille Royale, 78600 Le Mesnil le Roi, France.
 
20
 *
 
21
 */
 
22
 
 
23
package org.gudy.azureus2.update;
 
24
 
 
25
/**
 
26
 * @author parg
 
27
 *
 
28
 */
 
29
 
 
30
import java.util.*;
 
31
import java.net.*;
 
32
import java.io.*;
 
33
 
 
34
import org.gudy.azureus2.core3.util.*;
 
35
import org.gudy.azureus2.core3.logging.*;
 
36
import org.gudy.azureus2.core3.logging.Logger;
 
37
import org.gudy.azureus2.core3.config.*;
 
38
import org.gudy.azureus2.core3.html.*;
 
39
 
 
40
import org.gudy.azureus2.plugins.*;
 
41
import org.gudy.azureus2.plugins.logging.*;
 
42
import org.gudy.azureus2.plugins.update.*;
 
43
import org.gudy.azureus2.plugins.utils.resourcedownloader.*;
 
44
 
 
45
import com.aelitis.azureus.core.versioncheck.*;
 
46
import com.aelitis.azureus.ui.UIFunctions;
 
47
import com.aelitis.azureus.ui.UIFunctionsManager;
 
48
 
 
49
 
 
50
public class 
 
51
CoreUpdateChecker
 
52
        implements Plugin, UpdatableComponent
 
53
{               
 
54
        public static final String      LATEST_VERSION_PROPERTY = "latest_version";
 
55
        public static final String      MESSAGE_PROPERTY                = "message";
 
56
        
 
57
        public static final int RD_GET_DETAILS_RETRIES  = 3;
 
58
        public static final int RD_GET_MIRRORS_RETRIES  = 3;
 
59
        
 
60
        public static final int RD_SIZE_RETRIES = 3;
 
61
        public static final int RD_SIZE_TIMEOUT = 10000;
 
62
 
 
63
        protected static CoreUpdateChecker              singleton;
 
64
        
 
65
        protected PluginInterface                               plugin_interface;
 
66
        protected ResourceDownloaderFactory     rdf;
 
67
        protected LoggerChannel                                 log;
 
68
        protected ResourceDownloaderListener    rd_logger;
 
69
        
 
70
        protected boolean                                               first_check             = true;
 
71
        
 
72
        public static void
 
73
        doUsageStats()
 
74
        {
 
75
                singleton.doUsageStatsSupport();
 
76
        }
 
77
        
 
78
        public
 
79
        CoreUpdateChecker()
 
80
        {
 
81
                singleton       = this;
 
82
        }
 
83
        
 
84
        protected void
 
85
        doUsageStatsSupport()
 
86
        {
 
87
                try{
 
88
                        Map decoded = VersionCheckClient.getSingleton().getVersionCheckInfo(
 
89
                                                first_check?VersionCheckClient.REASON_UPDATE_CHECK_START:VersionCheckClient.REASON_UPDATE_CHECK_PERIODIC);
 
90
          
 
91
                        displayUserMessage( decoded );
 
92
                        
 
93
                }finally{
 
94
                        
 
95
                          first_check   = false;
 
96
                }
 
97
        }
 
98
 
 
99
        
 
100
        public void
 
101
        initialize(
 
102
                PluginInterface         _plugin_interface )
 
103
        {
 
104
                plugin_interface        = _plugin_interface;
 
105
                
 
106
                plugin_interface.getPluginProperties().setProperty( "plugin.name", "Core Updater" );
 
107
                
 
108
                log     = plugin_interface.getLogger().getChannel("CoreUpdater");
 
109
                
 
110
                rd_logger =
 
111
                        new ResourceDownloaderAdapter()
 
112
                        {
 
113
                                public void
 
114
                                reportActivity(
 
115
                                        ResourceDownloader      downloader,
 
116
                                        String                          activity )
 
117
                                {
 
118
                                        log.log( activity );
 
119
                                }
 
120
                        };
 
121
                        
 
122
                Properties      props = plugin_interface.getPluginProperties();
 
123
                                                        
 
124
                props.setProperty( "plugin.version", plugin_interface.getAzureusVersion());
 
125
                
 
126
                rdf = plugin_interface.getUtilities().getResourceDownloaderFactory();
 
127
        
 
128
                plugin_interface.getUpdateManager().registerUpdatableComponent( this, true );
 
129
        }
 
130
        
 
131
        public String
 
132
        getName()
 
133
        {
 
134
                return( "Azureus Core" );
 
135
        }
 
136
        
 
137
        public int
 
138
        getMaximumCheckTime()
 
139
        {
 
140
                return( ( RD_SIZE_RETRIES * RD_SIZE_TIMEOUT )/1000);
 
141
        }       
 
142
 
 
143
        public void
 
144
        checkForUpdate(
 
145
                final UpdateChecker     checker )
 
146
        {
 
147
                try{                    
 
148
                        String  current_version = plugin_interface.getAzureusVersion();
 
149
                        
 
150
                        log.log( "Update check starts: current = " + current_version );
 
151
                                                                                                        
 
152
                        Map     decoded = VersionCheckClient.getSingleton().getVersionCheckInfo(
 
153
                                        first_check?VersionCheckClient.REASON_UPDATE_CHECK_START:VersionCheckClient.REASON_UPDATE_CHECK_PERIODIC);
 
154
 
 
155
      
 
156
                        displayUserMessage( decoded );
 
157
                        
 
158
                        String latest_version;
 
159
                        String latest_file_name;
 
160
                        
 
161
                        byte[] b_version = (byte[])decoded.get("version");
 
162
                        
 
163
                        if ( b_version != null ){
 
164
                        
 
165
                                latest_version = new String( b_version );
 
166
                                
 
167
                                plugin_interface.getPluginProperties().setProperty( LATEST_VERSION_PROPERTY, latest_version );
 
168
                                
 
169
                        }else{
 
170
                                
 
171
                                throw( new Exception( "No version found in reply" ));
 
172
                        }
 
173
                        
 
174
                        byte[] b_filename = (byte[]) decoded.get("filename");
 
175
                        
 
176
                        if ( b_filename != null ){
 
177
                        
 
178
                                latest_file_name = new String( b_filename );
 
179
                                
 
180
                        }else{
 
181
                                
 
182
                                throw( new Exception( "No update file details in reply" ));
 
183
                        }
 
184
                        
 
185
                        //latest_version                = "3.0.0.3";
 
186
                        //latest_file_name      = "http://torrents.aelitis.com:88/torrents/Azureus2.5.0.0.jar.torrent";
 
187
                        //latest_file_name      = "Azureus2.5.0.0.jar.torrent";
 
188
                        
 
189
                        String  msg = "Core: latest_version = '" + latest_version + "', file = '" + latest_file_name + "'";
 
190
                        
 
191
                        URL             full_download_url;
 
192
                        
 
193
                                // since 2501 we support a full download URL, falling back to SF mirrors if this
 
194
                                // fails. 
 
195
                                        
 
196
                        if ( latest_file_name.startsWith( "http" )){
 
197
                                
 
198
                                try{
 
199
                                        full_download_url       = new URL( latest_file_name );
 
200
                                        
 
201
                                }catch( Throwable e ){
 
202
                                        
 
203
                                        full_download_url = null;
 
204
                                        
 
205
                                        log.log( e );
 
206
                                }
 
207
                                
 
208
                                int     pos = latest_file_name.lastIndexOf( '/' );
 
209
                                
 
210
                                latest_file_name = latest_file_name.substring( pos+1 );
 
211
                                
 
212
                        }else{
 
213
                                
 
214
                                full_download_url       = null;
 
215
                        }
 
216
                        
 
217
                        checker.reportProgress( msg );
 
218
                        
 
219
                        log.log( msg );
 
220
                        
 
221
                        if ( !shouldUpdate( current_version, latest_version )){
 
222
                                
 
223
                                return;
 
224
                        }
 
225
                                
 
226
                        final String    f_latest_version        = latest_version;
 
227
                        final String    f_latest_file_name      = latest_file_name;
 
228
                        
 
229
                        ResourceDownloader      top_downloader;
 
230
                        
 
231
                        if ( full_download_url == null ){
 
232
                                
 
233
                                ResourceDownloader[]    primary_mirrors;
 
234
                                        
 
235
                                primary_mirrors = getPrimaryDownloaders( latest_file_name );
 
236
        
 
237
                                        // the download hierarchy is primary mirrors first (randomised alternate)
 
238
                                        // then backup mirrors (randomised alternate)
 
239
                                
 
240
                                        // we don't want to load the backup mirrors until the primary mirrors fail
 
241
                                
 
242
                                ResourceDownloader              random_primary_mirrors = rdf.getRandomDownloader( primary_mirrors );
 
243
                                
 
244
                                ResourceDownloader              backup_downloader =
 
245
                                        rdf.create(
 
246
                                                new ResourceDownloaderDelayedFactory()
 
247
                                                {
 
248
                                                        public ResourceDownloader
 
249
                                                        create()
 
250
                                                        {
 
251
                                                                ResourceDownloader[]    backup_mirrors = getBackupDownloaders( f_latest_file_name );
 
252
                                                        
 
253
                                                                return( rdf.getRandomDownloader( backup_mirrors ));
 
254
                                                        }
 
255
                                                });
 
256
                                                                
 
257
                                top_downloader = 
 
258
                                        rdf.getAlternateDownloader( 
 
259
                                                        new ResourceDownloader[]
 
260
                                                                {
 
261
                                                                        random_primary_mirrors,
 
262
                                                                        backup_downloader,
 
263
                                                                });
 
264
 
 
265
                        }else{
 
266
                                
 
267
                                ResourceDownloader full_rd = rdf.create( full_download_url );
 
268
                                
 
269
                                full_rd = rdf.getSuffixBasedDownloader( full_rd );
 
270
                                
 
271
                                ResourceDownloader              primary_downloader =
 
272
                                        rdf.create(
 
273
                                                new ResourceDownloaderDelayedFactory()
 
274
                                                {
 
275
                                                        public ResourceDownloader
 
276
                                                        create()
 
277
                                                        {
 
278
                                                                ResourceDownloader[]    primary_mirrors = getPrimaryDownloaders( f_latest_file_name );
 
279
                                                        
 
280
                                                                return( rdf.getRandomDownloader( primary_mirrors ));
 
281
                                                        }
 
282
                                                });
 
283
                                        
 
284
                                ResourceDownloader              backup_downloader =
 
285
                                        rdf.create(
 
286
                                                new ResourceDownloaderDelayedFactory()
 
287
                                                {
 
288
                                                        public ResourceDownloader
 
289
                                                        create()
 
290
                                                        {
 
291
                                                                ResourceDownloader[]    backup_mirrors = getBackupDownloaders( f_latest_file_name );
 
292
                                                        
 
293
                                                                return( rdf.getRandomDownloader( backup_mirrors ));
 
294
                                                        }
 
295
                                                });
 
296
                                
 
297
                                
 
298
                                top_downloader = 
 
299
                                        rdf.getAlternateDownloader( 
 
300
                                                        new ResourceDownloader[]
 
301
                                                                {
 
302
                                                                        full_rd,
 
303
                                                                        primary_downloader,
 
304
                                                                        backup_downloader,
 
305
                                                                });
 
306
                        }
 
307
                        
 
308
                        top_downloader.addListener( rd_logger );
 
309
                        
 
310
                                // get size so it is cached
 
311
                        
 
312
                        top_downloader.getSize();               
 
313
                                                        
 
314
 
 
315
                        byte[]  info_b = (byte[])decoded.get( "info" );
 
316
                        
 
317
                        String  info = null;
 
318
                        
 
319
                        if ( info_b != null ){
 
320
                        
 
321
                                try{
 
322
                                        info = new String( info_b );
 
323
                                
 
324
                                }catch( Throwable e ){
 
325
                                        
 
326
                                        Debug.printStackTrace( e );
 
327
                                }
 
328
                        }
 
329
                        
 
330
                        byte[] info_url_bytes = (byte[])decoded.get("info_url");
 
331
                        
 
332
                        String info_url = null;
 
333
                        
 
334
                        if ( info_url_bytes != null ){
 
335
                                
 
336
                                try{
 
337
                                        info_url = new String( info_url_bytes );
 
338
                                        
 
339
                                }catch( Exception e ){
 
340
                                        
 
341
                                        Debug.out(e);
 
342
                                }
 
343
                        }
 
344
                        
 
345
                        if ( info != null || info_url != null ){
 
346
                                
 
347
                                String  check;
 
348
                                
 
349
                                if ( info == null ){
 
350
                                        
 
351
                                        check = info_url;
 
352
                                        
 
353
                                }else if ( info_url == null ){
 
354
                                        
 
355
                                        check = info;
 
356
                                        
 
357
                                }else{
 
358
                                        
 
359
                                        check = info + "|" + info_url;
 
360
                                }
 
361
                                
 
362
                                byte[]  sig = (byte[])decoded.get( "info_sig" );
 
363
 
 
364
                                boolean ok = false;
 
365
                                
 
366
                                if ( sig == null ){
 
367
                                
 
368
                                        Logger.log( new LogEvent( LogIDs.LOGGER, "info signature check failed - missing signature" ));
 
369
 
 
370
                                }else{
 
371
                                        
 
372
                                        try{
 
373
                                                AEVerifier.verifyData( check, sig );
 
374
 
 
375
                                                ok = true;
 
376
                                                
 
377
                                        }catch( Throwable e ){
 
378
 
 
379
                                                Logger.log( new LogEvent( LogIDs.LOGGER, "info signature check failed", e  ));
 
380
                                        }                       
 
381
                                }
 
382
                                
 
383
                                if ( !ok ){
 
384
                                        
 
385
                                        info            = null;
 
386
                                        info_url        = null;
 
387
                                }
 
388
                        }
 
389
                        
 
390
                        String[]        desc;
 
391
                        
 
392
                        if ( info == null ){
 
393
                                
 
394
                                desc = new String[]{"Core Azureus Version" };
 
395
                                
 
396
                        }else{
 
397
                                
 
398
                                desc = new String[]{"Core Azureus Version", info };
 
399
                        }
 
400
                        
 
401
 
 
402
 
 
403
                        final Update update = 
 
404
                                checker.addUpdate(
 
405
                                                "Core Azureus Version",
 
406
                                                desc,
 
407
                                                latest_version,
 
408
                                                top_downloader,
 
409
                                                Update.RESTART_REQUIRED_YES );
 
410
                        
 
411
                        if ( info_url != null ){
 
412
                                
 
413
                                update.setDescriptionURL(info_url);
 
414
                        }
 
415
                        
 
416
                        top_downloader.addListener( 
 
417
                                        new ResourceDownloaderAdapter()
 
418
                                        {
 
419
                                                public boolean
 
420
                                                completed(
 
421
                                                        final ResourceDownloader        downloader,
 
422
                                                        InputStream                                     data )
 
423
                                                {       
 
424
                                                        installUpdate( checker, update, downloader, f_latest_version, data );
 
425
                                                                        
 
426
                                                        return( true );
 
427
                                                }
 
428
                                        });
 
429
                }catch( Throwable e ){
 
430
                        
 
431
                        log.log( e );
 
432
                        
 
433
                        Debug.printStackTrace( e );
 
434
                        
 
435
                        checker.failed();
 
436
                        
 
437
                }finally{
 
438
                        
 
439
                        checker.completed();
 
440
                        
 
441
                        first_check = false;
 
442
                }
 
443
        }
 
444
        
 
445
      
 
446
  
 
447
  
 
448
  /**
 
449
   * Log and display a user message if contained within reply.
 
450
   * @param reply from server
 
451
   */
 
452
  private void 
 
453
  displayUserMessage( 
 
454
        Map reply ) 
 
455
  {
 
456
          //  pick up any user message in the reply
 
457
 
 
458
          try{
 
459
                  Iterator it = reply.keySet().iterator();
 
460
                  
 
461
                  while( it.hasNext()){
 
462
                          
 
463
                          String        key = (String)it.next();
 
464
                  
 
465
                                // support message + message_sig
 
466
                                //              message_1 + message_sig_1   etc
 
467
                          
 
468
                          if ( key.startsWith( "message_sig" ) || !key.startsWith( "message" )){
 
469
                                  
 
470
                                  continue;
 
471
                          }
 
472
                          
 
473
                          byte[]  message_bytes = (byte[])reply.get( key );
 
474
        
 
475
                          if ( message_bytes != null && message_bytes.length > 0 ){
 
476
        
 
477
                                  String  message = new String(message_bytes);
 
478
        
 
479
                                  String sig_key;
 
480
                                  
 
481
                                  int   pos = key.indexOf('_');
 
482
                                  
 
483
                                  if ( pos == -1 ){
 
484
                                          
 
485
                                          sig_key = "message_sig";
 
486
                                          
 
487
                                  }else{
 
488
                                          
 
489
                                          sig_key = "message_sig" + key.substring( pos );
 
490
                                  }
 
491
                                  
 
492
                                  String        last_message_key = "CoreUpdateChecker.last" + key;
 
493
                                  
 
494
                                  String  last = COConfigurationManager.getStringParameter( last_message_key, "" );
 
495
        
 
496
                                  if ( !message.equals( last )){
 
497
        
 
498
                                          byte[]        signature = (byte[])reply.get( sig_key );
 
499
        
 
500
                                          if ( signature == null ){
 
501
        
 
502
                                                  Logger.log( new LogEvent( LogIDs.LOGGER, "Signature missing from message" ));
 
503
        
 
504
                                                  return;
 
505
                                          }
 
506
        
 
507
                                          try{
 
508
                                                  AEVerifier.verifyData( message, signature );
 
509
        
 
510
                                          }catch( Throwable e ){
 
511
        
 
512
                                                  Logger.log( new LogEvent( LogIDs.LOGGER, "Message signature check failed", e  ));
 
513
        
 
514
                                                  return;
 
515
                                          }
 
516
        
 
517
                                          boolean       completed = false;
 
518
                                          
 
519
                                          if ( message.startsWith( "x:" )){
 
520
                                                  
 
521
                                                        // emergency patch application
 
522
                                                  
 
523
                                                  try{
 
524
                                                          URL jar_url = new URL( message.substring(2));
 
525
                                                          
 
526
                                                          Logger.log( new LogEvent( LogIDs.LOGGER, "Patch application requsted: url=" + jar_url ));
 
527
 
 
528
                                                          File  temp_dir = AETemporaryFileHandler.createTempDir();
 
529
                                                          
 
530
                                                          File  jar_file = new File( temp_dir, "patch.jar" );
 
531
                                                          
 
532
                                                          InputStream is = rdf.create( jar_url ).download();
 
533
                                                          
 
534
                                                          try{
 
535
                                                                  FileUtil.copyFile( is, jar_file );
 
536
                                                                  
 
537
                                                                  is = null;
 
538
                                                                  
 
539
                                                                  AEVerifier.verifyData( jar_file );
 
540
                                                                  
 
541
                                                                  ClassLoader cl = CoreUpdateChecker.class.getClassLoader();
 
542
                                                                                
 
543
                                                                  if ( cl instanceof URLClassLoader ){
 
544
 
 
545
                                                                          URL[] old = ((URLClassLoader)cl).getURLs();
 
546
 
 
547
                                                                          URL[] new_urls = new URL[old.length+1];
 
548
 
 
549
                                                                          System.arraycopy( old, 0, new_urls, 1, old.length );
 
550
 
 
551
                                                                          new_urls[0]= jar_file.toURL();
 
552
 
 
553
                                                                          cl = new URLClassLoader( new_urls, cl );
 
554
 
 
555
                                                                  }else{
 
556
 
 
557
                                                                          cl = new URLClassLoader( new URL[]{jar_file.toURL()}, cl );
 
558
                                                                  }
 
559
        
 
560
                                                                  Class cla = cl.loadClass( "org.gudy.azureus2.update.version.Patch" );
 
561
                                                                  
 
562
                                                                  cla.newInstance();
 
563
                                                                  
 
564
                                                                  completed = true;
 
565
                                                                  
 
566
                                                          }finally{
 
567
                                                                  
 
568
                                                                  if ( is != null ){
 
569
                                                                  
 
570
                                                                          is.close();
 
571
                                                                  }
 
572
                                                          }
 
573
                                                  }catch( Throwable e ){
 
574
                                                          
 
575
                                                          Logger.log( new LogEvent( LogIDs.LOGGER, "Patch application failed", e  ));
 
576
                                                  }
 
577
                                          } else if ( message.startsWith("u:") && message.length() > 4 ) {
 
578
                                                try {
 
579
                                                String type = message.substring(2, 3);
 
580
                                                String url = message.substring(4);
 
581
                                                UIFunctions uif = UIFunctionsManager.getUIFunctions();
 
582
                                                if (uif != null) {
 
583
                                                        uif.viewURL(url, null, 0.9, 0.9, true, type.equals("1"));
 
584
                                                }
 
585
                                                } catch (Throwable t) {
 
586
                                                          Logger.log( new LogEvent( LogIDs.LOGGER, "URL message failed", t  ));
 
587
                                                }
 
588
                                                // mark as complete even if errored
 
589
                                                  completed = true;
 
590
                                          }else{
 
591
                                                  
 
592
                                                  int   alert_type    = LogAlert.AT_WARNING;
 
593
                                                  
 
594
                                                  String  alert_text    = message;
 
595
                
 
596
                                                  if ( alert_text.startsWith("i:" )){
 
597
                
 
598
                                                          alert_type = LogAlert.AT_INFORMATION;
 
599
                
 
600
                                                          alert_text = alert_text.substring(2);
 
601
                                                  }
 
602
                
 
603
                                                  plugin_interface.getPluginProperties().setProperty( MESSAGE_PROPERTY, alert_text );
 
604
                
 
605
                                                  Logger.log(new LogAlert(LogAlert.UNREPEATABLE, alert_type, alert_text));
 
606
                                                  
 
607
                                                  completed = true;
 
608
                                          }
 
609
                                          
 
610
                                          if ( completed ){
 
611
                                                  
 
612
                                                  COConfigurationManager.setParameter( last_message_key, message );
 
613
        
 
614
                                                  COConfigurationManager.save();
 
615
                                          }
 
616
                                  }
 
617
                          }
 
618
                  }
 
619
          }catch( Throwable e ){
 
620
 
 
621
                  Debug.printStackTrace( e );
 
622
          }
 
623
  } 
 
624
        
 
625
        protected ResourceDownloader[]
 
626
        getPrimaryDownloaders(
 
627
                String          latest_file_name )
 
628
        {
 
629
                log.log( "Downloading primary mirrors" );
 
630
                
 
631
                List    res = new ArrayList();
 
632
 
 
633
                try{
 
634
                        if ( latest_file_name == null ){
 
635
                
 
636
                                        // very old method, non-mirror based
 
637
                                
 
638
                                res.add( new URL( Constants.SF_WEB_SITE + "Azureus2.jar" ));
 
639
                                                                
 
640
                        }else{
 
641
                
 
642
                                URL mirrors_url = new URL("http://prdownloads.sourceforge.net/azureus/" + latest_file_name + "?download");
 
643
                                
 
644
                                ResourceDownloader      rd = rdf.create( mirrors_url );
 
645
                                
 
646
                                rd = rdf.getRetryDownloader( rd, RD_GET_MIRRORS_RETRIES );
 
647
                                
 
648
                                rd.addListener( rd_logger );
 
649
                                
 
650
                                String  page = HTMLPageFactory.loadPage( rd.download()).getContent();
 
651
                                
 
652
                                String pattern = "/azureus/" + latest_file_name + "?use_mirror=";
 
653
             
 
654
                                int position = page.indexOf(pattern);
 
655
                                
 
656
                                while ( position > 0 ){
 
657
                                        
 
658
                                        int end = page.indexOf(">", position);
 
659
                                        
 
660
                                        if (end < 0) {
 
661
                                                
 
662
                                                position = -1;
 
663
                                                
 
664
                                        }else{
 
665
                                                
 
666
                                                String mirror = page.substring(position, end);
 
667
                                                
 
668
                                                if ( mirror.endsWith("\"")){
 
669
                                                        
 
670
                                                        mirror = mirror.substring(0,mirror.length()-1);
 
671
                                                }
 
672
                                                
 
673
                                                try{
 
674
                                                        res.add( new URL( "http://prdownloads.sourceforge.net" + mirror ));
 
675
                                                        
 
676
                                                }catch( Throwable e ){
 
677
                                                        
 
678
                                                        log.log( "Invalid URL read:" + mirror, e );
 
679
                                                }
 
680
                  
 
681
                                                position = page.indexOf(pattern, position + 1);
 
682
                                        }
 
683
                                }
 
684
                        }
 
685
                }catch( Throwable e ){
 
686
                        
 
687
                        log.log( "Failed to read primary mirror list", e );
 
688
                }
 
689
                
 
690
                ResourceDownloader[]    dls = new ResourceDownloader[res.size()];
 
691
                                
 
692
                for (int i=0;i<res.size();i++){
 
693
                        
 
694
                        URL     url =(URL)res.get(i);
 
695
                        
 
696
                        log.log( "    Primary mirror:" +url.toString());
 
697
                        
 
698
                        ResourceDownloader dl = rdf.create( url );
 
699
                        
 
700
                        dl = rdf.getMetaRefreshDownloader( dl );
 
701
                        
 
702
                                // add in a layer to do torrent based downloads if url ends with .torrent
 
703
                        
 
704
                        dl = rdf.getSuffixBasedDownloader( dl );
 
705
                        
 
706
                        dls[i] = dl;
 
707
                }
 
708
                
 
709
                return( dls );
 
710
        }
 
711
        
 
712
        protected ResourceDownloader[]
 
713
        getBackupDownloaders(
 
714
                String  latest_file_name )
 
715
        {
 
716
                List    res = new ArrayList();
 
717
        
 
718
                try{
 
719
                        if ( latest_file_name != null ){
 
720
                                                        
 
721
                                log.log( "Downloading backup mirrors" );
 
722
                                
 
723
                                URL mirrors_url = new URL("http://azureus.sourceforge.net/mirrors.php");
 
724
                                
 
725
                                ResourceDownloader      rd = rdf.create( mirrors_url );
 
726
                                
 
727
                                rd = rdf.getRetryDownloader( rd, RD_GET_MIRRORS_RETRIES );
 
728
                                
 
729
                                rd.addListener( rd_logger );
 
730
                                
 
731
                                BufferedInputStream     data = new BufferedInputStream(rd.download());
 
732
                                
 
733
                                Map decoded = BDecoder.decode(data);
 
734
                                
 
735
                                data.close();
 
736
                                
 
737
                                List mirrors = (List)decoded.get("mirrors");
 
738
                
 
739
                                for (int i=0;i<mirrors.size();i++){
 
740
                                        
 
741
                                        String mirror = new String( (byte[])mirrors.get(i));
 
742
                                        
 
743
                                        try{
 
744
                                                
 
745
                                                res.add( new URL( mirror + latest_file_name ));
 
746
                                                // res.add( new URL( "http://torrents.aelitis.com:88/torrents/Azureus2.4.0.2_signed.jar.torrent" ));
 
747
                                                
 
748
                                        }catch(Throwable e){
 
749
                                                
 
750
                                                log.log( "Invalid URL read:" + mirror, e );
 
751
                                        }
 
752
                                }
 
753
                        }
 
754
                }catch( Throwable e ){
 
755
                        
 
756
                        log.log( "Failed to read backup mirror list", e );
 
757
                }
 
758
                
 
759
                ResourceDownloader[]    dls = new ResourceDownloader[res.size()];
 
760
                
 
761
                for (int i=0;i<res.size();i++){
 
762
                        
 
763
                        URL     url =(URL)res.get(i);
 
764
                        
 
765
                        log.log( "    Backup mirror:" +url.toString());
 
766
                        
 
767
                        ResourceDownloader dl = rdf.create( url );
 
768
 
 
769
                                // add in .torrent decoder if appropriate
 
770
                        
 
771
                        dl = rdf.getSuffixBasedDownloader( dl );
 
772
 
 
773
                        dls[i] = dl;
 
774
                }
 
775
                
 
776
                return( dls );
 
777
        }               
 
778
 
 
779
        protected void
 
780
        installUpdate(
 
781
                UpdateChecker           checker,
 
782
                Update                          update,
 
783
                ResourceDownloader      rd,
 
784
                String                          version,
 
785
                InputStream                     data )
 
786
        {
 
787
                try{
 
788
                        data = update.verifyData( data, true );
 
789
 
 
790
                        rd.reportActivity( "Data verified successfully" );
 
791
                        
 
792
                        String  temp_jar_name   = "Azureus2_" + version + ".jar";
 
793
                        String  target_jar_name = "Azureus2.jar";
 
794
                        
 
795
                        UpdateInstaller installer = checker.createInstaller();
 
796
                        
 
797
                        installer.addResource( temp_jar_name, data );
 
798
                        
 
799
                        if ( Constants.isOSX ){
 
800
                                
 
801
                                installer.addMoveAction( 
 
802
                                        temp_jar_name,
 
803
                                        installer.getInstallDir() + "/" + SystemProperties.getApplicationName() + ".app/Contents/Resources/Java/" + target_jar_name );        
 
804
                        }else{
 
805
                                
 
806
                                installer.addMoveAction( 
 
807
                                        temp_jar_name,
 
808
                                        installer.getInstallDir() + File.separator + target_jar_name );
 
809
                        }
 
810
                }catch( Throwable e ){
 
811
                        
 
812
                        rd.reportActivity("Update install failed:" + e.getMessage());
 
813
                }
 
814
        }
 
815
        
 
816
        protected static boolean
 
817
        shouldUpdate(
 
818
                String  current_version,
 
819
                String  latest_version )
 
820
        {
 
821
                String  current_base    = Constants.getBaseVersion( current_version );
 
822
                int             current_inc             = Constants.getIncrementalBuild( current_version );
 
823
 
 
824
                String  latest_base     = Constants.getBaseVersion( latest_version );
 
825
                int             latest_inc      = Constants.getIncrementalBuild( latest_version );
 
826
                        
 
827
                        // currently we upgrade from, for example
 
828
                        //  1) 2.4.0.0     -> 2.4.0.2
 
829
                        //      2) 2.4.0.1_CVS -> 2.4.0.2
 
830
                        //      3) 2.4.0.1_B12 -> 2.4.0.2  and 2.4.0.1_B14
 
831
                
 
832
                        // but NOT
 
833
                        //  1) 2.4.0.0     -> 2.4.0.1_CVS or 2.4.0.1_B23
 
834
                        //  2) 2.4.0.1_CVS -> 2.4.0.1_B23
 
835
                
 
836
                        // for inc values: 0 = not CVS, -1 = _CVS, > 0 = Bnn
 
837
 
 
838
                int     major_comp = Constants.compareVersions( current_base, latest_base );
 
839
                
 
840
                if ( major_comp < 0 && latest_inc == 0 ){
 
841
                        
 
842
                        return( true );         // latest is higher version and not CVS
 
843
                }
 
844
                
 
845
                        // same version, both are B versions and latest B is more recent
 
846
                
 
847
                return( major_comp == 0 && current_inc > 0 && latest_inc > 0 && latest_inc > current_inc );
 
848
        }
 
849
        
 
850
        public static void
 
851
        main(
 
852
                String[]        args )
 
853
        {
 
854
                String[][]      tests = {
 
855
                                { "2.4.0.0",            "2.4.0.2",              "true" },
 
856
                                { "2.4.0.1_CVS",        "2.4.0.2",              "true" },
 
857
                                { "2.4.0.1_B12",        "2.4.0.2",              "true" },
 
858
                                { "2.4.0.1_B12",        "2.4.0.1_B34",  "true" },
 
859
                                { "2.4.0.1_B12",        "2.4.0.1_B6",   "false" },
 
860
                                { "2.4.0.0",            "2.4.0.1_CVS",  "false" },
 
861
                                { "2.4.0.0",            "2.4.0.1_B12",  "false" },
 
862
                                { "2.4.0.0",            "2.4.0.0"       ,       "false" },
 
863
                                { "2.4.0.1_CVS",        "2.4.0.1_CVS",  "false" },
 
864
                                { "2.4.0.1_B2",         "2.4.0.1_B2",   "false" },
 
865
                                { "2.4.0.1_CVS",        "2.4.0.1_B2",   "false" },
 
866
                                { "2.4.0.1_B2",         "2.4.0.1_CVS",  "false" },
 
867
 
 
868
                };
 
869
 
 
870
                for (int i=0;i<tests.length;i++){
 
871
                        
 
872
                        System.out.println( shouldUpdate(tests[i][0],tests[i][1]) + " / " + tests[i][2] );
 
873
                }
 
874
                
 
875
                /*
 
876
                AEDiagnostics.startup();
 
877
                
 
878
                CoreUpdateChecker       checker = new CoreUpdateChecker();
 
879
                
 
880
                checker.log = new LoggerImpl(null).getTimeStampedChannel("");
 
881
                checker.rdf     = new ResourceDownloaderFactoryImpl();
 
882
                checker.rd_logger = 
 
883
                        new ResourceDownloaderAdapter()
 
884
                        {
 
885
                                public void
 
886
                                reportActivity(
 
887
                                        ResourceDownloader      downloader,
 
888
                                        String                          activity )
 
889
                                {
 
890
                                        System.out.println( activity );
 
891
                                }
 
892
                                
 
893
                                public void
 
894
                                reportPercentComplete(
 
895
                                        ResourceDownloader      downloader,
 
896
                                        int                                     percentage )
 
897
                                {
 
898
                                        System.out.println( "    % = " + percentage );
 
899
                                }
 
900
                        };
 
901
                        
 
902
                ResourceDownloader[]    primaries = checker.getPrimaryDownloaders( "Azureus-2.0.3.0.jar" );
 
903
                
 
904
                for (int i=0;i<primaries.length;i++){
 
905
                        
 
906
                        System.out.println( "primary: " + primaries[i].getName());
 
907
                }
 
908
                
 
909
                try{
 
910
                        ResourceDownloader      rd = primaries[0];
 
911
                        
 
912
                        rd.addListener( checker.rd_logger );
 
913
                        
 
914
                        rd.download();
 
915
                        
 
916
                        System.out.println( "done" );
 
917
                        
 
918
                }catch( Throwable e ){
 
919
                        
 
920
                        e.printStackTrace();
 
921
                }
 
922
                */
 
923
        }
 
924
}