1 11 package org.eclipse.ltk.ui.refactoring.history; 12 13 import java.util.ArrayList ; 14 import java.util.Calendar ; 15 import java.util.List ; 16 17 import org.eclipse.core.runtime.Assert; 18 19 import org.eclipse.ltk.core.refactoring.RefactoringDescriptorProxy; 20 import org.eclipse.ltk.core.refactoring.history.RefactoringHistory; 21 22 import org.eclipse.ltk.internal.ui.refactoring.history.RefactoringHistoryCollection; 23 import org.eclipse.ltk.internal.ui.refactoring.history.RefactoringHistoryDate; 24 import org.eclipse.ltk.internal.ui.refactoring.history.RefactoringHistoryEntry; 25 import org.eclipse.ltk.internal.ui.refactoring.history.RefactoringHistoryNode; 26 27 import org.eclipse.jface.viewers.ITreeContentProvider; 28 import org.eclipse.jface.viewers.Viewer; 29 30 45 public class RefactoringHistoryContentProvider implements ITreeContentProvider { 46 47 48 private static final Object [] NO_ELEMENTS= {}; 49 50 65 private static int binarySearch(final long[] array, final long number) { 66 int left= 0; 67 int right= array.length - 1; 68 int median; 69 do { 70 median= (left + right) / 2; 71 if (number > array[median]) 72 right= median - 1; 73 else 74 left= median + 1; 75 } while (number != array[median] && left <= right); 76 if (number == array[median]) 77 return median; 78 return left; 79 } 80 81 90 private static int getRefactoringRootKindIndex(final long[][] structure, final int kind) { 91 for (int index= structure.length - 1; index >= 0; index--) { 92 if (kind >= structure[index][1]) 93 return index; 94 } 95 return -1; 96 } 97 98 99 private final RefactoringHistoryControlConfiguration fControlConfiguration; 100 101 102 private RefactoringHistory fRefactoringHistory= null; 103 104 105 private long[][] fRefactoringRoots= null; 106 107 108 private long[] fRefactoringStamps= null; 109 110 116 public RefactoringHistoryContentProvider(final RefactoringHistoryControlConfiguration configuration) { 117 Assert.isNotNull(configuration); 118 fControlConfiguration= configuration; 119 } 120 121 124 public void dispose() { 125 } 127 128 131 public Object [] getChildren(final Object element) { 132 if (element instanceof RefactoringHistoryNode) { 133 final RefactoringHistoryNode node= (RefactoringHistoryNode) element; 134 final RefactoringDescriptorProxy[] proxies= getRefactoringDescriptorProxies(); 135 if (proxies.length > 0) { 136 final long[][] structure= getRefactoringRootStructure(proxies[0].getTimeStamp()); 137 final int kind= node.getKind(); 138 switch (kind) { 139 case RefactoringHistoryNode.COLLECTION: 140 return getRefactoringHistoryEntries(node); 141 default: { 142 if (node instanceof RefactoringHistoryDate) { 143 final RefactoringHistoryDate date= (RefactoringHistoryDate) node; 144 final long stamp= date.getTimeStamp(); 145 switch (kind) { 146 case RefactoringHistoryNode.TODAY: 147 return getRefactoringHistoryEntries(date, stamp, Long.MAX_VALUE); 148 case RefactoringHistoryNode.YESTERDAY: 149 return getRefactoringHistoryEntries(date, stamp, structure[getRefactoringRootKindIndex(structure, RefactoringHistoryNode.TODAY)][0] - 1); 150 case RefactoringHistoryNode.THIS_WEEK: 151 return getRefactoringHistoryDays(date, stamp, structure[getRefactoringRootKindIndex(structure, RefactoringHistoryNode.YESTERDAY)][0] - 1); 152 case RefactoringHistoryNode.LAST_WEEK: 153 return getRefactoringHistoryDays(date, stamp, structure[getRefactoringRootKindIndex(structure, RefactoringHistoryNode.THIS_WEEK)][0] - 1); 154 case RefactoringHistoryNode.THIS_MONTH: 155 return getRefactoringHistoryWeeks(date, stamp, structure[getRefactoringRootKindIndex(structure, RefactoringHistoryNode.LAST_WEEK)][0] - 1); 156 case RefactoringHistoryNode.LAST_MONTH: 157 return getRefactoringHistoryWeeks(date, stamp, structure[getRefactoringRootKindIndex(structure, RefactoringHistoryNode.THIS_MONTH)][0] - 1); 158 case RefactoringHistoryNode.DAY: 159 return getRefactoringHistoryEntries(date, stamp, stamp + 1000 * 60 * 60 * 24 - 1); 160 case RefactoringHistoryNode.WEEK: 161 return getRefactoringHistoryDays(date, stamp, stamp + 1000 * 60 * 60 * 24 * 7 - 1); 162 case RefactoringHistoryNode.MONTH: { 163 final Calendar calendar= Calendar.getInstance(); 164 calendar.setTimeInMillis(stamp); 165 calendar.add(Calendar.MONTH, 1); 166 return getRefactoringHistoryWeeks(date, stamp, calendar.getTimeInMillis() - 1); 167 } 168 case RefactoringHistoryNode.YEAR: { 169 final Calendar calendar= Calendar.getInstance(); 170 calendar.setTimeInMillis(stamp); 171 calendar.add(Calendar.YEAR, 1); 172 return getRefactoringHistoryMonths(date, stamp, calendar.getTimeInMillis() - 1); 173 } 174 } 175 } 176 } 177 } 178 } 179 } else if (element instanceof RefactoringHistory) 180 return getElements(element); 181 return NO_ELEMENTS; 182 } 183 184 187 public Object [] getElements(final Object element) { 188 if (element instanceof RefactoringHistory) { 189 if (fControlConfiguration.isTimeDisplayed()) 190 return getRootElements(); 191 else if (fRefactoringHistory != null && !fRefactoringHistory.isEmpty()) 192 return new Object [] { new RefactoringHistoryCollection()}; 193 } 194 return NO_ELEMENTS; 195 } 196 197 200 public Object getParent(final Object element) { 201 if (element instanceof RefactoringHistoryNode) { 202 final RefactoringHistoryNode node= (RefactoringHistoryNode) element; 203 return node.getParent(); 204 } 205 return null; 206 } 207 208 214 private RefactoringDescriptorProxy[] getRefactoringDescriptorProxies() { 215 final RefactoringDescriptorProxy[] proxies= fRefactoringHistory.getDescriptors(); 216 if (fRefactoringStamps == null) { 217 final int length= proxies.length; 218 fRefactoringStamps= new long[length]; 219 for (int index= 0; index < length; index++) 220 fRefactoringStamps[index]= proxies[index].getTimeStamp(); 221 } 222 return proxies; 223 } 224 225 237 private Object [] getRefactoringHistoryDays(final RefactoringHistoryDate parent, final long start, final long end) { 238 final long time= parent.getTimeStamp(); 239 final Calendar calendar= Calendar.getInstance(); 240 final RefactoringDescriptorProxy[] proxies= getRefactoringDescriptorProxies(); 241 final int[] range= getRefactoringHistoryRange(start, end); 242 final List list= new ArrayList (proxies.length); 243 int last= -1; 244 for (int index= range[0]; index <= range[1]; index++) { 245 long stamp= proxies[index].getTimeStamp(); 246 if (stamp >= time) { 247 calendar.setTimeInMillis(stamp); 248 final int day= calendar.get(Calendar.DAY_OF_YEAR); 249 if (day != last) { 250 last= day; 251 calendar.set(Calendar.MILLISECOND, 0); 252 calendar.set(Calendar.SECOND, 0); 253 calendar.set(Calendar.MINUTE, 0); 254 calendar.set(Calendar.HOUR_OF_DAY, 0); 255 stamp= calendar.getTimeInMillis(); 256 if (stamp < time) 257 list.add(new RefactoringHistoryDate(parent, time, RefactoringHistoryNode.DAY)); 258 else 259 list.add(new RefactoringHistoryDate(parent, stamp, RefactoringHistoryNode.DAY)); 260 } 261 } 262 } 263 return list.toArray(); 264 } 265 266 278 private Object [] getRefactoringHistoryEntries(final RefactoringHistoryDate parent, final long start, final long end) { 279 final RefactoringDescriptorProxy[] proxies= getRefactoringDescriptorProxies(); 280 final int[] range= getRefactoringHistoryRange(start, end); 281 final List list= new ArrayList (proxies.length); 282 for (int index= range[0]; index <= range[1]; index++) 283 list.add(new RefactoringHistoryEntry(parent, proxies[index])); 284 return list.toArray(); 285 } 286 287 295 private Object [] getRefactoringHistoryEntries(final RefactoringHistoryNode parent) { 296 final RefactoringDescriptorProxy[] proxies= getRefactoringDescriptorProxies(); 297 final List list= new ArrayList (proxies.length); 298 for (int index= 0; index < proxies.length; index++) 299 list.add(new RefactoringHistoryEntry(parent, proxies[index])); 300 return list.toArray(); 301 } 302 303 315 private Object [] getRefactoringHistoryMonths(final RefactoringHistoryDate parent, final long start, final long end) { 316 final long time= parent.getTimeStamp(); 317 final Calendar calendar= Calendar.getInstance(); 318 final RefactoringDescriptorProxy[] proxies= getRefactoringDescriptorProxies(); 319 final int[] range= getRefactoringHistoryRange(start, end); 320 final List list= new ArrayList (proxies.length); 321 int last= -1; 322 for (int index= range[0]; index <= range[1]; index++) { 323 long stamp= proxies[index].getTimeStamp(); 324 if (stamp >= time) { 325 calendar.setTimeInMillis(stamp); 326 final int month= calendar.get(Calendar.MONTH); 327 if (month != last) { 328 last= month; 329 calendar.set(Calendar.MILLISECOND, 0); 330 calendar.set(Calendar.SECOND, 0); 331 calendar.set(Calendar.MINUTE, 0); 332 calendar.set(Calendar.HOUR_OF_DAY, 0); 333 calendar.set(Calendar.DAY_OF_MONTH, 1); 334 stamp= calendar.getTimeInMillis(); 335 if (stamp < time) 336 list.add(new RefactoringHistoryDate(parent, time, RefactoringHistoryNode.MONTH)); 337 else 338 list.add(new RefactoringHistoryDate(parent, stamp, RefactoringHistoryNode.MONTH)); 339 } 340 } 341 } 342 return list.toArray(); 343 } 344 345 354 private int[] getRefactoringHistoryRange(final long start, final long end) { 355 final int[] range= new int[2]; 356 range[1]= binarySearch(fRefactoringStamps, start) - 1; 357 range[0]= binarySearch(fRefactoringStamps, end); 358 return range; 359 } 360 361 373 private Object [] getRefactoringHistoryWeeks(final RefactoringHistoryDate parent, final long start, final long end) { 374 final long time= parent.getTimeStamp(); 375 final Calendar calendar= Calendar.getInstance(); 376 final RefactoringDescriptorProxy[] proxies= getRefactoringDescriptorProxies(); 377 final int[] range= getRefactoringHistoryRange(start, end); 378 final List list= new ArrayList (proxies.length); 379 int last= -1; 380 for (int index= range[0]; index <= range[1]; index++) { 381 long stamp= proxies[index].getTimeStamp(); 382 if (stamp >= time) { 383 calendar.setTimeInMillis(stamp); 384 final int week= calendar.get(Calendar.WEEK_OF_YEAR); 385 if (week != last) { 386 last= week; 387 calendar.set(Calendar.MILLISECOND, 0); 388 calendar.set(Calendar.SECOND, 0); 389 calendar.set(Calendar.MINUTE, 0); 390 calendar.set(Calendar.HOUR_OF_DAY, 0); 391 calendar.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY); 392 stamp= calendar.getTimeInMillis(); 393 if (stamp < time) 394 list.add(new RefactoringHistoryDate(parent, time, RefactoringHistoryNode.WEEK)); 395 else 396 list.add(new RefactoringHistoryDate(parent, stamp, RefactoringHistoryNode.WEEK)); 397 } 398 } 399 } 400 return list.toArray(); 401 } 402 403 410 private long[][] getRefactoringRootStructure(final long stamp) { 411 if (fRefactoringRoots == null) { 412 final long time= System.currentTimeMillis(); 413 final Calendar calendar= Calendar.getInstance(); 414 calendar.setTimeInMillis(time); 415 calendar.set(Calendar.HOUR_OF_DAY, 0); 416 calendar.set(Calendar.MINUTE, 0); 417 calendar.set(Calendar.SECOND, 0); 418 calendar.set(Calendar.MILLISECOND, 0); 419 final int zoneOffset= calendar.get(Calendar.ZONE_OFFSET); 420 final int dstOffset= calendar.get(Calendar.DST_OFFSET); 421 int count= 0; 422 final long[] thresholds= new long[32]; 423 final int[] kinds= new int[32]; 424 thresholds[count]= calendar.getTimeInMillis(); 425 kinds[count]= RefactoringHistoryNode.TODAY; 426 count++; 427 calendar.add(Calendar.DATE, -1); 428 thresholds[count]= calendar.getTimeInMillis(); 429 kinds[count]= RefactoringHistoryNode.YESTERDAY; 430 count++; 431 final int day= calendar.get(Calendar.DAY_OF_WEEK); 432 if (day != Calendar.SUNDAY) { 433 calendar.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY); 434 thresholds[count]= calendar.getTimeInMillis(); 435 kinds[count]= RefactoringHistoryNode.THIS_WEEK; 436 count++; 437 calendar.add(Calendar.WEEK_OF_YEAR, -1); 438 } 439 calendar.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY); 440 thresholds[count]= calendar.getTimeInMillis(); 441 kinds[count]= RefactoringHistoryNode.LAST_WEEK; 442 count++; 443 calendar.setTimeInMillis(time); 444 calendar.set(Calendar.HOUR_OF_DAY, 0); 445 calendar.set(Calendar.MINUTE, 0); 446 calendar.set(Calendar.SECOND, 0); 447 calendar.set(Calendar.MILLISECOND, 0); 448 calendar.set(Calendar.DAY_OF_MONTH, 1); 449 if (thresholds[count - 1] >= calendar.getTimeInMillis()) { 450 thresholds[count]= calendar.getTimeInMillis(); 451 kinds[count]= RefactoringHistoryNode.THIS_MONTH; 452 count++; 453 } 454 calendar.add(Calendar.MONTH, -1); 455 thresholds[count]= calendar.getTimeInMillis(); 456 kinds[count]= RefactoringHistoryNode.LAST_MONTH; 457 count++; 458 final int month= calendar.get(Calendar.MONTH); 459 if (month != 0) { 460 calendar.set(Calendar.MONTH, 0); 461 thresholds[count]= calendar.getTimeInMillis(); 462 kinds[count]= RefactoringHistoryNode.YEAR; 463 count++; 464 } 465 if (stamp > 0) { 466 final long localized= stamp + zoneOffset + dstOffset; 467 calendar.set(Calendar.MONTH, 0); 468 do { 469 calendar.add(Calendar.YEAR, -1); 470 thresholds[count]= calendar.getTimeInMillis(); 471 kinds[count]= RefactoringHistoryNode.YEAR; 472 count++; 473 } while (calendar.getTimeInMillis() > localized); 474 } 475 final long[][] result= new long[count - 1][2]; 476 for (int index= 0; index < count - 1; index++) { 477 result[index][0]= thresholds[index]; 478 result[index][1]= kinds[index]; 479 } 480 fRefactoringRoots= result; 481 } 482 return fRefactoringRoots; 483 } 484 485 494 public Object [] getRootElements() { 495 final List list= new ArrayList (16); 496 if (fRefactoringHistory != null && !fRefactoringHistory.isEmpty()) { 497 final RefactoringDescriptorProxy[] proxies= getRefactoringDescriptorProxies(); 498 if (proxies.length > 0) { 499 final long[][] structure= getRefactoringRootStructure(proxies[0].getTimeStamp()); 500 int begin= 0; 501 long end= Long.MAX_VALUE; 502 for (int index= 0; index < proxies.length; index++) { 503 final long stamp= proxies[index].getTimeStamp(); 504 for (int offset= begin; offset < structure.length; offset++) { 505 final long start= structure[offset][0]; 506 if (stamp >= start && stamp <= end) { 507 list.add(new RefactoringHistoryDate(null, start, (int) structure[offset][1])); 508 begin= offset + 1; 509 end= start - 1; 510 break; 511 } 512 } 513 } 514 } 515 } 516 return list.toArray(); 517 } 518 519 522 public boolean hasChildren(final Object element) { 523 return !(element instanceof RefactoringHistoryEntry); 524 } 525 526 529 public void inputChanged(final Viewer viewer, final Object predecessor, final Object successor) { 530 if (predecessor == successor || fRefactoringHistory == successor) 531 return; 532 if (successor instanceof RefactoringHistory) { 533 if (successor.equals(fRefactoringHistory)) 534 return; 535 fRefactoringHistory= (RefactoringHistory) successor; 536 } else 537 fRefactoringHistory= null; 538 fRefactoringRoots= null; 539 fRefactoringStamps= null; 540 } 541 } 542 | Popular Tags |