/*
| GSObjectComm.java
|------------------------------------------------------------------------------
| Copyright 2000 by GalaSoft Laurent Bugnion
|------------------------------------------------------------------------------
| Project Name : GSUtils
| Package Name : galasoftLB.api.pGSUtils
| Target : JAVA Virtual machine (JRE #1.0.2)
| Language/Compiler : JAVA JDK #1.0.2
| Development environment: JBuilder 3.0 Professional
| Author : Laurent Bugnion
|------------------------------------------------------------------------------
| Description:
| See JavaDoc section here under.
|
| History:
| 08.12.1999 Lbu : First release.
| Backup03 of package.
| 10.05.2000 Lbu : New release of package because of new website.
| Backup04 of package (V1.0-1).
| 05.09.2000 Lbu : Changed demo version to work also locally on e:\galasoft\myjava
| Backup05 of package (V1.0-2)
|------------------------------------------------------------------------------
*/
package galasoftLB.api.pGSUtils;
/* Imports *******************************************************************/
/* Standard */
import java.applet.*;
import java.util.*;
/* JavaDoc *******************************************************************/
/**
* Description
*
This class will be used when it is needed that 2 objects communicate.
*
As long as all objects run inside the same virtual machine,
* the communication can be established.
*
Typically, this class can be used to have two applets communicate
* (also across frames or browser-windows).
*
*
To use this class, follow this sequence:
*
* - 1) in each object's init method or constructor, call
* GSObjectComm.init()
*
These calls will create one (and only one) instance of the object's
* list.
*
* - 2) in each object, call GSObjectComm.addObject( this )
*
This will add the current object to the object's list.
*
* - 3) when an object wishes to communicate with another, use:
*
Object theOtherObject = GSObjectComm.getObject( "theOtherObjectName" );
*
You can then cast theOtherObject to its type.
*
It is therefore necessary that the calling object knows the callee's name
* and its type.
*
For more flexibility in applets, it is recommended that the callee's name is
* passed to the caller as a parameter.
*
(use the HTML tags <PARAM> to do this).
*
* Known bugs, limitations
*
* - In Internet explorer, two applets in different windows can communicate
* only if both windows belong to the same instance of the Internet explorer.
*
If the second window has been opened through the menu "File New window",
* or if it has been opened with a javascript call, it will work.
*
If the second window has been opened by double-clicking the Internet Explorer
* icon, a second virtual machine is started, and the method won't work.
* - In Netscape, when a page is loaded, clicking shift-reload will reload the
* page and restart the applets. As I tested, this will cause this class
* to not work properly anymore (only after the shift-reload has been executed).
* Apparently, it is a bug in Netscape (tested in Netscape 4.7 on NT4.0 and Win95).
* - In Netscape, when an applet is defined with the attribute MAYSCRIPT (for
* communication with JavaScript using the LiveConnect technology), this class
* cannot be used. It is thus necessary to avoid using LiveConnect in applets
* using this class.
*
*
* @author Laurent Bugnion, GalaSoft
* @version 1.0-2, 05.09.2000, JDK 1.0.2
*/
public abstract class GSObjectComm
{
/* Class attributes ********************************************************/
/* static */
/* Constants ***************************************************************/
/* final */
/* Instance attributes *****************************************************/
/* This hashtable follows the singleton pattern: there can be one and only */
/* one instance of theHT. As it is static, every access to it must be */
/* synchronized to avoid that two objects access it simultaneously. */
private static Hashtable theHT;
/* If this attribute is true, some messages will be sent to the java */
/* console when the other methods are called. */
private static boolean outputOnConsole = false;
/* Components of the object ************************************************/
/* Constructors ************************************************************/
/* No constructor (the class is abstract) */
/***************************************************************************/
/* These methods are called by the objects wishing to communicate **********/
/***************************************************************************/
/***************************************************************************/
/** Must be called by both objects before they inscribe
* themselves in the objects' list. It makes sure that one and only one
* instance of the objects' list exist.
*
* If the method enableOutputOnConsole(true) has been called before,
* some infos will be sent to the java console when this method is called.
*/
synchronized public static void init()
{
if ( outputOnConsole )
{
System.out.println( "init called in GSObjectComm" );
}
if ( theHT == null )
{
if ( outputOnConsole )
{
System.out.println( "creating hashtable" );
}
theHT = new Hashtable();
}
}
/***************************************************************************/
/** Is used by the objects who wish to be added in the list.
*
* If the method enableOutputOnConsole(true) has been called before,
* some infos will be sent to the java console when this method is called.
*
* @param name the name of the object to be added;
*
for an applet, typically, the name of the applet used in the HTML tag NAME.
* @param anObject the object to be added
*
* @exception Exception If name is already used in this list, an exception
* is thrown.
*/
synchronized public static void addObject( String name, Object anObject )
throws Exception
{
/* Uncomment the "demos" comments to produce a demo version runnable in GalaSoft only */
//demos*/ Applet anObjectAsApplet = (Applet) anObject;
//demos*/ String theCodeBase = anObjectAsApplet.getCodeBase().toString();
//demos*/ if ( ( theCodeBase.indexOf( "http://www.galasoft-lb.ch/" ) != -1 )
//demos*/ || ( theCodeBase.toLowerCase().indexOf( "file:/e|/galasoft/myjava/" ) != -1 ) )
//demos*/ {
if ( outputOnConsole )
{
System.out.println( "Checking " + name );
}
if ( theHT.containsKey( name ) )
{
String msg = name + " is already used as key in this virtual machine";
Exception ex = new Exception( msg );
throw ex;
}
else
{
if ( outputOnConsole )
{
System.out.println( "Adding " + name );
}
theHT.put( name, anObject );
}
}
/***************************************************************************/
/** Is used when an object wishes to be removed from the list.
*
When this class is used with applets, it is highly recommended that
* every applet calls this method in its stop() method.
*
* If the method enableOutputOnConsole(true) has been called before,
* some infos will be sent to the java console when this method is called.
*
* @param name the name of the object to be removed;
*
for an applet, typically, the name of the applet used in the HTML tag NAME.
*/
synchronized public static void removeObject( String name )
{
if ( outputOnConsole )
{
System.out.println( "removing " + name );
}
theHT.remove( name );
}
/***************************************************************************/
/** Is used to get an object from the list, in order to
* communicate with it.
*
* If the method enableOutputOnConsole(true) has been called before,
* some infos will be sent to the java console when this method is called.
*
* @param name the name of the object to be returned;
*
for an applet, typically, the name of the applet used in the HTML tag NAME.
* @return the object whose name is passed in parameter;
*
if name cannot be found, null.
*/
synchronized public static Object getObject( String name )
{
if ( outputOnConsole )
{
System.out.println( "getting " + name );
}
return theHT.get( name );
}
/***************************************************************************/
/** Enables the output of messages on the java console when
* different methods of this class are called.
*
This feature is very useful when developing new applications, to debug
* the communication.
*
* @param enable must be true if an output is wanted on the console,
* false if not.
*/
public static void enableOutputOnConsole( boolean enable )
{
outputOnConsole = enable;
showStatusOfConsole();
}
/***************************************************************************/
/** Shows on the console if the output is enabled or not for
* the other methods of this class.
*
* @returns true is the output is enabled, false if not.
*/
public static boolean showStatusOfConsole()
{
if ( outputOnConsole )
{
System.out.println( "Output on the console is enabled" );
}
else
{
System.out.println( "Output on the console is disabled" );
}
return outputOnConsole;
}
}