https://bugs.eclipse.org/bugs/show_bug.cgi?id=378094
updated validation constraints, moved some to jbpm plugin
decorators updating correctly (more or less)
added decorators to Property page fields.
diff --git a/org.eclipse.bpmn2.modeler.core/plugin.xml b/org.eclipse.bpmn2.modeler.core/plugin.xml
index 8791aad..5e90515 100644
--- a/org.eclipse.bpmn2.modeler.core/plugin.xml
+++ b/org.eclipse.bpmn2.modeler.core/plugin.xml
@@ -88,28 +88,33 @@
</constraint>
<constraint
class="org.eclipse.bpmn2.modeler.core.validation.BPMN2BatchValidationConstraint"
- id="org.eclipse.bpmn2.modeler.core.validation.basic"
+ id="org.eclipse.bpmn2.modeler.core.validation.error"
isEnabledByDefault="true"
lang="Java"
mode="Batch"
- name="Basic Diagram Validation"
+ name="Errors"
severity="ERROR"
statusCode="1">
- <message>
- {0}
- </message>
- <description>
- General Error
- </description>
- <target
- class="BPMNDiagram">
- </target>
- <target
- class="Definitions">
- </target>
- <target
- class="BaseElement">
- </target>
+ <message>{0}</message>
+ <description>Diagram Validation Errors</description>
+ <target class="BPMNDiagram"/>
+ <target class="Definitions"/>
+ <target class="BaseElement"/>
+ </constraint>
+ <constraint
+ class="org.eclipse.bpmn2.modeler.core.validation.BPMN2BatchValidationConstraint"
+ id="org.eclipse.bpmn2.modeler.core.validation.warning"
+ isEnabledByDefault="true"
+ lang="Java"
+ mode="Batch"
+ name="Warnings"
+ severity="WARNING"
+ statusCode="1">
+ <message>{0}</message>
+ <description>Diagram Validation Warnings</description>
+ <target class="BPMNDiagram"/>
+ <target class="Definitions"/>
+ <target class="BaseElement"/>
</constraint>
</constraints>
diff --git a/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/merrimac/clad/AbstractBpmn2PropertySection.java b/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/merrimac/clad/AbstractBpmn2PropertySection.java
index fad1fb9..ca4911a 100644
--- a/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/merrimac/clad/AbstractBpmn2PropertySection.java
+++ b/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/merrimac/clad/AbstractBpmn2PropertySection.java
@@ -219,6 +219,7 @@
if (parent.isLayoutDeferred())
parent.setLayoutDeferred(false);
}
+ sectionRoot.refresh();
}
}
}
diff --git a/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/merrimac/clad/AbstractDetailComposite.java b/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/merrimac/clad/AbstractDetailComposite.java
index 61675c2..7d63f06 100644
--- a/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/merrimac/clad/AbstractDetailComposite.java
+++ b/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/merrimac/clad/AbstractDetailComposite.java
@@ -14,10 +14,13 @@
package org.eclipse.bpmn2.modeler.core.merrimac.clad;
import java.math.BigInteger;
+import java.util.ArrayList;
import java.util.List;
import java.util.Stack;
+import org.eclipse.bpmn2.Bpmn2Package;
import org.eclipse.bpmn2.modeler.core.adapters.InsertionAdapter;
+import org.eclipse.bpmn2.modeler.core.merrimac.IConstants;
import org.eclipse.bpmn2.modeler.core.merrimac.dialogs.BooleanObjectEditor;
import org.eclipse.bpmn2.modeler.core.merrimac.dialogs.ComboObjectEditor;
import org.eclipse.bpmn2.modeler.core.merrimac.dialogs.FeatureListObjectEditor;
@@ -26,16 +29,21 @@
import org.eclipse.bpmn2.modeler.core.merrimac.dialogs.ReadonlyTextObjectEditor;
import org.eclipse.bpmn2.modeler.core.merrimac.dialogs.TextObjectEditor;
import org.eclipse.bpmn2.modeler.core.utils.ModelUtil;
+import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.ecore.EAttribute;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.emf.ecore.EStructuralFeature;
+import org.eclipse.emf.ecore.EcorePackage;
+import org.eclipse.emf.ecore.InternalEObject;
+import org.eclipse.emf.ecore.impl.ENotificationImpl;
import org.eclipse.emf.ecore.util.BasicFeatureMap;
import org.eclipse.emf.ecore.util.EObjectContainmentEList;
import org.eclipse.emf.ecore.util.FeatureMap;
import org.eclipse.emf.ecore.util.FeatureMap.Entry;
+import org.eclipse.emf.edit.provider.INotifyChangedListener;
import org.eclipse.emf.transaction.ResourceSetListener;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.StyledText;
@@ -44,13 +52,14 @@
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;
import org.eclipse.ui.forms.events.ExpansionEvent;
import org.eclipse.ui.forms.events.IExpansionListener;
import org.eclipse.ui.forms.widgets.ExpandableComposite;
import org.eclipse.ui.forms.widgets.Section;
-
+import org.eclipse.emf.ecore.impl.ENotificationImpl;
/**
* This is a base class for all Property Sheet Sections. The Composite is used to render
@@ -592,4 +601,30 @@
return objectStack.size();
}
}
+
+ public void refresh() {
+ Display.getDefault().asyncExec( new Runnable() {
+ public void run() {
+ List<Control>kids = new ArrayList<Control>();
+ Composite parent = AbstractDetailComposite.this;
+ try {
+ AbstractBpmn2PropertySection section = AbstractDetailComposite.this.getPropertySection();
+ if (section!=null && section.getTabbedPropertySheetPage()!=null) {
+ parent = (Composite)section.getTabbedPropertySheetPage().getControl();
+ }
+ }
+ catch (Exception e) {
+ }
+ Notification n = new ENotificationImpl(null, Notification.SET, -1, 0, 0);
+ getAllChildWidgets(parent, kids);
+ for (Control c : kids) {
+ INotifyChangedListener listener = (INotifyChangedListener)c.getData(
+ IConstants.NOTIFY_CHANGE_LISTENER_KEY);
+ if (listener!=null) {
+ listener.notifyChanged(n);
+ }
+ }
+ }
+ });
+ }
}
\ No newline at end of file
diff --git a/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/merrimac/clad/ListAndDetailCompositeBase.java b/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/merrimac/clad/ListAndDetailCompositeBase.java
index 9822e84..740bc49 100644
--- a/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/merrimac/clad/ListAndDetailCompositeBase.java
+++ b/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/merrimac/clad/ListAndDetailCompositeBase.java
@@ -236,7 +236,7 @@
return null;
}
- private void getAllChildWidgets(Composite parent, List<Control>kids) {
+ protected void getAllChildWidgets(Composite parent, List<Control>kids) {
if (parent!=null && !parent.isDisposed()) {
Control[] cs = parent.getChildren();
for (Control c : cs) {
diff --git a/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/merrimac/dialogs/BooleanObjectEditor.java b/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/merrimac/dialogs/BooleanObjectEditor.java
index 6eabfa1..bfcaf60 100644
--- a/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/merrimac/dialogs/BooleanObjectEditor.java
+++ b/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/merrimac/dialogs/BooleanObjectEditor.java
@@ -102,6 +102,7 @@
@Override
public void notifyChanged(Notification notification) {
+ super.notifyChanged(notification);
if (this.object == notification.getNotifier() &&
this.feature == notification.getFeature()) {
button.setSelection((Boolean) object.eGet(feature));
diff --git a/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/merrimac/dialogs/ComboObjectEditor.java b/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/merrimac/dialogs/ComboObjectEditor.java
index c4e17d7..9e05de9 100644
--- a/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/merrimac/dialogs/ComboObjectEditor.java
+++ b/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/merrimac/dialogs/ComboObjectEditor.java
@@ -297,6 +297,7 @@
@Override
public void notifyChanged(Notification notification) {
+ super.notifyChanged(notification);
for (String item : comboViewer.getCombo().getItems()) {
Object o = comboViewer.getData(item);
if (o == notification.getNotifier()) {
diff --git a/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/merrimac/dialogs/FeatureListObjectEditor.java b/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/merrimac/dialogs/FeatureListObjectEditor.java
index b33f10c..93777c0 100644
--- a/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/merrimac/dialogs/FeatureListObjectEditor.java
+++ b/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/merrimac/dialogs/FeatureListObjectEditor.java
@@ -174,6 +174,7 @@
public void notifyChanged(Notification notification) {
if (this.object == notification.getNotifier() &&
this.feature == notification.getFeature()) {
+ super.notifyChanged(notification);
updateTextField();
}
}
diff --git a/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/merrimac/dialogs/IntObjectEditor.java b/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/merrimac/dialogs/IntObjectEditor.java
index 2a7f4fe..64b86d4 100644
--- a/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/merrimac/dialogs/IntObjectEditor.java
+++ b/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/merrimac/dialogs/IntObjectEditor.java
@@ -152,6 +152,7 @@
@Override
public void notifyChanged(Notification notification) {
+ super.notifyChanged(notification);
if (this.object == notification.getNotifier() &&
this.feature == notification.getFeature()) {
updateText();
diff --git a/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/merrimac/dialogs/ObjectEditingDialog.java b/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/merrimac/dialogs/ObjectEditingDialog.java
index 8baac6b..19b5e75 100644
--- a/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/merrimac/dialogs/ObjectEditingDialog.java
+++ b/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/merrimac/dialogs/ObjectEditingDialog.java
@@ -99,6 +99,8 @@
data.right = new FormAttachment(100, 0);
dialogContent.setLayoutData(data);
+ getShell().setSize(600,400);
+
form.setContent(body);
}
diff --git a/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/merrimac/dialogs/ObjectEditor.java b/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/merrimac/dialogs/ObjectEditor.java
index f2ce7cf..09f1318 100644
--- a/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/merrimac/dialogs/ObjectEditor.java
+++ b/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/merrimac/dialogs/ObjectEditor.java
@@ -13,21 +13,33 @@
package org.eclipse.bpmn2.modeler.core.merrimac.dialogs;
+import org.eclipse.bpmn2.modeler.core.Activator;
import org.eclipse.bpmn2.modeler.core.merrimac.IConstants;
import org.eclipse.bpmn2.modeler.core.merrimac.clad.AbstractDetailComposite;
import org.eclipse.bpmn2.modeler.core.utils.ErrorUtils;
import org.eclipse.bpmn2.modeler.core.utils.ModelUtil;
+import org.eclipse.bpmn2.modeler.core.validation.ValidationStatusAdapter;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EStructuralFeature;
+import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.emf.edit.provider.INotifyChangedListener;
import org.eclipse.emf.transaction.TransactionalEditingDomain;
+import org.eclipse.emf.validation.model.ConstraintStatus;
import org.eclipse.graphiti.mm.pictograms.Diagram;
+import org.eclipse.graphiti.platform.IPlatformImageConstants;
+import org.eclipse.graphiti.tb.ImageDecorator;
import org.eclipse.graphiti.ui.editor.DiagramEditor;
+import org.eclipse.jface.fieldassist.ControlDecoration;
import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Label;
+import org.eclipse.ui.ISharedImages;
+import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.forms.widgets.FormToolkit;
/**
@@ -43,6 +55,7 @@
protected EStructuralFeature feature;
protected AbstractDetailComposite parent;
private Label label;
+ protected ControlDecoration decoration;
protected int style;
public ObjectEditor(AbstractDetailComposite parent, EObject object, EStructuralFeature feature, int style) {
@@ -102,6 +115,8 @@
protected Label createLabel(Composite parent, String name) {
label = getToolkit().createLabel(parent, name);
label.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1));
+ decoration = new ControlDecoration(label, SWT.TOP | SWT.LEFT);
+ updateLabelDecorator();
return label;
}
@@ -109,6 +124,67 @@
return label;
}
+ private boolean statusApplies(IStatus status) {
+ if (status instanceof ConstraintStatus) {
+ ConstraintStatus cs = (ConstraintStatus)status;
+ for (EObject f : cs.getResultLocus()) {
+ if (f instanceof EStructuralFeature && f==this.feature) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ protected void updateLabelDecorator() {
+ boolean applies = false;
+ String image = null;
+ String text = null;
+ ValidationStatusAdapter statusAdapter = (ValidationStatusAdapter) EcoreUtil.getRegisteredAdapter(
+ object, ValidationStatusAdapter.class);
+ if (statusAdapter != null) {
+ final IStatus status = statusAdapter.getValidationStatus();
+ if (status.isMultiStatus()) {
+ for (IStatus s : status.getChildren()) {
+ if (statusApplies(s)) {
+ applies = true;
+ break;
+ }
+ }
+ }
+ else if (statusApplies(status))
+ applies = true;
+
+ if (applies) {
+ text = status.getMessage();
+ switch (status.getSeverity()) {
+ case IStatus.INFO:
+ image = ISharedImages.IMG_OBJS_INFO_TSK;
+ break;
+ case IStatus.WARNING:
+ image = ISharedImages.IMG_DEC_FIELD_WARNING;
+ break;
+ case IStatus.ERROR:
+ image = ISharedImages.IMG_DEC_FIELD_ERROR;
+ break;
+ default:
+ break;
+ }
+ }
+ }
+
+ if (applies) {
+ decoration.setImage(PlatformUI.getWorkbench().getSharedImages().getImage(image));
+ decoration.show();
+ decoration.setDescriptionText(text);
+ }
+ else {
+ decoration.setImage(null);
+ decoration.setDescriptionText(null);
+ decoration.hide();
+ }
+ }
+
protected boolean updateObject(final Object result) {
TransactionalEditingDomain domain = getDiagramEditor().getEditingDomain();
boolean success = ModelUtil.setValue(domain, object, feature, result);
@@ -119,6 +195,12 @@
" with value '"+ModelUtil.getDisplayName(result)+"'");
return false;
}
+ updateLabelDecorator();
return true;
}
+
+ @Override
+ public void notifyChanged(Notification notification) {
+ updateLabelDecorator();
+ }
}
diff --git a/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/merrimac/dialogs/TextObjectEditor.java b/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/merrimac/dialogs/TextObjectEditor.java
index 5bf4263..36204c4 100644
--- a/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/merrimac/dialogs/TextObjectEditor.java
+++ b/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/merrimac/dialogs/TextObjectEditor.java
@@ -158,6 +158,7 @@
@Override
public void notifyChanged(Notification notification) {
+ super.notifyChanged(notification);
if (this.object == notification.getNotifier() &&
this.feature == notification.getFeature()) {
updateText();
diff --git a/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/utils/ModelUtil.java b/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/utils/ModelUtil.java
index c043056..e313fb6 100644
--- a/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/utils/ModelUtil.java
+++ b/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/utils/ModelUtil.java
@@ -549,6 +549,43 @@
return list;
}
+ public static EStructuralFeature getAnyAttribute(EObject object, String name) {
+ EStructuralFeature anyAttribute = ((EObject)object).eClass().getEStructuralFeature("anyAttribute");
+ if (anyAttribute!=null && object.eGet(anyAttribute) instanceof BasicFeatureMap) {
+ BasicFeatureMap map = (BasicFeatureMap)object.eGet(anyAttribute);
+ for (Entry entry : map) {
+ EStructuralFeature feature = entry.getEStructuralFeature();
+ if (feature.getName().equals(name))
+ return feature;
+ }
+ }
+ return null;
+ }
+
+ @SuppressWarnings("unchecked")
+ public static EStructuralFeature addAnyAttribute(EObject childObject, String name, Object value) {
+ return addAnyAttribute(childObject, childObject.eClass().getEPackage().getNsURI(), name, value);
+ }
+
+ @SuppressWarnings("unchecked")
+ public static EStructuralFeature addAnyAttribute(EObject childObject, String namespace, String name, Object value) {
+ EStructuralFeature anyAttribute = childObject.eClass().getEStructuralFeature(Bpmn2Package.BASE_ELEMENT__ANY_ATTRIBUTE);
+ List<BasicFeatureMap.Entry> anyMap = (List<BasicFeatureMap.Entry>)childObject.eGet(anyAttribute);
+ for (BasicFeatureMap.Entry fe : anyMap) {
+ if (fe.getEStructuralFeature() instanceof EAttributeImpl) {
+ EAttributeImpl a = (EAttributeImpl) fe.getEStructuralFeature();
+ if (namespace.equals(a.getExtendedMetaData().getNamespace()) && name.equals(a.getName())) {
+ return a;
+ }
+ }
+ }
+
+ // this featuremap can only hold attributes, not elements
+ EStructuralFeature attr = ExtendedMetaData.INSTANCE.demandFeature(namespace, name, false);
+ anyMap.add( FeatureMapUtil.createEntry(attr, value) );
+ return attr;
+ }
+
public static EAttribute createDynamicAttribute(EPackage pkg, EObject object, String name, String type) {
EClass docRoot = ExtendedMetaData.INSTANCE.getDocumentRoot(pkg);
for (EStructuralFeature f : docRoot.getEStructuralFeatures()) {
@@ -594,25 +631,6 @@
return ref;
}
- @SuppressWarnings("unchecked")
- public static EStructuralFeature addAnyAttribute(EObject childObject, String namespace, String name, Object value) {
- EStructuralFeature anyAttribute = childObject.eClass().getEStructuralFeature(Bpmn2Package.BASE_ELEMENT__ANY_ATTRIBUTE);
- List<BasicFeatureMap.Entry> anyMap = (List<BasicFeatureMap.Entry>)childObject.eGet(anyAttribute);
- for (BasicFeatureMap.Entry fe : anyMap) {
- if (fe.getEStructuralFeature() instanceof EAttributeImpl) {
- EAttributeImpl a = (EAttributeImpl) fe.getEStructuralFeature();
- if (namespace.equals(a.getExtendedMetaData().getNamespace()) && name.equals(a.getName())) {
- return a;
- }
- }
- }
-
- // this featuremap can only hold attributes, not elements
- EStructuralFeature attr = ExtendedMetaData.INSTANCE.demandFeature(namespace, name, false);
- anyMap.add( FeatureMapUtil.createEntry(attr, value) );
- return attr;
- }
-
public static EObject createStringWrapper(String value) {
DynamicEObjectImpl de = new DynamicEObjectImpl();
de.eSetClass(EcorePackage.eINSTANCE.getEObject());
@@ -979,7 +997,7 @@
InsertionAdapter.executeIfNeeded((EObject)value);
}
- if (isEmpty(value)){
+ if (value==null){ // DO NOT use isEmpty() because this erases an object's anyAttribute feature!
domain.getCommandStack().execute(new RecordingCommand(domain) {
@Override
protected void doExecute() {
diff --git a/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/validation/BPMN2BatchValidationConstraint.java b/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/validation/BPMN2BatchValidationConstraint.java
index 0329a1b..9b20a6f 100644
--- a/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/validation/BPMN2BatchValidationConstraint.java
+++ b/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/validation/BPMN2BatchValidationConstraint.java
@@ -1,13 +1,10 @@
package org.eclipse.bpmn2.modeler.core.validation;
-import java.util.ArrayList;
-import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
-import java.util.Map;
-import org.eclipse.bpmn2.AdHocSubProcess;
import org.eclipse.bpmn2.BaseElement;
+import org.eclipse.bpmn2.Bpmn2Package;
import org.eclipse.bpmn2.BusinessRuleTask;
import org.eclipse.bpmn2.CallActivity;
import org.eclipse.bpmn2.CatchEvent;
@@ -16,6 +13,13 @@
import org.eclipse.bpmn2.ConditionalEventDefinition;
import org.eclipse.bpmn2.DataObject;
import org.eclipse.bpmn2.Definitions;
+import org.eclipse.bpmn2.Error;
+import org.eclipse.bpmn2.Escalation;
+import org.eclipse.bpmn2.ItemDefinition;
+import org.eclipse.bpmn2.Message;
+import org.eclipse.bpmn2.Resource;
+import org.eclipse.bpmn2.Signal;
+import org.eclipse.bpmn2.DataStore;
import org.eclipse.bpmn2.EndEvent;
import org.eclipse.bpmn2.ErrorEventDefinition;
import org.eclipse.bpmn2.EscalationEventDefinition;
@@ -24,7 +28,6 @@
import org.eclipse.bpmn2.ExclusiveGateway;
import org.eclipse.bpmn2.ExtensionAttributeValue;
import org.eclipse.bpmn2.FlowElement;
-import org.eclipse.bpmn2.FlowElementsContainer;
import org.eclipse.bpmn2.FlowNode;
import org.eclipse.bpmn2.FormalExpression;
import org.eclipse.bpmn2.Gateway;
@@ -32,7 +35,6 @@
import org.eclipse.bpmn2.InclusiveGateway;
import org.eclipse.bpmn2.MessageEventDefinition;
import org.eclipse.bpmn2.ParallelGateway;
-import org.eclipse.bpmn2.Property;
import org.eclipse.bpmn2.Process;
import org.eclipse.bpmn2.RootElement;
import org.eclipse.bpmn2.ScriptTask;
@@ -40,16 +42,12 @@
import org.eclipse.bpmn2.SequenceFlow;
import org.eclipse.bpmn2.SignalEventDefinition;
import org.eclipse.bpmn2.StartEvent;
-import org.eclipse.bpmn2.SubProcess;
import org.eclipse.bpmn2.Task;
import org.eclipse.bpmn2.ThrowEvent;
import org.eclipse.bpmn2.TimerEventDefinition;
import org.eclipse.bpmn2.UserTask;
import org.eclipse.bpmn2.di.BPMNDiagram;
-import org.eclipse.bpmn2.modeler.core.Activator;
import org.eclipse.core.runtime.IStatus;
-import org.eclipse.core.runtime.MultiStatus;
-import org.eclipse.core.runtime.Status;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.util.FeatureMap;
import org.eclipse.emf.validation.AbstractModelConstraint;
@@ -58,19 +56,24 @@
public class BPMN2BatchValidationConstraint extends AbstractModelConstraint {
- List<IStatus> errorList = new ArrayList<IStatus>();
- IValidationContext context;
-
+ public final static String ERROR_ID = "org.eclipse.bpmn2.modeler.core.validation.error";
+ public final static String WARNING_ID = "org.eclipse.bpmn2.modeler.core.validation.warning";
+
+ private boolean warnings = false;
+
public BPMN2BatchValidationConstraint() {
}
@Override
public IStatus validate(IValidationContext ctx) {
- this.context = ctx;
EObject eObj = ctx.getTarget();
EMFEventType eType = ctx.getEventType();
- errorList.clear();
-
+ String id = ctx.getCurrentConstraintId();
+ if (WARNING_ID.equals(id))
+ warnings = true;
+ else
+ warnings = false;
+
// In the case of batch mode.
if (eType == EMFEventType.NULL) {
if (eObj instanceof BPMNDiagram) {
@@ -83,7 +86,6 @@
return validateBaseElement(ctx, (BaseElement) eObj);
}
} else { // In the case of live mode.
- System.err.println("Live: " + getClass().getSimpleName() + ": " + eObj + ": " + ctx.getFeatureNewValue());
}
return ctx.createSuccessStatus();
@@ -99,56 +101,75 @@
for (RootElement root : rootElements) {
if (root instanceof Process) {
Process process = (Process) root;
- if (process.getFlowElements() != null && process.getFlowElements().size() > 0) {
- process.getFlowElements().get(0).getId();
- }
- if (isEmpty(process.getId())) {
- return ctx.createFailureStatus("Process has no id.");
- } else {
- if (!SyntaxCheckerUtils.isNCName(process.getId())) {
- return ctx.createFailureStatus(
- "Invalid process id. See http://www.w3.org/TR/REC-xml-names/#NT-NCName for more info.");
- }
- }
-
- String pname = null;
- Iterator<FeatureMap.Entry> iter = process.getAnyAttribute().iterator();
- boolean foundPackageName = false;
- while (iter.hasNext()) {
- FeatureMap.Entry entry = iter.next();
- if (entry.getEStructuralFeature().getName().equals("packageName")) {
- foundPackageName = true;
- pname = (String) entry.getValue();
- if (isEmpty(pname)) {
- return ctx.createFailureStatus("Process has no package name.");
+ if (warnings) {
+ // report warnings only
+ boolean foundStartEvent = false;
+ boolean foundEndEvent = false;
+ List<FlowElement> flowElements = process.getFlowElements();
+ for (FlowElement fe : flowElements) {
+ if (fe instanceof StartEvent) {
+ foundStartEvent = true;
+ }
+ if (fe instanceof EndEvent) {
+ foundEndEvent = true;
}
}
- }
- if (!foundPackageName) {
- return ctx.createFailureStatus("Process has no package name.");
- }
-
- if (isEmpty(process.getName())) {
- return ctx.createFailureStatus("Process has no name.");
- }
-
- boolean foundStartEvent = false;
- boolean foundEndEvent = false;
- List<FlowElement> flowElements = process.getFlowElements();
- for (FlowElement fe : flowElements) {
- if (fe instanceof StartEvent) {
- foundStartEvent = true;
+ if (!foundStartEvent) {
+ ctx.addResult(root);
+ return ctx.createFailureStatus("Process has no Start Event");
}
- if (fe instanceof EndEvent) {
- foundEndEvent = true;
+ if (!foundEndEvent) {
+ ctx.addResult(root);
+ return ctx.createFailureStatus("Process has no End Event");
}
}
- if (!foundStartEvent) {
- return ctx.createFailureStatus("Process has no Start node.");
+ else {
+ // report errors only
+ if (isEmpty(process.getName())) {
+ ctx.addResult(root);
+ return ctx.createFailureStatus("Process has no name");
+ }
}
- if (!foundEndEvent) {
- return ctx.createFailureStatus("Process has no End node.");
+ }
+ else if (root instanceof Error) {
+ if (warnings) {
+ if (((Error)root).getStructureRef()==null) {
+ ctx.addResult(root);
+ return ctx.createFailureStatus("Error has no type definition");
+ }
+ }
+ }
+ else if (root instanceof Escalation) {
+ if (warnings) {
+ if (((Escalation)root).getStructureRef()==null) {
+ ctx.addResult(root);
+ return ctx.createFailureStatus("Escalation has no type definition");
+ }
+ }
+ }
+ else if (root instanceof Message) {
+ if (warnings) {
+ if (((Message)root).getItemRef()==null) {
+ ctx.addResult(root);
+ return ctx.createFailureStatus("Message has no type definition");
+ }
+ }
+ }
+ else if (root instanceof Signal) {
+ if (warnings) {
+ if (((Signal)root).getStructureRef()==null) {
+ ctx.addResult(root);
+ return ctx.createFailureStatus("Signal has no type definition");
+ }
+ }
+ }
+ else if (root instanceof ItemDefinition) {
+ if (!warnings) {
+ if (((ItemDefinition)root).getStructureRef()==null) {
+ ctx.addResult(root);
+ return ctx.createFailureStatus("Item Definition has no structure");
+ }
}
}
}
@@ -159,301 +180,258 @@
if (fe instanceof StartEvent) {
StartEvent se = (StartEvent) fe;
- if (se.getOutgoing() == null || se.getOutgoing().size() < 1) {
- return ctx.createFailureStatus("Start node has no outgoing connections");
+
+ if (!warnings) {
+ if (se.getOutgoing() == null || se.getOutgoing().size() < 1) {
+ return ctx.createFailureStatus("Start Event has no outgoing connections");
+ }
}
- } else if (fe instanceof EndEvent) {
+ }
+ else if (fe instanceof EndEvent) {
EndEvent ee = (EndEvent) fe;
- if (ee.getIncoming() == null || ee.getIncoming().size() < 1) {
- return ctx.createFailureStatus("End node has no incoming connections");
+
+ if (!warnings) {
+ if (ee.getIncoming() == null || ee.getIncoming().size() < 1) {
+ return ctx.createFailureStatus("End Event has no incoming connections");
+ }
}
- } else {
- if (fe instanceof FlowNode) {
- FlowNode fn = (FlowNode) fe;
+ }
+ else if (fe instanceof ScriptTask) {
+ ScriptTask st = (ScriptTask) fe;
+
+ if (warnings) {
+ if (isEmpty(st.getScript())) {
+ return ctx.createFailureStatus("Script Task has no script");
+ }
+ if (isEmpty(st.getScriptFormat())) {
+ return ctx.createFailureStatus("Script Task has no script format");
+ }
+ }
+ }
+ else if (fe instanceof SendTask) {
+ SendTask st = (SendTask) fe;
+
+ if (!warnings) {
+ if (st.getOperationRef() == null) {
+ return ctx.createFailureStatus("Send Task has no operation");
+ }
+ if (st.getMessageRef() == null) {
+ return ctx.createFailureStatus("Send Task has no message");
+ }
+ }
+ }
+ else if (fe instanceof CatchEvent) {
+ CatchEvent event = (CatchEvent) fe;
+
+ if (!warnings) {
+ List<EventDefinition> eventdefs = event.getEventDefinitions();
+ if (eventdefs.size()==0) {
+ return ctx.createFailureStatus("Catch Event has no event definitions");
+ }
+
+ for (EventDefinition ed : eventdefs) {
+ if (ed instanceof TimerEventDefinition) {
+ TimerEventDefinition ted = (TimerEventDefinition) ed;
+ if ( ted.getTimeDate() == null
+ && ted.getTimeDuration() == null
+ && ted.getTimeCycle() == null
+ ) {
+ return ctx.createFailureStatus("Timer Event has no timer definition");
+ }
+ } else if (ed instanceof SignalEventDefinition) {
+ if (((SignalEventDefinition) ed).getSignalRef() == null) {
+ return ctx.createFailureStatus("Signal Event has no signal definition");
+ }
+ } else if (ed instanceof ErrorEventDefinition) {
+ if (((ErrorEventDefinition) ed).getErrorRef() == null
+ || ((ErrorEventDefinition) ed).getErrorRef().getErrorCode() == null) {
+ return ctx.createFailureStatus("Error Event has no error definition");
+ }
+ } else if (ed instanceof ConditionalEventDefinition) {
+ FormalExpression conditionalExp = (FormalExpression) ((ConditionalEventDefinition) ed)
+ .getCondition();
+ if (conditionalExp.getBody() == null) {
+ return ctx.createFailureStatus("Conditional Event has no condition expression");
+ }
+ } else if (ed instanceof EscalationEventDefinition) {
+ if (((EscalationEventDefinition) ed).getEscalationRef() == null) {
+ return ctx.createFailureStatus("Escalation Event has no escalation definition");
+ }
+ } else if (ed instanceof MessageEventDefinition) {
+ if (((MessageEventDefinition) ed).getMessageRef() == null) {
+ return ctx.createFailureStatus("Message Event has no message definition");
+ }
+ } else if (ed instanceof CompensateEventDefinition) {
+ if (((CompensateEventDefinition) ed).getActivityRef() == null) {
+ return ctx.createFailureStatus("Compensate Event has no activity definition");
+ }
+ }
+ }
+ }
+ }
+ else if (fe instanceof ThrowEvent) {
+ ThrowEvent event = (ThrowEvent) fe;
+
+ if (!warnings) {
+ List<EventDefinition> eventdefs = event.getEventDefinitions();
+ if (eventdefs.size()==0) {
+ return ctx.createFailureStatus("Throw Event has no event definitions");
+ }
+
+ for (EventDefinition ed : eventdefs) {
+ if (ed instanceof TimerEventDefinition) {
+ TimerEventDefinition ted = (TimerEventDefinition) ed;
+ if ( ted.getTimeDate() == null
+ && ted.getTimeDuration() == null
+ && ted.getTimeCycle() == null
+ ) {
+ return ctx.createFailureStatus("Timer Event has no timer definition");
+ }
+ } else if (ed instanceof SignalEventDefinition) {
+ if (((SignalEventDefinition) ed).getSignalRef() == null) {
+ return ctx.createFailureStatus("Signal Event has no signal definition");
+ }
+ } else if (ed instanceof ErrorEventDefinition) {
+ if (((ErrorEventDefinition) ed).getErrorRef() == null
+ || ((ErrorEventDefinition) ed).getErrorRef().getErrorCode() == null) {
+ return ctx.createFailureStatus("Error Event has no error definition");
+ }
+ } else if (ed instanceof ConditionalEventDefinition) {
+ FormalExpression conditionalExp = (FormalExpression) ((ConditionalEventDefinition) ed)
+ .getCondition();
+ if (conditionalExp.getBody() == null) {
+ return ctx.createFailureStatus("Conditional Event has no condition expression");
+ }
+ } else if (ed instanceof EscalationEventDefinition) {
+ if (((EscalationEventDefinition) ed).getEscalationRef() == null) {
+ return ctx.createFailureStatus("Escalation Event has no conditional escalation definition");
+ }
+ } else if (ed instanceof MessageEventDefinition) {
+ if (((MessageEventDefinition) ed).getMessageRef() == null) {
+ return ctx.createFailureStatus("Message Event has no conditional message definition");
+ }
+ } else if (ed instanceof CompensateEventDefinition) {
+ if (((CompensateEventDefinition) ed).getActivityRef() == null) {
+ return ctx.createFailureStatus("Compensate Event has no conditional activity definition");
+ }
+ }
+ }
+ }
+ }
+ else if (fe instanceof SequenceFlow) {
+ SequenceFlow sf = (SequenceFlow) fe;
+
+ if (!warnings) {
+ if (sf.getSourceRef() == null) {
+ return ctx.createFailureStatus("Sequence Flow is not connected to a source");
+ }
+ if (sf.getTargetRef() == null) {
+ return ctx.createFailureStatus("Sequence Flow is not connected to a target");
+ }
+ }
+ }
+ else if (fe instanceof Gateway) {
+ Gateway gw = (Gateway) fe;
+
+ if (!warnings) {
+ if (gw.getGatewayDirection() == null
+ || gw.getGatewayDirection().getValue() == GatewayDirection.UNSPECIFIED.getValue()) {
+ ctx.addResult(Bpmn2Package.eINSTANCE.getGateway_GatewayDirection());
+ return ctx.createFailureStatus("Gateway does not specify a valid direction");
+ }
+ if (gw instanceof ExclusiveGateway) {
+ if (gw.getGatewayDirection().getValue() != GatewayDirection.DIVERGING.getValue()
+ && gw.getGatewayDirection().getValue() != GatewayDirection.CONVERGING.getValue()) {
+ return ctx.createFailureStatus(
+ "Invalid Gateway direction for Exclusing Gateway. It should be 'Converging' or 'Diverging'");
+ }
+ }
+ if (gw instanceof EventBasedGateway) {
+ if (gw.getGatewayDirection().getValue() != GatewayDirection.DIVERGING.getValue()) {
+ return ctx.createFailureStatus(
+ "Invalid Gateway direction for EventBased Gateway. It should be 'Diverging'");
+ }
+ }
+ if (gw instanceof ParallelGateway) {
+ if (gw.getGatewayDirection().getValue() != GatewayDirection.DIVERGING.getValue()
+ && gw.getGatewayDirection().getValue() != GatewayDirection.CONVERGING.getValue()) {
+ return ctx.createFailureStatus(
+ "Invalid Gateway direction for Parallel Gateway. It should be 'Converging' or 'Diverging'");
+ }
+ }
+ if (gw instanceof InclusiveGateway) {
+ if (gw.getGatewayDirection().getValue() != GatewayDirection.DIVERGING.getValue()) {
+ return ctx.createFailureStatus(
+ "Invalid Gateway direction for Inclusive Gateway. It should be 'Diverging'");
+ }
+ }
+ if (gw instanceof ComplexGateway) {
+ if (gw.getGatewayDirection().getValue() != GatewayDirection.DIVERGING.getValue()
+ && gw.getGatewayDirection().getValue() != GatewayDirection.CONVERGING.getValue()) {
+ return ctx.createFailureStatus(
+ "Invalid Gateway direction for Complex Gateway. It should be 'Converging' or 'Diverging'");
+ }
+ }
+ }
+ }
+ else if (fe instanceof CallActivity) {
+ CallActivity ca = (CallActivity) fe;
+
+ if (!warnings) {
+ if (ca.getCalledElementRef() == null) {
+ return ctx.createFailureStatus(
+ "Reusable Subprocess has no called element specified");
+ }
+ }
+ }
+ else if (fe instanceof DataObject) {
+ DataObject dao = (DataObject) fe;
+
+ if (!warnings) {
+ if (dao.getName() == null || dao.getName().length() < 1) {
+ return ctx.createFailureStatus("Data Object has no name");
+ } else {
+ if (containsWhiteSpace(dao.getName())) {
+ return ctx.createFailureStatus("Data Object name contains whitespace");
+ }
+ }
+ }
+ }
+
+
+ if (fe instanceof FlowNode) {
+ return validateFlowNode(ctx, (FlowNode) fe);
+ }
+
+ return ctx.createSuccessStatus();
+ }
+
+ private IStatus validateFlowNode(IValidationContext ctx, FlowNode fn) {
+ if (!warnings) {
+ boolean needIncoming = true;
+ boolean needOutgoing = true;
+ if (fn instanceof ThrowEvent)
+ needOutgoing = false;
+ if (fn instanceof CatchEvent)
+ needIncoming = false;
+
+ if (needOutgoing) {
if ((fn.getOutgoing() == null || fn.getOutgoing().size() < 1)) {
return ctx.createFailureStatus("Node has no outgoing connections");
}
+ }
+ if (needIncoming) {
if ((fn.getIncoming() == null || fn.getIncoming().size() < 1)) {
return ctx.createFailureStatus("Node has no incoming connections");
}
}
}
- if (fe instanceof BusinessRuleTask) {
- BusinessRuleTask bt = (BusinessRuleTask) fe;
- Iterator<FeatureMap.Entry> biter = bt.getAnyAttribute().iterator();
- boolean foundRuleflowGroup = false;
- while (biter.hasNext()) {
- FeatureMap.Entry entry = biter.next();
- if (entry.getEStructuralFeature().getName().equals("ruleFlowGroup")) {
- foundRuleflowGroup = true;
- String ruleflowGroup = (String) entry.getValue();
- if (isEmpty(ruleflowGroup)) {
- return ctx.createFailureStatus("Business Rule Task has no ruleflow-group.");
- }
- }
- }
- if (!foundRuleflowGroup) {
- return ctx.createFailureStatus("Business Rule Task has no ruleflow-group.");
- }
- }
-
- if (fe instanceof ScriptTask) {
- ScriptTask st = (ScriptTask) fe;
- if (isEmpty(st.getScript())) {
- return ctx.createFailureStatus("Script Task has no script.");
- }
- if (isEmpty(st.getScriptFormat())) {
- return ctx.createFailureStatus("Script Task has no script format.");
- }
- }
-
- if (fe instanceof SendTask) {
- SendTask st = (SendTask) fe;
- if (st.getOperationRef() == null) {
- return ctx.createFailureStatus("Send Task has no operation.");
- }
- if (st.getMessageRef() == null) {
- return ctx.createFailureStatus("Send Task has no message.");
- }
- }
-
- if (fe instanceof UserTask) {
- UserTask ut = (UserTask) fe;
- String taskName = null;
- Iterator<FeatureMap.Entry> utiter = ut.getAnyAttribute().iterator();
- boolean foundTaskName = false;
- while (utiter.hasNext()) {
- FeatureMap.Entry entry = utiter.next();
- if (entry.getEStructuralFeature().getName().equals("taskName")) {
- foundTaskName = true;
- taskName = (String) entry.getValue();
- if (isEmpty(taskName)) {
- return ctx.createFailureStatus("User Task has no task name.");
- }
- }
- }
- if (!foundTaskName) {
- return ctx.createFailureStatus("User Task has no task name.");
- }
-
- // simulation validation
- if (ut.getExtensionValues() != null && fe.getExtensionValues().size() > 0) {
- boolean foundStaffAvailability = false;
- for (ExtensionAttributeValue extattrval : fe.getExtensionValues()) {
- FeatureMap extensionElements = extattrval.getValue();
- }
- if (!foundStaffAvailability) {
- return ctx.createFailureStatus("User Task has no staff availability defined.");
- }
- }
- }
-
- if (fe instanceof Task) {
- Task ta = (Task) fe;
- // simulation validation
- if (ta.getExtensionValues() != null && fe.getExtensionValues().size() > 0) {
- boolean foundDistributionType = false;
- String distributionTypeValue = "";
- boolean foundDuration = false;
- boolean foundTimeUnits = false;
- boolean foundRange = false;
- boolean foundStandardDeviation = false;
- for (ExtensionAttributeValue extattrval : fe.getExtensionValues()) {
- FeatureMap extensionElements = extattrval.getValue();
-
- }
- if (!foundDistributionType) {
- return ctx.createFailureStatus("Task has no distribution type defined.");
- }
- if (!foundDuration) {
- return ctx.createFailureStatus("Task has no duration defined.");
- }
- if (!foundTimeUnits) {
- return ctx.createFailureStatus( "Task has no Time Units defined.");
- }
- if (foundDistributionType) {
- if ((distributionTypeValue.equals("random") || distributionTypeValue.equals("uniform"))
- && !foundRange) {
- return ctx.createFailureStatus("Task has no Range defined.");
- }
- if (distributionTypeValue.equals("normal") && !foundStandardDeviation) {
- return ctx.createFailureStatus("Task has no Standard Deviation defined.");
- }
- }
- }
- }
-
- if (fe instanceof CatchEvent) {
- CatchEvent event = (CatchEvent) fe;
- List<EventDefinition> eventdefs = event.getEventDefinitions();
- for (EventDefinition ed : eventdefs) {
- if (ed instanceof TimerEventDefinition) {
- TimerEventDefinition ted = (TimerEventDefinition) ed;
- boolean gotTimerDef = (ted.getTimeDate() != null || ted.getTimeDuration() != null || ted
- .getTimeCycle() != null);
- if (!gotTimerDef) {
- return ctx.createFailureStatus("Catch Event has no time value.");
- }
- } else if (ed instanceof SignalEventDefinition) {
- if (((SignalEventDefinition) ed).getSignalRef() == null) {
- return ctx.createFailureStatus("Catch Event has no signalref.");
- }
- } else if (ed instanceof ErrorEventDefinition) {
- if (((ErrorEventDefinition) ed).getErrorRef() == null
- || ((ErrorEventDefinition) ed).getErrorRef().getErrorCode() == null) {
- return ctx.createFailureStatus("Catch Event has no errorref.");
- }
- } else if (ed instanceof ConditionalEventDefinition) {
- FormalExpression conditionalExp = (FormalExpression) ((ConditionalEventDefinition) ed)
- .getCondition();
- if (conditionalExp.getBody() == null) {
- return ctx.createFailureStatus("Catch Event has no condition expression.");
- }
- } else if (ed instanceof EscalationEventDefinition) {
- if (((EscalationEventDefinition) ed).getEscalationRef() == null) {
- return ctx.createFailureStatus("Catch Event has no escalationref.");
- }
- } else if (ed instanceof MessageEventDefinition) {
- if (((MessageEventDefinition) ed).getMessageRef() == null) {
- return ctx.createFailureStatus("Catch Event has no messageref.");
- }
- } else if (ed instanceof CompensateEventDefinition) {
- if (((CompensateEventDefinition) ed).getActivityRef() == null) {
- return ctx.createFailureStatus("Catch Event has no activityref.");
- }
- }
- }
- }
-
- if (fe instanceof ThrowEvent) {
- ThrowEvent event = (ThrowEvent) fe;
- List<EventDefinition> eventdefs = event.getEventDefinitions();
- for (EventDefinition ed : eventdefs) {
- if (ed instanceof TimerEventDefinition) {
- TimerEventDefinition ted = (TimerEventDefinition) ed;
- if (ted.getTimeDate() == null) {
- return ctx.createFailureStatus("Throw Event has no timedate.");
- }
- if (ted.getTimeDuration() == null) {
- return ctx.createFailureStatus("Throw Event has no timeduration.");
- }
- if (ted.getTimeCycle() != null) {
- return ctx.createFailureStatus("Throw Event has no timecycle.");
- }
- } else if (ed instanceof SignalEventDefinition) {
- if (((SignalEventDefinition) ed).getSignalRef() == null) {
- return ctx.createFailureStatus("Throw Event has no signalref.");
- }
- } else if (ed instanceof ErrorEventDefinition) {
- if (((ErrorEventDefinition) ed).getErrorRef() == null
- || ((ErrorEventDefinition) ed).getErrorRef().getErrorCode() == null) {
- return ctx.createFailureStatus("Throw Event has no errorref.");
- }
- } else if (ed instanceof ConditionalEventDefinition) {
- FormalExpression conditionalExp = (FormalExpression) ((ConditionalEventDefinition) ed)
- .getCondition();
- if (conditionalExp.getBody() == null) {
- return ctx.createFailureStatus("Throw Event has no conditional expression.");
- }
- } else if (ed instanceof EscalationEventDefinition) {
- if (((EscalationEventDefinition) ed).getEscalationRef() == null) {
- return ctx.createFailureStatus("Throw Event has no conditional escalationref.");
- }
- } else if (ed instanceof MessageEventDefinition) {
- if (((MessageEventDefinition) ed).getMessageRef() == null) {
- return ctx.createFailureStatus("Throw Event has no conditional messageref.");
- }
- } else if (ed instanceof CompensateEventDefinition) {
- if (((CompensateEventDefinition) ed).getActivityRef() == null) {
- return ctx.createFailureStatus("Throw Event has no conditional activityref.");
- }
- }
- }
- }
-
- if (fe instanceof SequenceFlow) {
- SequenceFlow sf = (SequenceFlow) fe;
- if (sf.getSourceRef() == null) {
- return ctx.createFailureStatus("An Edge must have a source node.");
- }
- if (sf.getTargetRef() == null) {
- return ctx.createFailureStatus("An Edge must have a target node.");
- }
- }
-
- if (fe instanceof Gateway) {
- Gateway gw = (Gateway) fe;
- if (gw.getGatewayDirection() == null
- || gw.getGatewayDirection().getValue() == GatewayDirection.UNSPECIFIED.getValue()) {
- return ctx.createFailureStatus("Gateway does not specify a valid direction.");
- }
- if (gw instanceof ExclusiveGateway) {
- if (gw.getGatewayDirection().getValue() != GatewayDirection.DIVERGING.getValue()
- && gw.getGatewayDirection().getValue() != GatewayDirection.CONVERGING.getValue()) {
- return ctx.createFailureStatus(
- "Invalid Gateway direction for Exclusing Gateway. It should be 'Converging' or 'Diverging'.");
- }
- }
- if (gw instanceof EventBasedGateway) {
- if (gw.getGatewayDirection().getValue() != GatewayDirection.DIVERGING.getValue()) {
- return ctx.createFailureStatus(
- "Invalid Gateway direction for EventBased Gateway. It should be 'Diverging'.");
- }
- }
- if (gw instanceof ParallelGateway) {
- if (gw.getGatewayDirection().getValue() != GatewayDirection.DIVERGING.getValue()
- && gw.getGatewayDirection().getValue() != GatewayDirection.CONVERGING.getValue()) {
- return ctx.createFailureStatus(
- "Invalid Gateway direction for Parallel Gateway. It should be 'Converging' or 'Diverging'.");
- }
- }
- if (gw instanceof InclusiveGateway) {
- if (gw.getGatewayDirection().getValue() != GatewayDirection.DIVERGING.getValue()) {
- return ctx.createFailureStatus(
- "Invalid Gateway direction for Inclusive Gateway. It should be 'Diverging'.");
- }
- }
- if (gw instanceof ComplexGateway) {
- if (gw.getGatewayDirection().getValue() != GatewayDirection.DIVERGING.getValue()
- && gw.getGatewayDirection().getValue() != GatewayDirection.CONVERGING.getValue()) {
- return ctx.createFailureStatus(
- "Invalid Gateway direction for Complex Gateway. It should be 'Converging' or 'Diverging'.");
- }
- }
- }
-
- if (fe instanceof CallActivity) {
- CallActivity ca = (CallActivity) fe;
- if (ca.getCalledElementRef() == null) {
- return ctx.createFailureStatus(
- "Reusable Subprocess has no called element specified.");
- }
- }
-
- if (fe instanceof DataObject) {
- DataObject dao = (DataObject) fe;
- if (dao.getName() == null || dao.getName().length() < 1) {
- return ctx.createFailureStatus("Data Object has no name defined.");
- } else {
- if (containsWhiteSpace(dao.getName())) {
- return ctx.createFailureStatus("Data Object name contains white spaces.");
- }
- }
- }
return ctx.createSuccessStatus();
}
- private static boolean isEmpty(final CharSequence str) {
- if (str == null || str.length() == 0) {
- return true;
- }
- for (int i = 0, length = str.length(); i < length; i++) {
- if (str.charAt(i) != ' ') {
- return false;
- }
- }
- return true;
+ private static boolean isEmpty(String str) {
+ return str == null || str.isEmpty();
}
private boolean containsWhiteSpace(String testString) {
diff --git a/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/validation/BPMN2ProjectValidator.java b/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/validation/BPMN2ProjectValidator.java
index 7b1e38b..14aad79 100644
--- a/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/validation/BPMN2ProjectValidator.java
+++ b/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/validation/BPMN2ProjectValidator.java
@@ -13,6 +13,11 @@
import java.io.IOException;
import org.eclipse.bpmn2.modeler.core.Activator;
+import org.eclipse.bpmn2.modeler.core.ProxyURIConverterImplExtension;
+import org.eclipse.bpmn2.modeler.core.model.Bpmn2ModelerResourceImpl;
+import org.eclipse.bpmn2.modeler.core.model.Bpmn2ModelerResourceSetImpl;
+import org.eclipse.bpmn2.modeler.core.preferences.Bpmn2Preferences;
+import org.eclipse.bpmn2.modeler.core.runtime.TargetRuntime;
import org.eclipse.core.resources.IBuildConfiguration;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IMarker;
@@ -50,17 +55,27 @@
/** ID for BPMN2 specific problem markers. */
public static final String BPMN2_MARKER_ID = "org.eclipse.bpmn2.modeler.core.problemMarker";
+ private Bpmn2Preferences preferences;
+ private TargetRuntime targetRuntime;
+ private IFile modelFile;
@Override
public ValidationResult validate(ValidationEvent event, ValidationState state, IProgressMonitor monitor) {
- if ((event.getKind() & IResourceDelta.REMOVED) != 0 || event.getResource().isDerived(IResource.CHECK_ANCESTORS)) {
+ IResource file = event.getResource();
+ if ((event.getKind() & IResourceDelta.REMOVED) != 0
+ || file.isDerived(IResource.CHECK_ANCESTORS)
+ || !(file instanceof IFile)) {
return new ValidationResult();
}
+ modelFile = (IFile) file;
- ResourceSet rs = new ResourceSetImpl();
- Resource resource = rs.createResource(
- URI.createPlatformResourceURI(event.getResource().getFullPath().toString(), false),
- "org.eclipse.bpmn2.content-type.xml");
+ ResourceSet rs = new Bpmn2ModelerResourceSetImpl();
+ getTargetRuntime().setResourceSet(rs);
+ rs.setURIConverter(new ProxyURIConverterImplExtension());
+
+ Resource resource = rs.createResource(
+ URI.createPlatformResourceURI(modelFile.getFullPath().toString(), false),
+ Bpmn2ModelerResourceImpl.BPMN2_CONTENT_TYPE_ID);
try {
resource.load(null);
} catch (IOException e) {
@@ -68,12 +83,12 @@
}
ValidationResult result = new ValidationResult();
if (resource.getContents().isEmpty()) {
- ValidatorMessage message = ValidatorMessage.create("Invalid bpmn2 file", event.getResource());
+ ValidatorMessage message = ValidatorMessage.create("Invalid bpmn2 file", modelFile);
message.setType(BPMN2_MARKER_ID);
result.add(message);
} else {
IBatchValidator validator = ModelValidationService.getInstance().newValidator(EvaluationMode.BATCH);
- processStatus(validator.validate(resource.getContents(), monitor), event.getResource(), result);
+ processStatus(validator.validate(resource.getContents(), monitor), modelFile, result);
}
return result;
}
@@ -83,32 +98,35 @@
boolean needValidation = false;
IWorkspace workspace = ResourcesPlugin.getWorkspace();
IWorkspaceDescription description = workspace.getDescription();
+ resource.getURI().toFileString();
+ String pathString = resource.getURI().toPlatformString(true);
+ IPath path = Path.fromOSString(pathString);
+ IFile file = ResourcesPlugin.getWorkspace().getRoot().getFile(path);
+ IProject project = file.getProject();
+
if (!description.isAutoBuilding()) {
needValidation = true;
}
if (!needValidation) {
- resource.getURI().toFileString();
- String pathString = resource.getURI().toPlatformString(true);
- IPath path = Path.fromOSString(pathString);
- IFile file = ResourcesPlugin.getWorkspace().getRoot().getFile(path);
- IProject project = file.getProject();
if (project!=null) {
try {
+ // TODO: if there is no project builder, force validation
IBuildConfiguration config = project.getActiveBuildConfig();
if (config==null || config.getName()==null || config.getName().isEmpty())
needValidation = true;
- IBuildConfiguration[] configs = project.getBuildConfigs();
- for (IBuildConfiguration c : configs) {
- System.out.println(c.getName());
- }
} catch (CoreException e) {
- // TODO Auto-generated catch block
e.printStackTrace();
}
}
}
if (needValidation) {
+ try {
+ project.deleteMarkers(BPMN2_MARKER_ID, false, IProject.DEPTH_INFINITE);
+ } catch (CoreException e) {
+ Activator.getDefault().getLog().log(e.getStatus());
+ }
+
IBatchValidator validator = ModelValidationService.getInstance().newValidator(EvaluationMode.BATCH);
IStatus status = validator.validate(resource.getContents(), monitor);
try {
@@ -157,7 +175,8 @@
relatedUris.append(EcoreUtil.getURI(eobject).toString()).append(" ");
}
relatedUris.deleteCharAt(relatedUris.length() - 1);
- message.setAttribute(EValidator.RELATED_URIS_ATTRIBUTE, relatedUris.toString());
+ String uris = relatedUris.toString();
+ message.setAttribute(EValidator.RELATED_URIS_ATTRIBUTE, uris);
}
}
@@ -175,6 +194,26 @@
Activator.getDefault().getLog().log(e.getStatus());
}
}
+
+ protected TargetRuntime getTargetRuntime() {
+ if (targetRuntime==null)
+ targetRuntime = getPreferences().getRuntime(modelFile);
+ return targetRuntime;
+ }
+
+ protected Bpmn2Preferences getPreferences() {
+ if (preferences==null) {
+ assert(modelFile!=null);
+ IProject project = modelFile.getProject();
+ loadPreferences(project);
+ }
+ return preferences;
+ }
+
+ protected void loadPreferences(IProject project) {
+ preferences = Bpmn2Preferences.getInstance(project);
+ preferences.load();
+ }
public static class MarkerConfigurator implements IMarkerConfigurator {
diff --git a/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/validation/ProblemsReporter.java b/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/validation/ProblemsReporter.java
index 0e8cb97..a20b56e 100644
--- a/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/validation/ProblemsReporter.java
+++ b/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/validation/ProblemsReporter.java
@@ -50,5 +50,5 @@
}
}
}
- }
+ }
}
\ No newline at end of file
diff --git a/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/validation/SyntaxCheckerUtils.java b/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/validation/SyntaxCheckerUtils.java
index 4c4e51f..dfcf90b 100644
--- a/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/validation/SyntaxCheckerUtils.java
+++ b/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/validation/SyntaxCheckerUtils.java
@@ -2,11 +2,10 @@
public class SyntaxCheckerUtils {
public static final boolean isNCName(String name) {
- int nameLength = name.length();
-
- if (nameLength == 0) {
+ if (name==null || name.isEmpty())
return false;
- }
+
+ int nameLength = name.length();
// Check first character
char c = name.charAt(0);
diff --git a/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/validation/ValidIdConstraint.java b/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/validation/ValidIdConstraint.java
index 7d019dd..a2a49d4 100644
--- a/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/validation/ValidIdConstraint.java
+++ b/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/validation/ValidIdConstraint.java
@@ -1,53 +1,51 @@
-/*******************************************************************************
- * Copyright (c) 2011 Red Hat, Inc.
- * All rights reserved.
- * This program is made available under the terms of the
- * Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * Red Hat, Inc. - initial API and implementation
- *
- * @author Bob Brodt
- ******************************************************************************/
-package org.eclipse.bpmn2.modeler.core.validation;
-
-import org.eclipse.bpmn2.BaseElement;
-import org.eclipse.core.runtime.IStatus;
-import org.eclipse.emf.ecore.EObject;
-import org.eclipse.emf.validation.AbstractModelConstraint;
-import org.eclipse.emf.validation.EMFEventType;
-import org.eclipse.emf.validation.IValidationContext;
-
-public class ValidIdConstraint extends AbstractModelConstraint {
-
- String validIdRegEx = "^[^0-9][a-zA-Z0-9-_]*";
-
- @Override
- public IStatus validate(IValidationContext ctx) {
- EObject eObj = ctx.getTarget();
- EMFEventType eType = ctx.getEventType();
-
- // In the case of batch mode.
- if (eType == EMFEventType.NULL) {
- String id = null;
- if (eObj instanceof BaseElement) {
- id = ((BaseElement)eObj).getId();
- }
-
- if (id == null || id.length() == 0 || id.indexOf(' ')>=0 || !id.matches(validIdRegEx) ) {
- return ctx.createFailureStatus(new Object[] {eObj.eClass().getName()});
- }
- // In the case of live mode.
- } else {
- String newValue = (String) ctx.getFeatureNewValue();
-
- if (newValue == null || newValue.length() == 0 || newValue.indexOf(' ')>=0 || !newValue.matches(validIdRegEx)) {
- return ctx.createFailureStatus(new Object[] {eObj.eClass().getName()});
- }
- }
-
- return ctx.createSuccessStatus();
- }
-
-}
+/*******************************************************************************
+ * Copyright (c) 2011 Red Hat, Inc.
+ * All rights reserved.
+ * This program is made available under the terms of the
+ * Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Red Hat, Inc. - initial API and implementation
+ *
+ * @author Bob Brodt
+ ******************************************************************************/
+package org.eclipse.bpmn2.modeler.core.validation;
+
+import org.eclipse.bpmn2.BaseElement;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.validation.AbstractModelConstraint;
+import org.eclipse.emf.validation.EMFEventType;
+import org.eclipse.emf.validation.IValidationContext;
+
+public class ValidIdConstraint extends AbstractModelConstraint {
+
+ @Override
+ public IStatus validate(IValidationContext ctx) {
+ EObject eObj = ctx.getTarget();
+ EMFEventType eType = ctx.getEventType();
+
+ // In the case of batch mode.
+ if (eType == EMFEventType.NULL) {
+ String id = null;
+ if (eObj instanceof BaseElement) {
+ id = ((BaseElement)eObj).getId();
+ }
+
+ if (!SyntaxCheckerUtils.isNCName(id)) {
+ return ctx.createFailureStatus(new Object[] {eObj.eClass().getName()});
+ }
+ // In the case of live mode.
+ } else {
+ String newValue = (String) ctx.getFeatureNewValue();
+
+ if (!SyntaxCheckerUtils.isNCName(newValue)) {
+ return ctx.createFailureStatus(new Object[] {eObj.eClass().getName()});
+ }
+ }
+
+ return ctx.createSuccessStatus();
+ }
+
+}
diff --git a/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/validation/ValidationStatusAdapter.java b/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/validation/ValidationStatusAdapter.java
index 53dd800..dec0793 100644
--- a/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/validation/ValidationStatusAdapter.java
+++ b/org.eclipse.bpmn2.modeler.core/src/org/eclipse/bpmn2/modeler/core/validation/ValidationStatusAdapter.java
@@ -27,7 +27,11 @@
*/
public class ValidationStatusAdapter extends AdapterImpl {
- private List<IStatus> _validationStatus = new ArrayList<IStatus>();
+ public ValidationStatusAdapter() {
+ super();
+ }
+
+ private List<IStatus> _validationStatus = new ArrayList<IStatus>();
@Override
public boolean isAdapterForType(Object type) {
diff --git a/org.eclipse.bpmn2.modeler.runtime.jboss.jbpm5/plugin.xml b/org.eclipse.bpmn2.modeler.runtime.jboss.jbpm5/plugin.xml
index 9dd93e5..a046d3e 100644
--- a/org.eclipse.bpmn2.modeler.runtime.jboss.jbpm5/plugin.xml
+++ b/org.eclipse.bpmn2.modeler.runtime.jboss.jbpm5/plugin.xml
@@ -1215,4 +1215,124 @@
</imageProvider>
</extension>
+ <extension
+ point="org.eclipse.emf.validation.constraintProviders">
+ <category
+ name="jBPM Constraints"
+ id="org.eclipse.bpmn2.modeler.runtime.jboss.jbpm5"/>
+ <constraintProvider cache="true">
+ <package namespaceUri="http://www.omg.org/spec/BPMN/20100524/MODEL-XMI"/>
+ <constraints categories="org.eclipse.bpmn2.modeler.runtime.jboss.jbpm5">
+ <constraint
+ lang="Java"
+ class="org.eclipse.bpmn2.modeler.runtime.jboss.jbpm5.validation.ProcessConstraint"
+ severity="ERROR"
+ mode="Batch"
+ name="Process Validation"
+ id="org.eclipse.bpmn2.modeler.runtime.jboss.jbpm5.validation.Process"
+ statusCode="1">
+ <description>
+ Process Name, ID and Package Name validation.
+ </description>
+ <message>
+ {0}
+ </message>
+ <target class="Process"/>
+ </constraint>
+ <constraint
+ lang="Java"
+ class="org.eclipse.bpmn2.modeler.runtime.jboss.jbpm5.validation.BusinessRuleTaskConstraint"
+ severity="ERROR"
+ mode="Batch"
+ name="Business Rule Task Validation"
+ id="org.eclipse.bpmn2.modeler.runtime.jboss.jbpm5.validation.BusinessRuleTask"
+ statusCode="1">
+ <description>
+ Business Rule Task validation.
+ </description>
+ <message>
+ {0}
+ </message>
+ <target class="BusinessRuleTask"/>
+ </constraint>
+ <constraint
+ lang="Java"
+ class="org.eclipse.bpmn2.modeler.runtime.jboss.jbpm5.validation.UserTaskConstraint"
+ severity="WARNING"
+ mode="Batch"
+ name="User Task Validation"
+ id="org.eclipse.bpmn2.modeler.runtime.jboss.jbpm5.validation.UserTask"
+ statusCode="1">
+ <description>
+ User Task validation.
+ </description>
+ <message>
+ {0}
+ </message>
+ <target class="UserTask"/>
+ </constraint>
+ <constraint
+ lang="Java"
+ class="org.eclipse.bpmn2.modeler.runtime.jboss.jbpm5.validation.TaskConstraint"
+ severity="WARNING"
+ mode="Batch"
+ name="Task Validation"
+ id="org.eclipse.bpmn2.modeler.runtime.jboss.jbpm5.validation.Task"
+ statusCode="1">
+ <description>
+ Task validation.
+ </description>
+ <message>
+ {0}
+ </message>
+ <target class="Task"/>
+ </constraint>
+ <constraint
+ lang="Java"
+ class="org.eclipse.bpmn2.modeler.runtime.jboss.jbpm5.validation.GatewayConstraint"
+ severity="WARNING"
+ mode="Batch"
+ name="Gateway Validation"
+ id="org.eclipse.bpmn2.modeler.runtime.jboss.jbpm5.validation.Gateway"
+ statusCode="1">
+ <description>
+ Gateway validation.
+ </description>
+ <message>
+ {0}
+ </message>
+ <target class="Gateway"/>
+ </constraint>
+ <constraint
+ lang="Java"
+ class="org.eclipse.bpmn2.modeler.runtime.jboss.jbpm5.validation.CallActivityConstraint"
+ severity="WARNING"
+ mode="Batch"
+ name="CallActivity Validation"
+ id="org.eclipse.bpmn2.modeler.runtime.jboss.jbpm5.validation.CallActivity"
+ statusCode="1">
+ <description>
+ CallActivity validation.
+ </description>
+ <message>
+ {0}
+ </message>
+ <target class="CallActivity"/>
+ </constraint>
+ </constraints>
+ </constraintProvider>
+ </extension>
+
+ <extension
+ point="org.eclipse.emf.validation.constraintBindings">
+ <clientContext
+ default="false"
+ id="org.eclipse.bpmn2.modeler.core.validationContext">
+ <selector class="org.eclipse.bpmn2.modeler.core.validation.ValidationDelegateClientSelector"/>
+ </clientContext>
+ <binding
+ context="org.eclipse.bpmn2.modeler.core.validationContext"
+ category="org.eclipse.bpmn2.modeler.runtime.jboss.jbpm5"/>
+ </extension>
+
</plugin>
diff --git a/org.eclipse.bpmn2.modeler.runtime.jboss.jbpm5/src/org/eclipse/bpmn2/modeler/runtime/jboss/jbpm5/property/JbpmDescriptionPropertySection.java b/org.eclipse.bpmn2.modeler.runtime.jboss.jbpm5/src/org/eclipse/bpmn2/modeler/runtime/jboss/jbpm5/property/JbpmDescriptionPropertySection.java
index 5c23f13..414e5d1 100644
--- a/org.eclipse.bpmn2.modeler.runtime.jboss.jbpm5/src/org/eclipse/bpmn2/modeler/runtime/jboss/jbpm5/property/JbpmDescriptionPropertySection.java
+++ b/org.eclipse.bpmn2.modeler.runtime.jboss.jbpm5/src/org/eclipse/bpmn2/modeler/runtime/jboss/jbpm5/property/JbpmDescriptionPropertySection.java
@@ -13,15 +13,20 @@
package org.eclipse.bpmn2.modeler.runtime.jboss.jbpm5.property;
+import java.util.List;
+
import org.eclipse.bpmn2.BaseElement;
import org.eclipse.bpmn2.Participant;
import org.eclipse.bpmn2.Process;
import org.eclipse.bpmn2.di.BPMNDiagram;
import org.eclipse.bpmn2.modeler.core.merrimac.clad.AbstractBpmn2PropertySection;
import org.eclipse.bpmn2.modeler.core.merrimac.clad.AbstractDetailComposite;
+import org.eclipse.bpmn2.modeler.core.model.Bpmn2ModelerFactory;
+import org.eclipse.bpmn2.modeler.core.utils.ModelUtil;
import org.eclipse.bpmn2.modeler.ui.property.DescriptionPropertySection;
import org.eclipse.bpmn2.modeler.ui.property.tasks.TaskDetailComposite;
import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.ui.IWorkbenchPart;
diff --git a/org.eclipse.bpmn2.modeler.runtime.jboss.jbpm5/src/org/eclipse/bpmn2/modeler/runtime/jboss/jbpm5/property/JbpmUserTaskDetailComposite.java b/org.eclipse.bpmn2.modeler.runtime.jboss.jbpm5/src/org/eclipse/bpmn2/modeler/runtime/jboss/jbpm5/property/JbpmUserTaskDetailComposite.java
index dcc5b41..882c19e 100644
--- a/org.eclipse.bpmn2.modeler.runtime.jboss.jbpm5/src/org/eclipse/bpmn2/modeler/runtime/jboss/jbpm5/property/JbpmUserTaskDetailComposite.java
+++ b/org.eclipse.bpmn2.modeler.runtime.jboss.jbpm5/src/org/eclipse/bpmn2/modeler/runtime/jboss/jbpm5/property/JbpmUserTaskDetailComposite.java
@@ -14,9 +14,11 @@
package org.eclipse.bpmn2.modeler.runtime.jboss.jbpm5.property;
import org.eclipse.bpmn2.FormalExpression;
+import org.eclipse.bpmn2.InputOutputSpecification;
import org.eclipse.bpmn2.PotentialOwner;
import org.eclipse.bpmn2.ResourceAssignmentExpression;
import org.eclipse.bpmn2.UserTask;
+import org.eclipse.bpmn2.modeler.core.adapters.InsertionAdapter;
import org.eclipse.bpmn2.modeler.core.merrimac.clad.AbstractBpmn2PropertySection;
import org.eclipse.bpmn2.modeler.core.merrimac.clad.AbstractListComposite;
import org.eclipse.bpmn2.modeler.core.merrimac.dialogs.TextObjectEditor;
@@ -50,18 +52,14 @@
ResourceAssignmentExpression resourceAssignment = null;
FormalExpression expression = null;
if (task.getResources().size() == 0) {
- owner = (PotentialOwner) ModelUtil.createFeature(
- task,
- PACKAGE.getActivity_Resources(),
- PACKAGE.getPotentialOwner());
- resourceAssignment = (ResourceAssignmentExpression) ModelUtil.createFeature(
- owner,
- PACKAGE.getResourceRole_ResourceAssignmentExpression(),
- PACKAGE.getResourceAssignmentExpression());
- expression = (FormalExpression) ModelUtil.createFeature(
- resourceAssignment,
- PACKAGE.getResourceAssignmentExpression_Expression(),
- PACKAGE.getFormalExpression());
+ owner = FACTORY.createPotentialOwner();
+ InsertionAdapter.add(task, PACKAGE.getActivity_Resources(), owner);
+
+ resourceAssignment = FACTORY.createResourceAssignmentExpression();
+ InsertionAdapter.add(owner, PACKAGE.getResourceRole_ResourceAssignmentExpression(), resourceAssignment);
+
+ expression = FACTORY.createFormalExpression();
+ InsertionAdapter.add(resourceAssignment, PACKAGE.getResourceAssignmentExpression_Expression(), expression);
}
else if (task.getResources().get(0) instanceof PotentialOwner){
owner = (PotentialOwner)task.getResources().get(0);
diff --git a/org.eclipse.bpmn2.modeler.runtime.jboss.jbpm5/src/org/eclipse/bpmn2/modeler/runtime/jboss/jbpm5/validation/BusinessRuleTaskConstraint.java b/org.eclipse.bpmn2.modeler.runtime.jboss.jbpm5/src/org/eclipse/bpmn2/modeler/runtime/jboss/jbpm5/validation/BusinessRuleTaskConstraint.java
new file mode 100644
index 0000000..84d489a
--- /dev/null
+++ b/org.eclipse.bpmn2.modeler.runtime.jboss.jbpm5/src/org/eclipse/bpmn2/modeler/runtime/jboss/jbpm5/validation/BusinessRuleTaskConstraint.java
@@ -0,0 +1,39 @@
+package org.eclipse.bpmn2.modeler.runtime.jboss.jbpm5.validation;
+
+import java.util.Iterator;
+
+import org.eclipse.bpmn2.BusinessRuleTask;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.util.FeatureMap;
+import org.eclipse.emf.validation.AbstractModelConstraint;
+import org.eclipse.emf.validation.IValidationContext;
+
+public class BusinessRuleTaskConstraint extends AbstractModelConstraint {
+
+ @Override
+ public IStatus validate(IValidationContext ctx) {
+ EObject eObj = ctx.getTarget();
+ if (eObj instanceof BusinessRuleTask) {
+ BusinessRuleTask bt = (BusinessRuleTask)eObj;
+
+ Iterator<FeatureMap.Entry> biter = bt.getAnyAttribute().iterator();
+ boolean foundRuleflowGroup = false;
+ while (biter.hasNext()) {
+ FeatureMap.Entry entry = biter.next();
+ if (entry.getEStructuralFeature().getName().equals("ruleFlowGroup")) {
+ foundRuleflowGroup = true;
+ String ruleflowGroup = (String) entry.getValue();
+ if (ruleflowGroup==null || ruleflowGroup.isEmpty()) {
+ return ctx.createFailureStatus("Business Rule Task has no ruleflow group");
+ }
+ }
+ }
+ if (!foundRuleflowGroup) {
+ return ctx.createFailureStatus("Business Rule Task has no ruleflow group");
+ }
+ }
+ return ctx.createSuccessStatus();
+ }
+
+}
diff --git a/org.eclipse.bpmn2.modeler.runtime.jboss.jbpm5/src/org/eclipse/bpmn2/modeler/runtime/jboss/jbpm5/validation/CallActivityConstraint.java b/org.eclipse.bpmn2.modeler.runtime.jboss.jbpm5/src/org/eclipse/bpmn2/modeler/runtime/jboss/jbpm5/validation/CallActivityConstraint.java
new file mode 100644
index 0000000..369988f
--- /dev/null
+++ b/org.eclipse.bpmn2.modeler.runtime.jboss.jbpm5/src/org/eclipse/bpmn2/modeler/runtime/jboss/jbpm5/validation/CallActivityConstraint.java
@@ -0,0 +1,49 @@
+package org.eclipse.bpmn2.modeler.runtime.jboss.jbpm5.validation;
+
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.eclipse.bpmn2.CallActivity;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.validation.AbstractModelConstraint;
+import org.eclipse.emf.validation.IValidationContext;
+
+public class CallActivityConstraint extends AbstractModelConstraint {
+ private IDiagramProfile profile;
+ private String uuid = "uuid";
+
+ @Override
+ public IStatus validate(IValidationContext ctx) {
+ EObject eObj = ctx.getTarget();
+ if (eObj instanceof CallActivity) {
+ CallActivity ca = (CallActivity) eObj;
+ if (ca.getCalledElementRef() == null) {
+ ctx.createFailureStatus("Reusable Subprocess has no called element specified.");
+ } else {
+ String[] packageAssetInfo = ServletUtil.findPackageAndAssetInfo(uuid, profile);
+ String packageName = packageAssetInfo[0];
+ List<String> allProcessesInPackage = ServletUtil.getAllProcessesInPackage(packageName, profile);
+ boolean foundCalledElementProcess = false;
+ for (String p : allProcessesInPackage) {
+ String processContent = ServletUtil.getProcessSourceContent(packageName, p, profile);
+ Pattern pattern = Pattern.compile("<\\S*process[\\s\\S]*id=\"" + ca.getCalledElementRef() + "\"",
+ Pattern.MULTILINE);
+ Matcher m = pattern.matcher(processContent);
+ if (m.find()) {
+ foundCalledElementProcess = true;
+ break;
+ }
+ }
+ foundCalledElementProcess = true; // TODO: remove this
+ if (!foundCalledElementProcess) {
+ ctx.createFailureStatus("No existing process with id=" + ca.getCalledElementRef()
+ + " could be found.");
+ }
+ }
+ }
+ return ctx.createSuccessStatus();
+ }
+
+}
diff --git a/org.eclipse.bpmn2.modeler.runtime.jboss.jbpm5/src/org/eclipse/bpmn2/modeler/runtime/jboss/jbpm5/validation/DroolsPackage.java b/org.eclipse.bpmn2.modeler.runtime.jboss.jbpm5/src/org/eclipse/bpmn2/modeler/runtime/jboss/jbpm5/validation/DroolsPackage.java
new file mode 100644
index 0000000..e22a453
--- /dev/null
+++ b/org.eclipse.bpmn2.modeler.runtime.jboss.jbpm5/src/org/eclipse/bpmn2/modeler/runtime/jboss/jbpm5/validation/DroolsPackage.java
@@ -0,0 +1,13 @@
+package org.eclipse.bpmn2.modeler.runtime.jboss.jbpm5.validation;
+
+import org.eclipse.emf.ecore.EStructuralFeature;
+
+public class DroolsPackage {
+
+ public interface Literals {
+
+ EStructuralFeature DOCUMENT_ROOT__METADATA = null;
+
+ }
+
+}
diff --git a/org.eclipse.bpmn2.modeler.runtime.jboss.jbpm5/src/org/eclipse/bpmn2/modeler/runtime/jboss/jbpm5/validation/GatewayConstraint.java b/org.eclipse.bpmn2.modeler.runtime.jboss.jbpm5/src/org/eclipse/bpmn2/modeler/runtime/jboss/jbpm5/validation/GatewayConstraint.java
new file mode 100644
index 0000000..2381519
--- /dev/null
+++ b/org.eclipse.bpmn2.modeler.runtime.jboss.jbpm5/src/org/eclipse/bpmn2/modeler/runtime/jboss/jbpm5/validation/GatewayConstraint.java
@@ -0,0 +1,67 @@
+package org.eclipse.bpmn2.modeler.runtime.jboss.jbpm5.validation;
+
+import java.util.List;
+
+import org.eclipse.bpmn2.ExtensionAttributeValue;
+import org.eclipse.bpmn2.Gateway;
+import org.eclipse.bpmn2.ParallelGateway;
+import org.eclipse.bpmn2.SequenceFlow;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.util.FeatureMap;
+import org.eclipse.emf.validation.AbstractModelConstraint;
+import org.eclipse.emf.validation.IValidationContext;
+
+public class GatewayConstraint extends AbstractModelConstraint {
+
+ @Override
+ public IStatus validate(IValidationContext ctx) {
+ EObject eObj = ctx.getTarget();
+
+ if (!(eObj instanceof ParallelGateway)) {
+ Gateway gw = (Gateway) eObj;
+
+ List<SequenceFlow> outgoingGwSequenceFlows = gw.getOutgoing();
+ if (outgoingGwSequenceFlows != null && outgoingGwSequenceFlows.size() > 0) {
+ int sum = 0;
+ for (SequenceFlow sf : outgoingGwSequenceFlows) {
+ // simulation validation
+ if (sf.getExtensionValues() != null && sf.getExtensionValues().size() > 0) {
+ boolean foundProbability = false;
+ for (ExtensionAttributeValue extattrval : sf.getExtensionValues()) {
+ FeatureMap extensionElements = extattrval.getValue();
+ @SuppressWarnings("unchecked")
+ List<MetadataType> metadataTypeExtensions = (List<MetadataType>) extensionElements.get(
+ DroolsPackage.Literals.DOCUMENT_ROOT__METADATA, true);
+ if (metadataTypeExtensions != null && metadataTypeExtensions.size() > 0) {
+ MetadataType metaType = metadataTypeExtensions.get(0);
+ for (Object metaEntryObj : metaType.getMetaentry()) {
+ MetaentryType entry = (MetaentryType) metaEntryObj;
+ if (entry.getName() != null && entry.getName().equals("probability")) {
+ Integer i = new Integer(entry.getValue());
+ if (i < 0) {
+ ctx.addResult(sf);
+ ctx.createFailureStatus("Probability value must be positive.");
+ } else {
+ sum += i;
+ }
+ foundProbability = true;
+ }
+ }
+ }
+ }
+ if (!foundProbability) {
+ ctx.addResult(sf);
+ ctx.createFailureStatus("Sequence Flow has no probability defined.");
+ }
+ }
+ }
+ if (sum != 100) {
+ ctx.createFailureStatus("The sum of probability values of all outgoing Sequence Flows must be equal 100.");
+ }
+ }
+ }
+ return ctx.createSuccessStatus();
+ }
+
+}
diff --git a/org.eclipse.bpmn2.modeler.runtime.jboss.jbpm5/src/org/eclipse/bpmn2/modeler/runtime/jboss/jbpm5/validation/IDiagramProfile.java b/org.eclipse.bpmn2.modeler.runtime.jboss.jbpm5/src/org/eclipse/bpmn2/modeler/runtime/jboss/jbpm5/validation/IDiagramProfile.java
new file mode 100644
index 0000000..d896802
--- /dev/null
+++ b/org.eclipse.bpmn2.modeler.runtime.jboss.jbpm5/src/org/eclipse/bpmn2/modeler/runtime/jboss/jbpm5/validation/IDiagramProfile.java
@@ -0,0 +1,5 @@
+package org.eclipse.bpmn2.modeler.runtime.jboss.jbpm5.validation;
+
+public interface IDiagramProfile {
+
+}
diff --git a/org.eclipse.bpmn2.modeler.runtime.jboss.jbpm5/src/org/eclipse/bpmn2/modeler/runtime/jboss/jbpm5/validation/MetadataType.java b/org.eclipse.bpmn2.modeler.runtime.jboss.jbpm5/src/org/eclipse/bpmn2/modeler/runtime/jboss/jbpm5/validation/MetadataType.java
new file mode 100644
index 0000000..374d5b2
--- /dev/null
+++ b/org.eclipse.bpmn2.modeler.runtime.jboss.jbpm5/src/org/eclipse/bpmn2/modeler/runtime/jboss/jbpm5/validation/MetadataType.java
@@ -0,0 +1,12 @@
+package org.eclipse.bpmn2.modeler.runtime.jboss.jbpm5.validation;
+
+import java.util.List;
+
+public class MetadataType {
+
+ public List getMetaentry() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+}
\ No newline at end of file
diff --git a/org.eclipse.bpmn2.modeler.runtime.jboss.jbpm5/src/org/eclipse/bpmn2/modeler/runtime/jboss/jbpm5/validation/MetaentryType.java b/org.eclipse.bpmn2.modeler.runtime.jboss.jbpm5/src/org/eclipse/bpmn2/modeler/runtime/jboss/jbpm5/validation/MetaentryType.java
new file mode 100644
index 0000000..4e07769
--- /dev/null
+++ b/org.eclipse.bpmn2.modeler.runtime.jboss.jbpm5/src/org/eclipse/bpmn2/modeler/runtime/jboss/jbpm5/validation/MetaentryType.java
@@ -0,0 +1,15 @@
+package org.eclipse.bpmn2.modeler.runtime.jboss.jbpm5.validation;
+
+public class MetaentryType {
+
+ public String getValue() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public Object getName() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+}
\ No newline at end of file
diff --git a/org.eclipse.bpmn2.modeler.runtime.jboss.jbpm5/src/org/eclipse/bpmn2/modeler/runtime/jboss/jbpm5/validation/ProcessConstraint.java b/org.eclipse.bpmn2.modeler.runtime.jboss.jbpm5/src/org/eclipse/bpmn2/modeler/runtime/jboss/jbpm5/validation/ProcessConstraint.java
new file mode 100644
index 0000000..5868d8c
--- /dev/null
+++ b/org.eclipse.bpmn2.modeler.runtime.jboss.jbpm5/src/org/eclipse/bpmn2/modeler/runtime/jboss/jbpm5/validation/ProcessConstraint.java
@@ -0,0 +1,44 @@
+package org.eclipse.bpmn2.modeler.runtime.jboss.jbpm5.validation;
+
+import java.util.Iterator;
+
+import org.eclipse.bpmn2.Bpmn2Package;
+import org.eclipse.bpmn2.Process;
+import org.eclipse.bpmn2.modeler.runtime.jboss.jbpm5.model.ModelPackage;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.util.FeatureMap;
+import org.eclipse.emf.validation.AbstractModelConstraint;
+import org.eclipse.emf.validation.IValidationContext;
+
+public class ProcessConstraint extends AbstractModelConstraint {
+
+ @Override
+ public IStatus validate(IValidationContext ctx) {
+ EObject eObj = ctx.getTarget();
+ if (eObj instanceof Process) {
+ Process process = (Process)eObj;
+
+ String name = null;
+ Iterator<FeatureMap.Entry> iter = process.getAnyAttribute().iterator();
+ while (iter.hasNext()) {
+ FeatureMap.Entry entry = iter.next();
+ if (entry.getEStructuralFeature().getName().equals("packageName")) {
+ name = (String) entry.getValue();
+ if (name==null || name.isEmpty()) {
+ ctx.addResult(entry.getEStructuralFeature());
+ return ctx.createFailureStatus("Process has no package name.");
+ }
+ }
+ }
+
+ name = process.getName();
+ if (name==null || name.isEmpty()) {
+ ctx.addResult(process.eClass().getEStructuralFeature("name"));
+ return ctx.createFailureStatus("Process has no name.");
+ }
+ }
+ return ctx.createSuccessStatus();
+ }
+
+}
diff --git a/org.eclipse.bpmn2.modeler.runtime.jboss.jbpm5/src/org/eclipse/bpmn2/modeler/runtime/jboss/jbpm5/validation/ServletUtil.java b/org.eclipse.bpmn2.modeler.runtime.jboss.jbpm5/src/org/eclipse/bpmn2/modeler/runtime/jboss/jbpm5/validation/ServletUtil.java
new file mode 100644
index 0000000..798ee46
--- /dev/null
+++ b/org.eclipse.bpmn2.modeler.runtime.jboss.jbpm5/src/org/eclipse/bpmn2/modeler/runtime/jboss/jbpm5/validation/ServletUtil.java
@@ -0,0 +1,25 @@
+package org.eclipse.bpmn2.modeler.runtime.jboss.jbpm5.validation;
+
+import java.util.List;
+
+public class ServletUtil {
+
+ public static String[] findPackageAndAssetInfo(String uuid, IDiagramProfile profile) {
+ return new String[] {uuid};
+ }
+
+ public static boolean assetExistsInGuvnor(String string, String taskFormName, IDiagramProfile profile) {
+ return true;
+ }
+
+ public static List<String> getAllProcessesInPackage(String packageName, IDiagramProfile profile) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public static String getProcessSourceContent(String packageName, String p, IDiagramProfile profile) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+}
diff --git a/org.eclipse.bpmn2.modeler.runtime.jboss.jbpm5/src/org/eclipse/bpmn2/modeler/runtime/jboss/jbpm5/validation/TaskConstraint.java b/org.eclipse.bpmn2.modeler.runtime.jboss.jbpm5/src/org/eclipse/bpmn2/modeler/runtime/jboss/jbpm5/validation/TaskConstraint.java
new file mode 100644
index 0000000..4819666
--- /dev/null
+++ b/org.eclipse.bpmn2.modeler.runtime.jboss.jbpm5/src/org/eclipse/bpmn2/modeler/runtime/jboss/jbpm5/validation/TaskConstraint.java
@@ -0,0 +1,102 @@
+package org.eclipse.bpmn2.modeler.runtime.jboss.jbpm5.validation;
+
+import java.util.Iterator;
+import java.util.List;
+
+import org.eclipse.bpmn2.ExtensionAttributeValue;
+import org.eclipse.bpmn2.Task;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.util.FeatureMap;
+import org.eclipse.emf.validation.AbstractModelConstraint;
+import org.eclipse.emf.validation.IValidationContext;
+
+public class TaskConstraint extends AbstractModelConstraint {
+
+ @Override
+ public IStatus validate(IValidationContext ctx) {
+ EObject eObj = ctx.getTarget();
+ if (eObj instanceof Task) {
+ Task ta = (Task) eObj;
+
+ if (ta.getExtensionValues() != null && ta.getExtensionValues().size() > 0) {
+ boolean foundDistributionType = false;
+ String distributionTypeValue = "";
+ boolean foundDuration = false;
+ boolean foundTimeUnits = false;
+ boolean foundRange = false;
+ boolean foundStandardDeviation = false;
+ for (ExtensionAttributeValue extattrval : ta.getExtensionValues()) {
+ FeatureMap extensionElements = extattrval.getValue();
+ @SuppressWarnings("unchecked")
+ List<MetadataType> metadataTypeExtensions = (List<MetadataType>) extensionElements.get(
+ DroolsPackage.Literals.DOCUMENT_ROOT__METADATA, true);
+
+ if (metadataTypeExtensions != null && metadataTypeExtensions.size() > 0) {
+ MetadataType metaType = metadataTypeExtensions.get(0);
+ for (Object metaEntryObj : metaType.getMetaentry()) {
+ MetaentryType entry = (MetaentryType) metaEntryObj;
+ if (entry.getName() != null && entry.getName().equals("costpertimeunit")) {
+ Float f = new Float(entry.getValue());
+ if (f.floatValue() < 0) {
+ ctx.createFailureStatus("Cost per Time Unit value must be positive");
+ }
+ }
+ if (entry.getName() != null && entry.getName().equals("distributiontype")) {
+ foundDistributionType = true;
+ distributionTypeValue = entry.getValue();
+ }
+ if (entry.getName() != null && entry.getName().equals("duration")) {
+ Float f = new Float(entry.getValue());
+ if (f.floatValue() < 0) {
+ ctx.createFailureStatus("Duration value must be positive");
+ }
+ foundDuration = true;
+ }
+ if (entry.getName() != null && entry.getName().equals("timeunit")) {
+ foundTimeUnits = true;
+ }
+ if (entry.getName() != null && entry.getName().equals("workinghours")) {
+ Float f = new Float(entry.getValue());
+ if (f.floatValue() < 0) {
+ ctx.createFailureStatus("Working Hours value must be positive");
+ }
+ }
+ if (entry.getName() != null && entry.getName().equals("range")) {
+ Float f = new Float(entry.getValue());
+ if (f.floatValue() < 0) {
+ ctx.createFailureStatus("Range value must be positive");
+ }
+ foundRange = true;
+ }
+ if (entry.getName() != null && entry.getName().equals("standarddeviation")) {
+ foundStandardDeviation = true;
+ }
+ }
+ }
+
+ }
+ if (!foundDistributionType) {
+ ctx.createFailureStatus("Task has no distribution type defined");
+ }
+ if (!foundDuration) {
+ ctx.createFailureStatus("Task has no duration defined");
+ }
+ if (!foundTimeUnits) {
+ ctx.createFailureStatus("Task has no Time Units defined");
+ }
+ if (foundDistributionType) {
+ if ((distributionTypeValue.equals("random") || distributionTypeValue.equals("uniform"))
+ && !foundRange) {
+ ctx.createFailureStatus("Task has no Range defined");
+ }
+ if (distributionTypeValue.equals("normal") && !foundStandardDeviation) {
+ ctx.createFailureStatus("Task has no Standard Deviation defined");
+ }
+ }
+ }
+ }
+ return ctx.createSuccessStatus();
+ }
+
+}
diff --git a/org.eclipse.bpmn2.modeler.runtime.jboss.jbpm5/src/org/eclipse/bpmn2/modeler/runtime/jboss/jbpm5/validation/UserTaskConstraint.java b/org.eclipse.bpmn2.modeler.runtime.jboss.jbpm5/src/org/eclipse/bpmn2/modeler/runtime/jboss/jbpm5/validation/UserTaskConstraint.java
new file mode 100644
index 0000000..250e66a
--- /dev/null
+++ b/org.eclipse.bpmn2.modeler.runtime.jboss.jbpm5/src/org/eclipse/bpmn2/modeler/runtime/jboss/jbpm5/validation/UserTaskConstraint.java
@@ -0,0 +1,80 @@
+package org.eclipse.bpmn2.modeler.runtime.jboss.jbpm5.validation;
+
+import java.util.Iterator;
+import java.util.List;
+
+import org.eclipse.bpmn2.ExtensionAttributeValue;
+import org.eclipse.bpmn2.UserTask;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.util.FeatureMap;
+import org.eclipse.emf.validation.AbstractModelConstraint;
+import org.eclipse.emf.validation.IValidationContext;
+
+public class UserTaskConstraint extends AbstractModelConstraint {
+ private IDiagramProfile profile;
+ private String uuid = "uuid";
+
+ @Override
+ public IStatus validate(IValidationContext ctx) {
+ EObject eObj = ctx.getTarget();
+ if (eObj instanceof UserTask) {
+ UserTask ut = (UserTask)eObj;
+
+ String taskName = null;
+ Iterator<FeatureMap.Entry> utiter = ut.getAnyAttribute().iterator();
+ boolean foundTaskName = false;
+ while (utiter.hasNext()) {
+ FeatureMap.Entry entry = utiter.next();
+ if (entry.getEStructuralFeature().getName().equals("taskName")) {
+ foundTaskName = true;
+ taskName = (String) entry.getValue();
+ if (taskName==null || taskName.isEmpty()) {
+ return ctx.createFailureStatus("User Task has no task name");
+ }
+ }
+ }
+ if (!foundTaskName) {
+ return ctx.createFailureStatus("User Task has no task name");
+ } else {
+ // TODO:
+ if (taskName != null) {
+ String[] packageAssetInfo = ServletUtil.findPackageAndAssetInfo(uuid, profile);
+ String taskFormName = taskName + "-taskform";
+ if (!ServletUtil.assetExistsInGuvnor(packageAssetInfo[0], taskFormName, profile)) {
+ ctx.createFailureStatus("User Task has no task form defined");
+ }
+ }
+ }
+
+ // simulation validation
+ if (ut.getExtensionValues() != null && ut.getExtensionValues().size() > 0) {
+ boolean foundStaffAvailability = false;
+ for (ExtensionAttributeValue extattrval : ut.getExtensionValues()) {
+ FeatureMap extensionElements = extattrval.getValue();
+ @SuppressWarnings("unchecked")
+ List<MetadataType> metadataTypeExtensions = (List<MetadataType>) extensionElements.get(
+ DroolsPackage.Literals.DOCUMENT_ROOT__METADATA, true);
+ if (metadataTypeExtensions != null && metadataTypeExtensions.size() > 0) {
+ MetadataType metaType = metadataTypeExtensions.get(0);
+ for (Object metaEntryObj : metaType.getMetaentry()) {
+ MetaentryType entry = (MetaentryType) metaEntryObj;
+ if (entry.getName() != null && entry.getName().equals("staffavailability")) {
+ Float f = new Float(entry.getValue());
+ if (f.floatValue() < 0) {
+ ctx.createFailureStatus("Staff Availability value must be positive");
+ }
+ foundStaffAvailability = true;
+ }
+ }
+ }
+ if (!foundStaffAvailability) {
+ return ctx.createFailureStatus("User Task has no staff availability defined");
+ }
+ }
+ }
+ }
+ return ctx.createSuccessStatus();
+ }
+
+}
diff --git a/org.eclipse.bpmn2.modeler.ui/src/org/eclipse/bpmn2/modeler/ui/editor/BPMN2Editor.java b/org.eclipse.bpmn2.modeler.ui/src/org/eclipse/bpmn2/modeler/ui/editor/BPMN2Editor.java
index 50259a7..763cb1d 100644
--- a/org.eclipse.bpmn2.modeler.ui/src/org/eclipse/bpmn2/modeler/ui/editor/BPMN2Editor.java
+++ b/org.eclipse.bpmn2.modeler.ui/src/org/eclipse/bpmn2/modeler/ui/editor/BPMN2Editor.java
@@ -93,6 +93,8 @@
import org.eclipse.ui.IEditorSite;
import org.eclipse.ui.IFileEditorInput;
import org.eclipse.ui.IPartListener2;
+import org.eclipse.ui.IViewPart;
+import org.eclipse.ui.IViewReference;
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.IWorkbenchListener;
import org.eclipse.ui.IWorkbenchPage;
@@ -104,8 +106,10 @@
import org.eclipse.ui.ide.IGotoMarker;
import org.eclipse.ui.ide.ResourceUtil;
import org.eclipse.ui.part.FileEditorInput;
+import org.eclipse.ui.part.IPage;
import org.eclipse.ui.progress.IProgressService;
import org.eclipse.ui.views.properties.IPropertySheetPage;
+import org.eclipse.ui.views.properties.PropertySheet;
import org.eclipse.ui.views.properties.tabbed.ITabDescriptorProvider;
import org.eclipse.wst.validation.ValidationState;
@@ -405,7 +409,23 @@
} catch (CoreException e) {
Activator.logStatus(e.getStatus());
}
-
+
+ IWorkbenchPage page = getEditorSite().getPage();
+ String viewID = "org.eclipse.ui.views.PropertySheet";
+ try {
+ IViewReference[] views = page.getViewReferences();
+ for (IViewReference v : views) {
+ if (viewID.equals(v.getId())) {
+ PropertySheet ps = (PropertySheet)v.getView(true);
+ IPage pp = ps.getCurrentPage();
+ if (pp instanceof Bpmn2TabbedPropertySheetPage) {
+ ((Bpmn2TabbedPropertySheetPage)pp).refresh();
+ }
+ }
+ }
+ }
+ catch (Exception e) {
+ }
}
private EObject getTargetObject(IMarker marker) {