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

Last change on this file since 1207 was 1207, checked in by bln4, 5 years ago
File size: 10.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 // Previously lines in a .exp file had to start with a letter (A-Z, a-z). This allowed for an efficient check for valid lines.
71 // As we started to run out of spare letters to use for properties, we wished to use the full range of characters. But we did not
72 // wish to loose the efficiency of the Character.isLetter check. In order to maintain as much of this efficiency as possible, but
73 // allow for all characters, we take advantage of how || is evaluated:
74 // if the check for Character.isLetter passes, then the more complex map lookup operation does not take place.
75 return s.length() >= 2 && (Character.isLetter(s.charAt(0)) || _ItemTags.keySet().contains(s.charAt(0)));
76 }
77
78 /**
79 * Reads a file with the given name from disk.
80 *
81 * @param frameName
82 * the name of the Frame to read in from a file.
83 * @return A new Frame object that contains any Items described in the file.
84 * @throws IOException
85 * Any exceptions occured by the BufferedReader.
86 */
87 @Override
88 public Frame readFrame(BufferedReader reader) throws IOException {
89 _reader = reader;
90 String next = "";
91 Frame newFrame = new Frame();
92
93 try {
94 // Framename must be set before setting the frame number
95 newFrame.setName(_frameName);
96
97 final List<DelayedAction> delayedActions = new LinkedList<DelayedAction>();
98
99 // First read all the header lines
100 while (_reader.ready() && !(next = _reader.readLine()).equals("Z")) {
101 if (isValidLine(next)) {
102 processHeaderLine(newFrame, next);
103 }
104 }
105
106 // Now read all the items
107 Item currentItem = null;
108 while (_reader.ready() && !(next = _reader.readLine()).equals("Z")) {
109 // if this is the start of a new item add a new item
110 if (isValidLine(next)) {
111 if (getTag(next) == 'S') {
112 String value = getValue(next);
113 int id = Integer.parseInt(value.substring(2));
114
115 switch (value.charAt(0)) {
116 case 'P': // check if its a point
117 currentItem = new Dot(id);
118 break;
119 default:
120 currentItem = new Text(id);
121 break;
122 }
123 _linePoints.put(currentItem.getID(), currentItem);
124 newFrame.addItem(currentItem);
125 } else if (currentItem != null && actionShouldBeDelayed(getTag(next))) {
126 delayedActions.add(new DelayedAction(currentItem, next));
127 } else if (currentItem != null) {
128 processBodyLine(currentItem, next);
129// final boolean hasSpecifiedPermission = currentItem.getPermission() != null;
130// final boolean hasSpecifiedOwner = currentItem.getOwner() != null;
131// if (hasSpecifiedPermission && hasSpecifiedOwner && currentItem.getPermission().getPermission(currentItem.getOwner()) == UserAppliedPermission.denied) {
132// newFrame.removeItem(currentItem);
133// newFrame.addItemHidden(currentItem);
134// continue;
135// }
136 } else {
137 System.err.println("Error while reading in frame (ExpReader): Found body line but no current item to apply it to.");
138 }
139 }
140 }
141
142 // Read the lines
143 while (_reader.ready() && !(next = _reader.readLine()).equals("Z")) {
144 if (isValidLine(next)) {
145 Point idtype = separateValues(next.substring(2));
146 // The next line must be the endpoints
147 if (!_reader.ready()) {
148 throw new Exception("Unexpected end of file");
149 }
150 next = _reader.readLine();
151 Point startend = separateValues(next.substring(2));
152 int start = startend.getX();
153 int end = startend.getY();
154
155 if (_linePoints.get(start) != null
156 && _linePoints.get(end) != null) {
157 newFrame.addItem(new Line(_linePoints.get(start),
158 _linePoints.get(end), idtype.getX()));
159 } else {
160 System.out
161 .println("Error reading line with unknown end points");
162 }
163 }
164 }
165
166 // Read the constraints
167 while (_reader.ready() && !(next = _reader.readLine()).equals("Z")) {
168 if (isValidLine(next)) {
169 Point idtype = separateValues(next.substring(2));
170 // The next line must be the endpoints
171 if (!_reader.ready()) {
172 throw new Exception("Unexpected end of file");
173 }
174 next = _reader.readLine();
175 Point startend = separateValues(next.substring(2));
176
177 Item a = _linePoints.get(startend.getX());
178 Item b = _linePoints.get(startend.getY());
179
180 new Constraint(a, b, idtype.getX(), idtype.getY());
181 }
182 }
183
184 for(DelayedAction action: delayedActions) {
185 action.exec();
186 }
187
188 // Read the stats
189 while (_reader.ready() && ((next = _reader.readLine()) != null)) {
190 if (next.startsWith(SessionStats.ACTIVE_TIME_ATTRIBUTE)) {
191 try {
192 String value = next.substring(SessionStats.ACTIVE_TIME_ATTRIBUTE.length()).trim();
193 newFrame.setActiveTime(value);
194 } catch (Exception e) {
195 }
196
197 } else if (next.startsWith(SessionStats.DARK_TIME_ATTRIBUTE)) {
198 try {
199 String value = next.substring(SessionStats.DARK_TIME_ATTRIBUTE.length()).trim();
200 newFrame.setDarkTime(value);
201 } catch (Exception e) {
202 }
203
204 }
205 }
206
207 } catch (Exception e) {
208 e.printStackTrace();
209 System.out.println("Error reading frame file line: " + next + " "
210 + e.getMessage());
211 }
212
213 //newFrame.refreshItemPermissions();
214 _reader.close();
215 newFrame.setChanged(false);
216
217 return newFrame;
218 }
219
220 private class DelayedAction {
221 private Item theItem;
222 private String theLine;
223
224 DelayedAction(final Item theItem, final String theLine) {
225 this.theItem = theItem;
226 this.theLine = theLine;
227 }
228
229 void exec() {
230 processBodyLine(theItem, theLine);
231 }
232 }
233
234 // Stores points used when constructing lines
235 private HashMap<Integer, Item> _linePoints = new HashMap<Integer, Item>();
236
237 /**
238 * Processes the body section of the Exp file, which contains all Items
239 *
240 * @param frame
241 * The Frame to add any created Items to.
242 * @param line
243 * The line of text read in from the file to process.
244 */
245 protected void processBodyLine(Item item, String line) {
246 // separate the tag from the value
247 Character tag = getTag(line);
248 String value = getValue(line);
249
250 Method toRun = _ItemTags.get(tag);
251
252 if (toRun == null) {
253 System.out.println("Error accessing tag method: " + tag);
254 }
255
256 Object[] vals = Conversion.Convert(toRun, value);
257 try {
258 if (vals != null) {
259 toRun.invoke(item, vals);
260 }
261 } catch (Exception e) {
262 System.out.println("Error running tag method: " + tag);
263 e.printStackTrace();
264 }
265 }
266
267 protected static Character getTag(String line) {
268 assert (line.length() > 0);
269 return line.charAt(0);
270 }
271
272 protected static String getValue(String line) {
273 if (line.length() > 2) {
274 return line.substring(2);
275 } else {
276 return "";
277 }
278 }
279
280 protected static boolean actionShouldBeDelayed(Character c) {
281 return _DelayedItemTags.contains(c);
282 }
283
284 /**
285 * Reads the header section of the file, which contains information about
286 * the Frame.
287 *
288 * @param frame
289 * The Frame to assign the read values to.
290 * @param line
291 * The line from the file to process.
292 * @return False if the end of the header has been reached, True otherwise.
293 */
294 private void processHeaderLine(Frame frame, String line) throws IOException {
295 // first separate the tag from the text
296 Character tag = getTag(line);
297 String value = getValue(line);
298 Method toRun = _FrameTags.get(tag);
299
300 if (toRun == null) {
301 if (tag != 'v') {
302 System.out.println("Tag '" + tag + "' in '" + line
303 + "' is not supported.");
304 }
305 return;
306 }
307
308 Object[] vals = Conversion.Convert(toRun, value);
309 try {
310 toRun.invoke(frame, vals);
311 } catch (Exception e) {
312 System.out.println("Error running method: "
313 + toRun.toGenericString());
314 e.printStackTrace();
315 }
316 }
317
318 // Returns a point from a String containing two ints separated by a space
319 protected Point separateValues(String line) {
320 int x = Integer.parseInt(line.substring(0, line.indexOf(" ")));
321 int y = Integer.parseInt(line.substring(line.indexOf(" ") + 1));
322
323 return new Point(x, y);
324 }
325
326 public static int getVersion(String fullpath) {
327 try {
328 BufferedReader reader = new BufferedReader(new FileReader(fullpath));
329 String next = "";
330 // First read the header lines until we get the version number
331 while (reader.ready() && !(next = reader.readLine()).equals("Z")) {
332 if (isValidLine(next)) {
333 Character tag = getTag(next);
334 String value = getValue(next);
335 if (tag.equals('V')) {
336 reader.close();
337 return Integer.parseInt(value);
338 }
339 }
340 }
341 reader.close();
342 } catch (Exception e) {
343 }
344 return -1;
345 }
346}
Note: See TracBrowser for help on using the repository browser.