
org.ow2.bonita.parsing.binding.ActivityBinding Maven / Gradle / Ivy
/**
* Copyright (C) 2006 Bull S. A. S.
* Bull, Rue Jean Jaures, B.P.68, 78340, Les Clayes-sous-Bois
* This library is free software; you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Foundation
* version 2.1 of the License.
* This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU Lesser General Public License for more details.
* You should have received a copy of the GNU Lesser General Public License along with this
* program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
* Floor, Boston, MA 02110-1301, USA.
**/
package org.ow2.bonita.parsing.binding;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.ow2.bonita.definition.VariablePerformerAssign;
import org.ow2.bonita.facade.def.element.DeadlineDefinition;
import org.ow2.bonita.facade.def.element.HookDefinition;
import org.ow2.bonita.facade.def.element.MultiInstantiationDefinition;
import org.ow2.bonita.facade.def.element.PerformerAssignDefinition;
import org.ow2.bonita.facade.def.element.SimulationInformationDefinition;
import org.ow2.bonita.facade.def.element.SubFlowDefinition;
import org.ow2.bonita.facade.def.element.TimeEstimationDefinition;
import org.ow2.bonita.facade.def.element.ToolDefinition;
import org.ow2.bonita.facade.def.element.TransitionRestrictionDefinition;
import org.ow2.bonita.facade.def.element.TransitionRestrictionDefinition.JoinType;
import org.ow2.bonita.facade.def.element.TransitionRestrictionDefinition.SplitType;
import org.ow2.bonita.facade.def.element.impl.DeadlineDefinitionImpl;
import org.ow2.bonita.facade.def.element.impl.HookDefinitionImpl;
import org.ow2.bonita.facade.def.element.impl.MultiInstantiationDefinitionImpl;
import org.ow2.bonita.facade.def.element.impl.PerformerAssignDefinitionImpl;
import org.ow2.bonita.facade.def.element.impl.SimulationInformationDefinitionImpl;
import org.ow2.bonita.facade.def.element.impl.SubFlowDefinitionImpl;
import org.ow2.bonita.facade.def.element.impl.TimeEstimationDefinitionImpl;
import org.ow2.bonita.facade.def.element.impl.TransitionRestrictionDefinitionImpl;
import org.ow2.bonita.facade.def.majorElement.ActivityDefinition;
import org.ow2.bonita.facade.def.majorElement.DataFieldDefinition;
import org.ow2.bonita.facade.def.majorElement.impl.ActivityDefinitionImpl;
import org.ow2.bonita.facade.def.majorElement.impl.DataFieldDefinitionImpl;
import org.ow2.bonita.facade.uuid.ActivityDefinitionUUID;
import org.ow2.bonita.facade.uuid.PackageDefinitionUUID;
import org.ow2.bonita.facade.uuid.ProcessDefinitionUUID;
import org.ow2.bonita.pvm.internal.util.XmlUtil;
import org.ow2.bonita.pvm.internal.xml.Parse;
import org.ow2.bonita.pvm.internal.xml.Parser;
import org.ow2.bonita.services.util.ServiceEnvTool;
import org.ow2.bonita.util.Misc;
import org.w3c.dom.Element;
/**
* @author Marc Blachon, Guillaume Porcher, Charles Souillard, Miguel Valdes, Pierre Vigneras
*/
public class ActivityBinding extends MajorElementBinding {
public ActivityBinding() {
super("Activity");
}
private static final Logger LOG = Logger.getLogger(PackageBinding.class.getName());
public Object parse(final Element activityElement, final Parse parse, final Parser parser) {
if (ActivityBinding.LOG.isLoggable(Level.FINE)) {
ActivityBinding.LOG.fine("parsing element = " + activityElement);
}
final String id = this.getId(activityElement);
final String name = this.getName(activityElement);
final ActivityDefinitionUUID recordUUID =
ServiceEnvTool.getUUIDGenerator().getActivityDefinitionUUID(
this.getObject(PackageDefinitionUUID.class, parse),
this.getObject(ProcessDefinitionUUID.class, parse),
id);
parse.pushObject(recordUUID);
boolean isAsync = false;
final Element asyncElement = this.getExtendedAttribute(activityElement, "Async");
if (asyncElement != null) {
isAsync = Boolean.valueOf(XmlUtil.attribute(asyncElement, "Value"));
}
final String description = this.getChildTextContent(activityElement, "Description");
final String limit = this.getChildTextContent(activityElement, "Limit");
if (limit != null) {
parse.addProblem("'Limit' element not yet supported on activity definition."
+ "Please remove it from activity: " + id);
if ("".equals(limit.trim())) {
parse.addProblem("Limit definition incorrect: no value specified in element 'Limit' for activity: " + id);
}
}
final boolean route = XmlUtil.element(activityElement, "Route") != null;
boolean noImplementation = false;
SubFlowDefinition subFlow = null;
Set tools = null;
final Element implementationElement = XmlUtil.element(activityElement, "Implementation");
if (implementationElement != null) {
noImplementation = XmlUtil.element(implementationElement, "No") != null;
subFlow = this.getSubflowDef(implementationElement, parse);
tools = this.getToolDef(implementationElement, parse);
}
String blockId = null;
final Element blockActivityElement = XmlUtil.element(activityElement, "BlockActivity");
if (blockActivityElement != null) {
blockId = XmlUtil.attribute(blockActivityElement, "Id");
}
final String performer = this.getChildTextContent(activityElement, "Performer");
ActivityDefinition.StartMode startMode = ActivityDefinition.StartMode.Automatic;
final Element startModeElement = XmlUtil.element(activityElement, "StartMode");
if (startModeElement != null) {
final Element startModeFirstChildElement = XmlUtil.element(startModeElement);
startMode = this.getEnumValue(ActivityDefinition.StartMode.class,
startModeFirstChildElement.getLocalName(), ActivityDefinition.StartMode.Automatic);
}
ActivityDefinition.FinishMode finishMode = null;
final Element finishModeElement = XmlUtil.element(activityElement, "FinishMode");
if (finishModeElement != null) {
final Element finishModeFirstChildElement = XmlUtil.element(finishModeElement);
finishMode = this.getEnumValue(ActivityDefinition.FinishMode.class,
finishModeFirstChildElement.getLocalName(), ActivityDefinition.FinishMode.Automatic);
} else {
if (startMode.equals(ActivityDefinition.StartMode.Automatic)) {
finishMode = ActivityDefinition.FinishMode.Automatic;
} else if (startMode.equals(ActivityDefinition.StartMode.Automatic)) {
finishMode = ActivityDefinition.FinishMode.Automatic;
} else {
finishMode = ActivityDefinition.FinishMode.Manual;
}
}
this.checkStartAndFinishMode(startMode, finishMode, performer, id, noImplementation,parse);
final String priority = this.getChildTextContent(activityElement, "Priority");
if (priority != null) {
parse.addProblem("'Priority' element not yet supported on activity definition. Please remove it from activity: " + id);
}
final Set deadlines = this.getDeadlines(activityElement, parse);
final SimulationInformationDefinition simulationInformation = this.getSimulationInformation(activityElement);
final String icon = this.getChildTextContent(activityElement, "Icon");
final String documentation = this.getChildTextContent(activityElement, "Documentation");
Set transitionRestrictions = null;
final Element transitionRestrictionsElement = XmlUtil.element(activityElement, "TransitionRestrictions");
if (transitionRestrictionsElement != null) {
final List transitionRestrictionElements =
XmlUtil.elements(transitionRestrictionsElement, "TransitionRestriction");
if (transitionRestrictionElements != null) {
transitionRestrictions = new HashSet();
for (final Element transitionrestrictionElement : transitionRestrictionElements) {
final JoinType joinType = this.getJoinType(transitionrestrictionElement, parse);
final SplitType splitType = this.getSplitType(transitionrestrictionElement, parse);
final Set splitTransitionRefIds = this.getSplitTransitionRefIds(transitionrestrictionElement, parse);
final TransitionRestrictionDefinition transitionRestrictionDefinition =
new TransitionRestrictionDefinitionImpl(joinType, splitType, splitTransitionRefIds);
transitionRestrictions.add(transitionRestrictionDefinition);
}
}
}
// parse hooks
final boolean isAutomaticActivity = startMode.equals(ActivityDefinition.StartMode.Automatic);
final Set hooks = this.getHooks(activityElement, parse, isAutomaticActivity);
// parse performer asign
final PerformerAssignDefinition performerAssign = this.getPerformerAssign(activityElement, parse);
// parse datafields
final Set dataFields = this.getDataFields(activityElement, parse);
// parse iterations
final Set iterations = this.parseIterationElements(activityElement);
// parse multi instantiation
final MultiInstantiationDefinition activityInstantiator = this.parseMultiInstantiationDefinition(activityElement, parse);
if (route && activityInstantiator != null) {
parse.addProblem("Multi Instantiation cannot be defined on a Route activity");
}
final ActivityDefinition activityDefinition = new ActivityDefinitionImpl(recordUUID, id,
this.getObject(PackageDefinitionUUID.class, parse), this.getObject(ProcessDefinitionUUID.class, parse),
blockId, deadlines, description, documentation, finishMode,
icon, limit, name, performer, priority, simulationInformation,
startMode, subFlow, tools, transitionRestrictions,
noImplementation, route, hooks, performerAssign, dataFields,
iterations, activityInstantiator, isAsync);
parse.popObject();
return activityDefinition;
}
/**
* Parse multi instantiation info from the activity element.
* @param activityElement
* @param parse
* @return
*/
private MultiInstantiationDefinition parseMultiInstantiationDefinition(final Element activityElement, final Parse parse) {
MultiInstantiationDefinition activityInstantiator = null;
final Element activityInstantiatorElement = this.getExtendedAttribute(activityElement, "MultiInstantiation");
if (activityInstantiatorElement != null) {
final String className = this.getChildTextContent(activityInstantiatorElement, "MultiInstantiator");
if (className == null) {
parse.addProblem("MultiInstantiation needs to specify a MultiInstantiator class name "
+ "(in a nested MultiInstantiator element)");
}
final String variableId = this.getChildTextContent(activityInstantiatorElement, "Variable");
if (variableId == null) {
parse.addProblem("MultiInstantiation needs to specify a variable id "
+ "(in a nested Variable element)");
}
if (className != null && variableId != null) {
activityInstantiator = new MultiInstantiationDefinitionImpl(variableId, className, null);
}
}
return activityInstantiator;
}
/**
* Parse iteration transitions (inherited from bonita 3)
* @param activityElement
* @return
*/
private Set parseIterationElements(final Element activityElement) {
final Set iterationElements = this.getExtendedAttributes(activityElement, "Iteration");
Set iterations = null;
if (iterationElements != null) {
iterations = new HashSet();
for (final Element iterationElement : iterationElements) {
final String iterationCondition = XmlUtil.attribute(iterationElement, "Value");
final String iterationTo = this.getChildTextContent(iterationElement, "To");
iterations.add(new ActivityDefinitionImpl.IterationDefinitionImpl(iterationTo, iterationCondition));
}
}
return iterations;
}
private JoinType getJoinType(final Element transitionrestrictionElement, final Parse parse) {
JoinType joinType = null;
final Element joinElement = XmlUtil.element(transitionrestrictionElement, "Join");
if (joinElement != null) {
joinType = this.getEnumValue(JoinType.class, XmlUtil.attribute(joinElement, "Type"), null);
if (joinType == null) {
parse.addProblem("Mandatory type attribute is not specified on join element");
}
}
return joinType;
}
private SplitType getSplitType(final Element transitionrestrictionElement, final Parse parse) {
SplitType splitType = null;
final Element splitElement = XmlUtil.element(transitionrestrictionElement, "Split");
if (splitElement != null) {
splitType = this.getEnumValue(SplitType.class, XmlUtil.attribute(splitElement, "Type"), null);
if (splitType == null) {
parse.addProblem("Mandatory type attribute is not specified on Split element!");
}
}
return splitType;
}
private Set getSplitTransitionRefIds(final Element transitionrestrictionElement, final Parse parse) {
Set splitTransitionRefIds = null;
final Element splitElement = XmlUtil.element(transitionrestrictionElement, "Split");
if (splitElement != null) {
final Element transitionRefsElement = XmlUtil.element(transitionrestrictionElement, "TransitionRefs");
if (transitionRefsElement != null) {
parse.addProblem("TransitionRefs element on Split is not supported.");
splitTransitionRefIds = new HashSet();
final List transitionRefElements = XmlUtil.elements(transitionRefsElement, "TransitionRef");
for (final Element transitionRefElement : transitionRefElements) {
final String id = XmlUtil.attribute(transitionRefElement, "Id");
splitTransitionRefIds.add(id);
}
}
}
return splitTransitionRefIds;
}
protected PerformerAssignDefinition getPerformerAssign(final Element activityElement, final Parse parse) {
final Element performerAssignElement = this.getExtendedAttribute(activityElement, "PerformerAssign");
if (performerAssignElement != null) {
final String value = XmlUtil.attribute(performerAssignElement, "Value");
String className = null;
Map parameters = null;
if ("Callback".equals(value)) {
final Element callbackElement = XmlUtil.element(performerAssignElement, "Callback");
className = callbackElement.getTextContent();
} else if ("Custom".equals(value)) {
final Element callbackElement = XmlUtil.element(performerAssignElement, "Custom");
className = callbackElement.getTextContent();
} else if ("Variable".equals(value)) {
final Element propertyElement = XmlUtil.element(performerAssignElement, "Variable");
parameters = new HashMap();
parameters.put("variableId", propertyElement.getTextContent());
className = VariablePerformerAssign.class.getName();
} else if ("Property".equals(value)) { // Bonita/ProEd V3
parse.addWarning("PerformerAssign: " + value
+ ". \"Property\" type is a Bonita v3 type name. Bonita v4 type name is \"Variable\". Class used will be: "
+ VariablePerformerAssign.class.getName());
final Element propertyElement = XmlUtil.element(performerAssignElement, "Property");
parameters = new HashMap();
parameters.put("variableId", propertyElement.getTextContent());
className = VariablePerformerAssign.class.getName();
} else {
parse.addProblem("Unsupported value on extendedAttribute PerformerAssign: " + value);
}
return new PerformerAssignDefinitionImpl(className, parameters);
}
return null;
}
private void checkStartAndFinishMode(final ActivityDefinition.StartMode startMode,
final ActivityDefinition.FinishMode finishMode, final String performer,
final String activityId, final boolean isNoImpl, final Parse parse) {
if (
(ActivityDefinition.FinishMode.Manual.equals(finishMode) && ActivityDefinition.StartMode.Automatic.equals(startMode))
||
(ActivityDefinition.FinishMode.Automatic.equals(finishMode) && ActivityDefinition.StartMode.Manual.equals(startMode))
) {
parse.addProblem("StartMode and FinishMode have different values: this feature is not yet supported.");
}
final boolean hasManualMode =
ActivityDefinition.StartMode.Manual.equals(startMode) || ActivityDefinition.FinishMode.Manual.equals(finishMode);
if (hasManualMode) {
if (performer == null) {
parse.addProblem("StartMode or FinishMode is Manual and no performer is specified on activity processDefinitionUUID = "
+ activityId + "! Please specify one.");
}
if (!isNoImpl) {
parse.addProblem("StartMode or FinishMode is Manual and activity implementation is not No:"
+ "this feature is not yet supported.");
}
}
}
protected SimulationInformationDefinition getSimulationInformation(final Element activityElement) {
SimulationInformationDefinition simulationInformationDefinition = null;
final Element simulationInformationElement = XmlUtil.element(activityElement, "SimulationInformation");
if (simulationInformationElement != null) {
final SimulationInformationDefinition.Instantiation instantiation =
this.getEnumValue(SimulationInformationDefinition.Instantiation.class,
XmlUtil.attribute(simulationInformationElement, "Instantiation"), null);
final String cost = this.getChildTextContent(simulationInformationElement, "Cost");
TimeEstimationDefinition timeEstimation = null;
final Element timeEstimationElement = XmlUtil.element(simulationInformationElement, "TimeEstimation");
if (timeEstimationElement != null) {
final String waitingTime = this.getChildTextContent(timeEstimationElement, "WaitingTime");
final String workingTime = this.getChildTextContent(timeEstimationElement, "WorkingTime");
final String duration = this.getChildTextContent(timeEstimationElement, "Duration");
timeEstimation = new TimeEstimationDefinitionImpl(duration, waitingTime, workingTime);
}
simulationInformationDefinition = new SimulationInformationDefinitionImpl(cost, instantiation, timeEstimation);
}
return simulationInformationDefinition;
}
protected Set getToolDef(final Element implementationElement, final Parse parse) {
final Element toolElement = XmlUtil.element(implementationElement, "Tool");
if (toolElement != null) {
parse.addProblem("Tool is not supported as an implementationType");
//implementation.setImplementationType(activity.new ToolImplementation());
}
return null;
}
protected SubFlowDefinition getSubflowDef(final Element implementationElement, final Parse parse) {
SubFlowDefinition subFlowDefinition = null;
final Element subFlowElement = XmlUtil.element(implementationElement, "SubFlow");
if (subFlowElement != null) {
List actualParameters = null;
final Element actualparametersElement = XmlUtil.element(subFlowElement, "ActualParameters");
if (actualparametersElement != null) {
final List actualparameterElements = XmlUtil.elements(actualparametersElement, "ActualParameter");
if (actualparameterElements != null) {
actualParameters = new ArrayList();
for (final Element actualparameterElement : actualparameterElements) {
actualParameters.add(actualparameterElement.getTextContent());
}
}
}
final String id = XmlUtil.attribute(subFlowElement, "Id");
final SubFlowDefinition.Execution execution = this.getEnumValue(SubFlowDefinition.Execution.class,
XmlUtil.attribute(subFlowElement, "Execution"), null);
if (execution != null) {
if (SubFlowDefinition.Execution.ASYNCHR.equals(execution)) {
parse.addProblem("Asyncr SubFlow is not supported");
}
}
subFlowDefinition = new SubFlowDefinitionImpl(actualParameters, execution, id);
}
return subFlowDefinition;
}
@SuppressWarnings("unchecked")
protected Set getDataFields(final Element activityElement, final Parse parse) {
Set result = null;
final Set propertyElements = this.getExtendedAttributes(activityElement, "property");
if (propertyElements != null) {
Set activityDataFields = new HashSet();
activityDataFields = parse.findObject(activityDataFields.getClass());
if (activityDataFields == null) {
parse.addProblem("No activity dataFields is defined within the process.");
} else {
result = new HashSet();
for (final Element propertyElement : propertyElements) {
final String dataFieldId = XmlUtil.attribute(propertyElement, "Value");
final DataFieldDefinition dataField = this.getActivityDataField(activityDataFields, dataFieldId);
if (dataField == null) {
parse.addProblem("Looking for a datafield with processDefinitionUUID: " + dataFieldId
+ " in enclosing process but unable to find it.");
} else {
result.add(new DataFieldDefinitionImpl(dataField));
}
final String propagatedValue = this.getChildTextContent(propertyElement, "Propagated");
if (propagatedValue != null && !("no".equalsIgnoreCase(propagatedValue) || "false".equalsIgnoreCase(propagatedValue))) {
parse.addProblem("Propagated value not supported: " + propagatedValue
+ ". Use instance variables instead."
+ "(Only 'no' or 'false' are supported for backward compatibility.)");
}
}
}
}
return result;
}
protected DataFieldDefinition getActivityDataField(final Set activityDataFields,
final String dataFieldId) {
for (final DataFieldDefinition dataField : activityDataFields) {
if (dataField.getDataFieldId().equals(dataFieldId)) {
return dataField;
}
}
return null;
}
protected Set getHooks(final Element activityElement, final Parse parse, final boolean isAutomatic) {
final Set hookElements = this.getExtendedAttributes(activityElement, "hook");
Set hooks = null;
if (hookElements != null) {
hooks = new HashSet();
for (final Element hookElement : hookElements) {
final String className = XmlUtil.attribute(hookElement, "Value");
final String hookEventName = this.getChildTextContent(hookElement, "HookEventName");
if (hookEventName == null) {
parse.addProblem("hook ExtendedAttribute needs an element child called HookEventName");
} else {
final String rollBackFlag = this.getChildTextContent(hookElement, "Rollback");
if (rollBackFlag == null) {
parse.addWarning("Rollback flag is not specified for hook: " + hookEventName
+ ". Using Bonita v3 hook compatibility parser.");
//beforeTerminate, afterTerminate, beforeFinish, afterFinish,
//beforeStart, afterStart, onDeadline, taskOnCancel, taskOnReady
HookDefinition.V3Event v3Event = null;
try {
v3Event = Misc.stringToEnum(HookDefinition.V3Event.class, hookEventName);
} catch (final IllegalArgumentException iae) {
parse.addProblem("Unsupported HookEventName: " + hookEventName + " for "
+ (isAutomatic ? "automatic" : "manual") + " activity.");
}
if (v3Event != null) {
final HookDefinition.Event event = HookDefinition.V3Event.getV4FromV3HookEventName(v3Event, isAutomatic);
if (event == null) {
parse.addProblem("Unsupported HookEventName: " + hookEventName + " for "
+ (isAutomatic ? "automatic" : "manual") + " activity");
} else {
parse.addWarning("Bonita v3 HookEventName: " + v3Event + " is mapped to Bonita v4 HookEventName: "
+ event + "' for " + (isAutomatic ? "automatic " : "manual") + " activity");
final boolean throwingException = ActivityBinding.getExceptionFlagFromV3Hook(v3Event);
hooks.add(new HookDefinitionImpl(className, event, null, throwingException));
}
}
} else { // Bonita v4 Hook Specification (see ProEd v4)
HookDefinition.Event event = null;
// We can't use Boolean's class methods since in their case,
// true == "true" and false == !true (anything different to "true")
// In our case, we really want either "true" or "false". Any other string
// is simply an invalid flag.
boolean throwingException = false;
if ("true".equals(rollBackFlag)) {
throwingException = true;
} else if ("false".equals(rollBackFlag)) {
throwingException = false;
} else {
parse.addProblem("Invalid Rollback specification: " + rollBackFlag + ". It should be either 'true' or 'false'.");
}
try {
event = Misc.stringToEnum(HookDefinition.Event.class, hookEventName);
} catch (final IllegalArgumentException iae) {
parse.addProblem("Unsupported HookEventName: " + hookEventName + " for "
+ (isAutomatic ? "automatic" : "manual") + " activity.");
}
if (event != null) {
hooks.add(new HookDefinitionImpl(className, event, null, throwingException));
}
}
}
}
}
if (hooks != null) {
if (isAutomatic) {
for (final HookDefinition hookDefinition : hooks) {
final HookDefinition.Event event = hookDefinition.getEvent();
if (!HookDefinition.Event.automaticOnEnter.equals(event)) {
parse.addProblem("Unsupported HookEventName: " + event + " for automatic activity"
+ ". Hook class = " + hookDefinition.getClassName()
+ ". Valid HookEventName for automatic activity is: " + HookDefinition.Event.automaticOnEnter);
}
}
} else {
for (final HookDefinition hook : hooks) {
if (!HookDefinition.Event.TASK_EVENTS.contains(hook.getEvent())) {
parse.addProblem("Task activities (NoImplementation - manual) can only define hook on event: "
+ HookDefinition.Event.TASK_EVENTS + ". Hook class = "
+ hook.getClassName());
}
}
}
}
return hooks;
}
private static boolean getExceptionFlagFromV3Hook(final HookDefinition.V3Event event) {
if (event.equals(HookDefinition.V3Event.afterTerminate) || event.equals(HookDefinition.V3Event.beforeStart)) {
return false;
}
return true;
}
protected Set getDeadlines(final Element activityElement, final Parse parse) {
final List deadlineElements = XmlUtil.elements(activityElement, "Deadline");
Set deadlines = null;
if (deadlineElements != null) {
if (ActivityBinding.LOG.isLoggable(Level.WARNING)) {
ActivityBinding.LOG.warning("Bonita use of deadlines is specific: refer to bonita User Guide for more details");
}
deadlines = new HashSet();
for (final Element deadlineElement : deadlineElements) {
DeadlineDefinition.Execution execution =
this.getEnumValue(DeadlineDefinition.Execution.class,
XmlUtil.attribute(deadlineElement, "Execution"), null);
if (execution == null) {
execution = DeadlineDefinition.Execution.SYNCHR;
}
// schema validation ensures that deadlineCondtion and ExceptionName
// are specified once and only once
final String deadlineCondition = this.getChildTextContent(deadlineElement, "DeadlineCondition");
if (deadlineCondition == null) {
parse.addProblem("DeadlineCondition element is not specified on deadline element");
}
final String exceptionName = this.getChildTextContent(deadlineElement, "ExceptionName");
if (exceptionName == null) {
parse.addProblem("ExceptionName element is not specified on deadline element");
}
deadlines.add(new DeadlineDefinitionImpl(deadlineCondition, exceptionName, execution));
}
}
return deadlines;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy