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