1 // Copyright 2011-2012 IBM Corporation and Others. All rights reserved. 2 3 package org.unicode.cldr.web; 4 5 import java.util.Collection; 6 import java.util.Comparator; 7 import java.util.LinkedList; 8 import java.util.List; 9 import java.util.Set; 10 import java.util.TreeSet; 11 import java.util.Vector; 12 13 import org.unicode.cldr.web.DataSection.DataRow; 14 import org.unicode.cldr.web.Partition.Membership; 15 16 /** 17 * This class represents a mode of sorting: i.e., by code, etc. 18 * 19 * @author srl 20 * 21 */ 22 23 public abstract class SortMode { 24 25 static String getSortMode(WebContext ctx, String prefix) { 26 String sortMode = null; 27 sortMode = ctx.pref(SurveyMain.PREF_SORTMODE, SurveyMain.PREF_SORTMODE_DEFAULT); 28 return sortMode; 29 } 30 31 public static String getSortMode(WebContext ctx, DataSection section) { 32 return getSortMode(ctx, section.xpathPrefix); 33 } 34 35 public static SortMode getInstance(String mode) { 36 if (mode.equals(CodeSortMode.name)) { 37 return new CodeSortMode(); 38 } else if (mode.equals(CalendarSortMode.name)) { 39 return new CalendarSortMode(); 40 } else if (mode.equals(MetazoneSortMode.name)) { 41 return new MetazoneSortMode(); 42 } else if (mode.equals(InterestSort.name)) { 43 return new InterestSort(); 44 } else if (mode.equals(NameSort.name)) { 45 return new NameSort(); 46 } else if (mode.equals(PathHeaderSort.name)) { 47 return new PathHeaderSort(); 48 } else { 49 return new CodeSortMode(); 50 } 51 } 52 53 public static List<String> getSortModesFor(String xpath) { 54 List<String> list = new LinkedList<>(); 55 if (xpath.contains("/calendars")) { 56 list.add(CalendarSortMode.name); 57 } else if (xpath.contains("zone")) { 58 list.add(MetazoneSortMode.name); 59 } else { 60 list.add(CodeSortMode.name); 61 } 62 if (false) { // hide others 63 list.add(NameSort.name); 64 list.add(InterestSort.name); 65 } 66 return list; 67 } 68 69 /** 70 * For subclasses 71 * 72 * @param p 73 * @param memberships 74 * @return 75 */ 76 protected static final int categorizeDataRow(DataRow p, Partition.Membership[] memberships) { 77 int rv = -1; 78 for (int i = 0; (rv == -1) && (i < memberships.length); i++) { 79 if (memberships[i].isMember(p)) { 80 rv = i; 81 } 82 } 83 return rv; 84 } 85 86 /** 87 * Name of this mode. 88 * 89 * @return 90 */ 91 abstract String getName(); 92 93 abstract String getDisplayName(); 94 95 /** 96 * 97 * @return 98 */ 99 abstract Partition.Membership[] memberships(); 100 101 /** 102 * 103 * @return 104 */ 105 abstract Comparator<DataRow> createComparator(); 106 107 public String getDisplayName(DataRow p) { 108 if (p == null) { 109 return "(null)"; 110 } else if (p.getDisplayName() != null) { 111 return p.getDisplayName(); 112 } else { 113 return p.prettyPath; 114 } 115 } 116 117 enum SortKeyType { 118 SORTKEY_INTEREST, SORTKEY_CALENDAR, SORTKEY_METAZONE 119 } 120 121 public static final int[] reserveForSort() { 122 int[] x = new int[SortKeyType.values().length]; 123 for (int i = 0; i < x.length; i++) { 124 x[i] = -1; 125 } 126 return x; 127 } 128 129 protected static int compareMembers(DataRow p1, DataRow p2, Membership[] memberships, int ourKey) { 130 if (p1.reservedForSort[ourKey] == -1) { 131 p1.reservedForSort[ourKey] = categorizeDataRow(p1, memberships); 132 } 133 if (p2.reservedForSort[ourKey] == -1) { 134 p2.reservedForSort[ourKey] = categorizeDataRow(p2, memberships); 135 } 136 137 if (p1.reservedForSort[ourKey] < p2.reservedForSort[ourKey]) { 138 return -1; 139 } else if (p1.reservedForSort[ourKey] > p2.reservedForSort[ourKey]) { 140 return 1; 141 } else { 142 return 0; 143 } 144 } 145 146 public Partition[] createPartitions(DataRow[] rows) { 147 return createPartitions(memberships(), rows); 148 } 149 150 /** 151 * Create partitions based on the membership in the rows 152 * 153 * @param memberships 154 * @param rows 155 * @return 156 */ 157 protected Partition[] createPartitions(Membership[] memberships, DataRow[] rows) { 158 Vector<Partition> v = new Vector<>(); 159 if (memberships != null) { // something with partitions 160 Partition testPartitions[] = createPartitions(memberships); 161 162 // find the starts 163 int lastGood = 0; 164 for (int i = 0; i < rows.length; i++) { 165 DataRow p = rows[i]; 166 167 for (int j = lastGood; j < testPartitions.length; j++) { 168 if (testPartitions[j].pm.isMember(p)) { 169 if (j > lastGood) { 170 lastGood = j; 171 } 172 if (testPartitions[j].start == -1) { 173 testPartitions[j].start = i; 174 } 175 break; // sit here until we fail membership 176 } 177 178 if (testPartitions[j].start != -1) { 179 testPartitions[j].limit = i; 180 } 181 } 182 } 183 // catch the last item 184 if ((testPartitions[lastGood].start != -1) && (testPartitions[lastGood].limit == -1)) { 185 testPartitions[lastGood].limit = rows.length; // limit = off the 186 // end. 187 } 188 189 for (int j = 0; j < testPartitions.length; j++) { 190 if (testPartitions[j].start != -1) { 191 if (testPartitions[j].start != 0 && v.isEmpty()) { 192 // v.add(new 193 // Partition("Other",0,testPartitions[j].start)); 194 } 195 v.add(testPartitions[j]); 196 } 197 } 198 } else { 199 // default partition - e'erthing. 200 v.add(new Partition(null, 0, rows.length)); 201 } 202 return v.toArray(new Partition[0]); // fold it up 203 } 204 205 /** 206 * Create empty partitions 207 * 208 * @param memberships 209 * @return 210 */ 211 public static Partition[] createPartitions(Membership[] memberships) { 212 if (memberships == null) { 213 Partition empty[] = new Partition[1]; 214 empty[0] = new Partition(null, 0, 0); 215 return empty; 216 } 217 Partition testPartitions[] = new Partition[memberships.length]; 218 for (int i = 0; i < memberships.length; i++) { 219 testPartitions[i] = new Partition(memberships[i]); 220 } 221 return testPartitions; 222 } 223 224 public DataSection.DisplaySet createDisplaySet(XPathMatcher matcher, Collection<DataRow> values) { 225 DataRow rows[] = createSortedList(createComparator(), matcher, values); 226 return new DataSection.DisplaySet(rows, this, createPartitions(rows)); 227 } 228 229 protected DataRow[] createSortedList(Comparator<DataRow> comparator, XPathMatcher matcher, Collection<DataRow> rows) { 230 // partitions = sortMode.createPartitions(rows); 231 // DisplaySet aDisplaySet = new DisplaySet(createSortedList(sortMode, 232 // matcher,rowsHash.values()), sortMode); 233 Set<DataRow> newSet; 234 235 newSet = new TreeSet<>(comparator); 236 237 if (matcher == null) { 238 newSet.addAll(rows); // sort it 239 } else { 240 for (Object o : rows) { 241 DataRow p = (DataRow) o; 242 243 // /*srl*/ /*if(p.type.indexOf("Australia")!=-1)*/ { 244 // System.err.println("xp: "+p.xpathSuffix+":"+p.type+"- match: "+(matcher.matcher(p.type).matches())); 245 // } 246 247 if (!matcher.matches(p.getXpath(), p.getXpathId())) { 248 if (false) 249 System.err.println("not match: " + p.xpathId + " / " + p.getXpath()); 250 continue; 251 252 } else { 253 newSet.add(p); 254 } 255 } 256 } 257 String matchName = "(*)"; 258 if (matcher != null) { 259 matchName = matcher.getName(); 260 } 261 if (SurveyMain.isUnofficial()) 262 System.err.println("Loaded " + newSet.size() + " from " + matchName + " - base xpath (" + rows.size() + ") = " 263 + getName()); 264 return newSet.toArray(new DataRow[newSet.size()]); 265 } 266 } 267