SeffBranch.java
package de.uka.ipd.sdq.beagle.core;
import org.apache.commons.lang3.Validate;
import org.apache.commons.lang3.builder.EqualsBuilder;
import org.apache.commons.lang3.builder.HashCodeBuilder;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
/**
* Models branches in a component's SEFF, originating from conditional constructs.
*
* <p>SEFF conditions are conditions (like Java’s if , if - else and switch - case
* statements) which affect the calls a component makes to other components. Such
* conditions are—contrary to conditions that stay within an internal action—modelled in a
* component’s SEFF.
*
* @author Annika Berger
* @author Roman Langrehr
*/
public class SeffBranch implements MeasurableSeffElement {
/**
* Serialisation version UID, see {@link java.io.Serializable}.
*/
private static final long serialVersionUID = -1525692970296450080L;
/**
* All branches for this SeffBranch.
*/
private final List<CodeSection> branches;
/**
* Creates a SeffBranch using a given code section.
*
* @param branches A set of valid code sections. Each code sections represents a
* branch of this SeffBranch. It must be sure, that two points of execution
* exists, the so called beginning and ending of this branch, with the
* following properties: When you would insert an empty code line at the
* beginning and an empty code line at the ending, those would form a valid
* code section with the beginning line as first line and the line at the
* ending as last line. And each time the beginning point was reached,
* exactly one code section of this branch gets executed immediately after
* that. This is not checked during runtime, because it would solve the
* halting problem. Immediately after that, the ending point is reached.
* The set must contain at least {@code 2} code sections. Must not be
* {@code null}. May not contain {@code null} entries.
* @throws IllegalArgumentException If {@code branches} has less than {@code 2}
* branches.
*/
public SeffBranch(final Set<CodeSection> branches) {
if (branches.size() <= 1) {
throw new IllegalArgumentException(
"The code section set for the SeffBranch had less than two code sections");
}
Validate.noNullElements(branches);
this.branches = new ArrayList<>(branches);
}
@Override
public boolean equals(final Object object) {
if (object == null) {
return false;
}
if (object == this) {
return true;
}
if (object.getClass() != this.getClass()) {
return false;
}
final SeffBranch other = (SeffBranch) object;
return new EqualsBuilder().append(this.branches, other.branches).isEquals();
}
/**
* Gives a set of valid code sections representing a branch of this SeffBranch.
*
* @return A list of valid code sections representing a branch of this SeffBranch.
* They fulfil the following property: Two points of execution exist, the so
* called beginning and ending of this branch, with the following properties:
* When you would insert an (empty) code line at the beginning and an (empty)
* code line at the ending, those would form a valid code section with the
* beginning line as first line and the line at the ending as last line. And
* each time the beginning point was reached, exactly one code section of this
* branch gets executed immediately after that. Immediately after that, the
* ending point is reached. The set contains at least {@code 2} code sections.
* The list is never {@code null}. This list never contains {@code null}
* entries. Changes to the list are not reflected in the SeffBranch.
*/
public List<CodeSection> getBranches() {
return new ArrayList<>(this.branches);
}
@Override
public int hashCode() {
// you pick a hard-coded, randomly chosen, non-zero, odd number
// ideally different for each class
return new HashCodeBuilder(21, 49).append(this.branches).toHashCode();
}
@Override
public String toString() {
return String.format("SeffBranch@%4.4s<%s>", Integer.toHexString(this.hashCode()), this.branches);
}
}