source: trunk/src/org/expeditee/io/DefaultTreeWriter.java@ 457

Last change on this file since 457 was 376, checked in by ra33, 16 years ago
File size: 4.4 KB
Line 
1package org.expeditee.io;
2
3import java.io.IOException;
4import java.util.List;
5import java.util.Stack;
6
7import org.expeditee.gui.Frame;
8import org.expeditee.gui.FrameIO;
9import org.expeditee.gui.MessageBay;
10import org.expeditee.items.Item;
11import org.expeditee.items.Text;
12
13public abstract class DefaultTreeWriter extends DefaultFrameWriter implements
14 TreeWriter {
15
16 private int _indent = 0;
17
18 // the list of frames currently being processed
19 private Stack<FrameCounter> _frames = new Stack<FrameCounter>();
20
21 private int _frameCount = 0;
22
23 public int getFrameCount() {
24 return _frameCount;
25 }
26
27 public String writeTree(Frame toWrite) throws IOException {
28 try {
29 initialise(toWrite);
30 outputTree(toWrite);
31
32 } catch (IOException ioe) {
33 _running = false;
34 throw ioe;
35 } catch (Exception e) {
36 e.printStackTrace();
37 }
38 _running = false;
39 return finaliseTree();
40 }
41
42 /**
43 * This method is used to output any tags before following the Item's link
44 * when using tree writers.
45 *
46 * @param linker
47 * The linked Item that is about to be followed.
48 * @throws IOException
49 */
50 protected void writeStartLink(Item linker) throws IOException {
51 _indent++;
52 }
53
54 /**
55 * This method is called after the Frame the Item links to has been
56 * processed. This allows end tags to be written if the format requires it.
57 *
58 * @param linker
59 * The Item whose link was just followed.
60 * @throws IOException
61 */
62 protected void writeEndLink(Item linker) throws IOException {
63 _indent--;
64 }
65
66 protected void resumeFrame(Frame resuming) {
67 }
68
69 protected void outputTree(Frame toWrite) throws IOException {
70 if (toWrite == null)
71 return;
72
73 _frames.push(new FrameCounter(toWrite.getName(), -1));
74
75 // process the entire tree of frames in depth-first order
76 while (_frames.size() > 0) {
77 FrameCounter cur = _frames.pop();
78
79 if (_stop)
80 return;
81
82 Frame next = FrameIO.LoadFrame(cur.frame);
83
84 if (next == null) {
85 return;
86 }
87
88 Text title = next.getTitleItem();
89
90 // the items on the frame currently being processed.
91 List<Item> items = next.getItems();
92
93 // write any information relating to the end of the link
94 if (cur.index > 0) {
95 this.writeEndLink(items.get(cur.index));
96 this.resumeFrame(next);
97 } else {
98 MessageBay.overwriteMessage("Writing: " + next.getName());
99 _frameCount++;
100 writeStartFrame(next);
101 }
102
103 boolean complete = true;
104
105 // resume from the next item in the list
106 for (int i = cur.index + 1; i < items.size(); i++) {
107 if (_stop)
108 return;
109
110 Item item = items.get(i);
111
112 // ignore annotation and framenames
113 if (item.getID() >= 0) {
114 // Only follow the links of non annotation text items
115 boolean followLink = item instanceof Text
116 && item.getLink() != null
117 && (!item.isAnnotation() /*|| item.getText()
118 .toLowerCase().equals("@next")*/);
119
120 if (followLink) {
121 cur.index = i;
122 _frames.push(cur);
123
124 // write any information relating to the start of the
125 // link
126 this.writeStartLink(item);
127
128 Frame linked = FrameIO
129 .LoadFrame(item.getAbsoluteLink());
130
131 // if the linked frame was found, then display it next
132 if (linked != null) {
133 FrameCounter fc = new FrameCounter(
134 linked.getName(), -1);
135 if (!_frames.contains(fc)) {
136 // remember what frame we are on before
137 // processing it
138 _frames.push(fc);
139
140 complete = false;
141 // process the loaded frame immediately
142 // (depth-first)
143 break;
144 }
145 }
146 // Dont write out the title here because it is written
147 // out earlier
148 } else if (item != title)
149 this.writeItem(item);
150 }
151 }
152
153 if (complete)
154 writeEndFrame(next);
155 }
156 }
157
158 protected String finaliseTree() throws IOException {
159 return "Tree" + finalise();
160 }
161
162 /**
163 * Inner class used to keep track of what frames have been seen, as well as
164 * what Item in the Frame the processing was up to. Only Frame names are
165 * stored to keep memory usage down.
166 */
167 private class FrameCounter {
168 public int index;
169
170 public String frame;
171
172 public FrameCounter(String f, int i) {
173 frame = f.toLowerCase();
174 index = i;
175 }
176
177 @Override
178 public boolean equals(Object o) {
179 if (o instanceof FrameCounter)
180 return (((FrameCounter) o).frame.equals(frame));// && fc.index
181 // == index);
182
183 return false;
184 }
185 }
186
187 protected int getIndent() {
188 return _indent;
189 }
190}
Note: See TracBrowser for help on using the repository browser.