• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 package org.unicode.cldr.util;
2 
3 import java.util.Date;
4 import java.util.EnumSet;
5 import java.util.HashMap;
6 import java.util.HashSet;
7 import java.util.Map;
8 import java.util.Set;
9 import org.unicode.cldr.test.CheckCLDR;
10 import org.unicode.cldr.test.SubmissionLocales;
11 
12 /**
13  * This interface is for objects which can expose information on which reports have been completed.
14  *
15  * @param T the type for each voter. Must be an Integer.
16  */
17 public abstract class VoterReportStatus<T> {
18     /**
19      * Enumeration for the reports. In order shown in SurveyTool. Note: when adding an entry here,
20      * also update cldrText.js to add the display name, for example, 'special_r_personnames':
21      * 'Person Names' Also see {@link org.unicode.cldr.tool.Chart#forReport(ReportId, String)}
22      */
23     public enum ReportId {
24         datetime, // non-Chart
25         zones, // non-Chart
26         compact, // non-Chart, aka 'numbers'
27         personnames; // Chart
28 
29         /**
30          * True if this report is available in this vetting period
31          *
32          * @return
33          */
isAvailable()34         public boolean isAvailable() {
35             return (!CheckCLDR.LIMITED_SUBMISSION)
36                     || (SubmissionLocales.getReportsAvailableInLimited().contains(this));
37         }
38 
getReportsAvailable()39         public static Set<ReportId> getReportsAvailable() {
40             if (!CheckCLDR.LIMITED_SUBMISSION) {
41                 return EnumSet.allOf(ReportId.class);
42             } else {
43                 return SubmissionLocales.getReportsAvailableInLimited();
44             }
45         }
46     };
47 
48     public enum ReportAcceptability {
49         notAcceptable,
50         acceptable;
51 
isAcceptable()52         boolean isAcceptable() {
53             return this == acceptable;
54         }
55 
fromPair(boolean isComplete, boolean isAcceptable)56         static ReportAcceptability fromPair(boolean isComplete, boolean isAcceptable) {
57             if (isAcceptable) {
58                 return acceptable;
59             } else if (isComplete) {
60                 return notAcceptable;
61             } else {
62                 return null;
63             }
64         }
65     };
66 
getReportStatus(T user, CLDRLocale locale)67     public abstract ReportStatus getReportStatus(T user, CLDRLocale locale);
68 
69     public static class ReportStatus {
70         public EnumSet<ReportId> completed = EnumSet.noneOf(ReportId.class);
71         public EnumSet<ReportId> acceptable = EnumSet.noneOf(ReportId.class);
72         public Date date = null;
73 
mark(ReportId r, boolean asComplete, boolean asAcceptable)74         public ReportStatus mark(ReportId r, boolean asComplete, boolean asAcceptable) {
75             return this.mark(r, asComplete, asAcceptable, null);
76         }
77 
mark(ReportId r, boolean asComplete, boolean asAcceptable, Date date)78         public ReportStatus mark(ReportId r, boolean asComplete, boolean asAcceptable, Date date) {
79             if (!asComplete && asAcceptable) {
80                 throw new IllegalArgumentException("Cannot be !complete&&acceptable");
81             }
82             if (asComplete) {
83                 completed.add(r);
84             } else {
85                 completed.remove(r);
86             }
87             if (asAcceptable) {
88                 acceptable.add(r);
89             } else {
90                 acceptable.remove(r);
91             }
92             this.date = date;
93             return this;
94         }
95 
getDate()96         public Date getDate() {
97             return date;
98         }
99 
100         /**
101          * Return the acceptability enum for this report type
102          *
103          * @param r report type
104          * @return the acceptability enum, or null if there was no entry
105          */
getAcceptability(ReportId r)106         public ReportAcceptability getAcceptability(ReportId r) {
107             return ReportAcceptability.fromPair(completed.contains(r), acceptable.contains(r));
108         }
109     }
110 
111     /**
112      * Update a Resolver for a particular Report. The resolver will be cleared. Note that T must be
113      * an Integer for this to succeed.
114      *
115      * @param l locale
116      * @param r which report
117      * @param userList set of users
118      * @param res which
119      * @return vote statistics for each acceptability level
120      */
updateResolver( CLDRLocale l, ReportId r, Set<T> userList, VoteResolver<ReportAcceptability> res, Map<T, ReportAcceptability> votes)121     public Map<ReportAcceptability, Set<Integer>> updateResolver(
122             CLDRLocale l,
123             ReportId r,
124             Set<T> userList,
125             VoteResolver<ReportAcceptability> res,
126             Map<T, ReportAcceptability> votes) {
127         Map<ReportAcceptability, Set<Integer>> statistics = new HashMap<>();
128         res.clear();
129         votes.clear();
130         res.setBaileyValue(null);
131         // Get the report status for each user
132         userList.forEach(
133                 id -> {
134                     // get the report status for this user
135                     final ReportStatus rs = getReportStatus(id, l);
136                     // convert the ReportStatus for the specific id, into an enum (or null)
137                     final ReportAcceptability acc = rs.getAcceptability(r);
138                     if (acc != null) {
139                         // if not an abstention, add
140                         res.add(
141                                 acc,
142                                 (Integer) id,
143                                 null,
144                                 rs.getDate()); // TODO: Cast because T must be an Integer.
145                         // Refactor class to not be templatized
146                         statistics.computeIfAbsent(acc, k -> new HashSet<>()).add((Integer) id);
147                         votes.put(id, acc);
148                     }
149                 });
150         return statistics;
151     }
152 }
153