1 19 package org.netbeans.modules.tasklist.core; 20 21 import java.io.BufferedReader ; 22 import java.io.IOException ; 23 import java.io.Reader ; 24 import java.io.Writer ; 25 import java.util.*; 26 import java.util.logging.Level ; 27 import java.util.logging.Logger ; 28 import javax.swing.event.EventListenerList ; 29 import org.netbeans.modules.tasklist.client.Suggestion; 30 import org.netbeans.modules.tasklist.client.SuggestionPriority; 31 import org.openide.ErrorManager; 32 import org.openide.nodes.Node; 33 import org.openide.nodes.Node.Cookie; 34 35 41 public class Task extends Suggestion implements Cloneable , Cookie { 42 private static final Logger LOGGER = TLUtils.getLogger(Task.class); 43 44 static { 45 LOGGER.setLevel(Level.OFF); 46 } 47 48 54 static final String PROP_ATTRS_CHANGED = "attrs"; 56 57 protected EventListenerList listeners = new EventListenerList (); 58 59 private boolean visitable; 60 61 private Task parent; 62 63 64 private Object key; 65 66 67 private List subtasks = null; 68 69 70 private List subtasksCopy; 71 72 78 private boolean zombie = false; 79 80 public Task() { 81 super(null, null, null, null); 82 parent = null; 83 visitable = true; 84 key = new Object (); 85 } 86 87 public Task(String desc, Task parent) { 88 super(null, null, desc, null); 89 this.parent = parent; 90 visitable = true; 91 key = new Object (); 92 } 93 94 100 public int indexOf(Task t) { 101 if (!hasSubtasks()) 102 return -1; 103 return subtasks.indexOf(t); 104 } 105 106 109 public void clear() { 110 if (hasSubtasks()) { 111 subtasks.clear(); 112 subtasksCopy = null; 113 fireStructureChanged(); 114 } 115 } 116 117 122 public int getLevel() { 123 Task t = getParent(); 124 int level = 0; 125 while (t != null) { 126 level++; 127 t = t.getParent(); 128 } 129 return level; 130 } 131 132 137 public void setSummary(String ndesc) { 138 super.setSummary(ndesc); 139 } 140 141 public void setDetails(String ndesc) { 142 super.setDetails(ndesc); 143 } 144 145 public void setPriority(SuggestionPriority priority) { 146 super.setPriority(priority); 147 } 148 149 155 public boolean isVisitable() { 156 return visitable; 157 } 158 159 167 public void setVisitable(boolean visitable) { 168 this.visitable = visitable; 169 } 170 171 178 protected void firePropertyChange(String propertyName, Object oldValue, 179 Object newValue) { 180 super.firePropertyChange(propertyName, oldValue, newValue); 181 } 182 183 public void addTaskListener(TaskListener l) { 184 if (LOGGER.isLoggable(Level.FINE)) 185 Thread.dumpStack(); 186 listeners.add(TaskListener.class, l); 187 } 188 189 public void removeTaskListener(TaskListener l) { 190 if (LOGGER.isLoggable(Level.FINE)) 191 Thread.dumpStack(); 192 listeners.remove(TaskListener.class, l); 193 } 194 195 protected final void fireStructureChanged() { 196 Object [] l = listeners.getListenerList(); 198 for (int i = l.length - 2; i >= 0; i -= 2) { 199 if (l[i] == TaskListener.class) { 200 ((TaskListener) l[i+1]).structureChanged(this); 201 } 202 } 203 204 if (this instanceof TaskListener) { 205 ((TaskListener) this).structureChanged(this); 206 } 207 } 208 209 214 protected final void fireAddedTask(Task t) { 215 Object [] l = listeners.getListenerList(); 217 for (int i = l.length - 2; i >= 0; i -= 2) { 218 if (l[i] == TaskListener.class) { 219 ((TaskListener) l[i+1]).addedTask(t); 220 } 221 } 222 if (this instanceof TaskListener) { 223 ((TaskListener) this).addedTask(t); 224 } 225 } 226 227 228 234 protected final void fireRemovedTask(Task t, int index) { 235 Object [] l = listeners.getListenerList(); 237 for (int i = l.length - 2; i >= 0; i -= 2) { 238 if (l[i] == TaskListener.class) { 239 ((TaskListener) l[i+1]).removedTask(this, t, index); 240 } 241 } 242 243 if (this instanceof TaskListener) { 244 ((TaskListener) this).removedTask(this, t, index); 245 } 246 } 247 248 protected void recursivePropertyChange() { 249 firePropertyChange(PROP_ATTRS_CHANGED, null, null); 250 if (subtasks != null) { 251 Iterator it = getSubtasks().iterator(); 252 while (it.hasNext()) { 253 Task item = (Task)it.next(); 254 item.recursivePropertyChange(); 255 } 256 } 257 } 258 259 266 public final List getSubtasks() { 267 if (subtasks == null) { 268 return Collections.EMPTY_LIST; 269 } else { 270 if (subtasksCopy == null) { 272 synchronized (subtasks) { 273 subtasksCopy = Collections.unmodifiableList( 274 new ArrayList(subtasks)); 275 } 276 } 277 return subtasksCopy; 278 } 279 } 280 281 287 public final Iterator subtasksIterator() { return getSubtasks().iterator(); 289 } 290 291 296 public final int subtasksCount() { 297 if (subtasks == null) { 298 return 0; 299 } else { 300 return subtasks.size(); 301 } 302 } 303 304 307 public final boolean containsSubtask(Task task) { 308 if (subtasks == null) { 309 return false; 310 } else { 311 return subtasks.contains(task); 312 } 313 } 314 315 322 public void addSubtask(Task subtask) { 323 addSubtask(subtask, false); 324 } 325 326 336 public void addSubtask(Task subtask, Task after) { 337 subtask.parent = this; 338 if (subtasks == null) { 339 ErrorManager.getDefault().log("addSubtask(subtask,after) called where subtasks==null"); return; 342 } 343 int pos = subtasks.indexOf(after); 344 subtasks.add(pos+1, subtask); 345 subtasksCopy = null; 346 fireAddedTask(subtask); 347 } 348 349 358 public void addSubtasks(List tasks, boolean append, Task after) { 359 ListIterator it = tasks.listIterator(); 360 while (it.hasNext()) { 361 Task task = (Task)it.next(); 362 task.parent = this; 363 } 364 365 if (subtasks == null) { 366 subtasks = Collections.synchronizedList(new LinkedList()); 367 } 368 if (after != null) { 369 int pos = subtasks.indexOf(after); 370 subtasks.addAll(pos+1, tasks); 371 } else if (append) { 372 subtasks.addAll(tasks); 373 } else { 374 subtasks.addAll(0, tasks); 375 } 376 subtasksCopy = null; 377 fireStructureChanged(); 378 } 379 380 385 public void addSubtask(Task subtask, boolean append) { 386 subtask.parent = this; 387 if (subtasks == null) { 388 subtasks = Collections.synchronizedList(new LinkedList()); 389 } 390 391 if (subtasks.contains(subtask)) return; 394 395 if (append) { 396 subtasks.add(subtask); 397 } else { 398 subtasks.add(0, subtask); 399 } 400 subtasksCopy = null; 401 fireAddedTask(subtask); 402 } 403 404 409 public void removeSubtask(Task subtask) { 410 subtask.zombie = true; 413 if (subtasks == null) { 414 return; 415 } 416 int index = subtasks.indexOf(subtask); 417 subtasks.remove(index); 418 if (subtasks.size() == 0) { 419 subtasks = null; 420 } 421 422 subtasksCopy = null; 423 fireRemovedTask(subtask, index); 424 } 425 426 430 public final boolean hasSubtasks() { 431 return ((subtasks != null) && (subtasks.size() != 0)); 432 } 433 434 public final Task getParent() { 435 return parent; 436 } 437 438 439 public final Task getRoot() { 440 Task parent = getParent(); 441 if (parent != null) { 442 return parent.getRoot(); 443 } else { 444 return this; 445 } 446 } 447 448 449 450 public final boolean isParentOf(Task task) { 451 if (task.getKey() == getKey()) return true; 452 Task nextLevel = task.getParent(); 453 if (nextLevel == null) return false; 454 return isParentOf(nextLevel); } 456 457 463 public boolean isZombie() { 464 return zombie; 465 } 466 467 478 public static void generate(Task item, Writer w) throws IOException { 479 w.write(item.getSummary()); 480 } 481 482 493 public static Task parse(Reader r) throws IOException { 494 LOGGER.fine("parsing"); 495 496 BufferedReader reader = new BufferedReader (r); 497 String line; 499 while ((line = reader.readLine()) != null) { 500 Task item = new Task(); 506 item.setSummary(line); 507 return item; 508 } 509 return null; 510 } 511 512 513 518 public int getSubtaskCountRecursively() { 519 if(subtasks == null) return 0; 520 521 int n = 0; 522 synchronized(subtasks) { 523 Iterator it = subtasks.iterator(); 524 while(it.hasNext()) { 525 Task t = (Task) it.next(); 526 n += t.getSubtaskCountRecursively() + 1; 527 } 528 return n; 529 } 530 } 531 532 536 public Node[] createNode() { 537 if (subtasks != null) { return new Node[] {new TaskNode(this, new TaskChildren(this))}; 540 } else { 541 return new Node[] {new TaskNode(this)}; 542 } 543 } 544 545 549 protected Object clone() { 550 Task t = new Task(); 551 t.copyFrom(this); 552 return t; 553 } 554 555 558 public final Object getKey() { 559 return key; 560 } 561 562 566 public Object getSeed() { 567 return null; 568 } 569 570 571 583 protected void copyFrom(Task from) { 584 visitable = from.visitable; 585 zombie = from.zombie; 586 587 assert from.key != null; 588 key = from.key; 589 590 super.setSummary(from.getSummary()); 592 super.setPriority(from.getPriority()); 593 super.setIcon(from.getIcon()); 594 super.setType(from.getType()); 595 super.setLine(from.getLine()); 596 super.setAction(from.getAction()); 597 super.setDetails(from.getDetails()); 598 599 parent = from.parent; 604 605 607 if (from.subtasks != null) { 611 synchronized(from.subtasks) { 612 Iterator it = from.subtasks.iterator(); 613 subtasks = Collections.synchronizedList(new LinkedList()); 614 while (it.hasNext()) { 615 Task task = (Task)it.next(); 616 Task mycopy = (Task)task.clone(); 617 mycopy.parent = this; 618 subtasks.add(mycopy); 619 } 620 subtasksCopy = null; 621 } 622 } 623 } 624 } 625 626 | Popular Tags |