VisioProperty.java
package com.taxonomy.visio;
import java.math.BigDecimal;
import java.util.Objects;
/** Literal Shape Data values; user values are never written as ShapeSheet formulas. */
public record VisioProperty(Kind kind, String value) {
public enum Kind { STRING, NUMBER, BOOLEAN }
public VisioProperty {
Objects.requireNonNull(kind, "property kind");
Objects.requireNonNull(value, "property value");
if (kind == Kind.NUMBER) {
if (value.length() > 350) throw new IllegalArgumentException("Property number is too long");
BigDecimal number;
try {
number = new BigDecimal(value).stripTrailingZeros();
} catch (NumberFormatException exception) {
throw new IllegalArgumentException("Invalid numeric Visio property", exception);
}
if (Math.abs((long) number.scale()) > 350 || number.precision() > 350
|| !Double.isFinite(number.doubleValue())) {
throw new IllegalArgumentException("Property number is outside the supported finite range");
}
value = number.toPlainString();
}
if (kind == Kind.BOOLEAN && !value.equals("true") && !value.equals("false")) {
throw new IllegalArgumentException("Invalid Boolean property");
}
}
public static VisioProperty text(Object value) {
return new VisioProperty(Kind.STRING, Objects.requireNonNull(value, "property value").toString());
}
public static VisioProperty number(double value) {
if (!Double.isFinite(value)) throw new IllegalArgumentException("Property number must be finite");
return new VisioProperty(Kind.NUMBER, BigDecimal.valueOf(value).toPlainString());
}
public static VisioProperty bool(boolean value) { return new VisioProperty(Kind.BOOLEAN, Boolean.toString(value)); }
public String shapeType() { return switch (kind) { case STRING -> "0"; case NUMBER -> "2"; case BOOLEAN -> "3"; }; }
public String shapeValue() { return kind == Kind.BOOLEAN ? (value.equals("true") ? "1" : "0") : value; }
}