Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2018, 2026, Oracle and/or its affiliates. All rights reserved.
*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
Expand Down Expand Up @@ -213,41 +213,31 @@ public String getInteractivePrototype() {
}
}

/*
* NOTE: The type parameter T doesn't strictly need to extend Comparable<T>, particularly not
* for UNPARSEABLE. For the other cases, it seemed possible that they could be used where being
* Comparable would be beneficial.
*/
public static <T extends Comparable<T>> QuantityConversionException unparsable(
String badString, T prototype, IPersister<T> persister) {
public static <T> QuantityConversionException unparsable(String badString, T prototype, IPersister<T> persister) {
return new Persisted(Problem.UNPARSEABLE, badString, prototype, persister);
}

public static <T extends Comparable<T>> QuantityConversionException noUnit(
String badString, T prototype, IPersister<T> persister) {
public static <T> QuantityConversionException noUnit(String badString, T prototype, IPersister<T> persister) {
return new Persisted(Problem.NO_UNIT, badString, prototype, persister);
}

public static <T extends Comparable<T>> QuantityConversionException unknownUnit(
String badString, T prototype, IPersister<T> persister) {
public static <T> QuantityConversionException unknownUnit(String badString, T prototype, IPersister<T> persister) {
return new Persisted(Problem.UNKNOWN_UNIT, badString, prototype, persister);
}

public static <T extends Comparable<T>> QuantityConversionException tooLow(
T badValue, T min, IPersister<T> persister) {
public static <T> QuantityConversionException tooLow(T badValue, T min, IPersister<T> persister) {
return new Persisted(Problem.TOO_LOW, badValue, min, persister);
}

public static <T extends Comparable<T>> QuantityConversionException tooHigh(
T badValue, T max, IPersister<T> persister) {
public static <T> QuantityConversionException tooHigh(T badValue, T max, IPersister<T> persister) {
return new Persisted(Problem.TOO_HIGH, badValue, max, persister);
}

/*
* FIXME: This currently reports that the value is "below precision". Replace precisionLimit
* with a closest valid quantity (and change the problem message)?
*/
public static <T extends Comparable<T>> QuantityConversionException belowPrecision(
public static <T> QuantityConversionException belowPrecision(
T badValue, T precisionLimit, IPersister<T> persister) {
return new Persisted(Problem.TOO_SMALL_MAGNITUDE, badValue, precisionLimit, persister);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2018, 2026, Oracle and/or its affiliates. All rights reserved.
*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
Expand Down Expand Up @@ -91,14 +91,9 @@ final public class UnitLookup {
private static final String UNIT_ID_SEPARATOR = ":";
public static final LinearKindOfQuantity MEMORY = createMemory();
public static final LinearKindOfQuantity TIMESPAN = createTimespan();
/*
* NOTE: These 3 (count, index, and identifier) cannot be persisted/restored due to Long(1) and
* Integer(1) not being equal or comparable. We either need to split into concrete wrappers,
* support a custom Comparator, or wrap into a (simple) IQuantity.
*/
public static final ContentType<Number> COUNT = createCount();
public static final ContentType<Number> INDEX = createIndex();
public static final ContentType<Number> IDENTIFIER = createIdentifier();
public static final ContentType<Long> COUNT = createCount();
public static final ContentType<Long> INDEX = createIndex();
public static final ContentType<Long> IDENTIFIER = createIdentifier();
public static final KindOfQuantity<TimestampUnit> TIMESTAMP = createTimestamp(TIMESPAN);
public static final LinearKindOfQuantity PERCENTAGE = createPercentage();
public static final LinearKindOfQuantity NUMBER = createNumber();
Expand Down Expand Up @@ -426,15 +421,99 @@ private static String formatHexNumber(IQuantity quantity) {
return String.format("0x%08X", quantity.longValue());
}

private static Number parseNumber(String numberStr) {
try {
return Long.parseLong(numberStr);
} catch (NumberFormatException eLong) {
return Double.parseDouble(numberStr);
}
}

// FIXME: Rename to createPrimitiveNumber? Remove?
private static ContentType<Number> createRawNumber() {
ContentType<Number> contentType = new ContentType<>("raw number");
ContentType<Number> contentType = new LeafContentType<Number>("raw number") {
@Override
public boolean validate(Number value) {
checkNull(value);
return false;
}

@Override
public String persistableString(Number value) {
validate(value);
return value.toString();
}

@Override
public Number parsePersisted(String persistedValue) throws QuantityConversionException {
checkNull(persistedValue);
try {
return parseNumber(persistedValue);
} catch (NumberFormatException e) {
throw QuantityConversionException.unparsable(persistedValue, 0, this);
}
}

@Override
public String interactiveFormat(Number value) {
validate(value);
return value.toString();
}

@Override
public Number parseInteractive(String interactiveValue) throws QuantityConversionException {
checkNull(interactiveValue);
try {
return parseNumber(interactiveValue);
} catch (NumberFormatException e) {
throw QuantityConversionException.unparsable(interactiveValue, 0, this);
}
}
};
contentType.addFormatter(new DisplayFormatter<>(contentType, IDisplayable.AUTO, "Value"));
return contentType;
}

private static ContentType<Long> createRawLong() {
ContentType<Long> contentType = new ContentType<>("raw long");
ContentType<Long> contentType = new LeafContentType<Long>("raw long") {
@Override
public boolean validate(Long value) {
checkNull(value);
return false;
}

@Override
public String persistableString(Long value) {
validate(value);
return value.toString();
}

@Override
public Long parsePersisted(String persistedValue) throws QuantityConversionException {
checkNull(persistedValue);
try {
return Long.parseLong(persistedValue);
} catch (NumberFormatException e) {
throw QuantityConversionException.unparsable(persistedValue, 0L, this);
}
}

@Override
public String interactiveFormat(Long value) {
validate(value);
return value.toString();
}

@Override
public Long parseInteractive(String interactiveValue) throws QuantityConversionException {
checkNull(interactiveValue);
try {
return Long.parseLong(interactiveValue);
} catch (NumberFormatException e) {
throw QuantityConversionException.unparsable(interactiveValue, 0L, this);
}
}
};
contentType.addFormatter(new DisplayFormatter<>(contentType, IDisplayable.AUTO, "Value"));
return contentType;
}
Expand Down Expand Up @@ -568,25 +647,134 @@ private static LinearKindOfQuantity createPercentage() {
return percentage;
}

private static ContentType<Number> createCount() {
ContentType<Number> contentType = new ContentType<>("count");
// contentType.addDisplayUnit(
// new DisplayUnit(contentType, DisplayUnit.ENGINEERING_NOTATION_IDENTIFIER, "Engineering Notation"));
contentType.addFormatter(new DisplayFormatter<>(contentType, IDisplayable.AUTO, "Value"));
private static ContentType<Long> createCount() {
ContentType<Long> contentType = new LeafContentType<Long>("count") {
@Override
public boolean validate(Long value) {
checkNull(value);
return false;
}

@Override
public String persistableString(Long value) {
validate(value);
return value.toString();
}

@Override
public Long parsePersisted(String persistedValue) throws QuantityConversionException {
checkNull(persistedValue);
try {
return Long.parseLong(persistedValue);
} catch (NumberFormatException e) {
throw QuantityConversionException.unparsable(persistedValue, 0L, this);
}
}

@Override
public String interactiveFormat(Long value) {
validate(value);
return value.toString();
}

// contentType.addDisplayUnit(
// new DisplayUnit(contentType, DisplayUnit.SCIENTIFIC_NOTATION_IDENTIFIER, "Scientific Notation"));
@Override
public Long parseInteractive(String interactiveValue) throws QuantityConversionException {
checkNull(interactiveValue);
try {
return Long.parseLong(interactiveValue);
} catch (NumberFormatException e) {
throw QuantityConversionException.unparsable(interactiveValue, 0L, this);
}
}
};
contentType.addFormatter(new DisplayFormatter<>(contentType, IDisplayable.AUTO, "Value"));
return contentType;
}

private static ContentType<Number> createIdentifier() {
ContentType<Number> contentType = new ContentType<>("identifier");
private static ContentType<Long> createIdentifier() {
ContentType<Long> contentType = new LeafContentType<Long>("identifier") {
@Override
public boolean validate(Long value) {
checkNull(value);
return false;
}

@Override
public String persistableString(Long value) {
validate(value);
return value.toString();
}

@Override
public Long parsePersisted(String persistedValue) throws QuantityConversionException {
checkNull(persistedValue);
try {
return Long.parseLong(persistedValue);
} catch (NumberFormatException e) {
throw QuantityConversionException.unparsable(persistedValue, 0L, this);
}
}

@Override
public String interactiveFormat(Long value) {
validate(value);
return value.toString();
}

@Override
public Long parseInteractive(String interactiveValue) throws QuantityConversionException {
checkNull(interactiveValue);
try {
return Long.parseLong(interactiveValue);
} catch (NumberFormatException e) {
throw QuantityConversionException.unparsable(interactiveValue, 0L, this);
}
}
};
contentType.addFormatter(new DisplayFormatter<>(contentType, IDisplayable.AUTO, "Value"));
return contentType;
}

private static ContentType<Number> createIndex() {
ContentType<Number> contentType = new ContentType<>("index");
private static ContentType<Long> createIndex() {
ContentType<Long> contentType = new LeafContentType<Long>("index") {
@Override
public boolean validate(Long value) {
checkNull(value);
return false;
}

@Override
public String persistableString(Long value) {
validate(value);
return value.toString();
}

@Override
public Long parsePersisted(String persistedValue) throws QuantityConversionException {
checkNull(persistedValue);
try {
return Long.parseLong(persistedValue);
} catch (NumberFormatException e) {
throw QuantityConversionException.unparsable(persistedValue, 0L, this);
}
}

@Override
public String interactiveFormat(Long value) {
validate(value);
return value.toString();
}

@Override
public Long parseInteractive(String interactiveValue) throws QuantityConversionException {
checkNull(interactiveValue);
try {
return Long.parseLong(interactiveValue);
} catch (NumberFormatException e) {
throw QuantityConversionException.unparsable(interactiveValue, 0L, this);
}
}
};
contentType.addFormatter(new DisplayFormatter<>(contentType, IDisplayable.AUTO, "Value"));
return contentType;
}
Expand Down
Loading
Loading