xref: /aosp_15_r20/external/cldr/tools/cldr-code/src/main/java/org/unicode/cldr/tool/Chart.java (revision 912701f9769bb47905792267661f0baf2b85bed5)
1 package org.unicode.cldr.tool;
2 
3 import com.ibm.icu.text.ListFormatter;
4 import com.ibm.icu.util.ICUUncheckedIOException;
5 import com.ibm.icu.util.ULocale;
6 import java.io.IOException;
7 import java.io.OutputStream;
8 import java.io.OutputStreamWriter;
9 import java.io.Writer;
10 import java.util.Arrays;
11 import java.util.stream.Collectors;
12 import org.unicode.cldr.tool.FormattedFileWriter.Anchors;
13 import org.unicode.cldr.util.CLDRConfig;
14 import org.unicode.cldr.util.CLDRFile;
15 import org.unicode.cldr.util.CLDRURLS;
16 import org.unicode.cldr.util.Factory;
17 import org.unicode.cldr.util.PathHeader;
18 import org.unicode.cldr.util.SupplementalDataInfo;
19 import org.unicode.cldr.util.VoterReportStatus.ReportId;
20 
21 /**
22  * To add a new chart, subclass this, and add the subclass to {@link
23  * ShowLanguages.printLanguageData()}. There isn't much documentation, so best to look at a simple
24  * subclass to see how it works.
25  *
26  * @author markdavis
27  */
28 public abstract class Chart {
29     public static final CLDRConfig CONFIG = CLDRConfig.getInstance();
30     public static final SupplementalDataInfo SDI = CONFIG.getSupplementalDataInfo();
31     public static final CLDRFile ENGLISH = CONFIG.getEnglish();
32     public static final String LS = System.lineSeparator();
33 
34     public static final String PREV_CHART_VERSION_DIRECTORY =
35             ToolConstants.getBaseDirectory(ToolConstants.PREV_CHART_VERSION);
36     public static final String CHART_VERSION_DIRECTORY =
37             ToolConstants.getBaseDirectory(ToolConstants.CHART_VERSION);
38 
39     public static final String GITHUB_ROOT = CLDRURLS.CLDR_REPO_ROOT + "/blob/main/";
40     public static final String LDML_SPEC = "https://unicode.org/reports/tr35/";
41 
dataScrapeMessage(String specPart, String testFile, String... dataFiles)42     public static String dataScrapeMessage(String specPart, String testFile, String... dataFiles) {
43         final String dataFileList =
44                 dataFiles.length == 0
45                         ? null
46                         : ListFormatter.getInstance(ULocale.ENGLISH)
47                                 .format(
48                                         Arrays.asList(dataFiles).stream()
49                                                 .map(dataFile -> Chart.dataFileLink(dataFile))
50                                                 .collect(Collectors.toSet()));
51 
52         return "<p>"
53                 + "<b>Warning:</b> Do not scrape this chart for production data.\n"
54                 + "Instead, for the meaning of the fields and data consult the "
55                 + Chart.ldmlSpecLink(specPart)
56                 + (dataFileList == null
57                         ? ""
58                         : ", and for machine-readable source data, access " + dataFileList)
59                 + (testFile == null ? "" : ", and for test data, access " + dataFileLink(testFile))
60                 + ".</p>\n";
61     }
62 
dataFileLink(String dataFile)63     private static String dataFileLink(String dataFile) {
64         return "<a href='"
65                 + GITHUB_ROOT
66                 + dataFile
67                 + "' target='"
68                 + dataFile
69                 + "'>"
70                 + dataFile
71                 + "</a>";
72     }
73 
ldmlSpecLink(String specPart)74     public static String ldmlSpecLink(String specPart) {
75         return "<a href='"
76                 + LDML_SPEC
77                 + (specPart == null ? "" : specPart)
78                 + "' target='units.xml'>LDML specification</a>";
79     }
80 
81     /**
82      * null means a string will be constructed from the title. Otherwise a real file name (no html
83      * extension).
84      *
85      * @return
86      */
getFileName()87     public String getFileName() {
88         return null;
89     }
90 
91     /**
92      * Show Date?
93      *
94      * @return
95      */
getExplanation()96     public String getExplanation() {
97         return null;
98     }
99 
100     /**
101      * Short explanation that will go just after the title/dates.
102      *
103      * @return
104      */
getShowDate()105     public boolean getShowDate() {
106         return true;
107     }
108 
109     /**
110      * Directory for the file to go into.
111      *
112      * @return
113      */
getDirectory()114     public abstract String getDirectory();
115 
116     /**
117      * Short title for page. Will appear at the top, and in the window title, and in the index.
118      *
119      * @return
120      */
getTitle()121     public abstract String getTitle();
122 
123     /**
124      * Work
125      *
126      * @param pw
127      * @throws IOException
128      */
writeContents(FormattedFileWriter pw)129     public void writeContents(FormattedFileWriter pw) throws IOException {
130         writeContents(pw.getStringWriter());
131     }
132 
133     /**
134      * Helper function to use the default factory. Not for use within SurveyTool.
135      *
136      * @param pw
137      * @throws IOException
138      */
writeContents(Writer pw)139     public void writeContents(Writer pw) throws IOException {
140         writeContents(pw, CLDRConfig.getInstance().getCldrFactory());
141     }
142 
writeContents(OutputStream output, Factory factory)143     public void writeContents(OutputStream output, Factory factory) throws IOException {
144         try (final Writer w = new OutputStreamWriter(output); ) {
145             writeContents(w, factory);
146         }
147     }
148 
149     /**
150      * Do the work of generating the chart.
151      *
152      * @param pw
153      * @param factory
154      * @throws IOException
155      */
writeContents(Writer pw, Factory factory)156     public void writeContents(Writer pw, Factory factory) throws IOException {
157         // TODO: this should be an abstract function.
158         throw new IllegalArgumentException("Not implemented yet");
159     }
160 
161     private static final class AnalyticsHelper {
162         private static final AnalyticsHelper INSTANCE = new AnalyticsHelper();
163 
164         public final String str;
165 
AnalyticsHelper()166         AnalyticsHelper() {
167             str =
168                     ToolUtilities.getUTF8Data("analytics.html")
169                             .lines()
170                             .collect(Collectors.joining("\n"));
171         }
172     }
173 
174     public enum AnalyticsID {
175         CLDR("G-BPN1D3SEJM"),
176         ICU("G-06PL1DM20S"),
177         ICU_GUIDE("UA-7670256-1"),
178         UNICODE("G-GC4HXC4GVQ"),
179         UNICODE_UTILITY("G-0M7Q5QLZPV");
180         public final String id;
181 
AnalyticsID(String id)182         private AnalyticsID(String id) {
183             this.id = id;
184         }
185 
getScript()186         public String getScript() {
187             return AnalyticsHelper.INSTANCE.str.replaceAll("TAG_ID", id);
188         }
189     }
190 
writeChart(Anchors anchors)191     public final void writeChart(Anchors anchors) {
192         try (FormattedFileWriter x =
193                 new FormattedFileWriter(getFileName(), getTitle(), getExplanation(), anchors); ) {
194             x.setDirectory(getDirectory());
195             x.setShowDate(getShowDate());
196             writeContents(x);
197         } catch (IOException e) {
198             throw new ICUUncheckedIOException(e);
199         }
200     }
201 
getTsvDir(String targetDir, String topicName)202     public static String getTsvDir(String targetDir, String topicName) {
203         String target = targetDir.replaceAll(topicName, "tsv");
204         if (target.equals(targetDir)) {
205             throw new IllegalArgumentException("Can't make TSV directory from " + targetDir);
206         }
207         return target;
208     }
209 
getFixLinkFromPath(CLDRFile cldrFile, String path)210     public String getFixLinkFromPath(CLDRFile cldrFile, String path) {
211         String result = PathHeader.getLinkedView(CLDRConfig.getInstance().urls(), cldrFile, path);
212         return result == null ? "" : result;
213     }
214 
215     /**
216      * Attempt to allocate the Chart that goes along with this report Also see {@link
217      * org.unicode.cldr.util.VoterReportStatus.ReportId} and keep up to date
218      */
forReport(final ReportId report, final String locale)219     public static Chart forReport(final ReportId report, final String locale) {
220         switch (report) {
221             case personnames:
222                 return new ChartPersonName(locale);
223             default:
224                 return null;
225         }
226     }
227 }
228