blob: b56f73bfee960a86d782eaa0489ff2b68391df7c [file] [log] [blame]
package org.unicode.cldr.util;
import java.util.Date;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
/**
* This interface is for objects which can expose information on which reports have been completed.
* @param T the type for each voter. Must be an Integer.
*/
public abstract class VoterReportStatus<T> {
/**
* Enumeration for the reports. In order.
*/
public enum ReportId {
datetime, zones, compact, // aka 'numbers'
};
public enum ReportAcceptability {
notAcceptable, acceptable;
boolean isAcceptable() {
return this == acceptable;
}
static ReportAcceptability fromPair(boolean isComplete, boolean isAcceptable) {
if (isAcceptable) {
return acceptable;
} else if (isComplete) {
return notAcceptable;
} else {
return null;
}
}
};
public abstract ReportStatus getReportStatus(T user, CLDRLocale locale);
public static class ReportStatus {
public EnumSet<ReportId> completed = EnumSet.noneOf(ReportId.class);
public EnumSet<ReportId> acceptable = EnumSet.noneOf(ReportId.class);
public Date date = null;
public ReportStatus mark(ReportId r, boolean asComplete, boolean asAcceptable) {
return this.mark(r, asComplete, asAcceptable, null);
}
public ReportStatus mark(ReportId r, boolean asComplete, boolean asAcceptable, Date date) {
if (!asComplete && asAcceptable) {
throw new IllegalArgumentException("Cannot be !complete&&acceptable");
}
if (asComplete) {
completed.add(r);
} else {
completed.remove(r);
}
if (asAcceptable) {
acceptable.add(r);
} else {
acceptable.remove(r);
}
this.date = date;
return this;
}
public Date getDate() {
return date;
}
/**
* Return the acceptability enum for this report type
* @param r report type
* @return the acceptability enum, or null if there was no entry
*/
public ReportAcceptability getAcceptability(ReportId r) {
return ReportAcceptability.fromPair(completed.contains(r), acceptable.contains(r));
}
}
/**
* Update a Resolver for a particular Report. The resolver will be cleared.
* Note that T must be an Integer for this to succeed.
* @param l locale
* @param r which report
* @param userList set of users
* @param status the source
* @param res which
* @return vote statistics for each acceptability level
*/
public Map<ReportAcceptability, Set<Integer>>
updateResolver(CLDRLocale l, ReportId r,
Set<T> userList, VoteResolver<ReportAcceptability> res) {
Map<ReportAcceptability, Set<Integer>> statistics = new HashMap<>();
res.clear();
res.setBaileyValue(null);
// Get the report status for each user
userList.forEach(id -> {
// get the report status for this user
final ReportStatus rs = getReportStatus(id, l);
// convert the ReportStatus for the specific id, into an enum (or null)
final ReportAcceptability acc = rs.getAcceptability(r);
if (acc != null) {
// if not an abstention, add
res.add(acc, (Integer) id, null, rs.getDate()); // TODO: Cast because T must be an Integer. Refactor class to not be templatized
statistics.computeIfAbsent(acc, k -> new HashSet<>())
.add((Integer) id);
}
});
return statistics;
}
}