1 11 package org.eclipse.help.internal.util; 12 13 import java.util.ArrayList ; 14 import java.util.Collections ; 15 import java.util.HashSet ; 16 import java.util.Iterator ; 17 import java.util.List ; 18 import java.util.ListIterator ; 19 import java.util.Set ; 20 21 29 public class SequenceResolver { 30 31 private List primaryList; 32 private List [] secondaryLists; 33 private ListIterator primaryIter; 34 private ListIterator [] secondaryIters; 35 private Set processedItems; 36 37 74 public List getSequence(List primary, List [] secondary) { 75 primaryList = primary; 76 secondaryLists = secondary; 77 prepareDataStructures(); 78 List order = new ArrayList (); 79 Object item; 80 while ((item = getNextItem()) != null) { 81 processedItems.add(item); 82 advanceIterator(primaryIter); 83 for (int i=0;i<secondaryIters.length;++i) { 84 advanceIterator(secondaryIters[i]); 85 } 86 order.add(item); 87 } 88 return order; 89 } 90 91 94 private void prepareDataStructures() { 95 primaryIter = primaryList.listIterator(); 96 secondaryIters = new ListIterator [secondaryLists.length]; 97 for (int i=0;i<secondaryLists.length;++i) { 98 secondaryIters[i] = secondaryLists[i].listIterator(); 99 } 100 processedItems = new HashSet (); 101 } 102 103 107 private Object getNextItem() { 108 Candidate[] candidates = getTopCandidates(); 109 switch(candidates.length) { 110 case 0: 111 return null; 112 case 1: 113 return candidates[0].item; 114 default: 115 for (int i=0;i<candidates.length;++i) { 116 if (candidates[i].isPrimary) { 117 return candidates[i].item; 118 } 119 } 120 return candidates[0].item; 121 } 122 } 123 124 128 private Candidate[] getTopCandidates() { 129 Candidate[] candidates = getEligibleCandidates(); 130 rankCandidates(candidates); 131 if (candidates.length > 0) { 132 int topRank = candidates[0].rank; 133 for (int i=1;i<candidates.length;++i) { 134 if (candidates[i].rank < topRank) { 135 topRank = candidates[i].rank; 136 } 137 } 138 List topCandidates = new ArrayList (); 139 for (int i=0;i<candidates.length;++i) { 140 if (candidates[i].rank == topRank) { 141 topCandidates.add(candidates[i]); 142 } 143 } 144 return (Candidate[])topCandidates.toArray(new Candidate[topCandidates.size()]); 145 } 146 return candidates; 147 } 148 149 155 private Candidate[] getEligibleCandidates() { 156 Candidate[] allCandidates = getAllCandidates(); 157 Candidate primary = null; 158 for (int i=0;i<allCandidates.length;++i) { 159 if (allCandidates[i].isPrimary) { 160 primary = allCandidates[i]; 161 break; 162 } 163 } 164 if (primary != null) { 166 List eligibleCandidates = new ArrayList (allCandidates.length); 167 eligibleCandidates.add(primary); 169 Set primarySet = Collections.singleton(primary.item); 170 for (int i=0;i<allCandidates.length;++i) { 171 Candidate c = allCandidates[i]; 172 if (c != primary) { 173 if (countPrecedingItems(c.item, primary.src, primarySet) == 0) { 175 eligibleCandidates.add(c); 176 } 177 } 178 } 179 return (Candidate[])eligibleCandidates.toArray(new Candidate[eligibleCandidates.size()]); 180 } 181 return allCandidates; 182 } 183 184 188 private Candidate[] getAllCandidates() { 189 List candidates = new ArrayList (); 190 Object item = getNextItem(primaryIter); 191 if (item != null) { 192 Candidate c = new Candidate(); 193 c.item = item; 194 c.isPrimary = true; 195 c.src = primaryList; 196 candidates.add(c); 197 } 198 for (int i=0;i<secondaryIters.length;++i) { 199 item = getNextItem(secondaryIters[i]); 200 if (item != null) { 201 Candidate c = new Candidate(); 202 c.item = item; 203 c.isPrimary = false; 204 c.src = secondaryLists[i]; 205 if (!candidates.contains(c)) { 206 candidates.add(c); 207 } 208 } 209 } 210 return (Candidate[])candidates.toArray(new Candidate[candidates.size()]); 211 } 212 213 219 private void rankCandidates(Candidate[] candidates) { 220 Set candidateItems = new HashSet (); 222 for (int i=0;i<candidates.length;++i) { 223 candidateItems.add(candidates[i].item); 224 } 225 for (int i=0;i<candidates.length;++i) { 226 Candidate c = candidates[i]; 227 for (int j=0;j<candidates.length;++j) { 228 c.rank += countPrecedingItems(c.item, candidates[j].src, candidateItems); 229 } 230 } 231 } 232 233 237 private int countPrecedingItems(Object item, List list, Set set) { 238 int count = 0; 239 Iterator iter = list.iterator(); 240 while (iter.hasNext()) { 241 Object next = iter.next(); 242 if (next.equals(item)) { 243 return count; 244 } 245 if (set.contains(next)) { 246 ++count; 247 } 248 } 249 return 0; 250 } 251 252 256 private Object getNextItem(ListIterator iter) { 257 if (iter.hasNext()) { 258 Object next = iter.next(); 259 iter.previous(); 260 return next; 261 } 262 return null; 263 } 264 265 269 private void advanceIterator(ListIterator iter) { 270 while (iter.hasNext()) { 271 Object item = iter.next(); 272 if (!processedItems.contains(item)) { 273 iter.previous(); 274 break; 275 } 276 } 277 } 278 279 283 private static class Candidate { 284 public Object item; 285 public boolean isPrimary; 286 public int rank; 287 public List src; 288 289 public boolean equals(Object obj) { 290 return item.equals(obj); 291 } 292 293 public int hashCode() { 294 return item.hashCode(); 295 } 296 } 297 } 298 | Popular Tags |