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

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

New Attributes (and repurposed old ones) to be used for encryption of frames:

  • FrameEncryptionLabel. Used to be EncryptionLabel, which is still the case for items. When applied to a frame, it determines the label used to encrypt the entire frame.
  • HomogeneousEncryptionLabel. Does not yet actually do anything. The future point of this attribute is to provide the label that must be used to encrypt items on the frame when the user has only homogeneous encryption permissions.
  • EncryptionFramePermission. Does not yet actually do anything. The future point of this attribute isto determine if a user is able to change the FrameEncryptionLabel on a frame. Level 0 (none), no they cannot. Level 1 (homogeneous), they can only change it to HomogeneousEncryptionLabel. Level 2 (Hetrogeneous Owner), they can change it to any label as long as the owner of the Frame has that label. Level 3 (Hetrogeneous), they can change it to anything.
  • EncryptionPermission. Does not yet actually do anything. The future point of this attribute is to determine what encryption labels can be applied to items on the frame. Level 0 (none), cannot apply an encryption label. Level 1 (homogeneous), they can only used the label specified in HomogeneousEncryptionLabel. Level 2 (Hetrogeneous Owner), they can only use encryption labels that the owner of the frame has. Level 3 (Hetrogeneous) they can use any labels to encrypt an item.
File size: 32.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.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 // Standard Frame attributes
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("Group", Frame.class.getMethod("getGroup"),
203 Frame.class.getMethod("setGroup", pString));
204
205 // Encryption Frame attributes
206 _FrameAttrib.put("FrameEncryptionLabel", Frame.class.getMethod("getFrameEncryptionLabel"),
207 Frame.class.getMethod("setFrameEncryptionLabel", pString));
208 _FrameAttrib.put("EncryptionFramePermission", Frame.class.getMethod("getFrameEncryptionPermission"),
209 Frame.class.getMethod("setFrameEncryptionPermission", pEncPermission));
210 _FrameAttrib.put("HomogeneousEncryptionLabel", Frame.class.getMethod("getHomogeneousEncryptionLabel"),
211 Frame.class.getMethod("setHomogeneousEncryptionLabel", pString));
212 _FrameAttrib.put("EncryptionPermission", Frame.class.getMethod("getEncryptionPermission"),
213 Frame.class.getMethod("setEncryptionPermission", pEncPermission));
214
215 // aliases for Standard frame attribute settings
216 _FrameAttrib.alias("fgc", "foregroundcolor");
217 _FrameAttrib.alias("bgc", "backgroundcolor");
218 _FrameAttrib.alias("p", "permission");
219
220 // aliases for Encryption frame attribute settings
221 _FrameAttrib.alias("encframelabel", "FrameEncryptionLabel");
222 _FrameAttrib.alias("encframeperm", "EncryptionFramePermission");
223 _FrameAttrib.alias("homoenclabel", "HomogeneousEncryptionLabel");
224 _FrameAttrib.alias("encperm", "EncryptionPermission");
225
226 // Generic Items
227 _Attrib.put("DateCreated", Item.class.getMethod("getDateCreated"),
228 Item.class.getMethod("setDateCreated", pString));
229 _Attrib.put("Color", Item.class.getMethod("getColor"),
230 Item.class.getMethod("setColor", pColor));
231 _Attrib.put("BackgroundColor", Item.class.getMethod("getBackgroundColor"),
232 Item.class.getMethod("setBackgroundColor", pColor));
233 _Attrib.put("BorderColor", Item.class.getMethod("getBorderColor"),
234 Item.class.getMethod("setBorderColor", pColor));
235 _Attrib.put("AnchorLeft", Item.class.getMethod("getAnchorLeft"),
236 Item.class.getMethod("setAnchorLeft", pIntO));
237 _Attrib.put("AnchorRight", Item.class.getMethod("getAnchorRight"),
238 Item.class.getMethod("setAnchorRight", pIntO));
239 _Attrib.put("AnchorTop", Item.class.getMethod("getAnchorTop"),
240 Item.class.getMethod("setAnchorTop", pIntO));
241 _Attrib.put("AnchorBottom", Item.class.getMethod("getAnchorBottom"),
242 Item.class.getMethod("setAnchorBottom", pIntO));
243 _Attrib.put("Position", Item.class.getMethod("getPosition"),
244 Item.class.getMethod("setPosition", pPoint));
245 _Attrib.put("Link", Item.class.getMethod("getLink"),
246 Item.class.getMethod("setLink", pString));
247 _Attrib.put("AddToHistory", Item.class.getMethod("getLinkHistory"),
248 Item.class.getMethod("setLinkHistory", pBool));
249 _Attrib.put("Action", Item.class.getMethod("getAction"),
250 Item.class.getMethod("setActions", pList));
251 _Attrib.put("ActionMark", Item.class.getMethod("getActionMark"),
252 Item.class.getMethod("setActionMark", pBool));
253 _Attrib.put("ActionCursorEnter", Item.class.getMethod("getActionCursorEnter"),
254 Item.class.getMethod("setActionCursorEnter", pList));
255 _Attrib.put("ActionCursorLeave", Item.class.getMethod("getActionCursorLeave"),
256 Item.class.getMethod("setActionCursorLeave", pList));
257 _Attrib.put("ActionEnterFrame", Item.class.getMethod("getActionEnterFrame"),
258 Item.class.getMethod("setActionEnterFrame", pList));
259 _Attrib.put("ActionLeaveFrame", Item.class.getMethod("getActionLeaveFrame"),
260 Item.class.getMethod("setActionLeaveFrame", pList));
261 _Attrib.put("Data", Item.class.getMethod("getData"),
262 Item.class.getMethod("setData", pList));
263 _Attrib.put("Highlight", Item.class.getMethod("getHighlight"),
264 Item.class.getMethod("setHighlight", pBool));
265 _Attrib.put("FillColor", Item.class.getMethod("getFillColor"),
266 Item.class.getMethod("setFillColor", pColor));
267 _Attrib.put("GradientColor", Item.class.getMethod("getGradientColor"),
268 Item.class.getMethod("setGradientColor", pColor));
269 _Attrib.put("GradientAngle", Item.class.getMethod("getGradientAngle"),
270 Item.class.getMethod("setGradientAngle", pDouble));
271 _Attrib.put("FillPattern", Item.class.getMethod("getFillPattern"),
272 Item.class.getMethod("setFillPattern", pString));
273 _Attrib.put("Owner", Item.class.getMethod("getOwner"),
274 Item.class.getMethod("setOwner", pString));
275 _Attrib.put("LinkMark", Item.class.getMethod("getLinkMark"),
276 Item.class.getMethod("setLinkMark", pBool));
277 _Attrib.put("LinkFrameset", Item.class.getMethod("getLinkFrameset"),
278 Item.class.getMethod("setLinkFrameset", pString));
279 _Attrib.put("LinkTemplate", Item.class.getMethod("getLinkTemplate"),
280 Item.class.getMethod("setLinkTemplate", pString));
281 _Attrib.put("LinePattern", Item.class.getMethod("getLinePattern"),
282 Item.class.getMethod("setLinePattern", pIntArray));
283 _Attrib.put("Arrow", Item.class.getMethod("getArrow"),
284 Item.class.getMethod("setArrow", pArrow));
285 _Attrib.put("DotType", Item.class.getMethod("getDotType"),
286 Item.class.getMethod("setDotType", pDotType));
287 _Attrib.put("Filled", Item.class.getMethod("getFilled"),
288 Item.class.getMethod("setFilled", pBool));
289 _Attrib.put("Formula", Item.class.getMethod("getFormula"),
290 Item.class.getMethod("setFormula", pString));
291 _Attrib.put("Thickness", Item.class.getMethod("getThickness"),
292 Item.class.getMethod("setThickness", pFloat));
293// _Attrib.put("LineIDs", Item.class.getMethod("getLineIDs"),
294// Item.class.getMethod("setLineIDs", pString));
295// _Attrib.put("ConstraintIDs", Item.class.getMethod("getConstraintIDs"),
296// Item.class.getMethod("setConstraintIDs", pString));
297 _Attrib.put("Size", Item.class.getMethod("getSize"),
298 Item.class.getMethod("setSize", pFloat));
299 _Attrib.put("Save", Item.class.getMethod("getSave"),
300 Item.class.getMethod("setSave", pBool));
301 _Attrib.put("AutoStamp", Item.class.getMethod("getAutoStamp"),
302 Item.class.getMethod("setAutoStamp", pFloatO));
303 _Attrib.put("Width", Item.class.getMethod("getWidthToSave"),
304 Item.class.getMethod("setWidth", pIntO));
305 _Attrib.put("MinWidth", Item.class.getMethod("getMinWidthToSave"),
306 Item.class.getMethod("setMinWidth", pIntO));
307 _Attrib.put("X", null,
308 Item.class.getMethod("setX", pFloat));
309 _Attrib.put("Y", null,
310 Item.class.getMethod("setY", pFloat));
311 _Attrib.put("Tooltip", Item.class.getMethod("getTooltip"),
312 Item.class.getMethod("setTooltips", pList));
313 _Attrib.put("Permission", Item.class.getMethod("getPermission"),
314 Item.class.getMethod("setPermission", pPermission));
315 _Attrib.put("EncryptionLabel", Item.class.getMethod("getEncryptionLabel"),
316 Item.class.getMethod("setEncryptionLabel", pString));
317 _Attrib.put("ID", Item.class.getMethod("getID"),
318 Item.class.getMethod("setIDFail", pInt));
319
320 // Text Items
321 _Attrib.put("Family", Text.class.getMethod("getFamily"),
322 Text.class.getMethod("setFamily", pString));
323 _Attrib.put("FontStyle", Text.class.getMethod("getFontStyle"),
324 Text.class.getMethod("setFontStyle", pString));
325 _Attrib.put("Justification", Text.class.getMethod("getJustification"),
326 Text.class.getMethod("setJustification", pJustification));
327 _Attrib.put("AutoWrap", Text.class.getMethod("getAutoWrapToSave"),
328 Text.class.getMethod("setAutoWrap", pBool));
329
330 _Attrib.put("LineSpacing", Text.class.getMethod("getSpacing"),
331 Text.class.getMethod("setSpacing", pFloat));
332
333 _Attrib.put("LetterSpacing", Text.class.getMethod("getLetterSpacing"),
334 Text.class.getMethod("setLetterSpacing", pFloat));
335 _Attrib.put("Mask", Text.class.getMethod("getMask"),
336 Text.class.getMethod("setMask", pIntO));
337 _Attrib.put("Placeholder", Text.class.getMethod("getPlaceholder"),
338 Text.class.getMethod("setPlaceholder", pString));
339 _Attrib.put("SingleLineOnly", Text.class.getMethod("isSingleLineOnly"),
340 Text.class.getMethod("setSingleLineOnly", pBool));
341 _Attrib.put("TabIndex", Text.class.getMethod("getTabIndex"),
342 Text.class.getMethod("setTabIndex", pInt));
343 _Attrib.put("EnterClick", Item.class.getMethod("acceptsKeyboardEnter"),
344 Item.class.getMethod("setAcceptsEnter", pBool));
345 _Attrib.put("KeyImage", Item.class.getMethod("keyType"),
346 Item.class.getMethod("setKeyType", pString));
347
348 // Aliases for attribute setting
349 _Attrib.alias("pos", "position");
350 _Attrib.alias("p", "position");
351 _Attrib.alias("xy", "position");
352 _Attrib.alias("a", "action");
353 _Attrib.alias("d", "data");
354 _Attrib.alias("f", "formula");
355 _Attrib.alias("font", "family");
356 _Attrib.alias("s", "size");
357 _Attrib.alias("l", "link");
358 _Attrib.alias("at", "anchortop");
359 _Attrib.alias("ab", "anchorbottom");
360 _Attrib.alias("al", "anchorleft");
361 _Attrib.alias("ar", "anchorright");
362 _Attrib.alias("t", "thickness");
363 // _Attrib.alias("c", "color"); // breaks circle creation
364 _Attrib.alias("bgc", "backgroundcolor");
365 _Attrib.alias("bc", "bordercolor");
366 _Attrib.alias("fc", "fillcolor");
367 _Attrib.alias("gc", "gradientcolor");
368 _Attrib.alias("ga", "gradientangle");
369 _Attrib.alias("fp", "fillpattern");
370 _Attrib.alias("lm", "linkmark");
371 _Attrib.alias("am", "actionmark");
372 _Attrib.alias("dt", "dottype");
373 _Attrib.alias("fill", "filled");
374 _Attrib.alias("lp", "linepattern");
375 _Attrib.alias("lf", "linkframeset");
376 _Attrib.alias("lt", "linktemplate");
377 _Attrib.alias("face", "fontstyle");
378 _Attrib.alias("j", "justification");
379 _Attrib.alias("w", "width");
380 _Attrib.alias("mw", "minwidth");
381 _Attrib.alias("as", "autostamp");
382 } catch (SecurityException e) {
383 // TODO Auto-generated catch block
384 e.printStackTrace();
385 } catch (NoSuchMethodException e) {
386 // TODO Auto-generated catch block
387 e.printStackTrace();
388 }
389 }
390
391 /**
392 * Extracts a list of attributes from the given Item. Any method that
393 * starts with <code>get</code>, takes no arguments and is not found in
394 * the Ignore list will be run, All the attributes are then put into a Text
395 * Item of the form <Name>:<Value> If the value returned by the get method
396 * is null, then the attribute will not be included, unless the name of the
397 * method is found in the AllowNull list.
398 *
399 * @param toExtract
400 * The Object from which to extract the attributes
401 * @return A Text Item containing the extracted Attributes.
402 */
403 public static Item extractAttributes(Object toExtract) {
404
405 // System.out.println(toExtract);
406
407 if (toExtract == null) {
408 return null;
409 }
410
411 // Ensure the lists are populated
412 ensureReady();
413
414 AttributeSet attribSet = null;
415 if(toExtract instanceof Frame) {
416 attribSet = _FrameAttrib;
417 } else if(toExtract instanceof Item) {
418 attribSet = _Attrib;
419 } else {
420 throw new IncorrectTypeException("toExtract", "Item | Frame");
421 }
422
423 // StringBuffer to store all the extracted Attribute:Value pairs
424 StringBuffer attributes = new StringBuffer();
425
426 // iterate through the list of methods
427 for (String prop : attribSet.keys) {
428
429 Attribute a = attribSet.get(prop);
430 // Make sure the classes of the methods match the item
431 if (a != null && a.getter != null && a.getter.getDeclaringClass().isAssignableFrom(toExtract.getClass())) {
432 try {
433 String s = getValue(prop, a, toExtract, true);
434 if (s == null) {
435 continue;
436 }
437 // Append the attributes
438 attributes.append(a.displayName)
439 .append(AttributeValuePair.SEPARATOR_STRING)
440 .append(s).append('\n');
441 } catch (Exception e) {
442 // TODO Auto-generated catch block
443 e.printStackTrace();
444 }
445 }
446 }
447
448 // if no attributes were extracted
449 if (attributes.length() <= 0) {
450 return null;
451 }
452
453 while (attributes.charAt(attributes.length() - 1) == '\n') {
454 attributes.delete(attributes.length() - 1, attributes.length());
455 }
456
457 // create the text Item
458 Frame current = DisplayController.getCurrentFrame();
459 Item attribs = current.getStatsTextItem(attributes.toString());
460 return attribs;
461 }
462
463 /**
464 * Gets a string form of the value for a given item get method.
465 * @param method
466 * @param item
467 * @param ignore true if the attributes in the IGNORE list should be ignored
468 * @return
469 */
470 private static String getValue(String name, Attribute a, Object item, boolean ignore) {
471 // assert(method.getName().startsWith("get"));
472
473 Object o = null;
474 try {
475 o = a.getter.invoke(item, (Object[]) null);
476 } catch (IllegalArgumentException e) {
477 e.printStackTrace();
478 return null;
479 } catch (IllegalAccessException e) {
480 e.printStackTrace();
481 return null;
482 } catch (InvocationTargetException e) {
483 e.printStackTrace();
484 return null;
485 }
486
487 if (o == null) {
488 // methods that return null are only included if they
489 // are in the AllowNull list
490 if (_AllowNull.contains(a.getter)) {
491 if (name.equals("color")) {
492 o = "default";
493 } else if (name.equals("backgroundcolor")) {
494 o = "transparent";
495 } else if (name.equals("foregroundcolor")) {
496 o = "auto";
497 } else {
498 o = "";
499 }
500 } else {
501 return null;
502 }
503 }
504 // skip methods that are in the ignore lists
505 if (ignore && _IgnoreGet.contains(name)) {
506 return null;
507 }
508
509 if (o instanceof Integer) {
510 Integer i = (Integer) o;
511 if (i == Item.DEFAULT_INTEGER) {
512 return null;
513 }
514 if (a.getter.getName().endsWith("Justification")
515 && ((Justification) o).toString() != null) {
516 o = ((Justification) o).toString();
517 // -1 indicates default value
518 } else {
519 o = i;
520 }
521 } else if (o instanceof Float) {
522 if (((Float) o) < -0.0001)
523 {
524 return null;
525 // Null indicates default
526 // o = Math.round((Float) o);
527 }
528 } else if (o instanceof Double) {
529 // -1 indicates default value
530 if (((Double) o) < 0.0001) {
531 return null;
532 }
533 } else if (o instanceof Colour) {
534 // converts the color to the Expeditee code
535 o = Conversion.getExpediteeColorCode((Colour) o);
536 if (o == null) {
537 return null;
538 }
539 } else if (o instanceof Point) {
540 Point p = (Point) o;
541 o = Math.round(p.getX()) + " " + Math.round(p.getY());
542 } else if (o instanceof Font) {
543 Font f = (Font) o;
544
545 String s = f.getFamilyName() + "-";
546 if (f.isPlain()) {
547 s += "Plain";
548 }
549
550 if (f.isBold()) {
551 s += "Bold";
552 }
553
554 if (f.isItalic()) {
555 s += "Italic";
556 }
557
558 s += "-" + f.getSize();
559 o = s;
560 } else if (o instanceof Text) {
561 o = ((Text) o).getFirstLine();
562 } else if (o instanceof List) {
563 List list = (List) o;
564 StringBuffer sb = new StringBuffer();
565 for (Object ob : list) {
566 // TODO check that this works ok
567 if (sb.length() == 0) {
568 sb.append(ob);
569 } else {
570 sb.append('\n').append(a.displayName).append(AttributeValuePair.SEPARATOR_STRING).append(ob);
571 }
572 }
573 return sb.toString();
574 } else if (o instanceof int[]) {
575 StringBuffer sb = new StringBuffer();
576 int[] values = (int[]) o;
577 for (int i = 0; i < values.length; i++) {
578 sb.append(values[i]).append(' ');
579 }
580 sb.deleteCharAt(sb.length() - 1);
581 o = sb.toString();
582 } else if (o instanceof Boolean) {
583 try {
584 Class<?> parentClass = item.getClass();
585 Field defaultValueField = parentClass.getField(a.getter.getName() + "Default");
586 boolean defaultValue = defaultValueField.getBoolean(null);
587 if (defaultValue == (boolean) o) {
588 return null;
589 }
590 } catch (IllegalArgumentException e) {
591 e.printStackTrace();
592 } catch (SecurityException e) {
593 e.printStackTrace();
594 } catch (NoSuchFieldException e) {
595 // true is the default for boolean values when no other default is provided
596 if ((boolean) o) {
597 return null;
598 }
599 } catch (IllegalAccessException e) {
600 e.printStackTrace();
601 }
602 }
603 return o.toString();
604 }
605
606 /**
607 * Attempts to set the attribute in the given attribute: value pair. The
608 * value string should be formatted as follows:
609 * <code> Attribute: Value </code> Multiple values can be used if they are
610 * separated by spaces
611 *
612 * @param toSet
613 * The Item or Frame to set the attribute of
614 * @param attribs
615 * The Text item that contains the list of attributes to set
616 * @return True if the attribute(s) were sucessfully set, false otherwise
617 */
618 public static boolean setAttribute(Object toSet, Text attribs) {
619 return setAttribute(toSet, attribs, 1);
620 }
621
622 public static boolean setAttribute(Object toSet, Text attribs,
623 int minAttributeLength) {
624 // error checking
625 if (toSet == null || attribs == null) {
626 return false;
627 }
628
629 ensureReady();
630
631 AttributeSet attribSet = null;
632 if(toSet instanceof Frame) {
633 attribSet = _FrameAttrib;
634 } else if(toSet instanceof Item) {
635 attribSet = _Attrib;
636 } else {
637 throw new IncorrectTypeException("toExtract", "Item | Frame");
638 }
639
640 // if(attribs.isAnnotation())
641 // return false;
642
643 // get the list of attribute: value pairs
644 List<String> values = attribs.getTextList();
645 // if no pairs exist, we are done
646 if (values == null || values.size() == 0) {
647 return false;
648 }
649
650 // loop through all attribute: value pairs
651 for (int i = 0; i < values.size(); i++) {
652 AttributeValuePair avp = new AttributeValuePair(values.get(i),
653 false);
654
655 // If the first is not an attribute value pair then don't do
656 // attribute merging
657 if (!avp.hasAttribute()
658 || avp.getAttribute().length() < minAttributeLength) {
659 return false;
660 }
661
662 // check if the next string is another attribute to merge or a
663 // continuation
664 for (; i < values.size() - 1; i++) {
665 AttributeValuePair nextAvp = new AttributeValuePair(values
666 .get(i + 1), false);
667
668 // if the next String has a colon, then it may be another
669 // attribute
670 if (nextAvp.hasAttribute()) {
671 // if the attribute is the same as v, then it is a
672 // continuation
673 if (nextAvp.getAttribute().equals(avp.getAttribute())) {
674 // strip the attribute from next
675 avp.appendValue(nextAvp.getValue() + "\n");
676
677 // if the attribute is not the same, then it may be a
678 // new method
679 } else {
680 break;
681 }
682 }
683
684 // v.append("\n").append(next);
685 }
686
687 try {
688 if (!setAttribute(toSet, avp, values.size() > 1)) {
689
690 String stripped = avp.getAttribute();
691 if (!avp.hasPair()) {
692 // This happens when there is an attribute at the start
693 // Then a bunch of plain text
694 return false;
695 } else if (_IgnoreSet.contains(stripped)) {
696 return false;
697 } else {
698 Attribute a = attribSet.get(stripped);
699 if(a == null || a.setter == null) {
700 return false;
701 }
702 String types = "";
703 for (Class<?> c : a.setter.getParameterTypes()) {
704 types += c.getSimpleName() + " ";
705 }
706 MessageBay.warningMessage("Wrong arguments for: '"
707 + avp.getAttribute() + "' expecting "
708 + types.trim() + " found '" + avp.getValue() + "'");
709 }
710 }
711 } catch (AttributeException e) {
712 MessageBay.errorMessage(e.getMessage());
713 }
714 }
715
716 return true;
717 }
718
719 /**
720 * Sets a single attribute of a frame or item.
721 *
722 * @param toSet
723 * @param avp
724 * @param isAttributeList
725 * some properties are ignored when attribute list are injected
726 * into an item. These properties are ignored if this param is
727 * true
728 * @return
729 * @throws NoSuchAttributeException
730 */
731 private static boolean setAttribute(Object toSet, AttributeValuePair avp,
732 boolean isAttributeList) throws AttributeException {
733
734 assert (avp.hasAttribute());
735
736 // separate attribute and value from string
737 String attribute = avp.getAttribute().toLowerCase();
738
739 String value = avp.getValue();
740 assert (value != null);
741
742 AttributeSet attribSet = null;
743 if(toSet instanceof Frame) {
744 attribSet = _FrameAttrib;
745 } else if(toSet instanceof Item) {
746 attribSet = _Attrib;
747 } else {
748 throw new IncorrectTypeException("toExtract", "Item | Frame");
749 }
750
751 // Some properties are ignored when multiple attributes are being set on
752 // an item at the same time
753 if (isAttributeList && _IgnoreSet.contains(attribute)) {
754 // System.out.println("Attribute ignored: " + attribute);
755 return true;
756 }
757
758 // Separate multiple values if required
759
760 Attribute a = attribSet.get(attribute);
761 // if this is not the name of a method, it may be the name of an agent
762 if (a == null || a.setter == null) {
763 // System.out.println("Attrib not found for: " + attribute);
764 return false;
765 }
766
767 // if there are duplicate methods with the same name
768 List<Method> possibles = new LinkedList<Method>();
769 if (a.setter.getDeclaringClass().isInstance(toSet)) {
770 possibles.add(a.setter);
771 }
772 int i = 0;
773 while (attribSet.containsKey(attribute + i)) {
774 Method m = attribSet.get(attribute + i).setter;
775 if(m == null) {
776 break;
777 }
778 if (m.getDeclaringClass().isAssignableFrom(toSet.getClass())) {
779 possibles.add(m);
780 }
781 i++;
782 }
783
784 for (Method possible : possibles) {
785 Object current = invokeAttributeGetMethod(avp.getAttribute(), toSet);
786 // find the corresponding get method for this set method
787 // and get the current value of the attribute
788
789 try {
790 Object[] params = Conversion.Convert(possible, value, current);
791
792 try {
793 possible.invoke(toSet, params);
794 return true;
795 } catch (IllegalArgumentException e) {
796 // TODO Auto-generated catch block
797 e.printStackTrace();
798 } catch (IllegalAccessException e) {
799 // TODO Auto-generated catch block
800 e.printStackTrace();
801 } catch (InvocationTargetException e) {
802 MessageBay.displayMessage(toSet.getClass().getSimpleName()
803 + " type does not support that attribute.");
804 // e.printStackTrace();
805 }
806 } catch (NumberFormatException e) {
807
808 }
809 }
810
811 if(possibles.size() == 0){
812 if(invokeAttributeGetMethod(avp.getAttribute(), toSet) == null) {
813 throw new NoSuchAttributeException(avp.getAttribute(), toSet.getClass().getSimpleName());
814 }
815 throw new ReadOnlyAttributeException(avp.getAttribute(), toSet.getClass().getSimpleName());
816 }
817
818 return false;
819 }
820
821 private static Object invokeAttributeGetMethod(String name, Object toSet) {
822
823 AttributeSet attribSet = null;
824 if(toSet instanceof Frame) {
825 attribSet = _FrameAttrib;
826 } else if(toSet instanceof Item) {
827 attribSet = _Attrib;
828 } else {
829 throw new IncorrectTypeException("toExtract", "Item | Frame");
830 }
831
832 Attribute a = attribSet.get(name.toLowerCase());
833 if(a == null) {
834 return null;
835 }
836 try {
837 return a.getter.invoke(toSet);
838 } catch (Exception e) {
839 e.printStackTrace();
840 }
841 return null;
842 }
843
844 /**
845 * Replaces the current value for the text item with the new value.
846 *
847 * @param text
848 * the item whos value is to be changed
849 * @param newValue
850 * the new value for the item
851 */
852 public static void replaceValue(Text text, String newValue) {
853 assert (newValue != null);
854
855 AttributeValuePair avp = new AttributeValuePair(text.getText());
856
857 if (avp.getAttribute() == null) {
858 avp.setAttribute(avp.getValue());
859 }
860 avp.setValue(newValue);
861 text.setText(avp.toString());
862 }
863
864 public static String getAttribute(Item item, String attribute) {
865
866 // ensure the lists are populated
867 ensureReady();
868
869 // separate attribute and value from string
870 String lowerAttribute = attribute.trim().toLowerCase();
871
872 Attribute a = _Attrib.get(lowerAttribute);
873 if(a == null) {
874 MessageBay.errorMessage("Could no extract unknown attribute value: " + attribute);
875 return null;
876 }
877 return a.displayName + AttributeValuePair.SEPARATOR_STRING + getValue(lowerAttribute, a, item, false);
878 }
879}
Note: See TracBrowser for help on using the repository browser.