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

Last change on this file since 1477 was 1477, checked in by bnemhaus, 4 years ago

Added label existance check for when setting encryption label on a frame.

Added padlock icon on items that are encrypted.

Added key icon on items with KeyImage property set to 'PartialKey' or 'FullKey'. This will hopefully soon transformed into automatically setting these properties on key items that are on the secrets frame. The property should not be set-able by user once fully implemented and is only atm for debug purposes.

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