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