1 package org.unicode.cldr.util; 2 3 import com.google.common.cache.Cache; 4 import com.google.common.cache.CacheBuilder; 5 import java.util.Objects; 6 import java.util.concurrent.Callable; 7 import java.util.concurrent.ExecutionException; 8 import org.unicode.cldr.test.CoverageLevel2; 9 10 public class CoverageInfo { 11 private static final int MAXLOCALES = 50; 12 13 private static final class XPathWithLocation { 14 private final String xpath; 15 private final String location; 16 private final int hashCode; 17 XPathWithLocation(String xpath, String location)18 public XPathWithLocation(String xpath, String location) { 19 this.xpath = xpath; 20 this.location = location; 21 this.hashCode = Objects.hash(this.xpath, this.location); 22 } 23 24 @Override hashCode()25 public int hashCode() { 26 return hashCode; 27 } 28 29 @Override equals(Object other)30 public boolean equals(Object other) { 31 if (other == null) { 32 return false; 33 } 34 if (this == other) { 35 return true; 36 } 37 if (hashCode != other.hashCode()) { 38 return false; 39 } 40 if (!getClass().equals(other.getClass())) { 41 return false; 42 } 43 XPathWithLocation o = (XPathWithLocation) other; 44 if (location != null && !location.equals(o.location)) { 45 return false; 46 } 47 if (xpath != null && !xpath.equals(o.xpath)) { 48 return false; 49 } 50 return true; 51 } 52 getXPath()53 public String getXPath() { 54 return xpath; 55 } 56 getLocation()57 public String getLocation() { 58 return location; 59 } 60 } 61 62 private Cache<String, CoverageLevel2> localeToCoverageLevelInfo = 63 CacheBuilder.newBuilder().maximumSize(MAXLOCALES).build(); 64 private Cache<XPathWithLocation, Level> coverageCache = 65 CacheBuilder.newBuilder().maximumSize(MAXLOCALES).build(); 66 67 private final SupplementalDataInfo supplementalDataInfo; 68 CoverageInfo(SupplementalDataInfo coverageInfoGettable)69 public CoverageInfo(SupplementalDataInfo coverageInfoGettable) { 70 this.supplementalDataInfo = coverageInfoGettable; 71 } 72 73 /** 74 * Used to get the coverage value for a path. This is generally the most efficient way for tools 75 * to get coverage. 76 * 77 * @param xpath 78 * @param loc 79 * @return 80 */ getCoverageLevel(String xpath, String loc)81 public Level getCoverageLevel(String xpath, String loc) { 82 Level result = null; 83 final XPathWithLocation xpLoc = new XPathWithLocation(xpath, loc); 84 try { 85 result = 86 coverageCache.get( 87 xpLoc, 88 new Callable<Level>() { 89 90 @Override 91 public Level call() throws Exception { 92 final String location = xpLoc.getLocation(); 93 CoverageLevel2 cov = 94 localeToCoverageLevelInfo.get( 95 location, 96 new Callable<CoverageLevel2>() { 97 98 @Override 99 public CoverageLevel2 call() 100 throws Exception { 101 return CoverageLevel2.getInstance( 102 supplementalDataInfo, location); 103 } 104 }); 105 Level result = cov.getLevel(xpLoc.getXPath()); 106 return result; 107 } 108 }); 109 } catch (ExecutionException e) { 110 e.printStackTrace(); 111 } 112 return result; 113 } 114 115 /** 116 * Used to get the coverage value for a path. Note, it is more efficient to create a 117 * CoverageLevel2 for a language, and keep it around. 118 * 119 * @param xpath 120 * @param loc 121 * @return 122 */ getCoverageValue(String xpath, String loc)123 public int getCoverageValue(String xpath, String loc) { 124 return getCoverageLevel(xpath, loc).getLevel(); 125 } 126 } 127