package sushi.application.pages.simulator.model; import java.io.Serializable; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import org.apache.wicket.extensions.markup.html.repeater.data.sort.ISortState; import org.apache.wicket.extensions.markup.html.repeater.tree.ISortableTreeProvider; import org.apache.wicket.extensions.markup.html.repeater.util.SingleSortState; import sushi.application.components.table.model.AbstractDataProvider; import sushi.application.pages.simulator.DurationEntryPanel; import sushi.bpmn.decomposition.XORComponent; import sushi.bpmn.element.AbstractBPMNElement; import sushi.bpmn.element.AbstractBPMNGateway; import sushi.bpmn.element.BPMNTask; import sushi.bpmn.element.BPMNXORGateway; import sushi.event.SushiEventType; import sushi.event.attribute.SushiAttribute; import sushi.event.attribute.SushiAttributeTypeEnum; import sushi.event.collection.SushiTree; import sushi.simulation.DerivationType; import sushi.util.Tuple; /** * wraps the given tree nodes * * @param <T> */ /** * @author micha * * @param <T> */ public class SimulationTreeTableProvider<T> extends AbstractDataProvider implements ISortableTreeProvider<SimulationTreeTableElement<T>, String> { private static final long serialVersionUID = 1L; private List<SimulationTreeTableElement<T>> treeTableElements; private List<SimulationTreeTableElement<T>> treeTableRootElements; private List<SimulationTreeTableElement<T>> selectedTreeTableElements = new ArrayList<SimulationTreeTableElement<T>>(); private List<SushiAttribute> correlationAttributes; public SimulationTreeTableProvider() { this.treeTableElements = new ArrayList<SimulationTreeTableElement<T>>(); } /** * constructor * * @param treeNodes root nodes of the tree, child nodes are accessed by this component automatically */ public SimulationTreeTableProvider(ArrayList<SimulationTreeTableElement<T>> treeNodes) { this.treeTableElements = treeNodes; } @Override public void detach() { } @Override public Iterator<? extends SimulationTreeTableElement<T>> getRoots() { return getRootElements().iterator(); } private List<SimulationTreeTableElement<T>> getRootElements(){ treeTableRootElements = new ArrayList<SimulationTreeTableElement<T>>(); for(SimulationTreeTableElement<T> element : treeTableElements){ if(element.getParent() == null){ treeTableRootElements.add(element); } } return treeTableRootElements; } @Override public boolean hasChildren(SimulationTreeTableElement<T> node) { return !node.getChildren().isEmpty(); } @Override public Iterator<? extends SimulationTreeTableElement<T>> getChildren(SimulationTreeTableElement<T> node) { return node.getChildren().iterator(); } @Override public SimulationTreeTableElementModel<T> model(SimulationTreeTableElement<T> node) { return new SimulationTreeTableElementModel<T>(getRootElements(), node); } @Override public ISortState<String> getSortState() { return new SingleSortState<String>(); } @Override public void selectEntry(int entryId) { for (SimulationTreeTableElement<T> treeTableElement : treeTableElements) { if(treeTableElement.getID() == entryId) { selectedTreeTableElements.add(treeTableElement); return; } } } @Override public void deselectEntry(int entryId) { for (SimulationTreeTableElement<T> treeTableElement : treeTableElements) { if(treeTableElement.getID() == entryId) { selectedTreeTableElements.remove(treeTableElement); return; } } } @Override public boolean isEntrySelected(int entryId) { for (SimulationTreeTableElement<T> treeTableElement : selectedTreeTableElements) { if(treeTableElement.getID() == entryId) { return true; } } return false; } /** * Returns the next free ID for an new element. * @return */ public int getNextID(){ int highestNumber = 0; for(SimulationTreeTableElement<T> element : treeTableElements ){ highestNumber = element.getID() > highestNumber ? element.getID() : highestNumber; } return ++highestNumber; } public List<SimulationTreeTableElement<T>> getTreeTableElements() { return treeTableElements; } public void addTreeTableElement(SimulationTreeTableElement<T> treeTableElement) { this.treeTableElements.add(treeTableElement); if(!selectedTreeTableElements.isEmpty()){ SimulationTreeTableElement<T> parent = selectedTreeTableElements.get(0); parent.getChildren().add(treeTableElement); treeTableElement.setParent(parent); } } public void addTreeTableElementWithParent(SimulationTreeTableElement<T> treeTableElement, SimulationTreeTableElement<T> parent) { this.treeTableElements.add(treeTableElement); parent.getChildren().add(treeTableElement); treeTableElement.setParent(parent); } public void setTreeTableElements(List<SimulationTreeTableElement<T>> treeTableElements) { this.treeTableElements = treeTableElements; } public void deleteSelectedEntries() { for(SimulationTreeTableElement<T> element : selectedTreeTableElements){ element.remove(); } treeTableElements.removeAll(selectedTreeTableElements); selectedTreeTableElements.clear(); } public List<SimulationTreeTableElement<T>> getSelectedTreeTableElements() { return selectedTreeTableElements; } public List<SimulationTreeTableElement<T>> getRootTreeTableElements() { return getRootElements(); } public SushiTree<T> getModelAsTree(){ SushiTree<T> tree = new SushiTree<T>(); for(SimulationTreeTableElement<T> element : treeTableRootElements){ addElementToTree(null, element, tree); } return tree; } private void addElementToTree(SimulationTreeTableElement<T> parent, SimulationTreeTableElement<T> element, SushiTree<T> tree) { if(parent != null){ tree.addChild(parent.getContent(), element.getContent()); } else { tree.addChild(null, element.getContent()); } if(element.getContent() instanceof SushiEventType){ Map<SushiAttribute, String> attributeMap = new HashMap<SushiAttribute, String>(); for(SimulationTreeTableElement<T> child : element.getChildren()){ attributeMap.put((SushiAttribute) child.getContent(), (String) child.getInput()); } tree.addChild(element.getContent(), (T) attributeMap); } else{ for(SimulationTreeTableElement<T> child : element.getChildren()){ addElementToTree(element, child, tree); } } } public String getInputForEntry(int entryID) { return getEntry(entryID).getInput(); } public void setInputForEntry(String input, int entryID) { getEntry(entryID).setInput(input); } public String getDurationForEntry(int entryID) { return getEntry(entryID).getDuration(); } public void setDurationForEntry(String duration, int entryID) { getEntry(entryID).setDuration(duration); } public void setDerivationTypeForEntry(DerivationType derivationType, int entryID) { getEntry(entryID).setDerivationType(derivationType); } public DerivationType getDerivationTypeForEntry(int entryID) { return getEntry(entryID).getDerivationType(); } public void setDerivationForEntry(String derivation, int entryID) { getEntry(entryID).setDerivation(derivation); } public String getDerivationForEntry(int entryID) { return getEntry(entryID).getDerivation(); } public void setProbabilityForEntry(String probability, int entryID) { getEntry(entryID).setProbability(probability); } public String getProbabilityForEntry(int entryID) { return getEntry(entryID).getProbability(); } public boolean editableColumnsVisibleForEntry(int entryID){ //TODO: rename! return getEntry(entryID).editableColumnsVisible(); } public Map<SushiAttribute, List<Serializable>> getAttributeValuesFromModel() { Map<SushiAttribute, List<Serializable>> attributes = new HashMap<SushiAttribute, List<Serializable>>(); Boolean alreadyInserted; for (SimulationTreeTableElement<T> treeTableElement : treeTableElements) { if(treeTableElement.getContent() instanceof SushiAttribute){ alreadyInserted = false; for(SushiAttribute insertedAttribute : attributes.keySet()){ if(insertedAttribute.equals((SushiAttribute) treeTableElement.getContent())){ alreadyInserted = true; break; } } if(!alreadyInserted){ attributes.put((SushiAttribute) treeTableElement.getContent(), getValuesFromInput(treeTableElement)); } } } return attributes; } private List<Serializable> getValuesFromInput(SimulationTreeTableElement<T> attributeElement) { List<Serializable> values = new ArrayList<Serializable>(); String valueString = attributeElement.getInput(); SushiAttribute attribute = (SushiAttribute) attributeElement.getContent(); if(attribute.getType().equals(SushiAttributeTypeEnum.DATE)){ //TODO: datum parsen } else if(attribute.getType().equals(SushiAttributeTypeEnum.INTEGER)){ String[] split = valueString.split(","); for(int i = 0; i < split.length; i++){ if(split[i].contains("-")){ String[] subSplit = split[i].split("-"); //falsche eingaben abfangen if(subSplit.length != 2){ //TODO: was tun bei falscher eingabe? } else{ for(Integer j = Integer.parseInt(subSplit[0].trim()); j <= Integer.parseInt(subSplit[1].trim()); j++){ values.add(j); } } } else{ values.add(Integer.parseInt(split[i].trim())); } } } else{ String[] split = valueString.split(","); for(int i = 0; i < split.length; i++){ values.add(split[i].trim()); } } return values; } public void updateAllEqualInputFields(String input, int entryID) { SimulationTreeTableElement<T> sourceTreeTableElement = getEntry(entryID); for (SimulationTreeTableElement<T> treeTableElement : treeTableElements) { if(treeTableElement.getContent().equals(sourceTreeTableElement.getContent())) { treeTableElement.setInput(input); Integer otherEntryId = treeTableElement.getID(); setInputForEntry(input, otherEntryId); } } } public void setCorrelationAttributes(List<SushiAttribute> correlationAttributes) { this.correlationAttributes = correlationAttributes; } public void deleteAllEntries() { for(SimulationTreeTableElement<T> element : treeTableElements){ element.remove(); } selectedTreeTableElements.clear(); treeTableElements.clear(); } /** * Checks if an element of the provider has empty input fields. * @return */ public boolean hasEmptyFields(){ for(SimulationTreeTableElement<T> element : treeTableElements){ if(element.getContent() instanceof SushiAttribute){ if(element.getInput() == null || element.getInput().isEmpty()){ return true; } } } return false; } public List<SushiEventType> getEventTypes() { List<SushiEventType> eventTypes = new ArrayList<SushiEventType>(); for(SimulationTreeTableElement<T> element : treeTableElements){ if(element.getContent() instanceof SushiEventType){ eventTypes.add((SushiEventType) element.getContent()); } } return eventTypes; } public List<SimulationTreeTableElement<T>> getEventTypeElements() { List<SimulationTreeTableElement<T>> eventTypes = new ArrayList<SimulationTreeTableElement<T>>(); for(SimulationTreeTableElement<T> element : treeTableElements){ if(element.getContent() instanceof SushiEventType){ eventTypes.add(element); } } return eventTypes; } public Map<SushiEventType, String> getEventTypesWithDuration() { Map<SushiEventType, String> eventTypesWithDuration = new HashMap<SushiEventType, String>(); for(SimulationTreeTableElement<T> element : treeTableElements){ if(element.getContent() instanceof SushiEventType){ eventTypesWithDuration.put((SushiEventType) element.getContent(), element.getDuration()); } } return eventTypesWithDuration; } public Map<SushiEventType, String> getEventTypesWithDerivation() { Map<SushiEventType, String> eventTypesWithDuration = new HashMap<SushiEventType, String>(); for(SimulationTreeTableElement<T> element : treeTableElements){ if(element.getContent() instanceof SushiEventType){ eventTypesWithDuration.put((SushiEventType) element.getContent(), element.getDerivation()); } } return eventTypesWithDuration; } public Map<SushiEventType, DerivationType> getEventTypesWithDerivationType() { Map<SushiEventType, DerivationType> eventTypesWithDuration = new HashMap<SushiEventType, DerivationType>(); for(SimulationTreeTableElement<T> element : treeTableElements){ if(element.getContent() instanceof SushiEventType){ eventTypesWithDuration.put((SushiEventType) element.getContent(), element.getDerivationType()); } } return eventTypesWithDuration; } public Map<AbstractBPMNElement, String> getBPMNElementWithDuration() { Map<AbstractBPMNElement, String> taskssWithDuration = new HashMap<AbstractBPMNElement, String>(); for(SimulationTreeTableElement<T> element : treeTableElements){ if(element.getContent() instanceof AbstractBPMNElement){ taskssWithDuration.put((AbstractBPMNElement) element.getContent(), element.getDuration()); } } return taskssWithDuration; } @Override public SimulationTreeTableElement<T> getEntry(int entryId) { for(SimulationTreeTableElement<T> treeTableElement : treeTableElements){ if(treeTableElement.getID() == entryId){ return treeTableElement; } } return null; } public void registerDurationInputAtEntry(DurationEntryPanel durationEntryPanel, int entryId) { getEntry(entryId).setDurationEntryPanel(durationEntryPanel); } public Map<Object, String> getProbabilityStrings() { Map<Object, String> probabilityStrings = new HashMap<Object, String>(); for(SimulationTreeTableElement<T> element : treeTableElements){ if(element.getContent() instanceof XORComponent){ for(SimulationTreeTableElement<T> child : element.getChildren()){ probabilityStrings.put(child, child.getProbability()); } } } return probabilityStrings; } public Map<AbstractBPMNElement, DerivationType> getBPMNElementWithDerivationType() { Map<AbstractBPMNElement, DerivationType> elementsWithDerivation = new HashMap<AbstractBPMNElement, DerivationType>(); for(SimulationTreeTableElement<T> element : treeTableElements){ if(element.getContent() instanceof AbstractBPMNElement){ elementsWithDerivation.put((AbstractBPMNElement) element.getContent(), element.getDerivationType()); } } return elementsWithDerivation; } public Map<AbstractBPMNElement, String> getBPMNElementWithDerivation() { Map<AbstractBPMNElement, String> elementWithDerivation = new HashMap<AbstractBPMNElement, String>(); for(SimulationTreeTableElement<T> element : treeTableElements){ if(element.getContent() instanceof AbstractBPMNElement){ elementWithDerivation.put((AbstractBPMNElement) element.getContent(), element.getDerivation()); } } return elementWithDerivation; } public Map<BPMNXORGateway, List<Tuple<AbstractBPMNElement, String>>> getXorSuccessorsWithProbability() { Map<BPMNXORGateway, List<Tuple<AbstractBPMNElement, String>>> xorSuccessorsProbability = new HashMap<BPMNXORGateway, List<Tuple<AbstractBPMNElement, String>>>(); for(SimulationTreeTableElement<T> element : treeTableElements){ if(element.getContent() instanceof BPMNXORGateway && ((AbstractBPMNGateway) element.getContent()).isSplitGateway()){ List<Tuple<AbstractBPMNElement, String>> successorList= new ArrayList<Tuple<AbstractBPMNElement, String>>(); for(SimulationTreeTableElement<T> xorSuccessorElement : treeTableElements){ if(((BPMNXORGateway) element.getContent()).getSuccessors().contains(xorSuccessorElement.getContent())){ Tuple<AbstractBPMNElement, String> tuple = new Tuple<AbstractBPMNElement, String>((AbstractBPMNElement) xorSuccessorElement.getContent(), xorSuccessorElement.getProbability()); successorList.add(tuple); } } xorSuccessorsProbability.put((BPMNXORGateway) element.getContent(), successorList); } } return xorSuccessorsProbability; } public List<SushiAttribute> getAttributes() { Boolean isInList; List<SushiAttribute> attributeList = new ArrayList<SushiAttribute>(); for(SimulationTreeTableElement<T> element : treeTableElements){ if(element.getContent() instanceof SushiAttribute){ isInList = false; for(SushiAttribute attributeInList : attributeList){ if(attributeInList.equals(element.getContent())){ isInList = true; break; } } if(!isInList){ attributeList.add((SushiAttribute) element.getContent()); } } } return attributeList; } public List<BPMNTask> getTasks() { List<BPMNTask> tasks = new ArrayList<BPMNTask>(); for(SimulationTreeTableElement<T> element : treeTableElements){ if(element.getContent() instanceof BPMNTask){ tasks.add((BPMNTask) element.getContent()); } } return tasks; } }