SourceForge has been redesigned. Learn more.
Close

#9 Fix to This For Compiled Commands

open
nobody
None
5
2014-08-21
2005-09-06
Anonymous
No

The following is a fix to the This class so that it
corresponds to the way that the Name class will first
attempt to getMethod() from the namespace and then try
to do a getCommand() on the namespace. The reason for
this patch is that when a namespace object had imported
commands from a location where some commands are
compiled java code commands, the commands could not be
accessed when not inside that particular namespace.

e.g.

aNamespace.someCompiledJavaCodeCommand("foo");

This case would not work without the following patch:

/*
invokeMethod() here is generally used by outside code
to callback
into the bsh interpreter. e.g. when we are acting as
an interface
for a scripted listener, etc. In this case there is
no real call stack
so we make a default one starting with the special
JAVACODE namespace
and our namespace as the next.
*/
public Object invokeMethod(
String methodName, Object [] args,
Interpreter interpreter, CallStack callstack,
SimpleNode callerInfo,
boolean declaredOnly )
throws EvalError
{
/*
Wrap nulls.
This is a bit of a cludge to address a deficiency in
the class
generator whereby it does not wrap nulls on method
delegate. See
Class Generator.java. If we fix that then we can
remove this.
(just have to generate the code there.)
*/
if ( args != null )
{
Object [] oa = new Object [args.length];
for(int i=0; i<args.length; i++)
oa[i] = ( args[i] == null ? Primitive.NULL : args[i] );
args = oa;
}

if ( interpreter == null )
interpreter = declaringInterpreter;
if ( callstack == null )
callstack = new CallStack( namespace );
if ( callerInfo == null )
callerInfo = SimpleNode.JAVACODE;

// Find the bsh method
Class [] types = Types.getTypes( args );
BshMethod bshMethod = null;
try {
bshMethod = namespace.getMethod( methodName, types,
declaredOnly );
} catch ( UtilEvalError e ) {
// leave null
}

if ( bshMethod != null )
return bshMethod.invoke( args, interpreter,
callstack, callerInfo );

/*
No scripted method of that name.
Implement the required part of the Object protocol:
public int hashCode();
public boolean equals(java.lang.Object);
public java.lang.String toString();
if these were not handled by scripted methods we
must provide
a default impl.
*/
// a default toString() that shows the interfaces we
implement
if ( methodName.equals("toString" ) )
return toString();

// a default hashCode()
if ( methodName.equals("hashCode" ) )
return new Integer(this.hashCode());

// a default equals() testing for equality with the
This reference
if ( methodName.equals("equals" ) ) {
Object obj = args[0];
return new Boolean( this == obj );
}

// Look for a default invoke() handler method in the
namespace
// Note: this code duplicates that in NameSpace
getCommand()
// is that ok?
try {
bshMethod = namespace.getMethod(
"invoke", new Class [] { null, null } );
} catch ( UtilEvalError e ) { /*leave null*/ }

// Call script "invoke( String methodName, Object []
args );
if ( bshMethod != null )
return bshMethod.invoke( new Object [] { methodName,
args },
interpreter, callstack, callerInfo );
// We will do one last desperate attempt. We will see
if the method being
// called on us is for a compiled command
else {
Class [] argTypes = Types.getTypes(args);
Object commandObject = null;
try {
commandObject =
namespace.getCommand(methodName,argTypes,interpreter);
} catch (UtilEvalError e) {
// Do nothing, just drop out and allow the method
to exit normally.
}

if (commandObject != null && commandObject
instanceof Class) {
try {
return
Reflect.invokeCompiledCommand((Class)commandObject,args,interpreter,callstack);
} catch (UtilEvalError e) {
// Do nothing, just drop out and let the method
exit normally.
}
}
}

throw new EvalError("Method " +
StringUtil.methodString( methodName, types ) +
" not found in bsh scripted object: "+
namespace.getName(),
callerInfo, callstack );
}

Discussion


Log in to post a comment.