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

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

Completed several tasks specified by Rob...

  1. Changing the resize for single text items to use the text items origin as the origin for the resize.
  1. Added message linking to documentation for SIMPLE statements when a statement is used incorrectly.
  1. Other minor changes...
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 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("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.