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

Last change on this file since 460 was 460, checked in by davidb, 11 years ago

Introduction of method 'gSortedItems()' to help with more advanced forms of text-item traversal. Used (i.e. overriden), for example, in JavaWriter

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