jpdlReader.addError("invalid parent lock mode '" + lock + "'");
}
}
public void execute(ExecutionContext executionContext) {
Token token = executionContext.getToken();
boolean isAbleToReactivateParent = token.isAbleToReactivateParent();
if (!token.hasEnded()) token.end(false);
// if this token is not able to reactivate the parent,
// we don't need to check anything
if (isAbleToReactivateParent) {
// the token arrived in the join and can only reactivate the parent once
token.setAbleToReactivateParent(false);
Token parentToken = token.getParent();
if (parentToken != null) {
JbpmContext jbpmContext = executionContext.getJbpmContext();
Session session = jbpmContext != null ? jbpmContext.getSession() : null;
if (session != null) {
// obtain update lock by default (LockMode.UPGRADE)
LockMode lockMode = parentLockMode != null ? LockMode.parse(parentLockMode)
: LockMode.UPGRADE;
log.debug("acquiring " + lockMode + " lock on " + parentToken);
// lock updates as appropriate, no need to flush here
session.lock(parentToken, lockMode);
}
boolean reactivateParent = true;
// if this is a discriminator
if (isDiscriminator) {
// reactivate the parent when the first token arrives in the join.
// this must be the first token arriving, otherwise isAbleToReactivateParent()
// should have been false above.
reactivateParent = true;
}
// if a fixed set of tokenNames is specified at design time...
else if (tokenNames != null) {
// check reactivation on the basis of those tokenNames
reactivateParent = mustParentBeReactivated(parentToken, tokenNames.iterator());
}
// if a script is specified
else if (script != null) {
// check if the script returns a collection or a boolean
Object result = null;
try {
result = script.eval(token);
}
catch (Exception e) {
this.raiseException(e, executionContext);
}
// if the result is a collection
if (result instanceof Collection) {
// it must be a collection of tokenNames
Collection<String> runtimeTokenNames = CollectionUtil.checkCollection(
(Collection<?>) result, String.class);
reactivateParent = mustParentBeReactivated(parentToken, runtimeTokenNames.iterator());
}
// if it's a boolean...
else if (result instanceof Boolean) {
// the boolean specifies if the parent needs to be reactivated
reactivateParent = (Boolean) result;
}
}
// if a nOutOfM is specified
else if (nOutOfM != -1) {
int n = 0;
// check how many tokens already arrived in the join
for (Token concurrentToken : parentToken.getChildren().values()) {
if (equals(concurrentToken.getNode())) n++;
}
if (n < nOutOfM) reactivateParent = false;
}
// if no configuration is specified..
else {
// the default behaviour is to check all concurrent tokens and reactivate
// the parent if the last token arrives in the join
reactivateParent = mustParentBeReactivated(parentToken, parentToken.getChildren()
.keySet()
.iterator());
}
// if the parent token needs to be reactivated from this join node
if (reactivateParent) {
// write to all child tokens that the parent is already reactivated
for (Token child : parentToken.getChildren().values()) {
child.setAbleToReactivateParent(false);
}
// write to all child tokens that the parent is already reactivated
ExecutionContext parentContext = new ExecutionContext(parentToken);
leave(parentContext);