/* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @Autor Yvo Swillens
*
* Updates existing (Flow)elements in Activiti Diagram
* based on elements in BPMN2.0.xml
*/
package org.activiti.designer.eclipse.editor.sync;
import java.io.InputStreamReader;
import java.util.Iterator;
import java.util.List;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamReader;
import org.activiti.designer.eclipse.bpmn.BpmnParser;
import org.activiti.designer.eclipse.bpmn.SequenceFlowModel;
import org.eclipse.bpmn2.BaseElement;
import org.eclipse.bpmn2.BusinessRuleTask;
import org.eclipse.bpmn2.CandidateGroup;
import org.eclipse.bpmn2.CandidateUser;
import org.eclipse.bpmn2.FieldExtension;
import org.eclipse.bpmn2.FlowElement;
import org.eclipse.bpmn2.MailTask;
import org.eclipse.bpmn2.ScriptTask;
import org.eclipse.bpmn2.SequenceFlow;
import org.eclipse.bpmn2.ServiceTask;
import org.eclipse.bpmn2.Task;
import org.eclipse.bpmn2.UserTask;
import org.eclipse.core.resources.IStorage;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.transaction.RecordingCommand;
import org.eclipse.emf.transaction.TransactionalEditingDomain;
import org.eclipse.graphiti.dt.IDiagramTypeProvider;
import org.eclipse.graphiti.features.IFeatureProvider;
import org.eclipse.graphiti.features.IReason;
import org.eclipse.graphiti.features.IUpdateFeature;
import org.eclipse.graphiti.features.context.impl.UpdateContext;
import org.eclipse.graphiti.mm.pictograms.Diagram;
import org.eclipse.graphiti.mm.pictograms.PictogramElement;
import org.eclipse.graphiti.ui.services.GraphitiUi;
/**
* @author Yvo Swillens
*/
public class DiagramUpdater extends RecordingCommand {
Diagram diagram;
IStorage bpmnStorage;
public DiagramUpdater(TransactionalEditingDomain editingDomain,
Diagram diagram, IStorage bpmnStorage) {
super(editingDomain);
this.diagram = diagram;
this.bpmnStorage = bpmnStorage;
}
@Override
protected void doExecute() {
syncDiagram();
}
private void syncDiagram() {
if (diagram == null) {
System.out.println("diagram cannot be null");
return;
}
if (bpmnStorage == null) {
System.out.println("bpmnStorage cannot be null");
return;
}
IDiagramTypeProvider dtp = GraphitiUi.getExtensionManager().createDiagramTypeProvider(diagram,
GraphitiUi.getExtensionManager().getDiagramTypeProviderId(diagram.getDiagramTypeId())); //$NON-NLS-1$
IFeatureProvider featureProvider = dtp.getFeatureProvider();
BpmnParser bpmnParser = readBpmn(bpmnStorage);
if (bpmnParser.process != null) {
updateProcessInDiagram(diagram, bpmnParser.process);
}
if (bpmnParser.bpmnList == null || bpmnParser.bpmnList.size() == 0)
return;
updateFlowElementsInDiagram(diagram, bpmnParser.bpmnList, featureProvider);
if (bpmnParser.sequenceFlowList == null || bpmnParser.sequenceFlowList.size() == 0)
return;
updateSequenceFlowsInDiagram(diagram, bpmnParser.sequenceFlowList);
}
private static BpmnParser readBpmn(IStorage bpmnStorage) {
BpmnParser bpmnParser = new BpmnParser();
try {
XMLInputFactory xif = XMLInputFactory.newInstance();
InputStreamReader in = new InputStreamReader(bpmnStorage.getContents(), "UTF-8");
XMLStreamReader xtr = xif.createXMLStreamReader(in);
bpmnParser.parseBpmn(xtr);
xtr.close();
in.close();
} catch (Exception e) {
e.printStackTrace();
}
return bpmnParser;
}
private static void updateFlowElementsInDiagram(final Diagram diagram, final List<FlowElement> bpmnFlowElements,
IFeatureProvider featureProvider) {
for (FlowElement bpmnFlowElement : bpmnFlowElements) {
FlowElement diagramFlowElement = lookupFlowElementInDiagram(bpmnFlowElement, diagram);
if (diagramFlowElement != null) {
diagramFlowElement.setName(bpmnFlowElement.getName());
if (diagramFlowElement instanceof UserTask && bpmnFlowElement instanceof UserTask) {
UserTask targetUserTask = (UserTask) diagramFlowElement;
UserTask parsedUserTask = (UserTask) bpmnFlowElement;
targetUserTask.setAssignee(parsedUserTask.getAssignee());
targetUserTask.setFormKey(parsedUserTask.getFormKey());
targetUserTask.setPriority(parsedUserTask.getPriority());
targetUserTask.setDueDate(parsedUserTask.getDueDate());
targetUserTask.getFormProperties().clear();
targetUserTask.getFormProperties().addAll(parsedUserTask.getFormProperties());
Iterator<CandidateGroup> itCandidateGroup = targetUserTask.getCandidateGroups().iterator();
while (itCandidateGroup.hasNext()) {
diagram.eResource().getContents().remove(itCandidateGroup.next());
}
targetUserTask.getCandidateGroups().clear();
if (parsedUserTask.getCandidateGroups() != null) {
for (CandidateGroup candidateGroup : parsedUserTask.getCandidateGroups()) {
diagram.eResource().getContents().add(candidateGroup);
targetUserTask.getCandidateGroups().add(candidateGroup);
}
}
Iterator<CandidateUser> itCandidateUser = targetUserTask.getCandidateUsers().iterator();
while (itCandidateUser.hasNext()) {
diagram.eResource().getContents().remove(itCandidateUser.next());
}
targetUserTask.getCandidateUsers().clear();
if (parsedUserTask.getCandidateUsers() != null) {
for (CandidateUser candidateUser : parsedUserTask.getCandidateUsers()) {
diagram.eResource().getContents().add(candidateUser);
targetUserTask.getCandidateUsers().add(candidateUser);
}
}
} else if (diagramFlowElement instanceof ScriptTask && bpmnFlowElement instanceof ScriptTask) {
ScriptTask targetScriptTask = (ScriptTask) diagramFlowElement;
ScriptTask parsedScriptTask = (ScriptTask) bpmnFlowElement;
targetScriptTask.setScriptFormat(parsedScriptTask.getScriptFormat());
targetScriptTask.setScript(parsedScriptTask.getScript());
} else if (diagramFlowElement instanceof ServiceTask && bpmnFlowElement instanceof ServiceTask) {
ServiceTask targetServiceTask = (ServiceTask) diagramFlowElement;
ServiceTask parsedServiceTask = (ServiceTask) bpmnFlowElement;
targetServiceTask.setImplementationType(parsedServiceTask.getImplementationType());
targetServiceTask.setImplementation(parsedServiceTask.getImplementation());
targetServiceTask.setResultVariableName(parsedServiceTask.getResultVariableName());
Iterator<FieldExtension> itField = targetServiceTask.getFieldExtensions().iterator();
while (itField.hasNext()) {
diagram.eResource().getContents().remove(itField.next());
}
targetServiceTask.getFieldExtensions().clear();
if (parsedServiceTask.getFieldExtensions() != null) {
for (FieldExtension fieldExtension : parsedServiceTask.getFieldExtensions()) {
diagram.eResource().getContents().add(fieldExtension);
targetServiceTask.getFieldExtensions().add(fieldExtension);
}
}
} else if (diagramFlowElement instanceof BusinessRuleTask && bpmnFlowElement instanceof BusinessRuleTask) {
BusinessRuleTask targetBusinessRuleTask = (BusinessRuleTask) diagramFlowElement;
BusinessRuleTask parsedBusinessRuleTask = (BusinessRuleTask) bpmnFlowElement;
targetBusinessRuleTask.setResultVariableName(parsedBusinessRuleTask.getResultVariableName());
targetBusinessRuleTask.setExclude(parsedBusinessRuleTask.isExclude());
targetBusinessRuleTask.getRuleNames().clear();
targetBusinessRuleTask.getRuleNames().addAll(parsedBusinessRuleTask.getRuleNames());
targetBusinessRuleTask.getInputVariables().clear();
targetBusinessRuleTask.getInputVariables().addAll(parsedBusinessRuleTask.getInputVariables());
} else if (diagramFlowElement instanceof MailTask && bpmnFlowElement instanceof MailTask) {
MailTask targetMailTask = (MailTask) diagramFlowElement;
MailTask parsedMailTask = (MailTask) bpmnFlowElement;
targetMailTask.setBcc(parsedMailTask.getBcc());
targetMailTask.setCc(parsedMailTask.getCc());
targetMailTask.setFrom(parsedMailTask.getFrom());
targetMailTask.setHtml(parsedMailTask.getHtml());
targetMailTask.setSubject(parsedMailTask.getSubject());
targetMailTask.setText(parsedMailTask.getText());
targetMailTask.setTo(parsedMailTask.getTo());
}
if (diagramFlowElement instanceof Task && bpmnFlowElement instanceof Task) {
Task targetTask = (Task) diagramFlowElement;
Task parsedTask = (Task) bpmnFlowElement;
targetTask.setLoopCharacteristics(parsedTask.getLoopCharacteristics());
targetTask.setAsynchronous(parsedTask.isAsynchronous());
targetTask.getActivitiListeners().clear();
if (parsedTask.getActivitiListeners() != null) {
targetTask.getActivitiListeners().addAll(parsedTask.getActivitiListeners());
}
}
updatePictogramContext(diagramFlowElement, featureProvider);
}
}
}
private static void updateSequenceFlowsInDiagram(final Diagram diagram,
final List<SequenceFlowModel> sequenceFlowElements) {
for (SequenceFlowModel sequenceFlowModel : sequenceFlowElements) {
SequenceFlow diagramFlowElement = lookupSequenceFlowInDiagram(sequenceFlowModel, diagram);
if (diagramFlowElement != null) {
if (sequenceFlowModel.conditionExpression != null) {
diagramFlowElement.setConditionExpression(sequenceFlowModel.conditionExpression);
}
if (sequenceFlowModel.listenerList != null) {
diagramFlowElement.getExecutionListeners().clear();
diagramFlowElement.getExecutionListeners().addAll(sequenceFlowModel.listenerList);
}
}
}
}
private static void updateProcessInDiagram(final Diagram diagram, final org.eclipse.bpmn2.Process process) {
org.eclipse.bpmn2.Process diagramElement = lookupProcessInDiagram(diagram);
if (diagramElement != null) {
if (process.getExecutionListeners() != null) {
diagramElement.getExecutionListeners().clear();
diagramElement.getExecutionListeners().addAll(process.getExecutionListeners());
}
}
}
private static void updatePictogramContext(BaseElement source, IFeatureProvider featureProvider) {
PictogramElement pictoElem = featureProvider.getPictogramElementForBusinessObject(source);
UpdateContext context = new UpdateContext(pictoElem);
IUpdateFeature feature = featureProvider.getUpdateFeature(context);
if (feature.canUpdate(context)) {
IReason reason = feature.updateNeeded(context);
if (reason.toBoolean()) {
feature.update(context);
}
}
}
private static FlowElement lookupFlowElementInDiagram(FlowElement sourceElement, Diagram diagram) {
FlowElement modifyElement = null;
for (EObject targetElement : diagram.eResource().getContents()) {
if ((targetElement instanceof FlowElement) && flowIdIsEqual(sourceElement, (FlowElement) targetElement)) {
modifyElement = (FlowElement) targetElement;
break;
}
}
return modifyElement;
}
private static boolean flowIdIsEqual(FlowElement f1, FlowElement f2) {
return f1.getId().equalsIgnoreCase(f2.getId());
}
private static SequenceFlow lookupSequenceFlowInDiagram(SequenceFlowModel sequenceModel, Diagram diagram) {
SequenceFlow modifyElement = null;
for (EObject targetElement : diagram.eResource().getContents()) {
if ((targetElement instanceof SequenceFlow)) {
SequenceFlow sequenceFlow = (SequenceFlow) targetElement;
if (sequenceModel.sourceRef.equals(sequenceFlow.getSourceRef().getId()) && sequenceModel.targetRef.equals(sequenceFlow.getTargetRef().getId())) {
modifyElement = sequenceFlow;
break;
}
}
}
return modifyElement;
}
private static org.eclipse.bpmn2.Process lookupProcessInDiagram(Diagram diagram) {
org.eclipse.bpmn2.Process process = null;
for (EObject targetElement : diagram.eResource().getContents()) {
if ((targetElement instanceof org.eclipse.bpmn2.Process)) {
process = (org.eclipse.bpmn2.Process) targetElement;
break;
}
}
return process;
}
}