source: trunk/src/org/expeditee/agents/TreeProcessor.java@ 80

Last change on this file since 80 was 80, checked in by ra33, 16 years ago

Added some more unit tests
Did a bunch of refactoring
AND added a few new features... @b @v were the most significant

File size: 3.0 KB
Line 
1package org.expeditee.agents;
2
3import java.util.List;
4import java.util.Stack;
5
6import org.expeditee.gui.Frame;
7import org.expeditee.gui.FrameIO;
8import org.expeditee.items.Item;
9
10/**
11 * This class provides some generic methods that process a tree of Frames.
12 * Subclasses that only use text items can simply implement
13 * processTextItem(Text, int)
14 */
15public abstract class TreeProcessor extends DefaultAgent {
16
17 // the list of frames currently being processed
18 private Stack<FrameCounter> _frames = new Stack<FrameCounter>();
19
20 public TreeProcessor(String delay) {
21 super(delay);
22 }
23
24 public TreeProcessor() {
25 super();
26 }
27
28 /**
29 * Processes the Frame by calling processItem() for each unlinked item
30 * encountered. Linked items call processStartLinkItem(), then load the
31 * linked frame and process it recursively, upon returning
32 * processEndLinkItem() is called.
33 */
34 protected Frame process(Frame toProcess) {
35 if (_stop)
36 return null;
37
38 if (toProcess == null)
39 return null;
40
41 _frames.push(new FrameCounter(toProcess.getName(), -1));
42
43 // process the entire tree of frames in depth-first order
44 while (_frames.size() > 0) {
45 if (_stop)
46 return null;
47
48 FrameCounter cur = _frames.pop();
49
50 Frame next = FrameIO.LoadFrame(cur.frame);
51 if (next == null) {
52 message("There is no " + cur.frame + " Frame to display");
53 return null;
54 }
55
56 if (cur.index < 0) {
57 if (next != null)
58 overwriteMessage("Processing: " + next.getName());
59 processFrame(next);
60 }
61
62 // the items on the frame currently being processed.
63 List<Item> items = next.getItems();
64
65 // resume from the next item in the list
66 for (int i = cur.index + 1; i < items.size(); i++) {
67 Item item = items.get(i);
68
69 // ignore annotation and framenames
70 if (!item.isAnnotation() && item.getID() >= 0) {
71 if (item.getLink() != null) {
72 cur.index = i;
73 _frames.push(cur);
74
75 Frame linked = FrameIO.LoadFrame(item.getAbsoluteLink());
76
77 // if the linked frame was found, then display it next
78 if (linked != null) {
79 FrameCounter fc = new FrameCounter(linked
80 .getName(), -1);
81 if (!_frames.contains(fc)) {
82 // remember what frame we are on before
83 // processing it
84 _frames.push(fc);
85
86 // processFrame(linked);
87
88 // process the loaded frame immediately
89 // (depth-first)
90 break;
91 }
92 }
93 }
94 }
95 }
96 }
97
98 return null;
99 }
100
101 protected abstract void processFrame(Frame toProcess);
102
103 /**
104 * Inner class used to keep track of what frames have been seen, as well as
105 * what Item in the Frame the processing was up to. Only Frame names are
106 * stored to keep memory usage down.
107 */
108 private class FrameCounter {
109 public int index;
110
111 public String frame;
112
113 public FrameCounter(String f, int i) {
114 frame = f.toLowerCase();
115 index = i;
116 }
117
118 @Override
119 public boolean equals(Object o) {
120 if (o instanceof FrameCounter)
121 return (((FrameCounter) o).frame.equals(frame));// && fc.index
122 // == index);
123
124 return false;
125 }
126 }
127
128}
Note: See TracBrowser for help on using the repository browser.