com.redhat.ceylon.common.tool.Multiplicity Maven / Gradle / Ivy
package com.redhat.ceylon.common.tool;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* The multiplicity of an option argument or argument.
* @author tom
*/
public class Multiplicity {
public static final Multiplicity _1 = new Multiplicity(1, 1);
public static final Multiplicity _0_OR_MORE = new Multiplicity(0, Integer.MAX_VALUE);
public static final Multiplicity _0_OR_1 = new Multiplicity(0, 1);
public static final Multiplicity _1_OR_MORE = new Multiplicity(1, Integer.MAX_VALUE);
private final int min;
private final int max;
Multiplicity(int minMax) {
this(minMax, minMax);
}
Multiplicity(int min, int max) {
if (min < 0 || max <= 0 || max < min) {
throw new IllegalArgumentException();
}
this.min = min;
this.max = max;
}
/** true if {@linkplain #getMin() min} > 0 */
public boolean isRequired() {
return this.min > 0;
}
/** true if {@linkplain #getMax() max} > 1 */
public boolean isMultivalued() {
return this.max > 1;
}
/** true if {@linkplain #getMin() min} != {@linkplain #getMax() max} */
public boolean isRange() {
return this.max != this.min;
}
/** true if the given number is between {@linkplain #getMin() min}
* and {@linkplain #getMax() max}, inclusive.
*/
public boolean isWithinBound(int num) {
return min <= num && num <= max;
}
public int getMax() {
return max;
}
public int getMin() {
return min;
}
public static Multiplicity fromString(String str) {
str = str.trim();
switch (str) {
case "1":
return _1;
case "*":
return _0_OR_MORE;
case "?":
return _0_OR_1;
case "+":
return _1_OR_MORE;
}
str = str.trim();
Matcher matcher = Pattern.compile("([0-9]+)").matcher(str);
if (matcher.matches()) {
int num = Integer.parseInt(matcher.group(1));
return new Multiplicity(num);
}
matcher = Pattern.compile("([\\(\\[])\\s*([0-9]+)\\s*,\\s*([0-9]+)?\\s*([\\)\\]])").matcher(str);
if (matcher.matches()) {
boolean minInclusive = "[".equals(matcher.group(1));
int min = Integer.parseInt(matcher.group(2));
boolean maxInclusive = "]".equals(matcher.group(4));
int max = matcher.group(3) != null ? Integer.parseInt(matcher.group(3)) : Integer.MAX_VALUE;
return new Multiplicity(minInclusive ? min : min + 1,
maxInclusive || matcher.group(3) == null ? max : max - 1);
}
throw new RuntimeException("Unsupported multiplicity " + str);
}
@Override
public int hashCode() {
return min ^ max;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Multiplicity other = (Multiplicity) obj;
return this.min == other.min
&& this.max == other.max;
}
public String toString() {
if (this.equals(_0_OR_MORE)) {
return "*";
} else if (this.equals(_0_OR_1)) {
return "?";
} else if (this.equals(_1_OR_MORE)) {
return "+";
} else if (min == max) {
return String.valueOf(min);
}
return "[" + min + "," + max + "]";
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy