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

Last change on this file since 1415 was 1415, checked in by bln4, 5 years ago

Renamed Frame.getItems() to Frame.getSortedItems() to better represent its functionality.

-> org.apollo.ApolloGestureActions
-> org.apollo.ApolloSystem
-> org.expeditee.actions.Actions
-> org.expeditee.actions.Debug
-> org.expeditee.actions.ExploratorySearchActions
-> org.expeditee.actions.JfxBrowserActions
-> org.expeditee.actions.Misc
-> org.expeditee.actions.Navigation
-> org.expeditee.actions.ScriptBase
-> org.expeditee.actions.Simple
-> org.expeditee.agents.ComputeTree
-> org.expeditee.agents.CopyTree
-> org.expeditee.agents.DisplayComet
-> org.expeditee.agents.DisplayTree
-> org.expeditee.agents.DisplayTreeLeaves
-> org.expeditee.agents.GraphFramesetLinks
-> org.expeditee.agents.TreeProcessor
-> org.expeditee.gio.gesture.StandardGestureActions
-> org.expeditee.gui.DisplayController
-> org.expeditee.gui.FrameCreator
-> org.expeditee.gui.FrameIO
-> org.expeditee.io.DefaultTreeWriter
-> org.expeditee.io.JavaWriter
-> org.expeditee.io.PDF2Writer
-> org.expeditee.io.TXTWriter
-> org.expeditee.io.WebParser
-> org.expeditee.io.flowlayout.XGroupItem
-> org.expeditee.items.Dot
-> org.expeditee.items.Item
-> org.expeditee.items.ItemUtils
-> org.expeditee.network.FrameShare
-> org.expeditee.stats.TreeStats


Created ItemsList class to wrap ArrayList<Item>. Frames now use this new class to store its body list (used for display) as well as its primaryBody and surrogateBody.

-> org.expeditee.agents.Format
-> org.expeditee.agents.HFormat
-> org.expeditee.gio.gesture.StandardGestureActions
-> org.expeditee.gui.Frame
-> org.expeditee.gui.FrameUtils


Refactorted Frame.setResort(bool) to Frame.invalidateSorted() to better function how it is intended to with a more accurate name.

-> org.expeditee.agents.Sort


When writing out .exp files and getting attributes to respond to LEFT + RIGHT click, boolean items are by default true. This has always been the case. An ammendment to this is that defaults can now be established.
Also added 'EnterClick' functionality. If cursored over a item with this property and you press enter, it acts as if you have clicked on it instead.

-> org.expeditee.assets.resources-public.framesets.authentication.1.exp to 6.exp
-> org.expeditee.gio.gesture.StandardGestureActions
-> org.expeditee.gio.input.KBMInputEvent
-> org.expeditee.gio.javafx.JavaFXConversions
-> org.expeditee.gio.swing.SwingConversions
-> org.expeditee.gui.AttributeUtils
-> org.expeditee.io.Conversion
-> org.expeditee.io.DefaultFrameWriter
-> org.expeditee.items.Item


Fixed a bug caused by calling Math.abs on Integer.MIN_VALUE returning unexpected result. Due to zero being a thing, you cannot represent Math.abs(Integer.MIN_VALUE) in a Integer object. The solution is to use Integer.MIN_VALUE + 1 instead of Integer.MIN_VALUE.

-> org.expeditee.core.bounds.CombinationBounds
-> org.expeditee.io.flowlayout.DimensionExtent


Recoded the contains function in EllipticalBounds so that intersection tests containing circles work correctly.

-> org.expeditee.core.bounds.EllipticalBounds


Added toString() to PolygonBounds to allow for useful printing during debugging.

-> org.expeditee.core.bounds.PolygonBounds

Implemented Surrogate Mode!

-> org.expeditee.encryption.io.EncryptedExpReader
-> org.expeditee.encryption.io.EncryptedExpWriter
-> org.expeditee.encryption.items.surrogates.EncryptionDetail
-> org.expeditee.encryption.items.surrogates.Label
-> org.expeditee.gui.FrameUtils
-> org.expeditee.gui.ItemsList
-> org.expeditee.items.Item
-> org.expeditee.items.Text


???? Use Integer.MAX_VALUE cast to a float instead of Float.MAX_VALUE. This fixed some bug which I cannot remember.

-> org.expeditee.gio.TextLayoutManager
-> org.expeditee.gio.swing.SwingTextLayoutManager


Improved solution for dealing with the F10 key taking focus away from Expeditee due to it being a assessibility key.

-> org.expeditee.gio.swing.SwingInputManager


Renamed variable visibleItems in FrameGraphics.paintFrame to itemsToPaintCanditates to better represent functional intent.

-> org.expeditee.gui.FrameGraphics


Improved checking for if personal resources exist before recreating them

-> org.expeditee.gui.FrameIO


Repeated messages to message bay now have a visual feedback instead of just a beep. This visual feedback is in the form of a count of the amount of times it has repeated.

-> org.expeditee.gui.MessageBay


Updated comment on the Vector class to explain what vectors are.

-> org.expeditee.gui.Vector


Added constants to represent all of the property keys in DefaultFrameReader and DefaultFrameWriter.

-> org.expeditee.io.DefaultFrameReader
-> org.expeditee.io.DefaultFrameWriter


Updated the KeyList setting to be more heirarcial with how users will store their Secrets.

-> org.expeditee.settings.identity.secrets.KeyList

File size: 32.0 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
311 // Text Items
312 _Attrib.put("Family", Text.class.getMethod("getFamily"),
313 Text.class.getMethod("setFamily", pString));
314 _Attrib.put("FontStyle", Text.class.getMethod("getFontStyle"),
315 Text.class.getMethod("setFontStyle", pString));
316 _Attrib.put("Justification", Text.class.getMethod("getJustification"),
317 Text.class.getMethod("setJustification", pJustification));
318 _Attrib.put("AutoWrap", Text.class.getMethod("getAutoWrapToSave"),
319 Text.class.getMethod("setAutoWrap", pBool));
320
321 _Attrib.put("LineSpacing", Text.class.getMethod("getSpacing"),
322 Text.class.getMethod("setSpacing", pFloat));
323
324 _Attrib.put("LetterSpacing", Text.class.getMethod("getLetterSpacing"),
325 Text.class.getMethod("setLetterSpacing", pFloat));
326 _Attrib.put("Mask", Text.class.getMethod("getMask"),
327 Text.class.getMethod("setMask", pIntO));
328 _Attrib.put("Placeholder", Text.class.getMethod("getPlaceholder"),
329 Text.class.getMethod("setPlaceholder", pString));
330 _Attrib.put("SingleLineOnly", Text.class.getMethod("isSingleLineOnly"),
331 Text.class.getMethod("setSingleLineOnly", pBool));
332 _Attrib.put("TabIndex", Text.class.getMethod("getTabIndex"),
333 Text.class.getMethod("setTabIndex", pInt));
334 _Attrib.put("EnterClick", Item.class.getMethod("acceptsKeyboardEnter"),
335 Item.class.getMethod("setAcceptsEnter", pBool));
336
337 // Aliases for attribute setting
338 _Attrib.alias("pos", "position");
339 _Attrib.alias("p", "position");
340 _Attrib.alias("xy", "position");
341 _Attrib.alias("a", "action");
342 _Attrib.alias("d", "data");
343 _Attrib.alias("f", "formula");
344 _Attrib.alias("font", "family");
345 _Attrib.alias("s", "size");
346 _Attrib.alias("l", "link");
347 _Attrib.alias("at", "anchortop");
348 _Attrib.alias("ab", "anchorbottom");
349 _Attrib.alias("al", "anchorleft");
350 _Attrib.alias("ar", "anchorright");
351 _Attrib.alias("t", "thickness");
352 // _Attrib.alias("c", "color"); // breaks circle creation
353 _Attrib.alias("bgc", "backgroundcolor");
354 _Attrib.alias("bc", "bordercolor");
355 _Attrib.alias("fc", "fillcolor");
356 _Attrib.alias("gc", "gradientcolor");
357 _Attrib.alias("ga", "gradientangle");
358 _Attrib.alias("fp", "fillpattern");
359 _Attrib.alias("lm", "linkmark");
360 _Attrib.alias("am", "actionmark");
361 _Attrib.alias("dt", "dottype");
362 _Attrib.alias("fill", "filled");
363 _Attrib.alias("lp", "linepattern");
364 _Attrib.alias("lf", "linkframeset");
365 _Attrib.alias("lt", "linktemplate");
366 _Attrib.alias("face", "fontstyle");
367 _Attrib.alias("j", "justification");
368 _Attrib.alias("w", "width");
369 _Attrib.alias("mw", "minwidth");
370 _Attrib.alias("as", "autostamp");
371 } catch (SecurityException e) {
372 // TODO Auto-generated catch block
373 e.printStackTrace();
374 } catch (NoSuchMethodException e) {
375 // TODO Auto-generated catch block
376 e.printStackTrace();
377 }
378 }
379
380 /**
381 * Extracts a list of attributes from the given Item. Any method that
382 * starts with <code>get</code>, takes no arguments and is not found in
383 * the Ignore list will be run, All the attributes are then put into a Text
384 * Item of the form <Name>:<Value> If the value returned by the get method
385 * is null, then the attribute will not be included, unless the name of the
386 * method is found in the AllowNull list.
387 *
388 * @param toExtract
389 * The Object from which to extract the attributes
390 * @return A Text Item containing the extracted Attributes.
391 */
392 public static Item extractAttributes(Object toExtract) {
393
394 // System.out.println(toExtract);
395
396 if (toExtract == null) {
397 return null;
398 }
399
400 // Ensure the lists are populated
401 ensureReady();
402
403 AttributeSet attribSet = null;
404 if(toExtract instanceof Frame) {
405 attribSet = _FrameAttrib;
406 } else if(toExtract instanceof Item) {
407 attribSet = _Attrib;
408 } else {
409 throw new IncorrectTypeException("toExtract", "Item | Frame");
410 }
411
412 // StringBuffer to store all the extracted Attribute:Value pairs
413 StringBuffer attributes = new StringBuffer();
414
415 // iterate through the list of methods
416 for (String prop : attribSet.keys) {
417
418 Attribute a = attribSet.get(prop);
419 // Make sure the classes of the methods match the item
420 if (a != null && a.getter != null && a.getter.getDeclaringClass().isAssignableFrom(toExtract.getClass())) {
421 try {
422 String s = getValue(prop, a, toExtract, true);
423 if (s == null) {
424 continue;
425 }
426 // Append the attributes
427 attributes.append(a.displayName)
428 .append(AttributeValuePair.SEPARATOR_STRING)
429 .append(s).append('\n');
430 } catch (Exception e) {
431 // TODO Auto-generated catch block
432 e.printStackTrace();
433 }
434 }
435 }
436
437 // if no attributes were extracted
438 if (attributes.length() <= 0) {
439 return null;
440 }
441
442 while (attributes.charAt(attributes.length() - 1) == '\n') {
443 attributes.delete(attributes.length() - 1, attributes.length());
444 }
445
446 // create the text Item
447 Frame current = DisplayController.getCurrentFrame();
448 Item attribs = current.getStatsTextItem(attributes.toString());
449 return attribs;
450 }
451
452 /**
453 * Gets a string form of the value for a given item get method.
454 * @param method
455 * @param item
456 * @param ignore true if the attributes in the IGNORE list should be ignored
457 * @return
458 */
459 private static String getValue(String name, Attribute a, Object item, boolean ignore) {
460 // assert(method.getName().startsWith("get"));
461
462 Object o = null;
463 try {
464 o = a.getter.invoke(item, (Object[]) null);
465 } catch (IllegalArgumentException e) {
466 e.printStackTrace();
467 return null;
468 } catch (IllegalAccessException e) {
469 e.printStackTrace();
470 return null;
471 } catch (InvocationTargetException e) {
472 e.printStackTrace();
473 return null;
474 }
475
476 if (o == null) {
477 // methods that return null are only included if they
478 // are in the AllowNull list
479 if (_AllowNull.contains(a.getter)) {
480 if (name.equals("color")) {
481 o = "default";
482 } else if (name.equals("backgroundcolor")) {
483 o = "transparent";
484 } else if (name.equals("foregroundcolor")) {
485 o = "auto";
486 } else {
487 o = "";
488 }
489 } else {
490 return null;
491 }
492 }
493 // skip methods that are in the ignore lists
494 if (ignore && _IgnoreGet.contains(name)) {
495 return null;
496 }
497
498 if (o instanceof Integer) {
499 Integer i = (Integer) o;
500 if (i == Item.DEFAULT_INTEGER) {
501 return null;
502 }
503 if (a.getter.getName().endsWith("Justification")
504 && ((Justification) o).toString() != null) {
505 o = ((Justification) o).toString();
506 // -1 indicates default value
507 } else {
508 o = i;
509 }
510 } else if (o instanceof Float) {
511 if (((Float) o) < -0.0001)
512 {
513 return null;
514 // Null indicates default
515 // o = Math.round((Float) o);
516 }
517 } else if (o instanceof Double) {
518 // -1 indicates default value
519 if (((Double) o) < 0.0001) {
520 return null;
521 }
522 } else if (o instanceof Colour) {
523 // converts the color to the Expeditee code
524 o = Conversion.getExpediteeColorCode((Colour) o);
525 if (o == null) {
526 return null;
527 }
528 } else if (o instanceof Point) {
529 Point p = (Point) o;
530 o = Math.round(p.getX()) + " " + Math.round(p.getY());
531 } else if (o instanceof Font) {
532 Font f = (Font) o;
533
534 String s = f.getFamilyName() + "-";
535 if (f.isPlain()) {
536 s += "Plain";
537 }
538
539 if (f.isBold()) {
540 s += "Bold";
541 }
542
543 if (f.isItalic()) {
544 s += "Italic";
545 }
546
547 s += "-" + f.getSize();
548 o = s;
549 } else if (o instanceof Text) {
550 o = ((Text) o).getFirstLine();
551 } else if (o instanceof List) {
552 List list = (List) o;
553 StringBuffer sb = new StringBuffer();
554 for (Object ob : list) {
555 // TODO check that this works ok
556 if (sb.length() == 0) {
557 sb.append(ob);
558 } else {
559 sb.append('\n').append(a.displayName).append(AttributeValuePair.SEPARATOR_STRING).append(ob);
560 }
561 }
562 return sb.toString();
563 } else if (o instanceof int[]) {
564 StringBuffer sb = new StringBuffer();
565 int[] values = (int[]) o;
566 for (int i = 0; i < values.length; i++) {
567 sb.append(values[i]).append(' ');
568 }
569 sb.deleteCharAt(sb.length() - 1);
570 o = sb.toString();
571 } else if (o instanceof Boolean) {
572 try {
573 Class<?> parentClass = item.getClass();
574 Field defaultValueField = parentClass.getField(a.getter.getName() + "Default");
575 boolean defaultValue = defaultValueField.getBoolean(null);
576 if (defaultValue == (boolean) o) {
577 return null;
578 }
579 } catch (IllegalArgumentException e) {
580 e.printStackTrace();
581 } catch (SecurityException e) {
582 e.printStackTrace();
583 } catch (NoSuchFieldException e) {
584 // true is the default for boolean values when no other default is provided
585 if ((boolean) o) {
586 return null;
587 }
588 } catch (IllegalAccessException e) {
589 e.printStackTrace();
590 }
591 }
592 return o.toString();
593 }
594
595 /**
596 * Attempts to set the attribute in the given attribute: value pair. The
597 * value string should be formatted as follows:
598 * <code> Attribute: Value </code> Multiple values can be used if they are
599 * separated by spaces
600 *
601 * @param toSet
602 * The Item or Frame to set the attribute of
603 * @param attribs
604 * The Text item that contains the list of attributes to set
605 * @return True if the attribute(s) were sucessfully set, false otherwise
606 */
607 public static boolean setAttribute(Object toSet, Text attribs) {
608 return setAttribute(toSet, attribs, 1);
609 }
610
611 public static boolean setAttribute(Object toSet, Text attribs,
612 int minAttributeLength) {
613 // error checking
614 if (toSet == null || attribs == null) {
615 return false;
616 }
617
618 ensureReady();
619
620 AttributeSet attribSet = null;
621 if(toSet instanceof Frame) {
622 attribSet = _FrameAttrib;
623 } else if(toSet instanceof Item) {
624 attribSet = _Attrib;
625 } else {
626 throw new IncorrectTypeException("toExtract", "Item | Frame");
627 }
628
629 // if(attribs.isAnnotation())
630 // return false;
631
632 // get the list of attribute: value pairs
633 List<String> values = attribs.getTextList();
634 // if no pairs exist, we are done
635 if (values == null || values.size() == 0) {
636 return false;
637 }
638
639 // loop through all attribute: value pairs
640 for (int i = 0; i < values.size(); i++) {
641 AttributeValuePair avp = new AttributeValuePair(values.get(i),
642 false);
643
644 // If the first is not an attribute value pair then don't do
645 // attribute merging
646 if (!avp.hasAttribute()
647 || avp.getAttribute().length() < minAttributeLength) {
648 return false;
649 }
650
651 // check if the next string is another attribute to merge or a
652 // continuation
653 for (; i < values.size() - 1; i++) {
654 AttributeValuePair nextAvp = new AttributeValuePair(values
655 .get(i + 1), false);
656
657 // if the next String has a colon, then it may be another
658 // attribute
659 if (nextAvp.hasAttribute()) {
660 // if the attribute is the same as v, then it is a
661 // continuation
662 if (nextAvp.getAttribute().equals(avp.getAttribute())) {
663 // strip the attribute from next
664 avp.appendValue(nextAvp.getValue() + "\n");
665
666 // if the attribute is not the same, then it may be a
667 // new method
668 } else {
669 break;
670 }
671 }
672
673 // v.append("\n").append(next);
674 }
675
676 try {
677 if (!setAttribute(toSet, avp, values.size() > 1)) {
678
679 String stripped = avp.getAttribute();
680 if (!avp.hasPair()) {
681 // This happens when there is an attribute at the start
682 // Then a bunch of plain text
683 return false;
684 } else if (_IgnoreSet.contains(stripped)) {
685 return false;
686 } else {
687 Attribute a = attribSet.get(stripped);
688 if(a == null || a.setter == null) {
689 return false;
690 }
691 String types = "";
692 for (Class<?> c : a.setter.getParameterTypes()) {
693 types += c.getSimpleName() + " ";
694 }
695 MessageBay.warningMessage("Wrong arguments for: '"
696 + avp.getAttribute() + "' expecting "
697 + types.trim() + " found '" + avp.getValue() + "'");
698 }
699 }
700 } catch (AttributeException e) {
701 MessageBay.errorMessage(e.getMessage());
702 }
703 }
704
705 return true;
706 }
707
708 /**
709 * Sets a single attribute of a frame or item.
710 *
711 * @param toSet
712 * @param avp
713 * @param isAttributeList
714 * some properties are ignored when attribute list are injected
715 * into an item. These properties are ignored if this param is
716 * true
717 * @return
718 * @throws NoSuchAttributeException
719 */
720 private static boolean setAttribute(Object toSet, AttributeValuePair avp,
721 boolean isAttributeList) throws AttributeException {
722
723 assert (avp.hasAttribute());
724
725 // separate attribute and value from string
726 String attribute = avp.getAttribute().toLowerCase();
727
728 String value = avp.getValue();
729 assert (value != null);
730
731 AttributeSet attribSet = null;
732 if(toSet instanceof Frame) {
733 attribSet = _FrameAttrib;
734 } else if(toSet instanceof Item) {
735 attribSet = _Attrib;
736 } else {
737 throw new IncorrectTypeException("toExtract", "Item | Frame");
738 }
739
740 // Some properties are ignored when multiple attributes are being set on
741 // an item at the same time
742 if (isAttributeList && _IgnoreSet.contains(attribute)) {
743 // System.out.println("Attribute ignored: " + attribute);
744 return true;
745 }
746
747 // Separate multiple values if required
748
749 Attribute a = attribSet.get(attribute);
750 // if this is not the name of a method, it may be the name of an agent
751 if (a == null || a.setter == null) {
752 // System.out.println("Attrib not found for: " + attribute);
753 return false;
754 }
755
756 // if there are duplicate methods with the same name
757 List<Method> possibles = new LinkedList<Method>();
758 if (a.setter.getDeclaringClass().isInstance(toSet)) {
759 possibles.add(a.setter);
760 }
761 int i = 0;
762 while (attribSet.containsKey(attribute + i)) {
763 Method m = attribSet.get(attribute + i).setter;
764 if(m == null) {
765 break;
766 }
767 if (m.getDeclaringClass().isAssignableFrom(toSet.getClass())) {
768 possibles.add(m);
769 }
770 i++;
771 }
772
773 for (Method possible : possibles) {
774 Object current = invokeAttributeGetMethod(avp.getAttribute(), toSet);
775 // find the corresponding get method for this set method
776 // and get the current value of the attribute
777
778 try {
779 Object[] params = Conversion.Convert(possible, value, current);
780
781 try {
782 possible.invoke(toSet, params);
783 return true;
784 } catch (IllegalArgumentException e) {
785 // TODO Auto-generated catch block
786 e.printStackTrace();
787 } catch (IllegalAccessException e) {
788 // TODO Auto-generated catch block
789 e.printStackTrace();
790 } catch (InvocationTargetException e) {
791 MessageBay.displayMessage(toSet.getClass().getSimpleName()
792 + " type does not support that attribute.");
793 // e.printStackTrace();
794 }
795 } catch (NumberFormatException e) {
796
797 }
798 }
799
800 if(possibles.size() == 0){
801 if(invokeAttributeGetMethod(avp.getAttribute(), toSet) == null) {
802 throw new NoSuchAttributeException(avp.getAttribute(), toSet.getClass().getSimpleName());
803 }
804 throw new ReadOnlyAttributeException(avp.getAttribute(), toSet.getClass().getSimpleName());
805 }
806
807 return false;
808 }
809
810 private static Object invokeAttributeGetMethod(String name, Object toSet) {
811
812 AttributeSet attribSet = null;
813 if(toSet instanceof Frame) {
814 attribSet = _FrameAttrib;
815 } else if(toSet instanceof Item) {
816 attribSet = _Attrib;
817 } else {
818 throw new IncorrectTypeException("toExtract", "Item | Frame");
819 }
820
821 Attribute a = attribSet.get(name.toLowerCase());
822 if(a == null) {
823 return null;
824 }
825 try {
826 return a.getter.invoke(toSet);
827 } catch (Exception e) {
828 e.printStackTrace();
829 }
830 return null;
831 }
832
833 /**
834 * Replaces the current value for the text item with the new value.
835 *
836 * @param text
837 * the item whos value is to be changed
838 * @param newValue
839 * the new value for the item
840 */
841 public static void replaceValue(Text text, String newValue) {
842 assert (newValue != null);
843
844 AttributeValuePair avp = new AttributeValuePair(text.getText());
845
846 if (avp.getAttribute() == null) {
847 avp.setAttribute(avp.getValue());
848 }
849 avp.setValue(newValue);
850 text.setText(avp.toString());
851 }
852
853 public static String getAttribute(Item item, String attribute) {
854
855 // ensure the lists are populated
856 ensureReady();
857
858 // separate attribute and value from string
859 String lowerAttribute = attribute.trim().toLowerCase();
860
861 Attribute a = _Attrib.get(lowerAttribute);
862 if(a == null) {
863 MessageBay.errorMessage("Could no extract unknown attribute value: " + attribute);
864 return null;
865 }
866 return a.displayName + AttributeValuePair.SEPARATOR_STRING + getValue(lowerAttribute, a, item, false);
867 }
868}
Note: See TracBrowser for help on using the repository browser.