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_1, v1_2, v1_3, v1_4_1, v1_5_1, v1_6_1, v1_7_2, v1_8_1, v1_9_1, v2_0_1, 29 v21_0, v22_1, v23_1, v24_0, v25_0, v26_0, v27_0, v28_0, v29_0, v30_0, v31_0, v32_0, v33_0, v33_1, v34_0, 30 v35_0, v35_1, v36_0, v36_1, v37_0, 31 trunk; 32 33 private final String baseDirectory; 34 private final String dotName; 35 private final VersionInfo versionInfo; 36 37 /** 38 * Get the closest available version (successively dropping lower-significance values) 39 * We do this because the archive might contain a dot-dot version 40 * but have a folder called by the round(er) version number. 41 */ from(VersionInfo versionInfo)42 public static CldrVersion from(VersionInfo versionInfo) { 43 if (versionInfo == null) { 44 return unknown; 45 } 46 while (true) { 47 CldrVersion result = versionInfoToCldrVersion.get(versionInfo); 48 if (result != null) { 49 return result; 50 } 51 versionInfo = versionInfo.getMilli() != 0 ? VersionInfo.getInstance(versionInfo.getMajor(), versionInfo.getMinor()) 52 : versionInfo.getMinor() != 0 ? VersionInfo.getInstance(versionInfo.getMajor()) 53 : unknown.versionInfo; // will always terminate with unknown. 54 } 55 } 56 from(String versionString)57 public static CldrVersion from(String versionString) { 58 return valueOf(versionString.charAt(0) < 'A' ? "v" + versionString.replace('.', '_') : versionString); 59 } 60 getVersionInfo()61 public VersionInfo getVersionInfo() { 62 return versionInfo; 63 } 64 @Override toString()65 public String toString() { 66 return dotName; 67 } getBaseDirectory()68 public String getBaseDirectory() { 69 return baseDirectory; 70 } 71 isOlderThan(CldrVersion other)72 public boolean isOlderThan(CldrVersion other) { 73 return compareTo(other) < 0; 74 } 75 CldrVersion()76 private CldrVersion() { 77 String oldName = name(); 78 if (oldName.charAt(0) == 'v') { 79 dotName = oldName.substring(1).replace('_', '.'); 80 versionInfo = VersionInfo.getInstance(dotName); 81 baseDirectory = CLDRPaths.ARCHIVE_DIRECTORY + "cldr-" + toString() + "/"; 82 } else { 83 dotName = oldName; 84 baseDirectory = CLDRPaths.BASE_DIRECTORY; 85 SupplementalDataInfo sdi = SupplementalDataInfo.getInstance(); 86 versionInfo = "trunk".equals(oldName) ? sdi.getCldrVersion() : VersionInfo.getInstance(0); 87 } 88 } 89 90 public static final CldrVersion LAST_RELEASE_VERSION = values()[values().length-2]; 91 public static final List<CldrVersion> CLDR_VERSIONS_ASCENDING; 92 public static final List<CldrVersion> CLDR_VERSIONS_DESCENDING; 93 private static final Map<VersionInfo, CldrVersion> versionInfoToCldrVersion; 94 static { 95 EnumSet<CldrVersion> temp = EnumSet.allOf(CldrVersion.class); 96 CLDR_VERSIONS_ASCENDING = ImmutableList.copyOf(temp); 97 CLDR_VERSIONS_DESCENDING = ImmutableList.copyOf(Lists.reverse(CLDR_VERSIONS_ASCENDING)); 98 Map<VersionInfo, CldrVersion> temp2 = new LinkedHashMap<>(); 99 for (CldrVersion item : CLDR_VERSIONS_ASCENDING) { 100 VersionInfo version2 = item.versionInfo; temp2.put(version2, item)101 temp2.put(version2, item); 102 if (version2.getMilli() != 0) { 103 version2 = VersionInfo.getInstance(version2.getMajor(), version2.getMinor()); 104 if (!temp2.containsKey(version2)) { temp2.put(version2, item)105 temp2.put(version2, item); 106 } 107 } 108 if (version2.getMinor() != 0) { 109 version2 = VersionInfo.getInstance(version2.getMajor()); 110 if (!temp2.containsKey(version2)) { temp2.put(version2, item)111 temp2.put(version2, item); 112 } 113 } 114 } 115 versionInfoToCldrVersion = ImmutableMap.copyOf(temp2); 116 } 117 getPathsForFactory()118 public List<File> getPathsForFactory() { 119 return ImmutableList.copyOf(versionInfo != null && versionInfo.getMajor() < 27 120 ? new File[] { new File(getBaseDirectory() + "common/main/") } 121 : new File[] { 122 new File(getBaseDirectory() + "common/main/"), 123 new File(getBaseDirectory() + "common/annotations/") }); 124 } 125 126 /** 127 * For testing 128 */ checkVersions()129 public static void checkVersions() { 130 // System.out.println(Arrays.asList(CldrVersion.values())); 131 132 Set<VersionInfo> allFileVersions = new TreeSet<>(); 133 Set<VersionInfo> allTc = new TreeSet<>(); 134 Set<VersionInfo> missingEnums = new TreeSet<>(); 135 Set<CldrVersion> extraEnums = EnumSet.copyOf(CLDR_VERSIONS_ASCENDING); 136 extraEnums.remove(CldrVersion.trunk); 137 extraEnums.remove(CldrVersion.unknown); 138 139 for (String subdir : new File(CLDRPaths.ARCHIVE_DIRECTORY).list()) { 140 if (subdir.startsWith("cldr-")) { 141 String versionString = subdir.substring("cldr-".length()); 142 VersionInfo versionInfo = VersionInfo.getInstance(versionString); 143 allFileVersions.add(versionInfo); 144 try { 145 CldrVersion found = CldrVersion.from(versionString); 146 extraEnums.remove(found); 147 } catch (Exception e) { 148 missingEnums.add(versionInfo); 149 } 150 } 151 } 152 Set<String> errorMessages = new LinkedHashSet<>(); 153 154 // get versions from ToolConstants 155 for (String tc : ToolConstants.CLDR_VERSIONS) { 156 VersionInfo versionInfo = VersionInfo.getInstance(tc); 157 allTc.add(versionInfo); 158 } 159 // same? 160 if (!allTc.equals(allFileVersions)) { 161 LinkedHashSet<VersionInfo> tcMFile = new LinkedHashSet<>(allTc); 162 tcMFile.removeAll(allFileVersions); 163 if (!tcMFile.isEmpty()) { 164 errorMessages.add("Extra ToolConstants.CLDR_VERSIONS compared to " + CLDRPaths.ARCHIVE_DIRECTORY + ": " + tcMFile); 165 } 166 LinkedHashSet<VersionInfo> fileMTc = new LinkedHashSet<>(allFileVersions); 167 fileMTc.removeAll(allTc); 168 if (!fileMTc.isEmpty()) { 169 errorMessages.add("Extra folders in " + CLDRPaths.ARCHIVE_DIRECTORY + " compared to ToolConstants.CLDR_VERSIONS: " + fileMTc); 170 } 171 } 172 173 // Are there extra enums complete? 174 if (!extraEnums.isEmpty()) { 175 errorMessages.add("Extra enums compared to " + CLDRPaths.ARCHIVE_DIRECTORY + ": " + extraEnums); 176 } 177 // Is the archive complete? 178 if (!missingEnums.isEmpty()) { 179 StringBuilder temp = new StringBuilder(); 180 allFileVersions.forEach(v -> temp.append(", v" + v.getVersionString(2, 4).replace('.', '_'))); 181 errorMessages.add("Missing enums " + missingEnums + ", should be:\ntrunk" + temp + ", unknown"); 182 } 183 if (!errorMessages.isEmpty()) { 184 throw new IllegalArgumentException(errorMessages.toString()); 185 } 186 } 187 }