
com.effektif.workflow.impl.bpmn.BpmnMappings Maven / Gradle / Ivy
/* Copyright (c) 2014, Effektif GmbH.
*
* 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. */
package com.effektif.workflow.impl.bpmn;
import java.lang.annotation.Annotation;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.SortedSet;
import java.util.TreeSet;
import com.effektif.workflow.api.bpmn.BpmnElement;
import com.effektif.workflow.api.bpmn.BpmnTypeAttribute;
import com.effektif.workflow.api.bpmn.BpmnTypeChildElement;
import com.effektif.workflow.api.bpmn.BpmnWriter;
import com.effektif.workflow.api.bpmn.XmlElement;
import com.effektif.workflow.api.condition.Condition;
import com.effektif.workflow.api.workflow.Activity;
import com.effektif.workflow.api.workflow.Timer;
import com.effektif.workflow.impl.json.Mappings;
import com.effektif.workflow.impl.json.MappingsBuilder;
import com.effektif.workflow.impl.json.PolymorphicMapping;
import com.effektif.workflow.impl.json.TypeField;
/**
* @author Tom Baeyens
*/
public class BpmnMappings extends Mappings {
Map, BpmnTypeMapping> bpmnTypeMappingsByClass = new HashMap<>();
Map> bpmnTypeMappingsByElement = new HashMap<>();
public BpmnMappings(MappingsBuilder mappingsBuilder) {
super(mappingsBuilder);
initializeBpmnMappingFields();
}
public BpmnMappings(Mappings mappings) {
super(mappings);
initializeBpmnMappingFields();
}
protected void initializeBpmnMappingFields() {
PolymorphicMapping activityMapping = polymorphicMappings.get(Activity.class);
for (Class activitySubclass: activityMapping.getSubClasses()) {
registerBpmnSubclass(activitySubclass);
}
PolymorphicMapping conditionMapping = polymorphicMappings.get(Condition.class);
for (Class conditionSubclass: conditionMapping.getSubClasses()) {
registerBpmnSubclass(conditionSubclass);
}
PolymorphicMapping timerMapping = polymorphicMappings.get(Timer.class);
for (Class timerSubclass: timerMapping.getSubClasses()) {
registerBpmnSubclass(timerSubclass);
}
}
protected void registerBpmnSubclass(Class> subClass) {
BpmnElement bpmnElement = subClass.getAnnotation(BpmnElement.class);
if (bpmnElement!=null) {
BpmnTypeMapping bpmnTypeMapping = new BpmnTypeMapping();
String elementName = bpmnElement.value();
bpmnTypeMapping.setBpmnElementName(elementName);
bpmnTypeMapping.setType(subClass);
Annotation[] annotations = subClass.getAnnotations();
for (Annotation annotation: annotations) {
if (annotation instanceof BpmnTypeAttribute) {
BpmnTypeAttribute bpmnTypeAttribute = (BpmnTypeAttribute) annotation;
bpmnTypeMapping.addBpmnTypeAttribute(bpmnTypeAttribute.attribute(), bpmnTypeAttribute.value());
}
if (annotation instanceof BpmnTypeChildElement) {
BpmnTypeChildElement bpmnTypeChildElement = (BpmnTypeChildElement) annotation;
bpmnTypeMapping.setBpmnTypeChildElement(bpmnTypeChildElement.value());
bpmnTypeMapping.setBpmnTypeChildElementRequired(bpmnTypeChildElement.required());
}
}
bpmnTypeMappingsByClass.put(subClass, bpmnTypeMapping);
List typeMappings = bpmnTypeMappingsByElement.get(elementName);
if (typeMappings==null) {
typeMappings = new ArrayList<>();
}
bpmnTypeMappingsByElement.put(elementName, typeMappings);
typeMappings.add(bpmnTypeMapping);
} else {
// throw new RuntimeException("No bpmn element specified on "+subclass);
}
}
/**
* Returns a BPMN type mapping for the given BPMN XML element name.
*/
public BpmnTypeMapping getBpmnTypeMapping(String bpmnElementName) {
return bpmnTypeMappingsByElement.get(bpmnElementName).stream().findFirst().orElse(null);
}
/**
* Returns a BPMN type mapping for the given BPMN XML element, checking that elements match by {@link BpmnElement}
* and, if present, {@link BpmnTypeAttribute} or {@link BpmnTypeChildElement}.
*/
public BpmnTypeMapping getBpmnTypeMapping(XmlElement bpmnActivity, BpmnReaderImpl reader) {
List elementMappings = bpmnTypeMappingsByElement.get(bpmnActivity.getLocalBPMNName());
// Return the first strict match (by attribute or child element), or the first element match otherwise.
return elementMappings == null ? null : elementMappings.stream()
.filter(mapping -> mapping.matches(bpmnActivity, reader))
.findFirst()
.orElse(elementMappings.stream()
.filter(mapping -> mapping.matchesNonStrict(bpmnActivity, reader))
.findFirst().orElse(null));
}
public void writeTypeAttribute(BpmnWriter bpmnWriter, Object o, String attributeName) {
TypeField typeField = typeFields.get(o.getClass());
if (typeField!=null) {
bpmnWriter.writeStringAttributeEffektif(attributeName, typeField.getTypeName());
}
}
public BpmnTypeMapping getBpmnTypeMapping(Class> subClass) {
if (!bpmnTypeMappingsByClass.containsKey(subClass)) {
throw new IllegalArgumentException("No BPMN type mapping defined for " + subClass.getName());
}
return bpmnTypeMappingsByClass.get(subClass);
}
public SortedSet> getBpmnClasses() {
// TODO only add condition classes
SortedSet> bpmnClasses = new TreeSet(new Comparator>() {
public int compare(Class c1, Class c2) {
return c1.getName().compareTo(c2.getName());
}
});
bpmnClasses.addAll(bpmnTypeMappingsByClass.keySet());
return bpmnClasses;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy