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

Last change on this file since 919 was 919, checked in by jts21, 10 years ago

Added license headers to all files, added full GPL3 license file, moved license header generator script to dev/bin/scripts

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