Hello. So I want to create a new Element on the language. Ill explain
what I want, what I've done and what is my question.
Hope that this post, somehow, helps other people.
So, as I said, I want to create an extension Element called "When". It
appears in the language like this:
<bpel:process ...>
...
<bpel:variables>
...
</bpel:variables>
<ns:when name="test">
<bpel:condition ...> $var > 40 </bpel:condition>
<bpel:empty name="emptyTest"... />
</ns:when>
<bpel:sequence> ---> The Activity of this process
.....
</bpel:sequence>
</bpel:process>
It meaning is quite obvious: When the condition is true, run the
activity. I've inspired my code by what I understand ODE does with the
BPEL "if/switch" and "faultHandlers/catch". The if because the when
condition and the Handler because my 'when' its not an activity, its a
handler kind like.
*So, I've changed the ode-bpel-compiler project this way:*
* In the class org.apache.ode.bpel.compiler.bom.Bpel20QNames I add the
'when' QName
* Created a When.class that extends BpelObject with methods
getCondition() and getActivity()
* in the class org.apache.ode.bpel.compiler.bom.BpelObjectFactory i've
added a new line that maps the QName with the When.class
* in the class org.apache.ode.bpel.compiler.bom.Scope added the method
public List<When> getWhenDefs() that return getChildren(When.class)
* in the class org.apache.ode.bpel.compiler.BpelCompiler i've changed
the method compileScope. In this method I add this:
...
for (When when : src.getWhenDecls()) {
try {
compile(when);
} catch (CompilationException ce) {
recoveredFromError(when, ce);
}
}
* and to the compiler class I added the private method compile(When
when) :
private void compile(When src) {
// FIXME: keep track of line on eclipse IDE
final OScope oscope = _structureStack.topScope();
//validate
if (src.getCondition() == null){
CompilationMessage cmsg = new CompilationMessage();
cmsg.messageText = "When must have a condition";
cmsg.severity = CompilationMessage.ERROR;
throw new CompilationException(cmsg);
}
if (src.getActivity() == null){
CompilationMessage cmsg = new CompilationMessage();
cmsg.messageText = "When must have an activity";
cmsg.severity = CompilationMessage.ERROR;
throw new CompilationException(cmsg);
}
OWhen when = new OWhen(_oprocess, oscope);
when.activity = compile(src.getActivity());
when.expression = compileExpr(src.getCondition());
oscope.addWhenDef(when);
if (__log.isDebugEnabled())
__log.debug("Compiled when ");
}
So as you can see, I created also an OWhen class and I've changed the
OScope so it haves the methods add/getWhenDef(). If what I think is
correct, this way I can put the <when> on the <process> and in any
<scope> (but lets ignore that for now).
*At this point, i've changed to the project ode-bpel-obj.*
The OWhen.class is simply this:
package org.apache.ode.bpel.o;
public class OWhen extends OScope {
/**
*
*/
private static final long serialVersionUID = 757712690524854494L;
public OExpression expression;
public OWhen(OProcess owner, OScope oscope) {
super(owner, oscope);
}
}
I've extended the OSCope cause I followed the
OCompensationHandler/OFailureHandler/etc. class.
So at this point I think that I've "teached" ODE compiler how to
transform the new element in something to be used in the runtime. A bpel
process that I deploy doesnt give any compilation error.
*Now im in the ode-bpel-runtime project.*
To see if at Runtime my When info is the scope of the process I've
edited the method run() of the class org.apache.ode.bpel.runtime.PROCESS
adding this:
public void run() {
System.out.println("IS THERE ANY WHEN IN THIS PROCESS SCOPE??");
for (Object o : _oprocess.procesScope.getWhenDefinitions()){
System.out.println(o.getClass());
}
...
}
I've invoked the process and it can see my when declaration. I assume
that everthing that I've build is correct so far.
So now I wanted to somehow see when my when is executed. Aiming that,
I've altered the class org.apache.ode.bpel.runtime.Empty and in the
method run() I've put a system.out.println(...) just to see the empty
activity execution. Notice that there is ONLY ONE empty activity in my
process and its in the When. The process sequence is the hello world.
So here starts my problems. I didnt notice before but when I invoke the
process the Empty activity executes without any command of my part or
any programming. It just printed my "Empty usage detector sysout".
Can someone give me some hints how can I achieve my goal? I think that a
good path is making an odelistener that when recieve an
VariableModificationEvent with the destination variable beeing the $var
(declared in the When condition) he unlocks the When and execute the
Empty activity a single-time.
I really hope that this half tutorial on "how to make a new element on
BPEL" helps some one.
Thanks in advance.
Cheers from Portugal