17935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert/* 27935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert ******************************************************************************* 37935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Copyright (C) 1996-2012, Google, International Business Machines Corporation and * 47935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * others. All Rights Reserved. * 57935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert ******************************************************************************* 67935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert */ 77935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertpackage com.ibm.icu.dev.util; 87935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 97935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport java.util.Comparator; 107935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport java.util.HashMap; 117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport java.util.List; 127935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 137935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport com.ibm.icu.dev.util.UnicodeProperty.PatternMatcher; 147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport com.ibm.icu.impl.UnicodeRegex; 157935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport com.ibm.icu.text.UTF16; 167935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport com.ibm.icu.text.UnicodeSet; 177935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 187935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert/** 197935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Allows for overriding the parsing of UnicodeSet property patterns. 207935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * <p> 217935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * WARNING: If this UnicodePropertySymbolTable is used with {@code UnicodeSet.setDefaultXSymbolTable}, and the 227935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Unassigned characters (gc=Cn) are different than in ICU other than in ICU, you MUST call 237935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * {@code UnicodeProperty.ResetCacheProperties} afterwards. If you then call {@code UnicodeSet.setDefaultXSymbolTable} 247935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * with null to clear the value, you MUST also call {@code UnicodeProperty.ResetCacheProperties}. 257935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * 267935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @author markdavis 277935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert */ 287935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertpublic class UnicodePropertySymbolTable extends UnicodeSet.XSymbolTable { 297935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert UnicodeRegex unicodeRegex; 307935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert final UnicodeProperty.Factory factory; 317935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 327935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public UnicodePropertySymbolTable(UnicodeProperty.Factory factory) { 337935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert unicodeRegex = new UnicodeRegex().setSymbolTable(this); 347935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert this.factory = factory; 357935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 367935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 377935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 387935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // public boolean applyPropertyAlias0(String propertyName, 397935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // String propertyValue, UnicodeSet result) { 407935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // if (!propertyName.contains("*")) { 417935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // return applyPropertyAlias(propertyName, propertyValue, result); 427935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // } 437935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // String[] propertyNames = propertyName.split("[*]"); 447935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // for (int i = propertyNames.length - 1; i >= 0; ++i) { 457935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // String pname = propertyNames[i]; 467935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // 477935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // } 487935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // return null; 497935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // } 507935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 517935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public boolean applyPropertyAlias(String propertyName, 527935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert String propertyValue, UnicodeSet result) { 537935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert boolean status = false; 547935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert boolean invert = false; 557935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert int posNotEqual = propertyName.indexOf('\u2260'); 567935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert int posColon = propertyName.indexOf(':'); 577935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (posNotEqual >= 0 || posColon >= 0) { 587935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (posNotEqual < 0) posNotEqual = propertyName.length(); 597935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (posColon < 0) posColon = propertyName.length(); 607935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert int opPos = posNotEqual < posColon ? posNotEqual : posColon; 617935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert propertyValue = propertyValue.length() == 0 ? propertyName.substring(opPos+1) 627935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert : propertyName.substring(opPos+1) + "=" + propertyValue; 637935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert propertyName = propertyName.substring(0,opPos); 647935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (posNotEqual < posColon) { 657935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert invert = true; 667935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 677935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 687935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (propertyName.endsWith("!")) { 697935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert propertyName = propertyName.substring(0, propertyName.length() - 1); 707935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert invert = !invert; 717935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 727935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert propertyValue = propertyValue.trim(); 737935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (propertyValue.length() != 0) { 747935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert status = applyPropertyAlias0(propertyName, propertyValue, result); 757935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } else { 767935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert try { 777935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert status = applyPropertyAlias0("gc", propertyName, result); 787935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } catch (Exception e) {}; 797935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (!status) { 807935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert try { 817935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert status = applyPropertyAlias0("sc", propertyName, result); 827935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } catch (Exception e) {}; 837935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (!status) { 847935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert try { 857935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert status = applyPropertyAlias0(propertyName, "Yes", result); 867935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } catch (Exception e) {}; 877935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (!status) { 887935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert status = applyPropertyAlias0(propertyName, "", result); 897935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 907935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 917935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 927935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 937935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (status && invert) { 947935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert result.complement(); 957935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 967935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return status; 977935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 987935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 997935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert static final HashMap<String,String[]> GC_REMAP = new HashMap(); 1007935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert { 1017935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert GC_REMAP.put("c", "Cc Cf Cn Co Cs".split(" ")); 1027935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert GC_REMAP.put("other", GC_REMAP.get("c")); 1037935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 1047935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert GC_REMAP.put("l", "Ll Lm Lo Lt Lu".split(" ")); 1057935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert GC_REMAP.put("letter", GC_REMAP.get("l")); 1067935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 1077935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert GC_REMAP.put("lc", "Ll Lt Lu".split(" ")); 1087935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert GC_REMAP.put("casedletter", GC_REMAP.get("lc")); 1097935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 1107935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert GC_REMAP.put("m", "Mc Me Mn".split(" ")); 1117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert GC_REMAP.put("mark", GC_REMAP.get("m")); 1127935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 1137935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert GC_REMAP.put("n", "Nd Nl No".split(" ")); 1147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert GC_REMAP.put("number", GC_REMAP.get("n")); 1157935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 1167935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert GC_REMAP.put("p", "Pc Pd Pe Pf Pi Po Ps".split(" ")); 1177935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert GC_REMAP.put("punctuation", GC_REMAP.get("p")); 1187935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert GC_REMAP.put("punct", GC_REMAP.get("p")); 1197935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 1207935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert GC_REMAP.put("s", "Sc Sk Sm So".split(" ")); 1217935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert GC_REMAP.put("symbol", GC_REMAP.get("s")); 1227935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 1237935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert GC_REMAP.put("z", "Zl Zp Zs".split(" ")); 1247935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert GC_REMAP.put("separator", GC_REMAP.get("z")); 1257935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 1267935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 1277935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public boolean applyPropertyAlias0(String propertyName, 1287935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert String propertyValue, UnicodeSet result) { 1297935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert result.clear(); 1307935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert UnicodeProperty prop = factory.getProperty(propertyName); 1317935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert String canonicalName = prop.getName(); 1327935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert boolean isAge = UnicodeProperty.equalNames("Age", canonicalName); 1337935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 1347935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // Hack for special GC values 1357935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (canonicalName.equals("General_Category")) { 1367935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert String[] parts = GC_REMAP.get(UnicodeProperty.toSkeleton(propertyValue)); 1377935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (parts != null) { 1387935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert for (String part : parts) { 1397935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert prop.getSet(part, result); 1407935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 1417935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return true; 1427935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 1437935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 1447935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 1457935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert PatternMatcher patternMatcher = null; 1467935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (propertyValue.length() > 1 && propertyValue.startsWith("/") && propertyValue.endsWith("/")) { 1477935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert String fixedRegex = unicodeRegex.transform(propertyValue.substring(1, propertyValue.length() - 1)); 1487935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert patternMatcher = new UnicodeProperty.RegexMatcher().set(fixedRegex); 1497935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 1507935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert UnicodeProperty otherProperty = null; 1517935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert boolean testCp = false; 1527935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (propertyValue.length() > 1 && propertyValue.startsWith("@") && propertyValue.endsWith("@")) { 1537935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert String otherPropName = propertyValue.substring(1, propertyValue.length() - 1).trim(); 1547935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if ("cp".equalsIgnoreCase(otherPropName)) { 1557935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert testCp = true; 1567935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } else { 1577935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert otherProperty = factory.getProperty(otherPropName); 1587935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 1597935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 1607935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (prop != null) { 1617935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert UnicodeSet set; 1627935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (testCp) { 1637935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert set = new UnicodeSet(); 1647935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert for (int i = 0; i <= 0x10FFFF; ++i) { 1657935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (UnicodeProperty.equals(i, prop.getValue(i))) { 1667935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert set.add(i); 1677935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 1687935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 1697935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } else if (otherProperty != null) { 1707935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert set = new UnicodeSet(); 1717935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert for (int i = 0; i <= 0x10FFFF; ++i) { 1727935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert String v1 = prop.getValue(i); 1737935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert String v2 = otherProperty.getValue(i); 1747935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (UnicodeProperty.equals(v1, v2)) { 1757935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert set.add(i); 1767935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 1777935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 1787935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } else if (patternMatcher == null) { 1797935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (!isValid(prop, propertyValue)) { 1807935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert throw new IllegalArgumentException("The value '" + propertyValue + "' is illegal. Values for " + propertyName 1817935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert + " must be in " 1827935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert + prop.getAvailableValues() + " or in " + prop.getValueAliases()); 1837935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 1847935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (isAge) { 1857935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert set = prop.getSet(new ComparisonMatcher(propertyValue, Relation.geq)); 1867935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } else { 1877935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert set = prop.getSet(propertyValue); 1887935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 1897935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } else if (isAge) { 1907935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert set = new UnicodeSet(); 1917935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert List<String> values = prop.getAvailableValues(); 1927935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert for (String value : values) { 1937935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (patternMatcher.matches(value)) { 1947935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert for (String other : values) { 1957935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (other.compareTo(value) <= 0) { 1967935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert set.addAll(prop.getSet(other)); 1977935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 1987935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 1997935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 2007935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 2017935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } else { 2027935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert set = prop.getSet(patternMatcher); 2037935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 2047935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert result.addAll(set); 2057935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return true; 2067935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 2077935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert throw new IllegalArgumentException("Illegal property: " + propertyName); 2087935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 2097935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 2107935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 2117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 2127935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert private boolean isValid(UnicodeProperty prop, String propertyValue) { 2137935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert// if (prop.getName().equals("General_Category")) { 2147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert// if (propertyValue) 2157935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert// } 2167935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return prop.isValidValue(propertyValue); 2177935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 2187935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 2197935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public enum Relation {less, leq, equal, geq, greater} 2207935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 2217935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public static class ComparisonMatcher implements PatternMatcher { 2227935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert Relation relation; 2237935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert static Comparator comparator = new UTF16.StringComparator(true, false,0); 2247935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 2257935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert String pattern; 2267935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 2277935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public ComparisonMatcher(String pattern, Relation comparator) { 2287935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert this.relation = comparator; 2297935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert this.pattern = pattern; 2307935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 2317935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 2327935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public boolean matches(Object value) { 2337935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert int comp = comparator.compare(pattern, value.toString()); 2347935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert switch (relation) { 2357935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert case less: return comp < 0; 2367935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert case leq: return comp <= 0; 2377935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert default: return comp == 0; 2387935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert case geq: return comp >= 0; 2397935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert case greater: return comp > 0; 2407935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 2417935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 2427935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 2437935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public PatternMatcher set(String pattern) { 2447935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert this.pattern = pattern; 2457935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return this; 2467935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 2477935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 2487935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 249