1 package org.unicode.cldr.tool; 2 3 import com.google.common.collect.ImmutableList; 4 import com.google.common.collect.Lists; 5 import com.ibm.icu.impl.locale.XCldrStub.ImmutableMap; 6 import com.ibm.icu.util.VersionInfo; 7 import java.io.File; 8 import java.util.EnumSet; 9 import java.util.LinkedHashMap; 10 import java.util.LinkedHashSet; 11 import java.util.List; 12 import java.util.Map; 13 import java.util.Set; 14 import java.util.TreeSet; 15 import org.unicode.cldr.util.CLDRFile; 16 import org.unicode.cldr.util.CLDRPaths; 17 18 /** 19 * Enums that should exactly match what is in cldr-archive; eg, v2_0_1 means that there is a folder 20 * "cldr-2.0.1" 21 * 22 * @author markdavis 23 * @see CheckoutArchive for a tool to automatically populate the cldr-archive 24 */ 25 // TODO merge with all other copies of the CLDR version and replace with supplemental metadata, 26 // CLDR-9149 27 public enum CldrVersion { 28 unknown, 29 v1_1, 30 v1_1_1, 31 v1_2, 32 v1_3, 33 v1_4, 34 v1_4_1, 35 v1_5_0_1, 36 v1_5_1, 37 v1_6_1, 38 v1_7_2, 39 v1_8_1, 40 v1_9_1, 41 v2_0_1, 42 v21_0, 43 v22_1, 44 v23_1, 45 v24_0, 46 v25_0, 47 v26_0, 48 v27_0, 49 v28_0, 50 v29_0, 51 v30_0, 52 v31_0, 53 v32_0, 54 v33_0, 55 v33_1, 56 v34_0, 57 v35_0, 58 v35_1, 59 v36_0, 60 v36_1, 61 v37_0, 62 v38_0, 63 v38_1, 64 v39_0, 65 v40_0, 66 v41_0, 67 v42_0, 68 v43_0, 69 v44_0, 70 v44_1, 71 /** 72 * @see CLDRFile#GEN_VERSION 73 */ 74 baseline; 75 76 private final String baseDirectory; 77 private final String dotName; 78 private final VersionInfo versionInfo; 79 80 /** 81 * Get the closest available version (successively dropping lower-significance values) We do 82 * this because the archive might contain a dot-dot version but have a folder called by the 83 * round(er) version number. 84 */ from(VersionInfo versionInfo)85 public static CldrVersion from(VersionInfo versionInfo) { 86 if (versionInfo == null) { 87 return unknown; 88 } 89 while (true) { 90 CldrVersion result = versionInfoToCldrVersion.get(versionInfo); 91 if (result != null) { 92 return result; 93 } 94 versionInfo = 95 versionInfo.getMilli() != 0 96 ? VersionInfo.getInstance( 97 versionInfo.getMajor(), versionInfo.getMinor()) 98 : versionInfo.getMinor() != 0 99 ? VersionInfo.getInstance(versionInfo.getMajor()) 100 : unknown.versionInfo; // will always terminate with unknown. 101 } 102 } 103 from(String versionString)104 public static CldrVersion from(String versionString) { 105 // treat 'current' as baseline 106 if (versionString.equals(CLDRFile.GEN_VERSION) 107 || versionString.equals(CLDRFile.GEN_VERSION + ".0")) { 108 return CldrVersion.baseline; 109 } 110 return valueOf( 111 versionString.charAt(0) < 'A' 112 ? "v" + versionString.replace('.', '_') 113 : versionString); 114 } 115 getVersionInfo()116 public VersionInfo getVersionInfo() { 117 return versionInfo; 118 } 119 120 @Override toString()121 public String toString() { 122 return dotName; 123 } 124 getBaseDirectory()125 public String getBaseDirectory() { 126 return baseDirectory; 127 } 128 isOlderThan(CldrVersion other)129 public boolean isOlderThan(CldrVersion other) { 130 return compareTo(other) < 0; 131 } 132 CldrVersion()133 private CldrVersion() { 134 String oldName = name(); 135 if (oldName.charAt(0) == 'v') { 136 dotName = oldName.substring(1).replace('_', '.'); 137 versionInfo = VersionInfo.getInstance(dotName); 138 baseDirectory = CLDRPaths.ARCHIVE_DIRECTORY + "cldr-" + toString() + "/"; 139 } else { 140 dotName = oldName; 141 baseDirectory = CLDRPaths.BASE_DIRECTORY; 142 final VersionInfo cldrVersion = VersionInfo.getInstance(CLDRFile.GEN_VERSION); 143 versionInfo = "baseline".equals(oldName) ? cldrVersion : VersionInfo.getInstance(0); 144 } 145 } 146 147 public static final CldrVersion LAST_RELEASE_VERSION = values()[values().length - 2]; 148 public static final List<CldrVersion> CLDR_VERSIONS_ASCENDING; 149 public static final List<CldrVersion> CLDR_VERSIONS_DESCENDING; 150 private static final Map<VersionInfo, CldrVersion> versionInfoToCldrVersion; 151 152 static { 153 EnumSet<CldrVersion> temp = EnumSet.allOf(CldrVersion.class); 154 CLDR_VERSIONS_ASCENDING = ImmutableList.copyOf(temp); 155 CLDR_VERSIONS_DESCENDING = ImmutableList.copyOf(Lists.reverse(CLDR_VERSIONS_ASCENDING)); 156 Map<VersionInfo, CldrVersion> temp2 = new LinkedHashMap<>(); 157 for (CldrVersion item : CLDR_VERSIONS_ASCENDING) { 158 VersionInfo version2 = item.versionInfo; temp2.put(version2, item)159 temp2.put(version2, item); 160 if (version2.getMilli() != 0) { 161 version2 = VersionInfo.getInstance(version2.getMajor(), version2.getMinor()); 162 if (!temp2.containsKey(version2)) { temp2.put(version2, item)163 temp2.put(version2, item); 164 } 165 } 166 if (version2.getMinor() != 0) { 167 version2 = VersionInfo.getInstance(version2.getMajor()); 168 if (!temp2.containsKey(version2)) { temp2.put(version2, item)169 temp2.put(version2, item); 170 } 171 } 172 } 173 versionInfoToCldrVersion = ImmutableMap.copyOf(temp2); 174 } 175 getPathsForFactory()176 public List<File> getPathsForFactory() { 177 return ImmutableList.copyOf( 178 versionInfo != null && versionInfo.getMajor() < 27 179 ? new File[] {new File(getBaseDirectory() + "common/main/")} 180 : new File[] { 181 new File(getBaseDirectory() + "common/main/"), 182 new File(getBaseDirectory() + "common/annotations/") 183 }); 184 } 185 186 /** For testing */ checkVersions()187 public static void checkVersions() { 188 // System.out.println(Arrays.asList(CldrVersion.values())); 189 190 Set<VersionInfo> allFileVersions = new TreeSet<>(); 191 Set<VersionInfo> allTc = new TreeSet<>(); 192 Set<VersionInfo> missingEnums = new TreeSet<>(); 193 Set<CldrVersion> extraEnums = EnumSet.copyOf(CLDR_VERSIONS_ASCENDING); 194 extraEnums.remove(CldrVersion.baseline); 195 extraEnums.remove(CldrVersion.unknown); 196 197 for (String subdir : new File(CLDRPaths.ARCHIVE_DIRECTORY).list()) { 198 if (subdir.startsWith("cldr-")) { 199 String versionString = subdir.substring("cldr-".length()); 200 VersionInfo versionInfo = VersionInfo.getInstance(versionString); 201 allFileVersions.add(versionInfo); 202 try { 203 CldrVersion found = CldrVersion.from(versionString); 204 extraEnums.remove(found); 205 } catch (Exception e) { 206 missingEnums.add(versionInfo); 207 } 208 } 209 } 210 Set<String> errorMessages = new LinkedHashSet<>(); 211 212 // get versions from ToolConstants 213 for (String tc : ToolConstants.CLDR_VERSIONS) { 214 VersionInfo versionInfo = VersionInfo.getInstance(tc); 215 allTc.add(versionInfo); 216 } 217 // same? 218 if (!allTc.equals(allFileVersions)) { 219 LinkedHashSet<VersionInfo> tcMFile = new LinkedHashSet<>(allTc); 220 tcMFile.removeAll(allFileVersions); 221 if (!tcMFile.isEmpty()) { 222 errorMessages.add( 223 "Extra ToolConstants.CLDR_VERSIONS compared to " 224 + CLDRPaths.ARCHIVE_DIRECTORY 225 + ": " 226 + tcMFile); 227 } 228 LinkedHashSet<VersionInfo> fileMTc = new LinkedHashSet<>(allFileVersions); 229 fileMTc.removeAll(allTc); 230 if (!fileMTc.isEmpty()) { 231 errorMessages.add( 232 "Extra folders in " 233 + CLDRPaths.ARCHIVE_DIRECTORY 234 + " compared to ToolConstants.CLDR_VERSIONS: " 235 + fileMTc); 236 } 237 } 238 239 // Are there extra enums complete? 240 if (!extraEnums.isEmpty()) { 241 errorMessages.add( 242 "Extra enums compared to " + CLDRPaths.ARCHIVE_DIRECTORY + ": " + extraEnums); 243 } 244 // Is the archive complete? 245 if (!missingEnums.isEmpty()) { 246 StringBuilder temp = new StringBuilder(); 247 allFileVersions.forEach( 248 v -> temp.append(", v" + v.getVersionString(2, 4).replace('.', '_'))); 249 errorMessages.add( 250 "Missing enums " + missingEnums + ", should be:\ntrunk" + temp + ", unknown"); 251 } 252 if (!errorMessages.isEmpty()) { 253 throw new IllegalArgumentException(errorMessages.toString()); 254 } 255 } 256 } 257