source: trunk/src/org/expeditee/gui/AttributeUtils.java@ 98

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

Fixed a couple of minor bugs that popped up in the demo

File size: 22.5 KB
Line 
1package org.expeditee.gui;
2
3import java.awt.Color;
4import java.awt.Font;
5import java.awt.Point;
6import java.lang.reflect.InvocationTargetException;
7import java.lang.reflect.Method;
8import java.util.HashMap;
9import java.util.LinkedList;
10import java.util.List;
11
12import org.expeditee.io.Conversion;
13import org.expeditee.items.Item;
14import org.expeditee.items.Justification;
15import org.expeditee.items.Text;
16
17/**
18 * This class provides the methods to extract and set attributes of Items and
19 * Frames. These methods are called when a user merges a text item with
20 * <code>Attribute: Value</code> pairs.
21 *
22 * @author jdm18
23 *
24 */
25public class AttributeUtils {
26
27 public static final char SEPARATOR_CHAR = ':';
28
29 private static final String SEPARATOR_STRING = SEPARATOR_CHAR + " ";
30
31 private static final int GET_LENGTH = "get".length();
32
33 private static int SET_LENGTH = "set".length();
34
35 // List of method names to ignore when searching for a match
36 private static List<Method> _GetMethods = null;
37
38 private static HashMap<String, Method> _SetMethods = null;
39
40 // List of attributes which are ignored when copying.
41 private static List<String> _Ignore = null;
42
43 // List of method names to show in extraced lists even when they return
44 // null
45 // (Null is often used to indicate the default value is used)
46 private static List<Method> _AllowNull = null;
47
48 private static List<String> _ExtractIgnore = null;
49
50 // private static HashMap<String, String> _Abbreviations = null;
51
52 /**
53 * Initialises the _Ignore and _AllowNull lists.
54 */
55 private static void initLists() {
56
57 Class[] param = {};
58
59 try {
60 // TODO load these in with reflection...
61 // Set the shortcuts with annotation tags on the methods
62 _Ignore = new LinkedList<String>();
63 _Ignore.add("date");
64 _Ignore.add("datecreated");
65 _Ignore.add("d");
66 _Ignore.add("link");
67 _Ignore.add("l");
68 _Ignore.add("action");
69 _Ignore.add("a");
70 _Ignore.add("position");
71 _Ignore.add("pos");
72 _Ignore.add("p");
73 _Ignore.add("x");
74 _Ignore.add("y");
75
76 _ExtractIgnore = new LinkedList<String>();
77 _ExtractIgnore.add("x");
78 _ExtractIgnore.add("y");
79
80 _AllowNull = new LinkedList<Method>();
81 _AllowNull.add(Item.class.getMethod("getColor", param));
82 _AllowNull.add(Item.class.getMethod("getBackgroundColor", param));
83
84 _AllowNull.add(Frame.class.getMethod("getBackgroundColor", param));
85 _AllowNull.add(Frame.class.getMethod("getForegroundColor", param));
86
87 _GetMethods = new LinkedList<Method>();
88 _GetMethods.add(Item.class.getMethod("getDateCreated", param));
89
90 _GetMethods.add(Item.class.getMethod("getColor", param));
91 _GetMethods.add(Item.class.getMethod("getBackgroundColor", param));
92 _GetMethods.add(Item.class.getMethod("getAction", param));
93 _GetMethods.add(Item.class.getMethod("getData", param));
94 _GetMethods.add(Item.class.getMethod("getLink", param));
95 _GetMethods.add(Item.class.getMethod("getFillColor", param));
96 _GetMethods.add(Item.class.getMethod("getFillPattern", param));
97 _GetMethods.add(Item.class.getMethod("getThickness", param));
98
99 _GetMethods.add(Item.class.getMethod("getOwner", param));
100 _GetMethods.add(Item.class.getMethod("getLinkMark", param));
101 _GetMethods.add(Item.class.getMethod("getActionMark", param));
102
103 _GetMethods
104 .add(Item.class.getMethod("getActionCursorEnter", param));
105 _GetMethods
106 .add(Item.class.getMethod("getActionCursorLeave", param));
107 _GetMethods.add(Item.class.getMethod("getActionEnterFrame", param));
108 _GetMethods.add(Item.class.getMethod("getActionLeaveFrame", param));
109
110 _GetMethods.add(Item.class.getMethod("getTopShadowColor", param));
111 _GetMethods
112 .add(Item.class.getMethod("getBottomShadowColor", param));
113 _GetMethods.add(Item.class.getMethod("getArrow", param));
114
115 _GetMethods.add(Item.class.getMethod("getLinePattern", param));
116 _GetMethods.add(Item.class.getMethod("getLinkFrameset", param));
117 _GetMethods.add(Item.class.getMethod("getLinkTemplate", param));
118 _GetMethods.add(Item.class.getMethod("getPosition", param));
119 _GetMethods.add(Item.class.getMethod("getX", param));
120 _GetMethods.add(Item.class.getMethod("getY", param));
121
122 _GetMethods.add(Text.class.getMethod("getFamily", param));
123 _GetMethods.add(Text.class.getMethod("getFontStyle", param));
124 _GetMethods.add(Text.class.getMethod("getJustification", param));
125 _GetMethods.add(Text.class.getMethod("getWidth", param));
126 _GetMethods.add(Item.class.getMethod("getSize", param));
127
128 _GetMethods.add(Frame.class.getMethod("getOwner", param));
129 _GetMethods.add(Frame.class.getMethod("getProtection", param));
130 _GetMethods.add(Frame.class.getMethod("getDateCreated", param));
131 _GetMethods.add(Frame.class.getMethod("getLastModifyUser", param));
132 _GetMethods.add(Frame.class.getMethod("getLastModifyDate", param));
133 _GetMethods.add(Frame.class.getMethod("getForegroundColor", param));
134 _GetMethods.add(Frame.class.getMethod("getBackgroundColor", param));
135
136 Class[] pPoint = { Point.class };
137 Class[] pString = { String.class };
138 Class[] pInt = { int.class };
139 Class[] pFloat = { float.class };
140 Class[] pColor = { Color.class };
141 Class[] pBool = { boolean.class };
142 Class[] pArrow = { int.class, double.class };
143 Class[] pList = { List.class };
144 Class[] pIntArray = { int[].class };
145 Class[] pJustification = { Justification.class };
146
147 _SetMethods = new HashMap<String, Method>();
148 _SetMethods.put("x", Item.class.getMethod("setX", pFloat));
149 _SetMethods.put("y", Item.class.getMethod("setY", pFloat));
150 _SetMethods.put("position", Item.class.getMethod("setPosition",
151 pPoint));
152 _SetMethods.put("p", Item.class.getMethod("setPosition", pPoint));
153 _SetMethods.put("pos", Item.class.getMethod("setPosition", pPoint));
154 _SetMethods.put("thickness", Item.class.getMethod("setThickness",
155 pFloat));
156 _SetMethods.put("t", Item.class.getMethod("setThickness", pFloat));
157
158 _SetMethods.put("color", Item.class.getMethod("setColor", pColor));
159 _SetMethods.put("c", Item.class.getMethod("setColor", pColor));
160
161 _SetMethods.put("backgroundcolor", Item.class.getMethod(
162 "setBackgroundColor", pColor));
163 _SetMethods.put("bgc", Item.class.getMethod("setBackgroundColor",
164 pColor));
165
166 _SetMethods
167 .put("action", Item.class.getMethod("setActions", pList));
168 _SetMethods.put("a", Item.class.getMethod("setActions", pList));
169 _SetMethods.put("d", Item.class.getMethod("setData", pList));
170 _SetMethods.put("data", Item.class.getMethod("setData", pList));
171
172 _SetMethods.put("link", Item.class.getMethod("setLink", pString));
173 _SetMethods.put("l", Item.class.getMethod("setLink", pString));
174
175 _SetMethods.put("fillcolor", Item.class.getMethod("setFillColor",
176 pColor));
177 _SetMethods.put("fc", Item.class.getMethod("setFillColor", pColor));
178
179 _SetMethods.put("fillpattern", Item.class.getMethod(
180 "setFillPattern", pString));
181 _SetMethods.put("fp", Item.class.getMethod("setFillPattern",
182 pString));
183
184 _SetMethods.put("owner", Item.class.getMethod("setOwner", pString));
185 _SetMethods.put("linkmark", Item.class.getMethod("setLinkMark",
186 pBool));
187 _SetMethods.put("lm", Item.class.getMethod("setLinkMark", pBool));
188 _SetMethods.put("actionmark", Item.class.getMethod("setActionMark",
189 pBool));
190 _SetMethods.put("am", Item.class.getMethod("setActionMark", pBool));
191
192 _SetMethods.put("actioncursorenter", Item.class.getMethod(
193 "setActionCursorEnter", pList));
194 _SetMethods.put("actioncursorleave", Item.class.getMethod(
195 "setActionCursorLeave", pList));
196 _SetMethods.put("actionenterframe", Item.class.getMethod(
197 "setActionEnterFrame", pList));
198 _SetMethods.put("actionleaveframe", Item.class.getMethod(
199 "setActionLeaveFrame", pList));
200
201 _SetMethods.put("topshadow", Item.class.getMethod(
202 "setTopShadowColor", pColor));
203 _SetMethods.put("bottomshadow", Item.class.getMethod(
204 "setBottomShadowColor", pColor));
205 _SetMethods.put("arrow", Item.class.getMethod("setArrow", pArrow));
206
207 _SetMethods.put("linepattern", Item.class.getMethod(
208 "setLinePattern", pIntArray));
209 _SetMethods.put("lp", Item.class.getMethod("setLinePattern",
210 pIntArray));
211
212 _SetMethods.put("linkframeset", Item.class.getMethod(
213 "setLinkFrameset", pString));
214 _SetMethods.put("lf", Item.class.getMethod("setLinkFrameset",
215 pString));
216 _SetMethods.put("linktemplate", Item.class.getMethod(
217 "setLinkTemplate", pString));
218 _SetMethods.put("lt", Item.class.getMethod("setLinkTemplate",
219 pString));
220
221 _SetMethods.put("family", Text.class
222 .getMethod("setFamily", pString));
223 _SetMethods.put("face", Text.class.getMethod("setFontStyle",
224 pString));
225 _SetMethods.put("fontstyle", Text.class.getMethod("setFontStyle",
226 pString));
227 _SetMethods.put("justification", Text.class.getMethod(
228 "setJustification", pJustification));
229 _SetMethods.put("width", Text.class.getMethod("setWidth", pInt));
230 _SetMethods.put("size", Item.class.getMethod("setSize", pInt));
231 _SetMethods.put("s", Item.class.getMethod("setSize", pInt));
232
233 _SetMethods.put("foregroundcolor", Frame.class.getMethod(
234 "setForegroundColor", pColor));
235 _SetMethods.put("fgc", Frame.class.getMethod("setForegroundColor",
236 pColor));
237 _SetMethods.put("backgroundcolor0", Frame.class.getMethod(
238 "setBackgroundColor", pColor));
239 _SetMethods.put("bgc0", Frame.class.getMethod("setBackgroundColor",
240 pColor));
241 _SetMethods.put("protection", Frame.class.getMethod(
242 "setProtection", pString));
243
244 } catch (SecurityException e) {
245 // TODO Auto-generated catch block
246 e.printStackTrace();
247 } catch (NoSuchMethodException e) {
248 // TODO Auto-generated catch block
249 e.printStackTrace();
250 }
251 }
252
253 /**
254 * Extracts a list of attributes from the given Object. Any method that
255 * starts with <code>get</code>, takes no arguments and is not found in
256 * the Ignore list will be run, All the attributes are then put into a Text
257 * Item of the form <Name>:<Value> If the value returned by the get method
258 * is null, then the attribute will not be included, unless the name of the
259 * method is found in the AllowNull list.
260 *
261 * @param toExtract
262 * The Object from which to extract the attributes
263 * @return A Text Item containing the extracted Attributes.
264 */
265 public static Item extractAttributes(Object toExtract) {
266 if (toExtract == null)
267 return null;
268
269 // ensure the lists are populated
270 if (_Ignore == null)
271 initLists();
272
273 // StringBuffer to store all the extracted Attribute:Value pairs
274 StringBuffer attributes = new StringBuffer();
275
276 // iterate through the list of methods
277 for (Method m : _GetMethods) {
278
279 // Make sure the classes of the methods match the item
280 if (m.getDeclaringClass().isAssignableFrom(toExtract.getClass())) {
281 try {
282 Object o = m.invoke(toExtract, (Object[]) null);
283
284 if (o == null) {
285 // methods that return null are only included if they
286 // are in the AllowNull list
287 if (_AllowNull.contains(m)) {
288 String name = m.getName().substring(GET_LENGTH)
289 .toLowerCase();
290 if (name.equals("color"))
291 o = "default";
292 else if (name.equals("backgroundcolor"))
293 o = "transparent";
294 else if (name.equals("foregroundcolor"))
295 o = "auto";
296 else
297 o = "";
298 } else {
299 continue;
300 }
301 }
302 // skip methods that are in the ignore lists
303 if (_ExtractIgnore.contains(m.getName().substring(
304 GET_LENGTH).toLowerCase())) {
305 continue;
306 }
307
308 if (o instanceof Integer) {
309 Integer i = (Integer) o;
310 if (i == Item.DEFAULT_INTEGER)
311 continue;
312 if (m.getName().endsWith("Justification")
313 && ((Justification) o).toString() != null)
314 o = ((Justification) o).toString();
315 // -1 indicates default value
316 else
317 o = i;
318 } else if (o instanceof Float) {
319 // -1 indicates default value
320 if (((Float) o) < 0.0001)
321 continue;
322 } else if (o instanceof Double) {
323 // -1 indicates default value
324 if (((Double) o) < 0.0001)
325 continue;
326 } else if (o instanceof Color) {
327 // converts the color to the Expeditee code
328 o = Conversion.getExpediteeColorCode((Color) o);
329 if (o == null)
330 continue;
331 } else if (o instanceof Point) {
332 Point p = (Point) o;
333 o = (int) p.getX() + " " + (int) p.getY();
334 } else if (o instanceof Font) {
335 Font f = (Font) o;
336
337 String s = f.getName() + "-";
338 if (f.isPlain())
339 s += "Plain";
340
341 if (f.isBold())
342 s += "Bold";
343
344 if (f.isItalic())
345 s += "Italic";
346
347 s += "-" + f.getSize();
348 o = s;
349 } else if (o instanceof Text) {
350 o = ((Text) o).getFirstLine();
351 } else if (o instanceof List) {
352 List list = (List) o;
353 for (Object ob : list)
354 attributes
355 .append(m.getName().substring(GET_LENGTH))
356 .append(SEPARATOR_STRING).append(ob)
357 .append("\n");
358 continue;
359 } else if (o instanceof int[]) {
360 StringBuffer sb = new StringBuffer();
361 int[] values = (int[]) o;
362 for (int i = 0; i < values.length; i++) {
363 sb.append(values[i]).append(' ');
364 }
365 sb.deleteCharAt(attributes.length() - 1);
366 o = sb.toString();
367 } else if (o instanceof Boolean) {
368 // true is the default for boolean values
369 if (((Boolean) o).booleanValue())
370 continue;
371 }
372 // Append the attributes
373 attributes.append(m.getName().substring(GET_LENGTH))
374 .append(SEPARATOR_STRING).append(o).append("\n");
375 } catch (Exception e) {
376 // TODO Auto-generated catch block
377 e.printStackTrace();
378 }
379 }
380 }
381
382 // if no attributes were extracted
383 if (attributes.length() <= 0)
384 return null;
385
386 while (attributes.charAt(attributes.length() - 1) == '\n')
387 attributes.delete(attributes.length() - 1, attributes.length());
388
389 // create the text Item
390 Frame current = DisplayIO.getCurrentFrame();
391 Item attribs = current.getStatsTextItem(attributes.toString());
392 return attribs;
393 }
394
395 /**
396 * Attempts to set the attribute in the given attribute: value pair. The
397 * value string should be formatted as follows:
398 * <code> Attribute: Value </code> Multiple values can be used if they are
399 * separated by spaces
400 *
401 * @param toSet
402 * The Item or Frame to set the attribute of
403 * @param attribs
404 * The Text item that contains the list of attributes to set
405 * @return True if the attribute(s) were sucessfully set, false otherwise
406 */
407 public static boolean setAttribute(Object toSet, Text attribs) {
408 // error checking
409 if (toSet == null || attribs == null)
410 return false;
411
412 if (_Ignore == null)
413 initLists();
414
415 // get the list of attribute: value pairs
416 List<String> values = attribs.getTextList();
417 // if no pairs exist, we are done
418 if (values.size() == 0
419 || (values.size() == 1 && values.get(0).length() == 0)) {
420 return false;
421 }
422
423 // loop through all attribute: value pairs
424 for (int i = 0; i < values.size(); i++) {
425 StringBuffer v = new StringBuffer(values.get(i));
426
427 // remove the annotation mark (if applicable)
428 if (v.indexOf("@") == 0)
429 v = v.deleteCharAt(0);
430
431 // check if the next string is another attribute to merge or a
432 // continuation
433 while (i < values.size() - 1) {
434 StringBuffer next = new StringBuffer(values.get(i + 1));
435
436 // if the next String has a colon, then it may be another
437 // attribute
438 if (next.indexOf("" + SEPARATOR_CHAR) >= 0) {
439 // if the attribute is the same as v, then it is a
440 // continuation
441 if (v.indexOf(getAttribute(next.toString())) == 0) {
442 // strip the attribute from next
443 next = new StringBuffer(getValue(next.toString()));
444 // if the attribute is not the same, then it may be a
445 // new method
446 } else {
447 // if this is indeed a method, then leave the while loop
448 // if(_SetMethods.containsKey(StripFromColon(next.toString()).toLowerCase())){
449 break;
450 // }
451 }
452 }
453
454 v.append("\n").append(next);
455 i++;
456 }
457
458 if (v.length() > 0
459 && !setAttribute(toSet, v.toString(), values.size() > 1)) {
460 // if no other attributes have been set
461 if (i == 0)
462 return false;
463 // otherwise, this is a list of attributes, so continue
464 else {
465 String stripped = getAttribute(v.toString());
466 if (stripped == null) {
467 // This happens when there is an attribute at the start
468 // Then a bunch of plain text
469 return false;
470 } else if (_Ignore.contains(stripped)) {
471 return false;
472 } else if (!(_SetMethods.containsKey(stripped))) {
473 // Display an error message if its not in our list of
474 // attributes to ignore when copying
475 FrameGraphics.WarningMessage("Attribute: '"
476 + getAttribute(v.toString())
477 + "' does not exist.");
478 } else {
479 String types = "";
480 for (Class c : _SetMethods.get(stripped)
481 .getParameterTypes())
482 types += c.getSimpleName() + " ";
483 FrameGraphics.WarningMessage("Wrong arguments for: '"
484 + getAttribute(v.toString()) + "' expecting "
485 + types.trim() + " found '"
486 + getValue(v.toString()) + "'");
487 }
488 }
489 } else if (v.length() == 0)
490 return false;
491 }
492
493 return true;
494 }
495
496 private static boolean setAttribute(Object toSet, String value,
497 boolean isAttributeList) {
498 // separate attribute and value from string
499 String attribute = getAttribute(value);
500 //Check that an attribute was found
501 if(attribute == null)
502 return false;
503 attribute = attribute.toLowerCase();
504
505 value = getValue(value);
506 assert(value != null);
507
508 // Some properties are ignored when multiple attributes are being set on
509 // an item at the same time
510 if (isAttributeList && _Ignore.contains(attribute)) {
511 // System.out.println("Attribute ignored: " + attribute);
512 return true;
513 }
514
515 // Separate multiple values if required
516 Method toRun = _SetMethods.get( attribute);
517
518 // if this is not the name of a method, it may be the name of an agent
519 if (toRun == null) {
520 // System.out.println("Attrib not found for: " + attribute);
521 return false;
522 }
523
524 // if there are duplicate methods with the same name
525 List<Method> possibles = new LinkedList<Method>();
526 if (toRun.getDeclaringClass().isInstance(toSet))
527 possibles.add(toRun);
528 int i = 0;
529 while (_SetMethods.containsKey(attribute + i)) {
530 if (_SetMethods.get(attribute + i).getDeclaringClass()
531 .isAssignableFrom(toSet.getClass()))
532 possibles.add(_SetMethods.get(attribute + i));
533 i++;
534 }
535
536 for (Method possible : possibles) {
537 Object current = null;
538 Object[] param = {};
539 // find the corresponding get method for this set method
540 // and get the current value of the attribute
541 for (Method m : _GetMethods) {
542 if (m.getDeclaringClass().isAssignableFrom(toSet.getClass())
543 && m.getName().substring(GET_LENGTH).equals(
544 possible.getName().substring(SET_LENGTH))) {
545 try {
546 current = m.invoke(toSet, param);
547 } catch (IllegalArgumentException e) {
548 // TODO Auto-generated catch block
549 e.printStackTrace();
550 } catch (IllegalAccessException e) {
551 // TODO Auto-generated catch block
552 e.printStackTrace();
553 } catch (InvocationTargetException e) {
554 // TODO Auto-generated catch block
555 e.printStackTrace();
556 }
557 break;
558 }
559
560 }
561
562 try {
563 Object[] params = Conversion.Convert(possible, value, current);
564
565 try {
566 possible.invoke(toSet, params);
567 return true;
568 } catch (IllegalArgumentException e) {
569 // TODO Auto-generated catch block
570 e.printStackTrace();
571 } catch (IllegalAccessException e) {
572 // TODO Auto-generated catch block
573 e.printStackTrace();
574 } catch (InvocationTargetException e) {
575 FrameGraphics.DisplayMessage(toSet.getClass()
576 .getSimpleName()
577 + " type does not support that attribute.");
578 // e.printStackTrace();
579 }
580 } catch (NumberFormatException e) {
581
582 }
583 }
584
585 return false;
586 }
587
588 /**
589 * Returns the part of the given string that is after the attribute value
590 * pair separator. If that character is not there it returns empty
591 * if it is an annotation item or the entire string if it is not.
592 *
593 * @param attributeValuePair
594 * the string to get the value from.
595 * @return the value from the attribute value pair.
596 */
597 public static String getValue(String toStrip) {
598 assert (toStrip != null);
599
600 toStrip = toStrip.trim();
601 if (toStrip.length() == 0)
602 return "";
603
604 int ind = toStrip.lastIndexOf(SEPARATOR_CHAR);
605 int lineSeparator = toStrip.indexOf(Character.LINE_SEPARATOR, ind);
606 // If it is an annotation item return the empty string
607 // Annotation items can not be values only
608 if (ind < 0 && toStrip.charAt(0) == '@') {
609 return "";
610 }
611 //If its one line then our value goes to the end of the string
612 if(lineSeparator < 0)
613 lineSeparator = toStrip.length();
614
615 return toStrip.substring(ind + 1, lineSeparator).trim();
616 }
617
618 /**
619 * Returns the part of the given string that is before the attribute value
620 * pair separator, or null if the given String does not include the
621 * separator.
622 *
623 * @param attributeValuePair
624 * The String to strip
625 * @return the attribute if there is one or null if there is not
626 */
627 public static String getAttribute(String attributeValuePair) {
628 attributeValuePair = attributeValuePair.trim();
629
630 int ind = attributeValuePair.indexOf(SEPARATOR_CHAR);
631 if (ind < 1)
632 return null;
633 // If its an annotation there must be no space between the @ and colon
634 // and the first character after the annotation must be a letter
635 if (attributeValuePair.charAt(0) == '@') {
636 if (!Character.isLetter(attributeValuePair.charAt(1)))
637 return null;
638 for (int i = 2; i < ind; i++) {
639 if (!Character.isLetterOrDigit(attributeValuePair.charAt(i)))
640 return null;
641 }
642 }
643
644 attributeValuePair = attributeValuePair.substring(0, ind).trim();
645
646 return attributeValuePair;
647 }
648
649 /**
650 * Replaces the current value for the text item with the new value.
651 *
652 * @param text
653 * the item whos value is to be changed
654 * @param newValue
655 * the new value for the item
656 */
657 public static void replaceValue(Text text, String newValue) {
658 assert (newValue != null);
659
660 String oldText = text.getFirstLine();
661 String restOfText = text.getText().substring(oldText.length());
662 String attribute = getAttribute(oldText);
663
664 if (attribute == null)
665 attribute = text.getText().trim();
666
667 text.setText(attribute + SEPARATOR_STRING + newValue + restOfText);
668 }
669
670 /**
671 * Gets the value from an attribute value pair as a double.
672 *
673 * @param attributeValuePair
674 * the text to get the value from
675 * @return the double value or null if there is none
676 */
677 public static Double getDoubleValue(String attributeValuePair) {
678 String value = getValue(attributeValuePair);
679
680 assert (value != null);
681
682 try {
683 return Double.parseDouble(value);
684 } catch (Exception e) {
685 }
686 return null;
687 }
688}
Note: See TracBrowser for help on using the repository browser.