TBayen/How are processes called

From iDempiere en

This text is a brainstorming I did while thinking about IDEMPIERE-1718 (a redo of my efforts at IDEMPIERE-270). I did this to understand what really happens when calling processes and reports and to find the right place to change the code.Some older notes are at http://wiki.frei-bier.org/wiki/ListReports User:TBayen

understanding how processes are called

I examined the source and collected some informations. There are different code paths for swing and zk and for toolbar buttons, field buttons, reports and processes. I examined the source code want to collect some informations about that (to learn about it and) to find the right place to take the WindowNo and save it.

Every Field Buttons Process (in Swing) is called through the Method APanel.actionButtonCleanUp(VButton vButton). This method is the last to have access to the GridTab object. At their very end is (still in Swing) a call to new ProcessModalDialog(...). (This widget knows about the WindowNo but not the Window Object or the GridTab.) This Widget has an actionPerformed(...) method which calls the static method ProcessCtl.process(...). At the end this method calls the constructor new ProcessCtl(...). This is the first non-swing class and I hope this is the right place to save the WindowNo.

The Toolbar Buttons for Report, Print and Print Preview can also start a Process. They are called through one of the methods APanel.cmd_*. Thecmd_print() (also for preview) method leads to a call to ClientProcessCtl.process(...) which at the end also creates a new ProcessCtl(...) like the Field Button's code path. The cmd_report() method creates an AReport object (responsible for searching all possible PrintFormats etc). Its launchreport() method also calls ClientProcessCtl.process(...) to do the real work.

In the parent class AbstractProcessCtl the real work is done in the AbstractProcessCtl.run() method. This method seems the right way to catch all codepaths and thus all kinds of processes and reports.

Where is the best place to save the WindowNo

In AbstractProcessCtl.run() is some code to initialize the ProcessInfo object from the settings in AD_Process. These objects are created earlier by the calling methods (in the swing code) but most of their values are set here. I think there is the right place to add another value to save the WindowNo.

How to save the WindowNo

I thought a while about saving this as a parameter. The best way for this is to create a new entry in the AD_PInstance_Para table. But this is not a parameter the user gives. Does it belong there? Is it worth to create an mostly unused database record for every process call? It could also be saved as an own data field in the ProcessInfo with getWindowNo() and setWindowNo() methods.

What is the purpose of the ProcessInfo object

It is a non-persistent value object to keep some information about a process instance. Most of its values are set in the *ProcessCtl classes (exactly in AbstractProcessCtl) in the run() method. There only values from AD_Process are set (no instance values). The getParameter() value is set in different ways. Most processes run through ProcessInfoUtil.setParameterFromDB() which loads all entries from AD_PInstance_Para.

chat transscript

<tbayen> I did IDEMPIERE-1718. I want to use the calling window's WindowNo in a Report. (And when I am at it I want to make it accessable for every process.) I believe this helps much to use the Context values of the window.
<tbayen> One way could be to create a new property in ProcessInfo to save it.
<tbayen> Another could be to allow @WindowNo@ in parameters and exchange this variable in the ProcessParameterPanel.
<tbayen> wdyt?
<tbayen> Or is it better not to have the WindowNo at hand but take all values I need from the Context when defining parameters?
<CarlosRuiz> I think there is value added as you pointed
<CarlosRuiz> knowing the caller WindowNo when running a report/process
<tbayen> :-) The master says I am not totally stupid. :-) Fine!
<CarlosRuiz> wondering the consequence on your report if the caller window is closed and then you refresh the report
<CarlosRuiz> must be that the context disappeared - doesn't sound like a big deal - but maybe to take into account when writing processes
<tbayen> That was what I am afraid of. That there is a reason to make every value I use in my report persistent to not chain it to the gui.
<CarlosRuiz> passing that parameter to jasper sounds easy
<CarlosRuiz> would be just to add one more parameter to ReportStarter?
<tbayen> A normal process when using SrvProcess always has a "prepare()" method. I understand that this method is called at the very moment of the process start and has to collect the environment information it needs.
<tbayen> I would like to use _TabInfo_SQL. But later I might add some more interesting values to the context.
<CarlosRuiz> I think that must be half done
<CarlosRuiz> WProcessCtl already has reference to windowno
<tbayen> I could use "@_TabInfo_SQL@" as default in a not-editable parameter of every of my Jasper Processes. I am not sure what is the better way.
<CarlosRuiz> passing the windowno and even the tabno sounds more powerful
<CarlosRuiz> you can have access to all fields and variables in the context
<tbayen> yes.
<tbayen> This will not work if you start the process as a background process in the server. But that can be configured when I remember right.
<CarlosRuiz> yep - probably the context won't be passed
<tbayen> Do you agree that I try adding a property to ProcessInfo?
<CarlosRuiz> I don't remember what was the ticket where I needed something similar - it was a security ticket on reports
<CarlosRuiz> where you can go to a window and report all the records - not filtered by the window restrictions
<CarlosRuiz> I think I needed to pass windowno ahead in such ticket
<tbayen> I think sending it to the process with a parameter (parsing something like @WindowNo@) does not make sense because making it persistent will lead to wrong values when you reuse the pinstance_param somewhere later. Better using ProcessInfo.getWindowNo() and having no value at all in the case of a server process or so.