source: trunk/src/org/expeditee/io/KMSReader.java@ 108

Last change on this file since 108 was 108, checked in by ra33, 16 years ago

Heaps of changes!!!!
Added circles...
Better drawing of lines etc etc

File size: 15.7 KB
Line 
1package org.expeditee.io;
2
3import java.io.BufferedReader;
4import java.io.FileReader;
5import java.io.IOException;
6import java.lang.reflect.Constructor;
7import java.lang.reflect.InvocationTargetException;
8import java.lang.reflect.Method;
9import java.util.HashMap;
10import java.util.Iterator;
11import java.util.LinkedHashMap;
12
13import org.expeditee.gui.Frame;
14import org.expeditee.gui.FrameGraphics;
15import org.expeditee.items.Constraint;
16import org.expeditee.items.Dot;
17import org.expeditee.items.Item;
18import org.expeditee.items.Line;
19import org.expeditee.items.Text;
20import org.expeditee.stats.SessionStats;
21
22/**
23 * Reads in KMS format files and constructs the Frame and Item objects they
24 * contain.
25 *
26 * @author jdm18
27 *
28 */
29public class KMSReader extends FrameReader {
30
31 private BufferedReader _reader = null;
32
33 private static LinkedHashMap<String, Method> _ItemTags = null;
34
35 private static LinkedHashMap<String, Method> _FrameTags = null;
36
37 /**
38 * Does nothing, location must be set before use
39 */
40 public KMSReader() {
41 if (_ItemTags != null && _FrameTags != null)
42 return;
43
44 _ItemTags = new LinkedHashMap<String, Method>();
45 _FrameTags = new LinkedHashMap<String, Method>();
46
47 try {
48 _FrameTags.put("A", Frame.class.getMethod("setName", pString));
49 _FrameTags.put("V", Frame.class.getMethod("setVersion", pInt));
50 _FrameTags
51 .put("p", Frame.class.getMethod("setPermission", pPermission));
52 _FrameTags.put("U", Frame.class.getMethod("setOwner", pString));
53 _FrameTags.put("D", Frame.class
54 .getMethod("setDateCreated", pString));
55 _FrameTags.put("M", Frame.class.getMethod("setLastModifyUser",
56 pString));
57 _FrameTags.put("d", Frame.class.getMethod("setLastModifyDate",
58 pString));
59 _FrameTags
60 .put("F", Frame.class.getMethod("setFrozenDate", pString));
61
62 _FrameTags.put("O", Frame.class.getMethod("setForegroundColor",
63 pColor));
64 _FrameTags.put("B", Frame.class.getMethod("setBackgroundColor",
65 pColor));
66
67 _ItemTags.put("S", Item.class.getMethod("setID", pInt));
68 _ItemTags.put("s", Item.class.getMethod("setDateCreated", pString));
69 _ItemTags.put("d", Item.class.getMethod("setColor", pColor));
70 _ItemTags.put("G", Item.class.getMethod("setBackgroundColor",
71 pColor));
72 _ItemTags.put("P", Item.class.getMethod("setPosition", pPoint));
73 _ItemTags.put("F", Item.class.getMethod("setLink", pString));
74 _ItemTags.put("X", Item.class.getMethod("setActions", pList));
75 _ItemTags.put("x", Item.class.getMethod("setActionMark", pBool));
76 _ItemTags.put("U", Item.class.getMethod("setActionCursorEnter",
77 pList));
78 _ItemTags.put("V", Item.class.getMethod("setActionCursorLeave",
79 pList));
80 _ItemTags.put("W", Item.class.getMethod("setActionEnterFrame",
81 pList));
82 _ItemTags.put("Y", Item.class.getMethod("setActionLeaveFrame",
83 pList));
84 _ItemTags.put("D", Item.class.getMethod("setData", pList));
85 _ItemTags.put("u", Item.class.getMethod("setHighlight", pBool));
86 _ItemTags.put("e", Item.class.getMethod("setFillColor", pColor));
87 _ItemTags.put("i", Item.class.getMethod("setFillPattern", pString));
88 _ItemTags.put("o", Item.class.getMethod("setOwner", pString));
89 _ItemTags.put("n", Item.class.getMethod("setLinkMark", pBool));
90 _ItemTags
91 .put("q", Item.class.getMethod("setLinkFrameset", pString));
92 _ItemTags
93 .put("y", Item.class.getMethod("setLinkTemplate", pString));
94 _ItemTags.put("g", Item.class
95 .getMethod("setLinePattern", pIntArray));
96
97 _ItemTags.put("j", Item.class.getMethod("setArrow", pArrow));
98
99 _ItemTags.put("f", Text.class.getMethod("setFont", pFont));
100 _ItemTags.put("t", Text.class.getMethod("setSpacing", pInt));
101 _ItemTags.put("T", Text.class.getMethod("appendText", pString));
102
103 _ItemTags.put("a", Text.class.getMethod("setWordSpacing", pInt));
104 _ItemTags.put("b", Text.class.getMethod("setLetterSpacing", pInt));
105 _ItemTags.put("m", Text.class.getMethod("setInitialSpacing", pInt));
106 _ItemTags.put("w", Text.class.getMethod("setWidth", pInt));
107 _ItemTags.put("k", Text.class.getMethod("setJustification", pJustification));
108
109 _ItemTags.put("h", Item.class.getMethod("setThickness", pFloat));
110 _ItemTags.put("l", Item.class.getMethod("setLineIDs", pString));
111 _ItemTags.put("c", Item.class
112 .getMethod("setConstraintIDs", pString));
113
114 // Lines and constraints are created differently
115 _ItemTags.put("L", Line.class.getMethod("setStartItem", pItem));
116 // _ItemTags.put("g", null);
117
118 _ItemTags.put("C", Constraint.class.getMethod("getID",
119 (Class[]) null));
120 // _ItemTags.put("s2", null);
121 } catch (SecurityException e) {
122 // TODO Auto-generated catch block
123 e.printStackTrace();
124 } catch (NoSuchMethodException e) {
125 // TODO Auto-generated catch block
126 e.printStackTrace();
127 }
128 }
129
130 /**
131 * Determines whether a string begins with a KMS tag.
132 *
133 * @param s
134 * a line of text
135 * @return true if s begins with a KMS tag
136 */
137 private static boolean isValidLine(String s) {
138 return s.length() >= 3 && s.charAt(0) == '+' && s.charAt(2) == '+'
139 && Character.isLetter(s.charAt(1));
140 }
141
142 /**
143 * Reads a KMS file with the given name from disk.
144 *
145 * @param frameName
146 * the name of the Frame to read in from a file.
147 * @return A new Frame object that contains any Items described in the file.
148 * @throws IOException
149 * Any exceptions occured by the BufferedReader.
150 */
151 public Frame readFrame(String fullPath) throws IOException {
152 _reader = new BufferedReader(new FileReader(fullPath));
153 Frame newFrame = null;
154 String next = "";
155 boolean header = true;
156 // clear hashmap and line list
157 _data.clear();
158 _linePoints.clear();
159 // First read the header
160 try {
161 while (_reader.ready()) {
162 next = _reader.readLine();
163 if (isValidLine(next)) {
164 if (header) {
165 // Create the frame when the first +S+ is reached
166 // And set the flag to indicate the end of the header
167 if (getTag(next).equals("S")) {
168 newFrame = readFrameClass();
169 header = false;
170 _data.clear();
171 processBodyLine(newFrame, next);
172 } else
173 processHeaderLine(next);
174 } else
175 processBodyLine(newFrame, next);
176 } else if (next.startsWith(SessionStats.ACTIVE_TIME_ATTRIBUTE)) {
177 try {
178 String value = next.substring(SessionStats.ACTIVE_TIME_ATTRIBUTE.length()).trim();
179 newFrame.setActiveTime(value);
180 } catch (Exception e) {
181 }
182
183 } else if (next.startsWith(SessionStats.DARK_TIME_ATTRIBUTE)) {
184 try {
185 String value = next.substring(SessionStats.DARK_TIME_ATTRIBUTE.length()).trim();
186 newFrame.setDarkTime(value);
187 } catch (Exception e) {
188 }
189
190 }
191 }
192 } catch (Exception e) {
193 System.out.println("Error reading bodyLine: " + next + " "
194 + e.getMessage());
195 e.printStackTrace();
196 }
197
198 // if the frame contains no items (Default.0 does this)
199 if (newFrame == null)
200 newFrame = readFrameClass();
201
202 _reader.close();
203 if (newFrame != null) {
204 newFrame.refreshItemPermissions();
205 newFrame.setChanged(false);
206 }
207 return newFrame;
208 }
209
210 // stores the data of the Item to be created next
211 private LinkedHashMap<String, String> _data = new LinkedHashMap<String, String>(
212 20);
213
214 // creates an item from the last batch of data read from the file
215 private Item createItem() {
216 // creates an item based on the information in the hashmap
217 try {
218 return readItemClass();
219 } catch (IOException e) {
220 // TODO Auto-generated catch block
221 e.printStackTrace();
222 }
223
224 return null;
225 }
226
227 // Stores points used when constructing lines
228 private HashMap<Integer, Item> _linePoints = new HashMap<Integer, Item>();
229
230 /**
231 * Adds any lines stored in _lineStarts and _lineEnds to the given Frame.
232 *
233 * @param frame
234 * The Frame to add the newly created Line objects to.
235 */
236 private Line createLine() {
237 String s = _data.get("L");
238 _data.remove("L");
239
240 // get the line ID and type
241 java.awt.Point idtype = separateValues(s);
242
243 // get the end points
244 s = _data.get("s");
245 _data.remove("s");
246
247 java.awt.Point startend = separateValues(s);
248
249 int start = startend.x;
250 int end = startend.y;
251
252 if (_linePoints.get(start) != null && _linePoints.get(end) != null) {
253 Line line = new Line(_linePoints.get(start), _linePoints.get(end),
254 idtype.x);
255 return line;
256 }
257
258 // System.out.println(_linePoints.size());
259 // for (int i : _linePoints.keySet())
260 // System.out.println(i + " - "
261 // + _linePoints.get(i).getClass().getSimpleName());
262 //
263 // System.out.println("Error: Line " + idtype.x
264 // + " has missing end point(s) + (Looking for: " + start + " , "
265 // + end + ")");
266 return null;
267 }
268
269 /*
270 * Creates a constraint from the data containted in _data
271 */
272 private void createConstraint() {
273 java.awt.Point idtype = separateValues(_data.get("C"));
274 java.awt.Point startend = separateValues(_data.get("s"));
275
276 Item a = _linePoints.get(startend.x);
277 Item b = _linePoints.get(startend.y);
278
279 new Constraint(a, b, idtype.x, idtype.y);
280 }
281
282 /**
283 * Processes the body section of the KMS file, which contains all Items
284 *
285 * @param frame
286 * The Frame to add any created Items to.
287 * @param line
288 * The line of text read in from the file to process.
289 */
290 private void processBodyLine(Frame frame, String line) {
291 // separate the tag from the value
292 String tag = getTag(line);
293 line = getValue(line);
294
295 // if this is the start of a new item, a line, or a constraint
296 // then add the last item to the frame
297 if (tag.charAt(0) == 'S' || tag.charAt(0) == 'L'
298 || tag.charAt(0) == 'C') {
299 frame.addItem(createItem());
300
301 _data.clear();
302 _data.put(tag, line);
303 return;
304 }
305
306 // if this is the end of the file, then add the last item to the frame
307 if (tag.charAt(0) == 'Z') {
308 frame.addItem(createItem());
309 _data.clear();
310
311 return;
312 }
313
314 // check for duplicate tags (multiple lines of text)
315 String newtag = tag;
316 int i = 0;
317
318 // only executes if there are duplicate tags for this Item
319 while (_data.containsKey(newtag)) {
320 newtag = tag + i;
321 i++;
322 }
323
324 // All values are stored in a HashMap until the end of the Item is
325 // found.
326 _data.put(newtag, line);
327 }
328
329 private static String getTag(String line) {
330 assert (line.charAt(0) == '+');
331 assert (line.length() > 2);
332 return line.substring(1, 2);
333 }
334
335 private static String getValue(String line) {
336 assert (line.charAt(0) == '+');
337 if (line.length() > 4)
338 return line.substring(4);
339 else
340 return "";
341 }
342
343 /**
344 * Reads the header section of the file, which contains information about
345 * the Frame.
346 *
347 * @param frame
348 * The Frame to assign the read values to.
349 * @param line
350 * The line from the file to process.
351 * @return False if the end of the header has been reached, True otherwise.
352 */
353 private void processHeaderLine(String line) throws IOException {
354 // first separate the tag from the text
355 String tag = getTag(line);
356 String value = getValue(line);
357
358 if (tag.equals("Z"))
359 return;
360
361 if (_FrameTags.get(tag) == null) {
362 if (!tag.equals("t") && !tag.equals("v"))
363 FrameGraphics.ErrorMessage("Tag '" + tag + "' in '" + line
364 + "' is not supported.");
365 return;
366 }
367
368 _data.put(tag, value);
369 }
370
371 // returns two ints separated by a space from the given String
372 private java.awt.Point separateValues(String line) {
373 int x = Integer.parseInt(line.substring(0, line.indexOf(" ")));
374 int y = Integer.parseInt(line.substring(line.indexOf(" ") + 1));
375
376 return new java.awt.Point(x, y);
377 }
378
379 private Frame readFrameClass() throws IOException {
380 if (_data.size() == 0) {
381 FrameGraphics
382 .ErrorMessage("IO Error: File contains no valid KMS lines.");
383 return null;
384 }
385
386 Frame toMake = new Frame();
387 Iterator<String> it = _data.keySet().iterator();
388
389 while (it.hasNext()) {
390 String datatag = it.next();
391
392 Method toRun = _FrameTags.get(datatag);
393 Object[] vals = Conversion.Convert(toRun, _data.get(datatag));
394 try {
395 toRun.invoke(toMake, vals);
396 } catch (IllegalArgumentException e) {
397 // TODO Auto-generated catch block
398 e.printStackTrace();
399 } catch (IllegalAccessException e) {
400 // TODO Auto-generated catch block
401 e.printStackTrace();
402 } catch (InvocationTargetException e) {
403 // TODO Auto-generated catch block
404 e.printStackTrace();
405 }
406 }
407
408 return toMake;
409 }
410
411 @SuppressWarnings("unchecked")
412 private Item readItemClass() throws IOException {
413 Iterator<String> tags = _data.keySet().iterator();
414 Class toCreate = null;
415
416 // loop through all attributes read in for this item
417 while (tags.hasNext()) {
418 String next = tags.next();
419 Method m = _ItemTags.get(next);
420 if (m != null && _ItemTags.get(next + "2") == null) {
421 if (!m.getDeclaringClass().getSimpleName().equals("Item")) {
422 toCreate = m.getDeclaringClass();
423 break;
424 }
425 }
426 }
427
428 if (toCreate == null) {
429 if (_data.size() > 0)
430 toCreate = Dot.class;
431 else
432 return null;
433 }
434
435 Item toMake = null;
436
437 try {
438 if (toCreate == Line.class)
439 toMake = createLine();
440 else if (toCreate == Constraint.class) {
441 createConstraint();
442 return null;
443 } else if (toCreate == Item.class && _data.size() == 2) {
444 toCreate = Dot.class;
445 } else if (toCreate == Item.class) {
446 for (String s : _data.keySet())
447 System.out.println(s + " -> " + _data.get(s));
448 return null;
449 } else {
450 Object[] params = { -1 };
451 Constructor con = toCreate.getConstructor(int.class);
452 toMake = (Item) con.newInstance(params);
453 }
454 } catch (InstantiationException e) {
455 // TODO Auto-generated catch block
456 e.printStackTrace();
457 } catch (IllegalAccessException e) {
458 // TODO Auto-generated catch block
459 e.printStackTrace();
460 } catch (IllegalArgumentException e) {
461 // TODO Auto-generated catch block
462 e.printStackTrace();
463 } catch (InvocationTargetException e) {
464 // TODO Auto-generated catch block
465 e.printStackTrace();
466 } catch (SecurityException e) {
467 // TODO Auto-generated catch block
468 e.printStackTrace();
469 } catch (NoSuchMethodException e) {
470 // TODO Auto-generated catch block
471 e.printStackTrace();
472 }
473
474 if (toMake == null)
475 return null;
476
477 Iterator<String> it = _data.keySet().iterator();
478 String last = "";
479
480 int count = 0;
481
482 while (it.hasNext()) {
483 String tag = it.next();
484 if (_data.containsKey("" + tag.charAt(0) + count)) {
485 if (last.length() == 0)
486 last = _data.get(tag);
487 else
488 last += "\n" + _data.get(tag);
489
490 count++;
491 } else {
492 Method toRun = _ItemTags.get("" + tag.charAt(0));
493 if (toRun == null)
494 System.out.println("Error accessing tag method: "
495 + tag.charAt(0));
496 Object[] vals;
497 if (last.length() > 0)
498 vals = Conversion.Convert(toRun, last + "\n"
499 + _data.get(tag));
500 else
501 vals = Conversion.Convert(toRun, _data.get(tag));
502
503 try {
504 if (vals != null) {
505 toRun.invoke(toMake, vals);
506 }
507 } catch (IllegalArgumentException e) {
508 // TODO Auto-generated catch block
509 e.printStackTrace();
510 } catch (IllegalAccessException e) {
511 // TODO Auto-generated catch block
512 e.printStackTrace();
513 } catch (InvocationTargetException e) {
514 // TODO Auto-generated catch block
515 e.printStackTrace();
516 } catch (ClassCastException e) {
517 System.out.println(toRun.getName());
518 e.printStackTrace();
519 }
520
521 count = 0;
522 last = "";
523 }
524
525 }
526
527 if (!(toMake instanceof Line))
528 _linePoints.put(toMake.getID(), toMake);
529
530 return toMake;
531 }
532
533 public static int getVersion(String fullpath) {
534 try {
535 BufferedReader reader = new BufferedReader(new FileReader(fullpath));
536 String next = "";
537 // First read the header lines until we get the version number
538 while (reader.ready() && (next = reader.readLine()) != null) {
539 if (isValidLine(next)) {
540 char tag = getTag(next).charAt(0);
541 String value = getValue(next);
542 if (tag == 'V')
543 return Integer.parseInt(value);
544 else if (tag == 'Z')
545 return 0;
546 }
547 }
548 } catch (Exception e) {
549 }
550 return 0;
551 }
552}
Note: See TracBrowser for help on using the repository browser.