package org.enhydra.shark.xpdl;
import java.io.*;
import java.lang.reflect.Method;
import java.util.*;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.apache.xerces.parsers.DOMParser;
import org.enhydra.shark.xpdl.elements.Activities;
import org.enhydra.shark.xpdl.elements.Activity;
import org.enhydra.shark.xpdl.elements.ActivitySet;
import org.enhydra.shark.xpdl.elements.ActivitySets;
import org.enhydra.shark.xpdl.elements.ActivityTypes;
import org.enhydra.shark.xpdl.elements.ActualParameter;
import org.enhydra.shark.xpdl.elements.ActualParameters;
import org.enhydra.shark.xpdl.elements.Application;
import org.enhydra.shark.xpdl.elements.ApplicationTypes;
import org.enhydra.shark.xpdl.elements.Applications;
import org.enhydra.shark.xpdl.elements.ArrayType;
import org.enhydra.shark.xpdl.elements.Author;
import org.enhydra.shark.xpdl.elements.Automatic;
import org.enhydra.shark.xpdl.elements.BasicType;
import org.enhydra.shark.xpdl.elements.BlockActivity;
import org.enhydra.shark.xpdl.elements.Codepage;
import org.enhydra.shark.xpdl.elements.Condition;
import org.enhydra.shark.xpdl.elements.ConformanceClass;
import org.enhydra.shark.xpdl.elements.Cost;
import org.enhydra.shark.xpdl.elements.CostUnit;
import org.enhydra.shark.xpdl.elements.Countrykey;
import org.enhydra.shark.xpdl.elements.Created;
import org.enhydra.shark.xpdl.elements.DataField;
import org.enhydra.shark.xpdl.elements.DataFields;
import org.enhydra.shark.xpdl.elements.DataType;
import org.enhydra.shark.xpdl.elements.DataTypes;
import org.enhydra.shark.xpdl.elements.Deadline;
import org.enhydra.shark.xpdl.elements.DeadlineCondition;
import org.enhydra.shark.xpdl.elements.Deadlines;
import org.enhydra.shark.xpdl.elements.DeclaredType;
import org.enhydra.shark.xpdl.elements.Description;
import org.enhydra.shark.xpdl.elements.Documentation;
import org.enhydra.shark.xpdl.elements.Duration;
import org.enhydra.shark.xpdl.elements.EnumerationType;
import org.enhydra.shark.xpdl.elements.EnumerationValue;
import org.enhydra.shark.xpdl.elements.ExceptionName;
import org.enhydra.shark.xpdl.elements.ExtendedAttribute;
import org.enhydra.shark.xpdl.elements.ExtendedAttributes;
import org.enhydra.shark.xpdl.elements.ExternalPackage;
import org.enhydra.shark.xpdl.elements.ExternalPackages;
import org.enhydra.shark.xpdl.elements.ExternalReference;
import org.enhydra.shark.xpdl.elements.FinishMode;
import org.enhydra.shark.xpdl.elements.FormalParameter;
import org.enhydra.shark.xpdl.elements.FormalParameters;
import org.enhydra.shark.xpdl.elements.Icon;
import org.enhydra.shark.xpdl.elements.Implementation;
import org.enhydra.shark.xpdl.elements.ImplementationTypes;
import org.enhydra.shark.xpdl.elements.InitialValue;
import org.enhydra.shark.xpdl.elements.Join;
import org.enhydra.shark.xpdl.elements.Length;
import org.enhydra.shark.xpdl.elements.Limit;
import org.enhydra.shark.xpdl.elements.ListType;
import org.enhydra.shark.xpdl.elements.Manual;
import org.enhydra.shark.xpdl.elements.Member;
import org.enhydra.shark.xpdl.elements.Namespace;
import org.enhydra.shark.xpdl.elements.Namespaces;
import org.enhydra.shark.xpdl.elements.No;
import org.enhydra.shark.xpdl.elements.Package;
import org.enhydra.shark.xpdl.elements.PackageHeader;
import org.enhydra.shark.xpdl.elements.Participant;
import org.enhydra.shark.xpdl.elements.ParticipantType;
import org.enhydra.shark.xpdl.elements.Participants;
import org.enhydra.shark.xpdl.elements.Performer;
import org.enhydra.shark.xpdl.elements.Priority;
import org.enhydra.shark.xpdl.elements.PriorityUnit;
import org.enhydra.shark.xpdl.elements.ProcessHeader;
import org.enhydra.shark.xpdl.elements.RecordType;
import org.enhydra.shark.xpdl.elements.RedefinableHeader;
import org.enhydra.shark.xpdl.elements.Responsible;
import org.enhydra.shark.xpdl.elements.Responsibles;
import org.enhydra.shark.xpdl.elements.Route;
import org.enhydra.shark.xpdl.elements.SchemaType;
import org.enhydra.shark.xpdl.elements.Script;
import org.enhydra.shark.xpdl.elements.SimulationInformation;
import org.enhydra.shark.xpdl.elements.Split;
import org.enhydra.shark.xpdl.elements.StartFinishModes;
import org.enhydra.shark.xpdl.elements.StartMode;
import org.enhydra.shark.xpdl.elements.SubFlow;
import org.enhydra.shark.xpdl.elements.TimeEstimation;
import org.enhydra.shark.xpdl.elements.Tool;
import org.enhydra.shark.xpdl.elements.Tools;
import org.enhydra.shark.xpdl.elements.Transition;
import org.enhydra.shark.xpdl.elements.TransitionRef;
import org.enhydra.shark.xpdl.elements.TransitionRefs;
import org.enhydra.shark.xpdl.elements.TransitionRestriction;
import org.enhydra.shark.xpdl.elements.TransitionRestrictions;
import org.enhydra.shark.xpdl.elements.Transitions;
import org.enhydra.shark.xpdl.elements.TypeDeclaration;
import org.enhydra.shark.xpdl.elements.TypeDeclarations;
import org.enhydra.shark.xpdl.elements.UnionType;
import org.enhydra.shark.xpdl.elements.ValidFrom;
import org.enhydra.shark.xpdl.elements.ValidTo;
import org.enhydra.shark.xpdl.elements.Vendor;
import org.enhydra.shark.xpdl.elements.Version;
import org.enhydra.shark.xpdl.elements.WaitingTime;
import org.enhydra.shark.xpdl.elements.WorkflowProcess;
import org.enhydra.shark.xpdl.elements.WorkflowProcesses;
import org.enhydra.shark.xpdl.elements.WorkingTime;
import org.enhydra.shark.xpdl.elements.XPDLVersion;
import org.xml.sax.InputSource;
public class StandardPackageValidator implements XMLValidator{
public StandardPackageValidator()
{
epsValidationErrors = new HashMap();
schemaValidationErrors = new HashMap();
}
public StandardPackageValidator(Properties settings)
{
epsValidationErrors = new HashMap();
schemaValidationErrors = new HashMap();
this.settings = settings;
}
public void init(XMLInterface pXmlInterface, Package pPkg, boolean pGetExistingSchemaValidationErrors, String pEncoding, String pLocale)
{
Properties tempProperties = new Properties();
tempProperties.putAll(settings);
tempProperties.put("GetExistingSchemaValidationErrors", String.valueOf(pGetExistingSchemaValidationErrors));
tempProperties.put("CheckExternalPackages", "true");
tempProperties.put("Encoding", pEncoding);
tempProperties.put("Locale", pLocale);
init(tempProperties, pXmlInterface);
}
public void clearCache(Package pkg)
{
epsValidationErrors.remove(pkg);
schemaValidationErrors.remove(pkg);
}
public void clearCache()
{
epsValidationErrors.clear();
schemaValidationErrors.clear();
xmlInterface = null;
}
public Map getExtPkgValidationErrors()
{
return epsValidationErrors;
}
public void init(Properties props)
{
properties = props;
if(props == null)
clearCache();
}
public void init(Properties pProps, XMLInterface pXmlInterface)
{
init(pProps);
xmlInterface = pXmlInterface;
}
public void validateElement(XMLElement el, List existingErrors, boolean fullCheck)
{
if(!fullCheck && existingErrors.size() > 0)
return;
if(el.isEmpty() && !(el instanceof XMLCollection) && !el.isRequired())
return;
try
{
Class cl = el.getClass();
Method m = null;
try
{
m = getClass().getMethod("validateElement", new Class[] {
cl, java.util.List.class, Boolean.TYPE
});
}
catch(Exception ex)
{
if(cl != (org.enhydra.shark.xpdl.XMLSimpleElement.class) && cl != (org.enhydra.shark.xpdl.XMLAttribute.class) && cl != (org.enhydra.shark.xpdl.XMLComplexChoice.class) && cl != (org.enhydra.shark.xpdl.XMLComplexElement.class) && cl != (org.enhydra.shark.xpdl.XMLCollectionElement.class) && cl != (org.enhydra.shark.xpdl.XMLCollection.class))
if((org.enhydra.shark.xpdl.XMLComplexChoice.class).isAssignableFrom(cl))
cl = org.enhydra.shark.xpdl.XMLComplexChoice.class;
else
if((org.enhydra.shark.xpdl.XMLAttribute.class).isAssignableFrom(cl))
cl = org.enhydra.shark.xpdl.XMLAttribute.class;
else
if((org.enhydra.shark.xpdl.XMLSimpleElement.class).isAssignableFrom(cl))
cl = org.enhydra.shark.xpdl.XMLSimpleElement.class;
else
if((org.enhydra.shark.xpdl.XMLComplexElement.class).isAssignableFrom(cl))
cl = org.enhydra.shark.xpdl.XMLComplexElement.class;
else
if((org.enhydra.shark.xpdl.XMLCollection.class).isAssignableFrom(cl))
cl = org.enhydra.shark.xpdl.XMLCollection.class;
}
m = getClass().getMethod("validateElement", new Class[] {
cl, java.util.List.class, Boolean.TYPE
});
m.invoke(this, new Object[] {
el, existingErrors, new Boolean(fullCheck)
});
return;
}
catch(Throwable e)
{
e.printStackTrace();
}
validateStandard(el, existingErrors, fullCheck);
}
public void validateElement(XMLAttribute el, List existingErrors, boolean fullCheck)
{
XMLElement parent = el.getParent();
boolean isValid = true;
if(el.toName().equals("Id"))
{
if(parent instanceof SubFlow)
checkSubFlowId(el, existingErrors, fullCheck);
else
if(parent instanceof Tool)
checkToolId(el, existingErrors, fullCheck);
else
if(parent instanceof TransitionRef)
checkTransitionRefId(el, existingErrors, fullCheck);
else
if(parent instanceof DeclaredType)
{
checkDeclaredTypeId(el, existingErrors);
} else
{
if(!isIdValid(el.toValue()))
{
isValid = false;
XMLValidationError verr = new XMLValidationError("ERROR", "LOGIC", "ERROR_INVALID_ID", el.toValue(), el);
existingErrors.add(verr);
}
if((parent instanceof XMLCollectionElement) && (fullCheck || isValid) && !isIdUnique((XMLCollectionElement)parent))
{
isValid = false;
XMLValidationError verr = new XMLValidationError("ERROR", "LOGIC", "ERROR_NON_UNIQUE_ID", el.toValue(), el);
existingErrors.add(verr);
}
}
} else
if(el.toName().equals("href"))
{
if(parent instanceof ExternalPackage)
{
String val = el.toValue();
Package pkg = XMLUtil.getPackage(el);
String epId = pkg.getExternalPackageId(val);
if(epId == null || epId.equals(""))
{
XMLValidationError verr = new XMLValidationError("ERROR", "LOGIC", "ERROR_NON_EXISTING_EXTERNAL_PACKAGE_REFERENCE", val, el);
existingErrors.add(verr);
}
}
} else
if(parent instanceof Transition)
{
if(el.toName().equals("From"))
checkTransitionFrom(el, existingErrors);
else
if(el.toName().equals("To"))
checkTransitionTo(el, existingErrors);
} else
if(parent instanceof BlockActivity)
checkBlockId(el, existingErrors);
}
public void validateElement(XMLComplexChoice el, List existingErrors, boolean fullCheck)
{
validateElement(el.getChoosen(), existingErrors, fullCheck);
}
public void validateElement(XMLEmptyChoiceElement xmlemptychoiceelement, List list, boolean flag)
{
}
public void validateElement(XMLCollection el, List existingErrors, boolean fullCheck)
{
XMLElement cel;
for(Iterator it = el.toElements().iterator(); it.hasNext(); validateElement(cel, existingErrors, fullCheck))
cel = (XMLElement)it.next();
}
public void validateElement(XMLCollectionElement el, List existingErrors, boolean fullCheck)
{
validateElement(((XMLComplexElement) (el)), existingErrors, fullCheck);
}
public void validateElement(XMLComplexElement el, List existingErrors, boolean fullCheck)
{
XMLElement cel;
for(Iterator it = el.toElements().iterator(); it.hasNext(); validateElement(cel, existingErrors, fullCheck))
cel = (XMLElement)it.next();
}
public void validateElement(XMLSimpleElement xmlsimpleelement, List list, boolean flag)
{
}
protected void validateStandard(XMLElement el, List existingErrors, boolean fullCheck)
{
if(el instanceof XMLAttribute)
validateElement((XMLAttribute)el, existingErrors, fullCheck);
else
if(el instanceof XMLSimpleElement)
validateElement((XMLSimpleElement)el, existingErrors, fullCheck);
else
if(el instanceof XMLCollectionElement)
validateElement((XMLCollectionElement)el, existingErrors, fullCheck);
else
if(el instanceof XMLComplexElement)
validateElement((XMLComplexElement)el, existingErrors, fullCheck);
else
if(el instanceof XMLComplexChoice)
validateElement((XMLComplexChoice)el, existingErrors, fullCheck);
else
if(el instanceof XMLCollection)
validateElement((XMLCollection)el, existingErrors, fullCheck);
}
public void validateElement(Activities el, List existingErrors, boolean fullCheck)
{
validateStandard(el, existingErrors, fullCheck);
}
public void validateElement(Activity el, List existingErrors, boolean fullCheck)
{
validateStandard(el, existingErrors, fullCheck);
boolean isValid = existingErrors.size() == 0;
if(!isValid && !fullCheck)
return;
Set ets = XMLUtil.getExceptionalOutgoingTransitions(el);
if(el.getDeadlines().size() > 0 && ets.size() == 0)
{
XMLValidationError verr = new XMLValidationError("ERROR", "LOGIC", "ERROR_DEADLINES_NOT_PROPERLY_HANDLED_NO_EXCEPTIONAL_TRANSITIONS", "", el);
existingErrors.add(verr);
isValid = false;
}
if(!isValid && !fullCheck)
return;
Set outTrans = XMLUtil.getOutgoingTransitions(el);
Set inTrans = XMLUtil.getIncomingTransitions(el);
Split split = XMLUtil.getSplit(el);
if((split == null || split.getType().length() == 0) && outTrans.size() > 1)
{
isValid = false;
XMLValidationError verr = new XMLValidationError("ERROR", "LOGIC", "ERROR_MULTIPLE_OUTGOING_TRANSITIONS_WITHOUT_SPLIT_TYPE_DEFINED", "", el);
existingErrors.add(verr);
}
if(!isValid && !fullCheck)
return;
Join join = XMLUtil.getJoin(el);
if((join == null || join.getType().length() == 0) && inTrans.size() > 1)
{
isValid = false;
XMLValidationError verr = new XMLValidationError("ERROR", "LOGIC", "ERROR_MULTIPLE_INCOMING_TRANSITIONS_WITHOUT_JOIN_TYPE_DEFINED", "", el);
existingErrors.add(verr);
}
if(!fullCheck && !isValid)
{
return;
} else
{
checkMultipleOtherwiseOrDefaultExceptionTransitions(el, outTrans, existingErrors, fullCheck);
return;
}
}
public void validateElement(ActivitySet el, List existingErrors, boolean fullCheck)
{
validateStandard(el, existingErrors, fullCheck);
boolean isValid = true;
if((existingErrors.size() == 0 || fullCheck) && el.getActivities().toElements().size() == 0)
{
isValid = false;
XMLValidationError verr = new XMLValidationError("ERROR", "LOGIC", "ERROR_ACTIVITY_SET_NOT_DEFINED", "", el);
existingErrors.add(verr);
}
if(isValid || fullCheck)
isValid = checkGraphConnectionsForWpOrAs(el, existingErrors, fullCheck) || fullCheck;
if(isValid || fullCheck)
isValid = checkGraphConformanceForWpOrAs(el, existingErrors, fullCheck) || fullCheck;
}
public void validateElement(ActivitySets el, List existingErrors, boolean fullCheck)
{
validateStandard(el, existingErrors, fullCheck);
}
public void validateElement(ActivityTypes el, List existingErrors, boolean fullCheck)
{
validateStandard(el, existingErrors, fullCheck);
}
public void validateElement(ActualParameter el, List existingErrors, boolean fullCheck)
{
validateStandard(el, existingErrors, fullCheck);
}
public void validateElement(ActualParameters el, List existingErrors, boolean fullCheck)
{
validateStandard(el, existingErrors, fullCheck);
}
public void validateElement(Application el, List existingErrors, boolean fullCheck)
{
validateStandard(el, existingErrors, fullCheck);
}
public void validateElement(Applications el, List existingErrors, boolean fullCheck)
{
validateStandard(el, existingErrors, fullCheck);
}
public void validateElement(ApplicationTypes el, List existingErrors, boolean fullCheck)
{
validateStandard(el, existingErrors, fullCheck);
}
public void validateElement(ArrayType el, List existingErrors, boolean fullCheck)
{
validateStandard(el, existingErrors, fullCheck);
}
public void validateElement(Author el, List existingErrors, boolean fullCheck)
{
validateStandard(el, existingErrors, fullCheck);
}
public void validateElement(Automatic el, List existingErrors, boolean fullCheck)
{
validateStandard(el, existingErrors, fullCheck);
}
public void validateElement(BasicType el, List existingErrors, boolean fullCheck)
{
validateStandard(el, existingErrors, fullCheck);
}
public void validateElement(BlockActivity el, List existingErrors, boolean fullCheck)
{
validateStandard(el, existingErrors, fullCheck);
}
public void validateElement(Codepage el, List existingErrors, boolean fullCheck)
{
validateStandard(el, existingErrors, fullCheck);
}
public void validateElement(Condition el, List existingErrors, boolean fullCheck)
{
validateStandard(el, existingErrors, fullCheck);
String condType = el.getType();
String condExpr = el.toValue();
if(existingErrors.size() > 0 && !fullCheck)
return;
boolean validateCondByType = properties.getProperty("ValidateConditionByType", "false").equals("true");
if(condType.equals("DEFAULTEXCEPTION"))
{
if(validateCondByType && condExpr.length() > 0)
{
XMLValidationError verr = new XMLValidationError("WARNING", "LOGIC", "WARNING_DEFAULT_EXCEPTION_TRANSITION_WITH_EXPRESSION", condExpr, el);
existingErrors.add(verr);
}
return;
}
if(condType.equals("OTHERWISE"))
{
if(validateCondByType && condExpr.length() > 0)
{
XMLValidationError verr = new XMLValidationError("WARNING", "LOGIC", "WARNING_OTHERWISE_TRANSITION_WITH_EXPRESSION", condExpr, el);
existingErrors.add(verr);
}
return;
}
if(condType.equals(""))
{
if(validateCondByType && condExpr.length() > 0)
{
XMLValidationError verr = new XMLValidationError("WARNING", "LOGIC", "WARNING_UNCONDITIONAL_TRANSITION_WITH_EXPRESSION", condExpr, el);
existingErrors.add(verr);
}
} else
if(condType.equals("CONDITION"))
{
if(validateCondByType && condExpr.length() <= 0)
{
XMLValidationError verr = new XMLValidationError("WARNING", "LOGIC", "WARNING_CONDITIONAL_TRANSITION_WITHOUT_EXPRESSION", "", el);
existingErrors.add(verr);
}
} else
if(condType.equals("EXCEPTION"))
{
if(validateCondByType && condExpr.length() <= 0)
{
XMLValidationError verr = new XMLValidationError("WARNING", "LOGIC", "WARNING_EXCEPTION_TRANSITION_WITHOUT_EXPRESSION", "", el);
existingErrors.add(verr);
}
return;
}
if((existingErrors.size() == 0 || fullCheck) && condExpr.length() > 0 && properties.getProperty("ValidateConditionExpressions", "false").equals("true"))
{
if(condExpr.toLowerCase().indexOf("true") >= 0 || condExpr.toLowerCase().indexOf("false") >= 0 || condExpr.toLowerCase().indexOf("boolean") >= 0 || condExpr.toLowerCase().indexOf("equals") >= 0 || condExpr.toLowerCase().indexOf(">") >= 0 || condExpr.toLowerCase().indexOf(">=") >= 0 || condExpr.toLowerCase().indexOf("<") >= 0 || condExpr.toLowerCase().indexOf("<=") >= 0 || condExpr.toLowerCase().indexOf("==") >= 0)
return;
if(!XMLUtil.canBeExpression(condExpr, XMLUtil.getWorkflowProcess(el).getAllVariables(), false))
{
XMLValidationError verr = new XMLValidationError("WARNING", "LOGIC", "WARNING_CONDITION_EXPRESSION_POSSIBLY_INVALID", condExpr, el);
existingErrors.add(verr);
}
}
}
public void validateElement(ConformanceClass el, List existingErrors, boolean fullCheck)
{
validateStandard(el, existingErrors, fullCheck);
}
public void validateElement(Cost el, List existingErrors, boolean fullCheck)
{
validateStandard(el, existingErrors, fullCheck);
}
public void validateElement(CostUnit el, List existingErrors, boolean fullCheck)
{
validateStandard(el, existingErrors, fullCheck);
}
public void validateElement(Countrykey el, List existingErrors, boolean fullCheck)
{
validateStandard(el, existingErrors, fullCheck);
}
public void validateElement(Created el, List existingErrors, boolean fullCheck)
{
validateStandard(el, existingErrors, fullCheck);
}
public void validateElement(DataField el, List existingErrors, boolean fullCheck)
{
validateStandard(el, existingErrors, fullCheck);
boolean validateVariableUsage = properties.getProperty("ValidateUnusedVariables", "false").equals("true");
if(validateVariableUsage && (fullCheck || existingErrors.size() == 0) && getNoOfReferences(el.getParent().getParent().getClass(), (XMLComplexElement)el.getParent().getParent(), org.enhydra.shark.xpdl.elements.DataField.class, el) == 0)
{
XMLValidationError verr = new XMLValidationError("WARNING", "LOGIC", "WARNING_UNUSED_VARIABLE", el.getId(), el);
existingErrors.add(verr);
}
}
public void validateElement(DataFields el, List existingErrors, boolean fullCheck)
{
validateStandard(el, existingErrors, fullCheck);
}
public void validateElement(DataType el, List existingErrors, boolean fullCheck)
{
validateStandard(el, existingErrors, fullCheck);
}
public void validateElement(DataTypes el, List existingErrors, boolean fullCheck)
{
validateStandard(el, existingErrors, fullCheck);
}
public void validateElement(Deadline el, List existingErrors, boolean fullCheck)
{
validateStandard(el, existingErrors, fullCheck);
}
public void validateElement(DeadlineCondition el, List existingErrors, boolean fullCheck)
{
validateStandard(el, existingErrors, fullCheck);
String condExpr = el.toValue();
if((existingErrors.size() == 0 || fullCheck) && condExpr.length() > 0 && properties.getProperty("ValidateDeadlineExpressions", "false").equals("true"))
{
if(condExpr.toLowerCase().indexOf("date") >= 0 || condExpr.toLowerCase().indexOf("calendar") >= 0)
return;
if(!XMLUtil.canBeExpression(condExpr, XMLUtil.getWorkflowProcess(el).getAllVariables(), false))
{
XMLValidationError verr = new XMLValidationError("WARNING", "LOGIC", "WARNING_DEADLINE_EXPRESSION_POSSIBLY_INVALID", condExpr, el);
existingErrors.add(verr);
}
}
}
public void validateElement(Deadlines el, List existingErrors, boolean fullCheck)
{
Iterator dls = el.toElements().iterator();
int syncCount = 0;
do
{
if(!dls.hasNext())
break;
Deadline dl = (Deadline)dls.next();
if(dl.getExecution().equals("SYNCHR"))
syncCount++;
} while(true);
if(syncCount > 1)
{
XMLValidationError verr = new XMLValidationError("ERROR", "LOGIC", "ERROR_MULTIPLE_SYNC_DEADLINES_DEFINED", "", el);
existingErrors.add(verr);
}
if(fullCheck || syncCount > 1)
validateStandard(el, existingErrors, fullCheck);
}
public void validateElement(DeclaredType el, List existingErrors, boolean fullCheck)
{
validateStandard(el, existingErrors, fullCheck);
}
public void validateElement(Description el, List existingErrors, boolean fullCheck)
{
validateStandard(el, existingErrors, fullCheck);
}
public void validateElement(Documentation el, List existingErrors, boolean fullCheck)
{
validateStandard(el, existingErrors, fullCheck);
}
public void validateElement(Duration el, List existingErrors, boolean fullCheck)
{
validateStandard(el, existingErrors, fullCheck);
}
public void validateElement(EnumerationType el, List existingErrors, boolean fullCheck)
{
validateStandard(el, existingErrors, fullCheck);
}
public void validateElement(EnumerationValue el, List existingErrors, boolean fullCheck)
{
validateStandard(el, existingErrors, fullCheck);
}
public void validateElement(ExceptionName el, List existingErrors, boolean fullCheck)
{
Activity act = XMLUtil.getActivity(el);
Set ets = XMLUtil.getExceptionalOutgoingTransitions(act);
boolean isValid = true;
if(ets.size() == 0)
{
isValid = false;
} else
{
String en = el.toValue();
for(Iterator it = ets.iterator(); it.hasNext();)
{
Transition t = (Transition)it.next();
String cond = t.getCondition().toValue();
String ctype = t.getCondition().getType();
if(ctype.equals("DEFAULTEXCEPTION") || cond.equals(en) || cond.length() == 0)
return;
}
isValid = false;
}
if(!isValid)
{
XMLValidationError verr = new XMLValidationError("ERROR", "LOGIC", "ERROR_DEADLINE_EXCEPTION_NOT_PROPERLY_HANDLED_MISSING_SPECIFIED_EXCEPTION_TRANSITION_OR_DEFAULT_EXCEPTION_TRANSITION", "", el);
existingErrors.add(verr);
}
}
public void validateElement(ExtendedAttribute el, List existingErrors, boolean fullCheck)
{
validateStandard(el, existingErrors, fullCheck);
}
public void validateElement(ExtendedAttributes el, List existingErrors, boolean fullCheck)
{
validateStandard(el, existingErrors, fullCheck);
}
public void validateElement(ExternalPackage el, List existingErrors, boolean fullCheck)
{
validateStandard(el, existingErrors, fullCheck);
}
public void validateElement(ExternalPackages el, List existingErrors, boolean fullCheck)
{
validateStandard(el, existingErrors, fullCheck);
}
public void validateElement(ExternalReference el, List existingErrors, boolean fullCheck)
{
validateStandard(el, existingErrors, fullCheck);
}
public void validateElement(FinishMode el, List existingErrors, boolean fullCheck)
{
validateStandard(el, existingErrors, fullCheck);
}
public void validateElement(FormalParameter el, List existingErrors, boolean fullCheck)
{
validateStandard(el, existingErrors, fullCheck);
boolean validateVariableUsage = properties.getProperty("ValidateUnusedVariables", "false").equals("true");
if(validateVariableUsage && (el.getParent().getParent() instanceof WorkflowProcess) && (fullCheck || existingErrors.size() == 0) && getNoOfReferences(org.enhydra.shark.xpdl.elements.WorkflowProcess.class, (WorkflowProcess)el.getParent().getParent(), org.enhydra.shark.xpdl.elements.FormalParameter.class, el) == 0)
{
XMLValidationError verr = new XMLValidationError("WARNING", "LOGIC", "WARNING_UNUSED_VARIABLE", el.getId(), el);
existingErrors.add(verr);
}
}
protected int getNoOfReferences(Class parentCls, XMLComplexElement parent, Class elCls, XMLElement el)
{
int ret = -1;
try
{
Class clsJM = Class.forName("org.enhydra.jawe.JaWEManager");
Method mth = clsJM.getMethod("getInstance", null);
Object jm = mth.invoke(null, null);
mth = clsJM.getMethod("getXPDLUtils", null);
Object xpdlu = mth.invoke(jm, null);
mth = xpdlu.getClass().getMethod("getReferences", new Class[] {
parentCls, elCls
});
List l = (List)mth.invoke(xpdlu, new Object[] {
parent, el
});
ret = l.size();
}
catch(Exception ex) { }
return ret;
}
public void validateElement(FormalParameters el, List existingErrors, boolean fullCheck)
{
validateStandard(el, existingErrors, fullCheck);
}
public void validateElement(Icon el, List existingErrors, boolean fullCheck)
{
validateStandard(el, existingErrors, fullCheck);
}
public void validateElement(Implementation el, List existingErrors, boolean fullCheck)
{
validateStandard(el, existingErrors, fullCheck);
}
public void validateElement(ImplementationTypes el, List existingErrors, boolean fullCheck)
{
validateStandard(el, existingErrors, fullCheck);
}
public void validateElement(InitialValue el, List existingErrors, boolean fullCheck)
{
validateStandard(el, existingErrors, fullCheck);
}
public void validateElement(Join el, List existingErrors, boolean fullCheck)
{
validateStandard(el, existingErrors, fullCheck);
}
public void validateElement(Length el, List existingErrors, boolean fullCheck)
{
validateStandard(el, existingErrors, fullCheck);
}
public void validateElement(Limit el, List existingErrors, boolean fullCheck)
{
validateStandard(el, existingErrors, fullCheck);
}
public void validateElement(ListType el, List existingErrors, boolean fullCheck)
{
validateStandard(el, existingErrors, fullCheck);
}
public void validateElement(Manual el, List existingErrors, boolean fullCheck)
{
validateStandard(el, existingErrors, fullCheck);
}
public void validateElement(Member el, List existingErrors, boolean fullCheck)
{
validateStandard(el, existingErrors, fullCheck);
}
public void validateElement(Namespace el, List existingErrors, boolean fullCheck)
{
validateStandard(el, existingErrors, fullCheck);
}
public void validateElement(Namespaces el, List existingErrors, boolean fullCheck)
{
validateStandard(el, existingErrors, fullCheck);
}
public void validateElement(No el, List existingErrors, boolean fullCheck)
{
validateStandard(el, existingErrors, fullCheck);
}
public void validateElement(Package el, List existingErrors, boolean fullCheck)
{
validateAgainstXPDLSchema(el, existingErrors, fullCheck);
if(existingErrors.size() == 0 || fullCheck)
validateStandard(el, existingErrors, fullCheck);
if(existingErrors.size() == 0 || fullCheck)
checkExternalPackages(el, existingErrors, fullCheck);
}
public void validateElement(PackageHeader el, List existingErrors, boolean fullCheck)
{
validateStandard(el, existingErrors, fullCheck);
}
public void validateElement(Participant el, List existingErrors, boolean fullCheck)
{
validateStandard(el, existingErrors, fullCheck);
}
public void validateElement(Participants el, List existingErrors, boolean fullCheck)
{
validateStandard(el, existingErrors, fullCheck);
}
public void validateElement(ParticipantType el, List existingErrors, boolean fullCheck)
{
validateStandard(el, existingErrors, fullCheck);
}
public void validateElement(Performer el, List existingErrors, boolean fullCheck)
{
String performer = el.toValue();
Activity act = XMLUtil.getActivity(el);
int actType = act.getActivityType();
boolean toolOrNoAct = true;
if(actType != 1 && actType != 2){
toolOrNoAct = false;
}else{
Participant p = XMLUtil.findParticipant(xmlInterface, XMLUtil.getWorkflowProcess(act), performer);
String type = p.getParticipantType().getType();
if(actType == 1 && "SYSTEM".equals(type)){ //activity in system
XMLValidationError verr = new XMLValidationError("ERROR", "LOGIC", "ERROR_ACTIVITY_CANNOT_PLACE_IN_SYSTEM", "", el);
existingErrors.add(verr);
}
}
if(!toolOrNoAct && performer.length() > 0)
{
XMLValidationError verr = new XMLValidationError("WARNING", "LOGIC", "WARNING_ACTIVITY_CANNOT_HAVE_PERFORMER", "", el);
existingErrors.add(verr);
}
if(toolOrNoAct && properties.getProperty("ValidatePerformerExpressions", "false").equals("true"))
{
Participant p = XMLUtil.findParticipant(xmlInterface, XMLUtil.getWorkflowProcess(act), performer);
if(p == null && performer.length() > 0 && !XMLUtil.canBeExpression(performer, XMLUtil.getWorkflowProcess(act).getAllVariables(), true))
{
XMLValidationError verr = new XMLValidationError("WARNING", "LOGIC", "WARNING_PERFORMER_EXPRESSION_POSSIBLY_INVALID", performer, el);
existingErrors.add(verr);
}
}
}
public void validateElement(Priority el, List existingErrors, boolean fullCheck)
{
boolean notInt = false;
try
{
if(el.toValue().trim().length() > 0)
Integer.parseInt(el.toValue());
}
catch(Exception ex)
{
notInt = true;
}
if(notInt)
{
XMLValidationError verr = new XMLValidationError("ERROR", "LOGIC", "ERROR_PRIORITY_INVALID_VALUE", el.toValue(), el);
existingErrors.add(verr);
}
}
public void validateElement(PriorityUnit el, List existingErrors, boolean fullCheck)
{
validateStandard(el, existingErrors, fullCheck);
}
public void validateElement(ProcessHeader el, List existingErrors, boolean fullCheck)
{
validateStandard(el, existingErrors, fullCheck);
}
public void validateElement(RecordType el, List existingErrors, boolean fullCheck)
{
validateStandard(el, existingErrors, fullCheck);
}
public void validateElement(RedefinableHeader el, List existingErrors, boolean fullCheck)
{
validateStandard(el, existingErrors, fullCheck);
}
public void validateElement(Responsible el, List existingErrors, boolean fullCheck)
{
XMLComplexElement pkgOrWp = XMLUtil.getWorkflowProcess(el);
if(pkgOrWp == null)
pkgOrWp = XMLUtil.getPackage(el);
String rv = el.toValue();
Participant p;
if(pkgOrWp instanceof Package)
p = XMLUtil.findParticipant(xmlInterface, (Package)pkgOrWp, rv);
else
p = XMLUtil.findParticipant(xmlInterface, (WorkflowProcess)pkgOrWp, rv);
if(p == null)
{
XMLValidationError verr = new XMLValidationError("ERROR", "LOGIC", "ERROR_NON_EXISTING_PARTICIPANT_REFERENCE", rv, el);
existingErrors.add(verr);
}
}
public void validateElement(Responsibles el, List existingErrors, boolean fullCheck)
{
validateStandard(el, existingErrors, fullCheck);
}
public void validateElement(Route el, List existingErrors, boolean fullCheck)
{
validateStandard(el, existingErrors, fullCheck);
}
public void validateElement(SchemaType el, List existingErrors, boolean fullCheck)
{
validateStandard(el, existingErrors, fullCheck);
}
public void validateElement(Script el, List existingErrors, boolean fullCheck)
{
validateStandard(el, existingErrors, fullCheck);
}
public void validateElement(SimulationInformation el, List existingErrors, boolean fullCheck)
{
validateStandard(el, existingErrors, fullCheck);
}
public void validateElement(Split el, List existingErrors, boolean fullCheck)
{
validateStandard(el, existingErrors, fullCheck);
}
public void validateElement(StartFinishModes el, List existingErrors, boolean fullCheck)
{
validateStandard(el, existingErrors, fullCheck);
}
public void validateElement(StartMode el, List existingErrors, boolean fullCheck)
{
validateStandard(el, existingErrors, fullCheck);
}
public void validateElement(SubFlow el, List existingErrors, boolean fullCheck)
{
validateStandard(el, existingErrors, fullCheck);
if(existingErrors.size() == 0 || fullCheck)
{
WorkflowProcess wp = XMLUtil.findWorkflowProcess(xmlInterface, XMLUtil.getPackage(el), el.getId());
if(wp != null)
{
ActualParameters aps = el.getActualParameters();
checkParameterMatching(wp.getFormalParameters(), aps, existingErrors, properties.getProperty("ValidateActualParameterExpressions", "false").equals("true"), fullCheck);
}
}
}
public void validateElement(TimeEstimation el, List existingErrors, boolean fullCheck)
{
validateStandard(el, existingErrors, fullCheck);
}
public void validateElement(Tool el, List existingErrors, boolean fullCheck)
{
validateStandard(el, existingErrors, fullCheck);
if(existingErrors.size() == 0 || fullCheck)
{
String toolId = el.getId();
WorkflowProcess wp = XMLUtil.getWorkflowProcess(el);
Application app = XMLUtil.findApplication(xmlInterface, wp, toolId);
if(app != null)
{
XMLElement ch = app.getApplicationTypes().getChoosen();
if(ch instanceof FormalParameters)
{
ActualParameters aps = el.getActualParameters();
checkParameterMatching((FormalParameters)ch, aps, existingErrors, properties.getProperty("ValidateActualParameterExpressions", "false").equals("true"), fullCheck);
}
}
}
}
public void validateElement(Tools el, List existingErrors, boolean fullCheck)
{
boolean isValid = existingErrors.size() == 0;
if(el.size() == 0)
{
XMLValidationError verr = new XMLValidationError("ERROR", "LOGIC", "ERROR_NO_TOOLS_DEFINED", "", el);
existingErrors.add(verr);
isValid = false;
}
if(fullCheck || isValid)
validateStandard(el, existingErrors, fullCheck);
}
public void validateElement(Transition el, List existingErrors, boolean fullCheck)
{
validateStandard(el, existingErrors, fullCheck);
}
public void validateElement(TransitionRef el, List existingErrors, boolean fullCheck)
{
validateStandard(el, existingErrors, fullCheck);
}
public void validateElement(TransitionRefs el, List existingErrors, boolean fullCheck)
{
Set outTrans = XMLUtil.getOutgoingTransitions(XMLUtil.getActivity(el));
Split split = (Split)XMLUtil.getParentElement(org.enhydra.shark.xpdl.elements.Split.class, el);
boolean isValid = true;
if(el.size() != outTrans.size() && outTrans.size() > 1 && !split.getType().equals("AND"))
{
isValid = false;
XMLValidationError verr = new XMLValidationError("ERROR", "LOGIC", "ERROR_TRANSITION_REFS_AND_OUTGOING_TRANSITION_NUMBER_MISSMATCH", "", el);
existingErrors.add(verr);
}
if(!fullCheck && !isValid)
{
return;
} else
{
validateStandard(el, existingErrors, fullCheck);
return;
}
}
public void validateElement(TransitionRestriction el, List existingErrors, boolean fullCheck)
{
validateStandard(el, existingErrors, fullCheck);
}
public void validateElement(TransitionRestrictions el, List existingErrors, boolean fullCheck)
{
validateStandard(el, existingErrors, fullCheck);
}
public void validateElement(Transitions el, List existingErrors, boolean fullCheck)
{
validateStandard(el, existingErrors, fullCheck);
if(fullCheck || existingErrors.size() == 0)
{
Map actConns = new HashMap();
Set multipleConnections = new HashSet();
for(int i = 0; i < el.size(); i++)
{
Transition t = (Transition)el.get(i);
String actConn = "[" + t.getFrom() + "-" + t.getTo() + "]";
if(actConns.containsKey(actConn))
{
multipleConnections.add(actConns.get(actConn));
multipleConnections.add(t);
if(!fullCheck)
break;
}
actConns.put(actConn, t);
}
if(multipleConnections.size() > 0)
{
XMLValidationError verr;
for(Iterator it = multipleConnections.iterator(); it.hasNext(); existingErrors.add(verr))
{
Transition t = (Transition)it.next();
String actConn = "[" + t.getFrom() + "-" + t.getTo() + "]";
verr = new XMLValidationError("ERROR", "LOGIC", "ERROR_MULTIPLE_ACTIVITY_CONNECTIONS", actConn, t);
}
}
}
}
public void validateElement(TypeDeclaration el, List existingErrors, boolean fullCheck)
{
validateStandard(el, existingErrors, fullCheck);
}
public void validateElement(TypeDeclarations el, List existingErrors, boolean fullCheck)
{
validateStandard(el, existingErrors, fullCheck);
}
public void validateElement(UnionType el, List existingErrors, boolean fullCheck)
{
validateStandard(el, existingErrors, fullCheck);
}
public void validateElement(ValidFrom el, List existingErrors, boolean fullCheck)
{
validateStandard(el, existingErrors, fullCheck);
}
public void validateElement(ValidTo el, List existingErrors, boolean fullCheck)
{
validateStandard(el, existingErrors, fullCheck);
}
public void validateElement(Vendor el, List existingErrors, boolean fullCheck)
{
validateStandard(el, existingErrors, fullCheck);
}
public void validateElement(Version el, List existingErrors, boolean fullCheck)
{
validateStandard(el, existingErrors, fullCheck);
}
public void validateElement(WaitingTime el, List existingErrors, boolean fullCheck)
{
validateStandard(el, existingErrors, fullCheck);
}
public void validateElement(WorkflowProcess el, List existingErrors, boolean fullCheck)
{
boolean isValid = true;
if(el.getActivities().toElements().size() == 0)
{
isValid = false;
XMLValidationError verr = new XMLValidationError("ERROR", "LOGIC", "ERROR_WORKFLOW_PROCESS_NOT_DEFINED", "", el);
existingErrors.add(verr);
}
if(fullCheck || isValid)
validateStandard(el, existingErrors, fullCheck);
if(isValid || fullCheck)
checkGraphConnectionsForWpOrAs(el, existingErrors, fullCheck);
if(isValid || fullCheck)
checkGraphConformanceForWpOrAs(el, existingErrors, fullCheck);
}
public void validateElement(WorkflowProcesses el, List existingErrors, boolean fullCheck)
{
validateStandard(el, existingErrors, fullCheck);
}
public void validateElement(WorkingTime el, List existingErrors, boolean fullCheck)
{
validateStandard(el, existingErrors, fullCheck);
}
public void validateElement(XPDLVersion el, List existingErrors, boolean fullCheck)
{
if(!el.toValue().equals("1.0"))
{
XMLValidationError verr = new XMLValidationError("ERROR", "LOGIC", "ERROR_INVALID_XPDL_VERSION", el.toValue(), el);
existingErrors.add(verr);
}
}
protected void validateAgainstXPDLSchema(Package pkg, List existingErrors, boolean fullCheck)
{
List schValidationErrors = (List)schemaValidationErrors.get(pkg);
if(schValidationErrors != null && properties.getProperty("GetExistingSchemaValidationErrors", "false").equals("true"))
{
existingErrors.addAll(schValidationErrors);
return;
}
List errorMessages = new ArrayList();
try
{
String encoding = properties.getProperty("Encoding", "UTF-8");
org.w3c.dom.Document document = null;
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder dbuilder = dbf.newDocumentBuilder();
document = dbuilder.newDocument();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
XPDLRepositoryHandler repH = new XPDLRepositoryHandler();
repH.toXML(document, pkg);
TransformerFactory tFactory = TransformerFactory.newInstance();
Transformer transformer = tFactory.newTransformer();
transformer.setOutputProperty("indent", "yes");
transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "4");
transformer.setOutputProperty("encoding", encoding);
DOMSource source = new DOMSource(document);
StreamResult result = new StreamResult(baos);
transformer.transform(source, result);
DOMParser parser = new DOMParser();
try
{
String locale = properties.getProperty("Locale");
Locale l = new Locale("");
if(locale == null || locale.trim().length() == 0)
l = Locale.getDefault();
else
if(!locale.equals("default"))
l = new Locale(locale);
parser.setLocale(l);
parser.setFeature("http://apache.org/xml/features/continue-after-fatal-error", true);
ParsingErrors pErrors = new ParsingErrors();
parser.setErrorHandler(pErrors);
parser.setEntityResolver(new XPDLEntityResolver());
parser.setFeature("http://xml.org/sax/features/validation", true);
parser.setFeature("http://apache.org/xml/features/validation/schema", true);
parser.parse(new InputSource(new StringReader(baos.toString(encoding))));
errorMessages = pErrors.getErrorMessages();
}
catch(Exception ex)
{
ex.printStackTrace();
errorMessages.add("Fatal error while parsing document:" + ex.getMessage());
}
baos.close();
}
catch(Exception ex)
{
ex.printStackTrace();
errorMessages.add("Fatal error while validating schema for package " + pkg.getId() + " :" + ex.getMessage());
}
schValidationErrors = new ArrayList();
if(errorMessages.size() > 0)
{
XMLValidationError verr;
for(Iterator it2 = errorMessages.iterator(); it2.hasNext(); schValidationErrors.add(verr))
{
String msg = (String)it2.next();
verr = new XMLValidationError("ERROR", "SCHEMA", "", msg, pkg);
}
}
existingErrors.addAll(schValidationErrors);
schemaValidationErrors.put(pkg, schValidationErrors);
}
protected void checkExternalPackages(Package pkg, List existingErrors, boolean fullCheck)
{
if(properties.getProperty("CheckExternalPackages", "true").equals("false"))
return;
List epErrors;
for(Iterator it = XMLUtil.getAllExternalPackageIds(xmlInterface, pkg, new HashSet()).iterator(); it.hasNext(); existingErrors.addAll(epErrors))
{
Package p = xmlInterface.getPackageById((String)it.next());
epErrors = (List)epsValidationErrors.get(p);
if(epErrors == null)
epErrors = reCheckExternalPackage(p);
}
}
public List reCheckExternalPackage(Package p)
{
List epErrors = (List)epsValidationErrors.get(p);
if(epErrors != null)
epErrors.clear();
else
epErrors = new ArrayList();
Properties copy = new Properties();
for(Iterator it = properties.entrySet().iterator(); it.hasNext();)
{
java.util.Map.Entry me = (java.util.Map.Entry)it.next();
String key = (String)me.getKey();
String val = (String)me.getValue();
if(key.equals("CheckExternalPackages"))
copy.setProperty("CheckExternalPackages", "false");
else
if(key.equals("GetExistingSchemaValidationErrors"))
copy.setProperty("GetExistingSchemaValidationErrors", "false");
else
copy.setProperty(key, val);
}
StandardPackageValidator pv = createValidatorInstance();
pv.init(copy, xmlInterface);
List l = new ArrayList();
pv.validateElement(p, l, true);
epsValidationErrors.put(p, l);
schemaValidationErrors.remove(p);
return l;
}
protected boolean checkToolId(XMLAttribute tlId, List existingErrors, boolean fullCheck)
{
XMLValidationError verr = null;
String toolId = tlId.toValue();
WorkflowProcess wp = XMLUtil.getWorkflowProcess(tlId);
Application app = XMLUtil.findApplication(xmlInterface, wp, toolId);
if(app == null)
{
verr = new XMLValidationError("ERROR", "LOGIC", "ERROR_NON_EXISTING_APPLICATION_REFERENCE", toolId, tlId);
existingErrors.add(verr);
}
return verr != null;
}
protected boolean checkSubFlowId(XMLAttribute sbflwId, List existingErrors, boolean fullCheck)
{
XMLValidationError verr = null;
String subflowId = sbflwId.toValue();
if(subflowId.trim().equals(""))
verr = new XMLValidationError("ERROR", "LOGIC", "ERROR_NON_EXISTING_WORKFLOW_PROCESS_REFERENCE", subflowId, sbflwId);
Package pkg = XMLUtil.getPackage(sbflwId);
WorkflowProcess wp = null;
if(verr == null)
{
wp = XMLUtil.findWorkflowProcess(xmlInterface, pkg, subflowId);
if(wp == null && !isRemoteSubflowIdOK(subflowId) && properties.getProperty("ValidateSubFlowReferences", "true").equals("true"))
verr = new XMLValidationError("ERROR", "LOGIC", "ERROR_NON_EXISTING_WORKFLOW_PROCESS_REFERENCE", subflowId, sbflwId);
}
if(verr != null)
existingErrors.add(verr);
return verr == null;
}
protected void checkTransitionRefId(XMLAttribute trfId, List existingErrors, boolean fullCheck)
{
Set outTrans = XMLUtil.getOutgoingTransitions(XMLUtil.getActivity(trfId));
String transitionId = trfId.toValue();
if(!containsTransitionWithId(outTrans, transitionId))
{
XMLValidationError verr = new XMLValidationError("ERROR", "LOGIC", "ERROR_NON_EXISTING_TRANSITION_REFERENCE", transitionId, trfId);
existingErrors.add(verr);
}
}
protected boolean containsTransitionWithId(Set trans, String id)
{
for(Iterator it = trans.iterator(); it.hasNext();)
{
Transition t = (Transition)it.next();
if(t.getId().equals(id))
return true;
}
return false;
}
protected boolean isRemoteSubflowIdOK(String subflowId)
{
return false;
}
protected void checkMultipleOtherwiseOrDefaultExceptionTransitions(Activity act, Set outTrans, List existingErrors, boolean fullCheck)
{
boolean foundOtherwise = false;
boolean foundMultipleOtherwise = false;
boolean foundDefaultException = false;
boolean foundMultipleDefaultException = false;
Iterator ts = outTrans.iterator();
do
{
if(!ts.hasNext())
break;
Transition t = (Transition)ts.next();
String ct = t.getCondition().getType();
if(ct.equals("OTHERWISE"))
{
if(foundOtherwise)
{
foundMultipleOtherwise = true;
if(foundMultipleDefaultException || !fullCheck)
break;
} else
{
foundOtherwise = true;
}
continue;
}
if(!ct.equals("DEFAULTEXCEPTION"))
continue;
if(foundDefaultException)
{
foundMultipleDefaultException = true;
if(foundMultipleOtherwise || !fullCheck)
break;
} else
{
foundDefaultException = true;
}
} while(true);
if(foundMultipleOtherwise)
{
XMLValidationError verr = new XMLValidationError("ERROR", "LOGIC", "ERROR_MORE_THAN_ONE_OTHERWISE_TRANSITION", "", act);
existingErrors.add(verr);
}
if(foundMultipleDefaultException)
{
XMLValidationError verr = new XMLValidationError("ERROR", "LOGIC", "ERROR_MORE_THAN_ONE_DEFAULT_EXCEPTION_TRANSITION", "", act);
existingErrors.add(verr);
}
}
protected void checkTransitionFrom(XMLAttribute from, List existingErrors)
{
if(XMLUtil.getFromActivity(XMLUtil.getTransition(from)) == null)
{
XMLValidationError verr = new XMLValidationError("ERROR", "LOGIC", "ERROR_NON_EXISTING_ACTIVITY_REFERENCE", from.toValue(), from);
existingErrors.add(verr);
}
}
protected void checkTransitionTo(XMLAttribute to, List existingErrors)
{
if(XMLUtil.getToActivity(XMLUtil.getTransition(to)) == null)
{
XMLValidationError verr = new XMLValidationError("ERROR", "LOGIC", "ERROR_NON_EXISTING_ACTIVITY_REFERENCE", to.toValue(), to);
existingErrors.add(verr);
}
}
protected void checkDeclaredTypeId(XMLAttribute dtId, List existingErrors)
{
String tdId = dtId.toValue();
TypeDeclaration td = XMLUtil.getPackage(dtId).getTypeDeclaration(tdId);
if(td == null)
{
XMLValidationError verr = new XMLValidationError("ERROR", "LOGIC", "ERROR_NON_EXISTING_TYPE_DECLARATION_REFERENCE", tdId, dtId);
existingErrors.add(verr);
}
}
protected void checkBlockId(XMLAttribute bId, List existingErrors)
{
String blockId = bId.toValue();
ActivitySet as = XMLUtil.getWorkflowProcess(bId).getActivitySet(blockId);
if(as == null)
{
XMLValidationError verr = new XMLValidationError("ERROR", "LOGIC", "ERROR_NON_EXISTING_ACTIVITY_SET_REFERENCE", blockId, bId);
existingErrors.add(verr);
}
}
public static boolean isEmpty(String str)
{
return str == null || str.trim().length() == 0;
}
protected boolean isIdValid(String id)
{
return XMLUtil.isIdValid(id);
}
protected boolean isIdUnique(XMLCollectionElement newEl)
{
XMLElement parent = newEl.getParent();
if((newEl instanceof Tool) || (newEl instanceof TransitionRef))
return true;
if(newEl instanceof Activity)
return checkActivityId((Activity)newEl);
if(newEl instanceof Transition)
return checkTransitionId((Transition)newEl);
if(parent instanceof XMLCollection)
return XMLUtil.cntIds((XMLCollection)parent, newEl.getId()) <= 1;
else
return true;
}
protected boolean checkActivityId(Activity newEl)
{
int idCnt = 0;
WorkflowProcess proc = XMLUtil.getWorkflowProcess(newEl);
String newId = newEl.getId();
Activities acts = proc.getActivities();
idCnt += XMLUtil.cntIds(acts, newId);
ActivitySets actSets = proc.getActivitySets();
for(int y = 0; y < actSets.size(); y++)
{
ActivitySet actSet = (ActivitySet)actSets.get(y);
acts = actSet.getActivities();
idCnt += XMLUtil.cntIds(acts, newId);
}
return idCnt <= 1;
}
protected boolean checkTransitionId(Transition newEl)
{
int idCnt = 0;
WorkflowProcess proc = XMLUtil.getWorkflowProcess(newEl);
String newId = newEl.getId();
Transitions trans = proc.getTransitions();
idCnt += XMLUtil.cntIds(trans, newId);
ActivitySets actSets = proc.getActivitySets();
for(int y = 0; y < actSets.size(); y++)
{
ActivitySet actSet = (ActivitySet)actSets.get(y);
trans = actSet.getTransitions();
idCnt += XMLUtil.cntIds(trans, newId);
}
return idCnt <= 1;
}
public static void printIM(boolean im[][], List acts)
{
if(im != null)
{
for(int i = 0; i < im.length; i++)
{
for(int j = 0; j < im[i].length; j++)
System.out.print(acts.get(i) + "->" + acts.get(j) + "=" + im[i][j] + " ");
System.out.println();
}
} else
{
System.out.println("Passed array is null !!!");
}
}
public static void printIM2(boolean im[][], List acts)
{
System.out.println("Activities are" + acts);
if(im != null)
{
for(int i = 0; i < im.length; i++)
{
for(int j = 0; j < im[i].length; j++)
System.out.print((im[i][j] ? "1" : "0") + " ");
System.out.println();
}
} else
{
System.out.println("Passed array is null !!!");
}
}
protected boolean checkGraphConformanceForWpOrAs(XMLCollectionElement wpOrAs, List existingErrors, boolean fullCheck)
{
Package pkg = XMLUtil.getPackage(wpOrAs);
String conformanceClass = pkg.getConformanceClass().getGraphConformance();
int ct = XMLUtil.getConformanceClassNo(conformanceClass);
Activities acts = (Activities)wpOrAs.get("Activities");
List activities = acts.toElements();
if(activities.size() == 0)
return true;
boolean isGraphConformant = true;
Set splitActs = XMLUtil.getSplitOrJoinActivities(activities, 0);
Set joinActs = XMLUtil.getSplitOrJoinActivities(activities, 1);
Set noSplitActs = new HashSet(activities);
noSplitActs.removeAll(splitActs);
GraphChecker gc = null;
if(ct > 0 && (isGraphConformant || fullCheck))
{
boolean incidenceMatrix[][] = createIncidenceMatrix(acts);
if(incidenceMatrix == null)
{
XMLValidationError verr = new XMLValidationError("ERROR", "CONFORMANCE", "Unexpected error while checking graph conformance!", "", wpOrAs);
existingErrors.add(verr);
return false;
}
gc = new GraphChecker(incidenceMatrix);
boolean loopError = false;
if(fullCheck)
{
int loopNodes[] = gc.getCyclicNodes();
if(loopNodes != null)
{
isGraphConformant = false;
loopError = true;
for(int i = 0; i < loopNodes.length; i++)
{
Activity act = (Activity)activities.get(loopNodes[i]);
XMLValidationError verr = new XMLValidationError("ERROR", "CONFORMANCE", "ERROR_LOOP_CONTAINED_ACTIVITY_IN_LOOP_BLOCKED_MODE", "", act);
existingErrors.add(verr);
}
}
} else
{
loopError = gc.isGraphCyclic();
if(loopError)
{
isGraphConformant = false;
XMLValidationError verr = new XMLValidationError("ERROR", "CONFORMANCE", "ERROR_CYCLIC_GRAPH_IN_LOOP_BLOCKED_MODE", "", wpOrAs);
existingErrors.add(verr);
}
}
}
if(ct == 2 && (isGraphConformant || fullCheck))
{
if(XMLUtil.getStartingActivities(wpOrAs).size() != 1)
{
isGraphConformant = false;
XMLValidationError verr = new XMLValidationError("ERROR", "CONFORMANCE", "ERROR_MULTIPLE_STARTING_ACTIVITIES_IN_FULL_BLOCKED_MODE", "", wpOrAs);
existingErrors.add(verr);
}
if((isGraphConformant || fullCheck) && XMLUtil.getEndingActivities(wpOrAs).size() != 1)
{
isGraphConformant = false;
XMLValidationError verr = new XMLValidationError("ERROR", "CONFORMANCE", "ERROR_MULTIPLE_ENDING_ACTIVITIES_IN_FULL_BLOCKED_MODE", "", wpOrAs);
existingErrors.add(verr);
}
boolean smerr = false;
if((isGraphConformant || fullCheck) && splitActs.size() != joinActs.size())
{
if(splitActs.size() > joinActs.size())
{
XMLValidationError verr = new XMLValidationError("ERROR", "CONFORMANCE", "ERROR_SPLIT_JOIN_MISSMATCH_IN_FULL_BLOCKED_MODE_MORE_SPLITS", "", wpOrAs);
existingErrors.add(verr);
} else
{
XMLValidationError verr = new XMLValidationError("ERROR", "CONFORMANCE", "ERROR_SPLIT_JOIN_MISSMATCH_IN_FULL_BLOCKED_MODE_MORE_JOINS", "", wpOrAs);
existingErrors.add(verr);
}
isGraphConformant = false;
smerr = true;
}
if((isGraphConformant || fullCheck) && !smerr && getNoOfANDSplitsOrJoins(splitActs, 0) != getNoOfANDSplitsOrJoins(joinActs, 1))
{
XMLValidationError verr = new XMLValidationError("ERROR", "CONFORMANCE", "ERROR_SPLIT_JOIN_MISSMATCH_IN_FULL_BLOCKED_MODE_DIFFERENT_TYPES", "", wpOrAs);
existingErrors.add(verr);
isGraphConformant = false;
}
if(isGraphConformant || fullCheck)
{
Iterator it = splitActs.iterator();
label0:
do
{
Activity act;
XMLValidationError verr;
label1:
do
{
label2:
do
{
do
{
if(!it.hasNext())
break label2;
act = (Activity)it.next();
if(!XMLUtil.isANDTypeSplitOrJoin(act, 0))
continue label1;
} while(checkANDSplit(act));
isGraphConformant = false;
verr = new XMLValidationError("ERROR", "CONFORMANCE", "ERROR_CONDITIONAL_TRANSITION_FOR_AND_SPLIT_IN_FULL_BLOCKED_MODE", "", act);
existingErrors.add(verr);
} while(fullCheck);
break label0;
} while(checkXORSplit(act));
isGraphConformant = false;
verr = new XMLValidationError("ERROR", "CONFORMANCE", "ERROR_NO_OTHERWISE_TRANSITION_FOR_XOR_SPLIT_IN_FULL_BLOCKED_MODE", "", act);
existingErrors.add(verr);
} while(fullCheck);
it = noSplitActs.iterator();
label3:
do
{
Activity act;
do
{
if(!it.hasNext())
break label3;
act = (Activity)it.next();
} while(checkXORSplit(act));
isGraphConformant = false;
XMLValidationError verr = new XMLValidationError("ERROR", "CONFORMANCE", "ERROR_NO_OTHERWISE_TRANSITION_FOR_XOR_SPLIT_IN_FULL_BLOCKED_MODE", "", act);
existingErrors.add(verr);
} while(fullCheck);
}
if(isGraphConformant || fullCheck)
{
Iterator it = splitActs.iterator();
label4:
do
{
Activity act;
int ji;
label5:
do
{
label6:
do
{
int splitIndex;
label7:
{
do
{
if(!it.hasNext())
break;
act = (Activity)it.next();
splitIndex = activities.indexOf(act);
if(splitIndex != -1)
break label7;
XMLValidationError verr = new XMLValidationError("ERROR", "CONFORMANCE", "Unexpected error while searching for split/join matching for graph conformance!", "", wpOrAs);
existingErrors.add(verr);
isGraphConformant = false;
} while(fullCheck);
break label6;
}
ji = gc.getJoinIndex(splitIndex);
if(ji >= 0)
continue label5;
isGraphConformant = false;
XMLValidationError verr = new XMLValidationError("ERROR", "CONFORMANCE", "ERROR_NO_CORRESPONDING_JOIN_ACTIVITY_IN_FULL_BLOCKED_MODE", "", act);
existingErrors.add(verr);
} while(fullCheck);
break label4;
} while(XMLUtil.isANDTypeSplitOrJoin(act, 0) == XMLUtil.isANDTypeSplitOrJoin((Activity)activities.get(ji), 1));
isGraphConformant = false;
if(XMLUtil.isANDTypeSplitOrJoin(act, ji))
{
XMLValidationError verr = new XMLValidationError("ERROR", "CONFORMANCE", "ERROR_NO_CORRESPONDING_JOIN_ACTIVITY_TYPE_IN_FULL_BLOCKED_MODE_AND_XOR", "", act);
existingErrors.add(verr);
} else
{
XMLValidationError verr = new XMLValidationError("ERROR", "CONFORMANCE", "ERROR_NO_CORRESPONDING_JOIN_ACTIVITY_TYPE_IN_FULL_BLOCKED_MODE_XOR_AND", "", act);
existingErrors.add(verr);
}
} while(fullCheck);
}
}
return isGraphConformant;
}
protected boolean[][] createIncidenceMatrix(Activities activities)
{
int size = activities.size();
boolean incidenceMatrix[][] = new boolean[size][size];
for(int indAct = 0; indAct < size; indAct++)
{
Activity a = (Activity)activities.get(indAct);
for(Iterator trs = XMLUtil.getOutgoingTransitions(a).iterator(); trs.hasNext();)
{
Transition t = (Transition)trs.next();
String aOut = t.getTo();
Activity toAct = activities.getActivity(aOut);
if(toAct == null)
return (boolean[][])null;
int indOut = activities.indexOf(toAct);
incidenceMatrix[indAct][indOut] = true;
}
}
return incidenceMatrix;
}
protected int getNoOfANDSplitsOrJoins(Set acts, int sOrJ)
{
int no = 0;
Iterator it = acts.iterator();
do
{
if(!it.hasNext())
break;
Activity act = (Activity)it.next();
if(sOrJ == 0 && XMLUtil.isANDTypeSplitOrJoin(act, 0))
no++;
else
if(sOrJ == 1 && XMLUtil.isANDTypeSplitOrJoin(act, 0))
no++;
} while(true);
return no;
}
protected boolean checkANDSplit(Activity act)
{
return !hasAnyPostcondition(act);
}
protected boolean checkXORSplit(Activity act)
{
if(hasAnyPostcondition(act))
{
Set ots = XMLUtil.getOutgoingTransitions(act);
for(Iterator trs = ots.iterator(); trs.hasNext();)
{
Transition t = (Transition)trs.next();
if(t.getCondition().getType().equals("OTHERWISE"))
return true;
}
return false;
} else
{
return true;
}
}
protected boolean hasAnyPostcondition(Activity act)
{
Set outL = XMLUtil.getOutgoingTransitions(act);
for(Iterator it = outL.iterator(); it.hasNext();)
if(!((Transition)it.next()).getCondition().toValue().equals(""))
return true;
return false;
}
protected boolean checkGraphConnectionsForWpOrAs(XMLCollectionElement wpOrAs, List existingErrors, boolean fullCheck)
{
if(wpOrAs == null)
return false;
boolean isWellConnected = true;
Collection acts = ((Activities)wpOrAs.get("Activities")).toElements();
if(acts == null || acts.size() == 0)
return true;
Set startActs = null;
Set endActs = null;
if(fullCheck || isWellConnected)
{
startActs = XMLUtil.getStartingActivities(wpOrAs);
boolean allowUndefinedStart = properties.getProperty("AllowUndefinedStart", "true").equals("true");
if(startActs.size() == 0 && (!allowUndefinedStart || (wpOrAs instanceof ActivitySet)))
{
isWellConnected = false;
XMLValidationError verr = new XMLValidationError("ERROR", "LOGIC", "ERROR_NO_STARTING_ACTIVITY", "", wpOrAs);
existingErrors.add(verr);
}
}
if(fullCheck || isWellConnected)
{
endActs = XMLUtil.getEndingActivities(wpOrAs);
boolean allowUndefinedEnd = properties.getProperty("AllowUndefinedEnd", "true").equals("true");
if(endActs.size() == 0 && (!allowUndefinedEnd || (wpOrAs instanceof ActivitySet)))
{
isWellConnected = false;
XMLValidationError verr = new XMLValidationError("ERROR", "LOGIC", "ERROR_NO_ENDING_ACTIVITY", "", wpOrAs);
existingErrors.add(verr);
}
}
if(fullCheck || isWellConnected)
{
Iterator it = acts.iterator();
label0:
do
{
boolean wc;
do
{
if(!it.hasNext())
break label0;
Activity act = (Activity)it.next();
wc = checkActivityConnection(act, existingErrors, fullCheck);
} while(wc);
isWellConnected = false;
} while(fullCheck);
}
return isWellConnected;
}
protected boolean checkActivityConnection(Activity act, List existingErrors, boolean fullCheck)
{
return true;
}
protected static void checkParameterMatching(FormalParameters fps, ActualParameters aps, List existingErrors, boolean checkExpression, boolean fullCheck)
{
if(fps.size() != aps.size())
{
XMLValidationError verr = new XMLValidationError("ERROR", "LOGIC", "ERROR_FORMAL_AND_ACTUAL_PARAMETERS_NUMBER_MISSMATCH", "", aps);
existingErrors.add(verr);
}
if(!fullCheck && existingErrors.size() != 0)
return;
for(int i = 0; i < fps.size(); i++)
{
FormalParameter fp = (FormalParameter)fps.get(i);
if(aps.size() - 1 < i)
return;
ActualParameter ap = (ActualParameter)aps.get(i);
String fpMode = fp.getMode();
if(fpMode.equals("IN") && !checkExpression)
continue;
DataType fpdt = fp.getDataType();
DataTypes fpdtt = fpdt.getDataTypes();
XMLElement fpType = fpdtt.getChoosen();
Map idToDFOrFP = XMLUtil.getWorkflowProcess(aps).getAllVariables();
String apWRD = ap.toValue();
XMLCollectionElement ce = (XMLCollectionElement)idToDFOrFP.get(apWRD);
if(ce == null)
{
if(!fpMode.equals("IN"))
{
XMLValidationError verr = new XMLValidationError("ERROR", "LOGIC", "ERROR_NON_EXISTING_VARIABLE_REFERENCE", apWRD, ap);
existingErrors.add(verr);
continue;
}
boolean evaluateToString = false;
if(fpType instanceof BasicType)
{
String fpAT = ((BasicType)fpType).getType();
if(fpAT.equals("STRING"))
evaluateToString = true;
}
if(XMLUtil.canBeExpression(apWRD, XMLUtil.getWorkflowProcess(ap).getAllVariables(), evaluateToString) || apWRD.equals("null"))
continue;
if(fpType instanceof BasicType)
{
String fpAT = ((BasicType)fpType).getType();
if(fpAT.equals("INTEGER"))
{
try
{
new Integer(apWRD);
continue;
}
catch(Exception ex) { }
if(apWRD.toLowerCase().indexOf("short") >= 0 || apWRD.toLowerCase().indexOf("integer") >= 0 || apWRD.toLowerCase().indexOf("long") >= 0)
continue;
} else
if(fpAT.equals("FLOAT"))
{
try
{
new Double(apWRD);
continue;
}
catch(Exception ex) { }
if(apWRD.toLowerCase().indexOf("short") >= 0 || apWRD.toLowerCase().indexOf("integer") >= 0 || apWRD.toLowerCase().indexOf("long") >= 0 || apWRD.toLowerCase().indexOf("float") >= 0 || apWRD.toLowerCase().indexOf("double") >= 0)
continue;
} else
if(fpAT.equals("BOOLEAN") && (apWRD.equals("false") || apWRD.equals("true") || apWRD.toLowerCase().indexOf("boolean") >= 0))
continue;
}
XMLValidationError verr = new XMLValidationError("WARNING", "LOGIC", "WARNING_ACTUAL_PARAMETER_EXPRESSION_POSSIBLY_INVALID", apWRD, ap);
existingErrors.add(verr);
continue;
}
XMLElement apType = null;
DataType apdt = (DataType)ce.get("DataType");
DataTypes apdtt = apdt.getDataTypes();
apType = apdtt.getChoosen();
boolean invalidType = false;
if(fpType.getClass().equals(apType.getClass()))
{
if(fpType instanceof BasicType)
{
String fpAT = ((BasicType)fpType).getType();
String apAT = ((BasicType)apType).getType();
if(!fpAT.equals(apAT))
invalidType = true;
} else
if(fpType instanceof EnumerationType)
{
if(((EnumerationType)fpType).size() != ((EnumerationType)apType).size())
{
invalidType = true;
} else
{
for(int j = 0; j < ((EnumerationType)fpType).size(); j++)
{
EnumerationValue evFP = (EnumerationValue)((EnumerationType)fpType).get(j);
EnumerationValue evAP = (EnumerationValue)((EnumerationType)apType).get(j);
if(!evFP.getName().equals(evAP.getName()))
invalidType = true;
}
}
} else
if((fpType instanceof DeclaredType) && !((DeclaredType)fpType).getId().equals(((DeclaredType)apType).getId()))
invalidType = true;
} else
{
invalidType = true;
}
if(invalidType)
{
XMLValidationError verr = new XMLValidationError("ERROR", "LOGIC", "ERROR_INVALID_ACTUAL_PARAMETER_VARIABLE_TYPE", "", ap);
existingErrors.add(verr);
}
}
}
public String prepareMessageString(String msg)
{
if(msg != null)
msg = msg + "; ";
else
msg = "";
return msg;
}
public boolean hasErrors(List l)
{
for(int i = 0; i < l.size(); i++)
{
XMLValidationError verr = (XMLValidationError)l.get(i);
if(verr.getType().equals("ERROR"))
return true;
}
return false;
}
protected StandardPackageValidator createValidatorInstance()
{
return new StandardPackageValidator();
}
public static void main(String args[])
{
try
{
XMLInterfaceForJDK13 xmlI = new XMLInterfaceForJDK13();
Package pkg = xmlI.parseDocument(args[0], true);
StandardPackageValidator validator = new StandardPackageValidator();
validator.init(new Properties(), xmlI);
List verrors = new ArrayList();
validator.validateElement(pkg, verrors, false);
if(verrors.size() > 0)
System.out.println(args[0] + " is a valid XPDL package");
else
System.out.println(args[0] + " is not a valid XPDL package");
}
catch(Exception ex)
{
ex.printStackTrace();
System.exit(1);
}
}
public static final String VALIDATE_SUBFLOW_REFERENCES = "ValidateSubFlowReferences";
public static final String VALIDATE_PERFORMER_EXPRESSIONS = "ValidatePerformerExpressions";
public static final String VALIDATE_ACTUAL_PARAMETER_EXPRESSIONS = "ValidateActualParameterExpressions";
public static final String VALIDATE_DEADLINE_EXPRESSIONS = "ValidateDeadlineExpressions";
public static final String VALIDATE_CONDITION_EXPRESSIONS = "ValidateConditionExpressions";
public static final String VALIDATE_UNUSED_VARIABLES = "ValidateUnusedVariables";
public static final String VALIDATE_CONDITION_BY_TYPE = "ValidateConditionByType";
public static final String GET_EXISTING_SCHEMA_VALIDATION_ERRORS = "GetExistingSchemaValidationErrors";
public static final String CHECK_EXTERNAL_PACKAGES = "CheckExternalPackages";
public static final String ALLOW_UNDEFINED_START = "AllowUndefinedStart";
public static final String ALLOW_UNDEFINED_END = "AllowUndefinedEnd";
public static final String ENCODING = "Encoding";
public static final String LOCALE = "Locale";
protected static final String CURRENT_XPDL_VERSION = "1.0";
protected Properties properties;
protected XMLInterface xmlInterface;
protected Map epsValidationErrors;
protected Map schemaValidationErrors;
protected Properties settings;
}