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

Last change on this file since 290 was 290, checked in by ra33, 16 years ago
File size: 4.2 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 if (next == null) {
84 return;
85 }
86
87 // the items on the frame currently being processed.
88 List<Item> items = next.getItems();
89
90 // write any information relating to the end of the link
91 if (cur.index > 0) {
92 this.writeEndLink(items.get(cur.index));
93 this.resumeFrame(next);
94 } else {
95 MessageBay.overwriteMessage("Writing: " + next.getName());
96 _frameCount++;
97 writeStartFrame(next);
98 }
99
100 boolean complete = true;
101
102 // resume from the next item in the list
103 for (int i = cur.index + 1; i < items.size(); i++) {
104 if (_stop)
105 return;
106
107 Item item = items.get(i);
108
109 // ignore annotation and framenames
110 if (item.getID() >= 0) {
111 //Only follow the links of text items
112 if (item instanceof Text && item.getLink() != null
113 && !item.isAnnotation()) {
114 cur.index = i;
115 _frames.push(cur);
116
117 // write any information relating to the start of the
118 // link
119 this.writeStartLink(item);
120
121 Frame linked = FrameIO
122 .LoadFrame(item.getAbsoluteLink());
123
124 // if the linked frame was found, then display it next
125 if (linked != null) {
126 FrameCounter fc = new FrameCounter(
127 linked.getName(), -1);
128 if (!_frames.contains(fc)) {
129 // remember what frame we are on before
130 // processing it
131 _frames.push(fc);
132
133 complete = false;
134 // process the loaded frame immediately
135 // (depth-first)
136 break;
137 }
138 }
139 // Dont write out the title here because it is written
140 // out earlier
141 } else if (item != next.getTitleItem())
142 this.writeItem(item);
143 }
144 }
145
146 if (complete)
147 writeEndFrame(next);
148 }
149 }
150
151 protected String finaliseTree() throws IOException {
152 return "Tree" + finalise();
153 }
154
155 /**
156 * Inner class used to keep track of what frames have been seen, as well as
157 * what Item in the Frame the processing was up to. Only Frame names are
158 * stored to keep memory usage down.
159 */
160 private class FrameCounter {
161 public int index;
162
163 public String frame;
164
165 public FrameCounter(String f, int i) {
166 frame = f.toLowerCase();
167 index = i;
168 }
169
170 @Override
171 public boolean equals(Object o) {
172 if (o instanceof FrameCounter)
173 return (((FrameCounter) o).frame.equals(frame));// && fc.index
174 // == index);
175
176 return false;
177 }
178 }
179
180 protected int getIndent() {
181 return _indent;
182 }
183}
Note: See TracBrowser for help on using the repository browser.