Thursday 21 February 2008

How to test for a methods implementation

I had a little problem and could not find any reference to a way of doing this, I needed to check before hand if a method was implemented in a given class.

After a little bit of searching I came to the sysDictClass which implements a method that enables you to call a method of a class.

This Method is called InvokeObjectMethod it accepts a classid and a method name as a string parameter and invokes the method, if the method does not exist it will return an error.

Here is the complete Method code

public static anytype invokeObjectMethod(Object _object, identifiername _methodName, boolean _tryBaseClass = false)

{
DictClass dictClass = new DictClass(classidget(_object));
DictClass dictClassBase;
DictMethod dictMethod;
int i;
;
for (i=1; i<=dictClass.objectMethodCnt(); i++)
{
if (dictClass.objectMethod(i) == _methodName)
{
dictMethod = dictClass.objectMethodObject(i);
if (dictMethod.parameterCnt() == 0)
{
// invokeObjectMethod is listed as a dangerous API. Just suppress BP error;
// CAS is implemented by DictClass::callObject.
// BP deviation documented

return dictClass.callObject(_methodName, _object);
}
throw error(strfmt("@SYS87800", _methodName));
}
}
if (_tryBaseClass && dictClass.extend())
{
dictClassBase = new DictClass(dictClass.extend());
// BP deviation documented

return SysDictClass::invokeObjectMethod(dictClassBase.makeObject(), _methodName, _tryBaseClass);
}
throw error(strfmt("@SYS60360", _methodName));

}


As you can see the code has pretty much the functionality required to do the job, it cycles through the methods on a given class and tests for the existence of the wanted method by comparing the names.


So the above requires little change to create the below code:

public static boolean xxxObjectMethodExists(Object _object, identifiername _methodName, boolean _tryBaseClass = false)

{
DictClass dictClass = new DictClass(classidget(_object));
DictClass dictClassBase;
DictMethod dictMethod;
int i;
;
for (i=1; i<=dictClass.objectMethodCnt(); i++) { if (dictClass.objectMethod(i) == _methodName) { return true;

}
}
if (_tryBaseClass && dictClass.extend())
{
dictClassBase = new DictClass(dictClass.extend()); // BP deviation documented
return SysDictClass::xxxObjectMethodexists(dictClassBase.makeObject(), _methodName, _tryBaseClass);
}

return false;
}

I have in the above setup indentations etc but they are not working but the code should work if you just copy and paste it in.

Why did I need the above well I am working on a replacement of the Batch processing in Ax as I have too many operational problems with the Batch processing and I have decided it is time to create a Batch processing framework that can be called from the OS through COM and that can be used to execute any class in the system.

So I needed to know whether a class implemented a dialogmake method in order to know whether I can call one. I want to be able to execute also runbase classes not only runbasebatch classes :-).

But if you have another need feel free, plus if you have a better way also feel free to say so

Take care
Sven

No comments: