JavaBindCmd.java :  » Natural-Language-Processing » Ellogon » tcl » lang » Java Open Source

Java Open Source » Natural Language Processing » Ellogon 
Ellogon » tcl » lang » JavaBindCmd.java
/*
 * JavaBindCmd.java --
 *
 *  Implements the java::bind command.
 *
 * Copyright (c) 1997 Sun Microsystems, Inc.
 *
 * See the file "license.terms" for information on usage and
 * redistribution of this file, and for a DISCLAIMER OF ALL
 * WARRANTIES.
 *
 * RCS: @(#) $Id: JavaBindCmd.java,v 1.3 1999/05/09 21:44:48 dejong Exp $
 */

package tcl.lang;

import java.lang.reflect.*;
import java.beans.*;
import java.util.*;

/**
 * This class implements the built-in "java::bind" command in Tcl.
 */

class JavaBindCmd implements Command {

// The Bean Event Manager associated with the interp that owns this
// BindCmd instance.

BeanEventMgr eventMgr = null;

// Caches the BeanInfo for each Java class. The
// Introspector.getBeanInfo class in JDK 1.2 returns new instances of
// BeanInfo for each call.  That causes a lot of problems in Jacl,
// which assumes that there is the BeanInfo (and EventSetDescriptor,
// etc) associated with each class is always constant (i.e., always the
// same object).
//
// This cache allows us to always use the same BeanInfo instance for each
// Java class.

private Hashtable beanInfoCache = new Hashtable();


/*
 *----------------------------------------------------------------------
 *
 * cmdProc --
 *
 *  This procedure is invoked as part of the Command interface to
 *  process the "java::bind" Tcl command.  See the user
 *  documentation for details on what it does.
 *
 * Results:
 *  None.
 *
 * Side effects:
 *  See the user documentation.
 *
 *----------------------------------------------------------------------
 */

public void
cmdProc(
    Interp interp,    // Current interpreter.
    TclObject argv[])    // Argument list.
throws 
    TclException     // A standard Tcl exception.
{
    if ((argv.length < 2) || (argv.length > 4)) {
  throw new TclNumArgsException(interp, 1, argv, 
    "javaObj ?eventName? ?command?");
    }

    ReflectObject robj = ReflectObject.getReflectObject(interp, argv[1]);

    if (eventMgr == null) {
  eventMgr = BeanEventMgr.getBeanEventMgr(interp);
    }

    if (argv.length == 2) {
  // Return the list of all events handled by this widget.

  interp.setResult(eventMgr.getHandledEvents(robj));
    } else {
  EventSetDescriptor eventDesc;
  Method method;

  Object arr[] = getEventMethod(interp,
              robj.javaObj, robj.javaClass,
              argv[2].toString());

  eventDesc = (EventSetDescriptor)arr[0];

  if (!eventDesc.getListenerType().isInterface()) {
      throw new TclException(interp, "Cannot handle event listener: " +
        "listererType \"" + eventDesc.getListenerType() +
        "\" is not an interface");
  }

  method = (Method)arr[1];

  if (argv.length == 3) {
      // Return the script for the given event.

      TclObject script = eventMgr.getBinding(interp, robj, eventDesc,
        method);

      if (script != null) {
    interp.setResult(script);
      } else {
    interp.resetResult();
      }
  } else {
      // Set the script for the given event.

      eventMgr.setBinding(interp, robj, eventDesc, method, argv[3]);
  }
    }
}

/*
 *----------------------------------------------------------------------
 *
 * getEventMethod --
 *
 *  Returns the EventSet and event listener method represented by
 *  a string name. The string name must be in one of the following
 *  formats:
 *    + className.listenerMethod
 *    + listenerMethod
 *  The first format will always work. The second and third format
 *  may cause an error if there is an ambiguity.
 *
 * Return value:
 *  If successful, returns an Object array of two elements. arr[0]
 *  is the EventSetDescriptor and arr[1] is the Method, as given
 *  by eventName.
 *  
 * Side effects:
 *  None.
 *
 *----------------------------------------------------------------------
 */

Object[]
getEventMethod(
    Interp interp,    // Current interpreter.
    Object obj,      // The object whose event listener methods
        // are to be queried.
    Class  cls,                 // The class of the event object
    String eventName)    // The string name of the event.
throws
   TclException      // If the method cannot be found, or if
        // eventName is ambiguous.
{
    EventSetDescriptor eventDesc = null;
    Method method = null;
    int dotPos, i;

    search: {
  BeanInfo beanInfo;

  try {
      beanInfo = (BeanInfo) beanInfoCache.get(cls);
      if (beanInfo == null) {
    //System.out.println("Introspecting " + cls);
    beanInfo = Introspector.getBeanInfo(cls);
    beanInfoCache.put(cls, beanInfo);
    
      }
  } catch (IntrospectionException e) {
      break search;
  }
  EventSetDescriptor[] events = beanInfo.getEventSetDescriptors();

  if (events == null) {
      break search;
  }

  dotPos = eventName.lastIndexOf('.');
  if (dotPos == -1) {
      // the event string specifies only the event method. Must
      // ensure that exactly one event interface has this
      // method.

      for (i = 0; i < events.length; i++) {
    Method methods[] = events[i].getListenerType().getMethods();
    for (int j=0; j < methods.length; j++) {
        if (methods[j].getName().equals(eventName)) {
      if (method == null) {
          method = methods[j];
          eventDesc = events[i];
      } else {
          throw new TclException(interp, 
            "ambiguous event \"" + eventName + "\"");
      }
        }
    }
      }
  } else {
      String evtCls = eventName.substring(0, dotPos);
      String evtMethod = eventName.substring(dotPos + 1);

      for (i = 0; i < events.length; i++) {
    Class lsnType = events[i].getListenerType();
                //System.out.println("event index " + i);
                //if (evtCls == null) {System.out.println("null 1");}
                //if (lsnType == null) {System.out.println("null 2");}
                //if ((lsnType != null) && (evtCls == null)) {System.out.println("null 3");}
    if (evtCls.equals(lsnType.getName())) {
        eventDesc = events[i];
        break;
    }
      }

      if (eventDesc == null) {
    break search;
      }

      Method methods[] = eventDesc.getListenerType().getMethods();

      if (methods == null) {
    break search;
      }
      for (int j = 0; j < methods.length; j++) {
    if (methods[j].getName().equals(evtMethod)) {
        method = methods[j];
        break;
    }
      }
  }

  if (method != null) {
      Object arr[] = new Object[2];
      arr[0] = eventDesc;
      arr[1] = method;
      return arr;
  }
    }

    throw new TclException(interp, "unknown event \"" + eventName + "\"");
}

} // end JavaBindCmd

java2s.com  | Contact Us | Privacy Policy
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.