package net.xoetrope.xui;
import java.lang.reflect.Method;
import java.util.EventObject;
import java.util.Hashtable;
import java.awt.AWTEvent;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.event.TextEvent;
import java.awt.event.TextListener;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.Reader;
import java.net.URL;
import java.util.Enumeration;
import java.util.Vector;
import net.xoetrope.xui.build.BuildProperties;
import net.xoetrope.debug.DebugLogger;
import net.xoetrope.xml.XmlElement;
import net.xoetrope.xml.XmlSource;
import net.xoetrope.xui.evaluator.XAttributeEvaluator;
import net.xoetrope.xui.evaluator.XDefaultAttributeEvaluator;
import net.xoetrope.xui.events.XAction;
import net.xoetrope.xui.events.XActionManager;
import net.xoetrope.xui.events.XEventAdapter;
import net.xoetrope.xui.events.XListenerHelper;
import net.xoetrope.xui.events.XuiEventHandler;
import net.xoetrope.xui.exception.XExceptionHandler;
import net.xoetrope.xui.helper.ReflectionHelper;
import net.xoetrope.xui.helper.XuiUtilities;
import net.xoetrope.xui.validation.XValidationHandler;
import net.xoetrope.xui.validation.XValidator;
/**
* <p>Implements an event handler for XUI. Most of the common events
* are handled. The class is intended as a mixin for a panel class such as
* XPage and should not be used directly</p>
* <p>Copyright (c) Xoetrope Ltd., 2002-2003</p>
* <p>License: see license.txt</p>
* $Revision: 2.26 $
*/
public class XEventHandler implements XuiEventHandler, ActionListener, FocusListener, TextListener,
ItemListener, KeyListener, MouseListener,
MouseMotionListener
{
/**
* The config files used to build the set of component adapters. Stores the
* file names
*/
protected static Hashtable configFiles;
/**
* A counter for changes to the registry. Used to indicate if the registry
* needs to be rebuilt
*/
protected static int changeCounter;
/**
* Used for tracking changes to the registry spec.
*/
protected static int localChangeCounter = -1;
/**
* The collection of registered event handlers that are known
*/
protected static Hashtable registrations;
/**
* The current event, valid until processed
*/
protected static EventObject currentEvt;
/**
* The page or object whose event is being handled
*/
protected Object container;
/**
* The current project, the project that ultimately owns this event handler
*/
protected XProject currentProject;
/**
* The collection of event handlers that are known
*/
protected Hashtable handlers;
/**
* The component that owned the mouse pressed event
*/
protected Object mouseDownComponent = null;
/**
* A flagh indicating if the mouse event has been invoked yet
*/
protected boolean mouseEventInvoked = false;
/**
* A flag to dictate how focus event are processed in the event of a message display
*/
protected /*static*/ int suppressFocusEvents = 0;
/**
* The validation handler
*/
protected XValidationHandler xValidationHandler;
// private XEventHandler instance;
/**
* Create an event handler
* @param project the owner project
* @param c the container/page
* @param vh the validation handler
*/
public XEventHandler( XProject project, Object c, XValidationHandler vh )
{
handlers = new Hashtable( 5 );
if ( registrations == null )
registrations = new Hashtable();
currentProject = project;
container = c;
xValidationHandler = vh;
xValidationHandler.setupEventHandler( this );
currentProject = project;
if ( BuildProperties.DEBUG )
DebugLogger.trace( "Setting up XValidationFactory" );
addConfigFile( "XUI", "net/xoetrope/xui/events/events.xml", false );
currentProject = project;
String projectEventFile = currentProject.getStartupParam( "EventHandlers" );
if ( ( projectEventFile == null ) || ( projectEventFile.length() == 0 ) )
projectEventFile = "events.xml";
if ( projectEventFile.indexOf( ".xml" ) < 0 )
projectEventFile += ".xml";
URL url = currentProject.findResource( projectEventFile );
if ( url != null )
addConfigFile( "Project", url, false );
}
/**
* Remove all the event handlers for a particular object
* @param comp the object whose events are being removed
*/
public void removeHandlers( Object comp )
{
long hashCode = comp.hashCode();
if ( comp instanceof XHashCode )
hashCode = ( ( XHashCode )comp ).getComponentHashCode();
long[] handledEvents = { AWTEvent.ACTION_EVENT_MASK, AWTEvent.FOCUS_EVENT_MASK,
AWTEvent.TEXT_EVENT_MASK, AWTEvent.ITEM_EVENT_MASK, AWTEvent.KEY_EVENT_MASK,
AWTEvent.MOUSE_EVENT_MASK, AWTEvent.MOUSE_MOTION_EVENT_MASK };
String[] listener = { "ActionListener", "FocusListener",
"TextListener", "ItemListener", "KeyListener",
"MouseListener", "MouseMotionListener"};
for ( int i = 0; i < handledEvents.length; i++ ) {
Object key = new Long( handledEvents[ i ] * hashCode );
Object handler = handlers.get( key );
if ( handler != null ) {
handlers.remove( key );
// The addListener method just invokes the named method, so it can remove the listener
// just as easily.
addListener( comp, "remove" + listener[ i ], "java.awt.event." + listener[ i ], this );
}
}
}
/**
* Get the validation handler reference. Note that you should not hold a
* reference to this value as it will probably cause a memory leak.
* @return the current validation handler
*/
public XValidationHandler getValidationHandler()
{
return xValidationHandler;
}
/**
* Invokes an event. Called in response to an event. If a handler has been
* added for the event it will be invoked.
* @param eventType the event type
* @param evt the event object
*/
public void invoke( long eventType, EventObject evt )
{
// If necessary first check for presence of a validation event handler
// the method name will be "validationHandler" and stop event dispatch if an
// error has occurred.
try {
currentEvt = evt;
if ( xValidationHandler.validationHandler( this ) > XValidator.LEVEL_WARNING )
return;
// Then call any other event handler
XMethodReference reference = (XMethodReference)handlers.get( new Long( eventType * evt.getSource().hashCode() ) );
if ( reference == null ) {
String command = (String)ReflectionHelper.getViaReflection( "getActionCommand", evt.getSource(), false );
if ( command != null ) {
XActionManager actionManager = (XActionManager)currentProject.getObject( "ActionManager" );
if ( actionManager != null ) {
XAction action = actionManager.getAction( null, command );
if ( action != null )
action.actionPerformed( evt );
}
}
return;
}
Method m = reference.method;
try {
if (( m != null ) && ( m.getName().compareTo( "validationHandler" ) != 0 ))
m.invoke( reference.instance, reference.args );
}
catch ( Throwable error ) {
DebugLogger.logWarning( "error invoking '" + m.getName() + "' in XEventHandler" );
boolean continueHandling = false;
if ( container instanceof XExceptionHandler )
continueHandling = ((XExceptionHandler)container).handleEventHandlerException( currentProject, container, error );
if ( continueHandling && ( xValidationHandler != container ))
continueHandling = xValidationHandler.handleEventHandlerException( currentProject, container, error );
if ( continueHandling ) {
XExceptionHandler exceptionHandler = currentProject.getExceptionHandler();
if ( exceptionHandler != null )
continueHandling = exceptionHandler.handleEventHandlerException( currentProject, container, error );
}
if ( continueHandling ) {
if ( BuildProperties.DEBUG )
DebugLogger.logError( "Error while invoking the method: " + reference.method.getName() + ", in class: " + reference.clazz.getName());
error.getCause().printStackTrace();
}
}
currentEvt = null;
}
catch ( Exception ex ) {
System.out.println( "Error invoking" );
}
}
/**
* Lookup an event for a component.
* @param src the event source component
* @param eventType the event type
* @return the event handler method
*/
public Method findEvent( Object src, long eventType )
{
XMethodReference reference = ( XMethodReference )handlers.get( new Long( eventType * src.hashCode() ) );
return reference.method;
}
/**
* Check the focus change status
* @return true if the focus change events are being suppressed.
*/
public boolean isFocusChangeSuppressed()
{
return suppressFocusEvents > 0;
}
/**
* Get the current event
* @return the AWTEvent that was last triggered
*/
public EventObject getCurrentEvent()
{
return currentEvt;
}
/**
* <p>Adds an event handler. A specific handler such as the addActionHandler should
* be used instead of calling this method</p>
* <p>The handler can also be defined in classes other than the current page
* or classes derived from XPage. The syntax for such expressions is as follows:</p>
* <ul>
* <li><code>mypackage.MyClass[referenceName].myMethod</code> for a named object instance</li>
* <li><code>mypackage.MyClass[].myMethod</code> to create a new instance of the class on each evaluation</li>
* <li><code>mypackage.MyClass.myMethod</code> to invoke a static method</li>
* <li><code>myMethod[referenceName]</code> for a method contained with the invoking page</li>
* </ul>
* <p>where mypackage is the name of the Java package containing the class MyClass.
* The value of referenceName is a user defined value that identifies the instance
* of the class. The application instantiates an instance of the class when
* the expression is first encountered and thereafter maintains the instance with
* each subsequent call retrieving the same instance of the class.</p>
* <p>
* The page may also reference scripts with the expression <code>${script.XXXXX()}</code>
* where <code>XXXXX</code> is the name of the script method to be invoked.</p>
* @param eventType the event type
* @param methodStr the method to be invoked in response to the object
* @param comp the component that fires the event
* @throws java.lang.ClassNotFoundException The class cannot be found
* @throws java.lang.NoSuchMethodException The specified method does not exist in the class
*/
public XMethodReference addHandler( Object comp, long eventType, String methodStr ) throws ClassNotFoundException,
NoSuchMethodException
{
XMethodReference reference;
String className, methodName;
if ( methodStr == null )
return null;
if ( methodStr.startsWith( "${script." )) {
className = "Script";
methodName = methodStr;
}
else {
int pos = methodStr.lastIndexOf( "." );
if ( pos < 0 ) {
methodName = methodStr;
className = null;
}
else {
className = methodStr.substring( 0, pos );
methodName = methodStr.substring( pos + 1 );
}
}
reference = getMethodReference( container, className, methodName );
long hashCode = comp.hashCode();
if ( comp instanceof XHashCode )
hashCode = ( ( XHashCode )comp ).getComponentHashCode();
handlers.put( new Long( eventType * hashCode ), reference );
return reference;
}
/**
* Adds a listener for an event type. This method should not normally be
* called by an application
* @param comp the component that fires events
* @param listenerName the name of the listener interface
* @param argType the listener arguments
* @param listener the listener implementation, usually the page's this pointer
*/
public void addListener( Object comp, String listenerName, String argType, Object listener )
{
try {
Class params[] = new Class[ 1 ];
params[ 0 ] = Class.forName( argType.trim());
Method m = comp.getClass().getMethod( listenerName, params );
Object args[] = new Object[ 1 ];
args[ 0 ] = listener;
m.invoke( comp, args );
}
catch ( Error error ) {
error.printStackTrace();
}
catch ( Exception e ) {
e.printStackTrace();
}
}
/**
* Adds a handler for action events
* @param srcObj the menu item that fires the events
* @param methodName the method to be invoked in response to the action event
* @param adderMethod the adder method name e.g. addActionListener
* @param listenerInterface the listener interface e.g. java.awt.event.ActionListener
* @param eventMask the event mask e.g. AWTEvent.ACTION_EVENT_MASK
* @param listener the listener implementation, usually the page's this pointer
* @see java.awt.event.ActionListener
* @see java.awt.event.ActionEvent
*/
public XMethodReference addHandler( Object srcObj, String methodName, String adderMethod, String listenerInterface, long eventMask, Object listener )
{
XMethodReference reference = null;
if ( listener == null )
listener = this;
addListener( srcObj, adderMethod, listenerInterface, listener );
try {
reference = addHandler( srcObj, eventMask, methodName );
}
catch ( Error error ) {
if ( BuildProperties.DEBUG )
DebugLogger.logError( "Unable to add the handler: " + methodName );
error.printStackTrace();
}
catch ( Exception ex ) {
ex.printStackTrace();
}
return reference;
}
/**
* A utility method used to determine if the last event corrseponds to a mouse
* click. The notion of a click is extended by assuming the a mouse press and
* release within a single component constitutes a click even if not at the
* same coordinate. A MouseEvent.MOUSE_CLICKED is only triggered when the press
* and release are at the same location and this is often inadequate for end-user
* interaction.
* @return true if the mouse was clicked
*/
public boolean wasMouseClicked()
{
if ( currentEvt != null ) {
if ( currentEvt instanceof AWTEvent ) {
AWTEvent awtEvent = (AWTEvent)currentEvt;
if ( ( awtEvent.getID() == MouseEvent.MOUSE_CLICKED ) ||
( ( awtEvent.getID() == MouseEvent.MOUSE_RELEASED ) &&
( awtEvent.getSource() == mouseDownComponent ) ) ) {
mouseDownComponent = null;
return true;
}
}
}
mouseEventInvoked = true;
return false;
}
/**
* A utility method used to determine if the last event corrseponds to a mouse
* double click. The notion of a click is extended by assuming the a mouse press and
* release within a single component constitutes a click even if not at the
* same coordinate. A MouseEvent.MOUSE_CLICKED is only triggered when the press
* and release are at the same location and this is often inadequate for end-user
* interaction.
* @return true if the mouse was double clicked
*/
public boolean wasMouseDoubleClicked()
{
if ( currentEvt != null ) {
if ( currentEvt instanceof AWTEvent ) {
AWTEvent awtEvent = (AWTEvent)currentEvt;
if ( ( awtEvent.getID() == MouseEvent.MOUSE_CLICKED ) ||
( ( awtEvent.getID() == MouseEvent.MOUSE_RELEASED ) &&
( awtEvent.getSource() == mouseDownComponent ) ) &&
(((MouseEvent)awtEvent ).getModifiers() & MouseEvent.BUTTON1_MASK ) != 0 &&
(((MouseEvent)awtEvent ).getClickCount() == 2 ) ) {
mouseDownComponent = null;
return true;
}
}
}
mouseEventInvoked = true;
return false;
}
/**
* A utility method used to determine if the last event corrseponds to a mouse
* right click. The notion of a click is extended by assuming the a mouse press and
* release within a single component constitutes a click even if not at the
* same coordinate. A MouseEvent.MOUSE_CLICKED is only triggered when the press
* and release are at the same location and this is often inadequate for end-user
* interaction.
* @return true if the mouse was right clicked
*/
public boolean wasMouseRightClicked()
{
if ( currentEvt != null ) {
if ( currentEvt instanceof AWTEvent ) {
AWTEvent awtEvent = (AWTEvent)currentEvt;
if (( awtEvent.getID() == MouseEvent.MOUSE_CLICKED ) ||
((awtEvent.getID() == MouseEvent.MOUSE_RELEASED ) &&
(awtEvent.getSource() == mouseDownComponent ) ) &&
(((MouseEvent )awtEvent ).getModifiers() & MouseEvent.BUTTON3_MASK ) != 0 ) {
mouseDownComponent = null;
return true;
}
}
}
mouseEventInvoked = true;
return false;
}
//----------------------------------------------------------------------------
/**
* Adds the specified action listener to receive action events from this button.
* Action events occur when a user presses or releases the mouse over this button.
* If l is null, no exception is thrown and no action is performed.
* @param e the event
*/
public void actionPerformed( ActionEvent e )
{
invoke( AWTEvent.ACTION_EVENT_MASK, e );
}
/**
* This event indicates that the Component is now the focus owner.
* @param e the event
*/
public void focusGained( FocusEvent e )
{
// The suppressFocusEvents flag is used as poping up a message dialog causes
// input fields to loose focus. This in turn could cause a continuous loop
// of validation errors - messages - loss of focus - validations - validation errors
if ( suppressFocusEvents < 2 ) {
invoke( AWTEvent.FOCUS_EVENT_MASK, e );
if ( suppressFocusEvents == 1 )
suppressFocusEvents++;
}
}
/**
* This event indicates that the Component is no longer the focus owner.
* @param e the event
*/
public void focusLost( FocusEvent e )
{
if ( suppressFocusEvents == 0 )
invoke( AWTEvent.FOCUS_EVENT_MASK, e );
else
suppressFocusEvents--;
}
/**
* This event indicates that object's text changed.
* @param e the event
*/
public void textValueChanged( TextEvent e )
{
invoke( AWTEvent.TEXT_EVENT_MASK, e );
}
/**
* This event indicates that an item's state changed.
* @param e the event
*/
public void itemStateChanged( ItemEvent e )
{
invoke( AWTEvent.ITEM_EVENT_MASK, e );
}
/**
* A key has been pressed
* @param e the event
*/
public void keyPressed( KeyEvent e )
{
invoke( AWTEvent.KEY_EVENT_MASK, e );
}
/**
* A key has been released
* @param e the event
*/
public void keyReleased( KeyEvent e )
{
invoke( AWTEvent.KEY_EVENT_MASK, e );
}
/**
* A key was types
* @param e the event
*/
public void keyTyped( KeyEvent e )
{
invoke( AWTEvent.KEY_EVENT_MASK, e );
}
/**
* The mouse was clicked
* @param e the event
*/
public void mouseClicked( MouseEvent e )
{
if ( !mouseEventInvoked )
invoke( AWTEvent.MOUSE_EVENT_MASK, e );
}
/**
* The mouse has been moved over the component
* @param e the event
*/
public void mouseEntered( MouseEvent e )
{
invoke( AWTEvent.MOUSE_EVENT_MASK, e );
}
/**
* The mouse has moved beyond the bounds of the component
* @param e the event
*/
public void mouseExited( MouseEvent e )
{
invoke( AWTEvent.MOUSE_EVENT_MASK, e );
}
/**
* The mouse button has been pressed
* @param e the event
*/
public void mousePressed( MouseEvent e )
{
mouseDownComponent = e.getComponent();
mouseEventInvoked = false;
invoke( AWTEvent.MOUSE_EVENT_MASK, e );
}
/**
* The mouse button has been released
* @param e the event
*/
public void mouseReleased( MouseEvent e )
{
invoke( AWTEvent.MOUSE_EVENT_MASK, e );
}
/**
* The mouse has moved
* @param e the event
*/
public void mouseMoved( MouseEvent e )
{
invoke( AWTEvent.MOUSE_MOTION_EVENT_MASK, e );
}
/**
* The mouse was dragged
* @param e the event
*/
public void mouseDragged( MouseEvent e )
{
invoke( AWTEvent.MOUSE_MOTION_EVENT_MASK, e );
}
//----------------------------------------------------------------------------
/**
* Used by messageboxes and other dialogs to prevent the display of the dialog
* causing extra focus events from being fired.
* @param suppress true to suppress focus events
*/
public void suppressFocusEvents( boolean suppress )
{
if ( suppress )
suppressFocusEvents++;
else
suppressFocusEvents = Math.max( --suppressFocusEvents, 0 );
}
//----------------------------------------------------------------------------
//----------------------------------------------------------------------------
/**
* Get a reference to a method and a class instance.
* @param container the page or object whose event is being handled
* @param className the name of the class containing the handler
* @param methodName the name of the method.
* @throws ClassNotFoundException the className class could not be loaded
* @throws NoSuchMethodException the methodName method could not be found in the className class
*/
private XMethodReference getMethodReference( Object container, String className, String methodName ) throws
ClassNotFoundException, NoSuchMethodException
{
Class clazz = null;
if ( className == null ) {
clazz = container.getClass();
className = clazz.getName();
}
if ( className.startsWith( "${" ) ) {
XAttributeEvaluator attEval = ( XAttributeEvaluator )currentProject.getObject( "DefaultAttributeEvaluator" );
if ( attEval == null ) {
attEval = new XDefaultAttributeEvaluator( currentProject );
attEval.setCurrentProject( currentProject );
currentProject.setObject( "DefaultAttributeEvaluator", attEval );
}
XMethodReference methodRef = attEval.getMethodReference( container, className + "." + methodName );
return methodRef;
}
else if ( className.startsWith( "Script" )) {
XMethodReference methodRef = null;
try {
XAttributeEvaluator attEval = (XAttributeEvaluator)currentProject.getObject( "ScriptAttributeEvaluator" );
if ( attEval == null ) {
attEval = (XAttributeEvaluator)XEventHandler.class.forName( "net.xoetrope.optional.scripts.ScriptAttributeEvaluator" ).newInstance();
attEval.setCurrentProject( currentProject );
currentProject.setObject( "ScriptAttributeEvaluator", attEval );
}
methodRef = attEval.getMethodReference( methodName );
}
catch ( Throwable t )
{
}
return methodRef;
}
else {
Method method = null;
if ( clazz == null )
clazz = Class.forName( className.trim());
if ( methodName.endsWith( "}") )
methodName = methodName.substring( 0, methodName.length() - 1 );
if ( methodName.endsWith( "()") )
methodName = methodName.substring( 0, methodName.length() - 2 );
int pos;
if (( pos = methodName.indexOf( "(") ) > 0 ) {
String argValues = methodName.substring( pos + 1, methodName.indexOf( ')' ));
int numArgs = 1 + XuiUtilities.count( argValues, ',' );
Object[] args = new Object[ numArgs ];
Class[] params = new Class[ numArgs ];
XuiUtilities.getArguments( argValues, params, args, ',' );
methodName = methodName.substring( 0, pos );
method = clazz.getMethod( methodName, params );
return new XMethodReference( clazz, container, method, args );
}
else
method = clazz.getMethod( methodName, ( Class[] )null );
return new XMethodReference( clazz, container, method, null );
}
}
//----------------------------------------------------------------------------
/**
* Adds an event handler.
* @param xpage The page that contains the response methods
* @param targetComp the component to which the event handler is added
* @param typeStr the type of handler
* @param methodName the name of the response method
*/
public void addHandler( PageSupport xpage, Object targetComp, String typeStr, String methodName )
{
checkRegistration();
try {
if ( "Action".equals( typeStr )) {
ReflectionHelper.setViaReflection( "setActionCommand", targetComp, methodName );
return;
}
XEventRegistration er = (XEventRegistration)registrations.get( typeStr );
if ( er != null ) {
if ( typeStr.indexOf( '.' ) > 0 ) {
try {
XEventAdapter xea = (XEventAdapter)Class.forName( er.interfaceName.trim()).newInstance();
xea.setEventHandler( this );
addHandler( targetComp, methodName, xea.getAddMethodName(), xea.getListenerInterfaceName(), xea.getEventMask(), xea );
return;
}
catch ( Exception ex ) {
ex.printStackTrace();
}
}
String adder = "add" + er.interfaceName.substring( er.interfaceName.lastIndexOf( '.' ) + 1 );
addHandler( targetComp, methodName, adder, er.interfaceName, er.mask, this );
return;
}
//
// String adderMethod;
// String ifaceName;
// long mask;
// String types[] = { "MouseHandler", "MouseMotionHandler", "ActionHandler", "FocusHandler", "ItemHandler", "KeyHandler", "TextHandler", "MenuHandler" };
// String iface[] = { "java.awt.event.MouseListener", "java.awt.event.MouseMotionListener", "java.awt.event.ActionListener", "java.awt.event.FocusListener",
// "java.awt.event.ItemListener", "java.awt.event.KeyListener", "java.awt.event.TextListener", "java.awt.event.ActionListener" };
// long masks[] = { AWTEvent.MOUSE_EVENT_MASK, AWTEvent.MOUSE_MOTION_EVENT_MASK, AWTEvent.ACTION_EVENT_MASK, AWTEvent.FOCUS_EVENT_MASK,
// AWTEvent.ITEM_EVENT_MASK, AWTEvent.KEY_EVENT_MASK, AWTEvent.TEXT_EVENT_MASK, AWTEvent.ACTION_EVENT_MASK };
// for ( int i = 0; i < types.length; i++ ) {
// if ( typeStr.equals( types[ i ] )) {
// String adder = "add" + iface[ i ].substring( iface[ i ].lastIndexOf( '.' ) + 1 );
// addHandler( targetComp, methodName, adder, iface[ i ], masks[ i ], this );
// return;
// }
// }
//
/**
* @todo handle this in a more generic way
*/
// if ( targetComp.getClass().getName().indexOf( "Button" ) > -1 )
// WidgetAdapter.getInstance().setCursor( targetComp, XPageHelper.hand );
if ( typeStr.indexOf( '.' ) > 0 ) {
try {
XEventAdapter xea = (XEventAdapter)Class.forName( typeStr.trim()).newInstance();
xea.setEventHandler( this );
addHandler( targetComp, methodName, xea.getAddMethodName(), xea.getListenerInterfaceName(), xea.getEventMask(), xea );
}
catch ( Exception ex ) {
ex.printStackTrace();
}
}
else
((XListenerHelper)targetComp).addHandler( xpage, typeStr, methodName );
}
catch ( NoSuchMethodException ex ) {
if ( BuildProperties.DEBUG )
DebugLogger.logError( "BUILDER", "Unable to add the event handler method: " + methodName );
}
}
/**
* Add a configuration file.
* If the files have already been loaded then the new file will be loaded
* @param key the name by which the configuration file is referenced
* @param resource the name/path of the configuration file or the URL for the file
* @param overwrite true to overwrite and existing entry matching the specified key
*/
public static void addConfigFile( String key, Object resource, boolean overwrite )
{
if ( resource == null )
return;
if ( configFiles == null )
configFiles = new Hashtable();
Object resourceObj = configFiles.get( key );
// If the same file name is already used then ignore it.
if (( resourceObj != null ) && resource.equals( resourceObj ))
return;
changeCounter++;
if (( resourceObj != null ) || overwrite )
configFiles.remove( key );
configFiles.put( key, resource );
}
/**
* Signal that the configuration has been updated.
*/
public void updateConfig()
{
changeCounter++;
}
/**
* Read the component registry. The format is described in the components.xsd
* schema.
*/
protected void read()
{
registrations.clear();
Enumeration enumeration = configFiles.keys();
while ( enumeration.hasMoreElements() ) {
String key = ( String ) enumeration.nextElement();
if ( !key.equals( "Project" ) )
doRead( key, configFiles.get( key ) );
}
doRead( "Project", configFiles.get( "Project" ));
}
/**
* Read the component registry. The format is described in the components.xsd
* schema. The config file is also registered.
* @param configFile the name of the configuration file
* @param key the name by which the configuration file is referenced
*/
protected void read( String key, String configFile )
{
addConfigFile( key, configFile, true );
doRead( key, configFile );
}
/**
* Read the component registry. The format is described in the components.xsd
* schema.
* @param configFile the name of the configuration file
* @param key the name by which the configuration file is referenced
*/
protected void doRead( String key, Object configFile )
{
if ( configFile == null )
return;
else if ( configFile instanceof URL )
doRead( key, (URL)configFile );
else
doRead( key, (String)configFile );
}
/**
* Read the component registry. The format is described in the components.xsd
* schema.
* @param configFile the name of the configuration file
* @param key the name by which the configuration file is referenced
*/
protected void doRead( String key, String configFile )
{
if ( BuildProperties.DEBUG )
DebugLogger.trace( "XRegisteredDataBindingFactory reading config file: " + configFile );
try {
String fileName = configFile;
if ( fileName.indexOf( ".xml" ) < 0 )
fileName += ".xml";
Reader r = currentProject.getBufferedReader( fileName, null );
if ( r != null )
read( key, r );
}
catch ( Exception ex ) {
ex.printStackTrace();
}
}
/**
* Read the component registry. The format is described in the components.xsd
* schema.
* @param configFileURL the URL of the configuration file
* @param key the name by which the configuration file is referenced
*/
protected void doRead( String key, URL configFileURL )
{
if ( BuildProperties.DEBUG )
DebugLogger.trace( "XEventHandler reading config file: " + configFileURL.toString() );
try {
// String file = configFileURL.getFile();
Reader r = new BufferedReader( new InputStreamReader( configFileURL.openStream() ));
if ( r != null )
read( key, r );
}
catch ( Exception ex ) {
ex.printStackTrace();
}
}
/**
* Read the component registry. The format is described in the components.xsd
* schema.
* @param key the name by which the configuration file is referenced
* @param reader the reader from which to read the file
*/
public void read( String key, Reader reader )
{
try {
XmlElement regRoot = XmlSource.read( reader );
Vector children = regRoot.getChildren();
int numChildren = children.size();
for ( int i = 0; i < numChildren; i++ ) {
XmlElement ele = (XmlElement)children.elementAt( i );
String name = ele.getAttribute( "name" );
XEventRegistration er = new XEventRegistration();
er.interfaceName = ele.getAttribute( "adapter" );
if (( er.interfaceName == null ) || ( er.interfaceName.length() == 0 )) {
er.interfaceName = ele.getAttribute( "interface" );
er.mask = Long.parseLong( ele.getAttribute( "mask" ));
}
registrations.put( name, er );
}
}
catch ( Exception ex ) {
if ( BuildProperties.DEBUG )
DebugLogger.logError( "Unable to setup the validation registry" );
}
}
/**
* Loads XmlElements from the file and puts the element into the validations
* Hashtable with the name of the validation as the key.
* @param read The Reader object from which the validations will be loaded
*/
/**
* Check that all the registered components are loaded
*/
public void checkRegistration()
{
if ( localChangeCounter != changeCounter ) {
read();
localChangeCounter = changeCounter;
}
}
class XEventRegistration
{
public String interfaceName;
long mask;
}
}