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

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

Fix frame attribute setting (was using item attribute list where frame list should have been used)

File size: 27.7 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.DotType;
14import org.expeditee.items.Item;
15import org.expeditee.items.Justification;
16import org.expeditee.items.PermissionPair;
17import org.expeditee.items.Picture;
18import org.expeditee.items.Text;
19import org.expeditee.simple.IncorrectTypeException;
20
21/**
22 * This class provides the methods to extract and set attributes of Items and
23 * Frames. These methods are called when a user merges a text item with
24 * <code>Attribute: Value</code> pairs.
25 *
26 * @author jdm18
27 *
28 */
29public class AttributeUtils {
30
31 public static final class Attribute {
32 public final String displayName;
33 public final Method getter;
34 public final Method setter;
35
36 public Attribute(String displayName, Method getter, Method setter) {
37 this.displayName = displayName;
38 this.getter = getter;
39 this.setter = setter;
40 }
41 }
42
43 public static final class AttributeSet {
44
45 // the internal hashmap
46 private final HashMap<String, Attribute> map;
47 // a list of keys in the order they were added (used to make attribute extraction consistent)
48 public final List<String> keys;
49
50 public AttributeSet(int size) {
51 map = new HashMap<String, Attribute>(size);
52 keys = new LinkedList<String>();
53 }
54
55 public void put(String attributeName, Method getter, Method setter) {
56 if(map.containsKey(attributeName.toLowerCase())) {
57 System.err.println(this + " already contains key '" + attributeName + "', overwriting value!");
58 } else {
59 // we keep an ordered list of attributes for extraction
60 keys.add(attributeName.toLowerCase());
61 }
62 map.put(attributeName.toLowerCase(), new Attribute(attributeName, getter, setter));
63 }
64
65 // Create a second reference the the same Attribute, using a different name
66 // Does not modify the list of keys
67 public void alias(String alias, String name) {
68 if(map.containsKey(name.toLowerCase())) {
69 map.put(alias.toLowerCase(), map.get(name.toLowerCase()));
70 } else {
71 System.err.println("Cannot add alias '" + alias + "', because key '" + name + "' does not exist!");
72 }
73 }
74
75 public boolean containsKey(String key) {
76 return map.containsKey(key);
77 }
78
79 public Attribute get(String key) {
80 return map.get(key);
81 }
82 }
83
84 public static final AttributeSet _Attrib = new AttributeSet(128);
85 public static final AttributeSet _FrameAttrib = new AttributeSet(16);
86
87
88 // List of attributes which are ignored when extracting attributes
89 private static List<String> _IgnoreGet = null;
90 // List of attributes which are ignored when setting attributes,
91 // if multiple attributes are being set at once
92 private static List<String> _IgnoreSet = null;
93
94 /***************************************************************************
95 * List of method names to show in extraced lists even when they return null
96 * (Null is often used to indicate the default value is used)
97 **************************************************************************/
98 private static List<Method> _AllowNull = null;
99
100 // private static HashMap<String, String> _Abbreviations = null;
101
102 public static void ensureReady() {
103 if(_IgnoreSet == null) {
104 initLists();
105 }
106 }
107
108 /**
109 * Initialises the _Ignore and _AllowNull lists.
110 */
111 private static void initLists() {
112
113 try {
114
115 Class<?>[] pPoint = { Point.class };
116 Class<?>[] pString = { String.class };
117 Class<?>[] pInt = { int.class };
118 Class<?>[] pIntO = { Integer.class };
119 Class<?>[] pFloat = { float.class };
120 Class<?>[] pFloatO = { Float.class };
121 Class<?>[] pColor = { Color.class };
122 Class<?>[] pBool = { boolean.class };
123 //Class[] pDouble = { double.class };
124 //Class[] pDoubleO = { Double.class };
125 Class<?>[] pArrow = { float.class, double.class, double.class };
126 Class<?>[] pList = { List.class };
127 Class<?>[] pIntArray = { int[].class };
128 Class<?>[] pJustification = { Justification.class };
129 Class<?>[] pPermission = { PermissionPair.class };
130 Class<?>[] pDotType = { DotType.class };
131
132 _IgnoreSet = new LinkedList<String>();
133 _IgnoreGet = new LinkedList<String>();
134 _AllowNull = new LinkedList<Method>();
135
136 // TODO load these in with reflection...
137 // Set the shortcuts with annotation tags on the methods
138 _IgnoreSet.add("date");
139 _IgnoreSet.add("datecreated");
140 _IgnoreSet.add("d");
141 _IgnoreSet.add("link");
142 _IgnoreSet.add("l");
143 _IgnoreSet.add("action");
144 _IgnoreSet.add("a");
145 _IgnoreSet.add("position");
146 _IgnoreSet.add("pos");
147 _IgnoreSet.add("p");
148 _IgnoreSet.add("x");
149 _IgnoreSet.add("y");
150
151 _IgnoreGet.add("x");
152 _IgnoreGet.add("y");
153 _IgnoreGet.add("text");
154 _IgnoreGet.add("gradientangle");
155
156 _AllowNull.add(Item.class.getMethod("getColor"));
157 _AllowNull.add(Item.class.getMethod("getBackgroundColor"));
158
159 _AllowNull.add(Frame.class.getMethod("getBackgroundColor"));
160 _AllowNull.add(Frame.class.getMethod("getForegroundColor"));
161
162 /*
163 * Populate the backing lists of attributes
164 */
165
166 // Frames
167 _FrameAttrib.put("Permission", Frame.class.getMethod("getPermission"),
168 Frame.class.getMethod("setPermission", pPermission));
169 _FrameAttrib.put("Owner", Frame.class.getMethod("getOwner"),
170 Frame.class.getMethod("setOwner", pString));
171 _FrameAttrib.put("DateCreated", Frame.class.getMethod("getDateCreated"),
172 null);
173 _FrameAttrib.put("LastModifyUser", Frame.class.getMethod("getLastModifyUser"),
174 null);
175 _FrameAttrib.put("LastModifyDate", Frame.class.getMethod("getLastModifyDate"),
176 null);
177 _FrameAttrib.put("ForegroundColor", Frame.class.getMethod("getForegroundColor"),
178 Frame.class.getMethod("setForegroundColor", pColor));
179 _FrameAttrib.put("BackgroundColor", Frame.class.getMethod("getBackgroundColor"),
180 Frame.class.getMethod("setBackgroundColor", pColor));
181
182 // aliases for attribute setting
183 _FrameAttrib.alias("fgc", "foregroundcolor");
184 _FrameAttrib.alias("bgc", "backgroundcolor");
185 _FrameAttrib.alias("p", "permission");
186
187
188 // Generic Items
189 _Attrib.put("DateCreated", Item.class.getMethod("getDateCreated"),
190 Item.class.getMethod("setDateCreated", pString));
191 _Attrib.put("Color", Item.class.getMethod("getColor"),
192 Item.class.getMethod("setColor", pColor));
193 _Attrib.put("BackgroundColor", Item.class.getMethod("getBackgroundColor"),
194 Item.class.getMethod("setBackgroundColor", pColor));
195 _Attrib.put("BorderColor", Item.class.getMethod("getBorderColor"),
196 Item.class.getMethod("setBorderColor", pColor));
197 _Attrib.put("AnchorRight", Item.class.getMethod("getAnchorRight"),
198 Item.class.getMethod("setAnchorRight", pFloatO));
199 _Attrib.put("AnchorBottom", Item.class.getMethod("getAnchorBottom"),
200 Item.class.getMethod("setAnchorBottom", pFloatO));
201 _Attrib.put("Position", Item.class.getMethod("getPosition"),
202 Item.class.getMethod("setPosition", pPoint));
203 _Attrib.put("Link", Item.class.getMethod("getLink"),
204 Item.class.getMethod("setLink", pString));
205 _Attrib.put("Action", Item.class.getMethod("getAction"),
206 Item.class.getMethod("setActions", pList));
207 _Attrib.put("ActionMark", Item.class.getMethod("getActionMark"),
208 Item.class.getMethod("setActionMark", pBool));
209 _Attrib.put("ActionCursorEnter", Item.class.getMethod("getActionCursorEnter"),
210 Item.class.getMethod("setActionCursorEnter", pList));
211 _Attrib.put("ActionCursorLeave", Item.class.getMethod("getActionCursorLeave"),
212 Item.class.getMethod("setActionCursorLeave", pList));
213 _Attrib.put("ActionEnterFrame", Item.class.getMethod("getActionEnterFrame"),
214 Item.class.getMethod("setActionEnterFrame", pList));
215 _Attrib.put("ActionLeaveFrame", Item.class.getMethod("getActionLeaveFrame"),
216 Item.class.getMethod("setActionLeaveFrame", pList));
217 _Attrib.put("Data", Item.class.getMethod("getData"),
218 Item.class.getMethod("setData", pList));
219 _Attrib.put("Highlight", Item.class.getMethod("getHighlight"),
220 Item.class.getMethod("setHighlight", pBool));
221 _Attrib.put("FillColor", Item.class.getMethod("getFillColor"),
222 Item.class.getMethod("setFillColor", pColor));
223 _Attrib.put("GradientColor", Item.class.getMethod("getGradientColor"),
224 Item.class.getMethod("setGradientColor", pColor));
225 _Attrib.put("GradientAngle", Item.class.getMethod("getGradientAngle"),
226 Item.class.getMethod("setGradientAngle", pInt));
227 _Attrib.put("FillPattern", Item.class.getMethod("getFillPattern"),
228 Item.class.getMethod("setFillPattern", pString));
229 _Attrib.put("Owner", Item.class.getMethod("getOwner"),
230 Item.class.getMethod("setOwner", pString));
231 _Attrib.put("LinkMark", Item.class.getMethod("getLinkMark"),
232 Item.class.getMethod("setLinkMark", pBool));
233 _Attrib.put("LinkFrameset", Item.class.getMethod("getLinkFrameset"),
234 Item.class.getMethod("setLinkFrameset", pString));
235 _Attrib.put("LinkTemplate", Item.class.getMethod("getLinkTemplate"),
236 Item.class.getMethod("setLinkTemplate", pString));
237 _Attrib.put("LinePattern", Item.class.getMethod("getLinePattern"),
238 Item.class.getMethod("setLinePattern", pIntArray));
239 _Attrib.put("Arrow", Item.class.getMethod("getArrow"),
240 Item.class.getMethod("setArrow", pArrow));
241 _Attrib.put("DotType", Item.class.getMethod("getDotType"),
242 Item.class.getMethod("setDotType", pDotType));
243 _Attrib.put("Filled", Item.class.getMethod("getFilled"),
244 Item.class.getMethod("setFilled", pBool));
245 _Attrib.put("Formula", Item.class.getMethod("getFormula"),
246 Item.class.getMethod("setFormula", pString));
247 _Attrib.put("Thickness", Item.class.getMethod("getThickness"),
248 Item.class.getMethod("setThickness", pFloat));
249// _Attrib.put("LineIDs", Item.class.getMethod("getLineIDs"),
250// Item.class.getMethod("setLineIDs", pString));
251// _Attrib.put("ConstraintIDs", Item.class.getMethod("getConstraintIDs"),
252// Item.class.getMethod("setConstraintIDs", pString));
253 _Attrib.put("Size", Item.class.getMethod("getSize"),
254 Item.class.getMethod("setSize", pFloat));
255 _Attrib.put("Save", Item.class.getMethod("getSave"),
256 Item.class.getMethod("setSave", pBool));
257 _Attrib.put("AutoStamp", Item.class.getMethod("getAutoStamp"),
258 Item.class.getMethod("setAutoStamp", pFloatO));
259 _Attrib.put("Width", Item.class.getMethod("getWidthToSave"),
260 Item.class.getMethod("setWidth", pIntO));
261 _Attrib.put("X", null,
262 Item.class.getMethod("setX", pFloat));
263 _Attrib.put("Y", null,
264 Item.class.getMethod("setY", pFloat));
265 _Attrib.put("Tooltip", Item.class.getMethod("getTooltip"),
266 Item.class.getMethod("setTooltip", pString));
267
268 // Text Items
269 _Attrib.put("Family", Text.class.getMethod("getFamily"),
270 Text.class.getMethod("setFamily", pString));
271 _Attrib.put("FontStyle", Text.class.getMethod("getFontStyle"),
272 Text.class.getMethod("setFontStyle", pString));
273 _Attrib.put("Justification", Text.class.getMethod("getJustification"),
274 Text.class.getMethod("setJustification", pJustification));
275 _Attrib.put("AutoWrap", Text.class.getMethod("getAutoWrapToSave"),
276 Text.class.getMethod("setAutoWrap", pBool));
277
278 // Aliases for attribute setting
279 _Attrib.alias("pos", "position");
280 _Attrib.alias("p", "position");
281 _Attrib.alias("xy", "position");
282 _Attrib.alias("a", "action");
283 _Attrib.alias("d", "data");
284 _Attrib.alias("f", "formula");
285 _Attrib.alias("s", "size");
286 _Attrib.alias("l", "link");
287 _Attrib.alias("ab", "anchorbottom");
288 _Attrib.alias("ar", "anchorright");
289 _Attrib.alias("t", "thickness");
290 // _Attrib.alias("c", "color"); // breaks circle creation
291 _Attrib.alias("bgc", "backgroundcolor");
292 _Attrib.alias("bc", "bordercolor");
293 _Attrib.alias("fc", "fillcolor");
294 _Attrib.alias("gc", "gradientcolor");
295 _Attrib.alias("ga", "gradientangle");
296 _Attrib.alias("fp", "fillpattern");
297 _Attrib.alias("lm", "linkmark");
298 _Attrib.alias("am", "actionmark");
299 _Attrib.alias("dt", "dottype");
300 _Attrib.alias("fill", "filled");
301 _Attrib.alias("lp", "linepattern");
302 _Attrib.alias("lf", "linkframeset");
303 _Attrib.alias("lt", "linktemplate");
304 _Attrib.alias("face", "fontstyle");
305 _Attrib.alias("j", "justification");
306 _Attrib.alias("w", "width");
307 _Attrib.alias("as", "autostamp");
308
309
310 } catch (SecurityException e) {
311 // TODO Auto-generated catch block
312 e.printStackTrace();
313 } catch (NoSuchMethodException e) {
314 // TODO Auto-generated catch block
315 e.printStackTrace();
316 }
317 }
318
319 /**
320 * Extracts a list of attributes from the given Item. Any method that
321 * starts with <code>get</code>, takes no arguments and is not found in
322 * the Ignore list will be run, All the attributes are then put into a Text
323 * Item of the form <Name>:<Value> If the value returned by the get method
324 * is null, then the attribute will not be included, unless the name of the
325 * method is found in the AllowNull list.
326 *
327 * @param toExtract
328 * The Object from which to extract the attributes
329 * @return A Text Item containing the extracted Attributes.
330 */
331 public static Item extractAttributes(Object toExtract) {
332
333 // System.out.println(toExtract);
334
335 if (toExtract == null) {
336 return null;
337 }
338
339 // Ensure the lists are populated
340 ensureReady();
341
342 AttributeSet attribSet = null;
343 if(toExtract instanceof Frame) {
344 attribSet = _FrameAttrib;
345 } else if(toExtract instanceof Item) {
346 attribSet = _Attrib;
347 } else {
348 throw new IncorrectTypeException("toExtract", "Item | Frame");
349 }
350
351 // StringBuffer to store all the extracted Attribute:Value pairs
352 StringBuffer attributes = new StringBuffer();
353
354 // iterate through the list of methods
355 for (String prop : attribSet.keys) {
356
357 Attribute a = attribSet.get(prop);
358 // Make sure the classes of the methods match the item
359 if (a != null && a.getter != null && a.getter.getDeclaringClass().isAssignableFrom(toExtract.getClass())) {
360
361 try {
362 String s = getValue(prop, a, toExtract, true);
363
364 if (s == null)
365 continue;
366 // Append the attributes
367 attributes.append(a.displayName)
368 .append(AttributeValuePair.SEPARATOR_STRING)
369 .append(s).append('\n');
370 } catch (Exception e) {
371 // TODO Auto-generated catch block
372 e.printStackTrace();
373 }
374 }
375 }
376
377 // if no attributes were extracted
378 if (attributes.length() <= 0)
379 return null;
380
381 while (attributes.charAt(attributes.length() - 1) == '\n')
382 attributes.delete(attributes.length() - 1, attributes.length());
383
384 // create the text Item
385 Frame current = DisplayIO.getCurrentFrame();
386 Item attribs = current.getStatsTextItem(attributes.toString());
387 return attribs;
388 }
389
390 /**
391 * Gets a string form of the value for a given item get method.
392 * @param method
393 * @param item
394 * @param ignore true if the attributes in the IGNORE list should be ignored
395 * @return
396 */
397 private static String getValue(String name, Attribute a, Object item, boolean ignore) {
398 // assert(method.getName().startsWith("get"));
399
400 Object o = null;
401 try {
402 o = a.getter.invoke(item, (Object[]) null);
403 } catch (IllegalArgumentException e) {
404 e.printStackTrace();
405 return null;
406 } catch (IllegalAccessException e) {
407 e.printStackTrace();
408 return null;
409 } catch (InvocationTargetException e) {
410 e.printStackTrace();
411 return null;
412 }
413
414 if (o == null) {
415 // methods that return null are only included if they
416 // are in the AllowNull list
417 if (_AllowNull.contains(a.getter)) {
418 if (name.equals("color"))
419 o = "default";
420 else if (name.equals("backgroundcolor"))
421 o = "transparent";
422 else if (name.equals("foregroundcolor"))
423 o = "auto";
424 else
425 o = "";
426 } else {
427 return null;
428 }
429 }
430 // skip methods that are in the ignore lists
431 if (ignore && _IgnoreGet.contains(name)) {
432 return null;
433 }
434
435 if (o instanceof Integer) {
436 Integer i = (Integer) o;
437 if (i == Item.DEFAULT_INTEGER)
438 return null;
439 if (a.getter.getName().endsWith("Justification")
440 && ((Justification) o).toString() != null)
441 o = ((Justification) o).toString();
442 // -1 indicates default value
443 else
444 o = i;
445 } else if (o instanceof Float) {
446 if (((Float) o) < -0.0001)
447 return null;
448 // Null indicates default
449 // o = Math.round((Float) o);
450 } else if (o instanceof Double) {
451 // -1 indicates default value
452 if (((Double) o) < 0.0001)
453 return null;
454 } else if (o instanceof Color) {
455 // converts the color to the Expeditee code
456 o = Conversion.getExpediteeColorCode((Color) o);
457 if (o == null)
458 return null;
459 } else if (o instanceof Point) {
460 Point p = (Point) o;
461 o = Math.round(p.getX()) + " " + Math.round(p.getY());
462 } else if (o instanceof Font) {
463 Font f = (Font) o;
464
465 String s = f.getName() + "-";
466 if (f.isPlain())
467 s += "Plain";
468
469 if (f.isBold())
470 s += "Bold";
471
472 if (f.isItalic())
473 s += "Italic";
474
475 s += "-" + f.getSize();
476 o = s;
477 } else if (o instanceof Text) {
478 o = ((Text) o).getFirstLine();
479 } else if (o instanceof List) {
480 List list = (List) o;
481 StringBuffer sb = new StringBuffer();
482 for (Object ob : list)
483 // TODO check that this works ok
484 if (sb.length() == 0) {
485 sb.append(ob);
486 } else {
487 sb.append('\n').append(a.displayName).append(AttributeValuePair.SEPARATOR_STRING).append(ob);
488 }
489 return sb.toString();
490 } else if (o instanceof int[]) {
491 StringBuffer sb = new StringBuffer();
492 int[] values = (int[]) o;
493 for (int i = 0; i < values.length; i++) {
494 sb.append(values[i]).append(' ');
495 }
496 sb.deleteCharAt(sb.length() - 1);
497 o = sb.toString();
498 } else if (o instanceof Boolean) {
499 // true is the default for boolean values
500 if (((Boolean) o).booleanValue())
501 return null;
502 }
503 return o.toString();
504 }
505
506 /**
507 * Attempts to set the attribute in the given attribute: value pair. The
508 * value string should be formatted as follows:
509 * <code> Attribute: Value </code> Multiple values can be used if they are
510 * separated by spaces
511 *
512 * @param toSet
513 * The Item or Frame to set the attribute of
514 * @param attribs
515 * The Text item that contains the list of attributes to set
516 * @return True if the attribute(s) were sucessfully set, false otherwise
517 */
518 public static boolean setAttribute(Object toSet, Text attribs) {
519 return setAttribute(toSet, attribs, 1);
520 }
521
522 public static boolean setAttribute(Object toSet, Text attribs,
523 int minAttributeLength) {
524 // error checking
525 if (toSet == null || attribs == null)
526 return false;
527
528 ensureReady();
529
530 AttributeSet attribSet = null;
531 if(toSet instanceof Frame) {
532 attribSet = _FrameAttrib;
533 } else if(toSet instanceof Item) {
534 attribSet = _Attrib;
535 } else {
536 throw new IncorrectTypeException("toExtract", "Item | Frame");
537 }
538
539 // if(attribs.isAnnotation())
540 // return false;
541
542 // get the list of attribute: value pairs
543 List<String> values = attribs.getTextList();
544 // if no pairs exist, we are done
545 if (values == null || values.size() == 0) {
546 return false;
547 }
548
549 // loop through all attribute: value pairs
550 for (int i = 0; i < values.size(); i++) {
551 AttributeValuePair avp = new AttributeValuePair(values.get(i),
552 false);
553
554 // If the first is not an attribute value pair then don't do
555 // attribute merging
556 if (!avp.hasAttribute()
557 || avp.getAttribute().length() < minAttributeLength)
558 return false;
559
560 // check if the next string is another attribute to merge or a
561 // continuation
562 for (; i < values.size() - 1; i++) {
563 AttributeValuePair nextAvp = new AttributeValuePair(values
564 .get(i + 1), false);
565
566 // if the next String has a colon, then it may be another
567 // attribute
568 if (nextAvp.hasAttribute()) {
569 // if the attribute is the same as v, then it is a
570 // continuation
571 if (nextAvp.getAttribute().equals(avp.getAttribute())) {
572 // strip the attribute from next
573 avp.appendValue(nextAvp.getValue());
574
575 // if the attribute is not the same, then it may be a
576 // new method
577 } else {
578 break;
579 }
580 }
581
582 // v.append("\n").append(next);
583 }
584
585 try {
586 if (!setAttribute(toSet, avp, values.size() > 1)) {
587
588 String stripped = avp.getAttribute();
589 if (!avp.hasPair()) {
590 // This happens when there is an attribute at the start
591 // Then a bunch of plain text
592 return false;
593 } else if (_IgnoreSet.contains(stripped)) {
594 return false;
595 } else {
596 Attribute a = attribSet.get(stripped);
597 if(a == null || a.setter == null) {
598 return false;
599 }
600 String types = "";
601 for (Class<?> c : a.setter.getParameterTypes()) {
602 types += c.getSimpleName() + " ";
603 }
604 MessageBay.warningMessage("Wrong arguments for: '"
605 + avp.getAttribute() + "' expecting "
606 + types.trim() + " found '" + avp.getValue() + "'");
607 }
608 }
609 } catch (AttributeException e) {
610 MessageBay.errorMessage(e.getMessage());
611 }
612 }
613
614 return true;
615 }
616
617 /**
618 * Sets a single attrubute of a frame or item.
619 *
620 * @param toSet
621 * @param avp
622 * @param isAttributeList
623 * some properties are ignored when attribute list are injected
624 * into an item. These properties are ignored if this param is
625 * true
626 * @return
627 * @throws NoSuchAttributeException
628 */
629 private static boolean setAttribute(Object toSet, AttributeValuePair avp,
630 boolean isAttributeList) throws AttributeException {
631
632 assert (avp.hasAttribute());
633
634 // separate attribute and value from string
635 String attribute = avp.getAttribute().toLowerCase();
636
637 String value = avp.getValue();
638 assert (value != null);
639
640 AttributeSet attribSet = null;
641 if(toSet instanceof Frame) {
642 attribSet = _FrameAttrib;
643 } else if(toSet instanceof Item) {
644 attribSet = _Attrib;
645 } else {
646 throw new IncorrectTypeException("toExtract", "Item | Frame");
647 }
648
649 // Some properties are ignored when multiple attributes are being set on
650 // an item at the same time
651 if (isAttributeList && _IgnoreSet.contains(attribute)) {
652 // System.out.println("Attribute ignored: " + attribute);
653 return true;
654 }
655
656 // Separate multiple values if required
657
658 Attribute a = attribSet.get(attribute);
659 // if this is not the name of a method, it may be the name of an agent
660 if (a == null || a.setter == null) {
661 // System.out.println("Attrib not found for: " + attribute);
662 return false;
663 }
664
665 // if there are duplicate methods with the same name
666 List<Method> possibles = new LinkedList<Method>();
667 if (a.setter.getDeclaringClass().isInstance(toSet))
668 possibles.add(a.setter);
669 int i = 0;
670 while (attribSet.containsKey(attribute + i)) {
671 Method m = attribSet.get(attribute + i).setter;
672 if(m == null) {
673 break;
674 }
675 if (m.getDeclaringClass().isAssignableFrom(toSet.getClass())) {
676 possibles.add(m);
677 }
678 i++;
679 }
680
681 for (Method possible : possibles) {
682 Object current = invokeAttributeGetMethod(avp.getAttribute(), toSet);
683 // find the corresponding get method for this set method
684 // and get the current value of the attribute
685
686 try {
687 Object[] params = Conversion.Convert(possible, value, current);
688
689 try {
690 possible.invoke(toSet, params);
691 return true;
692 } catch (IllegalArgumentException e) {
693 // TODO Auto-generated catch block
694 e.printStackTrace();
695 } catch (IllegalAccessException e) {
696 // TODO Auto-generated catch block
697 e.printStackTrace();
698 } catch (InvocationTargetException e) {
699 MessageBay.displayMessage(toSet.getClass().getSimpleName()
700 + " type does not support that attribute.");
701 // e.printStackTrace();
702 }
703 } catch (NumberFormatException e) {
704
705 }
706 }
707
708 if(possibles.size() == 0){
709 if(invokeAttributeGetMethod(avp.getAttribute(), toSet) == null)
710 throw new NoSuchAttributeException(avp.getAttribute(), toSet.getClass().getSimpleName());
711 throw new ReadOnlyAttributeException(avp.getAttribute(), toSet.getClass().getSimpleName());
712 }
713
714 return false;
715 }
716
717 private static Object invokeAttributeGetMethod(String name, Object toSet) {
718
719 AttributeSet attribSet = null;
720 if(toSet instanceof Frame) {
721 attribSet = _FrameAttrib;
722 } else if(toSet instanceof Item) {
723 attribSet = _Attrib;
724 } else {
725 throw new IncorrectTypeException("toExtract", "Item | Frame");
726 }
727
728 Attribute a = attribSet.get(name.toLowerCase());
729 if(a == null) {
730 return null;
731 }
732 try {
733 return a.getter.invoke(toSet);
734 } catch (Exception e) {
735 e.printStackTrace();
736 }
737 return null;
738 }
739
740 /**
741 * Replaces the current value for the text item with the new value.
742 *
743 * @param text
744 * the item whos value is to be changed
745 * @param newValue
746 * the new value for the item
747 */
748 public static void replaceValue(Text text, String newValue) {
749 assert (newValue != null);
750
751 AttributeValuePair avp = new AttributeValuePair(text.getText());
752
753 if (avp.getAttribute() == null) {
754 avp.setAttribute(avp.getValue());
755 }
756 avp.setValue(newValue);
757 text.setText(avp.toString());
758 }
759
760 public static String getAttribute(Item item, String attribute) {
761
762 // ensure the lists are populated
763 ensureReady();
764
765 // separate attribute and value from string
766 String lowerAttribute = attribute.trim().toLowerCase();
767
768 Attribute a = _Attrib.get(lowerAttribute);
769 if(a == null) {
770 MessageBay.errorMessage("Could no extract unknown attribute value: " + attribute);
771 return null;
772 }
773 return a.displayName + AttributeValuePair.SEPARATOR_STRING + getValue(lowerAttribute, a, item, false);
774 }
775}
Note: See TracBrowser for help on using the repository browser.