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

Last change on this file since 1529 was 1529, checked in by bnemhaus, 4 years ago

When running the "WriteTree tex" action, the presence of the annotation "@flowwalker" is tested for. If it is present then the flow walker is used!

File size: 6.4 KB
Line 
1/**
2 * DefaultTreeWriter.java
3 * Copyright (C) 2010 New Zealand Digital Library, http://expeditee.org
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19package org.expeditee.io;
20
21import java.io.IOException;
22import java.util.ArrayList;
23import java.util.List;
24import java.util.Stack;
25
26import org.expeditee.gui.Frame;
27import org.expeditee.gui.FrameIO;
28import org.expeditee.gui.MessageBay;
29import org.expeditee.io.flowlayout.XGroupItem;
30import org.expeditee.items.Item;
31import org.expeditee.items.Text;
32
33public abstract class DefaultTreeWriter extends DefaultFrameWriter implements
34 TreeWriter {
35
36 private int _indent = 0;
37
38 // the list of frames currently being processed
39 private Stack<FrameCounter> _frames = new Stack<FrameCounter>();
40
41 private int _frameCount = 0;
42
43 public int getFrameCount() {
44 return _frameCount;
45 }
46
47 public String writeTree(Frame toWrite) throws IOException {
48 try {
49 initialise(toWrite);
50 //outputTree(toWrite);
51 outputTreeFlowWalkerStyle(toWrite);
52
53 } catch (IOException ioe) {
54 _running = false;
55 throw ioe;
56 } catch (Exception e) {
57 e.printStackTrace();
58 }
59 _running = false;
60 return finaliseTree();
61 }
62
63 /**
64 * This method is used to output any tags before following the Item's link
65 * when using tree writers.
66 *
67 * @param linker
68 * The linked Item that is about to be followed.
69 * @throws IOException
70 */
71 protected void writeStartLink(Item linker) throws IOException {
72 _indent++;
73 }
74
75 /**
76 * This method is called after the Frame the Item links to has been
77 * processed. This allows end tags to be written if the format requires it.
78 *
79 * @param linker
80 * The Item whose link was just followed.
81 * @throws IOException
82 */
83 protected void writeEndLink(Item linker) throws IOException {
84 _indent--;
85 }
86
87 protected void resumeFrame(Frame resuming) {
88 }
89
90 protected List<Item> getSortedItems(Frame frame)
91 {
92 List<Item> items = frame.getSortedItems();
93 return items;
94 }
95
96 protected void outputTree(Frame toWrite) throws IOException {
97 if (toWrite == null) {
98 return;
99 }
100
101 XGroupItem.doImplicitBoxing = false;
102
103 _frames.push(new FrameCounter(toWrite.getName(), -1));
104
105 // process the entire tree of frames in depth-first order
106 while (_frames.size() > 0) {
107 FrameCounter cur = _frames.pop();
108
109 if (_stop)
110 return;
111
112 Frame next = FrameIO.LoadFrame(cur.frame);
113
114 if (next == null) {
115 return;
116 }
117
118 Text title = next.getTitleItem();
119
120 // the items on the frame currently being processed.
121 List<Item> items = getSortedItems(next);
122
123 // write any information relating to the end of the link
124 if (cur.index > 0) {
125 this.writeEndLink(items.get(cur.index));
126 this.resumeFrame(next);
127 } else {
128 MessageBay.overwriteMessage("Writing: " + next.getName());
129 _frameCount++;
130 writeStartFrame(next);
131 }
132
133 boolean complete = true;
134
135 // resume from the next item in the list
136 for (int i = cur.index + 1; i < items.size(); i++) {
137 if (_stop)
138 return;
139
140 Item item = items.get(i);
141
142 // ignore annotation and framenames
143 if (item.getID() >= 0) {
144 // Only follow the links of non annotation text items
145 boolean followLink = item instanceof Text
146 && item.getLink() != null
147 && (!item.isAnnotation() /*|| item.getText()
148 .toLowerCase().equals("@next")*/);
149
150 if (followLink) {
151 cur.index = i;
152 _frames.push(cur);
153
154 // write any information relating to the start of the
155 // link
156 this.writeStartLink(item);
157
158 Frame linked = FrameIO
159 .LoadFrame(item.getAbsoluteLink());
160
161 // if the linked frame was found, then display it next
162 if (linked != null) {
163 FrameCounter fc = new FrameCounter(
164 linked.getName(), -1);
165 if (!_frames.contains(fc)) {
166 // remember what frame we are on before
167 // processing it
168 _frames.push(fc);
169
170 complete = false;
171 // process the loaded frame immediately
172 // (depth-first)
173 break;
174 }
175 }
176 // Don't write out the title here because it is written
177 // out earlier
178 } else if (item != title)
179 this.writeItem(item);
180 }
181 }
182
183 if (complete)
184 writeEndFrame(next);
185 }
186 }
187
188 protected void outputTreeFlowWalkerStyle(Frame toWrite) {
189 XGroupItem.doImplicitBoxing = true;
190 XGroupItem xgroup = new XGroupItem(toWrite, new ArrayList<Item>(toWrite.getAllItems()));
191 xgroup.repositionOutOfFlowGroups(xgroup);
192 xgroup.mapInXGroupItemsRecursive(xgroup.getGroupedItemList());
193
194 ArrayList<Item> yxOverlappingItemList = xgroup.getYXOverlappingItemList();
195
196 for(Item i: yxOverlappingItemList) {
197 if (i instanceof Text) {
198 Text t = (Text) i;
199 if (t.isAnnotation()) { continue; }
200 Text titleItem = t.getParent().getTitleItem();
201 if (t.equals(titleItem)) { continue; }
202 if (t.hasLink()) {
203 Frame toWalk = FrameIO.LoadFrame(t.getAbsoluteLink());
204 outputTreeFlowWalkerStyle(toWalk);
205 continue;
206 }
207 try {
208 this.writeItem(t);
209 } catch (IOException e) {
210 System.err.println("DefaultTreeWriter::outputTreeFlowWalkerStyle::IOException while writing item.");
211 System.err.println(e.getMessage());
212 }
213 }
214 }
215 }
216
217 protected String finaliseTree() throws IOException {
218 return "Tree" + finalise();
219 }
220
221 /**
222 * Inner class used to keep track of what frames have been seen, as well as
223 * what Item in the Frame the processing was up to. Only Frame names are
224 * stored to keep memory usage down.
225 */
226 private class FrameCounter {
227 public int index;
228
229 public String frame;
230
231 public FrameCounter(String f, int i) {
232 frame = f.toLowerCase();
233 index = i;
234 }
235
236 @Override
237 public boolean equals(Object o) {
238 if (o instanceof FrameCounter)
239 return (((FrameCounter) o).frame.equals(frame));// && fc.index
240 // == index);
241
242 return false;
243 }
244 }
245
246 protected int getIndent() {
247 return _indent;
248 }
249}
Note: See TracBrowser for help on using the repository browser.