Java tutorial
/*********************************************************** * This software is part of the ProM package * * http://www.processmining.org/ * * * * Copyright (c) 2003-2007 TU/e Eindhoven * * and is licensed under the * * Common Public License, Version 1.0 * * by Eindhoven University of Technology * * Department of Information Systems * * http://is.tm.tue.nl * * * **********************************************************/ package org.prom5.analysis.petrinet.cpnexport; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.ListIterator; import org.prom5.analysis.petrinet.cpnexport.hltocpn.ColorSetTranslator; import org.prom5.analysis.petrinet.cpnexport.hltocpn.CpnAttributeManager; import org.prom5.analysis.petrinet.cpnexport.hltocpn.VariableTranslator; import org.prom5.framework.models.ModelGraphVertex; import org.prom5.framework.models.hlprocess.HLActivity; import org.prom5.framework.models.hlprocess.HLAttribute; import org.prom5.framework.models.hlprocess.HLChoice; import org.prom5.framework.models.hlprocess.HLCondition; import org.prom5.framework.models.hlprocess.HLGroup; import org.prom5.framework.models.hlprocess.HLTypes; import org.prom5.framework.models.hlprocess.HLTypes.ChoiceEnum; import org.prom5.framework.models.hlprocess.hlmodel.HLPetriNet; import org.prom5.framework.models.petrinet.Place; import org.prom5.framework.models.petrinet.Transition; import att.grappa.Grappa; import att.grappa.Node; /** * Translates the high-level information to the CPN-specific Petri net * that can be immediately written to a .cpn file. * * @author arozinat * @author rmans */ public class HLToCPNTranslator { public final static String cpnVarNameForCaseId = "c"; public final static String cpnColorSetNameForCaseId = "CASE_ID"; public final static String cpnVarNameForStartCase = "t"; public final static String cpnColorSetNameForStartCase = "START_TIME"; public final static String cpnVarNameForDataAttributes = "data"; public final static String cpnVarNameForModifiedDataAttributes = "modifiedData"; public final static String cpnColorSetNameForDataAttributes = "DATA"; public final static String cpnVarNameForGroupAllResources = "Anybody"; public final static String cpnColorSetNameForGroupAllResources = "ANYBODY"; public final static String cpnVarNameForProbDep = "prob"; public final static String cpnColorSetNameForProbDep = "INT"; public final static String namePlaceExecuting = "E"; public final static String namePlaceWaiting = "W"; private boolean isRedesign = false; /** * the object containing the high-level information referring to this process * (i.e., the source of the translation process). */ private HLPetriNet highLevelPN; /** * the CPN-like object that needs to be filled with the translated information * (i.e., the target of the translation process). */ private ColoredPetriNet simulatedPN; /** * Saves information about the fusion places */ private HashMap<String, HashSet<ColoredPlace>> fusionPlaces = new HashMap<String, HashSet<ColoredPlace>>(); /** * the simulation environment for the process */ private ColoredPetriNet simulationEnvironment; /** * Saves the products of the cpnID of a transition and the corresponding pageinstanceIdRefs. * With this information, a data collector monitor can be generated that keeps tracks of the * resources in the resources place */ private HashMap<String, ArrayList> monitoringResources = new HashMap<String, ArrayList>(); /** * the cpn id of the function to which the monitor is attached that calculates * the throughput time for each case */ private String cpnIdMonitorThroughputTime = ""; /** * the page instanceidref of the page on which the transition is located which * has the monitor that calculates the throughput time for each case. */ private ArrayList<String> pageInstancesMonitorThroughputTime = new ArrayList<String>(); protected ColorSetTranslator colorsetTranslator; protected VariableTranslator variableTranslator; /** * Default constructor * @param hlPN the PetriNet-based simulation model * @param simPN the ordinary colored petri net */ public HLToCPNTranslator(HLPetriNet hlPN, ColoredPetriNet simPN) { highLevelPN = hlPN; simulatedPN = simPN; colorsetTranslator = new ColorSetTranslator(highLevelPN, simulatedPN); variableTranslator = new VariableTranslator(highLevelPN); } public void isRedesign(boolean isRedesign) { this.isRedesign = isRedesign; } /** * Resets all data structure that are used to write the CPN to file. * This is needed to enable the multiple export of the same ColoredPetriNet structure * (e.g., after changing some simulation parameters). */ public void reset() { fusionPlaces = new HashMap<String, HashSet<ColoredPlace>>(); monitoringResources = new HashMap<String, ArrayList>(); pageInstancesMonitorThroughputTime = new ArrayList<String>(); colorsetTranslator.reset(); } /** * Returns the fusion that are needed when generating the subpage * @return HashMap the fusionplaces */ public HashMap<String, HashSet<ColoredPlace>> getFusionPlaces() { return fusionPlaces; } /** * Retrieves the cpn id of the transition to which the monitor is attached * that calculates the throughput time for each case * @return String */ public String getCpnIdMonitorTroughputTime() { return cpnIdMonitorThroughputTime; } /** * Retrieves the pageinstance idrefs of the page on which the transition is * located which monitor calculates the throughput time for each case * @return ArrayList the pageinstanceidrefs */ public ArrayList<String> getPageinstancesMonitorThroughputTime() { return pageInstancesMonitorThroughputTime; } /** * Returns the declaration of a function that can be used in cpn * for generating random values (between some range) for the given data * attribute. * @param dataAttr HLAttribute the data attribute for which we want to obtain * a function that generates random values between some range * @return CpnFunction a declaration of a function that generates random values */ public CpnFunction generateRandomFunctionForDataAttribute(HLAttribute dataAttr) { return new CpnFunction(dataAttr); } /** * Creates a simulation environment for the given net. * @param net ColoredPetriNet the net for which a simulation environment needs to be * created * @return ColoredPetriNet the (hierarchical) simulation environment */ private ColoredPetriNet createSimulationEnvironment(ColoredPetriNet net) { // If the logging is enabled the types of some places needs to be changed and the // inscription of some arcs needs to be changed CpnColorSet colorSetPlace = null; String arcInscriptionEdge = ""; if (ManagerConfiguration.getInstance().isThroughputTimeMonitorEnabled()) { ArrayList<CpnColorSet> productColorSets = new ArrayList<CpnColorSet>(); productColorSets.add(colorsetTranslator.getColorSetCaseID()); productColorSets.add(colorsetTranslator.getColorSetStartCase()); colorSetPlace = colorsetTranslator.productCpnColorSet(productColorSets); // arc inscription arcInscriptionEdge = "(" + variableTranslator.getCpnVarForCaseId().getVarName() + "," + variableTranslator.getCpnVarForStartCase().getVarName() + ")"; } else { colorSetPlace = colorsetTranslator.getColorSetCaseID(); arcInscriptionEdge = variableTranslator.getCpnVarForCaseId().getVarName(); } // global resources place, needed to generate the monitor that keeps track of the // resources in the global resources place ColoredPlace globalResourcesPlace = null; ColoredPetriNet simulationOverview = new ColoredPetriNet(); simulationOverview.setIdentifier("Overview"); // create overview page ColoredPlace startPlace = new ColoredPlace("Start", simulationOverview, -289, -10, 48, 48); startPlace.setPlaceType(colorSetPlace.getNameColorSet()); if (ManagerConfiguration.getInstance().isCurrentStateSelected()) { // inject initial marking to enable loading current state startPlace.setInitMark("getInitialTokens(\"Overview`Start\")"); } simulationOverview.addPlace(startPlace); ColoredPlace endPlace = new ColoredPlace("End", simulationOverview, 65, -10, 48, 48); endPlace.setPlaceType(colorSetPlace.getNameColorSet()); if (ManagerConfiguration.getInstance().isCurrentStateSelected()) { // inject initial marking to enable loading current state endPlace.setInitMark("getInitialTokens(\"Overview`End\")"); } simulationOverview.addPlace(endPlace); ColoredTransition envTrans = new ColoredTransition("Environment", simulationOverview, -116, 98, 176, 38); simulationOverview.addTransition(envTrans); ColoredTransition procTrans = new ColoredTransition("Process", simulationOverview, -116, -10, 176, 94); simulationOverview.addTransition(procTrans); ColoredEdge StartToProc = new ColoredEdge(startPlace, procTrans); simulationOverview.addEdge(StartToProc); ColoredEdge ProcToEnd = new ColoredEdge(procTrans, endPlace); simulationOverview.addEdge(ProcToEnd); ColoredEdge EndToEnv = new ColoredEdge(endPlace, envTrans); ArrayList<String> bendpoint1 = new ArrayList<String>(); bendpoint1.add("65"); bendpoint1.add("98"); EndToEnv.addBendPoint(bendpoint1); simulationOverview.addEdge(EndToEnv); ColoredEdge EnvToStart = new ColoredEdge(envTrans, startPlace); ArrayList<String> bendpoint2 = new ArrayList<String>(); bendpoint2.add("-289"); bendpoint2.add("98"); EnvToStart.addBendPoint(bendpoint2); simulationOverview.addEdge(EnvToStart); // create environment page level ColoredPetriNet environmentPage = new ColoredPetriNet(); environmentPage.setIdentifier("Environment"); ColoredPlace startPlaceEnv = new ColoredPlace("Start", environmentPage, -292, -11, 48, 48); startPlaceEnv.setPlaceType(colorSetPlace.getNameColorSet()); environmentPage.addPlace(startPlaceEnv); ColoredPlace endPlaceEnv = new ColoredPlace("End", environmentPage, 259, -14, 48, 48); endPlaceEnv.setPlaceType(colorSetPlace.getNameColorSet()); environmentPage.addPlace(endPlaceEnv); ColoredPlace nextCaseID = new ColoredPlace("next\ncase ID", environmentPage, -292, 263, 120, 58); // Set the initial marking of this place if (ManagerConfiguration.getInstance().isCurrentStateSelected()) { nextCaseID.setInitMark("getNextCaseID()"); } else { nextCaseID.setInitMark("1"); } environmentPage.addPlace(nextCaseID); if (isRedesign) { // add for redesign ColoredPlace startFile = new ColoredPlace("startFile", environmentPage, -292, 500, 120, 58); environmentPage.addPlace(startFile); ColoredTransition initFile = new ColoredTransition("InitFile", environmentPage, -292, 400, 92, 56); environmentPage.addTransition(initFile); // arcs ColoredEdge startFileToInitFile = new ColoredEdge(startFile, initFile); startFileToInitFile.setArcInscription("c"); environmentPage.addEdge(startFileToInitFile); ColoredEdge initFileToNCID = new ColoredEdge(initFile, nextCaseID); initFileToNCID.setArcInscription("c"); environmentPage.addEdge(initFileToNCID); nextCaseID.setInitMark(""); startFile.setInitMark("1"); startFile.setPlaceType("CASE_ID"); initFile.setCodeInscription("input (c);output ();action(createFile());"); } // end for redesign ColoredTransition init = new ColoredTransition("Init", environmentPage, -292, 140, 92, 56); if (isRedesign) { init.setGuard("c<=readNumberOfCases()"); } environmentPage.addTransition(init); ColoredTransition cleanUp = new ColoredTransition("Clean-up", environmentPage, 259, 140, 92, 56); environmentPage.addTransition(cleanUp); if (isRedesign) { cleanUp.setCodeInscription("input (c,t); output (); action(addToFile(c,getTPT(t)));"); } ColoredEdge initToStart = new ColoredEdge(init, startPlaceEnv); if (ManagerConfiguration.getInstance().isThroughputTimeMonitorEnabled()) { String arcInscription = "(" + variableTranslator.getCpnVarForCaseId().getVarName() + ", ModelTime.toString(time()))"; initToStart.setArcInscription(arcInscription); } else { initToStart.setArcInscription(variableTranslator.getCpnVarForCaseId().getVarName()); } environmentPage.addEdge(initToStart); ColoredEdge initToNextCaseID = new ColoredEdge(init, nextCaseID); // case generation scheme if (ManagerConfiguration.getInstance().isTimePerspectiveEnabled()) { String timeDelayArc = ""; if (isRedesign) { timeDelayArc = "@+readArrivalRate()"; } else { timeDelayArc = "@+" + CpnUtils.getCpnDistributionFunction( highLevelPN.getHLProcess().getGlobalInfo().getCaseGenerationScheme()); } String arcInscription = variableTranslator.getCpnVarForCaseId().getVarName() + "+1 " + timeDelayArc; initToNextCaseID.setArcInscription(arcInscription); } else { initToNextCaseID.setArcInscription(variableTranslator.getCpnVarForCaseId().getVarName() + "+1"); } environmentPage.addEdge(initToNextCaseID); ColoredEdge nextCaseIdToInit = new ColoredEdge(nextCaseID, init); nextCaseIdToInit.setArcInscription(variableTranslator.getCpnVarForCaseId().getVarName()); environmentPage.addEdge(nextCaseIdToInit); ColoredEdge endToCleanUp = new ColoredEdge(endPlaceEnv, cleanUp); endToCleanUp.setArcInscription(arcInscriptionEdge); environmentPage.addEdge(endToCleanUp); if (ManagerConfiguration.getInstance().isDataPerspectiveEnabled() && highLevelPN.getHLProcess().getAttributes() != null && highLevelPN.getHLProcess().getAttributes().size() > 0) { // the place for the casedata ColoredPlace caseDat = new ColoredPlace("Case data", environmentPage, -18, 140, 120, 58); // inject initial marking for current state if (ManagerConfiguration.getInstance().isCurrentStateSelected()) { caseDat.setInitMark("getInitialCaseData()"); } // Set the type of this place ArrayList<CpnColorSet> productColorSet = new ArrayList<CpnColorSet>(); productColorSet.add(colorsetTranslator.getColorSetCaseID()); productColorSet.add(colorsetTranslator.getColorSetDataAttributes()); CpnColorSet colorSet = colorsetTranslator.productCpnColorSet(productColorSet); caseDat.setPlaceType(colorSet.getNameColorSet()); environmentPage.addPlace(caseDat); // the arc connecting the casedata place with the init transition ColoredEdge initToCaseDat = new ColoredEdge(init, caseDat); // Set the initialisation arc inscription String initString = ""; for (HLAttribute dataAttribute : highLevelPN.getHLProcess().getAttributes()) { initString = CpnAttributeManager.appendInitialValueString(dataAttribute, initString); } // remove the last , int length = initString.length(); if (length > 0) { initString = initString.substring(0, length - 2); } initToCaseDat.setArcInscription( "(" + variableTranslator.getCpnVarForCaseId().getVarName() + ", {" + initString + "})"); environmentPage.addEdge(initToCaseDat); // the arc connecting the casedata ColoredEdge caseDatToCleanUp = new ColoredEdge(caseDat, cleanUp); caseDatToCleanUp.setArcInscription("(" + variableTranslator.getCpnVarForCaseId().getVarName() + "," + variableTranslator.getCpnVarForDataAttributes().getVarName() + ")"); environmentPage.addEdge(caseDatToCleanUp); // the case data place needs to be a fusion place if (!fusionPlaces.containsKey("Case data")) { fusionPlaces.put("Case data", new HashSet<ColoredPlace>()); } fusionPlaces.get("Case data").add(caseDat); caseDat.setNameFusionPlace("Case data"); } if ((ManagerConfiguration.getInstance().isResourcePerspectiveEnabled()) && highLevelPN.getHLProcess().getResources() != null) { // create the resources place ColoredPlace resource = new ColoredPlace("Resources", environmentPage, -18, 0, 120, 58); String test = colorsetTranslator.getColorSetForResourcesPlace().getNameColorSet(); String test2 = CpnUtils.getCpnValidName(test); resource.setPlaceType( CpnUtils.getCpnValidName(colorsetTranslator.getColorSetForResourcesPlace().getNameColorSet())); environmentPage.addPlace(resource); // initialize this one if (ManagerConfiguration.getInstance().isCurrentStateSelected()) { resource.setInitMark("FREE.all()"); } else { SubSetColorSet cset = colorsetTranslator.getColorSetForResourcesPlace(); resource.setInitMark(cset.getInitMarking()); } // the resource place needs to be a fusion place if (!fusionPlaces.containsKey("Resources")) { fusionPlaces.put("Resources", new HashSet<ColoredPlace>()); } fusionPlaces.get("Resources").add(resource); resource.setNameFusionPlace("Resources"); globalResourcesPlace = resource; } // ensure that environmentPage, overviewpage and process has a cpnID. This // is needed for writing the cpnfile simulationOverview.setCpnID(ManagerID.getNewID()); environmentPage.setCpnID(ManagerID.getNewID()); net.setCpnID(ManagerID.getNewID()); // First, make sure that every transition and place in the environmentPage, // OverviewPage and Process has a cpnID. This is needed for writing the cpnfile simulationOverview.generateCpnIDs(); environmentPage.generateCpnIDs(); net.generateCpnIDs(); // establish hierarchy from Environment to Overview SubpageMapping mappingEnvToOv = new SubpageMapping(); mappingEnvToOv.addMapping(endPlaceEnv, endPlace); mappingEnvToOv.addMapping(startPlaceEnv, startPlace); mappingEnvToOv.setSubPageID(environmentPage.getCpnID()); // add the mapping to the environment transition envTrans.setSubpageMapping(mappingEnvToOv); envTrans.setSubpage(environmentPage); // establish hierarchy from Process to Overview SubpageMapping mappingProcToOv = new SubpageMapping(); // Map the input place of this net to the top input place of Overview // Map the output place of this net to the top output place of Overview // Assuming that this net has precisely one input and one output place Iterator places = net.getPlaces().iterator(); while (places.hasNext()) { ColoredPlace place = (ColoredPlace) places.next(); if (place.inDegree() == 0) { // This is an input place mappingProcToOv.addMapping(place, startPlace); } if (place.outDegree() == 0) { // This is an output place mappingProcToOv.addMapping(place, endPlace); } // inject initial marking for current state for all places // on process page but the start and the end place if (ManagerConfiguration.getInstance().isCurrentStateSelected() && place.inDegree() != 0 && place.outDegree() != 0) { place.setInitMark( "getInitialTokens(\"Process`" + CpnUtils.getCpnValidName(place.getIdentifier()) + "\")"); } } mappingProcToOv.setSubPageID(net.getCpnID()); procTrans.setSubpageMapping(mappingProcToOv); procTrans.setSubpage(net); // process page is always called "Process" (name of Petri net ignored) unless it is used for redesign if (!isRedesign) { net.setIdentifier("Process"); } if (ManagerConfiguration.getInstance().isResourcePerspectiveEnabled() && ManagerConfiguration.getInstance().isResourcesMonitorEnabled() && highLevelPN.getHLProcess().getResources() != null && highLevelPN.getHLProcess().getResources().size() > 0) { // save the cpnid of the resources place and the pageinstanceidref of the page on which // the resources places is located. Needed for the monitor that keeps track of resources in // the resources place. monitoringResources.put(globalResourcesPlace.getCpnID(), environmentPage.getPageInstanceIDs()); } // save the cpn id of cleanUp. Needed for the monitor that calculates the throughput time for each case this.cpnIdMonitorThroughputTime = cleanUp.getCpnID(); // the same for the pageinstanceidrefs of the page on which cleanUp is located this.pageInstancesMonitorThroughputTime = environmentPage.getPageInstanceIDs(); // return the hierarchical simulation model return simulationOverview; } /** * Generates the basic structure of a subpage of a transition. Only 'empty' transitions, * places and arcs are put on the subpage. So, no arc inscriptions, no code inscriptions * and so on, are provided * @param transition ColoredTransition the transition for which a subpage needs to be created. * @exception java.lang.Exception */ private void generateStructureSubPageForTransition(ColoredTransition transition) throws Exception { // input and output places of the transition, needed for the mapping between // sub to top ArrayList<ColoredPlace> inputPlacesSub = new ArrayList<ColoredPlace>(); SubpageMapping mapping = new SubpageMapping(); // you always have a complete transition and create a simulatedPetriNet for the subpage ColoredPetriNet subPage = new ColoredPetriNet(); subPage.setHighLevelProcess(highLevelPN); subPage.setTranslatorToCpn(this); ColoredTransition completeTransition = new ColoredTransition(transition.getIdentifier() + "_complete", subPage); // in the case that a subpage is generated for an invisible transition, then each transition on the generated // subpage does not have a logevent so that these transitions are also invisible and that as a consequence // no monitor is generated for these transitions and they are not logged if (transition.isInvisibleTask()) { completeTransition.setLogEvent(null); } completeTransition.setEventType(ColoredTransition.EventType.complete); // set a reference to the high level activity completeTransition.setHighLevelTransition(transition.getHighLevelTransition()); subPage.addTransition(completeTransition); // // define the type of the places in the net CpnColorSet colorSet = colorsetTranslator.getColorSetCaseID(); String arcInscription = variableTranslator.getCpnVarForCaseId().getVarName(); if (ManagerConfiguration.getInstance().isThroughputTimeMonitorEnabled()) { ArrayList<CpnColorSet> productColorSet = new ArrayList<CpnColorSet>(); productColorSet.add(colorsetTranslator.getColorSetCaseID()); productColorSet.add(colorsetTranslator.getColorSetStartCase()); colorSet = colorsetTranslator.productCpnColorSet(productColorSet); // the inscription for the arc needs to be adapted arcInscription = "(" + arcInscription + "," + variableTranslator.getCpnVarForStartCase().getVarName() + ")"; } // create port places for the input of the subpage Iterator onlyInputTop = transition.getVerticesOnlyPredecessor().iterator(); while (onlyInputTop.hasNext()) { ColoredPlace topPlace = (ColoredPlace) onlyInputTop.next(); ColoredPlace subPlace = new ColoredPlace(topPlace.getIdentifier(), subPage); subPlace.setPlaceType(colorSet.getNameColorSet()); inputPlacesSub.add(subPlace); subPage.addPlace(subPlace); // create a mapping from sub to top mapping.addMapping(subPlace, topPlace); } // create port places for the output of the subpage // connect the output places already with the complete transition Iterator onlyOutputTop = transition.getVerticesOnlySuccessor().iterator(); while (onlyOutputTop.hasNext()) { ColoredPlace topPlace = (ColoredPlace) onlyOutputTop.next(); ColoredPlace subPlace = new ColoredPlace(topPlace.getIdentifier(), subPage); subPlace.setPlaceType(colorSet.getNameColorSet()); subPage.addPlace(subPlace); // connect with the complete transition ColoredEdge edge = new ColoredEdge(completeTransition, subPlace); // set the arc inscription for the edge edge.setArcInscription(arcInscription); subPage.addEdge(edge); // create a mapping from sub to top mapping.addMapping(subPlace, topPlace); } // create port places for the places that are are both predecessor and // successor of the transition Iterator predAndSucc = transition.getVerticesPredecessorAndSuccessor().iterator(); while (predAndSucc.hasNext()) { ColoredPlace topPlace = (ColoredPlace) predAndSucc.next(); ColoredPlace subPlace = new ColoredPlace(topPlace.getIdentifier(), subPage); subPlace.setPlaceType(colorSet.getNameColorSet()); inputPlacesSub.add(subPlace); subPage.addPlace(subPlace); // connect with the complete transition ColoredEdge edge = new ColoredEdge(completeTransition, subPlace); // set the arc inscription for the edge edge.setArcInscription(arcInscription); subPage.addEdge(edge); // create a mapping from sub to top mapping.addMapping(subPlace, topPlace); } ColoredTransition firstTransition = null; // check for the settings of the configuration manager if (!ManagerConfiguration.getInstance().isTimePerspectiveEnabled() && !ManagerConfiguration.getInstance().isOnlyExecutionTimeEnabled() && !ManagerConfiguration.getInstance().isOnlyWaitingAndExecutionTimeEnabled() && !ManagerConfiguration.getInstance().isOnlySojournTimeEnabled()) { // only complete firstTransition = completeTransition; } else if (ManagerConfiguration.getInstance().isOnlyExecutionTimeEnabled()) { // start and complete ColoredTransition start = new ColoredTransition(transition.getIdentifier() + "_start", subPage); start.setEventType(ColoredTransition.EventType.start); // in the case that a subpage is generated for an invisible transition, then each transition on the generated // subpage does not have a logevent so that these transitions are also invisible and that as a consequence // no monitor is generated for these transitions and they are not logged if (transition.isInvisibleTask()) { start.setLogEvent(null); } // set a reference to the high level activity start.setHighLevelTransition(transition.getHighLevelTransition()); subPage.addTransition(start); ColoredPlace between = new ColoredPlace(namePlaceExecuting, subPage); subPage.addPlace(between); ColoredEdge startToBetween = new ColoredEdge(start, between); String timeDelay = CpnUtils .getCpnDistributionFunction(transition.getHighLevelTransition().getExecutionTime()); startToBetween.setArcInscription("@+" + timeDelay); subPage.addEdge(startToBetween); ColoredEdge betweenToComplete = new ColoredEdge(between, completeTransition); subPage.addEdge(betweenToComplete); // inject initial marking for current state. invisible transitions cannot take any time, and they // cannot be observed in the engine - pure routing. therefore no current state marking needed. if (ManagerConfiguration.getInstance().isCurrentStateSelected() && transition.isInvisibleTask() == false) { between.setInitMark("getInitialTokensExePlace(\"" + transition.getIdentifier() + "`E\")@+(" + timeDelay + " div 2)"); } firstTransition = start; } else if (ManagerConfiguration.getInstance().isOnlyWaitingAndExecutionTimeEnabled()) { // schedule, start and complete ColoredTransition schedule = new ColoredTransition(transition.getIdentifier() + "_schedule", subPage); schedule.setEventType(ColoredTransition.EventType.schedule); // in the case that a subpage is generated for an invisible transition, then each transition on the generated // subpage does not have a logevent so that these transitions are also invisible and that as a consequence // no monitor is generated for these transitions and they are not logged if (transition.isInvisibleTask()) { schedule.setLogEvent(null); } // set a reference to the high level activity schedule.setHighLevelTransition(transition.getHighLevelTransition()); subPage.addTransition(schedule); ColoredTransition start = new ColoredTransition(transition.getIdentifier() + "_start", subPage); start.setEventType(ColoredTransition.EventType.start); // in the case that a subpage is generated for an invisible transition, then each transition on the generated // subpage does not have a logevent so that these transitions are also invisible and that as a consequence // no monitor is generated for these transitions and they are not logged if (transition.isInvisibleTask()) { start.setLogEvent(null); } // set a reference to the high level activity start.setHighLevelTransition(transition.getHighLevelTransition()); subPage.addTransition(start); ColoredPlace betweenScheduleStart = new ColoredPlace(namePlaceWaiting, subPage); subPage.addPlace(betweenScheduleStart); ColoredPlace betweenStartComplete = new ColoredPlace(namePlaceExecuting, subPage); subPage.addPlace(betweenStartComplete); // create the edge between the nodes ColoredEdge scheduleToBetween1 = new ColoredEdge(schedule, betweenScheduleStart); String timeDelay = CpnUtils .getCpnDistributionFunction(transition.getHighLevelTransition().getWaitingTime()); // if resource are also used, applying waiting ratio to waiting time if (ManagerConfiguration.getInstance().isResourcePerspectiveEnabled()) { timeDelay = timeDelay.substring(0, timeDelay.length() - 1) + "*" + (ManagerConfiguration.getInstance().getWaitingRatio() / 100.0) + ")"; } scheduleToBetween1.setArcInscription("@+" + timeDelay); subPage.addEdge(scheduleToBetween1); ColoredEdge between1ToStart = new ColoredEdge(betweenScheduleStart, start); subPage.addEdge(between1ToStart); ColoredEdge startToBetween2 = new ColoredEdge(start, betweenStartComplete); subPage.addEdge(startToBetween2); String timeDelay2 = CpnUtils .getCpnDistributionFunction(transition.getHighLevelTransition().getExecutionTime()); startToBetween2.setArcInscription("@+" + timeDelay2); ColoredEdge between2ToComplete = new ColoredEdge(betweenStartComplete, completeTransition); subPage.addEdge(between2ToComplete); // inject initial marking for current state. invisible transitions cannot take any time, and they // cannot be observed in the engine - pure routing. therefore no current state marking needed. if (ManagerConfiguration.getInstance().isCurrentStateSelected() && transition.isInvisibleTask() == false) { betweenStartComplete.setInitMark("getInitialTokensExePlace(\"" + transition.getIdentifier() + "`E\")@+(" + timeDelay2 + " div 2)"); } firstTransition = schedule; } else if (ManagerConfiguration.getInstance().isOnlySojournTimeEnabled()) { // schedule and complete ColoredTransition schedule = new ColoredTransition(transition.getIdentifier() + "_schedule", subPage); schedule.setEventType(ColoredTransition.EventType.schedule); // in the case that a subpage is generated for an invisible transition, then each transition on the generated // subpage does not have a logevent so that these transitions are also invisible and that as a consequence // no monitor is generated for these transitions and they are not logged if (transition.isInvisibleTask()) { schedule.setLogEvent(null); } // set a reference to the high level activity schedule.setHighLevelTransition(transition.getHighLevelTransition()); subPage.addTransition(schedule); ColoredPlace between = new ColoredPlace("S", subPage); subPage.addPlace(between); ColoredEdge scheduleToBetween = new ColoredEdge(schedule, between); subPage.addEdge(scheduleToBetween); String timeDelay = CpnUtils .getCpnDistributionFunction(transition.getHighLevelTransition().getSojournTime()); scheduleToBetween.setArcInscription("@+" + timeDelay); ColoredEdge betweenToComplete = new ColoredEdge(between, completeTransition); subPage.addEdge(betweenToComplete); firstTransition = schedule; } else { throw new java.lang.Exception("Conflict when generating subpage!"); } // connect the first transition with its input port places Iterator inputSub = inputPlacesSub.iterator(); while (inputSub.hasNext()) { ColoredPlace sub = (ColoredPlace) inputSub.next(); // connect place sub with firstTransition ColoredEdge edge = new ColoredEdge(sub, firstTransition); // set the arc inscription edge.setArcInscription(arcInscription); subPage.addEdge(edge); } // create name for the subpage and ensure that the subpage itself and the transitions // on it have an unique CPN-id subPage.setIdentifier(transition.getIdentifier()); subPage.setCpnID(ManagerID.getNewID()); subPage.generateCpnIDs(); mapping.setSubPageID(subPage.getCpnID()); transition.setSubpageMapping(mapping); transition.setSubpage(subPage); } /** * Translate the simulation model to a cpn model * @return a petri net that is close to cpn and can be immediately * exported to cpn. */ public ColoredPetriNet translate() { // scaling and stretching of the simulatedPN scalingAndStretchingForPN(simulatedPN); // create the simulation environment this.simulationEnvironment = createSimulationEnvironment(simulatedPN); // If the logging is enabled the types of places on the process page needs to be changed if (ManagerConfiguration.getInstance().isThroughputTimeMonitorEnabled()) { ArrayList<CpnColorSet> productColorSets = new ArrayList<CpnColorSet>(); productColorSets.add(colorsetTranslator.getColorSetCaseID()); productColorSets.add(colorsetTranslator.getColorSetStartCase()); CpnColorSet colorSet = colorsetTranslator.productCpnColorSet(productColorSets); Iterator places = simulatedPN.getPlaces().iterator(); while (places.hasNext()) { ColoredPlace place = (ColoredPlace) places.next(); place.setPlaceType(colorSet.getNameColorSet()); } } // generate a sub-page for each transition "highLevelTrans" on the Process page Iterator<Transition> transitions = simulatedPN.getTransitions().iterator(); while (transitions.hasNext()) { ColoredTransition transition = (ColoredTransition) transitions.next(); //if (!transition.isInvisibleTask()) { if (true) { try { generateStructureSubPageForTransition(transition); generateLayoutHierarchicalPN(transition.getSubpage(), false); generateInscriptionsInnerPart(transition); // find high level activity and related choices for transition HLActivity act = highLevelPN.findActivity(transition); int noOfChoicesInvolved = highLevelPN.getHLProcess().getChoicesForTargetActivity(act.getID()) .size(); // generate based on configuration boolean test = ((ManagerConfiguration.getInstance().isDataPerspectiveEnabled() && highLevelPN.getHLProcess().getAttributes().size() > 0) && ((choiceAllowed(ChoiceEnum.DATA, transition) && noOfChoicesInvolved > 0) || transition.getHighLevelTransition().getOutputDataAttributes().size() > 0)); if (test == true) { generateDataStructureOnSubpage(transition, choiceAllowed(ChoiceEnum.DATA, transition)); } if ((ManagerConfiguration.getInstance().isResourcePerspectiveEnabled()) && !transition.isInvisibleTask() && !act.isAutomatic()) { // not needed if the transition is an automatic or invisible task generateResourceStructureOnSubpage(transition); } //if (transition.getHighLevelTransition().getFrequencyDependency() > 1 && if (noOfChoicesInvolved > 0 && choiceAllowed(ChoiceEnum.FREQ, transition)) { generateFrequencyDependencySubpage(transition); } } catch (Exception e) { e.printStackTrace(); } } else { // transition is a hidden task, so the arcs on the process page should // have the correct arc inscriptions String arcInscription = ""; if (ManagerConfiguration.getInstance().isThroughputTimeMonitorEnabled()) { arcInscription = "(" + this.cpnVarNameForCaseId + "," + this.cpnVarNameForStartCase + ")"; } else { arcInscription = this.cpnVarNameForCaseId; } // all the incoming and outgoing arcs of the hidden task need to have the arc inscription Iterator<ColoredEdge> inEdges = transition.getInEdgesIterator(); while (inEdges.hasNext()) { ColoredEdge edge = inEdges.next(); edge.setArcInscription(arcInscription); } Iterator<ColoredEdge> outEdges = transition.getOutEdgesIterator(); while (outEdges.hasNext()) { ColoredEdge edge = outEdges.next(); edge.setArcInscription(arcInscription); } } } // probability dependency. checkForPossibilityDependencies(simulatedPN.getPlaces()); return simulationEnvironment; } /** * Checks whether some choice is allowed for a decision point, so that it may * be put in the cpn model. In the GUI of the cpn export you can choose between * a choice based on data attributes, frequencies, probabilities or unguided for a * given decision point. Before translating to cpn, it needs be checked which option is chosen. * @param choiceType ChoiceEnum the kind of choice for which we want to check. * @param transition ColoredTransition the transition for which we want to check, whether * the kind of choice is allowed or not. * @return boolean <code>true</code>, if the choice is allowed for the transition. <code>false</code> otherwise. */ private boolean choiceAllowed(ChoiceEnum choiceType, ColoredTransition transition) { HLActivity act = highLevelPN.findActivity(transition); if (act != null) { Iterator<HLChoice> choiceIt = highLevelPN.getHLProcess().getChoicesForTargetActivity(act.getID()) .iterator(); while (choiceIt.hasNext()) { HLChoice choice = choiceIt.next(); if (choice.getChoiceConfiguration() == choiceType) { // return for first choice found with this type return true; } } } return false; } /** * Check whether there are possibility dependencies defined for some places. * In the case that there are more than one possibility dependencies defined for * one place, then generate the correct distribution function for each of these * possibility dependencies * @param places List the list of places in the net. */ private void checkForPossibilityDependencies(List<Place> places) { Iterator<Place> placesIt = places.iterator(); while (placesIt.hasNext()) { ColoredPlace place = (ColoredPlace) placesIt.next(); HLChoice choice = highLevelPN.findChoice(place); // if choice exists for this place and is configured to be based on // probability if (choice != null && choice.getChoiceConfiguration() == ChoiceEnum.PROB) { // first normalize if needed double sum = 0.0; Iterator<HLCondition> probDepsNorm = choice.getConditions().iterator(); while (probDepsNorm.hasNext()) { HLCondition probDepNorm = probDepsNorm.next(); sum += probDepNorm.getProbability(); } // check whether sum is 0, in that case use default values. if (sum == 0) { // use default values Iterator<HLCondition> dependencies = choice.getConditions().iterator(); while (dependencies.hasNext()) { HLCondition dependency = dependencies.next(); double prob = ((double) 1 / (double) choice.getConditions().size()); dependency.setProbability(prob); } } else { // use normalized values Iterator<HLCondition> dependencies = choice.getConditions().iterator(); while (dependencies.hasNext()) { HLCondition dependency = dependencies.next(); double prob = ((double) dependency.getProbability() / (double) sum); dependency.setProbability(prob); } } // first find the multiplier for a round value // maxInt value in cpn is 1073741823 // so the multiplier may be at most 100000000 double multiplier = 1.0; Iterator<HLCondition> probDeps = choice.getConditions().iterator(); while (probDeps.hasNext()) { HLCondition probDep = probDeps.next(); double doubleVal = probDep.getProbability(); while (Math.rint(doubleVal * multiplier) != (doubleVal * multiplier) && multiplier <= 100000000) { multiplier = multiplier * 10; } } // calculate the max value of all the probabilities int maxVal = 0; probDeps = choice.getConditions().iterator(); while (probDeps.hasNext()) { HLCondition probDep = probDeps.next(); maxVal += Math.round(probDep.getProbability() * multiplier); } // String distFunc = "round(uniform(0.0," + maxVal + ".0))"; String distFunc = "discrete(0," + (maxVal - 1) + ")"; // actually generate double cumulative = 0; Iterator<HLCondition> conditions = choice.getConditions().iterator(); int i = 0; while (conditions.hasNext()) { HLCondition cond = conditions.next(); if (i == 0) { // the first one String cpnVarNameProb = variableTranslator.getCpnVarForProbDep(cond).getVarName(); String guard = cpnVarNameProb + " < " + Math.round(cond.getProbability() * multiplier); generateProbabilityDependencySubpage(cond, distFunc, guard, cpnVarNameProb); cumulative = cumulative + Math.round(cond.getProbability() * multiplier); } else if (i == choice.getConditions().size() - 1) { // the last one String cpnVarNameProb = variableTranslator.getCpnVarForProbDep(cond).getVarName(); String guard = cpnVarNameProb + " >= " + ((int) cumulative); generateProbabilityDependencySubpage(cond, distFunc, guard, cpnVarNameProb); } else { // somewhere in the middle String cpnVarNameProb = variableTranslator.getCpnVarForProbDep(cond).getVarName(); String guard = cpnVarNameProb + " >= " + ((int) cumulative) + " andalso " + cpnVarNameProb + " < " + (Math.round(cumulative + (cond.getProbability() * multiplier))); generateProbabilityDependencySubpage(cond, distFunc, guard, cpnVarNameProb); cumulative = cumulative + Math.round(cond.getProbability() * multiplier); } // remember configuration option in colored pn structure // (needed for writing) HLActivity act = cond.getTarget(); ModelGraphVertex targetNode = highLevelPN.findModelGraphVertexForActivity(act.getID()); if (targetNode instanceof ColoredTransition) { //((ColoredTransition) targetNode) // .existsProbabilityDependency(true); ColoredTransition firstTransition = getFirstTransitionOnSubpage( ((ColoredTransition) targetNode).getSubpage()); if (firstTransition != null) { firstTransition.existsProbabilityDependency(true); } } i++; } } } } /** * generates the structure on the subpage that is needed to model the data attributes and * the data dependencies for a transition * @param transition ColoredTransition the transition for which the data structure on * the subpage needs to be generated. * @param choiceAllowed indicate whether for this transition a choice based on data is allowed. */ private void generateDataStructureOnSubpage(ColoredTransition transition, boolean choiceAllowed) { ColoredPlace caseDat = new ColoredPlace("Case data", transition.getSubpage()); caseDat.setCpnID(ManagerID.getNewID()); // inject initial marking for current state if (ManagerConfiguration.getInstance().isCurrentStateSelected()) { caseDat.setInitMark("getInitialCaseData()"); } // generate product color set for data attributes and case-id ArrayList<CpnColorSet> productColorSets = new ArrayList<CpnColorSet>(); productColorSets.add(colorsetTranslator.getColorSetCaseID()); productColorSets.add(colorsetTranslator.getColorSetDataAttributes()); CpnColorSet prodColSet = colorsetTranslator.productCpnColorSet(productColorSets); caseDat.setPlaceType(prodColSet.getNameColorSet()); transition.getSubpage().addPlace(caseDat); ColoredTransition firstTransition = getFirstTransitionOnSubpage(transition.getSubpage()); ColoredTransition lastTransition = getLastTransitionOnSubpage(transition.getSubpage()); // // add layout information manually // also take into account the scaling and the stretching factor caseDat.setWidth(120 * (int) Math.round((double) ManagerLayout.getInstance().getStretchFactor() / (double) ManagerLayout.DEFAULT_STRETCH_FACTOR)); caseDat.setHeight(58 * (int) Math.round((double) ManagerLayout.getInstance().getStretchFactor() / (double) ManagerLayout.DEFAULT_STRETCH_FACTOR)); caseDat.setYCoordinate((firstTransition.getYCoordinate() + 200) * (int) Math.round((double) ManagerLayout.getInstance().getScaleFactor() / (double) ManagerLayout.DEFAULT_SCALE_FACTOR)); int middle = 0; if (firstTransition.getXCoordinate() < lastTransition.getXCoordinate()) { middle = Math.round(firstTransition.getXCoordinate() + ((lastTransition.getXCoordinate() - firstTransition.getXCoordinate()) / 2)); } else { // lastTransition.getXCoordinate() <= // firstTransition.getXCoordinate() middle = Math.round(lastTransition.getXCoordinate() + ((firstTransition.getXCoordinate() - lastTransition.getXCoordinate()) / 2)); } caseDat.setXCoordinate(middle); // Generate the code inscription for the case that there exists data // attributes for // a transition and that the logging is enabled String codeInscription = ""; String actionPart = ""; if (transition.getHighLevelTransition().getOutputDataAttributes().size() > 0) { codeInscription = codeInscription + "input (" + variableTranslator.getCpnVarForDataAttributes().getVarName() + "); \n output (" + variableTranslator.getCpnVarForModifiedDataAttributes().getVarName() + "); \n action \n"; ListIterator<HLAttribute> dataAttributes = transition.getHighLevelTransition().getOutputDataAttributes() .listIterator(); boolean first = true; while (dataAttributes.hasNext()) { HLAttribute dataAttribute = (HLAttribute) dataAttributes.next(); if (first) { // the first element in the list if (transition.getHighLevelTransition().getTransformationType(dataAttribute.getID()) .equals(HLTypes.TransformationType.Resample)) { // the data attribute needs to be resampled actionPart = actionPart + "(" + colorsetTranslator.getColorSetDataAttributes().getNameColorSet() + ".set_" + CpnUtils.getCpnValidName( variableTranslator.getCpnVarForDataAttribute(dataAttribute).getVarName()) + " " + variableTranslator.getCpnVarForDataAttributes().getVarName() + " (" + generateRandomFunctionForDataAttribute(dataAttribute).getFunctionName() + "))"; } else { // the data attribute needs to be reused actionPart = actionPart + "(" + colorsetTranslator.getColorSetDataAttributes().getNameColorSet() + ".set_" + CpnUtils.getCpnValidName( variableTranslator.getCpnVarForDataAttribute(dataAttribute).getVarName()) + " " + variableTranslator.getCpnVarForDataAttributes().getVarName() + " (#" + variableTranslator.getCpnVarForDataAttribute(dataAttribute).getVarName() + " " + variableTranslator.getCpnVarForDataAttributes().getVarName() + "))"; } first = false; } else { if (transition.getHighLevelTransition().getTransformationType(dataAttribute.getID()) .equals(HLTypes.TransformationType.Resample)) { // the data attribute needs to be resampled actionPart = "(" + colorsetTranslator.getColorSetDataAttributes().getNameColorSet() + ".set_" + CpnUtils.getCpnValidName( variableTranslator.getCpnVarForDataAttribute(dataAttribute).getVarName()) + " " + actionPart + " (" + generateRandomFunctionForDataAttribute(dataAttribute).getFunctionName() + "))"; } else { // the data attribute needs to be reused actionPart = "(" + colorsetTranslator.getColorSetDataAttributes().getNameColorSet() + ".set_" + CpnUtils.getCpnValidName( variableTranslator.getCpnVarForDataAttribute(dataAttribute).getVarName()) + " " + actionPart + " (#" + variableTranslator.getCpnVarForDataAttribute(dataAttribute).getVarName() + " " + variableTranslator.getCpnVarForDataAttributes().getVarName() + "))"; } } } codeInscription = codeInscription + actionPart + ";"; } // Get the data dependencies for which this transition is the target // node, if there // exists more than one data dependency // then the epression of these data dependencies need to be the same, // but is assumed // that this is always the case //ArrayList<HLDataDependency> dataDependencies = getDataDependenciesForTargetNode(transition); HLActivity act = highLevelPN.findActivity(transition); ArrayList<HLChoice> dataDependencies = highLevelPN.getHLProcess().getChoicesForTargetActivity(act.getID()); if (dataDependencies.size() > 0 && choiceAllowed) { transition.existsDataDependency(true); } // if (transition.getHighLevelTransition().getDataAttributes().size() > // 0 && // dataDependencies.size() == 0) { if (transition.getHighLevelTransition().getOutputDataAttributes().size() > 0 && choiceAllowed == false) { // only data attributes, connect place caseDat with last transition ColoredEdge caseDatToLastTransition = new ColoredEdge(caseDat, lastTransition); transition.getSubpage().addEdge(caseDatToLastTransition); ColoredEdge lastTransitionToCaseDat = new ColoredEdge(lastTransition, caseDat); transition.getSubpage().addEdge(lastTransitionToCaseDat); // set the correct arc inscriptions caseDatToLastTransition.setArcInscription("(" + variableTranslator.getCpnVarForCaseId().getVarName() + "," + variableTranslator.getCpnVarForDataAttributes().getVarName() + ")"); lastTransitionToCaseDat.setArcInscription("(" + variableTranslator.getCpnVarForCaseId().getVarName() + "," + variableTranslator.getCpnVarForModifiedDataAttributes().getVarName() + ")"); // set the correct code inscription lastTransition.setCodeInscription(codeInscription); // bendpoint ArrayList bendpoint = new ArrayList(); bendpoint.add(caseDat.getXCoordinate() + 10); bendpoint.add(lastTransition.getYCoordinate() + 100); caseDatToLastTransition.addBendPoint(bendpoint); } else if (transition.getHighLevelTransition().getOutputDataAttributes().size() == 0 && dataDependencies.size() > 0 && choiceAllowed) { // only data dependencies, connect place caseDat with first // transition ColoredEdge caseDatFirstTransition = new ColoredEdge(caseDat, firstTransition); transition.getSubpage().addEdge(caseDatFirstTransition); // ColoredEdge firstTransitionToCaseDat = new // ColoredEdge(firstTransition, caseDat); // transition.getSubpage().addEdge(firstTransitionToCaseDat); // set the correct arc inscriptions caseDatFirstTransition.setArcInscription("(" + variableTranslator.getCpnVarForCaseId().getVarName() + "," + variableTranslator.getCpnVarForDataAttributes().getVarName() + ")"); caseDatFirstTransition.setDoubleHeaded(true); // firstTransitionToCaseDat.setArcInscription("(" + // getCpnVarForCaseId().getVarName() + // "," + getCpnVarForDataAttributes().getVarName() + ")"); // How do I know in the expression the correct cpn variable for the // data attributes??? HLChoice choice = dataDependencies.get(0); HLCondition cond = choice.getCondition(act.getID()); firstTransition.setGuard(CpnUtils.getCpnExpression(cond.getExpression())); firstTransition.existsDataDependency(true); // bendpoint ArrayList bendpoint = new ArrayList(); bendpoint.add(caseDat.getXCoordinate() - 10); bendpoint.add(firstTransition.getYCoordinate() + 100); caseDatFirstTransition.addBendPoint(bendpoint); } else if (transition.getHighLevelTransition().getOutputDataAttributes().size() > 0 && dataDependencies.size() > 0 && choiceAllowed) { transition.existsDataDependency(true); // data attributes and data dependencies if (firstTransition.equals(lastTransition)) { // connect caseDat with last Transition ColoredEdge caseDatToFirstTransition = new ColoredEdge(caseDat, firstTransition); transition.getSubpage().addEdge(caseDatToFirstTransition); ColoredEdge firstTransitionToCaseDat = new ColoredEdge(firstTransition, caseDat); transition.getSubpage().addEdge(firstTransitionToCaseDat); // set the correct arc inscriptions caseDatToFirstTransition .setArcInscription("(" + variableTranslator.getCpnVarForCaseId().getVarName() + "," + variableTranslator.getCpnVarForDataAttributes().getVarName() + ")"); firstTransitionToCaseDat .setArcInscription("(" + variableTranslator.getCpnVarForCaseId().getVarName() + "," + variableTranslator.getCpnVarForModifiedDataAttributes().getVarName() + ")"); // set the correct code inscription and the correct guard lastTransition.setCodeInscription(codeInscription); HLChoice choice = dataDependencies.get(0); HLCondition cond = choice.getCondition(act.getID()); firstTransition.setGuard(CpnUtils.getCpnExpression(cond.getExpression())); // bendpoint ArrayList bendpoint = new ArrayList(); bendpoint.add(firstTransition.getXCoordinate() - 10); bendpoint.add(firstTransition.getYCoordinate() + 100); caseDatToFirstTransition.addBendPoint(bendpoint); firstTransition.existsDataDependency(true); } else { // connect caseDat with first and last transition ColoredEdge caseDatFirstTransition = new ColoredEdge(caseDat, firstTransition); transition.getSubpage().addEdge(caseDatFirstTransition); // ColoredEdge firstTransitionToCaseDat = new // ColoredEdge(firstTransition, caseDat); // transition.getSubpage().addEdge(firstTransitionToCaseDat); ColoredEdge caseDatToLastTransition = new ColoredEdge(caseDat, lastTransition); transition.getSubpage().addEdge(caseDatToLastTransition); ColoredEdge lastTransitionToCaseDat = new ColoredEdge(lastTransition, caseDat); transition.getSubpage().addEdge(lastTransitionToCaseDat); // set the correct arc inscriptions caseDatFirstTransition.setArcInscription("(" + variableTranslator.getCpnVarForCaseId().getVarName() + "," + variableTranslator.getCpnVarForDataAttributes().getVarName() + ")"); caseDatFirstTransition.setDoubleHeaded(true); // firstTransitionToCaseDat.setArcInscription("(" + // getCpnVarForCaseId().getVarName() + "," // + this.getCpnVarForDataAttributes().getVarName() + ")"); caseDatToLastTransition.setArcInscription("(" + variableTranslator.getCpnVarForCaseId().getVarName() + "," + variableTranslator.getCpnVarForDataAttributes().getVarName() + ")"); lastTransitionToCaseDat.setArcInscription("(" + variableTranslator.getCpnVarForCaseId().getVarName() + "," + variableTranslator.getCpnVarForModifiedDataAttributes().getVarName() + ")"); // set the correct code inscription and the correct guard lastTransition.setCodeInscription(codeInscription); HLChoice choice = dataDependencies.get(0); HLCondition cond = choice.getCondition(act.getID()); firstTransition.setGuard(CpnUtils.getCpnExpression(cond.getExpression())); // add bendpoints ArrayList bendpoint1 = new ArrayList(); bendpoint1.add(caseDat.getXCoordinate() + 10); bendpoint1.add(lastTransition.getYCoordinate() + 100); caseDatToLastTransition.addBendPoint(bendpoint1); firstTransition.existsDataDependency(true); // firstTransitionToCaseDat.addBendPoint(bendpoint1); // bendpoint not needed anymore // ArrayList bendpoint2 = new ArrayList(); // bendpoint2.add(caseDat.getXCoordinate()-10); // bendpoint2.add(firstTransition.getYCoordinate()+100); // caseDatFirstTransition.addBendPoint(bendpoint2); } } else { // this should never happen } // the case data place needs to be a fusion place if (!fusionPlaces.containsKey("Case data")) { fusionPlaces.put("Case data", new HashSet<ColoredPlace>()); } fusionPlaces.get("Case data").add(caseDat); caseDat.setNameFusionPlace("Case data"); } /** * Generates the structure on the subpage that is needed to model the group for * a transition * @param transition ColoredTransition the transition for which the resource * structure on the subpage needs to be generated * @exception java.lang.Exception */ private void generateResourceStructureOnSubpage(ColoredTransition transition) throws Exception { // First, generate the Resources place // not needed if the task is an automatic task ColoredPlace resource = new ColoredPlace("Resources", transition.getSubpage()); resource.setCpnID(ManagerID.getNewID()); resource.setPlaceType( CpnUtils.getCpnValidName(colorsetTranslator.getColorSetForResourcesPlace().getNameColorSet())); // inject initial marking for current state if requested if (ManagerConfiguration.getInstance().isCurrentStateSelected()) { resource.setInitMark("FREE.all()"); } else { SubSetColorSet cset = colorsetTranslator.getColorSetForResourcesPlace(); resource.setInitMark(cset.getInitMarking()); } transition.getSubpage().addPlace(resource); ColoredTransition firstTransition = getFirstTransitionOnSubpage_Resource(transition.getSubpage()); //modified ColoredTransition lastTransition = getLastTransitionOnSubpage(transition.getSubpage()); // get the place that is in between first and last transition, the place with identifier E. ColoredPlace placeInBetween = null; Iterator successors = firstTransition.getSuccessors().iterator(); while (successors.hasNext()) { ColoredPlace successor = (ColoredPlace) successors.next(); if (successor.getIdentifier().equals(namePlaceExecuting)) { placeInBetween = successor; break; } } // add layout information manually // also take into account the scaling and stretch factor resource.setWidth(120 * (int) Math.round(((double) ManagerLayout.getInstance().getStretchFactor() / (double) ManagerLayout.DEFAULT_STRETCH_FACTOR))); resource.setHeight(58 * (int) Math.round((double) ManagerLayout.getInstance().getStretchFactor() / (double) ManagerLayout.DEFAULT_STRETCH_FACTOR)); if (placeInBetween != null) { resource.setYCoordinate((placeInBetween.getYCoordinate() - 200) * (int) Math.round((double) ManagerLayout.getInstance().getScaleFactor() / (double) ManagerLayout.DEFAULT_SCALE_FACTOR)); int middle = 0; if (firstTransition.getXCoordinate() < lastTransition.getXCoordinate()) { middle = Math.round(firstTransition.getXCoordinate() + ((lastTransition.getXCoordinate() - firstTransition.getXCoordinate()) / 2)); } else { // lastTransition.getXCoordinate() <= firstTransition.getXCoordinate() middle = Math.round(lastTransition.getXCoordinate() + ((firstTransition.getXCoordinate() - lastTransition.getXCoordinate()) / 2)); } resource.setXCoordinate(middle); } else { resource.setYCoordinate((firstTransition.getYCoordinate() - 200) * (int) Math.round((double) ManagerLayout.getInstance().getScaleFactor() / (double) ManagerLayout.DEFAULT_SCALE_FACTOR)); resource.setXCoordinate(firstTransition.getXCoordinate()); } // already determine which variable should be used for the arc expressions CpnVarAndType cpnVarForGroup = null; if (transition.getHighLevelTransition().getGroup() != null && transition.getHighLevelTransition().getGroup().getResources().size() > 0) { cpnVarForGroup = variableTranslator .getCpnVarForGroup((HLGroup) transition.getHighLevelTransition().getGroup()); } else { throw new Exception("The group attached to transition " + transition.getIdentifier() + " does not contain any resources"); } if (firstTransition.equals(lastTransition)) { // connect the resource place with the complete transition ColoredEdge resourceToFirstTransition = new ColoredEdge(resource, firstTransition); resourceToFirstTransition.setArcInscription(cpnVarForGroup.getVarName()); transition.getSubpage().addEdge(resourceToFirstTransition); ColoredEdge firstTransitionToResource = new ColoredEdge(firstTransition, resource); firstTransitionToResource.setArcInscription(cpnVarForGroup.getVarName()); transition.getSubpage().addEdge(firstTransitionToResource); } else { // check whether firstTransition has a start event Type if (firstTransition.getEventType().equals(ColoredTransition.EventType.start)) { // connect the resource place with the complete and the start transition ColoredEdge resourceToFirstTransition = new ColoredEdge(resource, firstTransition); resourceToFirstTransition.setArcInscription(cpnVarForGroup.getVarName()); transition.getSubpage().addEdge(resourceToFirstTransition); ColoredEdge lastTransitionToResource = new ColoredEdge(lastTransition, resource); lastTransitionToResource.setArcInscription(cpnVarForGroup.getVarName()); transition.getSubpage().addEdge(lastTransitionToResource); // add bendpoints ArrayList bendpoint1 = new ArrayList(); bendpoint1.add(String.valueOf(firstTransition.getXCoordinate())); bendpoint1.add(String.valueOf(resource.getYCoordinate())); resourceToFirstTransition.addBendPoint(bendpoint1); ArrayList bendpoint2 = new ArrayList(); bendpoint2.add(String.valueOf(lastTransition.getXCoordinate())); bendpoint2.add(String.valueOf(resource.getYCoordinate())); lastTransitionToResource.addBendPoint(bendpoint2); } else { // generate exception throw new Exception("Resources on subpage: The first transition after the incoming " + "place does not have the start event type"); } } // the resource place needs to be a fusion place if (!fusionPlaces.containsKey("Resources")) { fusionPlaces.put("Resources", new HashSet<ColoredPlace>()); } fusionPlaces.get("Resources").add(resource); // resource.setNameFusionPlace("Resources"); // // Save the cpnid for all the transitions that are connected to the resources and // the pageinstanceidref of the page on which the transition is located. // Actually, the only transition that can be connected to the resources place // are the first and the last transition on the page monitoringResources.put(firstTransition.getCpnID(), transition.getSubpage().getPageInstanceIDs()); monitoringResources.put(lastTransition.getCpnID(), transition.getSubpage().getPageInstanceIDs()); } private void generateFrequencyDependencySubpage(ColoredTransition transition) { // in the case that the incoming place of the transition is a decision place, // calculate the gcd of the frequency dependencies that are attached to the // outgoing transitions of that decision place HLActivity act = highLevelPN.findActivity(transition); ArrayList<HLChoice> choices = highLevelPN.getHLProcess().getChoicesForTargetActivity(act.getID()); // TODO: now only take first choice (and assume that the others would be consistent) // However, it might be that different frequencies are given for this activity for different choices // The cpn export currently does not deal with this - needs global normalization if required HLChoice choice = choices.get(0); // calculate the gcd for the frequencydependencies in transitionsFreqDep int gcd = 1; boolean start = true; Iterator<HLCondition> conditions = choice.getConditions().iterator(); while (conditions.hasNext()) { HLCondition cond1 = conditions.next(); if (start && conditions.hasNext()) { HLCondition cond2 = conditions.next(); int freq1 = cond1.getFrequency(); int freq2 = cond2.getFrequency(); gcd = org.apache.commons.math.util.MathUtils.gcd(freq1, freq2); start = false; } else { gcd = org.apache.commons.math.util.MathUtils.gcd(gcd, cond1.getFrequency()); } } SubpageMapping oldMapping = transition.getSubpageMapping(); ColoredPetriNet oldSubpage = transition.getSubpage(); // Generate subpage between the already existing subpage for this transition ColoredPetriNet subpage = new ColoredPetriNet(); subpage.setIdentifier("Frequency_dependency_" + transition.getIdentifier()); subpage.setCpnID(ManagerID.getNewID()); // Generate an input and an output place for each input and output place of transition SubpageMapping mappingFromSubpageToTop = new SubpageMapping(); mappingFromSubpageToTop.setSubPageID(subpage.getCpnID()); HashSet inputPlacesSubpage = new HashSet<ColoredPlace>(); HashSet outputPlacesSubpage = new HashSet<ColoredPlace>(); Iterator inputPlaces = transition.getVerticesOnlyPredecessor().iterator(); while (inputPlaces.hasNext()) { ColoredPlace top = (ColoredPlace) inputPlaces.next(); ColoredPlace sub = new ColoredPlace(top.getIdentifier(), subpage); // the type of the top and sub place needs to be the same sub.setPlaceType(top.getPlaceType()); subpage.addPlace(sub); inputPlacesSubpage.add(sub); mappingFromSubpageToTop.addMapping(sub, top); } // the same for the output places Iterator outputPlaces = transition.getVerticesOnlySuccessor().iterator(); while (outputPlaces.hasNext()) { ColoredPlace top = (ColoredPlace) outputPlaces.next(); ColoredPlace sub = new ColoredPlace(top.getIdentifier(), subpage); // the type of the top and sub place needs to be the same sub.setPlaceType(top.getPlaceType()); subpage.addPlace(sub); outputPlacesSubpage.add(sub); mappingFromSubpageToTop.addMapping(sub, top); } // the same for the places that are both output and input Iterator inputOutputPlaces = transition.getVerticesPredecessorAndSuccessor().iterator(); while (inputOutputPlaces.hasNext()) { ColoredPlace top = (ColoredPlace) inputOutputPlaces.next(); ColoredPlace sub = new ColoredPlace(top.getIdentifier(), subpage); // the type of the top and sub place needs to be the same sub.setPlaceType(top.getPlaceType()); subpage.addPlace(sub); inputPlacesSubpage.add(sub); outputPlacesSubpage.add(sub); mappingFromSubpageToTop.addMapping(sub, top); } transition.setSubpageMapping(mappingFromSubpageToTop); transition.setSubpage(subpage); // The number of the generated transitions on the subpage equals the frequency dependency // that has been set for the transition. Furthermore, ensure that each generated transition // is connected correctly with the input and output places HLCondition cond = choice.getCondition(act.getID()); for (int i = 0; i < ((cond.getFrequency()) / gcd); i++) { ColoredTransition generatedTransition = new ColoredTransition(transition.getIdentifier() + (i + 1), subpage); subpage.addTransition(generatedTransition); Iterator<ColoredPlace> subPageInputPlaces = inputPlacesSubpage.iterator(); while (subPageInputPlaces.hasNext()) { ColoredPlace inputSubpage = subPageInputPlaces.next(); // connect with generatedTransition ColoredEdge edge = new ColoredEdge(inputSubpage, generatedTransition); subpage.addEdge(edge); } Iterator<ColoredPlace> subPageOutputPlaces = outputPlacesSubpage.iterator(); while (subPageOutputPlaces.hasNext()) { ColoredPlace outputSubpage = subPageOutputPlaces.next(); // connect with generatedTransition ColoredEdge edge = new ColoredEdge(generatedTransition, outputSubpage); subpage.addEdge(edge); } // ensure that the generatedTransition is pointing to the correct subpage and that // the mapping is correct generatedTransition.setSubpage(oldSubpage); SubpageMapping newMapping = new SubpageMapping(); generatedTransition.setSubpageMapping(newMapping); newMapping.setSubPageID(oldMapping.getSubPageID()); // fix the mappings Iterator<Place> placesSub = oldSubpage.getPlaces().iterator(); while (placesSub.hasNext()) { ColoredPlace placeSub = (ColoredPlace) placesSub.next(); // Get the mapping that belongs to this place, if existing SubpageMapping.Mapping oldMappingForSubPlace = oldMapping.getMappingForSubPlace(placeSub); if (oldMappingForSubPlace != null) { ColoredPlace topPlace = oldMappingForSubPlace.second(); SubpageMapping.Mapping mappingTopToSubpageForPlace = mappingFromSubpageToTop .getMappingForTopPlace(topPlace); newMapping.addMapping(placeSub, mappingTopToSubpageForPlace.first()); } } } subpage.generateCpnIDs(); // generate the layout of the subpage generateLayoutHierarchicalPN(subpage, false); } private void generateProbabilityDependencySubpage(HLCondition probDep, String distFunction, String guard, String cpnVarNameProb) { HLActivity act = probDep.getTarget(); ModelGraphVertex targetNode = highLevelPN.findModelGraphVertexForActivity(act.getID()); HLChoice choice = probDep.getChoice(); ModelGraphVertex choiceNode = highLevelPN.findModelGraphVertexForChoice(choice.getID()); if (targetNode instanceof ColoredTransition) { ColoredTransition transition = (ColoredTransition) targetNode; // First, generate the fusion place for this probability dependency ColoredPlace posDep = new ColoredPlace(choiceNode.getIdentifier() + "_Probability", transition.getSubpage()); posDep.setCpnID(ManagerID.getNewID()); posDep.setPlaceType(this.cpnColorSetNameForProbDep); posDep.setInitMark(distFunction); transition.getSubpage().addPlace(posDep); // connect posDep with the first transition on the subpage ColoredTransition firstTransition = getFirstTransitionOnSubpage(transition.getSubpage()); // temporary String firstGuard = firstTransition.getGuard(); if (firstGuard.equals("")) { firstTransition.setGuard(guard); } else { firstTransition.setGuard(firstGuard + " andalso " + guard); } ColoredEdge posDepToFirst = new ColoredEdge(posDep, firstTransition); transition.getSubpage().addEdge(posDepToFirst); posDepToFirst.setArcInscription(cpnVarNameProb); ColoredEdge firstToPosDep = new ColoredEdge(firstTransition, posDep); transition.getSubpage().addEdge(firstToPosDep); firstToPosDep.setArcInscription(distFunction); // add layout information manually // Also take into account the scaling and stretch factor posDep.setWidth(120 * (int) Math.round((double) ManagerLayout.getInstance().getStretchFactor() / (double) ManagerLayout.DEFAULT_STRETCH_FACTOR)); posDep.setHeight(58 * (int) Math.round((double) ManagerLayout.getInstance().getStretchFactor() / (double) ManagerLayout.DEFAULT_STRETCH_FACTOR)); posDep.setYCoordinate((firstTransition.getYCoordinate() - 200) * (int) Math.round((double) ManagerLayout.getInstance().getScaleFactor() / (double) ManagerLayout.DEFAULT_SCALE_FACTOR)); posDep.setXCoordinate((firstTransition.getXCoordinate() - 100) * (int) Math.round((double) ManagerLayout.getInstance().getScaleFactor() / (double) ManagerLayout.DEFAULT_SCALE_FACTOR)); // add bendpoint ArrayList bendpoint = new ArrayList(); bendpoint.add((posDep.getXCoordinate() - 10) * (int) Math.round((double) ManagerLayout.getInstance().getScaleFactor() / (double) ManagerLayout.DEFAULT_SCALE_FACTOR)); bendpoint.add(firstTransition.getYCoordinate() - 100); firstToPosDep.addBendPoint(bendpoint); // add the probability place to the fusion places String nameFusion = choiceNode.getIdentifier() + "_Probability"; posDep.setNameFusionPlace(nameFusion); if (!fusionPlaces.containsKey(nameFusion)) { fusionPlaces.put(nameFusion, new HashSet<ColoredPlace>()); } fusionPlaces.get(nameFusion).add(posDep); } } /** * Generates the inscriptions for the inner part of the model. So, this means * that the arcs and places in between the first and last transition get the correct * inscription, respectively the correct type. * @param transition ColoredTransition */ private void generateInscriptionsInnerPart(ColoredTransition transition) { // needed for push/pull ArrayList<CpnColorSet> colorSetWithoutGroup = new ArrayList<CpnColorSet>(); HLGroup group = transition.getHighLevelTransition().getGroup(); ArrayList<CpnColorSet> colorSets = new ArrayList<CpnColorSet>(); ArrayList<CpnColorSet> colorSetsNoGroup = new ArrayList<CpnColorSet>(); CpnColorSet colorSetsCPN = null; CpnColorSet colorSetsNoGroupCPN = null; colorSets.add(colorsetTranslator.getColorSetCaseID()); if (ManagerConfiguration.getInstance().isThroughputTimeMonitorEnabled()) { colorSets.add(colorsetTranslator.getColorSetStartCase()); } if (!transition.isInvisibleTask() && (ManagerConfiguration.getInstance().isResourcePerspectiveEnabled()) && !transition.getHighLevelTransition().isAutomatic()) { if (ManagerConfiguration.getInstance().isPullEnabled()) { // need to have a group with and without group colorSetsNoGroup = (ArrayList<CpnColorSet>) colorSets.clone(); colorSetsNoGroupCPN = colorsetTranslator.productCpnColorSet(colorSetsNoGroup); } colorSets.add(colorsetTranslator.getColorSetGroup(group)); } colorSetsCPN = colorsetTranslator.productCpnColorSet(colorSets); SubpageMapping mapping = transition.getSubpageMapping(); Iterator<Place> places = transition.getSubpage().getPlaces().iterator(); while (places.hasNext()) { ColoredPlace p = (ColoredPlace) places.next(); if (mapping.getMappingForSubPlace(p) == null) { String arcInscription = ""; // if pull is enabled and we are considering place with name // W and the resource perspective is enabled and there are resources // then the product color set needs to be changed (so without resources) if (p.getIdentifier().equals(namePlaceWaiting) && ManagerConfiguration.getInstance().isPullEnabled()) { if (!transition.getHighLevelTransition().isAutomatic()) { // do not need a colorset with a group p.setPlaceType(CpnUtils.getCpnValidName(colorSetsNoGroupCPN.getNameColorSet())); } else { p.setPlaceType(CpnUtils.getCpnValidName(colorSetsCPN.getNameColorSet())); } } else { p.setPlaceType(CpnUtils.getCpnValidName(colorSetsCPN.getNameColorSet())); } // ensure that the ingoing arcs and outgoing arcs have the correct // inscription (tuple of a resource and a case-id) arcInscription = "(" + variableTranslator.getCpnVarForCaseId().getVarName(); if (ManagerConfiguration.getInstance().isThroughputTimeMonitorEnabled()) { arcInscription = arcInscription + "," + variableTranslator.getCpnVarForStartCase().getVarName(); } if ((ManagerConfiguration.getInstance().isResourcePerspectiveEnabled()) && !transition.getHighLevelTransition().isAutomatic() && !transition.isInvisibleTask()) { String withRes = "," + variableTranslator.getCpnVarForGroup(group).getVarName(); if (p.getIdentifier().equals(namePlaceWaiting)) { if (ManagerConfiguration.getInstance().isPushEnabled()) { arcInscription = arcInscription + withRes; } else { // nothing } } else { arcInscription = arcInscription + withRes; } } arcInscription = arcInscription + ")"; Iterator<ColoredEdge> edgesIn = p.getInEdgesIterator(); while (edgesIn.hasNext()) { ColoredEdge edge = edgesIn.next(); edge.setArcInscription(arcInscription + edge.getArcInscription()); } Iterator<ColoredEdge> edgesOut = p.getOutEdgesIterator(); while (edgesOut.hasNext()) { ColoredEdge edge = edgesOut.next(); edge.setArcInscription(arcInscription); } } } } /** * Returns the first transition on the subpage. The first transitions does either have the * schedule, start or complete eventtype * @param subpage ColoredPetriNet * @return ColoredTransition */ protected ColoredTransition getFirstTransitionOnSubpage(ColoredPetriNet subpage) { ColoredTransition returnTransition = null; Iterator transitionsSchedule = subpage.getTransitions().iterator(); while (transitionsSchedule.hasNext()) { ColoredTransition transition = (ColoredTransition) transitionsSchedule.next(); if (transition.getEventType().equals(ColoredTransition.EventType.schedule)) { returnTransition = transition; break; } } if (returnTransition == null) { Iterator transitionsStart = subpage.getTransitions().iterator(); while (transitionsStart.hasNext()) { ColoredTransition transition = (ColoredTransition) transitionsStart.next(); if (transition.getEventType().equals(ColoredTransition.EventType.start)) { returnTransition = transition; break; } } } if (returnTransition == null) { Iterator transitionsComplete = subpage.getTransitions().iterator(); while (transitionsComplete.hasNext()) { ColoredTransition transition = (ColoredTransition) transitionsComplete.next(); if (transition.getEventType().equals(ColoredTransition.EventType.complete)) { returnTransition = transition; break; } } } return returnTransition; } /** * Returns the first start transition on the subpage. * Since the resource can not be assigen to schedule event, * the first transitions does either have the * start or complete eventtype * @param subpage ColoredPetriNet * @return ColoredTransition */ protected ColoredTransition getFirstTransitionOnSubpage_Resource(ColoredPetriNet subpage) { ColoredTransition returnTransition = null; Iterator transitionsStart = subpage.getTransitions().iterator(); while (transitionsStart.hasNext()) { ColoredTransition transition = (ColoredTransition) transitionsStart.next(); if (transition.getEventType().equals(ColoredTransition.EventType.start)) { returnTransition = transition; break; } } if (returnTransition == null) { Iterator transitionsComplete = subpage.getTransitions().iterator(); while (transitionsComplete.hasNext()) { ColoredTransition transition = (ColoredTransition) transitionsComplete.next(); if (transition.getEventType().equals(ColoredTransition.EventType.complete)) { returnTransition = transition; break; } } } return returnTransition; } /** * Returns the last transition on the subpage. The last transition on the subpage * does always have the complete eventtype which always exists * @param subpage ColoredPetriNet * @return ColoredTransition */ protected ColoredTransition getLastTransitionOnSubpage(ColoredPetriNet subpage) { ColoredTransition returnTransition = null; Iterator transitions = subpage.getTransitions().iterator(); while (transitions.hasNext()) { ColoredTransition transition = (ColoredTransition) transitions.next(); if (transition.getEventType().equals(ColoredTransition.EventType.complete)) { returnTransition = transition; break; } } return returnTransition; } /** * Generates the layout for this petri net and all its underlying petri nets * @param pn ColoredPetriNet the petri net that is the top of the structure * of hierarchical petri nets * @param hierarchical <code>true</code> when also for the subprocesses of the transitions the layout * needs to be generated. <code>false</code> when only for the coloredpetriNet provided by pn, the * layout needs to be generated. */ private void generateLayoutHierarchicalPN(ColoredPetriNet pn, boolean hierarchical) { pn.getGrappaVisualization(); // start with the grappa stuff Iterator transitions = pn.getTransitions().iterator(); while (transitions.hasNext()) { ColoredTransition t = (ColoredTransition) transitions.next(); Node n = t.visualObject; int x = (int) n.getCenterPoint().getX() * ManagerLayout.getInstance().getScaleFactor(); int y = -(int) n.getCenterPoint().getY() * ManagerLayout.getInstance().getScaleFactor(); int width = (int) (((Double) n.getAttributeValue(Grappa.WIDTH_ATTR)).doubleValue() * ManagerLayout.getInstance().getStretchFactor()); int height = (int) (((Double) n.getAttributeValue(Grappa.HEIGHT_ATTR)).doubleValue() * ManagerLayout.getInstance().getStretchFactor()); t.setXCoordinate(x); t.setYCoordinate(y); t.setWidth(width); t.setHeight(height); // check for subpages // and check whether it is allowed to also generate the layout for // the subpages if (t.getSubpage() != null && hierarchical) { generateLayoutHierarchicalPN(t.getSubpage(), true); } } Iterator places = pn.getPlaces().iterator(); while (places.hasNext()) { ColoredPlace p = (ColoredPlace) places.next(); Node n = p.visualObject; int x = (int) n.getCenterPoint().getX() * ManagerLayout.getInstance().getScaleFactor(); int y = -(int) n.getCenterPoint().getY() * ManagerLayout.getInstance().getScaleFactor(); int width = (int) (((Double) n.getAttributeValue(Grappa.WIDTH_ATTR)).doubleValue() * ManagerLayout.getInstance().getStretchFactor()); int height = (int) (((Double) n.getAttributeValue(Grappa.HEIGHT_ATTR)).doubleValue() * ManagerLayout.getInstance().getStretchFactor()); p.setXCoordinate(x); p.setYCoordinate(y); p.setWidth(width); p.setHeight(height); } } /** * Stretches and scales the transitions and places in the given petri net * @param pn ColoredPetriNet the petri net of which the transitions and places needs to be * stretched and scaled. */ private void scalingAndStretchingForPN(ColoredPetriNet pn) { Iterator transitions = pn.getTransitions().iterator(); while (transitions.hasNext()) { ColoredTransition transition = (ColoredTransition) transitions.next(); transition.setXCoordinate(transition.getXCoordinate() * (int) Math.round((double) ManagerLayout.getInstance().getScaleFactor() / (double) ManagerLayout.DEFAULT_SCALE_FACTOR)); transition.setYCoordinate(transition.getYCoordinate() * (int) Math.round((double) ManagerLayout.getInstance().getScaleFactor() / (double) ManagerLayout.DEFAULT_SCALE_FACTOR)); transition.setWidth( transition.getWidth() * (int) Math.round((double) ManagerLayout.getInstance().getStretchFactor() / (double) ManagerLayout.DEFAULT_STRETCH_FACTOR)); transition.setHeight(transition.getHeight() * (int) Math.round((double) ManagerLayout.getInstance().getStretchFactor() / (double) ManagerLayout.DEFAULT_STRETCH_FACTOR)); } Iterator places = pn.getPlaces().iterator(); while (places.hasNext()) { ColoredPlace place = (ColoredPlace) places.next(); place.setXCoordinate( place.getXCoordinate() * (int) Math.round((double) ManagerLayout.getInstance().getScaleFactor() / (double) ManagerLayout.DEFAULT_SCALE_FACTOR)); place.setYCoordinate( place.getYCoordinate() * (int) Math.round((double) ManagerLayout.getInstance().getScaleFactor() / (double) ManagerLayout.DEFAULT_SCALE_FACTOR)); place.setWidth( place.getWidth() * (int) Math.round((double) ManagerLayout.getInstance().getStretchFactor() / (double) ManagerLayout.DEFAULT_STRETCH_FACTOR)); place.setHeight( place.getHeight() * (int) Math.round((double) ManagerLayout.getInstance().getStretchFactor() / (double) ManagerLayout.DEFAULT_STRETCH_FACTOR)); } } /** * Returns the information that is needed for generating the monitor that keeps * track of the resources that are available in the resources place * @return HashMap */ public HashMap<String, ArrayList> getInfoForMonitoringResources() { return monitoringResources; } /** * Gets for the given transitions all the other transitions that are involved in the * same choice based on frequencies. * @param transitionsFreqDep HashSet. A hashset in which we only have one transition and for * which we want to obtain all the other transitions that are involved in the same choice based on * frequencies. */ private void getTransitionsForChoiceOnFrequencies(HashSet<ColoredTransition> transitionsFreqDep) { int oldSizeTransitions = transitionsFreqDep.size(); HashSet<ColoredPlace> places = new HashSet<ColoredPlace>(); Iterator<ColoredTransition> transitionsFreqDepIt = transitionsFreqDep.iterator(); while (transitionsFreqDepIt.hasNext()) { ColoredTransition transition = transitionsFreqDepIt.next(); places.addAll(transition.getPredecessors()); } // get the outgoing transitions for each place in places Iterator<ColoredPlace> placesIt = places.iterator(); while (placesIt.hasNext()) { ColoredPlace place = placesIt.next(); transitionsFreqDep.addAll(place.getSuccessors()); } if (transitionsFreqDep.size() > oldSizeTransitions) { getTransitionsForChoiceOnFrequencies(transitionsFreqDep); } } }