source: trunk/src/org/expeditee/io/ExpReader.java@ 1189

Last change on this file since 1189 was 1189, checked in by bln4, 6 years ago
File size: 9.2 KB
Line 
1/**
2 * ExpReader.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.BufferedReader;
22import java.io.FileReader;
23import java.io.IOException;
24import java.lang.reflect.Method;
25import java.util.HashMap;
26import java.util.LinkedList;
27import java.util.List;
28
29import org.expeditee.core.Point;
30import org.expeditee.gui.Frame;
31import org.expeditee.items.Constraint;
32import org.expeditee.items.Dot;
33import org.expeditee.items.Item;
34import org.expeditee.items.Line;
35import org.expeditee.items.Text;
36import org.expeditee.stats.SessionStats;
37
38/**
39 * Reads in Exp format files and constructs the Frame and Item objects they
40 * contain.
41 *
42 * @author mrww1
43 *
44 */
45public class ExpReader extends DefaultFrameReader {
46
47 public static final String EXTENTION = ".exp";
48
49 private BufferedReader _reader = null;
50
51 private String _frameName;
52
53 /**
54 * Does nothing, location must be set before use
55 */
56 public ExpReader(String frameName) {
57 super();
58
59 _frameName = frameName;
60 }
61
62 /**
63 * Determines whether a string begins with tag.
64 *
65 * @param s
66 * a line of text
67 * @return true if s begins with a tag
68 */
69 protected static boolean isValidLine(String s) {
70 return s.length() >= 2 && s.charAt(1) == ' '
71 && (Character.isLetter(s.charAt(0)) || s.charAt(0) == '[' || s.charAt(0) == ']' || s.charAt(0) == '^' || s.charAt(0) == '_');
72 }
73
74 /**
75 * Reads a file with the given name from disk.
76 *
77 * @param frameName
78 * the name of the Frame to read in from a file.
79 * @return A new Frame object that contains any Items described in the file.
80 * @throws IOException
81 * Any exceptions occured by the BufferedReader.
82 */
83 @Override
84 public Frame readFrame(BufferedReader reader) throws IOException {
85 _reader = reader;
86 String next = "";
87 Frame newFrame = new Frame();
88
89 try {
90 // Framename must be set before setting the frame number
91 newFrame.setName(_frameName);
92
93 final List<DelayedAction> delayedActions = new LinkedList<DelayedAction>();
94
95 // First read all the header lines
96 while (_reader.ready() && !(next = _reader.readLine()).equals("Z")) {
97 if (isValidLine(next)) {
98 processHeaderLine(newFrame, next);
99 }
100 }
101
102 // Now read all the items
103 Item currentItem = null;
104 while (_reader.ready() && !(next = _reader.readLine()).equals("Z")) {
105 // if this is the start of a new item add a new item
106 if (isValidLine(next)) {
107 if (getTag(next) == 'S') {
108 String value = getValue(next);
109 int id = Integer.parseInt(value.substring(2));
110
111 switch (value.charAt(0)) {
112 case 'P': // check if its a point
113 currentItem = new Dot(id);
114 break;
115 default:
116 currentItem = new Text(id);
117 break;
118 }
119 _linePoints.put(currentItem.getID(), currentItem);
120 newFrame.addItem(currentItem);
121 } else if (currentItem != null && actionShouldBeDelayed(getTag(next))) {
122 delayedActions.add(new DelayedAction(currentItem, next));
123 } else if (currentItem != null) {
124 processBodyLine(currentItem, next);
125 } else {
126 System.err.println("Error while reading in frame (ExpReader): Found body line but no current item to apply it to.");
127 }
128 }
129 }
130
131 // Read the lines
132 while (_reader.ready() && !(next = _reader.readLine()).equals("Z")) {
133 if (isValidLine(next)) {
134 Point idtype = separateValues(next.substring(2));
135 // The next line must be the endpoints
136 if (!_reader.ready()) {
137 throw new Exception("Unexpected end of file");
138 }
139 next = _reader.readLine();
140 Point startend = separateValues(next.substring(2));
141 int start = startend.getX();
142 int end = startend.getY();
143
144 if (_linePoints.get(start) != null
145 && _linePoints.get(end) != null) {
146 newFrame.addItem(new Line(_linePoints.get(start),
147 _linePoints.get(end), idtype.getX()));
148 } else {
149 System.out
150 .println("Error reading line with unknown end points");
151 }
152 }
153 }
154
155 // Read the constraints
156 while (_reader.ready() && !(next = _reader.readLine()).equals("Z")) {
157 if (isValidLine(next)) {
158 Point idtype = separateValues(next.substring(2));
159 // The next line must be the endpoints
160 if (!_reader.ready()) {
161 throw new Exception("Unexpected end of file");
162 }
163 next = _reader.readLine();
164 Point startend = separateValues(next.substring(2));
165
166 Item a = _linePoints.get(startend.getX());
167 Item b = _linePoints.get(startend.getY());
168
169 new Constraint(a, b, idtype.getX(), idtype.getY());
170 }
171 }
172
173 for(DelayedAction action: delayedActions) {
174 action.exec();
175 }
176
177 // Read the stats
178 while (_reader.ready() && ((next = _reader.readLine()) != null)) {
179 if (next.startsWith(SessionStats.ACTIVE_TIME_ATTRIBUTE)) {
180 try {
181 String value = next.substring(SessionStats.ACTIVE_TIME_ATTRIBUTE.length()).trim();
182 newFrame.setActiveTime(value);
183 } catch (Exception e) {
184 }
185
186 } else if (next.startsWith(SessionStats.DARK_TIME_ATTRIBUTE)) {
187 try {
188 String value = next.substring(SessionStats.DARK_TIME_ATTRIBUTE.length()).trim();
189 newFrame.setDarkTime(value);
190 } catch (Exception e) {
191 }
192
193 }
194 }
195
196 } catch (Exception e) {
197 e.printStackTrace();
198 System.out.println("Error reading frame file line: " + next + " "
199 + e.getMessage());
200 }
201
202 //newFrame.refreshItemPermissions();
203 _reader.close();
204 newFrame.setChanged(false);
205
206 return newFrame;
207 }
208
209 private class DelayedAction {
210 private Item theItem;
211 private String theLine;
212
213 DelayedAction(final Item theItem, final String theLine) {
214 this.theItem = theItem;
215 this.theLine = theLine;
216 }
217
218 void exec() {
219 processBodyLine(theItem, theLine);
220 }
221 }
222
223 // Stores points used when constructing lines
224 private HashMap<Integer, Item> _linePoints = new HashMap<Integer, Item>();
225
226 /**
227 * Processes the body section of the Exp file, which contains all Items
228 *
229 * @param frame
230 * The Frame to add any created Items to.
231 * @param line
232 * The line of text read in from the file to process.
233 */
234 protected void processBodyLine(Item item, String line) {
235 // separate the tag from the value
236 Character tag = getTag(line);
237 String value = getValue(line);
238
239 Method toRun = _ItemTags.get(tag);
240 if (toRun == null) {
241 System.out.println("Error accessing tag method: " + tag);
242 }
243 Object[] vals = Conversion.Convert(toRun, value);
244
245 try {
246 if (vals != null) {
247 toRun.invoke(item, vals);
248 }
249 } catch (Exception e) {
250 System.out.println("Error running tag method: " + tag);
251 e.printStackTrace();
252 }
253 }
254
255 protected static Character getTag(String line) {
256 assert (line.length() > 0);
257 return line.charAt(0);
258 }
259
260 protected static String getValue(String line) {
261 if (line.length() > 2) {
262 return line.substring(2);
263 } else {
264 return "";
265 }
266 }
267
268 protected static boolean actionShouldBeDelayed(Character c) {
269 return _DelayedItemTags.contains(c);
270 }
271
272 /**
273 * Reads the header section of the file, which contains information about
274 * the Frame.
275 *
276 * @param frame
277 * The Frame to assign the read values to.
278 * @param line
279 * The line from the file to process.
280 * @return False if the end of the header has been reached, True otherwise.
281 */
282 private void processHeaderLine(Frame frame, String line) throws IOException {
283 // first separate the tag from the text
284 Character tag = getTag(line);
285 String value = getValue(line);
286 Method toRun = _FrameTags.get(tag);
287
288 if (toRun == null) {
289 if (tag != 'v') {
290 System.out.println("Tag '" + tag + "' in '" + line
291 + "' is not supported.");
292 }
293 return;
294 }
295
296 Object[] vals = Conversion.Convert(toRun, value);
297 try {
298 toRun.invoke(frame, vals);
299 } catch (Exception e) {
300 System.out.println("Error running method: "
301 + toRun.toGenericString());
302 e.printStackTrace();
303 }
304 }
305
306 // Returns a point from a String containing two ints separated by a space
307 protected Point separateValues(String line) {
308 int x = Integer.parseInt(line.substring(0, line.indexOf(" ")));
309 int y = Integer.parseInt(line.substring(line.indexOf(" ") + 1));
310
311 return new Point(x, y);
312 }
313
314 public static int getVersion(String fullpath) {
315 try {
316 BufferedReader reader = new BufferedReader(new FileReader(fullpath));
317 String next = "";
318 // First read the header lines until we get the version number
319 while (reader.ready() && !(next = reader.readLine()).equals("Z")) {
320 if (isValidLine(next)) {
321 Character tag = getTag(next);
322 String value = getValue(next);
323 if (tag.equals('V')) {
324 return Integer.parseInt(value);
325 }
326 }
327 }
328 } catch (Exception e) {
329 }
330 return -1;
331 }
332}
Note: See TracBrowser for help on using the repository browser.