package de.vanitasvitae.imi.codes.types; import java.util.regex.Pattern; import java.util.stream.IntStream; import de.vanitasvitae.imi.codes.input.InvalidOptionException; /** * Abstract class, that represents a {@link CharSequence} which MUST match a given REGEX. */ public abstract class BoundedCharSequence implements CharSequence { private final Pattern regex; private final String value; /** * Create a {@link BoundedCharSequence}. If the {@code value} doesn't match the {@code regex}, * a {@link InvalidOptionException} is thrown. * * @param regex regular expression * @param value value of the {@link BoundedCharSequence}. * @throws InvalidOptionException thrown when the value doesn't match the regex. */ protected BoundedCharSequence(Pattern regex, String value) throws InvalidOptionException { this.regex = regex; if (!matchPattern(value)) { throw new InvalidOptionException("Invalid input."); } this.value = value; } private boolean matchPattern(String input) { return regex.matcher(input).matches(); } @Override public int length() { return value.length(); } @Override public char charAt(int i) { return value.charAt(i); } @Override public CharSequence subSequence(int a, int b) { return value.subSequence(a, b); } @Override public IntStream chars() { return value.chars(); } @Override public IntStream codePoints() { return value.codePoints(); } @Override public int hashCode() { return value.hashCode(); } @Override public boolean equals(Object o) { BoundedCharSequence b = (BoundedCharSequence) o; return toString().equals(b.toString()); } @Override public String toString() { return value; } }