1 /* 2 * File : COConfigurationManager.java 3 * Created : 5 Oct. 2003 4 * By : Parg 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.core3.config; 24 25 import java.security.AccessControlException; 26 import java.security.Security; 27 import java.util.List; 28 import java.util.Map; 29 import java.util.Set; 30 import java.io.File; 31 import java.io.FileInputStream; 32 import java.io.FileOutputStream; 33 import java.io.IOException; 34 import java.io.InputStreamReader; 35 import java.io.LineNumberReader; 36 import java.io.OutputStreamWriter; 37 import java.io.PrintWriter; 38 import java.net.URL; 39 40 import org.gudy.azureus2.core3.config.impl.*; 41 import org.gudy.azureus2.core3.util.Constants; 42 import org.gudy.azureus2.core3.util.IndentWriter; 43 import org.gudy.azureus2.core3.util.SystemProperties; 44 import org.gudy.azureus2.core3.util.protocol.AzURLStreamHandlerFactory; 45 46 public class 47 COConfigurationManager 48 { 49 public static final int CONFIG_DEFAULT_MIN_MAX_UPLOAD_SPEED = 5; 50 public static final int CONFIG_DEFAULT_MAX_DOWNLOAD_SPEED = 0; 51 public static final int CONFIG_DEFAULT_MAX_CONNECTIONS_PER_TORRENT = 50; 52 public static final int CONFIG_DEFAULT_MAX_CONNECTIONS_GLOBAL = 250; 53 54 public static final int CONFIG_CACHE_SIZE_MAX_MB; 55 56 static{ 57 long max_mem_bytes = Runtime.getRuntime().maxMemory(); 58 long mb_1 = 1*1024*1024; 59 long mb_32 = 32*mb_1; 60 int size = (int)(( max_mem_bytes - mb_32 )/mb_1); 61 if( size > 2000 ) size = 2000; //safety check 62 if( size < 1 ) size = 1; 63 CONFIG_CACHE_SIZE_MAX_MB = size; 64 } 65 66 public static final boolean ENABLE_MULTIPLE_UDP_PORTS = false; 67 68 private static boolean pre_initialised; 69 70 public static synchronized void preInitialise()71 preInitialise() 72 { 73 if ( !pre_initialised ){ 74 75 pre_initialised = true; 76 77 try{ 78 if ( System.getProperty( "azureus.portable.enable", "false" ).equalsIgnoreCase( "true" )){ 79 80 try{ 81 if ( File.separatorChar != '\\' ){ 82 83 throw( new Exception( "Portable only supported on Windows" )); 84 } 85 86 File portable_root; 87 88 try{ 89 portable_root = new File( "." ).getCanonicalFile(); 90 91 }catch( Throwable e ){ 92 93 portable_root = new File( "." ).getAbsoluteFile(); 94 } 95 96 if ( !portable_root.canWrite()){ 97 98 throw( new Exception( "can't write to " + portable_root )); 99 } 100 101 File root_file = new File( portable_root, "portable.dat" ); 102 103 String str = portable_root.getAbsolutePath(); 104 105 if ( str.length() < 2 || str.charAt(1) != ':' ){ 106 107 throw( new Exception( "drive letter missing in '" + str + "'" )); 108 } 109 110 String root_relative = str.substring( 2 ); 111 112 boolean write_file = true; 113 114 if ( root_file.exists()){ 115 116 LineNumberReader lnr = new LineNumberReader( new InputStreamReader( new FileInputStream( root_file ), "UTF-8" )); 117 118 try{ 119 String line = lnr.readLine(); 120 121 if ( line != null ){ 122 123 line = line.trim(); 124 125 if ( line.equalsIgnoreCase( root_relative )){ 126 127 write_file = false; 128 129 }else{ 130 131 throw( new Exception( "root changed - old='" + line + "', new='" + root_relative )); 132 } 133 } 134 }finally{ 135 136 lnr.close(); 137 } 138 } 139 140 if ( write_file ){ 141 142 PrintWriter pw = new PrintWriter( new OutputStreamWriter( new FileOutputStream( root_file ), "UTF-8" )); 143 144 try{ 145 pw.println( root_relative ); 146 147 }finally{ 148 149 pw.close(); 150 } 151 } 152 153 System.setProperty( "azureus.install.path", str ); 154 System.setProperty( "azureus.config.path", str ); 155 156 System.setProperty( "azureus.portable.root", str ); 157 158 System.out.println( "Portable setup OK - root=" + root_relative + " (current=" + str + ")" ); 159 160 }catch( Throwable e ){ 161 162 System.err.println( "Portable setup failed: " + e.getMessage()); 163 164 System.setProperty( "azureus.portable.enable", "false" ); 165 166 System.setProperty( "azureus.portable.root", "" ); 167 } 168 }else{ 169 170 System.setProperty( "azureus.portable.root", "" ); 171 } 172 173 /* 174 String handlers = System.getProperty( "java.protocol.handler.pkgs" ); 175 176 if ( handlers == null ){ 177 178 handlers = "org.gudy.azureus2.core3.util.protocol"; 179 180 }else{ 181 182 handlers += "|org.gudy.azureus2.core3.util.protocol"; 183 } 184 185 System.setProperty( "java.protocol.handler.pkgs", handlers ); 186 */ 187 188 /* for the moment disable this as it is causing some users to get an SSL exception on 189 * trackers with Java 7 due to the tracker hostname setup 190 * See http://stackoverflow.com/questions/7615645/ssl-handshake-alert-unrecognized-name-error-since-upgrade-to-java-1-7-0 191 */ 192 193 // Update: nope, disabling this is causing too much other trouble, worked around SNI issues 194 // with various hacks... 195 //System.setProperty( "jsse.enableSNIExtension", "false" ); 196 197 try{ 198 // From Java 9 onwards this removes the need for unlimited policy files 199 // https://bugs.openjdk.java.net/browse/JDK-7024850 200 201 Security.setProperty( "crypto.policy", "unlimited"); 202 203 }catch( Throwable e ){ 204 } 205 206 System.setProperty( "sun.net.maxDatagramSockets", "4096" ); 207 208 URL.setURLStreamHandlerFactory(new AzURLStreamHandlerFactory()); 209 210 // DNS cache timeouts 211 212 System.setProperty("sun.net.inetaddr.ttl", "60"); 213 System.setProperty("networkaddress.cache.ttl", "60"); 214 System.setProperty("sun.net.inetaddr.negative.ttl", "300" ); 215 System.setProperty("networkaddress.cache.negative.ttl", "300" ); 216 217 // flick AWT into headless mode, which is supposed to make it more lightweight 218 // don't do this as it borks (for example) swing based plugins, java webstart installer, 219 // swing webui plugin, .... 220 221 // System.setProperty("java.awt.headless", "true"); 222 223 // defaults, overridden later if needed 224 225 System.setProperty( "sun.net.client.defaultConnectTimeout", "120000" ); 226 System.setProperty( "sun.net.client.defaultReadTimeout", "60000" ); 227 228 // allows us to set HOST headers which is needed when working with Tor+nginx... 229 230 System.setProperty( "sun.net.http.allowRestrictedHeaders", "true" ); 231 232 //see http://developer.apple.com/releasenotes/Java/Java142RN/ResolvedIssues/chapter_3_section_7.html 233 //fixes the osx kernel panic bug caused by Apple's faulty kqueue implementation (as of 10.3.6) 234 235 if( Constants.isOSX ) { 236 237 // things seem good in 10.6 238 239 //if ( !Constants.isOSX_10_6_OrHigher ){ 240 241 System.setProperty( "java.nio.preferSelect", "true" ); 242 //} 243 } 244 245 //if ( Constants.IS_CVS_VERSION && ( Constants.isOSX || Constants.isWindows )){ 246 // everyone gets this as we use it to force prevent resolution when running socks 247 248 System.setProperty("sun.net.spi.nameservice.provider.1","dns,aednsproxy"); 249 250 //} 251 252 SystemProperties.determineApplicationName(); 253 254 }catch( Throwable e ){ 255 256 // can happen in applet 257 258 if ( e instanceof AccessControlException ){ 259 260 }else{ 261 262 e.printStackTrace(); 263 } 264 } 265 } 266 } 267 268 public static ConfigurationManager initialise()269 initialise() 270 { 271 preInitialise(); 272 273 return ConfigurationManager.getInstance(); 274 } 275 276 public static ConfigurationManager initialiseFromMap( Map data )277 initialiseFromMap( 278 Map data ) 279 { 280 preInitialise(); 281 282 return ConfigurationManager.getInstance(data); 283 } 284 285 public static final boolean isNewInstall()286 isNewInstall() 287 { 288 return( ConfigurationManager.getInstance().isNewInstall()); 289 } 290 291 public static String getStringParameter( String _name )292 getStringParameter( 293 String _name ) 294 { 295 return( ConfigurationManager.getInstance().getStringParameter( _name )); 296 } 297 298 public static String getStringParameter( String _name, String _default )299 getStringParameter( 300 String _name, 301 String _default ) 302 { 303 return( ConfigurationManager.getInstance().getStringParameter( _name, _default )); 304 } 305 306 public static boolean setParameter(String parameter, String value)307 setParameter(String parameter, String value) 308 { 309 return ConfigurationManager.getInstance().setParameter( parameter, value ); 310 } 311 312 public static boolean verifyParameter(String parameter, String value)313 verifyParameter(String parameter, String value) 314 { 315 return ConfigurationManager.getInstance().verifyParameter( parameter, value ); 316 } 317 318 public static boolean getBooleanParameter( String _name )319 getBooleanParameter( 320 String _name ) 321 { 322 return( ConfigurationManager.getInstance().getBooleanParameter( _name )); 323 } 324 325 /** 326 * @deprecated You should set ConfigurationDefaults, and use {@link #getBooleanParameter(String)} 327 */ 328 public static boolean getBooleanParameter( String _name, boolean _default )329 getBooleanParameter( 330 String _name, 331 boolean _default ) 332 { 333 return( ConfigurationManager.getInstance().getBooleanParameter( _name, _default )); 334 } 335 336 public static boolean setParameter(String parameter, boolean value)337 setParameter(String parameter, boolean value) 338 { 339 return ConfigurationManager.getInstance().setParameter( parameter, value ); 340 } 341 342 public static int getIntParameter( String _name )343 getIntParameter( 344 String _name ) 345 { 346 return( ConfigurationManager.getInstance().getIntParameter( _name )); 347 } 348 349 350 /** 351 * Only use this for internal values, NOT for ones that the user can sensibly change. In this 352 * case add the key to the configuration defaults and use the above method 353 * @param _name 354 * @param _def 355 * @return 356 */ 357 358 public static int getIntParameter( String _name, int _default )359 getIntParameter( 360 String _name, 361 int _default ) 362 { 363 return( ConfigurationManager.getInstance().getIntParameter( _name, _default )); 364 } 365 366 public static boolean setParameter(String parameter, int value)367 setParameter(String parameter, int value) 368 { 369 return ConfigurationManager.getInstance().setParameter( parameter, value ); 370 } 371 372 public static boolean setParameter(String parameter, long value)373 setParameter(String parameter, long value) 374 { 375 return ConfigurationManager.getInstance().setParameter( parameter, value ); 376 } 377 378 public static long getLongParameter( String _name )379 getLongParameter( 380 String _name ) 381 { 382 return( ConfigurationManager.getInstance().getLongParameter( _name )); 383 } 384 385 /** 386 * Only use this for internal values, NOT for ones that the user can sensibly change. In this 387 * case add the key to the configuration defaults and use the above method 388 * @param _name 389 * @param _def 390 * @return 391 */ 392 393 public static long getLongParameter( String _name, long _def )394 getLongParameter( 395 String _name, 396 long _def ) 397 { 398 return( ConfigurationManager.getInstance().getLongParameter( _name, _def )); 399 } 400 getByteParameter(String _name)401 public static byte[] getByteParameter(String _name) { 402 return( ConfigurationManager.getInstance().getByteParameter(_name)); 403 } 404 405 public static byte[] getByteParameter( String _name, byte[] _default )406 getByteParameter( 407 String _name, 408 byte[] _default ) 409 { 410 return( ConfigurationManager.getInstance().getByteParameter( _name, _default )); 411 } 412 413 public static boolean setParameter(String parameter, byte[] value)414 setParameter(String parameter, byte[] value) 415 { 416 return ConfigurationManager.getInstance().setParameter( parameter, value ); 417 } 418 419 public static String getDirectoryParameter( String _name )420 getDirectoryParameter( 421 String _name ) 422 throws IOException 423 { 424 return( ConfigurationManager.getInstance().getDirectoryParameter( _name )); 425 } 426 427 428 429 /* 430 public static boolean 431 setParameter(String parameter, Color value) 432 { 433 return ConfigurationManager.getInstance().setParameter( parameter, value ); 434 } 435 436 public static boolean 437 setParameter(String parameter, RGB value) 438 { 439 return ConfigurationManager.getInstance().setParameter( parameter, value ); 440 } 441 */ 442 443 public static boolean setRGBParameter(String parameter, int red, int green, int blue)444 setRGBParameter(String parameter, int red, int green, int blue) 445 { 446 return ConfigurationManager.getInstance().setRGBParameter( parameter, red, green, blue); 447 } 448 setRGBParameter(String parameter, int[] rgb, boolean override)449 public static boolean setRGBParameter(String parameter, int[] rgb, boolean override) { 450 return ConfigurationManager.getInstance().setRGBParameter(parameter, rgb, override); 451 } 452 453 public static float getFloatParameter( String _name)454 getFloatParameter( 455 String _name) 456 { 457 return( ConfigurationManager.getInstance().getFloatParameter( _name )); 458 } 459 460 public static float getFloatParameter( String _name, float _def )461 getFloatParameter( 462 String _name, 463 float _def ) 464 { 465 return( ConfigurationManager.getInstance().getFloatParameter( _name, _def )); 466 } 467 public static boolean setParameter(String parameter, float value)468 setParameter(String parameter, float value) 469 { 470 return ConfigurationManager.getInstance().setParameter( parameter, value ); 471 } 472 473 public static boolean setParameter(String parameter,StringList value)474 setParameter(String parameter,StringList value) { 475 return ConfigurationManager.getInstance().setParameter( parameter, value ); 476 } 477 478 public static StringList getStringListParameter(String parameter)479 getStringListParameter(String parameter) 480 { 481 return( ConfigurationManager.getInstance().getStringListParameter( parameter )); 482 } 483 484 public static boolean setParameter(String parameter,List value)485 setParameter(String parameter,List value) { 486 return ConfigurationManager.getInstance().setParameter( parameter, value ); 487 } 488 489 public static List getListParameter(String parameter, List def)490 getListParameter(String parameter, List def) 491 { 492 return( ConfigurationManager.getInstance().getListParameter( parameter, def )); 493 } 494 495 public static boolean setParameter(String parameter,Map value)496 setParameter(String parameter,Map value) { 497 return ConfigurationManager.getInstance().setParameter( parameter, value ); 498 } 499 500 public static Map getMapParameter(String parameter, Map def)501 getMapParameter(String parameter, Map def) 502 { 503 return( ConfigurationManager.getInstance().getMapParameter( parameter, def )); 504 } 505 506 /** 507 * Returns true if a parameter with the given name exists. 508 * @param key The name of the parameter to check. 509 * @param explicit If <tt>true</tt>, we only check for a value which is 510 * definitely stored explicitly, <tt>false</tt> means that we'll also 511 * check against configuration defaults too. 512 */ hasParameter(String parameter, boolean explicit)513 public static boolean hasParameter(String parameter, boolean explicit) { 514 return ConfigurationManager.getInstance().hasParameter(parameter, explicit); 515 } 516 517 public static void save()518 save() 519 { 520 ConfigurationManager.getInstance().save(); 521 } 522 523 /** 524 * Mark as needing a save but not immediately - use when potentially needing a large number of saves that aren't 525 * absolutely required to be immediately persisted 526 */ 527 528 public static void setDirty()529 setDirty() 530 { 531 ConfigurationManager.getInstance().setDirty(); 532 } 533 534 public static void addListener( COConfigurationListener listener )535 addListener( 536 COConfigurationListener listener ) 537 { 538 ConfigurationManager.getInstance().addListener( listener ); 539 } 540 541 public static void addAndFireListener( COConfigurationListener listener )542 addAndFireListener( 543 COConfigurationListener listener ) 544 { 545 ConfigurationManager.getInstance().addAndFireListener( listener ); 546 } 547 548 public static void addParameterListener(String parameter, ParameterListener listener)549 addParameterListener(String parameter, ParameterListener listener) 550 { 551 ConfigurationManager.getInstance().addParameterListener(parameter, listener); 552 } 553 554 /** 555 * @param strings 556 * @param parameterListener 557 * 558 * @since 3.0.1.5 559 */ addParameterListener(String[] ids, ParameterListener listener)560 public static void addParameterListener(String[] ids, 561 ParameterListener listener) { 562 ConfigurationManager instance = ConfigurationManager.getInstance(); 563 for (int i = 0; i < ids.length; i++) { 564 instance.addParameterListener(ids[i], listener); 565 } 566 } 567 568 public static void addAndFireParameterListener(String parameter, ParameterListener listener)569 addAndFireParameterListener(String parameter, ParameterListener listener) 570 { 571 ConfigurationManager.getInstance().addParameterListener(parameter, listener); 572 573 listener.parameterChanged( parameter ); 574 } 575 576 public static void addAndFireParameterListeners(String[] parameters, ParameterListener listener)577 addAndFireParameterListeners(String[] parameters, ParameterListener listener) 578 { 579 for (int i=0;i<parameters.length;i++){ 580 ConfigurationManager.getInstance().addParameterListener(parameters[i], listener); 581 } 582 583 listener.parameterChanged( null ); 584 } 585 public static void removeParameterListener(String parameter, ParameterListener listener)586 removeParameterListener(String parameter, ParameterListener listener) 587 { 588 ConfigurationManager.getInstance().removeParameterListener(parameter, listener); 589 } 590 591 public static void removeListener( COConfigurationListener listener )592 removeListener( 593 COConfigurationListener listener ) 594 { 595 ConfigurationManager.getInstance().removeListener( listener ); 596 } 597 598 public static Set<String> getAllowedParameters()599 getAllowedParameters() 600 { 601 return ConfigurationDefaults.getInstance().getAllowedParameters(); 602 } 603 604 public static Set<String> getDefinedParameters()605 getDefinedParameters() 606 { 607 return ConfigurationManager.getInstance().getDefinedParameters(); 608 } 609 610 /** 611 * raw parameter access 612 * @param name 613 * @return 614 */ 615 public static Object getParameter( String name )616 getParameter( 617 String name ) 618 { 619 return ConfigurationManager.getInstance().getParameter(name); 620 } 621 622 /** 623 * checks if a default is defined for the named parameter 624 * @param parameter 625 * @return 626 */ 627 628 public static boolean doesParameterDefaultExist( String parameter)629 doesParameterDefaultExist( 630 String parameter) 631 { 632 return ConfigurationDefaults.getInstance().doesParameterDefaultExist(parameter); 633 } 634 635 /** 636 * checks if the user has explicitly set a value for the named parameter 637 * @param parameter 638 * @return 639 */ 640 641 public static boolean doesParameterNonDefaultExist( String parameter)642 doesParameterNonDefaultExist( 643 String parameter) 644 { 645 return ConfigurationManager.getInstance().doesParameterNonDefaultExist(parameter); 646 } 647 public static void registerExternalDefaults( Map addmap)648 registerExternalDefaults( 649 Map addmap) 650 { 651 ConfigurationDefaults.getInstance().registerExternalDefaults(addmap); 652 } 653 654 public static void setBooleanDefault( String parameter, boolean _default )655 setBooleanDefault( 656 String parameter, 657 boolean _default ) 658 { 659 ConfigurationDefaults.getInstance().addParameter( parameter, _default ); 660 } 661 setFloatDefault(String parameter, float _default)662 public static void setFloatDefault(String parameter, float _default) { 663 ConfigurationDefaults.getInstance().addParameter( parameter, _default ); 664 } 665 666 public static void setIntDefault( String parameter, int _default )667 setIntDefault( 668 String parameter, 669 int _default ) 670 { 671 ConfigurationDefaults.getInstance().addParameter( parameter, _default ); 672 } 673 674 public static void setLongDefault( String parameter, long _default )675 setLongDefault( 676 String parameter, 677 long _default ) 678 { 679 ConfigurationDefaults.getInstance().addParameter( parameter, _default ); 680 } 681 682 public static void setStringDefault( String parameter, String _default )683 setStringDefault( 684 String parameter, 685 String _default ) 686 { 687 ConfigurationDefaults.getInstance().addParameter( parameter, _default ); 688 } 689 690 public static void setByteDefault( String parameter, byte[] _default )691 setByteDefault( 692 String parameter, 693 byte[] _default ) 694 { 695 ConfigurationDefaults.getInstance().addParameter( parameter, _default ); 696 } 697 698 public static Object getDefault( String parameter )699 getDefault( 700 String parameter ) 701 { 702 return( ConfigurationDefaults.getInstance().getParameter( parameter )); 703 } 704 removeParameter(String parameter)705 public static boolean removeParameter(String parameter) { 706 return ConfigurationManager.getInstance().removeParameter(parameter); 707 } 708 removeRGBParameter(String parameter)709 public static boolean removeRGBParameter(String parameter) { 710 return ConfigurationManager.getInstance().removeRGBParameter(parameter); 711 } 712 713 public static void registerExportedParameter( String name, String key )714 registerExportedParameter( 715 String name, 716 String key ) 717 { 718 ConfigurationManager.getInstance().registerExportedParameter( name, key ); 719 } 720 721 public static void resetToDefaults()722 resetToDefaults() 723 { 724 ConfigurationManager.getInstance().resetToDefaults(); 725 } 726 727 public static void addResetToDefaultsListener( ResetToDefaultsListener l )728 addResetToDefaultsListener( 729 ResetToDefaultsListener l ) 730 { 731 ConfigurationManager.getInstance().addResetToDefaultsListener( l ); 732 } 733 734 public static void dumpConfigChanges( IndentWriter writer )735 dumpConfigChanges( 736 IndentWriter writer ) 737 { 738 ConfigurationManager.getInstance().dumpConfigChanges( writer ); 739 } 740 741 public interface 742 ParameterVerifier 743 { 744 public boolean verify( String parameter, Object value )745 verify( 746 String parameter, 747 Object value ); 748 } 749 750 public interface 751 ResetToDefaultsListener 752 { 753 public void reset()754 reset(); 755 } 756 } 757