Are BPMN sequenceFlow allowed to reference specific activities within another process/subprocess? - bpmn

I am modeling a complex process using BPMN 2.0
I have split the process into multiple global processes which can reference one another through call activity.
However, in one or two special cases, I would like to actually call directly into the middle of one of the other processes. I do not want to have to create an entirely duplicate [sub]process with just the first couple nodes missing and would also prefer not to split those couple nodes into their own little process.
I don't think common BPMN 2.0 tools support this, but is it explicitly disallowed by the spec? For instance, I read through http://www.omg.org/spec/BPMN/2.0.2/PDF and I don't see anywhere that it claims that a sequenceFlow's targetRef must be within the same FlowElementsContainer. Maybe it is just implied?

The correct way to do this would be to create several "none" start events in the global process and then reference the correct one via the targetRef attribute of a sequence flow incoming to the call activity. The spec says on p. 239:
"If the Process is used as a global Process (a callable Process that
can be invoked from Call Activities of other Processes) and there are
multiple None Start Events, then when flow is transferred from the
parent Process to the global Process, only one of the global Process’s
Start Events will be triggered. The targetRef attribute of a Sequence
Flow incoming to the Call Activity object can be extended to identify
the appropriate Start Event."

Related

Anylogic Nested Agent RandomNumberGenerator

I have an agent that is nested in another agent. This nested agent has a function that calls the annylogic probability distribution functions(pdfs) such as gamma(), lognormal(), etc. However I keep getting a nullPointerException if I call these pdfs inside the nested agent. I am realising this is because the nested agent cannot access the default randomNumberGenerator. Is there a way I can access the defaultRandomNumberGenerator within the nested agent as well or is the only solution to create a new generator for each nested agent?
The error is because your agent is outside the model hierarchy of agents.
This is not good practice; there should very rarely be a need to have 'floating' agents outside the model hierarchy; they can always be inside an agent population somewhere.
In the rare cases that there are strong design reasons to do so (or if you use plain Java classes and thus have Java objects which by definition are not Agents and are therefore outside the agent hierarchy), just give them a parameter (field in the case of a Java class) that points to some agent that is in the model hierarchy (typically their 'generator'), and then you can call all 'required-to-be-in-model-hierarchy' functions via that parameter. (That is, you are delegating all such calls to an agent instance which can call them.)
e.g., the nested agent type (let's say Thing) has parameter agentRef of type Agent set by whoever creates it; for example
Thing t = new Thing(this);
Then, within Thing, you use code such as agentRef.normal(1,10).
Only agents that are connected to the engine in some way have access to the random number generator. And if your experiment is set to run main - like the example below - then all agents that want to use the random number generator must be connected to main in some way
So if you do this for example it wont work, and you get an NPE (Null Pointer Exception)
If you do this it will
Best option is to just create your own random number generator
lognormal(0.1, 0.1, 5, new Random(0));
(Just put the random number generator somewhere so that you can use it again and again, else you will get the same number every time since it is the same (new) random object used to get the number)
This design is way better - see example here
Why do two flowcharts set up exactly the same end with different results every time the simulation is run even when I use a fixed seed?

Do I have to check the InvokeRequired and use the Invoke function with every control I want to update?

I'm writing a scheduler. It has a single form frmMain, which shows jobs that are currently running, and a history of job steps that have run. It has an object of class Scheduler that manages running new jobs. Scheduler keeps a collection class, List which contains objects of class RunningJob. RunningJob executes each step in turn through a series of sub-classes.
When a job is started, the Scheduler creates a new BackgroundWorker with the DoWork, ProgressChanged and RunWorkerCompleted methods setup with handlers that point back into the instance of RunningJob.
Each time a job/step starts/ends, one of these handers in RunningJob raises an appropriate event into Scheduler and Scheduler raises an appropriate event into frmMain. i.e.:
frmMain (1 instance) <---- Scheduler (1 instance) <---- RunningJob.WorkerProgressChanged (many instances)
The RunningJob executes correctly, but the reporting going up to the interface is not working correctly. Also any logging to files I do is suspect (I'm using a single function: LogInfo to do this). I have a number of questions:
When I use InvokeRequired() and Invoke() within frmMain, do I have to do this with every single control I want to update (there are several). Can I just check InvokeRequired() on one control and use Invoke on all of them based on that result.
Why bother checking InvokeRequired() at all and just use Invoke() every single time? It will make for simpler code.
There is only one instance of Scheduler and I am raising events to get execution back into it from each Job. I think this is part of the problem. How is multithreading handled doing this? Is there some sort of InvokeRequired/Invoke check I can do on the events before raising them? Can I raise events at all in this situation? I like events, rather than calling methods on the owner class, because it improves encapsulation. What is best practice here?
In general, if I'm calling a piece of code from many different threads, not necessarily to update a form, but just to perform some function (e.g. add a line of text to a file for logging purposes), how do I block one thread until the other has completed?

Check original language of repository objects at creation?

In our company, repository objects must be created with original language EN.
Is there a way to check the logon language in case of creating a new object in the ABAP repository?
Desired behaviour:
SE80 - Create program/class/data element/table/....
==> user exit/badi checks the logon language. When it is not 'EN', the creation will be refused.
regards,
Umar Abdullah
I know there is a exit for this but I haven't remember exact name. You can use general purpose for finding exit. Go to SE24 and open CL_EXITHANDLER class, find GET_INSTANCE method and add break point. Then start creating item, it will pause on debugger multiple times, try to find suitable one.
As #mkysoft suggested, you may implement a check in the BAdI CTS_REQUEST_CHECK, method CHECK_BEFORE_ADD_OBJECTS, which is invoked when the object is about to be attached to a transport request. Raise the exception CANCEL to make the attachment fail (and so the object is not created too).
EDIT: sorry, ignore my answer, "this method is NOT released for Customer usage" as said in note 2150125 - Method CHECK_BEFORE_ADD_OBJECTS not triggered
DISCLAIMER: THE METHOD DESCRIBED HERE IS ABSOLUTELY NOT RECOMMENDED.
As correctly pointed out by the other members there is no standard and customer-exposed method to achieve your requirement, but if you absolutely must enable this check during creation you can use the below method. As well as the previously offered to you, it also involves modification of SAP standard.
There is a system BAdi CTS_TADIR_SUBSCREEN that is located inside enhancement point CTS_ES_TADIR_POPUP. They are SAP internal and not released for customer usage, so do this at your own risk.
Implementation procedure:
Step 0. First thing you need to change is a SAP internal usage flag, for which you need Object Access key which can be obtained from SAP or from SAP partner that made the implementation in your org. In virgin state this BAdi throws the error if you try to implement it
So hereinafter we assume that you already ticked off this checkbox in BAdi settings
Step 1.
In order to implement the BAdi one need to implement enhancement spot prior to that. This is the most complicated part, because despite we disabled internality flag the SAP-namespaced enhancements must be stored only in SAP-namespaced objects. By SAP namespace I mean non-Z, non-Y and non-T (Test). This means to implement this enhancement, besides modifying the enhancement definition, one need to create, for example, CTS_ES_TADIR named enh.impl., and save it to non-Z package, which you also need to create. Your enhancement implementations selector should look somehow like this
On the above screen only the second will work, all the rest Z will not.
Every non-Z object need Object Access Key, remember? Too bad. But just to show the proof-of-concept, I will proceed.
Step 2. After you created the enh. implementation in SAP-namespace it will propose you to create the BAdi implementation. The same principle applies here: only SAP-namespaced container for SAP-namespaced objects, hence CTS_TADIR_SUBSCREEN should have implementing class for example CL_TADIR_SUBSCREEN. During the creation of enhancement you will see many warnings
but finally you should have something like this, where all system-named objects are created and the enhancement/BAdi is activated.
Step 3. In order to get the BAdi working we need to enable this subscreen processing
during the playing with enhancement I found out that BAdi class is not being triggered standalone, without screen events not enhanced, so to make it work you need to touch a screen enhancement for screen 100
If you do not wanna modify screen elements logic, just put the dummy enhancement in SHOW_TADIR dialog module in the end of the include LSTRDO18
PROCESS BEFORE OUTPUT.
MODULE SHOW_TADIR. "<-- create the dummy enhancement here
CALL SUBSCREEN subs_info INCLUDING gv_badi_prog gv_badi_dynnr.
for example declaration statement like I did
Step 4. Activate your created BAdi class and put the necessary logic there. I wasn't able to trigger method GET_DATA_FROM_SCREEN, but PUT_DATA_TO_SCREEN worked fine
If we put this simple processing for your requirement
METHOD cts_if_tadir_subscreen~get_data_from_screen.
IF object_data-l_mstlang <> 'E'.
MESSAGE 'Objects in non-English languages are not allowed!' TYPE 'A'.
ENDIF.
ENDMETHOD.
it will not allow creating objects in languages other than English.
The check in method get_data_from_screen is being done before showing the screen so language is determined from system logon settings. If to play more with this BAdi, I suppose the method GET_DATA_FROM_SCREEN can also be enabled, which will make it possible to check user input, i.e. the case when the user gonna change the default language.

The <invoke>-element of Mule 3, what does it do?

I have previously only used Mule 2.2.1, but i'm now reading up on Mule 3.4/3.5.
One major change between theses versions is the introduction of flows.
In the documentation of the Mule configuration i found this:
A flow begins with an inbound endpoint from which messages are read and continues with a list of message processors
However, in this post i came across the invoke-element. It appears that a flow can also begin with an invoke-element.
I was searching the Mule documentation for documentation of the invoke element, but was not able to find it. Can someone help explaining the semantics of the invoke-element, or point to any relevant documentation?
The "invoke" element is a message processor and not a message source.
The quote "A flow begins with an inbound endpoint from which messages are read and continues with a list of message processors" is not quite true as flows such as sub-flows or private flows that are referenced via other flows using flow-refs do not need an inbound-endpoint and can just have a list of message processors.
So it cannot be used to trigger a flow. However the example above seems to be a private flow which would be referenced from another flow via flow-ref so hence why it starts with a message processor. More eon private and sub-flows here: http://www.mulesoft.org/documentation/display/current/Using+Flows+for+Service+Orchestration
Back to the invoke message processor. THere is lacking documentation around this, but simply put, it calls the specified method for the given object using the given arguments.
From the javadoc: invokes a specified method of an object. An array of argument expressions can be provided to map the message to the method arguments. The method used is determined by the method name along with the number of argument expressions provided. The results of the expression evaluations will automatically be transformed where possible to the method argument type. Multiple methods with the same name and same number of arguments are not supported currently - http://www.mulesoft.org/docs/site/current3/apidocs/org/mule/processor/InvokerMessageProcessor.html

Notifications in wxWidgets?

I'm working on a small application using C++/wxWidgets, where several parts of the GUI need to be updated based on e.g. received UDP datagrams. More specifically, a secondary thread tries to keep a list of available "clients" in the network (which may come and go away) and e.g. corresponding comboboxes in the UI need to be updated to reflect the changes.
The documentation mentions that for this kind of thing EVT_UPDATE_UI would be a good choice. As far as I can understand from the sparse documentation, this event is sent automatically by the system and provides some support for assisted UI change.
However, I'd feel more comfortable using a more direct approach, i.e. where e.g. a window object could register/subscribe to receive notifications (either events or callbacks) upon particular events and another part of the code is sending out these notifications when required. I could do this in C++ using my own code, however I guess if wxWidgets already supports something like that, I should make use of it. However I haven't found anything in that regards.
So, the question is: does wxWidgets support this kind of notification system (or similar alternatives) or would I be best served coding my own?
AFAIK there is nothing directly usable in wxWidgets, but doing it on your own seems easy.
What I would do:
Create a wxEvtHandler-descendent class to hold the list of available "clients" in the network. Let this class have a wxCriticalSection, and use a wxCriticalSectionLocker for that in all methods that add or delete "clients".
Create a worker thread class by inheriting wxThread to handle your UDP datagrams, using blocking calls. The thread should directly call methods of the client list object whenever a client has to be added or removed. In these methods update the list of clients, and ::wxPostEvent() an event to itself (this will execute the whole notification calls in the main GUI thread).
Handle the event in the client list class, and notify all listeners that the list of clients has changed. The observer pattern seems to me a good fit. You could either call a method of all registered listeners directly, or send a wxCommandEvent to them.
Have you tried calling Update() on the widget(s) that change? Once you update the contents of the combo box, call Update(), and the contents should update.