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