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 v45_0, 72 /** 73 * @see CLDRFile#GEN_VERSION 74 */ 75 baseline; 76 77 private final String baseDirectory; 78 private final String dotName; 79 private final VersionInfo versionInfo; 80 81 /** 82 * Get the closest available version (successively dropping lower-significance values) We do 83 * this because the archive might contain a dot-dot version but have a folder called by the 84 * round(er) version number. 85 */ from(VersionInfo versionInfo)86 public static CldrVersion from(VersionInfo versionInfo) { 87 if (versionInfo == null) { 88 return unknown; 89 } 90 while (true) { 91 CldrVersion result = versionInfoToCldrVersion.get(versionInfo); 92 if (result != null) { 93 return result; 94 } 95 versionInfo = 96 versionInfo.getMilli() != 0 97 ? VersionInfo.getInstance( 98 versionInfo.getMajor(), versionInfo.getMinor()) 99 : versionInfo.getMinor() != 0 100 ? VersionInfo.getInstance(versionInfo.getMajor()) 101 : unknown.versionInfo; // will always terminate with unknown. 102 } 103 } 104 from(String versionString)105 public static CldrVersion from(String versionString) { 106 // treat 'current' as baseline 107 if (versionString.equals(CLDRFile.GEN_VERSION) 108 || versionString.equals(CLDRFile.GEN_VERSION + ".0")) { 109 return CldrVersion.baseline; 110 } 111 return valueOf( 112 versionString.charAt(0) < 'A' 113 ? "v" + versionString.replace('.', '_') 114 : versionString); 115 } 116 getVersionInfo()117 public VersionInfo getVersionInfo() { 118 return versionInfo; 119 } 120 121 @Override toString()122 public String toString() { 123 return dotName; 124 } 125 getBaseDirectory()126 public String getBaseDirectory() { 127 return baseDirectory; 128 } 129 isOlderThan(CldrVersion other)130 public boolean isOlderThan(CldrVersion other) { 131 return compareTo(other) < 0; 132 } 133 CldrVersion()134 private CldrVersion() { 135 String oldName = name(); 136 if (oldName.charAt(0) == 'v') { 137 dotName = oldName.substring(1).replace('_', '.'); 138 versionInfo = VersionInfo.getInstance(dotName); 139 baseDirectory = CLDRPaths.ARCHIVE_DIRECTORY + "cldr-" + toString() + "/"; 140 } else { 141 dotName = oldName; 142 baseDirectory = CLDRPaths.BASE_DIRECTORY; 143 final VersionInfo cldrVersion = VersionInfo.getInstance(CLDRFile.GEN_VERSION); 144 versionInfo = "baseline".equals(oldName) ? cldrVersion : VersionInfo.getInstance(0); 145 } 146 } 147 148 public static final CldrVersion LAST_RELEASE_VERSION = values()[values().length - 2]; 149 public static final List<CldrVersion> CLDR_VERSIONS_ASCENDING; 150 public static final List<CldrVersion> CLDR_VERSIONS_DESCENDING; 151 private static final Map<VersionInfo, CldrVersion> versionInfoToCldrVersion; 152 153 static { 154 EnumSet<CldrVersion> temp = EnumSet.allOf(CldrVersion.class); 155 CLDR_VERSIONS_ASCENDING = ImmutableList.copyOf(temp); 156 CLDR_VERSIONS_DESCENDING = ImmutableList.copyOf(Lists.reverse(CLDR_VERSIONS_ASCENDING)); 157 Map<VersionInfo, CldrVersion> temp2 = new LinkedHashMap<>(); 158 for (CldrVersion item : CLDR_VERSIONS_ASCENDING) { 159 VersionInfo version2 = item.versionInfo; temp2.put(version2, item)160 temp2.put(version2, item); 161 if (version2.getMilli() != 0) { 162 version2 = VersionInfo.getInstance(version2.getMajor(), version2.getMinor()); 163 if (!temp2.containsKey(version2)) { temp2.put(version2, item)164 temp2.put(version2, item); 165 } 166 } 167 if (version2.getMinor() != 0) { 168 version2 = VersionInfo.getInstance(version2.getMajor()); 169 if (!temp2.containsKey(version2)) { temp2.put(version2, item)170 temp2.put(version2, item); 171 } 172 } 173 } 174 versionInfoToCldrVersion = ImmutableMap.copyOf(temp2); 175 } 176 getPathsForFactory()177 public List<File> getPathsForFactory() { 178 return ImmutableList.copyOf( 179 versionInfo != null && versionInfo.getMajor() < 27 180 ? new File[] {new File(getBaseDirectory() + "common/main/")} 181 : new File[] { 182 new File(getBaseDirectory() + "common/main/"), 183 new File(getBaseDirectory() + "common/annotations/") 184 }); 185 } 186 187 /** For testing */ checkVersions()188 public static void checkVersions() { 189 // System.out.println(Arrays.asList(CldrVersion.values())); 190 191 Set<VersionInfo> allFileVersions = new TreeSet<>(); 192 Set<VersionInfo> allTc = new TreeSet<>(); 193 Set<VersionInfo> missingEnums = new TreeSet<>(); 194 Set<CldrVersion> extraEnums = EnumSet.copyOf(CLDR_VERSIONS_ASCENDING); 195 extraEnums.remove(CldrVersion.baseline); 196 extraEnums.remove(CldrVersion.unknown); 197 198 for (String subdir : new File(CLDRPaths.ARCHIVE_DIRECTORY).list()) { 199 if (subdir.startsWith("cldr-")) { 200 String versionString = subdir.substring("cldr-".length()); 201 VersionInfo versionInfo = VersionInfo.getInstance(versionString); 202 allFileVersions.add(versionInfo); 203 try { 204 CldrVersion found = CldrVersion.from(versionString); 205 extraEnums.remove(found); 206 } catch (Exception e) { 207 missingEnums.add(versionInfo); 208 } 209 } 210 } 211 Set<String> errorMessages = new LinkedHashSet<>(); 212 213 // get versions from ToolConstants 214 for (String tc : ToolConstants.CLDR_VERSIONS) { 215 VersionInfo versionInfo = VersionInfo.getInstance(tc); 216 allTc.add(versionInfo); 217 } 218 // same? 219 if (!allTc.equals(allFileVersions)) { 220 LinkedHashSet<VersionInfo> tcMFile = new LinkedHashSet<>(allTc); 221 tcMFile.removeAll(allFileVersions); 222 if (!tcMFile.isEmpty()) { 223 errorMessages.add( 224 "Extra ToolConstants.CLDR_VERSIONS compared to " 225 + CLDRPaths.ARCHIVE_DIRECTORY 226 + ": " 227 + tcMFile); 228 } 229 LinkedHashSet<VersionInfo> fileMTc = new LinkedHashSet<>(allFileVersions); 230 fileMTc.removeAll(allTc); 231 if (!fileMTc.isEmpty()) { 232 errorMessages.add( 233 "Extra folders in " 234 + CLDRPaths.ARCHIVE_DIRECTORY 235 + " compared to ToolConstants.CLDR_VERSIONS: " 236 + fileMTc); 237 } 238 } 239 240 // Are there extra enums complete? 241 if (!extraEnums.isEmpty()) { 242 errorMessages.add( 243 "Extra enums compared to " + CLDRPaths.ARCHIVE_DIRECTORY + ": " + extraEnums); 244 } 245 // Is the archive complete? 246 if (!missingEnums.isEmpty()) { 247 StringBuilder temp = new StringBuilder(); 248 allFileVersions.forEach( 249 v -> temp.append(", v" + v.getVersionString(2, 4).replace('.', '_'))); 250 errorMessages.add( 251 "Missing enums " + missingEnums + ", should be:\ntrunk" + temp + ", unknown"); 252 } 253 if (!errorMessages.isEmpty()) { 254 throw new IllegalArgumentException(errorMessages.toString()); 255 } 256 } 257 } 258