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

Last change on this file since 584 was 584, checked in by jts21, 11 years ago

Make FrameReader an interface and move it's HashMap to DefaultFrameReader

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