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

Last change on this file since 1548 was 1548, checked in by bnemhaus, 3 years ago

With a Item under your cursor, pressing left and right mouse buttons at the same time, extracts the properties of that item. (No change)
However, if an Item is attached to the users cursor when doing this, nothing happens. Now, instead of nothing happening, all attached Items are checked to see if they are in the format of "Property:". If they are then those specified properties are extracted.

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