1 /* 2 * File : PluginInterfaceImpl.java 3 * Created : 12 nov. 2003 4 * By : Olivier 5 * 6 * Azureus - a Java Bittorrent client 7 * 8 * This program is free software; you can redistribute it and/or modify 9 * it under the terms of the GNU General Public License as published by 10 * the Free Software Foundation; either version 2 of the License, or 11 * (at your option) any later version. 12 * 13 * This program is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 * GNU General Public License for more details ( see the LICENSE file ). 17 * 18 * You should have received a copy of the GNU General Public License 19 * along with this program; if not, write to the Free Software 20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 21 */ 22 23 package org.gudy.azureus2.pluginsimpl.local; 24 25 import java.util.*; 26 import java.io.File; 27 import java.net.URL; 28 29 import org.gudy.azureus2.platform.PlatformManagerFactory; 30 import org.gudy.azureus2.plugins.*; 31 import org.gudy.azureus2.plugins.dht.mainline.*; 32 import org.gudy.azureus2.plugins.logging.Logger; 33 import org.gudy.azureus2.plugins.messaging.MessageManager; 34 import org.gudy.azureus2.plugins.network.ConnectionManager; 35 import org.gudy.azureus2.pluginsimpl.local.deprecate.PluginDeprecation; 36 import org.gudy.azureus2.pluginsimpl.local.dht.mainline.*; 37 import org.gudy.azureus2.pluginsimpl.local.clientid.ClientIDManagerImpl; 38 import org.gudy.azureus2.pluginsimpl.local.ddb.DDBaseImpl; 39 import org.gudy.azureus2.pluginsimpl.local.download.DownloadManagerImpl; 40 import org.gudy.azureus2.pluginsimpl.local.ipc.IPCInterfaceImpl; 41 import org.gudy.azureus2.pluginsimpl.local.ipfilter.IPFilterImpl; 42 import org.gudy.azureus2.pluginsimpl.local.logging.LoggerImpl; 43 import org.gudy.azureus2.pluginsimpl.local.messaging.MessageManagerImpl; 44 import org.gudy.azureus2.pluginsimpl.local.network.ConnectionManagerImpl; 45 import org.gudy.azureus2.pluginsimpl.local.sharing.ShareManagerImpl; 46 import org.gudy.azureus2.pluginsimpl.local.torrent.TorrentManagerImpl; 47 import org.gudy.azureus2.pluginsimpl.local.tracker.*; 48 import org.gudy.azureus2.pluginsimpl.local.ui.*; 49 import org.gudy.azureus2.pluginsimpl.local.ui.config.*; 50 import org.gudy.azureus2.pluginsimpl.local.utils.*; 51 import org.gudy.azureus2.pluginsimpl.local.update.*; 52 import org.gudy.azureus2.plugins.ipc.IPCInterface; 53 import org.gudy.azureus2.plugins.ipfilter.IPFilter; 54 import org.gudy.azureus2.plugins.tracker.Tracker; 55 import org.gudy.azureus2.plugins.ui.config.Parameter; 56 import org.gudy.azureus2.plugins.ui.config.PluginConfigUIFactory; 57 import org.gudy.azureus2.plugins.platform.PlatformManager; 58 import org.gudy.azureus2.plugins.sharing.*; 59 import org.gudy.azureus2.plugins.clientid.ClientIDManager; 60 import org.gudy.azureus2.plugins.ddb.DistributedDatabase; 61 import org.gudy.azureus2.plugins.download.*; 62 import org.gudy.azureus2.plugins.torrent.*; 63 import org.gudy.azureus2.plugins.ui.*; 64 import org.gudy.azureus2.plugins.ui.config.ConfigSection; 65 import org.gudy.azureus2.plugins.utils.*; 66 import org.gudy.azureus2.plugins.update.*; 67 68 import org.gudy.azureus2.core3.util.*; 69 import org.gudy.azureus2.core3.logging.*; 70 71 import com.aelitis.azureus.core.AzureusCoreComponent; 72 import com.aelitis.azureus.core.util.CopyOnWriteList; 73 74 75 76 /** 77 * @author Olivier 78 * 79 */ 80 public final class 81 PluginInterfaceImpl 82 implements PluginInterface, AzureusCoreComponent 83 { 84 private static final LogIDs LOGID = org.gudy.azureus2.core3.logging.LogIDs.PLUGIN; 85 86 private Plugin plugin; 87 private PluginInitializer initialiser; 88 private Object initialiser_key; 89 protected ClassLoader class_loader; 90 91 private CopyOnWriteList<PluginListener> listeners = new CopyOnWriteList<PluginListener>(); 92 private Set<PluginListener> init_complete_fired_set = new HashSet<PluginListener>(); 93 94 private CopyOnWriteList<PluginEventListener> event_listeners = new CopyOnWriteList<PluginEventListener>(); 95 private String key; 96 private String pluginConfigKey; 97 private Properties props; 98 private String pluginDir; 99 private PluginConfigImpl config; 100 private String plugin_version; 101 private Logger logger; 102 private IPCInterfaceImpl ipc_interface; 103 protected List children = new ArrayList(); 104 private PluginStateImpl state; 105 106 /** 107 * This is the plugin ID value we were given when we were created. 108 * 109 * We might use it, but it depends what value is the plugins properties 110 * (which will override this value). 111 */ 112 private String given_plugin_id; 113 114 /** 115 * We store this value as soon as someone calls getPluginID(), meaning 116 * we will return a consistent value for the plugin's lifetime. 117 */ 118 private String plugin_id_to_use; 119 120 protected PluginInterfaceImpl( Plugin _plugin, PluginInitializer _initialiser, Object _initialiser_key, ClassLoader _class_loader, List<File> _verified_files, String _key, Properties _props, String _pluginDir, String _plugin_id, String _plugin_version )121 PluginInterfaceImpl( 122 Plugin _plugin, 123 PluginInitializer _initialiser, 124 Object _initialiser_key, 125 ClassLoader _class_loader, 126 List<File> _verified_files, 127 String _key, 128 Properties _props, 129 String _pluginDir, 130 String _plugin_id, 131 String _plugin_version ) 132 133 throws PluginException 134 { 135 // check we're being created by the core 136 137 StackTraceElement[] stack = Thread.currentThread().getStackTrace(); 138 139 int pos = 0; 140 141 while( !stack[pos].getClassName().equals( PluginInterfaceImpl.class.getName())){ 142 143 pos++; 144 } 145 146 String caller_class = stack[pos+1].getClassName(); 147 148 if ( !( caller_class.equals( "org.gudy.azureus2.pluginsimpl.local.PluginInitializer" ) || 149 caller_class.equals( "org.gudy.azureus2.pluginsimpl.local.PluginInterfaceImpl" ))){ 150 151 throw( new PluginException( "Invalid caller" )); 152 } 153 154 // check we haven't been subclassed 155 156 String class_name = getClass().getCanonicalName(); 157 158 if ( class_name == null || !class_name.equals( "org.gudy.azureus2.pluginsimpl.local.PluginInterfaceImpl" )){ 159 160 throw( new PluginException( "Subclassing not permitted" )); 161 } 162 163 plugin = _plugin; 164 initialiser = _initialiser; 165 initialiser_key = _initialiser_key; 166 class_loader = _class_loader; 167 key = _key; 168 pluginConfigKey = "Plugin." + _key; 169 props = new propertyWrapper(_props ); 170 pluginDir = _pluginDir; 171 config = new PluginConfigImpl(this,pluginConfigKey); 172 given_plugin_id = _plugin_id; 173 plugin_version = _plugin_version; 174 ipc_interface = new IPCInterfaceImpl( initialiser, plugin ); 175 state = new PluginStateImpl(this, initialiser); 176 177 boolean verified = false; 178 boolean bad = false; 179 180 if ( _plugin_id.endsWith( "_v" )){ 181 182 if ( plugin.getClass() == FailedPlugin.class ){ 183 184 verified = true; 185 186 }else{ 187 if ( _verified_files != null ){ 188 189 File jar = FileUtil.getJarFileFromClass( plugin.getClass()); 190 191 if ( jar != null ){ 192 193 for ( File file: _verified_files ){ 194 195 if ( file.equals( jar )){ 196 197 verified = true; 198 } 199 } 200 } 201 } 202 } 203 204 if ( !verified ){ 205 206 bad = true; 207 } 208 } 209 210 PluginInitializer.setVerified( this, plugin, verified, bad ); 211 } 212 213 public Plugin getPlugin()214 getPlugin() 215 { 216 return( plugin ); 217 } 218 isOperational()219 public boolean isOperational() { 220 PluginDeprecation.call("isOperational", this.given_plugin_id); 221 return getPluginState().isOperational(); 222 } 223 224 public Object getInitializerKey()225 getInitializerKey() 226 { 227 return( initialiser_key ); 228 } 229 230 public PluginManager getPluginManager()231 getPluginManager() 232 { 233 return( initialiser.getPluginManager()); 234 } 235 getApplicationName()236 public String getApplicationName() { 237 return Constants.APP_NAME; 238 } 239 240 public String getAzureusName()241 getAzureusName() 242 { 243 return( Constants.AZUREUS_NAME ); 244 } 245 246 public String getAzureusVersion()247 getAzureusVersion() 248 { 249 return( Constants.AZUREUS_VERSION ); 250 } 251 addConfigSection(ConfigSection section)252 public void addConfigSection(ConfigSection section) 253 { 254 // Method is used by autocat. 255 ConfigSectionRepository.getInstance().addConfigSection(section, this); 256 } 257 removeConfigSection(ConfigSection section)258 public void removeConfigSection(ConfigSection section) 259 { 260 ConfigSectionRepository.getInstance().removeConfigSection(section); 261 } 262 getConfigSections()263 public ConfigSection[] getConfigSections() { 264 ArrayList<ConfigSection> list = ConfigSectionRepository.getInstance().getList(); 265 for (Iterator<ConfigSection> iter = list.iterator(); iter.hasNext();) { 266 ConfigSection configSection = iter.next(); 267 if (configSection instanceof ConfigSectionHolder) { 268 if (((ConfigSectionHolder)configSection).getPluginInterface() != this) { 269 iter.remove(); 270 } 271 } 272 } 273 return list.toArray(new ConfigSection[0]); 274 } 275 276 /** 277 * @deprecated 278 */ openTorrentFile(String fileName)279 public void openTorrentFile(String fileName) { 280 PluginDeprecation.call("openTorrentFile", this.getPluginID()); 281 try{ 282 getDownloadManager().addDownload( new File(fileName)); 283 }catch( DownloadException e ){ 284 throw( new RuntimeException(e)); 285 } 286 } 287 288 /** 289 * @deprecated 290 */ openTorrentURL(String url)291 public void openTorrentURL(String url) { 292 PluginDeprecation.call("openTorrentURL", this.getPluginID()); 293 try{ 294 getDownloadManager().addDownload( new URL( url )); 295 }catch( Throwable e ){ 296 throw( new RuntimeException(e)); 297 } 298 } 299 300 public void setPluginName( String name )301 setPluginName( 302 String name ) 303 { 304 props.put( "plugin.name", name ); 305 } 306 getPluginName()307 public String getPluginName() 308 { 309 String name = null; 310 311 if ( props != null ){ 312 313 name = (String)props.get( "plugin.name"); 314 } 315 316 if ( name == null ){ 317 318 try{ 319 320 name = new File(pluginDir).getName(); 321 322 }catch( Throwable e ){ 323 324 } 325 } 326 327 if ( name == null || name.length() == 0 ){ 328 329 name = plugin.getClass().getName(); 330 } 331 332 return( name ); 333 } 334 335 public void setPluginVersion( String version )336 setPluginVersion( 337 String version ) 338 { 339 props.put( "plugin.version", version ); 340 } 341 342 public String getPluginVersion()343 getPluginVersion() 344 { 345 String version = (String)props.get("plugin.version"); 346 347 if ( version == null ){ 348 349 version = plugin_version; 350 } 351 352 return( version ); 353 } 354 355 public String getPluginID()356 getPluginID() 357 { 358 String id = (String)props.get("plugin.id"); 359 360 // hack alert - azupdater needs to change its plugin id due to general hackage 361 362 if ( id != null && id.equals( "azupdater" )){ 363 364 plugin_id_to_use = id; 365 } 366 367 if (plugin_id_to_use != null) {return plugin_id_to_use;} 368 369 // Calculate what plugin ID value to use - look at the properties file 370 // first, and if that isn't correct, base it on the given plugin ID 371 // value we were given. 372 373 if (id == null) {id = given_plugin_id;} 374 if (id == null) {id = "<none>";} 375 376 plugin_id_to_use = id; 377 return plugin_id_to_use; 378 } 379 isMandatory()380 public boolean isMandatory() { 381 PluginDeprecation.call("isMandatory", this.given_plugin_id); 382 return getPluginState().isMandatory(); 383 } 384 isBuiltIn()385 public boolean isBuiltIn() { 386 PluginDeprecation.call("isBuiltIn", this.given_plugin_id); 387 return getPluginState().isBuiltIn(); 388 } 389 getPluginProperties()390 public Properties getPluginProperties() 391 { 392 return(props); 393 } 394 getPluginDirectoryName()395 public String getPluginDirectoryName() { 396 return pluginDir; 397 } 398 getPerUserPluginDirectoryName()399 public String getPerUserPluginDirectoryName(){ 400 String name; 401 if ( pluginDir == null ){ 402 name = getPluginID(); 403 }else{ 404 name = new File( pluginDir).getName(); 405 } 406 407 String str = new File(new File(SystemProperties.getUserPath(),"plugins"),name).getAbsolutePath(); 408 409 if ( pluginDir == null ){ 410 411 return( str ); 412 } 413 414 try{ 415 if ( new File( pluginDir ).getCanonicalPath().equals( new File( str ).getCanonicalPath())){ 416 417 return( pluginDir ); 418 } 419 }catch( Throwable e ){ 420 421 } 422 423 return( str ); 424 } 425 426 public void setPluginDirectoryName( String name )427 setPluginDirectoryName( 428 String name ) 429 { 430 initialiser_key = new File(name); 431 432 pluginDir = name; 433 } 434 addConfigUIParameters(Parameter[] parameters, String displayName)435 public void addConfigUIParameters(Parameter[] parameters, String displayName) { 436 ParameterRepository.getInstance().addPlugin(parameters, displayName); 437 } 438 439 getPluginconfig()440 public PluginConfig getPluginconfig() { 441 return config; 442 } 443 444 getPluginConfigUIFactory()445 public PluginConfigUIFactory getPluginConfigUIFactory() { 446 return new PluginConfigUIFactoryImpl(config,pluginConfigKey); 447 } 448 449 public String getPluginConfigKey()450 getPluginConfigKey() 451 { 452 return( pluginConfigKey ); 453 } 454 getTracker()455 public Tracker getTracker() { 456 return( TrackerImpl.getSingleton()); 457 } 458 459 public ShareManager getShareManager()460 getShareManager() 461 462 throws ShareException 463 { 464 return( ShareManagerImpl.getSingleton()); 465 } 466 467 public DownloadManager getDownloadManager()468 getDownloadManager() 469 { 470 return( DownloadManagerImpl.getSingleton(initialiser.getAzureusCore())); 471 } 472 getMainlineDHTManager()473 public MainlineDHTManager getMainlineDHTManager() { 474 return new MainlineDHTManagerImpl(initialiser.getAzureusCore()); 475 } 476 477 public TorrentManager getTorrentManager()478 getTorrentManager() 479 { 480 return( TorrentManagerImpl.getSingleton().specialise( this )); 481 } 482 getLogger()483 public Logger getLogger() 484 { 485 if ( logger == null ){ 486 487 logger = new LoggerImpl( this ); 488 } 489 490 return( logger ); 491 } 492 493 public IPFilter getIPFilter()494 getIPFilter() 495 { 496 return( new IPFilterImpl()); 497 } 498 499 public Utilities getUtilities()500 getUtilities() 501 { 502 return( new UtilitiesImpl( initialiser.getAzureusCore(), this )); 503 } 504 505 public ShortCuts getShortCuts()506 getShortCuts() 507 { 508 return( new ShortCutsImpl(this)); 509 } 510 511 public UIManager getUIManager()512 getUIManager() 513 { 514 return( new UIManagerImpl( this )); 515 } 516 517 public UpdateManager getUpdateManager()518 getUpdateManager() 519 { 520 return( UpdateManagerImpl.getSingleton( initialiser.getAzureusCore())); 521 } 522 523 524 protected void unloadSupport()525 unloadSupport() 526 { 527 ipc_interface.unload(); 528 529 UIManagerImpl.unload( this ); 530 } 531 isUnloadable()532 public boolean isUnloadable() { 533 PluginDeprecation.call("unloadable", this.given_plugin_id); 534 return getPluginState().isUnloadable(); 535 } 536 reload()537 public void reload() throws PluginException { 538 PluginDeprecation.call("reload", this.given_plugin_id); 539 getPluginState().reload(); 540 } 541 unload()542 public void unload() throws PluginException { 543 PluginDeprecation.call("unload", this.given_plugin_id); 544 getPluginState().unload(); 545 } 546 uninstall()547 public void uninstall() throws PluginException { 548 PluginDeprecation.call("uninstall", this.given_plugin_id); 549 getPluginState().uninstall(); 550 } 551 552 public boolean isInitialisationThread()553 isInitialisationThread() 554 { 555 return( initialiser.isInitialisationThread()); 556 } 557 558 public ClientIDManager getClientIDManager()559 getClientIDManager() 560 { 561 return( ClientIDManagerImpl.getSingleton()); 562 } 563 564 getConnectionManager()565 public ConnectionManager getConnectionManager() { 566 return ConnectionManagerImpl.getSingleton( initialiser.getAzureusCore()); 567 } 568 getMessageManager()569 public MessageManager getMessageManager() { 570 return MessageManagerImpl.getSingleton( initialiser.getAzureusCore() ); 571 } 572 573 574 public DistributedDatabase getDistributedDatabase()575 getDistributedDatabase() 576 { 577 return( DDBaseImpl.getSingleton(initialiser.getAzureusCore())); 578 } 579 580 public PlatformManager getPlatformManager()581 getPlatformManager() 582 { 583 return( PlatformManagerFactory.getPlatformManager()); 584 } 585 586 protected void initialisationComplete()587 initialisationComplete() 588 { 589 Iterator<PluginListener> it = listeners.iterator(); 590 591 while( it.hasNext()){ 592 593 try{ 594 fireInitComplete( it.next()); 595 596 }catch( Throwable e ){ 597 598 Debug.printStackTrace( e ); 599 } 600 } 601 602 for (int i=0;i<children.size();i++){ 603 604 ((PluginInterfaceImpl)children.get(i)).initialisationComplete(); 605 } 606 } 607 608 protected void fireInitComplete( PluginListener listener )609 fireInitComplete( 610 PluginListener listener ) 611 { 612 synchronized( init_complete_fired_set ){ 613 614 if ( init_complete_fired_set.contains( listener )){ 615 616 return; 617 } 618 619 init_complete_fired_set.add( listener ); 620 } 621 622 try { 623 listener.initializationComplete(); 624 } catch (Exception e) { 625 Debug.out(e); 626 } 627 } 628 629 protected void closedownInitiated()630 closedownInitiated() 631 { 632 Iterator it = listeners.iterator(); 633 634 while( it.hasNext()){ 635 636 try{ 637 ((PluginListener)it.next()).closedownInitiated(); 638 639 }catch( Throwable e ){ 640 641 Debug.printStackTrace( e ); 642 } 643 } 644 645 for (int i=0;i<children.size();i++){ 646 647 ((PluginInterfaceImpl)children.get(i)).closedownInitiated(); 648 } 649 } 650 651 protected void closedownComplete()652 closedownComplete() 653 { 654 Iterator it = listeners.iterator(); 655 656 while( it.hasNext()){ 657 658 try{ 659 ((PluginListener)it.next()).closedownComplete(); 660 661 }catch( Throwable e ){ 662 663 Debug.printStackTrace( e ); 664 } 665 } 666 667 for (int i=0;i<children.size();i++){ 668 669 ((PluginInterfaceImpl)children.get(i)).closedownComplete(); 670 } 671 } 672 673 public ClassLoader getPluginClassLoader()674 getPluginClassLoader() 675 { 676 return( class_loader ); 677 } 678 679 public PluginInterface getLocalPluginInterface( Class plugin_class, String id )680 getLocalPluginInterface( 681 Class plugin_class, 682 String id ) 683 684 throws PluginException 685 { 686 try{ 687 Plugin p = (Plugin)plugin_class.newInstance(); 688 689 // Discard plugin.id from the properties, we want the 690 // plugin ID we create to take priority - not a value 691 // from the original plugin ID properties file. 692 Properties local_props = new Properties(props); 693 local_props.remove("plugin.id"); 694 695 696 if( id.endsWith( "_v" )){ 697 698 throw( new Exception( "Verified plugins must be loaded from a jar" )); 699 } 700 701 PluginInterfaceImpl pi = 702 new PluginInterfaceImpl( 703 p, 704 initialiser, 705 initialiser_key, 706 class_loader, 707 null, 708 key + "." + id, 709 local_props, 710 pluginDir, 711 getPluginID() + "." + id, 712 plugin_version ); 713 714 initialiser.fireCreated( pi ); 715 716 p.initialize( pi ); 717 718 children.add( pi ); 719 720 return( pi ); 721 722 }catch( Throwable e ){ 723 724 if ( e instanceof PluginException ){ 725 726 throw((PluginException)e); 727 } 728 729 throw( new PluginException( "Local initialisation fails", e )); 730 } 731 } 732 733 public IPCInterfaceImpl getIPC()734 getIPC() 735 { 736 return( ipc_interface ); 737 } 738 isShared()739 public boolean isShared() { 740 PluginDeprecation.call("isShared", this.given_plugin_id); 741 return getPluginState().isShared(); 742 } 743 744 745 // Not exposed in the interface. setAsFailed()746 void setAsFailed() { 747 getPluginState().setDisabled(true); 748 state.failed = true; 749 } 750 751 protected void destroy()752 destroy() 753 { 754 class_loader = null; 755 756 // unhook the reference to the plugin but leave with a valid reference in case 757 // something tries to use it 758 759 plugin = new FailedPlugin( "Plugin '" + getPluginID() + "' has been unloaded!", null ); 760 } 761 762 public void addListener( PluginListener l )763 addListener( 764 PluginListener l ) 765 { 766 listeners.add(l); 767 768 if ( initialiser.isInitialisationComplete()){ 769 770 fireInitComplete( l ); 771 } 772 } 773 774 public void removeListener( final PluginListener l )775 removeListener( 776 final PluginListener l ) 777 { 778 listeners.remove(l); 779 780 // we want to remove this ref, but there is a *small* chance that there's a parallel thread firing the complete so 781 // decrease chance of hanging onto unwanted ref 782 783 new DelayedEvent( 784 "PIL:clear", 10000, 785 new AERunnable() 786 { 787 public void 788 runSupport() 789 { 790 synchronized( init_complete_fired_set ){ 791 792 init_complete_fired_set.remove(l); 793 } 794 } 795 }); 796 } 797 798 public void addEventListener( final PluginEventListener l )799 addEventListener( 800 final PluginEventListener l ) 801 { 802 initialiser.runPEVTask( 803 new AERunnable() 804 { 805 public void 806 runSupport() 807 { 808 List<PluginEvent> events = initialiser.getPEVHistory(); 809 810 for ( PluginEvent event: events ){ 811 812 try{ 813 l.handleEvent( event ); 814 815 }catch( Throwable e ){ 816 817 Debug.out( e ); 818 } 819 } 820 event_listeners.add(l); 821 } 822 }); 823 } 824 825 public void removeEventListener( final PluginEventListener l )826 removeEventListener( 827 final PluginEventListener l ) 828 { 829 initialiser.runPEVTask( 830 new AERunnable() 831 { 832 public void 833 runSupport() 834 { 835 event_listeners.remove(l); 836 } 837 }); 838 } 839 840 public void firePluginEvent( final PluginEvent event )841 firePluginEvent( 842 final PluginEvent event ) 843 { 844 initialiser.runPEVTask( 845 new AERunnable() 846 { 847 public void 848 runSupport() 849 { 850 firePluginEventSupport( event ); 851 } 852 }); 853 } 854 855 protected void firePluginEventSupport( PluginEvent event )856 firePluginEventSupport( 857 PluginEvent event ) 858 { 859 Iterator<PluginEventListener> it = event_listeners.iterator(); 860 861 while( it.hasNext()){ 862 863 try{ 864 PluginEventListener listener = it.next(); 865 866 listener.handleEvent( event ); 867 868 }catch( Throwable e ){ 869 870 Debug.printStackTrace( e ); 871 } 872 } 873 874 for (int i=0;i<children.size();i++){ 875 876 ((PluginInterfaceImpl)children.get(i)).firePluginEvent(event); 877 } 878 } 879 880 protected void generateEvidence( IndentWriter writer )881 generateEvidence( 882 IndentWriter writer ) 883 { 884 writer.println( getPluginName()); 885 886 try{ 887 writer.indent(); 888 889 writer.println( "id:" + getPluginID() + ",version:" + getPluginVersion()); 890 891 String user_dir = FileUtil.getUserFile( "plugins" ).toString(); 892 String shared_dir = FileUtil.getApplicationFile( "plugins" ).toString(); 893 894 String plugin_dir = getPluginDirectoryName(); 895 896 String type; 897 boolean built_in = false; 898 899 if ( plugin_dir.startsWith( shared_dir )){ 900 901 type = "shared"; 902 903 }else if ( plugin_dir.startsWith( user_dir )){ 904 905 type = "per-user"; 906 907 }else{ 908 909 built_in = true; 910 911 type = "built-in"; 912 } 913 914 PluginState ps = getPluginState(); 915 916 String info = getPluginconfig().getPluginStringParameter( "plugin.info" ); 917 918 writer.println( "type:" + type + ",enabled=" + !ps.isDisabled() + ",load_at_start=" + ps.isLoadedAtStartup() + ",operational=" + ps.isOperational() + (info==null||info.length()==0?"":( ",info=" + info ))); 919 920 if ( ps.isOperational()){ 921 922 Plugin plugin = getPlugin(); 923 924 if ( plugin instanceof AEDiagnosticsEvidenceGenerator ){ 925 926 try{ 927 writer.indent(); 928 929 ((AEDiagnosticsEvidenceGenerator)plugin).generate( writer ); 930 931 }catch( Throwable e ){ 932 933 writer.println( "Failed to generate plugin-specific info: " + Debug.getNestedExceptionMessage( e )); 934 935 }finally{ 936 937 writer.exdent(); 938 } 939 } 940 }else{ 941 if ( !built_in ){ 942 943 File dir = new File( plugin_dir ); 944 945 if ( dir.exists()){ 946 947 String[] files = dir.list(); 948 949 if ( files != null ){ 950 951 String files_str = ""; 952 953 for ( String f: files ){ 954 955 files_str += (files_str.length()==0?"":", ") + f; 956 } 957 958 writer.println( " files: " + files_str ); 959 } 960 } 961 } 962 } 963 }finally{ 964 965 writer.exdent(); 966 } 967 } 968 isDisabled()969 public boolean isDisabled() { 970 PluginDeprecation.call("isDisabled", this.given_plugin_id); 971 return getPluginState().isDisabled(); 972 } 973 setDisabled(boolean disabled)974 public void setDisabled(boolean disabled) { 975 PluginDeprecation.call("setDisabled", this.given_plugin_id); 976 getPluginState().setDisabled(disabled); 977 } 978 getPluginState()979 public PluginState getPluginState() { 980 return this.state; 981 } 982 getPluginStateImpl()983 PluginStateImpl getPluginStateImpl() { 984 return this.state; 985 } 986 987 988 // unfortunately we need to protect ourselves against the plugin itself trying to set 989 // plugin.version and plugin.id as this screws things up if they get it "wrong". 990 // They should be setting these things in the plugin.properties file 991 // currently the RSSImport plugin does this (version 1.1 sets version as 1.0) 992 993 protected class 994 propertyWrapper 995 extends Properties 996 { 997 protected boolean initialising = true; 998 999 protected propertyWrapper( Properties _props )1000 propertyWrapper( 1001 Properties _props ) 1002 { 1003 Iterator it = _props.keySet().iterator(); 1004 1005 while( it.hasNext()){ 1006 1007 Object key = it.next(); 1008 1009 put( key, _props.get(key)); 1010 } 1011 1012 initialising = false; 1013 } 1014 1015 public Object setProperty( String str, String val )1016 setProperty( 1017 String str, 1018 String val ) 1019 { 1020 // if its us then we probably know what we're doing :P 1021 1022 if ( ! ( plugin.getClass().getName().startsWith( "org.gudy") || plugin.getClass().getName().startsWith( "com.aelitis."))){ 1023 1024 if ( str.equalsIgnoreCase( "plugin.id" ) || str.equalsIgnoreCase("plugin.version" )){ 1025 1026 if (org.gudy.azureus2.core3.logging.Logger.isEnabled()) 1027 org.gudy.azureus2.core3.logging.Logger 1028 .log(new LogEvent(LOGID, LogEvent.LT_WARNING, "Plugin '" 1029 + getPluginName() + "' tried to set property '" + str 1030 + "' - action ignored")); 1031 1032 return( null ); 1033 } 1034 } 1035 1036 return( super.setProperty( str, val )); 1037 } 1038 1039 public Object put( Object key, Object value )1040 put( 1041 Object key, 1042 Object value ) 1043 { 1044 // if its us then we probably know what we're doing :P 1045 1046 if ( ! ( plugin.getClass().getName().startsWith( "org.gudy") || plugin.getClass().getName().startsWith( "com.aelitis."))){ 1047 1048 if ((!initialising ) && key instanceof String ){ 1049 1050 String k_str = (String)key; 1051 1052 if ( k_str.equalsIgnoreCase( "plugin.id" ) || k_str.equalsIgnoreCase("plugin.version" )){ 1053 1054 if (org.gudy.azureus2.core3.logging.Logger.isEnabled()) 1055 org.gudy.azureus2.core3.logging.Logger.log(new LogEvent(LOGID, 1056 LogEvent.LT_WARNING, "Plugin '" + getPluginName() 1057 + "' tried to set property '" + k_str 1058 + "' - action ignored")); 1059 1060 return( null ); 1061 } 1062 } 1063 } 1064 1065 return( super.put( key, value )); 1066 } 1067 1068 public Object get( Object key )1069 get( 1070 Object key ) 1071 { 1072 return( super.get(key)); 1073 } 1074 } 1075 } 1076