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

de.uni.freiburg.iig.telematik.sepia.petrinet.abstr.AbstractFlowRelation Maven / Gradle / Ivy

package de.uni.freiburg.iig.telematik.sepia.petrinet.abstr;

import java.io.Serializable;

import de.invation.code.toval.validate.ParameterException;
import de.invation.code.toval.validate.ParameterException.ErrorCode;
import de.invation.code.toval.validate.Validate;
import de.uni.freiburg.iig.telematik.sepia.event.FlowRelationListener;
import de.uni.freiburg.iig.telematik.sepia.event.FlowRelationListenerSupport;
import de.uni.freiburg.iig.telematik.sepia.util.PNUtils;

/**
 * Abstract class that defines general properties for flow relations between Petri net places and transitions.
* Flow relations can lead from transitions to places or the other way round (direction).
* The direction of the flow relation is defined with the help of the {@link #directionPT}-property.
*
* Flow relations have a unique name which is determined by concatenation of place and transition names
* and the direction property (they have also unique names). * * @author Thomas Stocker * * @param

The type of Petri net places. * @param The type of Petri net transitions. */ public abstract class AbstractFlowRelation

,S>, T extends AbstractTransition, S>, S extends Object> implements Serializable{ private static final long serialVersionUID = -3305028252141027555L; protected final String nameFormatPT = "arcPT_%s%s"; protected final String nameFormatTP = "arcTP_%s%s"; protected final String toStringFormat = "%s: %s -%s-> %s"; protected FlowRelationListenerSupport> relationListenerSupport = new FlowRelationListenerSupport>(); protected S constraint = null; /** * The name of the flow relation. */ protected String name; /** * The place of the flow relation. */ protected P place; /** * The transition of the flow relation. */ protected T transition; /** * The direction of the flow relation. */ protected boolean directionPT; //------- Constructors --------------------------------------------------------------------------- /** * Creates a new flow relation leading from the given place to the given transition. * @param place Place where the flow relation starts. * @param transition Transition where the flow relation ends. * @throws ParameterException If some parameters are null. * @see #setValues(AbstractTransition, AbstractPlace) */ public AbstractFlowRelation(P place, T transition){ this(place, transition, true, null); } /** * Creates a new flow relation leading from the given transition to the given place. * @param transition Transition where the flow relation starts. * @param place Place where the flow relation ends. * @throws ParameterException If some parameters are null. * @see #setValues(AbstractTransition, AbstractPlace) */ public AbstractFlowRelation(T transition, P place){ this(place, transition, false, null); } public AbstractFlowRelation(P place, T transition, S constraint){ this(place, transition, true, constraint); } public AbstractFlowRelation(T transition, P place, S constraint){ this(place, transition, false, constraint); } private AbstractFlowRelation(P place, T transition, boolean directionPT, S constraint){ this.directionPT = directionPT; setValues(transition, place); if(constraint == null){ setConstraint(getDefaultConstraint()); } else { setConstraint(constraint); } } //------- Basic properties ----------------------------------------------------------------------- public final void setConstraint(S constraint){ validateConstraint(constraint); this.constraint = constraint; relationListenerSupport.notifyCapacityChanged(this); getTransition().checkState(); } public S getConstraint() { return constraint; } protected abstract S getDefaultConstraint(); protected abstract void validateConstraint(S constraint); /** * Returns the place of the flow relation. * @return The flow relations' place. */ public P getPlace() { return place; } /** * Returns the transition of the flow relation. * @return The flow relations' transition. */ public T getTransition() { return transition; } /** * Returns the direction of the flow relation. * @return true if the relation leads from a place to a transition;
* false if the relation leads from a transition to a place. */ public boolean getDirectionPT() { return directionPT; } protected void setDirectionPT(boolean directionPT){ this.directionPT = directionPT; } /** * This method is used in constructors to set the flow relation place and transition.
* It uses {@link #setName(AbstractPlace, AbstractTransition)} to assign the flow relation a unique name. * @param transition The transition for the flow relation. * @param place The place for the flow relation. * @throws ParameterException If some parameters are null. */ private void setValues(T transition, P place){ Validate.notNull(place); Validate.notNull(transition); this.place = place; this.transition = transition; setName(place, transition); } /** * Sets the name of the flow relation.

* If this method is used to explicitly set the flow relations' name,
* the caller is responsible to guarantee unique flow relation names.
* Name collisions can cause unintended or erroneous Petri net behavior. * @param name The name for the flow relation. It must start with a * character of the range [a-zA-Z] and must only contain alphanumerical * characters and the symbols -_.:. * @throws ParameterException If some parameters are null. */ public void setName(String name){ Validate.notNull(name); PNUtils.validateElementName(name); if(!relationListenerSupport.requestNameChangePermission(this, name)) throw new ParameterException(ErrorCode.INCONSISTENCY, "A connected Petri net already contains a relation with this name.\n Cancel renaming to avoid name clash."); this.name = name; } /** * Automatically sets the name of the flow relation on basis of the names of the given place and transition. * This method guarantees unique flow relation names which is a result of concatenating place and transition names
* together with the direction property (they have also unique names). * @param place The place whose name is used for automatic name determination. * @param transition The transition whose name is used for automatic name determination. */ protected void setName(P place, T transition){ if(directionPT){ name = String.format(nameFormatPT, place.getName(), transition.getName()); } else { name = String.format(nameFormatTP, transition.getName(), place.getName()); } } /** * Returns the name of the flow relation. * @return The name of the flow relation. */ public String getName(){ return name; } /** * Returns the source node (place or transition) of the flow relation. * @return The source node of the flow relation. */ public AbstractPNNode getSource(){ if(directionPT){ return place; } else { return transition; } } /** * Returns the target node (place or transition) of the flow relation. * @return The target node of the flow relation. */ public AbstractPNNode getTarget(){ if(directionPT){ return transition; } else { return place; } } //------- hashCode and equals -------------------------------------------------------------------- @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((constraint == null) ? 0 : constraint.hashCode()); result = prime * result + (directionPT ? 1231 : 1237); result = prime * result + ((name == null) ? 0 : name.hashCode()); result = prime * result + ((place == null) ? 0 : place.hashCode()); result = prime * result + ((transition == null) ? 0 : transition.hashCode()); return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; @SuppressWarnings("rawtypes") AbstractFlowRelation other = (AbstractFlowRelation) obj; if (constraint == null) { if (other.constraint != null) return false; } else if (!constraint.equals(other.constraint)) return false; if (directionPT != other.directionPT) return false; if (name == null) { if (other.name != null) return false; } else if (!name.equals(other.name)) return false; if (place == null) { if (other.place != null) return false; } else if (!place.equals(other.place)) return false; if (transition == null) { if (other.transition != null) return false; } else if (!transition.equals(other.transition)) return false; return true; } //------- Listener support ------------------------------------------------------------------------ /** * Adds a flow relation listener. * @param listener The flow relation listener to add. * @throws ParameterException If the listener reference is null. */ public void addRelationListener(FlowRelationListener> listener){ relationListenerSupport.addListener(listener); } /** * Removes a flow relation listener. * @param listener The flow relation listener to remove. * @throws ParameterException If the listener reference is null. */ public void removeRelationListener(FlowRelationListener> listener){ relationListenerSupport.removeListener(listener); } //------- toString ------------------------------------------------------------------------------- @Override public String toString() { if(directionPT) return String.format(toStringFormat, name, place.getName(), getConstraint(), transition.getName()); return String.format(toStringFormat, name, transition.getName(), getConstraint(), place.getName()); } //------- clone ---------------------------------------------------------------------------------- public abstract AbstractFlowRelation clone(P place, T transition, boolean directionPT); }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy