package MusicLandscape.util.matcher;
import MusicLandscape.entities.Track;
import MusicLandscape.util.MyMatcher;
/**
* Encapsulates the concept of matching a track based on its duration.
* <p>
* This class is used to test whether given a given track's duration lies in a certain range, the range being the
* pattern of this matcher.The pattern is a simple string consisting of the (white-space separated) lower and upper
* bounds (inclusive) of the range of duration s (in seconds) accepted by this matcher.
* <p>
* More precisely, a valid pattern is a String that can be interpreted as either a single integer number
* (leading and trailing whitespace are ignored, if present) which then represents the lower bound
* or two integer numbers, separated by (any number of) whitespace, which then represent lower and upper bound.
* <p>
* The bounds are understood to be inclusive.
*
* @author Jonas Altrock (ew20b126@technikum-wien.at)
* @version 1
* @since ExerciseSheet05
*/
public class DurationMatcher extends MyMatcher<Track> {
/**
* the lower bound of the accepted range.
*/
private int lower;
/**
* the upper bound of the accepted range.
*/
private int upper;
/**
* Creates a default duration matcher.<br>
* By default, a matcher matches any duration, including unknown duration.
*/
public DurationMatcher() {
super("");
}
/**
* Creates a duration matcher with a specified pattern.
*
* @param pat the pattern of this matcher
*/
public DurationMatcher(String pat) {
super(pat);
}
/**
* A track matches if its duration is in the range accepted by this matcher.
*
* @param track the object to match
* @return whether t matches the pattern of this matcher.
*/
@Override
public boolean matches(Track track) {
return track.getDuration() >= lower && track.getDuration() <= upper;
}
/**
* Sets the pattern of this matcher.
* <p>
* Interprets the argument as described in the class documentation. First sets the lower, then the upper bound.
* The bounds specified are set if and only if at the time of setting they are actually lower (for the lower bound)
* or higher (for the upper bound) than the other or at least equal to the other.
*
* @param pat the pattern to set
*/
@Override
public void setPattern(String pat) {
String[] parts = pat.trim().split("\\s+");
lower = 0;
upper = Integer.MAX_VALUE;
if (parts.length < 1 || parts[0].isEmpty()) {
return;
}
try {
lower = Integer.max(Integer.parseInt(parts[0]), 0);
} catch (NumberFormatException ignored) {}
if (parts.length < 2) {
return;
}
try {
int upperBound = Integer.min(Integer.parseInt(parts[1]), upper);
if (upperBound >= lower) {
upper = upperBound;
}
} catch (NumberFormatException ignored) {}
}
/**
* the valid pattern is <kbd>LOWER UPPER</kbd> separated by whitespace.
*
* @return the pattern
*/
@Override
public String getPattern() {
return lower + " " + upper;
}
/**
* the string representation is duration in range (RANGE)<br>
* with range as described in getPattern
*
* @return a string representation of the object.
*/
@Override
public String toString() {
return "duration in range (" + lower + " " + upper + ")";
}
}