/*
* Kouretes Statechart Editor-KSE developed
* by Angeliki Topalidou-Kyniazopoulou
* for Kouretes Team. Code developed by Nikolaos Spanoudakis, Alex Parashos,
* ibm, apache and eclipse is used.
*/
package statechart.diagram.providers;
import java.util.StringTokenizer;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.swing.JOptionPane;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.transaction.TransactionalEditingDomain;
import org.eclipse.emf.validation.AbstractModelConstraint;
import org.eclipse.emf.validation.IValidationContext;
import org.eclipse.emf.validation.model.IClientSelector;
import org.eclipse.gmf.runtime.emf.core.util.EMFCoreUtil;
import org.eclipse.gmf.runtime.notation.View;
import statechart.Model;
import statechart.Node;
import statechart.StatechartPackage;
import statechart.Transition;
import statechart.diagram.edit.parts.ModelEditPart;
import statechart.diagram.part.StateChartDiagramEditorPlugin;
import statechart.diagram.part.StateChartVisualIDRegistry;
/**
* @generated
*/
public class StateChartValidationProvider {
/**
* @generated
*/
private static boolean constraintsActive = false;
/**
* @generated
*/
public static boolean shouldConstraintsBePrivate() {
return false;
}
/**
* @generated
*/
public static void runWithConstraints(
TransactionalEditingDomain editingDomain, Runnable operation) {
final Runnable op = operation;
Runnable task = new Runnable() {
public void run() {
try {
constraintsActive = true;
op.run();
} finally {
constraintsActive = false;
}
}
};
if (editingDomain != null) {
try {
editingDomain.runExclusive(task);
} catch (Exception e) {
StateChartDiagramEditorPlugin.getInstance().logError(
"Validation failed", e); //$NON-NLS-1$
}
} else {
task.run();
}
}
/**
* @generated
*/
static boolean isInDefaultEditorContext(Object object) {
if (shouldConstraintsBePrivate() && !constraintsActive) {
return false;
}
if (object instanceof View) {
return constraintsActive
&& ModelEditPart.MODEL_ID.equals(StateChartVisualIDRegistry
.getModelID((View) object));
}
return true;
}
/**
* @generated
*/
public static class DefaultCtx implements IClientSelector {
/**
* @generated
*/
public boolean selects(Object object) {
return isInDefaultEditorContext(object);
}
}
/**
* @generated NOT
*/
// STATECHART RULE: More than one root
public static class Adapter1 extends AbstractModelConstraint {
/**
* @generated NOT
*/
public IStatus validate(IValidationContext ctx) {
Model context = (Model) ctx.getTarget();
if (context.getNodes().size() > 1) {
JOptionPane.showMessageDialog(null,
"Failure Only one root node per model");
System.out.println("Failure Only one root node per model");
return ctx.createFailureStatus(0);
} else
return ctx.createSuccessStatus();
/**
* LIVE VALIDATION
* */
}
}
/**
* @generated NOT
*/
// STATECHART RULE: AND node's children different than OR
public static class Adapter2 extends AbstractModelConstraint {
/**
* @generated NOT
*/
public IStatus validate(IValidationContext ctx) {
Node context = (Node) ctx.getTarget();
if (context.getType().equals("AND")) {
for (int i = 0; i < context.getChildren().size(); i++) {
if (!context.getChildren().get(i).getType().equals("OR")) {
System.out
.println("Failure And Can Have Only Or children");
JOptionPane.showMessageDialog(null,
"Failure And Can Have Only Or children");
return ctx.createFailureStatus(0);
}
}
}
return ctx.createSuccessStatus();
/**
* LIVE VALIDATION
* */
}
}
/**
* @generated NOT
*/
// STATECHART RULE: Transition can't have START as a target
public static class Adapter3 extends AbstractModelConstraint {
/**
* @generated NOT
*/
public IStatus validate(IValidationContext ctx) {
Transition context = (Transition) ctx.getTarget();
if (context.getTarget() != null
&& context.getTarget().getType().equals("START")) {
System.out.println("Failure start can't be target");
//JOptionPane
// .showMessageDialog(
// null,
// context.getTarget().getName()
// + " is a START Node so it shouldn't be target node for a transition");
return ctx.createFailureStatus(1);
} else
return ctx.createSuccessStatus();
}
}
/**
* @generated NOT
*/
// STATECHART RULE: Transition can't have END as a source
public static class Adapter4 extends AbstractModelConstraint {
/**
* @generated NOT
*/
public IStatus validate(IValidationContext ctx) {
Transition context = (Transition) ctx.getTarget();
if (context.getSource() != null
&& context.getSource().getType().equals("END")) {
System.out.println("Failure End can't be source");
// JOptionPane
// .showMessageDialog(
// null,
// context.getTarget().getName()
// + " is a END Node so it shouldn't be source node for a transition");
return ctx.createFailureStatus(1);
} else
return ctx.createSuccessStatus();
}
}
/**
* @generated NOT
*/
// STATECHART RULE: Transition can't have source and target from different father WARNING
public static class Adapter5 extends AbstractModelConstraint {
/**
* @generated NOT
*/
public IStatus validate(IValidationContext ctx) {
Transition context = (Transition) ctx.getTarget();
if (context.getSource() != null && context.getTarget() != null) {
if ((context.getSource().getFather_of() != null
&& context.getTarget().getFather_of() != null && !context
.getSource().getFather_of()
.equals(context.getTarget().getFather_of()))) {
System.out.println("Failure Different Father");
System.out.println("Target: "
+ context.getTarget().getName() + " Father_of: "
+ context.getTarget().getFather_of().getName());
System.out.println("Source: "
+ context.getSource().getName() + " Father_of: "
+ context.getSource().getFather_of().getName());
// JOptionPane
// .showMessageDialog(
// null,
// context.getName()
// + " is a transition between two nodes of a different parent.\nIt is recommended the source and target node of a transition to have the same parent node.");
return ctx.createFailureStatus(0);
} else if (context.getSource().getFather_of() == null
|| context.getTarget().getFather_of() == null) {
System.out.println("Failure No Transition Father");
// JOptionPane
// .showMessageDialog(
// null,
// context.getName()
// + " is a transition between two nodes of a different parent.\nIt is recommended the source and target node of a transition to have the same parent node.");
return ctx.createFailureStatus(0);
}
return ctx.createSuccessStatus();
} else
return ctx.createSuccessStatus();
}
}
/**
* @generated NOT
*/
// STATECHART RULE: An OR node can have only one START node
public static class Adapter6 extends AbstractModelConstraint {
/**
* @generated NOT
*/
public IStatus validate(IValidationContext ctx) {
Node context = (Node) ctx.getTarget();
int count = 0;
for (int i = 0; i < context.getChildren().size(); i++) {
if (context.getType().equals("OR")
&& ((Node) context.getChildren().get(i)).getType()
.equals("START")) {
count++;
}
}
if (count > 1) {
{
JOptionPane
.showMessageDialog(null,
"Failure OR Node Can Have Only one START node as a child");
}
return ctx.createFailureStatus();
} else
return ctx.createSuccessStatus();
/**
* LIVE VALIDATION
* */
}
}
/**
* @generated NOT
*/
// STATECHART RULE: An OR node can have only one END node
public static class Adapter7 extends AbstractModelConstraint {
/**
* @generated NOT
*/
public IStatus validate(IValidationContext ctx) {
Node context = (Node) ctx.getTarget();
int count = 0;
for (int i = 0; i < context.getChildren().size(); i++) {
if (context.getType().equals("OR")
&& ((Node) context.getChildren().get(i)).getType()
.equals("END")) {
count++;
}
}
if (count > 1) {
JOptionPane
.showMessageDialog(null,
"Failure OR Node Can Have Only one END node as a child");
return ctx.createFailureStatus();
} else
return ctx.createSuccessStatus();
/**
* LIVE VALIDATION
* */
}
}
/**
* @generated NOT
*/
// GRAMMAR RULE: Error in Transition's condition
// For Deactivating this rule please set validate 's variable active to false
public static class Adapter8 extends AbstractModelConstraint {
/**
* @generated NOT
*/
public IStatus validate(IValidationContext ctx) {
final Object context = ctx.getTarget().eGet(
StatechartPackage.eINSTANCE.getTransition_TE());
String te = (String) context;
if (context == null) {
return ctx.createSuccessStatus();
}
boolean active = false;
if (active) {
if (te != null) {
if (CheckSyntaxForCondition(te)) {
return ctx.createSuccessStatus();
} else {
JOptionPane.showMessageDialog(
null,
ctx.getTarget().eGet(
StatechartPackage.eINSTANCE
.getTransition_Name())
+ " has a syntax error in condition.");
return ctx.createFailureStatus(0);
}
}
}
return ctx.createSuccessStatus();
}
}
/**
* @generated NOT
*/
// GRAMMAR RULE: Error in Transition's action
// For Deactivating this rule please set validate 's variable active to false
public static class Adapter9 extends AbstractModelConstraint {
/**
* @generated NOT
*/
public IStatus validate(IValidationContext ctx) {
final Object context = ctx.getTarget().eGet(
StatechartPackage.eINSTANCE.getTransition_TE());
if (context == null) {
return Status.OK_STATUS;
}
boolean active = false;
if (active) {
String te = (String) context;
if (te != null) {
if (CheckSyntaxForAction(te))
return ctx.createSuccessStatus();
else {
JOptionPane.showMessageDialog(
null,
ctx.getTarget().eGet(
StatechartPackage.eINSTANCE
.getTransition_Name())
+ " has a syntax error in action.");
return ctx.createFailureStatus(0);
}
}
}
return ctx.createSuccessStatus();
}
}
/**
* @generated NOT
*/
// GRAMMAR RULE: Error in variable type
// For Deactivating this rule please set validate 's variable active to false
public static class Adapter10 extends AbstractModelConstraint {
/**
* @generated NOT
*/
public IStatus validate(IValidationContext ctx) {
final Object context = ctx.getTarget().eGet(
StatechartPackage.eINSTANCE.getVariable_Type());
boolean active = false;
if (context == null) {
return ctx.createFailureStatus(new Object[] { formatElement(ctx
.getTarget()) });
}
if (active) {
String type = (String) context;
Pattern varPattern = Pattern.compile("(\\w+?(\\.\\w+?){2})");
Matcher varMatcher = varPattern.matcher(type);
if (varMatcher.matches()) {
//System.out.println("Success VarType");
return ctx.createSuccessStatus();
} else {
//System.out.println("Failure VarType");
JOptionPane.showMessageDialog(
null,
ctx.getTarget().eGet(
StatechartPackage.eINSTANCE
.getVariable_Name())
+ " has a syntax error in variable type.");
return ctx
.createFailureStatus(new Object[] { formatElement(ctx
.getTarget()) });
}
} else
return ctx.createSuccessStatus();
}
}
/**
* @generated NOT
*/
// Error in variable name, the name has to start with a letter or _
public static class Adapter11 extends AbstractModelConstraint {
/**
* @generated NOT
*/
public IStatus validate(IValidationContext ctx) {
final Object context = ctx.getTarget().eGet(
StatechartPackage.eINSTANCE.getVariable_Name());
if (context == null) {
return ctx.createFailureStatus(new Object[] { formatElement(ctx
.getTarget()) });
}
String name = (String) context;
Pattern varPattern = Pattern.compile("([A-Za-z][\\w]*?)");
Matcher varMatcher = varPattern.matcher(name);
if (varMatcher.matches()) {
//System.out.println("Success VarName");
return ctx.createSuccessStatus();
} else {
//System.out.println("Failure VarName");
JOptionPane.showMessageDialog(
null,
ctx.getTarget().eGet(
StatechartPackage.eINSTANCE.getVariable_Name())
+ " has unacceptable name.");
return ctx.createFailureStatus(new Object[] { formatElement(ctx
.getTarget()) });
}
}
}
/**
* @generated
*/
static String formatElement(EObject object) {
return EMFCoreUtil.getQualifiedName(object, true);
}
/**
* @generated NOT
*/
public static String getEventOfExpression(String expression) {
// pattern for events
Pattern eventPattern = Pattern
.compile("^[\\w\\W&&[^/\\[\\]]]+(\\[[\\w\\W&&[^\\[\\]]]+\\])?(/[\\w\\W]+)?$");
Matcher eventMatcher = eventPattern.matcher(expression);
if (eventMatcher.find()
&& (eventMatcher.group().length() == expression.length())) {
StringTokenizer st = new StringTokenizer(expression, "[]/");
return st.nextToken();
}
return null;
}
/**
* @generated NOT
*/
public static String getConditionOfExpression(String expression) {
// pattern for conditions
Pattern conditionPattern = Pattern
.compile("^([\\w\\W&&[^/\\[\\]]]+)?(\\[[\\w\\W&&[^\\[\\]]]+\\])(/[\\w\\W]+)?$");
Matcher conditionMatcher = conditionPattern.matcher(expression);
if (conditionMatcher.find()
&& (conditionMatcher.group().length() == expression.length())) {
StringTokenizer st = new StringTokenizer(expression, "]");
String condition = st.nextToken();
condition = condition.substring(condition.indexOf("[") + 1);
return condition;
}
return null;
}
/**
* @generated NOT
*/
public static String getActionOfExpression(String expression) {
// pattern for actions
Pattern actionPattern = Pattern
.compile("^([\\w\\W&&[^/\\[\\]]]+)?(\\[[\\w\\W&&[^\\[\\]]]+\\])?(/[\\w\\W]+)$");
Matcher actionMatcher = actionPattern.matcher(expression);
if (actionMatcher.find()
&& (actionMatcher.group().length() == expression.length())) {
String action = expression
.substring(expression.lastIndexOf("/") + 1);
return action;
}
return null;
}
/**
* @generated NOT
*/
public static boolean CheckSyntaxForCondition(String xpr) {
String condExp = getConditionOfExpression(xpr);
if (condExp == null)
return true;
int open = 0, close = 0;
String parenth = new String(condExp);
while (parenth.contains("(")) {
open++;
if (parenth.indexOf("(") < parenth.length() - 1)
parenth = parenth.substring(parenth.indexOf("(") + 1);
}
parenth = new String(condExp);
while (parenth.contains(")")) {
close++;
if (parenth.indexOf(")") < parenth.length() - 1)
parenth = parenth.substring(parenth.indexOf(")") + 1);
}
if (open != close)
return false;
String Comparator = "(([<>]=??)|([!=]=))";
String LogicOperator = "((\\&\\&)|(\\|\\|))";
String NotOperator = "!";
String s = "(\\w+?)";
String var = "((\\w+?(\\.\\w+?){2})(\\.\\w+?\\(\\w*?\\))*?)";
String val = "(" + s + "|(\"" + s + "\"))";
String varVal = "(" + var + "|" + val + ")";
String args = "(((\\s*?)" + varVal + "(\\s*?))(\\,\\s*?" + varVal
+ "\\s*?)*?)";
String function = "((\\w+?(\\:{2})??)+?(\\(+?\\s*?)(" + args
+ ")??(\\s*?)\\)+?)";
String expr = "(" + function + "|" + var + ")";
String extXpr = "(\\(*?(\\s*?)" + NotOperator + "??" + expr
+ "\\)*?)(((\\s*?)" + Comparator + "\\s*?)((\\(*?(\\s*?)"
+ expr + "\\)*?(\\s*?))|(\\(*?(\\s*?)" + val
+ "\\)*?(\\s*?))))??";
String condition = "^(" + extXpr + "){1}(((\\s*?)" + LogicOperator
+ "(\\s*?))(" + extXpr + "))*?$";
Pattern variablePattern = Pattern.compile(condition);
Matcher m = variablePattern.matcher(condExp);
// System.out.println(condExp);
boolean mm = m.matches();
// System.out.println("True or False??? " + mm);
return mm;
}
/**
* @generated NOT
*/
public static boolean CheckSyntaxForAction(String xpr) {
String ActionExp = getActionOfExpression(xpr);
if (ActionExp == null)
return true;
int open = 0, close = 0;
String parenth = new String(ActionExp);
while (parenth.contains("(")) {
open++;
if (parenth.indexOf("(") < parenth.length() - 1)
parenth = parenth.substring(parenth.indexOf("(") + 1);
}
parenth = new String(ActionExp);
while (parenth.contains(")")) {
close++;
if (parenth.indexOf(")") < parenth.length() - 1)
parenth = parenth.substring(parenth.indexOf(")") + 1);
}
if (open != close)
return false;
String connectiveOp = "\\;";
String timeout = "(TimeoutAction\\.\\w+\\.\\d+)";
String action = "((process_messages)|(publish_all)|((publish)((\\.\\w+?){3})(\\.\\w+?\\(\\w*?\\))+?))";
String oneAction = "(" + action + "|" + timeout + ")";
String actions = "((\\s*?)" + oneAction + "(\\s*?)(" + connectiveOp
+ "(\\s*?)" + action + "(\\s*?))*?)";
Pattern variablePattern = Pattern.compile(actions);
Matcher m = variablePattern.matcher(ActionExp);
// System.out.println(ActionExp);
boolean mm = m.matches();
//System.out.println("True or False??? " + mm);
return mm;
}
}