1 package org.unicode.cldr.util; 2 3 import com.google.common.collect.ImmutableMultimap; 4 import com.google.common.collect.ImmutableSet; 5 import com.google.common.collect.Multimap; 6 import java.util.Collections; 7 import java.util.EnumSet; 8 import java.util.Set; 9 import org.unicode.cldr.util.GrammarInfo.GrammaticalFeature; 10 11 public enum UnitPathType { 12 // we may add features over time 13 unit( 14 "kilometer", 15 EnumSet.of( 16 GrammarInfo.GrammaticalFeature.grammaticalNumber, 17 GrammarInfo.GrammaticalFeature.grammaticalCase), 18 null), 19 perUnit("minute", null, null), 20 times( 21 null, 22 null, 23 ImmutableMultimap.<String, String>builder() 24 .put("", "newton-meter") 25 .put("", "kilowatt-hour") 26 .build()), 27 per( 28 null, 29 null, 30 ImmutableMultimap.<String, String>builder() 31 .put("", "meter-per-second") 32 .put("", "mile-per-gallon") 33 .build()), 34 prefix( 35 null, 36 null, 37 ImmutableMultimap.<String, String>builder() 38 .put("10p2", "hectopascal") 39 .put("10p3", "kilometer") 40 .put("10p6", "megabyte") 41 .put("10p9", "gigahertz") 42 .put("10p12", "terabyte") 43 .put("10p15", "petabyte") 44 .put("10p-1", "deciliter") 45 .put("10p-2", "centimeter") 46 .put("10p-3", "milligram") 47 .put("10p-6", "microsecond") 48 .put("10p-9", "nanosecond") 49 .put("10p-12", "picometer") 50 .build()), 51 power( 52 "power2", 53 EnumSet.of( 54 GrammarInfo.GrammaticalFeature.grammaticalNumber, 55 GrammarInfo.GrammaticalFeature.grammaticalCase, 56 GrammarInfo.GrammaticalFeature.grammaticalGender), 57 ImmutableMultimap.<String, String>builder() 58 .put("power2", "square-meter") 59 .put("power2", "square-second") 60 .put("power3", "cubic-meter") 61 .put("power3", "cubic-second") 62 .build()), 63 duration(null, null, null), 64 gender(null, null, null), 65 coordinate(null, null, null), 66 displayName(null, null, null); 67 68 public final Set<GrammaticalFeature> features; 69 public final Set<String> sampleShortUnitType; 70 public final ImmutableMultimap<String, String> sampleComposedShortUnitIds; 71 UnitPathType( String sampleType, Set<GrammarInfo.GrammaticalFeature> features, ImmutableMultimap<String, String> sampleComposedLongUnits)72 private UnitPathType( 73 String sampleType, 74 Set<GrammarInfo.GrammaticalFeature> features, 75 ImmutableMultimap<String, String> sampleComposedLongUnits) { 76 this.sampleShortUnitType = Collections.singleton(sampleType); 77 this.sampleComposedShortUnitIds = sampleComposedLongUnits; 78 this.features = features == null ? Collections.emptySet() : ImmutableSet.copyOf(features); 79 } 80 getPathType(XPathParts parts)81 public static UnitPathType getPathType(XPathParts parts) { 82 String el2 = parts.getElement(2); 83 if (el2.equals("durationUnit")) { 84 String lastEl = parts.getElement(-1); 85 if (lastEl.equals("durationUnitPattern")) { 86 return UnitPathType.duration; 87 } else { 88 return null; 89 } 90 } 91 if (!el2.equals("unitLength")) { 92 return null; 93 } 94 switch (parts.getElement(-1)) { 95 case "compoundUnitPattern": 96 return "times".equals(parts.getAttributeValue(-2, "type")) 97 ? UnitPathType.times 98 : UnitPathType.per; 99 case "unitPrefixPattern": 100 return UnitPathType.prefix; 101 case "compoundUnitPattern1": 102 return UnitPathType.power; 103 case "unitPattern": 104 return UnitPathType.unit; 105 case "perUnitPattern": 106 return UnitPathType.perUnit; 107 case "prefix": 108 return UnitPathType.prefix; 109 case "gender": 110 return UnitPathType.gender; 111 case "coordinateUnitPattern": 112 return UnitPathType.coordinate; 113 case "durationUnit": 114 return UnitPathType.duration; 115 case "alias": 116 return null; 117 case "displayName": 118 return UnitPathType.displayName; 119 } 120 throw new IllegalArgumentException("PathType: " + parts); 121 } 122 getTranslationPath( LocaleStringProvider resolvedFile, String width, String shortUnitId, String pluralCategory, String caseVariant, String genderVariant)123 public String getTranslationPath( 124 LocaleStringProvider resolvedFile, 125 String width, 126 String shortUnitId, 127 String pluralCategory, 128 String caseVariant, 129 String genderVariant) { 130 UnitPathType pathType = this; 131 final String pathPrefix = "//ldml/units/unitLength[@type=\"" + width + "\"]/"; 132 String longUnitId; 133 GrammarInfo grammarInfo1; 134 UnitConverter uc = CLDRConfig.getInstance().getSupplementalDataInfo().getUnitConverter(); 135 136 String grammaticalAttributes; 137 switch (pathType) { 138 case times: 139 return pathPrefix + "compoundUnit[@type=\"" + "times" + "\"]/compoundUnitPattern"; 140 case per: 141 return pathPrefix + "compoundUnit[@type=\"" + "per" + "\"]/compoundUnitPattern"; 142 case prefix: 143 longUnitId = 144 CLDRConfig.getInstance() 145 .getSupplementalDataInfo() 146 .getUnitConverter() 147 .getLongId(shortUnitId); 148 return pathPrefix + "compoundUnit[@type=\"" + longUnitId + "\"]/unitPrefixPattern"; 149 case power: 150 longUnitId = uc.getLongId(shortUnitId); 151 grammarInfo1 = 152 CLDRConfig.getInstance() 153 .getSupplementalDataInfo() 154 .getGrammarInfo(resolvedFile.getLocaleID()); 155 grammaticalAttributes = 156 GrammarInfo.getGrammaticalInfoAttributes( 157 grammarInfo1, pathType, pluralCategory, genderVariant, caseVariant); 158 return pathPrefix 159 + "compoundUnit[@type=\"" 160 + longUnitId 161 + "\"]/compoundUnitPattern1" 162 + grammaticalAttributes; 163 case unit: 164 longUnitId = uc.getLongId(shortUnitId); 165 grammarInfo1 = 166 CLDRConfig.getInstance() 167 .getSupplementalDataInfo() 168 .getGrammarInfo(resolvedFile.getLocaleID()); 169 grammaticalAttributes = 170 GrammarInfo.getGrammaticalInfoAttributes( 171 grammarInfo1, pathType, pluralCategory, genderVariant, caseVariant); 172 return pathPrefix 173 + "unit[@type=\"" 174 + longUnitId 175 + "\"]/unitPattern" 176 + grammaticalAttributes; 177 case displayName: 178 longUnitId = uc.getLongId(shortUnitId); 179 return pathPrefix + "unit[@type=\"" + longUnitId + "\"]/displayName"; 180 case perUnit: 181 longUnitId = uc.getLongId(shortUnitId); 182 return pathPrefix + "unit[@type=\"" + longUnitId + "\"]/perUnitPattern"; 183 case gender: 184 if (!width.equals("long")) { 185 throw new IllegalArgumentException("illegal width for gender: "); 186 } 187 longUnitId = uc.getLongId(shortUnitId); 188 return pathPrefix + "unit[@type=\"" + uc.getLongId(shortUnitId) + "\"]/gender"; 189 case coordinate: 190 return pathPrefix 191 + "coordinateUnit/coordinateUnitPattern[@type=\"" 192 + shortUnitId 193 + "\"]"; 194 case duration: 195 return "//ldml/units/durationUnit[@type=\"" 196 + shortUnitId 197 + "\"]/durationUnitPattern"; 198 } 199 throw new IllegalArgumentException("PathType: " + pathType); 200 } 201 getTrans( LocaleStringProvider resolvedFile, String width, String shortUnitId, String pluralCategory, String caseVariant, String genderVariant, Multimap<UnitPathType, String> partsUsed)202 public String getTrans( 203 LocaleStringProvider resolvedFile, 204 String width, 205 String shortUnitId, 206 String pluralCategory, 207 String caseVariant, 208 String genderVariant, 209 Multimap<UnitPathType, String> partsUsed) { 210 UnitPathType pathType = this; 211 String path = 212 pathType.getTranslationPath( 213 resolvedFile, 214 width, 215 shortUnitId, 216 pluralCategory, 217 caseVariant, 218 genderVariant); 219 String result = resolvedFile.getStringValue(path); 220 if (result == null) { 221 int debug = 0; 222 } 223 224 if (partsUsed != null) { 225 CLDRFile.Status status = new CLDRFile.Status(); 226 String foundLocale = resolvedFile.getSourceLocaleID(path, status); 227 partsUsed.put( 228 pathType, 229 (result != null ? "«" + result + "»" : "∅") 230 + (foundLocale.equals(resolvedFile.getLocaleID()) 231 ? "" 232 : "\n\t\tactualLocale: " + foundLocale) 233 + (status.pathWhereFound.equals(path) 234 ? "" 235 : "\n\t\trequestPath: " 236 + path 237 + "\n\t\tactualPath: " 238 + status.pathWhereFound)); 239 } 240 return result; 241 } 242 } 243