Skip to content

Commit 88e90ab

Browse files
authored
Various fixes to versioned property utilities (#1119)
* Allow for properties to pop in and out of existence, thereby simplifying the history display code. Do not show version ranges where we do not have version data. * != on String I hate you * Fix (recent) versioned nv queries * Properly apply the default class
1 parent 0f8bddb commit 88e90ab

File tree

4 files changed

+67
-42
lines changed

4 files changed

+67
-42
lines changed

UnicodeJsps/src/main/java/org/unicode/jsp/UnicodeJsp.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,9 @@ public static String getSimpleSet(
184184
a_out = UnicodeUtilities.getPrettySet(a, abbreviate, escape);
185185
} catch (Exception e) {
186186
a_out = e.getMessage();
187+
for (Throwable cause = e; cause != null; cause = cause.getCause()) {
188+
cause.printStackTrace();
189+
}
187190
}
188191
return a_out;
189192
}

UnicodeJsps/src/main/java/org/unicode/jsp/UnicodeUtilities.java

Lines changed: 52 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1692,22 +1692,22 @@ private static void showPropertyValue(
16921692
VersionInfo maxVersion,
16931693
Appendable out)
16941694
throws IOException {
1695-
String defaultClass =
1696-
getFactory().getProperty(propName).isDefault(codePoint) ? " class='default'" : "";
16971695
var indexedProperty = UcdProperty.forString(propName);
16981696
final boolean provisional =
16991697
indexedProperty != null
17001698
&& indexedProperty.getDerivedStatus() == DerivedPropertyStatus.Provisional;
17011699
class PropertyAssignment {
17021700
VersionInfo first;
17031701
VersionInfo last;
1702+
// The field `values` is null if the property does not exist in that range of versions.
1703+
// If the property has the value null (<none>), `values` is a one-element list whose
1704+
// sole element is null.
17041705
ArrayList<String> values;
1706+
boolean isDefault;
17051707
int span;
17061708
}
17071709
final boolean isMultivalued = getFactory().getProperty(propName).isMultivalued();
17081710
List<PropertyAssignment> history = new ArrayList<>();
1709-
int prehistoricSpan = 0;
1710-
int posthistoricSpan = 0;
17111711
if (getFactory().getProperty(propName)
17121712
instanceof IndexUnicodeProperties.IndexUnicodeProperty) {
17131713
for (int i = Utility.UNICODE_VERSIONS.size() - 1; i >= 0; --i) {
@@ -1725,25 +1725,21 @@ class PropertyAssignment {
17251725
continue;
17261726
}
17271727
final var property = IndexUnicodeProperties.make(version).getProperty(propName);
1728-
// Skip properties prior to their creation, as well as properties that no longer
1729-
// exist on the range minVersion..maxVersion.
1728+
ArrayList<String> values;
17301729
if (property.isTrivial() && !property.getName().equals("ISO_Comment")) {
1731-
if (history.isEmpty()) {
1732-
++prehistoricSpan;
1733-
} else {
1734-
++posthistoricSpan;
1735-
}
1736-
continue;
1730+
values = null;
1731+
} else {
1732+
values = new ArrayList<>();
1733+
property.getValues(codePoint).forEach(values::add);
17371734
}
1738-
ArrayList<String> values = new ArrayList<>();
1739-
property.getValues(codePoint).forEach(values::add);
17401735
PropertyAssignment lastAssignment =
17411736
history.isEmpty() ? null : history.get(history.size() - 1);
1742-
if (lastAssignment == null || (!values.equals(lastAssignment.values))) {
1737+
if (lastAssignment == null || (!Objects.equals(values, lastAssignment.values))) {
17431738
PropertyAssignment assignment = new PropertyAssignment();
17441739
assignment.first = version;
17451740
assignment.last = version;
17461741
assignment.values = values;
1742+
assignment.isDefault = property.isDefault(codePoint);
17471743
assignment.span = 1;
17481744
history.add(assignment);
17491745
} else {
@@ -1759,7 +1755,7 @@ class PropertyAssignment {
17591755
getFactory().getProperty(propName).getValues(codePoint).forEach(current.values::add);
17601756
history.add(current);
17611757
}
1762-
if (!history.isEmpty()) {
1758+
if (history.get(0).values != null || history.size() > 1) {
17631759
out.append(
17641760
"<tr><th width='50%'><a target='c' href='properties.jsp?a="
17651761
+ propName
@@ -1768,9 +1764,6 @@ class PropertyAssignment {
17681764
+ "'>"
17691765
+ (provisional ? "(" + propName + ")" : propName)
17701766
+ "</a></th>");
1771-
if (prehistoricSpan > 0) {
1772-
out.append("<td class='nonexistent' colspan=" + prehistoricSpan + "></td>");
1773-
}
17741767
for (PropertyAssignment assignment : history) {
17751768
String first =
17761769
assignment.first.getVersionString(2, 4)
@@ -1786,39 +1779,58 @@ class PropertyAssignment {
17861779
assignment.first.compareTo(Settings.LAST_VERSION_INFO) <= 0
17871780
&& Settings.LAST_VERSION_INFO.compareTo(assignment.last) <= 0;
17881781
boolean showVersion =
1789-
minVersion.compareTo(Settings.LAST_VERSION_INFO) < 0 || history.size() > 1;
1782+
indexedProperty != null
1783+
&& (minVersion.compareTo(Settings.LAST_VERSION_INFO) < 0
1784+
|| history.size() > 1);
17901785
boolean isSingleVersion = assignment.first == assignment.last;
17911786
boolean isNew = assignment.first == Settings.LATEST_VERSION_INFO;
17921787
String versionRange =
17931788
(showVersion ? (isSingleVersion ? first : first + ".." + last) + ": " : "");
17941789
String htmlValue =
1795-
assignment.values.stream()
1796-
.map(v -> v == null ? "<i>null</i>" : toHTML.transliterate(v))
1797-
.collect(Collectors.joining("<wbr>|"));
1790+
assignment.values == null
1791+
? null
1792+
: assignment.values.stream()
1793+
.map(
1794+
v ->
1795+
v == null
1796+
? "<i>null</i>"
1797+
: toHTML.transliterate(v))
1798+
.collect(Collectors.joining("<wbr>|"));
1799+
String tdClass = "";
1800+
if (assignment.values == null) {
1801+
tdClass = "class='nonexistent'";
1802+
} else if (assignment.isDefault) {
1803+
tdClass = "class='default'";
1804+
}
17981805
out.append(
1799-
"<td"
1800-
+ defaultClass
1806+
"<td "
1807+
+ tdClass
18011808
+ " colspan="
18021809
+ assignment.span
18031810
+ ">"
1804-
+ (isMultivalued || htmlValue.contains("<")
1805-
? "<span" + (isNew ? " class='changed'" : "") + ">"
1806-
: ("<a target='u' "
1807-
+ (isNew ? "class='changed' " : "")
1808-
+ "href='list-unicodeset.jsp?a=[:"
1809-
+ (isCurrent ? "" : "U" + last + ":")
1810-
+ propName
1811-
+ "="
1811+
+ (assignment.values != null
1812+
? (isMultivalued || htmlValue.contains("<")
1813+
? "<span"
1814+
+ (isNew ? " class='changed'" : "")
1815+
+ ">"
1816+
: ("<a target='u' "
1817+
+ (isNew ? "class='changed' " : "")
1818+
+ "href='list-unicodeset.jsp?a=[:"
1819+
+ (isCurrent
1820+
? ""
1821+
: "U" + last + ":")
1822+
+ propName
1823+
+ "="
1824+
+ htmlValue
1825+
+ ":]'>"))
1826+
+ versionRange
18121827
+ htmlValue
1813-
+ ":]'>"))
1814-
+ versionRange
1815-
+ htmlValue
1816-
+ (isMultivalued || htmlValue.contains("<") ? "</span>" : "</a>")
1828+
+ (isMultivalued || htmlValue.contains("<")
1829+
? "</span>"
1830+
: "</a>")
1831+
: "")
18171832
+ "</td>");
18181833
}
1819-
if (posthistoricSpan > 0) {
1820-
out.append("<td class='nonexistent' colspan=" + posthistoricSpan + "></td>");
1821-
}
18221834
out.append("</tr>");
18231835
}
18241836
}

unicodetools/src/main/java/org/unicode/props/UnicodeProperty.java

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
import com.ibm.icu.text.UnicodeMatcher;
1515
import com.ibm.icu.text.UnicodeSet;
1616
import com.ibm.icu.text.UnicodeSetIterator;
17+
import com.ibm.icu.util.ICUException;
1718
import java.io.PrintWriter;
1819
import java.io.StringWriter;
1920
import java.text.ParsePosition;
@@ -754,7 +755,16 @@ public static int compareRationals(String a, String b) {
754755
if (aIsNaN && bIsNaN) return 0;
755756
if (aIsNaN) return -1;
756757
if (bIsNaN) return 1;
757-
return RationalParser.BASIC.parse(a).compareTo(RationalParser.BASIC.parse(b));
758+
try {
759+
return RationalParser.BASIC.parse(a).compareTo(RationalParser.BASIC.parse(b));
760+
} catch (ICUException e) {
761+
// If either string fails to parse as a rational, compare the strings.
762+
// This is nonsense, but we do such comparisons with the UNCHANGED_IN_BASE_VERSION
763+
// placeholder string when operating on the chronologically compressed maps (we then
764+
// ignore the result by intersecting with the set where the UNCHANGED_IN_BASE_VERSION
765+
// placeholder does not appear).
766+
return a.compareTo(b);
767+
}
758768
}
759769

760770
public static final Comparator<String> CHARACTER_NAME_COMPARATOR =

unicodetools/src/main/java/org/unicode/text/UCD/VersionedSymbolTable.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -315,7 +315,7 @@ private VersionInfo parseVersionQualifier(StringBuilder qualified) {
315315
} else if (versionNumber.endsWith("α") || versionNumber.endsWith("β")) {
316316
final String versionSuffix = versionNumber.substring(versionNumber.length() - 1);
317317
versionNumber = versionNumber.substring(0, versionNumber.length() - 1);
318-
if (versionSuffix != Settings.latestVersionPhase.toString()) {
318+
if (!versionSuffix.equals(Settings.latestVersionPhase.toString())) {
319319
throw new IllegalArgumentException(
320320
"Invalid version-qualifier "
321321
+ versionQualifier

0 commit comments

Comments
 (0)