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

de.uni.freiburg.iig.telematik.sepia.petrinet.abstr.AbstractPNNode 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!
/* 
 * Copyright (c) 2015, IIG Telematics, Uni Freiburg
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted (subject to the limitations in the disclaimer
 * below) provided that the following conditions are met:
 *
 * * Redistributions of source code must retain the above copyright notice, this
 *   list of conditions and the following disclaimer.
 * * Redistributions in binary form must reproduce the above copyright notice,
 *   this list of conditions and the following disclaimer in the documentation
 *   and/or other materials provided with the distribution.
 * * Neither the name of IIG Telematics, Uni Freiburg nor the names of its
 *   contributors may be used to endorse or promote products derived from this
 *   software without specific prior written permission.
 *
 * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY
 * THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
 * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT
 * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
 * CONTRIBUTORS BELIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
package de.uni.freiburg.iig.telematik.sepia.petrinet.abstr;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import de.invation.code.toval.validate.ParameterException;
import de.invation.code.toval.validate.Validate;
import de.uni.freiburg.iig.telematik.sepia.util.PNUtils;
import java.util.HashMap;
import java.util.Map;


/**
 * This abstract class subsumes common properties of Petri net places and transitions.
* Petri net places and transitions are defined in the classes {@link AbstractPlace} and {@link AbstractTransition}
* whoch both inherit from {@link AbstractPNNode}.
* In detail, these properties are:
* *
    *
  • Name: The name of the node (unique).
  • *
  • Label: The label of the node (not unique).
  • *
  • Relations: Incoming and outgoing relations to other nodes.
    * This allows nodes to notify other nodes about state changes.
  • *
* * Besides basic properties, this class provides further functionality,
* such as extraction of child- and parent-nodes and source/drain properties. * * @author Thomas Stocker * * @param Relation Type (inherits from AbstractFlowRelation) * @see AbstractFlowRelation * @see AbstractPlace * @see AbstractTransition */ public abstract class AbstractPNNode, ? extends AbstractTransition, ?>> implements Serializable{ private static final long serialVersionUID = -809201554674739116L; protected final String toStringFormat = "%s[%s]"; /** * Incoming relations of the Petri net node. */ protected Map incomingRelations = new HashMap<>(); /** * Outgoing relations of the Petri net node. */ protected Map outgoingRelations = new HashMap<>(); /** * The name of the Petri net node.
* Node names must be unique within a Petri net and are used for distinction.
* Once added to a Petri net, the name property should not be changed to avoid conflicts. */ protected final String name; /** * The label of the Petri net node.
* The label is not unique and can be altered, whenever convenient. */ protected String label; private PNNodeType type = null; //------- Constructors --------------------------------------------------------------------------- // protected AbstractPNNode(PNNodeType type){ // super(); // this.type = type; // } /** * Creates a new Petri net node, using the given name.
* Ba default, the label of the node equals the name. * @param type The type of the Petri net node. * @param name The name for the Petri net node. * @throws ParameterException If the given name is null. */ public AbstractPNNode(PNNodeType type, String name){ this(type, name, name); this.type = type; } /** * Creates a new Petri net node, using the given name and label. * @param type The type of the Petri net node. * @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 -_.:. * @param label The label for the Petri net node. * @throws ParameterException If some parameters are null. */ public AbstractPNNode(PNNodeType type, String name, String label){ Validate.notNull(name); Validate.notNull(label); PNUtils.validateElementName(name); this.name = name; setLabel(label); this.type = type; } //------- Basic properties ----------------------------------------------------------------------- /** * Returns the name of the Petri net node. * @return The name of the Petri net. */ public String getName(){ return name; } // /** // * Sets the name of the Petri net node.
// * Implementing classes must make sure, that the net does not contain other nodes with the same name. // * @param name New name for the Petri net node. // * @throws ParameterException If the given name is null. // */ // protected abstract void setName(String name); /** * Returns the label of the Petri net node. * @return The label of the Petri net node. */ public String getLabel() { return label; } /** * Sets the label of the Petri net node. * @param label New label for the Petri net node. * @throws ParameterException If the given label is null. */ public final void setLabel(String label){ Validate.notNull(label); this.label = label; } /** * Indicates if the Petri net node is a source, i.e.
* it has outgoing relations, but no incoming relations. * @return true if the node is a source;
* false otherwise. */ public boolean isSource(){ return incomingRelations.isEmpty() && !outgoingRelations.isEmpty(); } /** * Indicates if the Petri net node is a drain, i.e.
* it has incoming relations, but no outgoing relations. * @return true if the node is a drain;
* false otherwise. */ public boolean isDrain(){ return !incomingRelations.isEmpty() && outgoingRelations.isEmpty(); } /** * Returns all parent nodes of this Petri net node. * @return A set of all parent nodes. */ @SuppressWarnings("unchecked") public Set> getParents(){ Set> result = new HashSet<>(); for(E relation: incomingRelations.values()){ result.add((AbstractPNNode) relation.getSource()); } return result; } /** * Returns all child nodes of this Petri net node. * @return A set of all child nodes. */ @SuppressWarnings("unchecked") public Set> getChildren(){ Set> result = new HashSet<>(); for(E relation: outgoingRelations.values()){ result.add((AbstractPNNode) relation.getTarget()); } return result; } //------- Relations ------------------------------------------------------------------------------ /** * Returns the incoming relations of the Petri net node. * @return A list of all incoming relations. */ public List getIncomingRelations(){ return new ArrayList<>(incomingRelations.values()); } /** * Returns the outgoing relations of the Petri net node. * @return A list of all outgoing relations. */ public List getOutgoingRelations(){ return new ArrayList<>(outgoingRelations.values()); } /** * Adds an incoming relation to the Petri net node.
* This method is protected, since adding relations to nodes should be done by the * corresponding Petri net only. * @param relation The incoming relation to add. * @return true if the relation was added;
* false otherwise. * @throws ParameterException If the given relation is null. */ protected boolean addIncomingRelation(E relation){ Validate.notNull(relation); return (incomingRelations.put(relation.getName(), relation)) == null; } /** * Adds an outgoing relation to the Petri net node.
* This method is protected, since adding relations to nodes should be done by the * corresponding Petri net only. * @param relation The outgoing relation to add. * @return true if the relation was added;
* false otherwise. * @throws ParameterException If the given relation is null. */ protected boolean addOutgoingRelation(E relation){ Validate.notNull(relation); return (outgoingRelations.put(relation.getName(), relation)) == null; } /** * Removes the given relation from the Petri net node.
* The method checks itself if the relation is incoming or outgoing. * @param relation The relation to remove. * @return true if the relation was removed;
* false otherwise. * @throws ParameterException If the given relation is null. */ protected boolean removeRelation(E relation){ Validate.notNull(relation); if(removeIncomingRelation(relation)) return true; return removeOutgoingRelation(relation); } /** * Removes the given relation from the set of incoming relations. * @param relation The incoming relation to remove. * @return true if the relation was removed;
* false otherwise. * @throws ParameterException If the given relation is null. */ protected boolean removeIncomingRelation(E relation){ Validate.notNull(relation); return (incomingRelations.remove(relation.getName())) != null; } /** * Removes the given relation from the set of outgoing relations. * @param relation The outgoing relation to remove. * @return true if the relation was removed;
* false otherwise. * @throws ParameterException If the given relation is null. */ protected boolean removeOutgoingRelation(E relation){ Validate.notNull(relation); return (outgoingRelations.remove(relation.getName())) != null; } /** * Returns the relation from the given Petri net node leading to this node.
* The method checks if there is an incoming relation with this property. * @param Type of the node, subclass of \@link AbstractPNNode}. * @param node The source node of the relation of interest. * @return The incoming relation leading from the given node to this node;
* null if there is no such incoming relation. * @throws ParameterException If the given node is null. */ public > E getRelationFrom(N node){ Validate.notNull(node); for(E incomingRelation: incomingRelations.values()){ if(incomingRelation.getSource().equals(node)){ return incomingRelation; } } return null; } /** * Returns the relation from this node leading to the given Petri net node.
* The method checks if there is an outgoing relation with this property. * @param Type of the node, subclass of \@link AbstractPNNode}. * @param node The target node of the relation of interest. * @return The outgoing relation leading from this node to the given node;
* null if there is no such outgoing relation. * @throws ParameterException If the given node is null. */ public > E getRelationTo(N node){ Validate.notNull(node); for(E outgoingRelation: outgoingRelations.values()){ if(outgoingRelation.getTarget().equals(node)){ return outgoingRelation; } } return null; } /** * Checks if there is an outgoing relation leading to the given Petri net node. * @param Type of the node, subclass of \@link AbstractPNNode}. * @param node The node of interest. * @return true if there is an outgoing relation to the given node;
* false otherwise. * @throws ParameterException If the given node is null. */ public > boolean containsRelationTo(N node){ return getRelationTo(node) != null; } /** * Checks if there is an incoming relation from the given Petri net node. * @param Type of the node, subclass of \@link AbstractPNNode}. * @param node The node of interest. * @return true if there is an incoming relation from the given node;
* false otherwise. * @throws ParameterException If the given node is null. */ public > boolean containsRelationFrom(N node){ return getRelationFrom(node) != null; } protected PNNodeType getPNNodeType() { return type; } protected void setType(PNNodeType type) { this.type = type; } public int degree(){ return outgoingRelations.size() + incomingRelations.size(); } public boolean isTransition(){ return type.equals(PNNodeType.TRANSITION); } public boolean isPlace(){ return type.equals(PNNodeType.PLACE); } //------- HashCode and Equals ------------------------------------------------------------------- /* (non-Javadoc) * @see java.lang.Object#hashCode() */ @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((label == null) ? 0 : label.hashCode()); result = prime * result + ((name == null) ? 0 : name.hashCode()); result = prime * result + ((toStringFormat == null) ? 0 : toStringFormat.hashCode()); result = prime * result + ((type == null) ? 0 : type.hashCode()); return result; } /* (non-Javadoc) * @see java.lang.Object#equals(java.lang.Object) */ @Override public boolean equals(Object obj) { if (this == obj) { return true; } if (obj == null) { return false; } if (getClass() != obj.getClass()) { return false; } @SuppressWarnings("rawtypes") AbstractPNNode other = (AbstractPNNode) obj; // if (incomingRelations == null) { // if (other.incomingRelations != null) { // return false; // } // } else if (!incomingRelations.equals(other.incomingRelations)) { // if (incomingRelations.size() == other.incomingRelations.size()) { // for (E incomingRelation : incomingRelations) { // if (!other.incomingRelations.contains(incomingRelation)) { // return false; // } // } // return true; // } // return false; // } if (label == null) { if (other.label != null) { return false; } } else if (!label.equals(other.label)) { return false; } if (name == null) { if (other.name != null) { return false; } } else if (!name.equals(other.name)) { return false; } // if (outgoingRelations == null) { // if (other.outgoingRelations != null) { // return false; // } // } else if (!outgoingRelations.equals(other.outgoingRelations)) { // if (outgoingRelations.size() == other.outgoingRelations.size()) { // for (E outgoingRelation : outgoingRelations) { // if (!other.outgoingRelations.contains(outgoingRelation)) { // return false; // } // } // return true; // } // return false; // } if (toStringFormat == null) { if (other.toStringFormat != null) { return false; } } else if (!toStringFormat.equals(other.toStringFormat)) { return false; } if (type != other.type) { return false; } return true; } @Override public AbstractPNNode clone() { AbstractPNNode result = newInstance(getName()); result.setLabel(getLabel()); result.setType(getPNNodeType()); // for (E incomingRelation: getIncomingRelations()) // result.addIncomingRelation(incomingRelation); // for (E outgoingRelation: getOutgoingRelations()) // result.addOutgoingRelation(outgoingRelation); // -> Is done in AbstractPetriNet.clone() return result; } //------- toString ------------------------------------------------------------------------------- @Override public String toString() { return String.format(toStringFormat, name, label); } protected abstract AbstractPNNode newInstance(String name); }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy