All Downloads are FREE. Search and download functionalities are using the official Maven repository.

de.uni.freiburg.iig.telematik.sepia.util.PNUtils Maven / Gradle / Ivy

Go to download

SEPIA provides implementations for various types of Petri nets. Along Place/Transition-nets, it supports Petri nets with distinguishable token colors and defines coloured workflow nets, where coloured tokens are interpreted as data elements used during process execution. To support information flow analysis of processes, SEPIA defines so-called IF-Nets, tailored for security-oriented workflow modeling which enable users to assign security-levels (HIGH, LOW) to transitions, data elements and persons/agents participating in the process execution.

The newest version!
package de.uni.freiburg.iig.telematik.sepia.util;

import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import de.invation.code.toval.math.MathUtils;
import de.invation.code.toval.types.HashList;
import de.invation.code.toval.validate.ParameterException;
import de.invation.code.toval.validate.Validate;
import de.uni.freiburg.iig.telematik.jagal.graph.exception.VertexNotFoundException;
import de.uni.freiburg.iig.telematik.jagal.traverse.TraversalUtils;
import de.uni.freiburg.iig.telematik.sepia.petrinet.abstr.AbstractFlowRelation;
import de.uni.freiburg.iig.telematik.sepia.petrinet.abstr.AbstractMarking;
import de.uni.freiburg.iig.telematik.sepia.petrinet.abstr.AbstractPNNode;
import de.uni.freiburg.iig.telematik.sepia.petrinet.abstr.AbstractPetriNet;
import de.uni.freiburg.iig.telematik.sepia.petrinet.abstr.AbstractPlace;
import de.uni.freiburg.iig.telematik.sepia.petrinet.abstr.AbstractTransition;
import de.uni.freiburg.iig.telematik.sepia.petrinet.pt.PTMarking;
import de.uni.freiburg.iig.telematik.sepia.petrinet.pt.PTNet;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class PNUtils {

    /**
     * Replacement string for invalid character blocks while sanitizing element
     * names.
     */
    public final static String SANITIZE_INVALID_CHARACTER_REPLACEMENT = "_";

    /**
     * Pattern to define allowed node names.
     */
    public static final Pattern XML_ID_PATTERN = Pattern.compile("^([a-zA-Z_][\\w-_\\.]*)$");

    /**
     * Pattern to define the first character in XML schema ID types.
     */
    public static final Pattern XML_ID_FIRST_CHARACTER = Pattern.compile("^[a-zA-Z_]$");

    /**
     * Pattern to define forbidden node name characters.
     */
    public static final Pattern XML_ID_FORBIDDEN_CHARACTERS = Pattern.compile("([^\\w-_\\.]+)");

    /**
     * Transforms a collection of transitions into a set of activities by
     * choosing the ID of the given transactions as activity names.
     *
     * @param  Transition type.
     * @param transitions Collection of transitions to get the labels from.
     * @param includeSilentTransitions Set true if silent
     * transitions should be included.
     * @return A set of activity names.
     */
    public static > Set getNameSetFromTransitions(Collection transitions, boolean includeSilentTransitions) {
        Validate.notNull(transitions);
        Validate.noNullElements(transitions);
        Set cActivities = new HashSet<>();
        for (AbstractTransition t : transitions) {
            if (includeSilentTransitions || !t.isSilent()) {
                cActivities.add(t.getName());
            }
        }
        return cActivities;
    }

    /**
     * Transforms a collection of transitions into a list of activities by
     * choosing the ID of the given transactions as activity names.
     *
     * @param  Transition type.
     * @param transitions Collection of transitions to get the labels from.
     * @return A list of activity names.
     */
    public static > List getNameListFromTransitions(Collection transitions) {
        Validate.notNull(transitions);
        Validate.noNullElements(transitions);
        List cActivities = new HashList<>();
        for (AbstractTransition t : transitions) {
            if (!t.isSilent()) {
                cActivities.add(t.getName());
            }
        }
        return cActivities;
    }

    /**
     * Transforms a collection of transitions into a set of activities by
     * choosing the label of the given transactions as activity names.
     *
     * @param transitions Collection of transitions to get the labels from.
     * @param includeSilentTransitions Set true if silent
     * transitions should be included.
     * @param  Transition type.
     * @return A set of activity labels.
     */
    public static > Set getLabelSetFromTransitions(Collection transitions, boolean includeSilentTransitions) {
        Validate.notNull(transitions);
        Validate.noNullElements(transitions);
        Set cActivities = new HashSet<>();
        for (AbstractTransition t : transitions) {
            if (includeSilentTransitions || !t.isSilent()) {
                cActivities.add(t.getLabel());
            }
        }
        return cActivities;
    }

    public static 

, T extends AbstractTransition, F extends AbstractFlowRelation, M extends AbstractMarking, S extends Object> Map> getAllPredecessors(AbstractPetriNet net) { Map> predecessors = new HashMap<>(); for (T transition : net.getTransitions()) { try { predecessors.put(transition, getPredecessors(net, transition)); } catch (VertexNotFoundException e) { throw new RuntimeException(e); } } return predecessors; } @SuppressWarnings("unchecked") public static

, T extends AbstractTransition, F extends AbstractFlowRelation, M extends AbstractMarking, S extends Object> Set getPredecessors(AbstractPetriNet net, T transition) throws VertexNotFoundException { Validate.notNull(net); Validate.notNull(transition); Set predecessors = new HashSet<>(); for (AbstractPNNode predecessorNode : TraversalUtils.getPredecessorsFor(net, transition)) { if (predecessorNode.isTransition()) { predecessors.add((T) predecessorNode); } } return predecessors; } public static > Set getSilentTransitions(Collection transitions) { Set result = new HashSet<>(); for (T transition : transitions) { if (transition.isSilent()) { result.add(transition); } } return result; } public static > Set getNonSilentTransitions(Collection transitions) { Set result = new HashSet<>(); for (T transition : transitions) { if (!transition.isSilent()) { result.add(transition); } } return result; } public static PTNet getORFragment(Set alternatives) { PTNet ptNet = new PTNet(); String[] alt = new String[alternatives.size()]; alternatives.toArray(alt); int k = alternatives.size(); ptNet.addPlace("in"); ptNet.addPlace("active"); ptNet.addPlace("fin"); ptNet.addPlace("out"); ptNet.addTransition("start", true); ptNet.addTransition("end", true); ptNet.addTransition("no_option", true); ptNet.addFlowRelationPT("fin", "end"); ptNet.addFlowRelationTP("end", "out"); ptNet.addFlowRelationTP("start", "active"); ptNet.addFlowRelationPT("active", "end"); ptNet.addFlowRelationPT("in", "start"); boolean[][] truthTable = MathUtils.getTruthTable(k); for (int i = 1; i <= k; i++) { String alternative = alt[i - 1]; ptNet.addPlace("p" + i); ptNet.addPlace("p_" + alternative); ptNet.addPlace("p_not_" + alternative); ptNet.addTransition(alternative); ptNet.addTransition("Not " + alternative, true); ptNet.addFlowRelationTP("start", "p" + i); ptNet.addFlowRelationPT("p" + i, alternative); ptNet.addFlowRelationPT("p" + i, "Not " + alternative); ptNet.addFlowRelationTP(alternative, "p_" + alternative); ptNet.addFlowRelationTP("Not " + alternative, "p_not_" + alternative); ptNet.addFlowRelationPT("p_not_" + alternative, "no_option"); ptNet.addFlowRelationTP("no_option", "p" + i); } for (int j = 0; j < Math.pow(2, k) - 1; j++) { String optionTransitionName = "Option_" + (j + 1); ptNet.addTransition(optionTransitionName, true); for (int l = 0; l < k; l++) { if (truthTable[l][j]) { ptNet.addFlowRelationPT("p_" + alt[l], optionTransitionName); } else { ptNet.addFlowRelationPT("p_not_" + alt[l], optionTransitionName); } } ptNet.addFlowRelationTP(optionTransitionName, "fin"); } PTMarking marking = new PTMarking(); marking.set("in", 1); ptNet.setInitialMarking(marking); return ptNet; } /** * Sanitizes element names by the XML ID datatype standard. Names must start * with a character of the range [a-zA-Z_] and must only contain alphanumeric * characters and the symbols -_.. * * @param name Name to sanitize. * @param leadingCharacters String to prepend to the name if it has not a * valid beginning. * @return Sanitized element name. */ public static String sanitizeElementName(String name, String leadingCharacters) { Validate.notEmpty(leadingCharacters); // replace forbidden characters by "_" name = name.replaceAll(XML_ID_FORBIDDEN_CHARACTERS.pattern(), SANITIZE_INVALID_CHARACTER_REPLACEMENT); // check if first element is in range [a-zA-Z] if (name.length() == 0 || !name.substring(0, 1).matches(XML_ID_FIRST_CHARACTER.pattern())) { name = leadingCharacters + name; } return name; } /** * Validates a given element name. * * @param name The name for the Petri net node. It must start with a * character of the range [a-zA-Z_] and must only contain alphanumerical * characters and the symbols -_.. */ public static void validateElementName(String name) { Matcher nameMatcher = XML_ID_PATTERN.matcher(name); if (!nameMatcher.matches()) { throw new ParameterException("Given name \"" + name + "\" is not according to the guidelines. Element names must match the pattern \"" + XML_ID_PATTERN + "\"."); } } }