001    /*
002      Copyright (C) 2002-2004 Renaud Pawlak <renaud@aopsys.com>, 
003                              Laurent Martelli <laurent@aopsys.com>
004    
005      This program is free software; you can redistribute it and/or modify
006      it under the terms of the GNU Lesser General Public License as
007      published by the Free Software Foundation; either version 2 of the
008      License, or (at your option) any later version.
009    
010      This program is distributed in the hope that it will be useful,
011      but WITHOUT ANY WARRANTY; without even the implied warranty of
012      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
013      GNU Lesser General Public License for more details.
014    
015      You should have received a copy of the GNU Lesser General Public License
016      along with this program; if not, write to the Free Software
017      Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
018    
019    package org.objectweb.jac.aspects.gui;
020    
021    import java.lang.reflect.Array;
022    import java.text.SimpleDateFormat;
023    import java.util.Arrays;
024    import java.util.Collection;
025    import java.util.Date;
026    import java.util.Enumeration;
027    import java.util.HashMap;
028    import java.util.Hashtable;
029    import java.util.Iterator;
030    import java.util.List;
031    import java.util.Map;
032    import java.util.StringTokenizer;
033    import java.util.Vector;
034    import org.apache.log4j.Level;
035    import org.apache.log4j.Logger;
036    import org.objectweb.jac.aspects.session.SessionAC;
037    import org.objectweb.jac.core.AspectComponent;
038    import org.objectweb.jac.core.Collaboration;
039    import org.objectweb.jac.core.Display;
040    import org.objectweb.jac.core.Interaction;
041    import org.objectweb.jac.core.Jac;
042    import org.objectweb.jac.core.NameRepository;
043    import org.objectweb.jac.core.ObjectRepository;
044    import org.objectweb.jac.core.Wrappee;
045    import org.objectweb.jac.core.Wrapping;
046    import org.objectweb.jac.core.dist.Distd;
047    import org.objectweb.jac.core.dist.RemoteContainer;
048    import org.objectweb.jac.core.rtti.AbstractMethodItem;
049    import org.objectweb.jac.core.rtti.ClassItem;
050    import org.objectweb.jac.core.rtti.ClassRepository;
051    import org.objectweb.jac.core.rtti.CollectionItem;
052    import org.objectweb.jac.core.rtti.FieldItem;
053    import org.objectweb.jac.core.rtti.MemberItem;
054    import org.objectweb.jac.core.rtti.MetaItem;
055    import org.objectweb.jac.core.rtti.MethodItem;
056    import org.objectweb.jac.core.rtti.NamingConventions;
057    import org.objectweb.jac.core.rtti.NoSuchMethodException;
058    import org.objectweb.jac.core.rtti.RttiAC;
059    import org.objectweb.jac.core.rtti.VirtualClassItem;
060    import org.objectweb.jac.util.Enum;
061    import org.objectweb.jac.util.ExtArrays;
062    import org.objectweb.jac.util.ExtBoolean;
063    import org.objectweb.jac.util.InvalidIndexException;
064    import org.objectweb.jac.util.Stack;
065    
066    /**
067     * This aspect component implements a very simple GUI that allows the
068     * user to browse the named object of the system and call methods on
069     * them.
070     *
071     * <p>It implements a MVC design pattern where the controllers are
072     * implemented by <code>ViewWrapper</code> instances.<p>
073     *
074     * @see ViewControlWrapper
075     * @see InputWrapper
076     * @see View
077     *
078     * @author <a href="mailto:renaud@cnam.fr">Renaud Pawlak</a>
079     * @author <a href="mailto:laurent@aopsys.com">Laurent Martelli</a>
080     */
081    
082    public class GuiAC extends AspectComponent implements GuiConf {
083        static Logger logger = Logger.getLogger("gui");
084        static Logger loggerContext = Logger.getLogger("gui.context");
085        static Logger loggerDisplay = Logger.getLogger("gui.display");
086        static Logger loggerApp = Logger.getLogger("application");
087        static Logger loggerWuni = Logger.getLogger("gui.wuni");
088        static Logger loggerTable = Logger.getLogger("gui.table");
089        static Logger loggerMenu = Logger.getLogger("gui.menu");
090        static Logger loggerFactory = Logger.getLogger("gui.factory");
091    
092        /** Name of the default generic object view */
093        public static final String DEFAULT_VIEW = "default";
094    
095        /** Name of the autocreated object view */
096        public static final String AUTOCREATE_VIEW = "autocreate";
097    
098        /** Stores the displays of the GUI (displayID -> display). */
099        protected static Hashtable displays = new Hashtable();
100    
101        /** Stores the cusomized GUI (class -> display). */
102        protected static Hashtable cguis = new Hashtable();
103    
104        // RTTI attributes
105        public static final String VIEWS = "GuiAC.VIEWS"; // Map String(view name) -> ObjectView
106        public static final String DEFAULTS_ATTRIBUTES_ORDER = "GuiAC.DEFAULTS_ATTRIBUTES_ORDER";
107        public static final String TREE_ATTRIBUTES_ORDER = "GuiAC.TREE_ATTRIBUTES_ORDER";
108        public static final String METHODS_ORDER = "GuiAC.METHODS_ORDER";
109        public static final String INTERACTION_HANDLER = "GuiAC.INTERACTION_HANDLER";
110        public static final String MIME_TYPE  = "GuiAC.MIME_TYPE";    
111    
112        
113        public static final String AUTO_CREATE = "GuiAC.AUTO_CREATE"; // Boolean
114        
115        public static final String AUTO_CREATE_INITIALIZER = "GuiAC.AUTO_CREATE_INITIALIZER"; // MethodItem
116        public static final String NO_AUTO_CREATE = "GuiAC.NO_AUTO_CREATE";
117        public static final String SORT_CRITERIA = "GuiAC.SORT_CRITERIA";
118        public static final String TABLE_VIEW = "GuiAC.TABLE_VIEW";
119        public static final String CHOICE_VIEW = "GuiAC.CHOICE_VIEW";
120        public static final String SHOW_ROW_NUMBERS = "GuiAC.SHOW_ROW_NUMBERS"; // Boolean
121        public static final String EDITABLE_DEFAULT_VALUES = "GuiAC.EDITABLE_DEFAULT_VALUES";
122        public static final String FILTERED_COLUMNS = "GuiAC.FILTERED_COLUMNS"; // Collection of FieldItem
123        public static final String TO_STRING = "GuiAC.TO_STRING";
124        public static final String CONTEXTUAL_TO_STRING = "GuiAC.CONTEXTUAL_TO_STRING";
125        public static final String TOOLTIP = "GuiAC.TOOLTIP";
126        public static final String CONTEXTUAL_TOOLTIP = "GuiAC.CONTEXTUAL_TOOLTIP";
127        //   public static final String EMBEDDED_VIEW = "GuiAC.EMBEDDED_VIEW";
128        public static final String EMBEDDED_EDITOR = "GuiAC.EMBEDDED_EDITOR";
129        // Boolean
130        public static final String VISIBLE = "GuiAC.VISIBLE"; // Boolean
131        public static final String EDITABLE = "GuiAC.EDITABLE"; // Boolean
132        public static final String ADDABLE = "GuiAC.ADDABLE"; // Boolean
133        public static final String REMOVABLE = "GuiAC.REMOVABLE"; // Boolean
134        public static final String CREATABLE = "GuiAC.CREATABLE"; // Boolean
135    
136        public static final String CATEGORIES = "GuiAC.CATEGORIES";
137        public static final String CATEGORIES_ICONS = "GuiAC.CATEGORIES_ICONS";
138        public static final String CATEGORIES_LABELS = "GuiAC.CATEGORIES_LABELS";
139        public static final String FIELD_CHOICE = "GuiAC.FIELD_CHOICE";
140        public static final String FIELD_ENUM = "GuiAC.FIELD_ENUM";
141        public static final String PARAMETER_ENUMS = "GuiAC.PARAMETER_ENUMS";
142        public static final String EDITABLE_CHOICE = "GuiAC.EDITABLE_CHOICE";
143        public static final String EDITABLE_CHOICES = "GuiAC.EDITABLE_CHOICES";
144        public static final String PARAMETER_CHOICES = "GuiAC.PARAMETER_CHOICES";
145        public static final String CLASS_CHOICES = "GuiAC.CLASS_CHOICES";
146        public static final String COLLECTION_TYPE = "GuiAC.COLLECTION_TYPE";
147        public static final String VIEW_ON_SELECTION = "GuiAC.VIEW_ON_SELECTION";
148        public static final String SELECTION_HANDLER = "GuiAC.SELECTION_HANDLER";
149        public static final String SELECTION_TARGET = "GuiAC.SELECTION_TARGET";
150        public static final String PARAMETER_NAMES = "GuiAC.PARAMETER_NAMES";
151        public static final String LINKED_PARAMETERS = "GuiAC.LINKED_PARAMETERS";
152        public static final String PASSWORD_PARAMETERS = "GuiAC.PASSWORD_PARAMETERS";
153        public static final String CREATION_ALLOWED_PARAMETERS = "GuiAC.CREATION_ALLOWED_PARAMETERS";
154        public static final String DEFAULT_VALUES = "GuiAC.DEFAULT_VALUES";
155        public static final String DYN_DEFAULT_VALUE = "GuiAC.DYN_DEFAULT_VALUE";
156        public static final String PARAMETER_FIELDS = "GuiAC.PARAMETER_FIELDS";
157        public static final String CONDITION = "GuiAC.CONDITION";
158        public static final String SLOW_OPERATION = "GuiAC.SLOW_OPERATION"; // Boolean
159        public static final String POST_INVOKE_HOOKS= "GuiAC.POST_INVOKE_HOOKS"; // List of AbstractMethodItems
160        public static final String VIEW_HEIGHT = "GuiAC.VIEW_HEIGHT";
161        public static final String VIEW_WIDTH = "GuiAC.VIEW_WIDTH";
162        public static final String EDITOR_HEIGHT = "GuiAC.EDITOR_HEIGHT";
163        public static final String EDITOR_WIDTH = "GuiAC.EDITOR_WIDTH";
164        public static final String EDITOR_COLS = "GuiAC.EDITOR_COLS";
165        public static final String EDITOR_ROWS = "GuiAC.EDITOR_ROWS";
166        public static final String EDITOR_SMALL_WIDTH = "GuiAC.EDITOR_SMALL_WIDTH";
167        public static final String EDITOR_SMALL_COLS = "GuiAC.EDITOR_SMALL_COLS";
168        public static final String EDITOR_SMALL_HEIGHT =
169        "GuiAC.EDITOR_SMALL_HEIGHT";
170        public static final String EDITOR_SMALL_ROWS = "GuiAC.EDITOR_SMALL_ROWS";
171        public static final String HIDDEN_TREE_RELATION =
172        "GuiAC.HIDDEN_TREE_RELATION";
173        public static final String BORDER = "GuiAC.BORDER";
174        public static final String DESCRIPTION = "GuiAC.DESCRIPTION";
175        public static final String ICON = "GuiAC.ICON";
176        public static final String DYNAMIC_ICON = "GuiAC.DYNAMIC_ICON";
177        public static final String MENU = "GuiAC.MENU";
178        public static final String DISPLAY_LABEL = "GuiAC.DISPLAY_LABEL"; // boolean
179        public static final String LABEL = "GuiAC.LABEL"; // String
180        public static final String MNEMONICS = "GuiAC.MNEMONICS"; // String
181        public static final String CONTEXTUAL_LABEL = "GuiAC.CONTEXTUAL_LABEL";
182        public static final String STYLE = "GuiAC.STYLE"; // String
183        public static final String NEW_WINDOW = "GuiAC.NEW_WINDOW";
184        public static final String NUM_ROWS_PER_PAGE = "GuiAC.NUM_ROWS_PER_PAGE"; // int
185        public static final String AVAILABLE_NUM_ROWS_PER_PAGE = "GuiAC.AVAILABLE_NUM_ROWS_PER_PAGE"; // int[]
186        public static final String AUTO_CREATED_STATE = "GuiAC.AUTO_CREATED_STATE";
187        public static final String SMALL_TARGET_CONTAINER = "GuiAC.SMALL_TARGET_CONTAINER";
188        public static final String NAVBAR = "GuiAC.NAVBAR";
189        public static final String FIELD_DEPENDENCIES = "GuiAC.FIELD_DEPENDENCIES";
190        public static final String LINE_BREAKS = "GuiAC.LINE_BREAKS";
191        public static final String DIRECT_COLLECTION_METHODS = "GuiAC.DIRECT_COLLECTION_METHODS";
192        public static final String DATE_FORMAT = "GuiAC.DATE_FORMAT";
193        public static final String DATEHOUR_FORMAT = "GuiAC.DATEHOUR_FORMAT";
194        public static final String FLOAT_FORMAT = "GuiAC.FLOATFORMAT";
195        public static final String INT_FORMAT = "GuiAC.INT_FORMAT";
196        public static final String FORMAT = "GuiAC.FORMAT";
197    
198        public static final String ASKING_SEQUENCE = "GuiAC.ASKING_SEQUENCE";
199    
200        public static final String DESKTOP_VIEW = "GuiAC.DESKTOP_VIEW"; //ClassItem
201        public static final String FILE_SELECTION_MODE =
202        "GuiAC.FILE_SELECTION_MODE";
203        // String
204        public static final String FILE_EXTENSIONS = "GuiAC.FILE_EXTENSIONS";
205        // String[]
206        public static final String FILE_EXTENSIONS_DESCRIPTION =
207        "GuiAC.FILE_EXTENSIONS_DESCRIPTION";
208        // String
209        public static final String FILE_CHOOSER_VIEW = "GuiAC.FILE_CHOOSER_VIEW";
210        public static final String FILE_EDITOR_CONFIG = "GuiAC.FILE_EDITOR_CONFIG";
211    
212        public static final String INDEXED_FIELD_SELECTOR =
213        "GuiAC.INDEXED_FIELD_SELECTOR";
214        // CollectionItem
215        public static final String INDEX_NOT_FOUND_HANDLER =
216        "RttiAC.INDEX_NOT_FOUND_HANDLER";
217        // MethodItem
218    
219        public static final String REPOSITORY_NAME = "GuiAC.REPOSITORY_NAME";
220    
221        // Context attributes
222    
223        public static final String DISPLAY_CONTEXT = "GuiAC.DISPLAY";
224        /** A "concrete" method we should ask parameters for */
225        public static final String ASK_FOR_PARAMETERS = "GuiAC.ASK_FOR_PARAMETERS";
226        /** The "not concrete" method we should ask parameters for */
227        public static final String INVOKED_METHOD = "GuiAC.INVOKED_METHOD";
228        public static final String AUTO_CREATION = "GuiAC.AUTO_CREATION";
229        public static final String AUTOCREATE_REASON = "GuiAC.AUTOCREATE_REASON";
230        // Boolean
231        /** Boolean value to force the use of embedded editors. Defaults to false. */
232        //public static final String EMBEDDED_EDITORS = "GuiAC.EMBEDDED_EDITORS";
233        // Boolean
234        public static final String SMALL_VIEW = "GuiAC.SMALL_VIEW"; // Boolean
235        public static final String OPPOSITE_ROLE = "GuiAC.OPPOSITE_ROLE";
236        // FieldItem
237        public static final String VIEW = "GuiAC.VIEW";
238        public static final String OPEN_VIEW = "GuiAC.OPEN_VIEW"; // Boolean
239        public static final String GRAPHIC_CONTEXT = "GuiAC.GRAPHIC_CONTEXT";
240    
241        /** Start index in a collection view Map (CollectionItem -> Integer) */
242        public static final String START_INDEXES = "GuiAC.START_INDEXES";
243    
244        public static final int THUMB_MAX_WIDTH = 100;
245        public static final int THUMB_MAX_HEIGHT = 50;
246        public static final int THUMB_QUALITY = 70;
247    
248        // Map: CollectionItem -> column index
249        public static final String SORT_COLUMN = "GuiAC.SORT_COLUMN"; // [+-]?<fieldname>
250        public static final String DEF_SORT = "GuiAC.DEF_SORT";
251    
252        // Map: CollectionItem -> ColumnFilter
253        public static final String TABLE_FILTER = "GuiAC.TABLE_FILTER";
254        
255    
256        /** Disable commit in editors */
257        //public static final String NO_COMMIT = "GuiAC.NO_COMMIT";
258    
259        /** Substance on which the method is invoked. Set when auto creating parameters */
260        public static final String SUBSTANCE = "GuiAC.SUBSTANCE"; // Wrappee
261    
262        /** TreeNode being removed, to optimize Tree refresh */
263        public static final String REMOVED_NODE = "GuiAC.REMOVED_NODE";
264    
265        static String parseFormatExpression(
266            String formatExpr,
267            Object o,
268            String beforeString,
269            String afterString) 
270        {
271            final String delim = "%";
272            StringBuffer result = new StringBuffer();
273            String subString = null;
274            ClassItem cl = ClassRepository.get().getClass(o);
275            StringTokenizer st = new StringTokenizer(formatExpr, delim, true);
276            while (st.hasMoreTokens()) {
277                boolean firstDelim = false;
278                String cur = st.nextToken();
279                // normal string
280                if (!cur.equals(delim)) {
281                    result.append(cur);
282                    continue;
283                }
284                // delimited expression
285                if (cur.equals(delim)) {
286                    cur = st.nextToken();
287                                    // double delim
288                    if (cur.equals(delim)) {
289                        result.append(delim);
290                        continue;
291                    }
292                    if (cur.indexOf("()") == -1) {
293                        // field name
294                        try {
295                            FieldItem field = cl.getField(cur);
296                            Object value = field.getThroughAccessor(o);
297                            if (beforeString != null) {
298                                result.append(beforeString);
299                            }
300                            if (field != null)
301                                result.append(GuiAC.toString(field, value));
302                            else
303                                result.append("<bad field: " + cur + ">");
304                            if (afterString != null) {
305                                result.append(afterString);
306                            }
307                        } catch (Exception e) {
308                            // bad field description
309                            result.append("<bad field: " + cur + ">");
310                        }
311                    } else {
312                        // method with no args
313                        try {
314                            Object value =
315                                ClassRepository.invokeDirect(
316                                    cl.getActualClass(),
317                                    cur.substring(0, cur.length() - 2),
318                                    o,
319                                    ExtArrays.emptyObjectArray);
320                            ;
321                            if (beforeString != null) {
322                                result.append(beforeString);
323                            }
324                            result.append(GuiAC.toString(value));
325                            if (afterString != null) {
326                                result.append(afterString);
327                            }
328                        } catch (Exception e) {
329                            // bad method description
330                            result.append(
331                                "<bad method: "
332                                + cur.substring(0, cur.length() - 2)
333                                + ">");
334                        }
335                    }
336                                    // read closing delim
337                    cur = st.nextToken();
338                }
339            }
340            return result.toString();
341        }
342    
343        public static String toString(Object o) {
344            return toString(o, null);
345        }
346    
347        public static String toString(float value) {
348            return toString(new Float(value), null);
349        }
350    
351        public static String toString(double value) {
352            return toString(new Double(value), null);
353        }
354    
355        /**
356         * Gets the string representation of an object.
357         * @param o the object
358         * @return a string representing the object o
359         * @see #setToString(ClassItem,String)
360         */
361        public static String toString(Object o, Stack context) {
362            if (o == null)
363                return "null";
364            ClassItem cl = ClassRepository.get().getClass(o);
365    
366            String formatExpr = (String) cl.getAttribute(TO_STRING);
367            if (context != null) {
368                formatExpr =
369                    (String) getContextAttribute(cl,
370                                                 CONTEXTUAL_TO_STRING,
371                                                 context,
372                                                 formatExpr);
373            }
374            if (formatExpr == null) {
375                if (o instanceof java.awt.Point) {
376                    java.awt.Point p = (java.awt.Point) o;
377                    return "(" + p.x + "," + p.y + ")";
378                } else if (o instanceof java.awt.Dimension) {
379                    java.awt.Dimension d = (java.awt.Dimension) o;
380                    return d.width + "x" + d.height;
381                } else if (o instanceof Date) {
382                    return new SimpleDateFormat(getDateFormat()).format((Date) o);
383                } else if (o instanceof Collection) {
384                    String string = "";
385                    Iterator it = ((Collection) o).iterator();
386                    while (it.hasNext()) {
387                        string += toString(it.next(), context);
388                        if (it.hasNext())
389                            string += ", ";
390                    }
391                    return string;
392                } else if (o instanceof Wrappee) {
393                    return NameRepository.get().getName(o);
394                } else {
395                    return o.toString();
396                }
397            } else {
398                return parseFormatExpression(formatExpr, o, null, null);
399            }
400        }
401    
402        /**
403         * Gets the tooltip text of an object.
404         * @param context a stack of meta items representing the context
405         * @param o the object
406         * @return the tooltip of the object in the given context
407         * @see #setToolTipText(ClassItem,String)
408         */
409        public static String getToolTip(Object o, Stack context) {
410            if (o == null)
411                return null;
412            ClassItem cl = ClassRepository.get().getClass(o);
413    
414            String formatExpr = (String) cl.getAttribute(TOOLTIP);
415            if (context != null) {
416                formatExpr =
417                    (String) getContextAttribute(cl,
418                                                 CONTEXTUAL_TOOLTIP,
419                                                 context,
420                                                 formatExpr);
421            }
422            if (formatExpr == null) {
423                return null;
424            } else {
425                return parseFormatExpression(formatExpr, o, null, null);
426            }
427        }
428    
429        /**
430         * @param item item holding the rules
431         * @param attribute name of attribute holding the rules
432         * @param defaultValue this value is returned if there is not matching context
433         */
434        public static Object getContextAttribute(
435            MetaItem item,
436            String attribute,
437            Stack context,
438            Object defaultValue) 
439        {
440            loggerContext.debug("getContextAttribute " + item + "," + attribute);
441            Map rules = (Map) item.getAttribute(attribute);
442            if (rules == null) {
443                loggerContext.debug("No attribute " + attribute);
444                return defaultValue;
445            } else {
446                if (context != null) {
447                    loggerContext.debug("rules = " + rules);
448                    for (int i = 0; i < context.size(); i++) {
449                        MetaItem elt = (MetaItem) context.peek(i);
450                        Iterator it = rules.keySet().iterator();
451                        while (it.hasNext()) {
452                            MetaItem selector = (MetaItem) it.next();
453                            if (selector instanceof ClassItem) {
454                                ClassItem cl = (ClassItem) selector;
455                                if ((elt instanceof ClassItem
456                                     && ((ClassItem) elt).isSubClassOf(cl))
457                                    || (elt instanceof MemberItem
458                                        && ((MemberItem) elt)
459                                        .getClassItem()
460                                        .isSubClassOf(cl))) {
461                                    loggerContext.debug(elt + " matches " + selector
462                                        + " -> " + rules.get(selector));
463                                    return rules.get(selector);
464                                }
465                            } else if (selector instanceof MemberItem) {
466                                MemberItem member = (MemberItem) selector;
467                                if (elt instanceof MemberItem) {
468                                    if (((MemberItem) elt)
469                                        .getClassItem()
470                                        .isSubClassOf(member.getClassItem())
471                                        && member.getName().equals(elt.getName())) {
472                                        loggerContext.debug(elt + " matches " + selector
473                                            + " -> " + rules.get(selector));
474                                        return rules.get(selector);
475                                    }
476                                }
477                            }
478                        }
479                    }
480                    return defaultValue;
481                } else {
482                    loggerContext.debug("No graphic context");
483                    return defaultValue;
484                }
485            }
486        }
487    
488        public static void pushGraphicContext(MetaItem value) {
489            Collaboration collab = Collaboration.get();
490            Stack gc = (Stack) collab.getAttribute(GRAPHIC_CONTEXT);
491            if (gc == null) {
492                gc = new Stack();
493                collab.addAttribute(GRAPHIC_CONTEXT, gc);
494            }
495            loggerContext.debug("push " + value);
496            gc.push(value);
497        }
498    
499        public static MetaItem popGraphicContext() {
500            Stack gc = (Stack) Collaboration.get().getAttribute(GRAPHIC_CONTEXT);
501            if (gc == null) {
502                loggerContext.error(
503                    "No GRAPHIC_CONTEXT in current context, cannot popGraphicContext");
504                return null;
505            } else {
506                loggerContext.debug("pop " + gc.peek());
507                return (MetaItem) gc.pop();
508            }
509        }
510    
511        public static Stack getGraphicContext() {
512            return (Stack) Collaboration.get().getAttribute(GRAPHIC_CONTEXT);
513        }
514    
515        /**
516         * Gets the string representation of the field of an object.
517         * @param field the field
518         * @param value the value of the field
519         * @return a string representing the value of the field
520         */
521        public static String toString(FieldItem field, Object value) {
522            if (value == null) {
523                return "null";
524            }
525            Enum enum = getEnum(field);
526            if (enum != null) {
527                try {
528                    return value != null
529                        ? enum.int2string(((Integer) value).intValue())
530                        : "";
531                } catch (InvalidIndexException e) {
532                    return "";
533                }
534            } else if (value instanceof Date) {
535                return new SimpleDateFormat(getDateFormat()).format((Date) value);
536            } else {
537                return toString(value);
538            }
539        }
540    
541        /**
542         * Gets the string representation of the field of an object.
543         * @param field the field
544         * @param value the value of the field
545         * @return a string representing the value of the field
546         */
547        public static String toString(FieldItem field, int value) {
548            return toString(field, new Integer(value));
549        }
550    
551        /**
552         * Gets a display from its ID.
553         *
554         * @param displayID the id of the display
555         * @see Display  */
556    
557        public static final Display getDisplay(String displayID) {
558            return (Display) displays.get(displayID);
559        }
560    
561        /**
562         * Gets a display from its ID.
563         *
564         * @param customizedID the id of the customized gui
565         * @see Display  
566         */
567        public static final CustomizedGUI getCustomized(String customizedID) {
568            return (CustomizedGUI) cguis.get(customizedID);
569        }
570    
571        /**
572         * This configuration method creates a new display and registers
573         * its.
574         *
575         * @param displayID the display name
576         * @param displayType the display type 
577         */
578        public static Display createDisplay(
579            String displayID,
580            Class displayType,
581            ViewFactory factory) 
582        {
583            Display ret = null;
584            loggerDisplay.debug("createDisplay(" + displayType.getName() + "," + displayType + ")");
585            if ((ret = getDisplay(displayID)) != null) {
586                loggerDisplay.warn("Display " + displayID + " is already registered");
587                return ret;
588            }
589            try {
590                ret =
591                    (Display) displayType
592                    .getDeclaredConstructor(new Class[] { ViewFactory.class })
593                    .newInstance(new Object[] { factory });
594    
595                ret.setDisplayID(displayID);
596                addDisplay(displayID, ret);
597            } catch (Exception e) {
598                e.printStackTrace();
599            }
600            return ret;
601        }
602    
603        public void createSwingDisplays(String[] customizedIDs) {
604            loggerDisplay.debug("createSwingDisplays(" + Arrays.asList(customizedIDs) + ")");
605            for (int i = 0; i < customizedIDs.length; i++) {
606                if (customizedIDs[i].equals("admin")) {
607                                    // createDisplay("admin",org.objectweb.jac.aspects.gui.swing.ProgramView.class,null);
608                } else {
609                    showCustomizedSwing(customizedIDs[i], customizedIDs[i]);
610                }
611            }
612        }
613    
614        public void createWebDisplays(String[] customizedIDs) {
615            int port = 8088;
616            try {
617                logger.info(
618                    "createWebDisplays "+Arrays.asList(customizedIDs)+
619                    " for application " + application);
620                org.objectweb.jac.aspects.gui.web.WebDisplay.startWebServer(
621                    application,
622                    customizedIDs,
623                    port);
624            } catch (Exception e) {
625                loggerDisplay.error("Failed to start webgui : " + e);
626                loggerDisplay.error("Check that another server is not running on port " + port);
627            }
628        }
629    
630        /**
631         * Adds a new display for this GUI.
632         *
633         * @param newDisplay the display to add
634         * @see Display 
635         */
636        public static void addDisplay(String displayID, Display newDisplay) {
637            loggerDisplay.debug("addDisplay(" + newDisplay.getClass().getName() + ")");
638            displays.put(displayID, newDisplay);
639        }
640    
641        /**
642         * Removes a display for this GUI.
643         *
644         * @param display the display to remove
645         * @see Display */
646    
647        public static void removeDisplay(Display display) {
648            if (display.getDisplayID() != null)
649                displays.remove(display.getDisplayID());
650        }
651    
652        /**
653         * This configuration method allows the user to register a new
654         * display.
655         * 
656         * <p>It instantiates a new display from its class name and
657         * registers its.
658         * 
659         * @param name the display name
660         * @param displayType the display type */
661    
662        public static void registerDisplay(
663            String name,
664            String displayType,
665            String guiType) 
666        {
667            try {
668                if (getDisplay(name) != null) {
669                    loggerDisplay.warn("display " + name + " is already launched");
670                    return;
671                }
672                createDisplay(
673                    name,
674                    Class.forName(displayType),
675                    getViewFactory(guiType));
676            } catch (Exception e) {
677                e.printStackTrace();
678            }
679        }
680    
681        public void registerCustomized(String name) {
682            try {
683                if (getCustomized(name) != null) {
684                    warning("customized GUI " + name + " is already registered");
685                    return;
686                }
687                CustomizedGUI cgui = new CustomizedGUI(name);
688                // the customized gui knows the application it belongs to
689                loggerApp.debug("customized gui " + name
690                                + " belongs to " + Collaboration.get().getCurApp());
691                cgui.setApplication(Collaboration.get().getCurApp());
692                cguis.put(name, cgui);
693            } catch (Exception e) {
694                e.printStackTrace();
695            }
696        }
697    
698        public void showCustomizedSwing(
699            String displayName,
700            String gui,
701            String host) 
702        {
703            CustomizedGUI cgui = (CustomizedGUI) getCustomized(gui);
704            if (cgui == null) {
705                error(gui+" has not been declared with registerCustomized. "+
706                      "Available customized GUI: " + cguis.keySet());
707                return;
708            }
709            if (host == null
710                || RemoteContainer.resolve(host) == null
711                || RemoteContainer.resolve(host).getName().equals(
712                    Distd.getLocalContainerName())) {
713                registerDisplay(
714                    displayName,
715                    "org.objectweb.jac.aspects.gui.swing.SwingDisplay",
716                    "swing");
717    
718                Display swingGUI = getDisplay(displayName);
719                Collaboration.get().addAttribute(
720                    DISPLAY_CONTEXT,
721                    new DisplayContext((CustomizedDisplay) swingGUI, null));
722                Collaboration.get().addAttribute(
723                    SessionAC.SESSION_ID,
724                    GuiAC.getLocalSessionID());
725                swingGUI.showCustomized(gui, cgui);
726                //swingGUI.applicationStarted();
727            } else {
728                displays.remove(gui);
729            }
730            //      ((ACManager)ACManager.get()).afterApplicationStarted();
731        }
732    
733        public void showCustomizedSwing(String displayName, String gui) {
734            showCustomizedSwing(displayName, gui, null);
735        }
736    
737        public void setWelcomeMessage(
738            String gui,
739            String title,
740            String message,
741            String icon) 
742        {
743            CustomizedGUI cgui = (CustomizedGUI) getCustomized(gui);
744            if (cgui == null) {
745                error(gui+" has not been declared with registerCustomized");
746                return;
747            }
748            cgui.setWelcomeMessage(title, message, icon);
749        }
750    
751        public void setStyle(FieldItem field, String style) {
752            if (style != null) {
753                field.setAttribute(STYLE, style);
754            }
755        }
756    
757        public void setStyle(ClassItem cli, String style) {
758            if (style != null) {
759                cli.setAttribute(STYLE, style);
760            }
761        }
762    
763        public void setOnCloseHandler(
764            String gui,
765            AbstractMethodItem eventHandler) 
766        {
767            CustomizedGUI cgui = (CustomizedGUI) getCustomized(gui);
768            if (cgui == null) {
769                error(gui+" has not been declared with registerCustomized");
770                return;
771            }
772            cgui.setOnCloseHandler(eventHandler);
773        }
774    
775        public void addStatusBar(String gui, MethodItem method, String position) {
776            CustomizedGUI cgui = (CustomizedGUI) getCustomized(gui);
777            if (cgui == null) {
778                error(gui+" has not been declared with registerCustomized");
779                return;
780            }
781            cgui.addStatusBar(method, position);
782        }
783    
784        public void addStatusBar(String gui, String position) {
785            CustomizedGUI cgui = (CustomizedGUI) getCustomized(gui);
786            if (cgui == null) {
787                error(gui+" has not been declared with registerCustomized");
788                return;
789            }
790            cgui.addStatusBar(null, position);
791        }
792    
793        public void setSubPanesGeometry(
794            String gui,
795            int subPanesCount,
796            String geometry) 
797        {
798            boolean[] scrollings = new boolean[subPanesCount];
799            Arrays.fill(scrollings, true);
800            setSubPanesGeometry(gui, subPanesCount, geometry, scrollings);
801        }
802    
803        public void setSubPanesGeometry(
804            String gui,
805            int subPanesCount,
806            String geometry,
807            boolean[] scrollings) 
808        {
809            if (subPanesCount != scrollings.length) {
810                throw new RuntimeException("setSubPanesGeometry: subPanesCount!=scrollings.length");
811            }
812            CustomizedGUI cgui = (CustomizedGUI) getCustomized(gui);
813            if (cgui == null) {
814                logger.error(gui+" has not been declared with registerCustomized");
815                return;
816            }
817            int geom = 0;
818            if (geometry.compareToIgnoreCase("VERTICAL")==0)
819                geom = CustomizedGUI.VERTICAL;
820            else if (geometry.compareToIgnoreCase("VERTICAL_LEFT")==0)
821                geom = CustomizedGUI.VERTICAL_LEFT;
822            else if (geometry.compareToIgnoreCase("VERTICAL_RIGHT")==0)
823                geom = CustomizedGUI.VERTICAL_RIGHT;
824            else if (geometry.compareToIgnoreCase("HORIZONTAL")==0)
825                geom = CustomizedGUI.HORIZONTAL;
826            else if (geometry.compareToIgnoreCase("HORIZONTAL_UP")==0)
827                geom = CustomizedGUI.HORIZONTAL_UP;
828            else if (geometry.compareToIgnoreCase("HORIZONTAL_DOWN")==0)
829                geom = CustomizedGUI.HORIZONTAL_DOWN;
830            else if (geometry.compareToIgnoreCase("NONE")==0)
831                geom = CustomizedGUI.HORIZONTAL;
832            else
833                warning("Unknown geometry '"+geometry+"'");
834            cgui.setSubPanesGeometry(subPanesCount, geom, scrollings);
835        }
836    
837        public void setPaneContent(
838            String gui,
839            String paneId,
840            String type,
841            String[] args) 
842        {
843            CustomizedGUI cgui = (CustomizedGUI) getCustomized(gui);
844            if (cgui == null) {
845                error(gui+" has not been declared with registerCustomized");
846                return;
847            }
848            cgui.setPaneContent(paneId, type, args);
849        }
850    
851        public void setPaneContainer(String gui, String paneId, String type) {
852            CustomizedGUI cgui = (CustomizedGUI) getCustomized(gui);
853            if (cgui == null) {
854                error(gui+" has not been declared with registerCustomized");
855                return;
856            }
857            cgui.setPaneContainer(paneId, type);
858        }
859    
860        public void setInvalidPane(
861            String gui,
862            String changedPane,
863            String invalidPane) 
864        {
865            CustomizedGUI cgui = (CustomizedGUI) getCustomized(gui);
866            if (cgui == null) {
867                error(gui+" has not been declared with registerCustomized");
868                return;
869            }
870            cgui.setInvalidPane(changedPane, invalidPane);
871        }
872    
873        public void addReferenceToPane(
874            String gui,
875            MemberItem field,
876            String panePath) 
877        {
878            addReferenceToPane(
879                gui,
880                field,
881                "Object",
882                new String[] { DEFAULT_VIEW },
883                Boolean.FALSE,
884                panePath);
885        }
886    
887        public void addReferenceToPane(
888            String gui,
889            MemberItem member,
890            String viewType,
891            String[] viewParams,
892            Boolean small,
893            String paneId) 
894        {
895            CustomizedGUI cgui = (CustomizedGUI) getCustomized(gui);
896            if (cgui == null) {
897                error(gui+" has not been declared with registerCustomized");
898                return;
899            }
900            member.setAttribute(SMALL_TARGET_CONTAINER, small);
901            cgui.addReferenceToPane(member, viewType, viewParams, paneId);
902        }
903    
904        public void newWindow(String gui, String className, String fieldName) {
905    
906            CustomizedGUI cgui = (CustomizedGUI) getCustomized(gui);
907            if (cgui == null) {
908                error(gui+" has not been declared with registerCustomized");
909                return;
910            }
911            ClassItem cli = ClassRepository.get().getClass(className);
912            FieldItem field = cli.getField(fieldName);
913            field.setAttribute(NEW_WINDOW, gui);
914        }
915    
916        public void setCustomizedIcon(String gui, String icon) {
917            CustomizedGUI cgui = (CustomizedGUI) getCustomized(gui);
918            if (cgui == null) {
919                error(gui+" has not been declared with registerCustomized");
920                return;
921            }
922            cgui.setIcon(icon);
923        }
924    
925        public void setPosition(
926            String gui,
927            int left,
928            int up,
929            int width,
930            int height) 
931        {
932            CustomizedGUI cgui = (CustomizedGUI) getCustomized(gui);
933            if (cgui == null) {
934                error(gui+" has not been declared with registerCustomized");
935                return;
936            }
937            cgui.setPosition(left, up, width, height);
938        }
939    
940        public void addMenuItem(
941            String gui,
942            String menu,
943            String[] menuPath,
944            AbstractMethodItem callback) 
945        {
946            addMenuItem(gui, menu, menuPath, null, callback, null);
947        }
948    
949        public void addMenuItem(
950            String gui,
951            String menu,
952            String[] menuPath,
953            String objectName,
954            AbstractMethodItem callback) 
955        {
956            addMenuItem(gui, menu, menuPath, objectName, callback, null);
957        }
958    
959        public void addMenuItem(
960            String gui,
961            String menu,
962            String[] menuPath,
963            AbstractMethodItem callback,
964            String[] parameters) 
965        {
966            addMenuItem(gui, menu, menuPath, null, callback, parameters);
967        }
968    
969        public void addMenuItem(
970            String gui,
971            String menu,
972            String[] menuPath,
973            String objectName,
974            AbstractMethodItem callback,
975            String[] parameters) 
976        {
977            CustomizedGUI cgui = (CustomizedGUI) getCustomized(gui);
978            if (cgui == null) {
979                error(gui+" has not been declared with registerCustomized");
980                return;
981            }
982            cgui.addMenuItem(
983                menu,
984                menuPath,
985                new Callback(objectName, callback, parameters));
986        }
987    
988        public void addMenuSeparator(String gui, String menu, String[] menuPath) {
989            CustomizedGUI cgui = (CustomizedGUI) getCustomized(gui);
990            if (cgui == null) {
991                error(gui+" has not been declared with registerCustomized");
992                return;
993            }
994            cgui.addMenuSeparator(menu, menuPath);
995        }
996    
997        public void setMenuPosition(String gui, String menu, String position) {
998            CustomizedGUI cgui = (CustomizedGUI) getCustomized(gui);
999            if (cgui == null) {
1000                error(gui+" has not been declared with registerCustomized");
1001                return;
1002            }
1003            cgui.setMenuPosition(menu, position);
1004        }
1005    
1006        public void setMenuIcon(
1007            String gui,
1008            String menu,
1009            String[] menuPath,
1010            String icon) 
1011        {
1012            CustomizedGUI cgui = (CustomizedGUI) getCustomized(gui);
1013            if (cgui == null) {
1014                error(gui+" has not been declared with registerCustomized");
1015                return;
1016            }
1017            cgui.setMenuIcon(menu, menuPath, ResourceManager.getResource(icon));
1018        }
1019    
1020        public void addToolbarAction(String gui, AbstractMethodItem method) {
1021            CustomizedGUI cgui = (CustomizedGUI) getCustomized(gui);
1022            if (cgui == null) {
1023                error(gui+" has not been declared with registerCustomized");
1024                return;
1025            }
1026            cgui.addToolbarAction(method);
1027        }
1028    
1029        public void addToolbarAction(
1030            String gui,
1031            String objectName,
1032            AbstractMethodItem method) 
1033        {
1034            CustomizedGUI cgui = (CustomizedGUI) getCustomized(gui);
1035            if (cgui == null) {
1036                error(gui+" has not been declared with registerCustomized");
1037                return;
1038            }
1039            cgui.addToolbarAction(objectName, method);
1040        }
1041    
1042        public void addToolbarSeparator(String gui) {
1043            CustomizedGUI cgui = (CustomizedGUI) getCustomized(gui);
1044            if (cgui == null) {
1045                error(gui+" has not been declared with registerCustomized");
1046                return;
1047            }
1048            cgui.addToolbarSeparator();
1049        }
1050    
1051        public void setSplitterLocation(
1052            String gui,
1053            int splitterId,
1054            float location)
1055        {
1056            CustomizedGUI cgui = (CustomizedGUI) getCustomized(gui);
1057            if (cgui == null) {
1058                error(gui+" has not been declared with registerCustomized");
1059                return;
1060            }
1061            cgui.setSplitterLocation(splitterId, location);
1062        }
1063    
1064        public void setTitle(String gui, String title) {
1065            CustomizedGUI cgui = (CustomizedGUI) getCustomized(gui);
1066            if (cgui == null) {
1067                error(gui+" has not been declared with registerCustomized");
1068                return;
1069            }
1070            cgui.setTitle(title);
1071        }
1072    
1073        public void addStyleSheetURL(String gui, String url) {
1074            CustomizedGUI cgui = (CustomizedGUI) getCustomized(gui);
1075            if (cgui == null) {
1076                error(gui+" has not been declared with registerCustomized");
1077                return;
1078            }
1079            cgui.addStyleSheetURL(url);
1080        }
1081    
1082        static Vector cssURLs = new Vector();
1083        public void addStyleSheetURL(String url) {
1084            cssURLs.add(url);
1085        }
1086        static public Vector getStyleSheetURLs() {
1087            return cssURLs;
1088        }
1089    
1090        public void setLoggingMethod(
1091            String gui,
1092            String objects,
1093            String classes,
1094            String methods,
1095            int paneID) 
1096        {
1097            CustomizedGUI cgui = (CustomizedGUI) getCustomized(gui);
1098            if (cgui == null) {
1099                error(gui+" has not been declared with registerCustomized");
1100                return;
1101            }
1102            /*
1103              JPanel pane = cgui.getPane(paneID);
1104              JTextArea textArea = new JTextArea();
1105              pane.add(textArea);
1106              pointcut( objects, classes, methods, 
1107              new LoggingWrapper(textArea), 
1108              "logIntoConsole");
1109            */
1110        }
1111    
1112        /**
1113         * The wrapper that logs methods into a Swing console. */
1114        /*
1115          public class LoggingWrapper extends Wrapper {
1116          JTextArea console;
1117          public LoggingWrapper(JTextArea console) {
1118          this.console = console;
1119          }
1120          public Object logIntoConsole() {
1121          if( console != null ) {
1122          console.append( (String)arg(0) );
1123          console.setCaretPosition( console.getText().length() );
1124          }
1125          return proceed();
1126          }
1127          }
1128        */
1129    
1130        public void defineResource(String type, String name, String path) {
1131            ResourceManager.defineResource(name, path);
1132        }
1133    
1134        public void setIcon(ClassItem cli, String name) {
1135            cli.setAttribute(ICON, ResourceManager.getResource(name));
1136        }
1137    
1138        public void setIcon(MemberItem member, String name) {
1139            member.setAttribute(ICON, ResourceManager.getResource(name));
1140        }
1141    
1142        public void setDynamicIcon(MethodItem method, MethodItem iconMethod) {
1143            method.setAttribute(DYNAMIC_ICON, iconMethod);
1144        }
1145    
1146        public void setDynamicIcon(ClassItem cli, MethodItem iconMethod) {
1147            cli.setAttribute(DYNAMIC_ICON, iconMethod);
1148        }
1149    
1150        /**
1151         * Returns the icon associated with this item. If no icon was set
1152         * with one the of setIcon() configuration methods, we try to
1153         * return a reasonable default.
1154         *
1155         * @see #setIcon(ClassItem,String)
1156         * @see #setIcon(MemberItem,String) 
1157         */
1158        public static String getIcon(MetaItem item) {
1159            String result = (String)item.getAttribute(ICON);
1160            if (result == null) {
1161                if (item instanceof MethodItem) {
1162                    MethodItem method = (MethodItem)item;
1163                    if (method.isSetter()) {
1164                        result = ResourceManager.getResource("edit_icon");
1165                    } else if (method.isAdder()) {
1166                        if (method.getParameterTypes().length > 0) {
1167                            result =
1168                                getIcon(
1169                                    ClassRepository.get().getClass(
1170                                        method.getParameterTypes()[0]));
1171                        }
1172                        if (result == null)
1173                            result = ResourceManager.getResource("new_icon");
1174                    } else if (method.isRemover()) {
1175                        result = ResourceManager.getResource("remove_icon");
1176                    }
1177                }
1178            }
1179            return result;
1180        }
1181    
1182        /**
1183         * Gets an icon for an object
1184         * @param cli the class of the object
1185         * @param object the object
1186         * @return an icon's resource name
1187         */
1188        public static String getIcon(ClassItem cli, Object object) {
1189            MethodItem dynIcon = (MethodItem)cli.getAttribute(DYNAMIC_ICON);
1190            String icon = null;
1191            if (dynIcon!=null) {
1192                icon = (String)dynIcon.invokeStatic(new Object[] {object});
1193            }
1194            if (icon==null)
1195                icon = (String)cli.getAttribute(ICON);
1196            return icon;
1197        }
1198    
1199        public static String getIcon(Callback callback) {
1200            AbstractMethodItem method = callback.getMethod();
1201            String icon =
1202                method != null ? GuiAC.getIcon(method) : null;
1203            if (method != null) {
1204                MethodItem dynIcon = (MethodItem)method.getAttribute(DYNAMIC_ICON);
1205                if (dynIcon!=null) {
1206                    icon = (String)dynIcon.invokeStatic(
1207                        new Object[] {
1208                            method,
1209                            callback.getObject(), 
1210                            callback.getParameters()});
1211                }
1212            }
1213            if (icon == null) {
1214                icon = ResourceManager.getResource("blank_icon");
1215            }
1216            return icon;
1217        }
1218    
1219        public void hideTreeRelation(FieldItem field) {
1220            field.setAttribute(HIDDEN_TREE_RELATION, Boolean.TRUE);
1221        }
1222    
1223        public void setMenu(ClassItem classItem, String[] menu) {
1224            MethodItem[] methods = new MethodItem[menu.length];
1225            for (int i = 0; i < menu.length; i++) {
1226                if (menu[i].equals(""))
1227                    methods[i] = null;
1228                else
1229                    try {
1230                        methods[i] = classItem.getMethod(menu[i]);
1231                    } catch (NoSuchMethodException e) {
1232                        warning(e.toString());
1233                        methods[i] = null;
1234                    }
1235            }
1236            classItem.setAttribute(MENU, methods);
1237        }
1238    
1239        public static MethodItem[] getMenu(ClassItem classItem) {
1240            Vector methods = new Vector();
1241            while (classItem != null) {
1242                MethodItem[] curmenu = (MethodItem[]) classItem.getAttribute(MENU);
1243                if (curmenu != null) {
1244                    for (int i = curmenu.length - 1; i >= 0; i--) {
1245                        if (!methods.contains(curmenu[i]))
1246                            methods.add(0, curmenu[i]);
1247                    }
1248                }
1249                classItem = classItem.getSuperclass();
1250            }
1251            MethodItem[] result = new MethodItem[methods.size()];
1252            for (int i = 0; i < result.length; i++) {
1253                result[i] = (MethodItem) methods.get(i);
1254            }
1255            return result;
1256        }
1257    
1258        /**
1259         * Catch this event and remove the display from the handled list if
1260         * exists.
1261         *
1262         * @param display the closing display */
1263    
1264        public void whenCloseDisplay(Display display) {
1265            removeDisplay(display);
1266        }
1267    
1268        public void whenReload() {
1269            Iterator it = displays.values().iterator();
1270            while (it.hasNext()) {
1271                Display display = (Display) it.next();
1272                if (display
1273                    .getClass()
1274                    .getName()
1275                    .equals("org.objectweb.jac.aspects.gui.swing.SwingDisplay")) {
1276                    loggerDisplay.debug("Refreshing display " + display);
1277                    display.fullRefresh();
1278                }
1279            }
1280        }
1281    
1282        public void beforeReload() {
1283            cguis.clear();
1284        }
1285    
1286        /**
1287         * The default constructor for the GUI aspect component.
1288         *
1289         * <p>By default it defines the visible property to false for some
1290         * JAC system items.
1291         *
1292         */
1293    
1294        public GuiAC() {
1295            blockKeywords = new String[] { "menu", "window", "view" };
1296            setDefaults();
1297        }
1298    
1299        /**
1300         * Defines the visible property to false for some JAC system items.  
1301         */
1302        public void setDefaults() {
1303            ClassRepository cr = ClassRepository.get();
1304            ClassItem nameRepositoryClass =
1305                cr.getClass("org.objectweb.jac.core.NameRepository");
1306            ClassItem acManagerClass =
1307                cr.getClass("org.objectweb.jac.core.ACManager");
1308            ClassItem topologyClass =
1309                cr.getClass("org.objectweb.jac.core.dist.Topology");
1310    
1311            setVisible(nameRepositoryClass.getField("names"), false);
1312            setVisible(
1313                acManagerClass,
1314                new String[] { "registering", "orderedObjects", "orderedNames" },
1315                false);
1316    
1317            setVisible(topologyClass.getField("nameReps"), false);
1318            setVisible(
1319                topologyClass.getMember(
1320                    "getContainerIndex(org.objectweb.jac.core.dist.RemoteContainer)"),
1321                false);
1322            setVisible(
1323                topologyClass.getMember("getContainerIndex(java.lang.String)"),
1324                false);
1325            setVisible(
1326                topologyClass.getMember("getContainerIndexes(gnu.regexp.RE)"),
1327                false);
1328            setVisible(
1329                topologyClass.getMember("getContainerIndexes(java.lang.String[])"),
1330                false);
1331            setVisible(topologyClass.getMember("countContainers"), false);
1332            setVisible(
1333                topologyClass.getMember("getContainer(java.lang.String)"),
1334                false);
1335            setVisible(topologyClass.getMember("getContainer(int)"), false);
1336            setVisible(topologyClass.getMember("isContainer"), false);
1337            setVisible(topologyClass.getMember("createNameReps"), false);
1338    
1339            setTableView(topologyClass.getField("containers"));
1340    
1341            setDirectCollectionMethods(
1342                topologyClass.getCollection("containers"),
1343                new String[] { "launchRemoteGUI" });
1344    
1345            ClassItem rmiStubClass =
1346                cr.getClass(
1347                    "org.objectweb.jac.core.dist.rmi.RMIRemoteContainerStub");
1348            setVisible(rmiStubClass.getMember("copy"), false);
1349            setVisible(rmiStubClass.getMember("getByteCodeFor"), false);
1350            setVisible(rmiStubClass.getMember("instantiates"), false);
1351    
1352            ClassItem applicationClass =
1353                cr.getClass("org.objectweb.jac.core.Application");
1354    
1355            setVisible(applicationClass.getMember("props"), false);
1356            //      applicationClass.setAttribute("GuiAC.List.showItem", applicationClass.getMethod("getName"));
1357            ClassItem applicationManagerClass =
1358                cr.getClass("org.objectweb.jac.core.ApplicationRepository");
1359    
1360            setTableMembersOrder(applicationClass,new String[] {"name","constructorClass","instantiated"});
1361    
1362            setViewOnSelection(
1363                applicationManagerClass.getCollection("applications"));
1364            setAutoCreate(applicationManagerClass.getField("applications"));
1365    
1366            applicationManagerClass.getMethod("addApplication").setAttribute(
1367                ASKING_SEQUENCE,
1368                new Object[] { "autoCreate" });
1369            setVisible(applicationManagerClass.getMember("getApplication"), false);
1370    
1371            setCategories(
1372                applicationClass,
1373                new String[] { "Aspects", "Properties" });
1374    
1375            setCategory(applicationClass.getMember("name"), "Properties");
1376            setCategory(applicationClass.getMember("path"), "Properties");
1377            setCategory(applicationClass.getMember("instantiated"), "Properties");
1378            setCategory(
1379                applicationClass.getMember("constructorClass"),
1380                "Properties");
1381            setCategory(applicationClass.getMember("arguments"), "Properties");
1382            setCategory(applicationClass.getMember("start"), "Properties");
1383    
1384            setCategory(applicationClass.getMember("acs"), "Aspects");
1385            setCategory(applicationClass.getMember("acConfigurations"), "Aspects");
1386    
1387            setEmbeddedEditor(applicationClass.getField("name"));
1388            setEmbeddedEditor(applicationClass.getField("path"));
1389    
1390            setFileChooserView(
1391                applicationClass.getMethod("setPath"),
1392                new String[] { "" },
1393                "directories");
1394    
1395            setViewOnSelection(applicationClass.getCollection("acConfigurations"));
1396            setAutoCreate(applicationClass.getField("acConfigurations"));
1397    
1398            //setTableView( "org.objectweb.jac.aspects.distribution.Topology", "containers");
1399    
1400            applicationClass.getMethod("addAcConfiguration").setAttribute(
1401                ASKING_SEQUENCE,
1402                new Object[] { "autoCreate" });
1403            //applicationClass.getMethod( "weave" ).setAttribute( CATEGORY, "Aspects");
1404            //applicationClass.getMethod( "unweave" ).setAttribute( CATEGORY, "Aspects");
1405            setCategory(applicationClass.getMember("realizes"), "Aspects");
1406    
1407            applicationClass.getMethod("configures").setAttribute(
1408                VISIBLE,
1409                Boolean.FALSE);
1410    
1411            applicationClass.getCollection("acs").setAttribute(
1412                VISIBLE,
1413                Boolean.FALSE);
1414    
1415            //applicationClass.getCollection( "acs" ).addAddingMethod( applicationClass.getMethod( "weave" ) );
1416            //applicationClass.getCollection( "acs" ).addRemovingMethod( applicationClass.getMethod( "unweave" ) );
1417    
1418            setSystemListener(true);
1419    
1420            // Trace configuration
1421            /*
1422              generateDefaultParameterNames( "org.objectweb.jac.aspects.gui.WrappableMap" );
1423              setMethodDynamicParameterChoice("org.objectweb.jac.aspects.gui.WrappableMap","put",
1424              new String[] { "org.objectweb.jac.aspects.gui.WrappableMap", 
1425              "org.objectweb.jac.aspects.gui.WrappableMap" }, 
1426              new String[] { "getCategories", "getLevels" },
1427              new String[] { "true", "false"});
1428              setParameterNames("org.objectweb.jac.aspects.gui.WrappableMap","put", 
1429              new String[] { "trace", "level"} );
1430              RttiAC rttiac = (RttiAC)ACManager.get().getObject("rtti");
1431              rttiac.addWrittenFields("org.objectweb.jac.aspects.gui.WrappableMap","put",new String[] {"delegate"});
1432            */
1433    
1434            pointcut(
1435                "ALL",
1436                "ALL && !org.objectweb.jac.aspects.gui.*Display && !COLLECTIONS",
1437                "MODIFIERS",
1438                ViewControlWrapper.class.getName(),
1439                null,
1440                NOT_SHARED);
1441            //pointcut("ALL","COLLECTIONS","add.* || remove.* || clear.*",
1442            //         ViewControlWrapper.class.getName(),"updateView",NOT_SHARED);
1443    
1444        }
1445    
1446        public void askForParameters(String classExpr) {
1447            // weave InputWrapper.askForParameters on all methods with parameters
1448            pointcut(
1449                "ALL",
1450                classExpr,
1451                "!.*().* && !CONSTRUCTORS",
1452                InputWrapper.class.getName(),
1453                "catchInputCanceled",
1454                SHARED);
1455        }
1456    
1457        /**
1458         * The default behavior of this <code>BaseProgramListener</code>
1459         * method is to notify the display with the
1460         * <code>applicationStarted</code> event.
1461         *
1462         * @see org.objectweb.jac.core.Display#applicationStarted() */
1463    
1464        public void afterApplicationStarted() {
1465            if (Jac.startSwingGUI()) {
1466                createSwingDisplays(Jac.getStartSwingGUI());
1467            }
1468            if (Jac.startWebGUI()) {
1469                createWebDisplays(Jac.getStartWebGUI());
1470            }
1471        }
1472    
1473        /**
1474         * Return a session id for the local display
1475         */
1476        public static String getLocalSessionID() {
1477            return "Swing"
1478                + org.objectweb.jac.core.dist.Distd.getLocalContainerName();
1479        }
1480    
1481        /**
1482         * The programmer of a new GUI aspect must overload this method to
1483         * return the right default program name.<p>
1484         *
1485         * By default, it returns the package path name of the current GUI
1486         * aspect (must be right most of the time).
1487         *
1488         * @return the default program name
1489         */
1490    
1491        protected String getDefaultProgramName() {
1492            return getClass().getName().substring(
1493                0,
1494                getClass().getName().lastIndexOf('.'));
1495        }
1496    
1497        /** A flag to memorize that the mainWindow is beeing launched (or
1498            has already been launched). */
1499        static boolean launched = false;
1500    
1501        public void setVisible(MemberItem member, boolean visible) {
1502            logger.debug("setVisible(" + member.getLongName() + "," + visible + ")");
1503            member.setAttribute(VISIBLE, Boolean.valueOf("" + visible));
1504        }
1505    
1506        public void setEditable(FieldItem field, boolean editable) {
1507            logger.debug("setEditable(" + field + "," + editable + ")");
1508            if (field != null) {
1509                field.setAttribute(EDITABLE, Boolean.valueOf("" + editable));
1510            }
1511        }
1512    
1513        public void setAddable(CollectionItem collection, boolean addable) {
1514            logger.debug("setAddable("+collection+","+addable+")");
1515            collection.setAttribute(ADDABLE, ExtBoolean.valueOf(addable));
1516        }
1517    
1518        public void setRemovable(CollectionItem collection, boolean removable)
1519        {
1520            logger.debug("setRemovable("+collection+","+removable+")");
1521            collection.setAttribute(REMOVABLE, ExtBoolean.valueOf(removable));
1522        }
1523    
1524        public void setEditableDefaultValues(
1525            CollectionItem collection,
1526            boolean editable) {
1527            collection.setAttribute(
1528                EDITABLE_DEFAULT_VALUES,
1529                editable ? Boolean.TRUE : Boolean.FALSE);
1530        }
1531    
1532        public static boolean hasEditableDefaultValues(MetaItem metaItem) {
1533            Object value = metaItem.getAttribute(EDITABLE_DEFAULT_VALUES);
1534            if (value == null)
1535                return false;
1536            else
1537                return ((Boolean) value).booleanValue();
1538        }
1539    
1540        /**
1541         * Tells if an item is visible (displayed by the GUI).
1542         *
1543         * @param substance the object holding the meta item
1544         * @param metaItem the meta item to check 
1545         * @return true if visible
1546         *
1547         * @see #setVisible(MemberItem,boolean) 
1548         * @see #isVisible(Object,MetaItem)
1549         */
1550        public static boolean isVisible(Object substance, MetaItem metaItem) {
1551            Object value = metaItem.getAttribute(substance, VISIBLE);
1552    
1553            if (value == null)
1554                return true;
1555            else
1556                return ((Boolean) value).booleanValue();
1557        }
1558    
1559        /**
1560         * Tells if an item is visible (displayed by the GUI).
1561         *
1562         * @param metaItem the meta item to check 
1563         * @return true if visible
1564         *
1565         * @see #setVisible(MemberItem,boolean) 
1566         * @see #isVisible(MetaItem)
1567         */
1568        public static boolean isVisible(MetaItem metaItem) {
1569            Object value = metaItem.getAttribute(VISIBLE);
1570    
1571            if (value == null)
1572                return true;
1573            else
1574                return ((Boolean) value).booleanValue();
1575        }
1576    
1577        /**
1578         * Tells if a field is editable from the GUI.
1579         *
1580         * @param substance the object holding the field item
1581         * @param field the field item to check 
1582         * @return true if the field is editable
1583         */
1584        public static boolean isEditable(Object substance, FieldItem field) {
1585            Object value = field.getAttribute(substance, EDITABLE);
1586            return field.getSetter() != null
1587                && (value == null || ((Boolean) value).booleanValue());
1588        }
1589    
1590        /**
1591         * Tells if a field is editable from the GUI.
1592         *
1593         * @param field the field item to check 
1594         * @return true if the field is editable
1595         */
1596        public static boolean isEditable(FieldItem field) {
1597            Object value = field.getAttribute(EDITABLE);
1598            return field.getSetter() != null
1599                && (value == null || ((Boolean) value).booleanValue());
1600        }
1601    
1602        /**
1603         * Wether to show "new" buttons for a class (defaults to true)
1604         * @param cli the class
1605         */
1606        public static boolean isCreatable(ClassItem cli) {
1607            Object value = cli.getAttribute(CREATABLE);
1608            return value == null || ((Boolean) value).booleanValue();
1609        }
1610    
1611        /**
1612         * Tells wether to show an add button for a collection
1613         *
1614         * @param collection the collection item to check 
1615         * @return true if an add button must be displayed
1616         */
1617        public static boolean isAddable(CollectionItem collection) {
1618            Object value = collection.getAttribute(ADDABLE);
1619            MethodItem adder = collection.getAdder();
1620            return adder != null
1621                && isVisible(adder)
1622                && (value == null || ((Boolean) value).booleanValue());
1623        }
1624    
1625        /**
1626         * Tells wether to show an add button for a collection
1627         *
1628         * @param substance the object holding the field item
1629         * @param collection the collection item to check 
1630         * @return true if an add button must be displayed
1631         */
1632        public static boolean isAddable(
1633            Object substance,
1634            CollectionItem collection) 
1635        {
1636            Object value = collection.getAttribute(substance, ADDABLE);
1637            MethodItem adder = collection.getAdder();
1638            return adder != null
1639                && isVisible(substance, adder)
1640                && (value == null || ((Boolean) value).booleanValue());
1641        }
1642    
1643        /**
1644         * Tells wether to show a remove button for a collection
1645         *
1646         * @param collection the collection item to check 
1647         * @return true if a remove button must be displayed
1648         */
1649        public static boolean isRemovable(CollectionItem collection) {
1650            Object value = collection.getAttribute(REMOVABLE);
1651            MethodItem remover = collection.getRemover();
1652            return remover != null
1653                && isVisible(remover)
1654                && (value == null || ((Boolean) value).booleanValue());
1655        }
1656    
1657        /**
1658         * Tells wether to show a remove button for a collection
1659         *
1660         * @param substance the object holding the field item
1661         * @param collection the collection item to check 
1662         * @return true if a remove button must be displayed
1663         */
1664        public static boolean isRemovable(
1665            Object substance,
1666            CollectionItem collection) 
1667        {
1668            Object value = collection.getAttribute(substance, REMOVABLE);
1669            MethodItem remover = collection.getRemover();
1670            return remover != null
1671                && isVisible(remover)
1672                && (value == null || ((Boolean) value).booleanValue());
1673        }
1674    
1675        public void setVisible(ClassItem cl, String itemNames[], boolean visible) {
1676            for (int i = 0; i < itemNames.length; i++) {
1677                setVisible(cl.getMember(itemNames[i]), visible);
1678            }
1679        }
1680    
1681        public void setReadOnly(ClassItem cli, String viewName, boolean readOnly) {
1682            getView(cli,viewName).setReadOnly(readOnly);
1683        }
1684    
1685        public void setEmbeddedEditors(ClassItem cli) {
1686            setEmbeddedEditors(cli,DEFAULT_VIEW,true);
1687        }
1688    
1689        public void setEmbeddedEditors(ClassItem cli, String viewName, boolean embedded) {
1690            FieldItem[] fields = cli.getFields();
1691            if (fields != null) {
1692                for (int i = 0; i < fields.length; i++) {
1693                    setEmbeddedEditor(fields[i],viewName,embedded);
1694                }
1695            }
1696        }
1697    
1698        public void setEmbeddedEditor(MemberItem member) {
1699            setEmbeddedEditor(member,DEFAULT_VIEW,true);
1700        }
1701    
1702        public void setEmbeddedEditor(MemberItem member, String viewName, boolean embedded) {
1703            if (member instanceof FieldItem) {
1704                FieldItem field = (FieldItem) member;
1705                if (!(field instanceof CollectionItem)) {
1706                    if (field.getSetter() == null) {
1707                        //Log.warning("setEmbeddedEditor: no setter for "+cl+"."+itemName+", ignored");
1708                    } else {
1709                        getView(field,viewName).setEmbeddedEditor(embedded);
1710                    }
1711                }
1712                return;
1713            } else {
1714                getView(member,viewName).setEmbeddedEditor(embedded);
1715                //member.setAttribute(EMBEDDED_EDITOR, Boolean.TRUE);
1716            }
1717        }
1718    
1719        public void setEmbeddedEditors(
1720            CollectionItem collection,
1721            String viewName,
1722            boolean embedded) 
1723        {
1724            CollectionItemView itemView =
1725                (CollectionItemView) getView(collection, viewName);
1726            itemView.setEmbeddedEditors(embedded);
1727            loggerTable.debug("setEmbeddedEditors "+collection+"/"+viewName+"/"+embedded+
1728                              "->"+itemView);
1729        }
1730    
1731        public void setEmbeddedEditorColumns(
1732            CollectionItem collection,
1733            String viewName,
1734            MemberItem[] members) 
1735        {
1736            CollectionItemView itemView =
1737                (CollectionItemView) getView(collection, viewName);
1738            for (int i = 0; i < members.length; i++) {
1739                itemView.addEmbeddedEditorColumn(members[i]);
1740            }
1741        }
1742    
1743        public void setMultiLineCollection(
1744            CollectionItem collection,
1745            String viewName,
1746            CollectionItem multiLine)
1747        {
1748            CollectionItemView itemView =
1749                (CollectionItemView) getView(collection, viewName);
1750            itemView.setMultiLineCollection(multiLine);
1751        }
1752    
1753        public void setAdditionalRow(CollectionItem collection,
1754                                     String viewName,
1755                                     String row) {
1756            CollectionItemView itemView =
1757                (CollectionItemView) getView(collection, viewName);
1758            itemView.setAdditionalRow(collection.getClassItem().getField(row));        
1759        }
1760    
1761        public void groupBy(
1762            CollectionItem collection,
1763            String viewName,
1764            FieldItem groupBy)
1765        {
1766            CollectionItemView itemView =
1767                (CollectionItemView) getView(collection, viewName);
1768            itemView.setGroupBy(groupBy);
1769        }
1770    
1771        public void setViewType(
1772            FieldItem field,
1773            String viewName,
1774            String viewType) 
1775        {
1776            MemberItemView itemView = (MemberItemView) getView(field, viewName);
1777            itemView.setViewType(viewType);
1778        }
1779    
1780        /**
1781         * @return true is the item has the property Gui.embeddedEditor set
1782         * to "true"
1783         * @see #hasEmbeddedEditors(ClassItem)
1784         * @see #setEmbeddedEditor(MemberItem)
1785         */
1786        public static boolean isEmbeddedEditor(MetaItem item) {
1787            Boolean value = (Boolean) item.getAttribute(EMBEDDED_EDITOR);
1788            return value != null && value.booleanValue();
1789        }
1790    
1791        /**
1792         * Returns the value of the EMBEDDED_EDITORS atrribute from the
1793         * current collaboration. Defaults to false.
1794         */
1795        /*
1796          public static boolean isEmbeddedEditors() {
1797          Boolean value =
1798          (Boolean) Collaboration.get().getAttribute(GuiAC.EMBEDDED_EDITORS);
1799          return value != null && value.booleanValue();
1800          }
1801        */
1802    
1803        /**
1804         * @return true if at least one field of the class has the property
1805         * Gui.embeddedEditor set to "true" 
1806         * @see #isEmbeddedEditor(MetaItem)
1807         * @see #setEmbeddedEditor(MemberItem)
1808         */
1809        public static boolean hasEmbeddedEditors(ClassItem cli) {
1810            FieldItem fields[] = cli.getFields();
1811            String[] cats = (String[]) cli.getAttribute(CATEGORIES);
1812            if (fields != null) {
1813                for (int i = 0; i < fields.length; i++) {
1814                    if (fields[i] instanceof CollectionItem)
1815                        continue;
1816                    if (cats != null && fields[i].getAttribute(CATEGORIES) == null)
1817                        continue;
1818                                    //(Arrays.asList(cats).contains(fields[i].getAttribute(CATEGORY))) 
1819                                    //  continue;
1820                    if (isEmbeddedEditor(fields[i]) && isVisible(fields[i])) {
1821                        return true;
1822                    }
1823                }
1824            }
1825            return false;
1826        }
1827    
1828        //public void setBorder(ClassItem cli, String fieldName,
1829        public void setBorder(FieldItem field, String alignment, String style) {
1830            //FieldItem field = cli.getField(fieldName);
1831            field.setAttribute(
1832                BORDER,
1833                new Border(
1834                    null,
1835                    Border.a2iAlignment(alignment),
1836                    Border.a2iStyle(style)));
1837        }
1838    
1839        //public void setBorder(ClassItem cli, String fieldName) {
1840        public void setBorder(FieldItem field) {
1841            setBorder(field, "LEFT", "LINE");
1842        }
1843    
1844        public static Border getBorder(FieldItem field) {
1845            return (Border) field.getAttribute(BORDER);
1846        }
1847    
1848        public void setCondition(AbstractMethodItem method, String condition) {
1849            ClassItem cl = method.getClassItem();
1850            MethodItem cond = cl.getMethod(condition);
1851            method.setAttribute(CONDITION, cond);
1852        }
1853    
1854        /**
1855         * Gets the condition method associated with a method, or null if
1856         * there's none.
1857         */
1858        public static MethodItem getCondition(AbstractMethodItem method) {
1859            return (MethodItem) method.getAttribute(CONDITION);
1860        }
1861    
1862        public void setSlowOperation(AbstractMethodItem method, boolean isSlow) {
1863            method.setAttribute(SLOW_OPERATION,ExtBoolean.valueOf(isSlow));
1864            if (isSlow) {
1865                pointcut(
1866                    "ALL",
1867                    method.getClassItem().getName(),
1868                    method.toString(),
1869                    WaitWrapper.class.getName(),
1870                    null,SHARED);
1871            }
1872        }
1873        
1874        public void setMimeType(AbstractMethodItem method, String type) {
1875            method.setAttribute(MIME_TYPE,type);
1876        }
1877    
1878        /**
1879         * Tells wethers a method is slow
1880         */
1881        public static boolean isSlowOperation(AbstractMethodItem method) {
1882            return method.getBoolean(SLOW_OPERATION,false);
1883        }
1884    
1885        public void addPostInvoke(AbstractMethodItem method, 
1886                                  AbstractMethodItem hook) {
1887            List hooks = (List)method.getAttribute(POST_INVOKE_HOOKS);
1888            if (hooks==null) {
1889                hooks = new Vector();
1890                method.setAttribute(POST_INVOKE_HOOKS,hooks);
1891            }
1892            hooks.add(hook);
1893        }
1894    
1895    
1896        /**
1897         * Tells wether a method should be enabled 
1898         */
1899        public static boolean isEnabled(
1900            AbstractMethodItem method,
1901            Object substance) {
1902            MethodItem condition = (MethodItem) method.getAttribute(CONDITION);
1903            if (condition != null) {
1904                loggerMenu.debug("Condition for " + method.getFullName() + ": " + condition);
1905                return ((Boolean) condition.invoke(substance, ExtArrays.emptyObjectArray))
1906                    .booleanValue();
1907            } else {
1908                loggerMenu.debug("No condition for " + method.getFullName());
1909                return true;
1910            }
1911        }
1912    
1913        public void setMethodParametersWidth(
1914            AbstractMethodItem method,
1915            int[] width,
1916            int[] columns)
1917            throws Exception {
1918            if (method.getParameterCount() != Array.getLength(width)) {
1919                throw new Exception(
1920                    "setMethodParametersWidth: wrong number of parameters widths for "
1921                    + method.getName());
1922            }
1923            method.setAttribute(EDITOR_WIDTH, width);
1924            method.setAttribute(EDITOR_COLS, columns);
1925        }
1926    
1927        /**
1928         * Returns the parameters widths of a method or null if none was set.
1929         * @param method the method
1930         * @see #setMethodParametersWidth(AbstractMethodItem,int[],int[])
1931         */
1932        public static int[] getMethodParametersWidth(AbstractMethodItem method) {
1933            int[] width = (int[]) method.getAttribute(EDITOR_WIDTH);
1934            return width;
1935        }
1936    
1937        /**
1938         * Returns the parameters numbers of columns of a method or null if none
1939         * was set.
1940         * @param method the method
1941         * @see #setMethodParametersWidth(AbstractMethodItem,int[],int[])
1942         */
1943        public static int[] getMethodParametersCols(AbstractMethodItem method) {
1944            int[] cols = (int[]) method.getAttribute(EDITOR_COLS);
1945            return cols;
1946        }
1947    
1948        public void setMethodParametersHeight(
1949            AbstractMethodItem method,
1950            int[] height,
1951            int[] rows)
1952            throws Exception {
1953            if (method.getParameterCount() != Array.getLength(height)) {
1954                throw new Exception(
1955                    "setMethodParametersHeight: wrong number of parameters heights for "
1956                    + method.getName());
1957            }
1958            method.setAttribute(EDITOR_HEIGHT, height);
1959            method.setAttribute(EDITOR_ROWS, rows);
1960        }
1961    
1962        /**
1963         * Returns the parameters heights of a method or null if none was set.
1964         * @param method the method
1965         * @see #setMethodParametersHeight(AbstractMethodItem,int[],int[])
1966         */
1967        public static int[] getMethodParametersHeight(AbstractMethodItem method) {
1968            int[] height = (int[]) method.getAttribute(EDITOR_HEIGHT);
1969            return height;
1970        }
1971    
1972        /**
1973         * Returns the parameters numbers of rows of a method or null if none
1974         * was set.
1975         * @param method the method
1976         * @see #setMethodParametersHeight(AbstractMethodItem,int[],int[])
1977         */
1978        public static int[] getMethodParametersRows(AbstractMethodItem method) {
1979            int[] rows = (int[]) method.getAttribute(EDITOR_ROWS);
1980            return rows;
1981        }
1982    
1983        public void setDefaultEditorWidth(
1984            VirtualClassItem type,
1985            int width,
1986            int columns) {
1987            type.setAttribute(EDITOR_WIDTH, new Integer(width));
1988            type.setAttribute(EDITOR_COLS, new Integer(columns));
1989        }
1990    
1991        public void setDefaultEditorWidth(ClassItem type, int width, int columns) {
1992            type.setAttribute(EDITOR_WIDTH, new Integer(width));
1993            type.setAttribute(EDITOR_COLS, new Integer(columns));
1994        }
1995    
1996        public static int getEditorWidth(MetaItem type) {
1997            Integer width = (Integer) type.getAttribute(EDITOR_WIDTH);
1998            if (width == null)
1999                return 0;
2000            else
2001                return width.intValue();
2002        }
2003    
2004        public static int getEditorColumns(MetaItem type) {
2005            Integer columns = (Integer) type.getAttribute(EDITOR_COLS);
2006            if (columns == null)
2007                return 0;
2008            else
2009                return columns.intValue();
2010        }
2011    
2012        public void setEditorWidth(FieldItem field, int width, int columns) {
2013            field.setAttribute(EDITOR_WIDTH, new Integer(width));
2014            field.setAttribute(EDITOR_COLS, new Integer(columns));
2015        }
2016    
2017        /**
2018         * Returns the editor width of a field or 0 if none was set.
2019         * @param field the field
2020         * @see #setEditorWidth(FieldItem,int,int)
2021         */
2022        public static int getEditorWidth(FieldItem field) {
2023            Integer width = (Integer) field.getAttribute(EDITOR_WIDTH);
2024            if (width == null)
2025                return 0;
2026            else
2027                return width.intValue();
2028        }
2029    
2030        /**
2031         * Returns the editor's number of columns of a field or 0 if none was set.
2032         * @param field the field
2033         * @see #setEditorWidth(FieldItem,int,int)
2034         */
2035        public static int getEditorCols(FieldItem field) {
2036            Integer cols = (Integer) field.getAttribute(EDITOR_COLS);
2037            if (cols == null)
2038                return 0;
2039            else
2040                return cols.intValue();
2041        }
2042    
2043        /**
2044         * Returns the editor's number of rows of a field or 0 if none was set.
2045         * @param field the field
2046         * @see #setEditorHeight(FieldItem,int,int)
2047         */
2048        public static int getEditorRows(FieldItem field) {
2049            Integer rows = (Integer) field.getAttribute(EDITOR_ROWS);
2050            if (rows == null)
2051                return 0;
2052            else
2053                return rows.intValue();
2054        }
2055    
2056        public static int getEditorRows(MetaItem type) {
2057            Integer rows = (Integer) type.getAttribute(EDITOR_ROWS);
2058            if (rows == null)
2059                return 0;
2060            else
2061                return rows.intValue();
2062        }
2063    
2064        public void setSmallEditorWidth(FieldItem field, int width, int columns) {
2065            field.setAttribute(EDITOR_SMALL_WIDTH, new Integer(width));
2066            field.setAttribute(EDITOR_SMALL_COLS, new Integer(columns));
2067        }
2068    
2069        public void setDefaultEditorHeight(
2070            VirtualClassItem type,
2071            int height,
2072            int rows) {
2073            type.setAttribute(EDITOR_HEIGHT, new Integer(height));
2074            type.setAttribute(EDITOR_ROWS, new Integer(rows));
2075        }
2076    
2077        public void setDefaultEditorHeight(ClassItem type, int height, int rows) {
2078            type.setAttribute(EDITOR_HEIGHT, new Integer(height));
2079            type.setAttribute(EDITOR_ROWS, new Integer(rows));
2080        }
2081    
2082        public void setEditorHeight(FieldItem field, int height, int rows) {
2083            field.setAttribute(EDITOR_HEIGHT, new Integer(height));
2084            field.setAttribute(EDITOR_ROWS, new Integer(rows));
2085        }
2086    
2087        public void setSmallEditorHeight(FieldItem field, int height, int rows) {
2088            field.setAttribute(EDITOR_SMALL_HEIGHT, new Integer(height));
2089            field.setAttribute(EDITOR_SMALL_ROWS, new Integer(rows));
2090        }
2091    
2092        static Map fontAttributes = new HashMap();
2093    
2094        public void setFontAttribute(String attribute, String value) {
2095            fontAttributes.put(attribute.toLowerCase(), value);
2096        }
2097    
2098        public static Map getFontAttributes() {
2099            return fontAttributes;
2100        }
2101    
2102        public void setCategories(ClassItem cli, String[] categories) {
2103            cli.setAttribute(CATEGORIES, categories);
2104        }
2105    
2106        /*
2107          public void setCategories(ClassItem cli, String viewName, 
2108          String[] categories) {
2109          getView(cli,viewName).setCategories(categories);
2110          }
2111        */
2112    
2113        public void setCategory(MemberItem member, String category) {
2114            setCategories(member, new String[] { category });
2115        }
2116    
2117        public void setCategories(MemberItem member, String[] categories) {
2118            member.setAttribute(CATEGORIES, categories);
2119        }
2120    
2121        /**
2122         * Get the category of a member as configured with setCategory().
2123         *
2124         * @param member the MemberItem
2125         * @return the category of the field or null.
2126         */
2127        public static String[] getCategories(MemberItem member) {
2128            return (String[]) member.getAttribute(CATEGORIES);
2129        }
2130    
2131        /**
2132         * Tells wether a member item belong to category
2133         * @return if category==null, true, otherwise if the categories of
2134         * the member contains the category, true, otherwise false.
2135         * @see #setCategory(MemberItem,String)
2136         * @see #setCategories(MemberItem,String[])
2137         */
2138        public static boolean isMemberInCategory(
2139            MemberItem member,
2140            String category) {
2141            if (category == null) {
2142                return true;
2143            }
2144    
2145            String[] categories = getCategories(member);
2146            if (categories == null)
2147                return false;
2148            for (int i = 0; i < categories.length; i++) {
2149                if (categories[i].equals(category)) {
2150                    return true;
2151                }
2152            }
2153            return false;
2154        }
2155    
2156        public void checkCategories(ClassItem cli, int length) {
2157            //String[] categories = getView(cli,DEFAULT_VIEW).getCategories();
2158            String[] categories = (String[]) cli.getAttribute(CATEGORIES);
2159            if (categories == null || categories.length != length) {
2160                throw new RuntimeException(
2161                    "Wrong number of icons for categories of class " + cli);
2162            }
2163        }
2164    
2165        public void setCategoriesIcons(ClassItem cli, String[] icons) {
2166            //      checkCategories(cli,icons.length);
2167            for (int i = 0; i < Array.getLength(icons); i++) {
2168                String str = ResourceManager.getResource(icons[i]);
2169                if (str == null)
2170                    warning("setCategoriesIcons: icon not found " + icons[i]);
2171                icons[i] = str;
2172            }
2173    
2174            cli.setAttribute(CATEGORIES_ICONS, icons);
2175        }
2176    
2177        /**
2178         * Get the categories icons (icons displayed in tabs).
2179         *
2180         * @param cl the class.
2181         * @return the list of icons.
2182         */
2183        public static String[] getCategoriesIcons(ClassItem cl) {
2184            return (String[]) cl.getAttribute(CATEGORIES_ICONS);
2185        }
2186    
2187        public void setCategoriesLabels(ClassItem cli, String[] labels) {
2188            //      checkCategories(cli,labels.length);
2189            cli.setAttribute(CATEGORIES_LABELS, labels);
2190        }
2191    
2192        /**
2193         * Get the categories labels (text displayed in tabs).
2194         *
2195         * @param cl the class
2196         * @return the list of labels.
2197         */
2198        public static String[] getCategoriesLabels(ClassItem cl) {
2199            return (String[]) cl.getAttribute(CATEGORIES_LABELS);
2200        }
2201    
2202        public void setEmbeddedView(MemberItem member) {
2203            setEmbeddedView(member, GuiAC.DEFAULT_VIEW, true);
2204        }
2205    
2206        public void setEmbeddedView(MemberItem member, boolean embedded) {
2207            setEmbeddedView(member, GuiAC.DEFAULT_VIEW, embedded);
2208        }
2209    
2210        public void setEmbeddedView(
2211            MemberItem member,
2212            String viewName,
2213            boolean embedded) 
2214        {
2215            getView(member, viewName).setEmbedded(embedded);
2216        }
2217    
2218        public void setEmbeddedAdder(CollectionItem collection, boolean embedded) {
2219            setEmbeddedView(collection.getAdder(), embedded);
2220        }
2221    
2222        /**
2223         * Tells if a field item's value must be displayed embbeded.
2224         * @return wether to display the field's values embbeded, default
2225         * to false.
2226         */
2227        /*
2228          public static boolean isEmbbededView(MemberItem member) {
2229          Boolean value = (Boolean)member.getAttribute(EMBEDDED_VIEW);
2230          return value!=null && value.booleanValue();
2231          }
2232        */
2233    
2234        public void setDesktopCustomizedView(ClassItem classItem, ClassItem type) {
2235            classItem.setAttribute(DESKTOP_VIEW, type);
2236        }
2237    
2238        public void setTableView(FieldItem field) {
2239            field.setAttribute(TABLE_VIEW, Boolean.TRUE);
2240        }
2241    
2242        public void setChoiceView(CollectionItem field, boolean external) {
2243            field.setAttribute(CHOICE_VIEW, ExtBoolean.valueOf(external));
2244        }
2245    
2246        public void showRowNumbers(CollectionItem collection, boolean value) {
2247            collection.setAttribute(
2248                SHOW_ROW_NUMBERS,
2249                value ? Boolean.TRUE : Boolean.FALSE);
2250        }
2251    
2252        protected static boolean defaultShowRowNumbers = false;
2253    
2254        public void setDefaultShowRowNumbers(boolean value) {
2255            defaultShowRowNumbers = value;
2256        }
2257    
2258        public static boolean isShowRowNumbers(CollectionItem collection) {
2259            return collection.getBoolean(SHOW_ROW_NUMBERS, defaultShowRowNumbers);
2260        }
2261    
2262        public void setToString(ClassItem classItem, String formatExpression) {
2263            classItem.setAttribute(TO_STRING, formatExpression);
2264        }
2265    
2266        public void setToString(
2267            ClassItem classItem,
2268            MemberItem selector,
2269            String formatExpression) 
2270        {
2271            Map rules = (Map) classItem.getAttributeAlways(CONTEXTUAL_TO_STRING);
2272            if (rules == null) {
2273                rules = new HashMap();
2274                classItem.setAttribute(CONTEXTUAL_TO_STRING, rules);
2275            }
2276            rules.put(selector, formatExpression);
2277        }
2278    
2279        public void setToString(
2280            ClassItem classItem,
2281            ClassItem selector,
2282            String formatExpression) 
2283        {
2284            Map rules = (Map) classItem.getAttributeAlways(CONTEXTUAL_TO_STRING);
2285            if (rules == null) {
2286                rules = new HashMap();
2287                classItem.setAttribute(CONTEXTUAL_TO_STRING, rules);
2288            }
2289            rules.put(selector, formatExpression);
2290        }
2291    
2292        public void setToolTipText(ClassItem classItem, String formatExpression) {
2293            classItem.setAttribute(TOOLTIP, formatExpression);
2294        }
2295    
2296        public void setToolTipText(
2297            ClassItem classItem,
2298            MemberItem selector,
2299            String formatExpression) 
2300        {
2301            Map rules = (Map) classItem.getAttributeAlways(CONTEXTUAL_TOOLTIP);
2302            if (rules == null) {
2303                rules = new HashMap();
2304                classItem.setAttribute(CONTEXTUAL_TOOLTIP, rules);
2305            }
2306            rules.put(selector, formatExpression);
2307        }
2308    
2309        public void setToolTipText(
2310            ClassItem classItem,
2311            ClassItem selector,
2312            String formatExpression) 
2313        {
2314            Map rules = (Map) classItem.getAttributeAlways(CONTEXTUAL_TOOLTIP);
2315            if (rules == null) {
2316                rules = new HashMap();
2317                classItem.setAttribute(CONTEXTUAL_TOOLTIP, rules);
2318            }
2319            rules.put(selector, formatExpression);
2320        }
2321    
2322        public void showColumnFilters(CollectionItem collection,                                  
2323                                      String[] columnNames) {
2324            ClassItem type = collection.getComponentType();
2325            Vector columns = new Vector();
2326            for (int i=0; i< columnNames.length; i++) {
2327                FieldItem field = type.getFieldNoError(columnNames[i]);
2328                if (field!=null) {
2329                    columns.add(field);
2330                } else {
2331                    warning("gui.showColumnFilters: no such field "+columnNames[i]+" in "+type.getName());
2332                }
2333            }
2334            collection.setAttribute(FILTERED_COLUMNS,columns);
2335        }
2336    
2337        public void setDefaultSortedColumn(
2338            CollectionItem collection,
2339            String column) 
2340        {
2341            collection.setAttribute(DEF_SORT, column);
2342        }
2343    
2344        public void setDefaultSortedColumn(ClassItem cl, String column) {
2345            cl.setAttribute(DEF_SORT, column);
2346        }
2347    
2348        public static String getDefaultSortedColumn(CollectionItem collection) {
2349            String column = (String) collection.getAttribute(GuiAC.DEF_SORT);
2350            if (column == null) {
2351                ClassItem type = collection.getComponentType();
2352                if (type != null)
2353                    column = (String) type.getAttribute(GuiAC.DEF_SORT);
2354            }
2355            return column;
2356        }
2357    
2358        public void setAutoCreate(FieldItem field) {
2359            field.setAttribute(AUTO_CREATE, Boolean.TRUE);
2360        }
2361    
2362        public static boolean isAutoCreate(FieldItem field) {
2363            Boolean bool = (Boolean) field.getAttribute(AUTO_CREATE);
2364            if (bool != null)
2365                return bool.booleanValue();
2366            else if (field instanceof CollectionItem) {
2367                CollectionItem collection = (CollectionItem) field;
2368                MethodItem adder = collection.getAdder();
2369                if (adder != null)
2370                    return GuiAC.isAutoCreateParameters(adder);
2371            } else {
2372                MethodItem setter = field.getSetter();
2373                if (setter != null)
2374                    return GuiAC.isAutoCreateParameters(setter);
2375            }
2376            return false;
2377        }
2378    
2379        public void setAutoCreateInitializer(
2380            FieldItem field,
2381            MethodItem initializer) 
2382        {
2383            field.setAttribute(AUTO_CREATE_INITIALIZER, initializer);
2384        }
2385    
2386        /**
2387         * Returns the initializer method of a field, if any, or null.
2388         * @param field the field
2389         * @see #setAutoCreateInitializer(FieldItem,MethodItem)
2390         */
2391        public static MethodItem getInitiliazer(FieldItem field) {
2392            return (MethodItem) field.getAttribute(AUTO_CREATE_INITIALIZER);
2393        }
2394    
2395        public void setAutoCreateParameters(AbstractMethodItem method) {
2396            method.setAttribute(AUTO_CREATE, Boolean.TRUE);
2397        }
2398    
2399        public static boolean isAutoCreateParameters(AbstractMethodItem method) {
2400            return method.getBoolean(AUTO_CREATE, false);
2401        }
2402    
2403        public void setAutoCreateAll(ClassItem cl) {
2404            setAutoCreateParametersEx(cl, ExtArrays.emptyStringArray);
2405        }
2406    
2407        public void setAutoCreateParametersEx(
2408            ClassItem cli,
2409            String[] excludedMethods) 
2410        {
2411            Class clazz = cli.getActualClass();
2412            boolean error = false;
2413            try {
2414                Iterator it = cli.getAllMethods().iterator();
2415                List l = Arrays.asList(excludedMethods);
2416                while (it.hasNext()) {
2417                    MethodItem cur = (MethodItem) it.next();
2418                    if ((!l.contains(cur.getName()))
2419                        && (!cur.isRemover())
2420                        && cur.getActualMethod().getDeclaringClass() == clazz) {
2421                        try {
2422                            setAutoCreateParameters(cur);
2423                        } catch (Exception e) {
2424                            e.printStackTrace();
2425                        }
2426                    }
2427                }
2428            } catch (Exception e) {
2429                e.printStackTrace();
2430            }
2431        }
2432    
2433        public void setAutoCreateState(ClassItem cli, String[] fields) {
2434            cli.setAttribute(AUTO_CREATED_STATE, fields);
2435        }
2436    
2437        public void setOpenViewMethod(ClassItem cli, String methodName) {
2438            MetaItem mi = cli.getMethod(methodName);
2439            mi.setAttribute(OPEN_VIEW, Boolean.TRUE);
2440        }
2441    
2442        public void declareView(
2443            ClassItem cli,
2444            String viewName,
2445            String parentViewName) 
2446        {
2447            ObjectView view =
2448                new ObjectView(cli, viewName, getView(cli, parentViewName));
2449            Map views = (Map) cli.getAttributeAlways(VIEWS);
2450            if (views == null) {
2451                views = new HashMap();
2452                cli.setAttribute(VIEWS, views);
2453            }
2454            views.put(viewName, view);
2455        }
2456    
2457        public void declareView(ClassItem cli, String viewName) {
2458            declareView(cli, viewName, DEFAULT_VIEW);
2459        }
2460    
2461        /**
2462         * Gets an object view by name. Creates one if it does not exist
2463         */
2464        public static ObjectView getView(ClassItem cli, String viewName) {
2465            Map views = (Map) cli.getAttributeAlways(VIEWS);
2466            if (views == null) {
2467                views = new HashMap();
2468                cli.setAttribute(VIEWS, views);
2469            }
2470            ObjectView view = (ObjectView) views.get(viewName);
2471            if (view == null) {
2472                if (viewName.equals(DEFAULT_VIEW))
2473                    view = new ObjectView(cli, viewName);
2474                else
2475                    view = new ObjectView(cli, viewName, getView(cli,DEFAULT_VIEW));
2476            }
2477            views.put(viewName, view);
2478            return view;
2479        }
2480    
2481        /**
2482         * Gets an object view by name. Creates one if it does not exist
2483         */
2484        public static MemberItemView getView(MemberItem member, String viewName) {
2485            Map views = (Map) member.getAttributeAlways(VIEWS);
2486            if (views == null) {
2487                views = new HashMap();
2488                member.setAttribute(VIEWS, views);
2489            }
2490            MemberItemView view = (MemberItemView) views.get(viewName);
2491            if (view == null) {
2492                if (member instanceof CollectionItem)
2493                    view =
2494                        new CollectionItemView((CollectionItem) member, viewName);
2495                else if (member instanceof FieldItem)
2496                    view = new FieldItemView((FieldItem) member, viewName);
2497                else if (member instanceof MethodItem)
2498                    view = new MethodItemView((MethodItem) member, viewName);
2499            }
2500            views.put(viewName, view);
2501            return view;
2502        }
2503    
2504        /**
2505         * Gets an object view by name. Creates one if it does not exist
2506         */
2507        public static CollectionItemView getView(
2508            CollectionItem collection,
2509            String viewName) 
2510        {
2511            Map views = (Map) collection.getAttributeAlways(VIEWS);
2512            if (views == null) {
2513                views = new HashMap();
2514                collection.setAttribute(VIEWS, views);
2515            }
2516            CollectionItemView view = (CollectionItemView) views.get(viewName);
2517            if (view == null) {
2518                view = new CollectionItemView(collection, viewName);
2519            }
2520            views.put(viewName, view);
2521            return view;
2522        }
2523    
2524        public void setAttributesOrder(ClassItem cli, String[] attributeNames) {
2525            setAttributesOrder(cli, DEFAULT_VIEW, attributeNames);
2526        }
2527    
2528        public void setAttributesOrder(
2529            ClassItem cli,
2530            String viewName,
2531            String[] attributeNames) 
2532        {
2533            getView(cli, viewName).setAttributesOrder(
2534                cli.getFields(attributeNames));
2535        }
2536    
2537        public void setLineBreaks(ClassItem cli, String[] fields) {
2538            FieldItem[] lineBreaks = new FieldItem[fields.length];
2539            for (int i = 0; i < fields.length; i++) {
2540                lineBreaks[i] = cli.getField(fields[i]);
2541            }
2542            cli.setAttribute(LINE_BREAKS, lineBreaks);
2543        }
2544    
2545        public void setMethodsOrder(ClassItem cli, String[] methodNames) {
2546            setMethodsOrder(cli, DEFAULT_VIEW, methodNames);
2547        }
2548    
2549        public void setMethodsOrder(
2550            ClassItem cli,
2551            String viewName,
2552            String[] methodNames) 
2553        {
2554            getView(cli, viewName).setMethodsOrder(cli.getMethods(methodNames));
2555        }
2556    
2557        public void setCreationAttributesOrder(
2558            ClassItem cli,
2559            String[] attributeNames) 
2560        {
2561            setAttributesOrder(cli, AUTOCREATE_VIEW, attributeNames);
2562        }
2563    
2564        /**
2565         * Gets the field items to display when creation a new instance a class
2566         */
2567        public static FieldItem[] getCreationAttributesOrder(ClassItem cl) {
2568            FieldItem[] fields = getView(cl,AUTOCREATE_VIEW).getAttributesOrder();
2569            if (fields == null) {
2570                fields = getView(cl,DEFAULT_VIEW).getAttributesOrder();
2571                if (fields == null) {
2572                    fields = cl.getFields();
2573                }
2574            }
2575            return fields;
2576        }
2577    
2578        public static boolean isCreationAttribute(FieldItem field) {
2579            ClassItem cl = field.getClassItem();
2580            FieldItem[] attributesOrder = getCreationAttributesOrder(cl);
2581            if (attributesOrder == null)
2582                return true;
2583            return ExtArrays.contains(attributesOrder, field);
2584        }
2585    
2586        public void setMembersOrder(
2587            CollectionItem collection,
2588            ClassItem targetClass,
2589            String[] memberNames) 
2590        {
2591            setMembersOrder(collection, DEFAULT_VIEW, targetClass, memberNames);
2592        }
2593    
2594        public void setMembersOrder(
2595            CollectionItem collection,
2596            String viewName,
2597            ClassItem targetClass,
2598            String[] memberNames) 
2599        {
2600            CollectionItemView itemView = getView(collection,viewName);
2601            itemView.setMembersOrder(targetClass.getMembers(memberNames));
2602        }
2603    
2604        public static MemberItem[] getMembersOrder(
2605            CollectionItem collection,
2606            String viewName) 
2607        {
2608            CollectionItemView itemView = getView(collection,viewName);
2609            return itemView.getMembersOrder();
2610        }
2611    
2612        public void setTableMembersOrder(ClassItem cli, String[] memberNames) {
2613            setTableMembersOrder(cli,DEFAULT_VIEW,memberNames);
2614        }
2615    
2616        public void setTableMembersOrder(ClassItem cli, String viewName, 
2617                                         String[] memberNames) {
2618            ObjectView view = getView(cli,viewName);
2619            view.setTableMembersOrder(cli.getMembers(memberNames));
2620        }
2621    
2622        public void setTreeAttributesOrder(
2623            ClassItem cli,
2624            String[] attributeNames) 
2625        {
2626            cli.setAttribute(TREE_ATTRIBUTES_ORDER, cli.getFields(attributeNames));
2627        }
2628    
2629        public void setFieldChoice(
2630            FieldItem field,
2631            Boolean editable,
2632            String[] choice) 
2633        {
2634            Object[] choice2 = choice;
2635            choice2 = new Object[choice.length];
2636            try {
2637                logger.debug("setFieldChoice " + field.getType());
2638                for (int i = 0; i < choice.length; i++) {
2639                    choice2[i] =
2640                        ClassRepository.instantiate(field.getType(), choice[i]);
2641                }
2642            } catch (Exception e) {
2643                e.printStackTrace();
2644            }
2645            field.setAttribute(FIELD_CHOICE, choice2);
2646            field.setAttribute(EDITABLE_CHOICE, editable);
2647        }
2648    
2649        public void setFieldEnum(FieldItem field, String enumName) {
2650            Enum enum = (Enum) enums.get(enumName);
2651            if (enum == null) {
2652                throw new RuntimeException("Unknown enumeration: " + enumName);
2653            }
2654            field.setAttribute(FIELD_ENUM, enum);
2655        }
2656    
2657        public static Enum getEnum(FieldItem field) {
2658            return (Enum)field.getAttribute(FIELD_ENUM);
2659        }
2660    
2661        public void setParameterEnums(
2662            AbstractMethodItem method,
2663            String[] enumNames)
2664            throws Exception 
2665        {
2666            if (enumNames.length != method.getParameterCount())
2667                throw new Exception(
2668                    method.getName()
2669                    + " expects "
2670                    + method.getParameterCount()
2671                    + " parameters");
2672            Enum[] enums = new Enum[enumNames.length];
2673            for (int i = 0; i < enumNames.length; i++) {
2674                if (enumNames[i] != null) {
2675                    enums[i] = (Enum) this.enums.get(enumNames[i]);
2676                    if (enums[i] == null) {
2677                        warning(
2678                            "setParameterEnums(" + method.getName()
2679                            + "): Unknown enumeration: " + enumNames[i]);
2680                    }
2681                }
2682            }
2683            method.setAttribute(PARAMETER_ENUMS, enums);
2684        }
2685    
2686        public void setLinkedParameters(
2687            AbstractMethodItem method,
2688            String[] collections)
2689            throws Exception 
2690        {
2691            if (collections.length != method.getParameterCount())
2692                throw new Exception(
2693                    method.getName()
2694                    + " expects "
2695                    + method.getParameterCount()
2696                    + " parameters");
2697            CollectionItem[] colls = new CollectionItem[collections.length];
2698            for (int i = 0; i < collections.length; i++) {
2699                if (!collections[i].equals("")) {
2700                    colls[i] =
2701                        (CollectionItem) MemberItem.getMemberFromFullName(
2702                            collections[i]);
2703                } else {
2704                    colls[i] = null;
2705                }
2706            }
2707            method.setAttribute(LINKED_PARAMETERS, colls);
2708        }
2709    
2710        public void setDefaultValue(
2711            FieldItem field,
2712            MethodItem method,
2713            String value) 
2714        {
2715            field.setAttribute(DYN_DEFAULT_VALUE, new Object[] { method, value });
2716        }
2717    
2718        public void setDefaultValue(FieldItem field, String value) {
2719            setDefaultValue(
2720                field,
2721                ClassRepository.get().getClass(GuiAC.class).getMethod(
2722                    "getDefaultValue"),
2723                value);
2724        }
2725    
2726        public static boolean hasDefaultValue(FieldItem field) {
2727            return field.getAttribute(DYN_DEFAULT_VALUE) != null;
2728        }
2729    
2730        public static boolean isEditableChoice(FieldItem field) {
2731            return field.getBoolean(EDITABLE_CHOICE, false);
2732        }
2733    
2734        public void setDynamicFieldChoice(
2735            FieldItem field,
2736            Boolean editable,
2737            ClassItem targetClass,
2738            String targetMethod) 
2739        {
2740            setDynamicFieldChoice(
2741                field,
2742                editable,
2743                targetClass.getMethod(targetMethod));
2744        }
2745    
2746        public void setDynamicFieldChoice(
2747            FieldItem field,
2748            CollectionItem targetField) 
2749        {
2750            field.setAttribute(FIELD_CHOICE, targetField);
2751            field.setAttribute(EDITABLE_CHOICE, Boolean.TRUE);
2752        }
2753    
2754        public void setDynamicFieldChoice(
2755            FieldItem field,
2756            Boolean editable,
2757            MethodItem targetMethod) 
2758        {
2759            field.setAttribute(FIELD_CHOICE, targetMethod);
2760            field.setAttribute(EDITABLE_CHOICE, editable);
2761        }
2762    
2763        public void setMethodDynamicParameterChoice(
2764            MethodItem method,
2765            ClassItem[] targetClasses,
2766            String[] targetMethods,
2767            boolean[] editable) 
2768        {
2769            MethodItem[] methods =
2770                new MethodItem[method.getParameterTypes().length];
2771            for (int i = 0; i < methods.length; i++) {
2772                if (targetClasses[i] != null && !targetClasses[i].equals("")) {
2773                    methods[i] = targetClasses[i].getMethod(targetMethods[i]);
2774                } else {
2775                    methods[i] = null;
2776                }
2777            }
2778            setMethodDynamicParameterChoice(method,methods,editable);
2779        }
2780    
2781        public void setMethodDynamicParameterChoice(
2782            MethodItem method,
2783            MethodItem[] targetMethods,
2784            boolean[] editable) 
2785        {
2786            method.setAttribute(PARAMETER_CHOICES, targetMethods);
2787            method.setAttribute(EDITABLE_CHOICES, editable);
2788        }
2789    
2790        public void setDynamicClassChoice(String className, MethodItem targetMethod) {
2791            MetaItem cli = ClassRepository.get().getVirtualClass(className);
2792            cli.setAttribute(CLASS_CHOICES,targetMethod);
2793        }
2794    
2795        public void setCollectionType(CollectionItem collection, String type) {
2796            collection.setAttribute(
2797                COLLECTION_TYPE,
2798                ClassRepository.get().getClass(type));
2799        }
2800    
2801        /**
2802         * Sets the selection mode for an URL.
2803         *
2804         * @param field the field (of URL type) 
2805         * @param mode the selection mode (DIRECTORIES_ONLY ||
2806         * FILES_AND_DIRECTORIES), default is FILES_ONLY
2807         * @param extensions the selection extensions (gif, ps, etc.)
2808         * @param extensionsDescription the description of the extensions
2809         * (can be null) 
2810         */
2811        public void setURLSelectionMode(
2812            FieldItem field,
2813            String mode,
2814            String[] extensions,
2815            String extensionsDescription) 
2816        {
2817            field.setAttribute(FILE_SELECTION_MODE, mode);
2818            field.setAttribute(FILE_EXTENSIONS, extensions);
2819            field.setAttribute(FILE_EXTENSIONS_DESCRIPTION, extensionsDescription);
2820        }
2821    
2822        /*
2823          public void addAllowedFileExtensions(
2824          FieldItem field,
2825          String[] fileExtensions,
2826          String fileDescription) 
2827          {
2828          FileEditorConfig config = (FileEditorConfig)field.getAttribute(FILE_EDITOR_CONFIG);
2829          if (config==null) {
2830          config = new FileEditorConfig();
2831          field.setAttribute(FILE_EDITOR_CONFIG,config);
2832          }
2833          }
2834        */
2835    
2836        public void setViewOnSelection(CollectionItem collection) {
2837            collection.setAttribute(VIEW_ON_SELECTION, Boolean.TRUE);
2838        }
2839    
2840        /**
2841         * Tells wether VIEW_ON_SELECTION is set for a given field. Defaults to true.
2842         * @param field the field
2843         * @return true if VIEW_ON_SELECTION is set for the field
2844         * @see #setViewOnSelection(CollectionItem)
2845         */
2846        public static boolean getViewOnSelection(FieldItem field) {
2847            return field.getBoolean(VIEW_ON_SELECTION, true);
2848        }
2849    
2850        public void setOnSelection(
2851            CollectionItem collection,
2852            MethodItem eventHandler) 
2853        {
2854            collection.setAttribute(SELECTION_HANDLER, eventHandler);
2855        }
2856    
2857        public void setSelectionTarget(
2858            CollectionItem collection,
2859            ClassItem targetClass,
2860            String targetField) 
2861        {
2862            collection.setAttribute(
2863                SELECTION_TARGET,
2864                targetClass.getField(targetField));
2865        }
2866    
2867        public static MethodItem getSelectionHandler(MemberItem member) {
2868            Object handler = member.getAttribute(SELECTION_HANDLER);
2869            return (handler instanceof MethodItem) ? (MethodItem) handler : null;
2870        }
2871    
2872        public void setPreferredHeight(CollectionItem collection, int height) {
2873            collection.setAttribute(VIEW_HEIGHT, new Integer(height));
2874        }
2875    
2876        public void setPreferredWidth(CollectionItem collection, int width) {
2877            collection.setAttribute(VIEW_WIDTH, new Integer(width));
2878        }
2879    
2880        public void setNumRowsPerPage(CollectionItem collection, int numRows) {
2881            collection.setAttribute(NUM_ROWS_PER_PAGE, new Integer(numRows));
2882        }
2883    
2884        public void setAvailableNumRowsPerPage(CollectionItem collection, int[] numRows) {
2885            collection.setAttribute(AVAILABLE_NUM_ROWS_PER_PAGE, numRows);
2886        }
2887    
2888        public static int[] getAvailableNumRowsPerPage(CollectionItem collection) {
2889            return (int[])collection.getAttribute(AVAILABLE_NUM_ROWS_PER_PAGE);
2890        }
2891    
2892        static int defaultNumRowsPerPage = 10;
2893    
2894        public static int getNumRowsPerPage(CollectionItem collection) {
2895            Object numRows = collection.getAttribute(NUM_ROWS_PER_PAGE);
2896            if (numRows == null)
2897                return defaultNumRowsPerPage;
2898            else
2899                return ((Integer) numRows).intValue();
2900        }
2901    
2902        /**
2903         * Gets start index for collection view from the context
2904         * @param collection the collection to get the start index of
2905         */
2906        public static int getStartIndex(CollectionItem collection) {
2907            Map startIndexes =
2908                (Map) Collaboration.get().getAttribute(START_INDEXES);
2909            if (startIndexes == null) {
2910                return 0;
2911            } else {
2912                Object value = startIndexes.get(collection);
2913                if (value == null)
2914                    return 0;
2915                else
2916                    return ((Integer) value).intValue();
2917            }
2918        }
2919    
2920        /**
2921         * Sets the start index for a collection view in the context
2922         * @param collection the collection
2923         * @param index the start index
2924         */
2925        public static void setStartIndex(CollectionItem collection, int index) {
2926            Map startIndexes =
2927                (Map) Collaboration.get().getAttribute(START_INDEXES);
2928            if (startIndexes == null) {
2929                startIndexes = new HashMap();
2930                Collaboration.get().addAttribute(START_INDEXES, startIndexes);
2931            }
2932    
2933            startIndexes.put(collection, new Integer(index));
2934        }
2935    
2936        public static void removeStartIndex(CollectionItem collection) {
2937            Map startIndexes =
2938                (Map) Collaboration.get().getAttribute(START_INDEXES);
2939            if (startIndexes != null) {
2940                startIndexes.remove(collection);
2941            }
2942        }
2943    
2944        public void setFileChooserView(
2945            MethodItem method,
2946            String[] fileExtensions,
2947            String fileDescription) 
2948        {
2949            method.setAttribute(
2950                FILE_CHOOSER_VIEW,
2951                new Object[] { fileExtensions, fileDescription });
2952            return;
2953        }
2954    
2955        /**
2956         * Tells if the given method call by the GUI opens a file chooser
2957         * dialog.<p>
2958         *
2959         * @param setter the setter for the field
2960         * @return true if a file chooser is oppened
2961         * @see #getFileExtensions(MethodItem)
2962         * @see #getFileDescription(MethodItem) */
2963    
2964        public boolean isFileChooserView(MethodItem setter) {
2965            return setter.getAttribute(FILE_CHOOSER_VIEW) != null;
2966        }
2967    
2968        /**
2969         * Gets the file extensions for a given field that is view as a
2970         * file chooser (more precisely, the field that is set by the given
2971         * setter).<p>
2972         *
2973         * For instance, the file extensions can be a strings array like
2974         * {"gif", "jpg", "png"} or {"txt", "doc"}.<p>
2975         *
2976         * @param setter the setter for the field
2977         * @return the description of the files that are associated to the
2978         * field
2979         * @see #isFileChooserView(MethodItem) */
2980    
2981        public String[] getFileExtensions(MethodItem setter) {
2982            Object attr = setter.getAttribute(FILE_CHOOSER_VIEW);
2983            if (attr != null) {
2984                return (String[]) ((Object[]) attr)[0];
2985            }
2986            return null;
2987        }
2988    
2989        /**
2990         * Gets the file description for a given field that is view as a
2991         * file chooser (more precisely, the field that is set by the given
2992         * setter).<p>
2993         *
2994         * For instance, the file description can be a string like "Image
2995         * files" or "Text files".<p>
2996         *
2997         * @param setter the setter for the field
2998         * @return the description of the files that are associated to the
2999         * field
3000         * @see #isFileChooserView(MethodItem) */
3001    
3002        public String getFileDescription(MethodItem setter) {
3003            Object attr = setter.getAttribute(FILE_CHOOSER_VIEW);
3004            if (attr != null) {
3005                return (String) ((Object[]) attr)[1];
3006            }
3007            return null;
3008        }
3009    
3010        /**
3011         * Returns true if the given item must be displayed by the GUI as a
3012         * table.<p>
3013         *
3014         * @param collection the collection to check 
3015         */
3016        public static boolean isTableView(CollectionItem collection) {
3017            return (collection.getBoolean(TABLE_VIEW, false))
3018                || (collection.isMap() && !RttiAC.isIndex(collection));
3019        }
3020    
3021        public static boolean isChoiceView(CollectionItem collection) {
3022            return collection.getBoolean(CHOICE_VIEW,false);
3023        }
3024    
3025        public static boolean isExternalChoiceView(CollectionItem collection) {
3026            return (collection.getBoolean(CHOICE_VIEW, false));
3027        }
3028    
3029        public void setCreationAllowedParameters(
3030            AbstractMethodItem method,
3031            boolean[] create) {
3032            method.setAttribute(CREATION_ALLOWED_PARAMETERS, create);
3033        }
3034    
3035        public void setCreationAllowed(FieldItem field, boolean allow) {
3036            field.getSetter().setAttribute(
3037                CREATION_ALLOWED_PARAMETERS,
3038                new boolean[] { allow });
3039        }
3040    
3041        /**
3042         * Tells wether to display a "new" button for a parameter of a method
3043         *
3044         * @param method the method
3045         * @param i index of the parameter
3046         * @return a boolean
3047         *
3048         * @see #setCreationAllowedParameters(AbstractMethodItem,boolean[])
3049         */
3050        public static boolean isCreationAllowedParameter(
3051            AbstractMethodItem method,
3052            int i) {
3053            boolean[] cs =
3054                (boolean[]) method.getAttribute(CREATION_ALLOWED_PARAMETERS);
3055            if (cs == null) {
3056                return Wrappee.class.isAssignableFrom(
3057                    method.getParameterTypes()[i]);
3058                /*
3059                  if (i==0 && ((MethodItem)method).getSetField()!=null) {
3060                  return true;
3061                  } else {
3062                  return false;
3063                  }
3064                */
3065            }
3066            return cs[i];
3067        }
3068    
3069        public void setParameterNames(
3070            AbstractMethodItem method,
3071            String[] parameterNames) 
3072        {
3073            method.setAttribute(PARAMETER_NAMES, parameterNames);
3074            int count = method.getParameterCount();
3075            if (parameterNames.length!=count) {
3076                warning("setParameterNames: expecting "+count+" parameterNames for "+
3077                        method+", got "+parameterNames.length);
3078            }
3079        }
3080    
3081        /**
3082         * Returns the parameter names of a method. If none were with
3083         * <code>setParameterNames</code>, try some naming convention
3084         * heuristic.
3085         * @param method the method 
3086         * @return the parameter names of the method
3087         * @see #setParameterNames(AbstractMethodItem,String[])
3088         * @see #setParameterNames(AbstractMethodItem,String[])
3089         */
3090        public static String[] getParameterNames(AbstractMethodItem method) {
3091            String[] parameterNames =
3092                (String[]) method.getAttribute(PARAMETER_NAMES);
3093            if (parameterNames == null && method instanceof MethodItem) {
3094                MethodItem m = (MethodItem) method;
3095                if (m.isSetter()) {
3096                    parameterNames = new String[] { getLabel(m.getSetField())};
3097                } else if (m.isRemover()) {
3098                    parameterNames =
3099                        new String[] { getLabel(m.getRemovedCollections()[0])};
3100                } else if (m.isAdder()) {
3101                    String collName = getLabel(m.getAddedCollections()[0]);
3102                    if (method.getParameterCount() == 1) {
3103                        parameterNames = new String[] { NamingConventions.getSingular(collName) };
3104                    } else if (method.getParameterCount() == 2) {
3105                        parameterNames = new String[] { "key", collName };
3106                    }
3107                }
3108            }
3109            return parameterNames;
3110        }
3111    
3112        public void setParameterFields(
3113            AbstractMethodItem method,
3114            String[] parameterFields) 
3115        {
3116            method.setAttribute(PARAMETER_FIELDS, parameterFields);
3117        }
3118    
3119        public void setPasswordParameters(
3120            AbstractMethodItem method,
3121            String[] params) 
3122        {
3123            method.setAttribute(PASSWORD_PARAMETERS, params);
3124        }
3125    
3126        public void setDirectCollectionMethods(
3127            CollectionItem collection,
3128            String[] methods) 
3129        {
3130            collection.setAttribute(
3131                DIRECT_COLLECTION_METHODS, 
3132                collection.getComponentType().getMethods(methods));
3133        }
3134    
3135        public void setDefaultValues(AbstractMethodItem method, Object[] values) {
3136            method.setAttribute(DEFAULT_VALUES, values);
3137        }
3138    
3139        public void setDefaultsAttributesOrder(
3140            ClassItem cl,
3141            String[] attributeNames) 
3142        {
3143            cl.setAttribute(
3144                DEFAULTS_ATTRIBUTES_ORDER,
3145                cl.getFields(attributeNames));
3146        }
3147    
3148        public static FieldItem[] getDefaultsAttributesOrder(ClassItem cl) {
3149            return (FieldItem[]) cl.getAttribute(DEFAULTS_ATTRIBUTES_ORDER);
3150        }
3151    
3152        public void setClosingMethod(ClassItem classItem, String methodName) {
3153            AbstractMethodItem method = classItem.getAbstractMethod(methodName);
3154            method.setAttribute("GuiAC.closingMethod", Boolean.TRUE);
3155        }
3156    
3157        public void setModifyingBoxes(
3158            ClassItem classItem,
3159            String methodName,
3160            String[] modifyingBoxes) 
3161        {
3162            AbstractMethodItem method = classItem.getAbstractMethod(methodName);
3163            method.setAttribute("GuiAC.modifyingBoxes", modifyingBoxes);
3164        }
3165    
3166        /**
3167         * Get the modifying boxes for the given abstract method item (a
3168         * method or a constructor).<p>
3169         *
3170         * @return the mofifying boxes names for each parameter */
3171    
3172        public String[] getModifyingBoxes(AbstractMethodItem method) {
3173            return (String[]) method.getAttribute("GuiAC.modifyingBoxes");
3174        }
3175    
3176        /**
3177         * Tells the swing gui to capture System.out so that it appears a
3178         * in tab.
3179         */
3180    
3181        public void captureSystemOut() {
3182            /*
3183              ProgramView pv = (ProgramView)getDisplay("admin");
3184              if (pv != null)
3185              pv.captureSystemOut();
3186              else
3187              Log.warning("gui","captureSystemOut(): no ProgramView found");
3188            */
3189        }
3190    
3191        public void captureSystemErr() {
3192            /*
3193              ProgramView pv = (ProgramView)getDisplay("admin");
3194              if (pv != null)
3195              pv.captureSystemErr();
3196              else
3197              Log.warning("gui","captureSystemErr(): no ProgramView found");
3198            */
3199        }
3200    
3201        String defaultCurrency;
3202    
3203        public void setDefaultCurrency(String currencyName, int precision) {
3204            MetaItem classItem =
3205                (MetaItem) ClassRepository.get().getVirtualClass("currency");
3206            classItem.setAttribute("gui.defaultCurrency", currencyName);
3207            declareCurrency(currencyName, precision, 1);
3208        }
3209    
3210        /**
3211         * Returns the default currency
3212         */
3213        public static String getDefaultCurrency() {
3214            MetaItem classItem =
3215                (MetaItem) ClassRepository.get().getVirtualClass("currency");
3216            return (String) classItem.getAttribute("gui.defaultCurrency");
3217        }
3218    
3219        public void declareCurrency(
3220            String currencyName,
3221            int precision,
3222            double rate) 
3223        {
3224            MetaItem classItem =
3225                (MetaItem) ClassRepository.get().getVirtualClass("currency");
3226            logger.debug("currency classItem =  " + classItem);
3227            Hashtable currencies =
3228                (Hashtable) classItem.getAttribute("gui.currencies");
3229            if (currencies == null) {
3230                logger.debug("building currencies");
3231                currencies = new Hashtable();
3232                classItem.setAttribute("gui.currencies", currencies);
3233            }
3234            currencies.put(
3235                currencyName,
3236                new Currency(currencyName, precision, rate));
3237            logger.debug("declareCurrency " + currencyName + " " + rate);
3238        }
3239        /**
3240         * Returns an enumeration of all declared currencies, including the
3241         * default currency. 
3242         * 
3243         * @return the declared currencies as an Enumeration of
3244         * Currency.
3245         */
3246        public static Enumeration getCurrencies() {
3247            MetaItem classItem =
3248                (MetaItem) ClassRepository.get().getVirtualClass("currency");
3249            Hashtable currencies =
3250                (Hashtable) classItem.getAttribute("gui.currencies");
3251            logger.debug(currencies.size() + " currencies");
3252            return currencies.keys();
3253        }
3254        /**
3255         * Returns the Currency object associated with a currency name.
3256         */
3257        public static Currency getCurrency(String currencyName) {
3258            MetaItem classItem =
3259                (MetaItem) ClassRepository.get().getVirtualClass("currency");
3260            Hashtable currencies =
3261                (Hashtable) classItem.getAttribute("gui.currencies");
3262            return (Currency) currencies.get(currencyName);
3263        }
3264    
3265        // guiType -> ViewFactories
3266        static Hashtable viewFactories = new Hashtable();
3267    
3268        /**
3269         * Returns a ViewFactory for a given guiType
3270         *
3271         * @param guiType the type of the gui ("swing","web",...)
3272         */
3273        public static ViewFactory getViewFactory(String guiType) {
3274            ViewFactory result = (ViewFactory) viewFactories.get(guiType);
3275            if (result == null) {
3276                loggerFactory.debug(
3277                    "Creating a ViewFactory for the \"" + guiType + "\" gui");
3278                result = new ViewFactory();
3279                ViewFactory.init(guiType, result);
3280                viewFactories.put(guiType, result);
3281            }
3282            return result;
3283        }
3284    
3285        /**
3286         * Set the view constructor for a given gui type.
3287         * @param guiType the type of the gui ("swing","web",...)
3288         * @param viewType the type of the view
3289         * @param constructor the view constructor for this gui type and view type
3290         */
3291        public void setViewConstructor(
3292            String guiType,
3293            String viewType,
3294            AbstractMethodItem constructor) 
3295        {
3296            getViewFactory(guiType).setViewConstructor(viewType, constructor);
3297        }
3298    
3299        // Dates
3300    
3301        public void setDateFormat(String dateFormat) {
3302            ClassRepository.get().getClass("java.util.Date").setAttribute(
3303                "DATE_FORMAT",
3304                dateFormat);
3305        }
3306    
3307        /**
3308         * Returns the date format as set by setDateFormat.
3309         *
3310         * @return the date format
3311         */
3312        public static String getDateFormat() {
3313            String format =
3314                (String) ClassRepository.get().getClass(
3315                    "java.util.Date").getAttribute(
3316                        "DATE_FORMAT");
3317            if (format == null)
3318                format = "dd/MM/yyyy";
3319            return format;
3320        }
3321    
3322        public void setDateHourFormat(String dateFormat) {
3323            ClassRepository.get().getClass("java.util.Date").setAttribute(
3324                DATEHOUR_FORMAT,
3325                dateFormat);
3326        }
3327    
3328        /**
3329         * Returns the date format for DateHours as set by setDateHourFormat.
3330         *
3331         * @return the date format
3332         */
3333        public static String getDateHourFormat() {
3334            String format =
3335                (String) ClassRepository.get().getClass(
3336                    "java.util.Date").getAttribute(
3337                        DATEHOUR_FORMAT);
3338            if (format == null)
3339                format = "dd/MM/yyyy HH:mm";
3340            return format;
3341        }
3342    
3343        /**
3344         * Returns the default display format of floats.
3345         */
3346        public static String getFloatFormat() {
3347            String format =
3348                (String) ClassRepository.get().getClass(
3349                    "java.lang.Float").getAttribute(
3350                        FLOAT_FORMAT);
3351            if (format == null)
3352                format = "0.00";
3353            return format;
3354        }
3355    
3356        public void setFloatFormat(FieldItem field, String format) {
3357            field.setAttribute(FLOAT_FORMAT, format);
3358        }
3359    
3360        /**
3361         * Returns the default display format of integers.
3362         */
3363        public static String getIntFormat() {
3364            String format =
3365                (String) ClassRepository.get().getClass(
3366                    "java.lang.Integer").getAttribute(FORMAT);
3367            if (format == null)
3368                format = "0";
3369            return format;
3370        }
3371    
3372        public void setIntFormat(FieldItem field, String format) {
3373            field.setAttribute(INT_FORMAT, format);
3374        }
3375    
3376        public void setFormat(String className, String format) {
3377            MetaItem metaItem = ClassRepository.get().getVirtualClass(className);
3378            metaItem.setAttribute(FORMAT, format);
3379        }
3380    
3381        /**
3382         * Returns the format of a ClassItem or VirtualClassItem.
3383         * @see #setFormat(String,String)
3384         */
3385        public static String getFormat(MetaItem item) {
3386            return (String) item.getAttribute(FORMAT);
3387        }
3388    
3389        /**
3390         * Returns the display format of an item.
3391         */
3392        public static String getFloatFormat(MetaItem item) {
3393            String format = (String) item.getAttribute(FLOAT_FORMAT);
3394            if (format == null)
3395                format = getFloatFormat();
3396            return format;
3397        }
3398    
3399        /**
3400         * Returns the display format of an item.
3401         */
3402        public static String getIntFormat(MetaItem item) {
3403            String format = (String) item.getAttribute(INT_FORMAT);
3404            if (format == null)
3405                format = getIntFormat();
3406            return format;
3407        }
3408    
3409        public void setCommitOnFocusLost(boolean value) {
3410            /*
3411              ClassRepository.get().getClass("org.objectweb.jac.aspects.gui.SwingObjectView").setAttribute(
3412              "gui.commitOnFocusLost",
3413              ExtBoolean.valueOf(value)
3414              );
3415            */
3416        }
3417    
3418        public static boolean getCommitOnFocusLost() {
3419            return true;
3420            /*
3421              Boolean val = (Boolean)ClassRepository.get().getClass("org.objectweb.jac.aspects.gui.SwingObjectView").
3422              getAttribute("gui.commitOnFocusLost");
3423              if (val == null)
3424              return true;
3425              else 
3426              return val.booleanValue();
3427            */
3428        }
3429    
3430        public void setDescription(ClassItem classItem, String description) {
3431            classItem.setAttribute(DESCRIPTION, description);
3432        }
3433    
3434        public void setDescription(MemberItem member, String description) {
3435            member.setAttribute(DESCRIPTION, description);
3436        }
3437    
3438        /**
3439         * Returns the description of an object if it has been set.
3440         */
3441    
3442        public static String getDescription(Object object) {
3443            return getDescription(object, null, null);
3444        }
3445    
3446        public static String getDescription(
3447            Object object,
3448            String beforeString,
3449            String afterString) 
3450        {
3451            String expr =
3452                (String) ClassRepository.get().getClass(object).getAttribute(
3453                    DESCRIPTION);
3454            if (expr == null)
3455                return null;
3456            else
3457                return parseFormatExpression(
3458                    expr,
3459                    object,
3460                    beforeString,
3461                    afterString);
3462        }
3463    
3464        public void setLabel(ClassItem classItem, String label) {
3465            classItem.setAttribute(LABEL, label);
3466        }
3467    
3468        public void setLabel(MemberItem member, String label) {
3469            member.setAttribute(LABEL, label);
3470        }
3471    
3472        public void setLabel(
3473            MemberItem member,
3474            MemberItem selector,
3475            String label) 
3476        {
3477            Map rules = (Map) member.getAttributeAlways(CONTEXTUAL_LABEL);
3478            if (rules == null) {
3479                rules = new HashMap();
3480                member.setAttribute(CONTEXTUAL_LABEL, rules);
3481            }
3482            rules.put(selector, label);
3483        }
3484    
3485        public static String getLabel(MetaItem item) {
3486            return getLabel(item, null);
3487        }
3488    
3489        /**
3490         * Returns the label of an item, or an automatically computed
3491         * string if none was set.
3492         * @param item the MetaItem
3493         * @return the label of the MetaItem
3494         */
3495        public static String getLabel(MetaItem item, Stack context) {
3496            String label = (String) item.getAttribute(LABEL);
3497            if (context != null) {
3498                label =
3499                    (String) getContextAttribute(item,
3500                                                 CONTEXTUAL_LABEL,
3501                                                 context,
3502                                                 label);
3503            }
3504            if (label == null) {
3505                label = NamingConventions.textForName(item.getName());
3506            }
3507            if (label==null)
3508                logger.warn("No label for "+item);
3509            return label;
3510        }
3511    
3512        public void setMnemonics(MemberItem method, String mnemonics) {
3513            method.setAttribute(MNEMONICS,mnemonics);
3514        }
3515    
3516        public void setMnemonics(ClassItem cli, String mnemonics) {
3517            cli.setAttribute(MNEMONICS,mnemonics);
3518        }
3519    
3520        public static String getMnemonics(MetaItem item) {
3521            String mnemonics = (String)item.getAttribute(MNEMONICS);
3522            return mnemonics!=null ? mnemonics : "";
3523        }
3524    
3525        public static String getMnemonics(MethodItem method) {
3526            String mnemonics = (String)method.getAttribute(MNEMONICS);
3527            if (mnemonics==null) {
3528                if (method.isSetter()) {
3529                    mnemonics = getMnemonics(method.getSetField());
3530                } else if (method.isGetter()) {
3531                    mnemonics = getMnemonics(method.getReturnedField());
3532                } else if (method.isAdder()) {
3533                    mnemonics = getMnemonics(method.getAddedCollection());
3534                } else if (method.isRemover()) {
3535                    mnemonics = getMnemonics(method.getRemovedCollection());
3536                }
3537            }
3538            return mnemonics!=null ? mnemonics : "";
3539        }
3540    
3541        Hashtable enums = new Hashtable();
3542    
3543        public void defineEnum(String name, String[] values, int start, int step) {
3544            enums.put(name, new Enum(values, start, step));
3545        }
3546    
3547        public void setDisplayLabel(MemberItem member, boolean displayLabel) {
3548            member.setAttribute(DISPLAY_LABEL, ExtBoolean.valueOf(displayLabel));
3549        }
3550    
3551        public void setDisplayLabel(String itemName, boolean displayLabel) {
3552            MetaItem metaItem = ClassRepository.get().getVirtualClass(itemName);
3553            metaItem.setAttribute(DISPLAY_LABEL, ExtBoolean.valueOf(displayLabel));
3554        }
3555    
3556        public void setViewableItems(CollectionItem collection, boolean viewable) {
3557            setViewableItems(collection,DEFAULT_VIEW,viewable);
3558        }
3559    
3560        public void setViewableItems(CollectionItem collection, String viewName, boolean viewable) {
3561            getView(collection,viewName).setViewableItems(viewable);
3562        }
3563    
3564        public void setEnableLinks(CollectionItem collection, String viewName, boolean enable) {
3565            getView(collection,viewName).setEnableLinks(enable);
3566        }
3567    
3568        public void setEnableLinks(ClassItem cli, String viewName, boolean enable) {
3569            getView(cli,viewName).setEnableLinks(enable);
3570        }
3571    
3572        public void setCellViewType(CollectionItem collection, String viewName, 
3573                                    FieldItem field, String viewType) {
3574            getView(collection,viewName).setViewType(field,viewType);
3575        }
3576    
3577        /**
3578         * Converts the a String into an object for the value of a field
3579         * @param field the field for which to convert the value
3580         * @param value the string to convert
3581         * @return an object of the type of the field whose string
3582         * representation is <em>value</em>, or null.
3583         */
3584        public static Object getDefaultValue(FieldItem field, String value) {
3585            //System.out.println("GET_DEFAULT_VALUE: "+field+ ", " + field.getType());
3586            Collection objects =
3587                ObjectRepository.getObjects(
3588                    ClassRepository.get().getClass(field.getType()));
3589            Iterator i = objects.iterator();
3590            while (i.hasNext()) {
3591                Object obj = i.next();
3592                //System.out.println("TESTING: "+GuiAC.toString(obj));
3593                if (GuiAC.toString(obj).equals(value)) {
3594                                    //System.out.println("RETURN: "+obj);
3595                    return obj;
3596                }
3597            }
3598            return null;
3599        }
3600    
3601        public String[] getDefaultConfigs() {
3602            return new String[] {
3603                "org/objectweb/jac/aspects/gui/gui.acc",
3604                /*"org/objectweb/jac/aspects/gui/swing/gui.acc", */
3605                "org/objectweb/jac/aspects/gui/web/gui.acc",
3606                "org/objectweb/jac/aspects/authentication/gui.acc",
3607                "org/objectweb/jac/aspects/user/gui.acc" };
3608        }
3609    
3610        public void setNavBar(String gui, CollectionItem collection) {
3611            CustomizedGUI cgui = (CustomizedGUI) getCustomized(gui);
3612            if (cgui == null) {
3613                error(gui+" has not been declared with registerCustomized");
3614                return;
3615            }
3616    
3617            Vector vect = (Vector) collection.getAttribute(NAVBAR);
3618    
3619            if (vect == null) {
3620                vect = new Vector();
3621                collection.setAttribute(NAVBAR, vect);
3622            }
3623            if (!vect.contains(cgui)) {
3624                vect.add(cgui);
3625            }
3626        }
3627    
3628        public static boolean hasSetNavBar(
3629            CustomizedGUI gui,
3630            CollectionItem coll) 
3631        {
3632            Vector vect = (Vector) coll.getAttribute(NAVBAR);
3633            return vect != null && vect.contains(gui);
3634        }
3635    
3636        public void addViewFieldDependency(ClassItem cl, String fieldName) {
3637            Collection fields =
3638                (Collection) cl.getAttributeAlways(FIELD_DEPENDENCIES);
3639            if (fields == null) {
3640                fields = new Vector();
3641                cl.setAttribute(FIELD_DEPENDENCIES, fields);
3642            }
3643            fields.add(cl.getField(fieldName));
3644        }
3645    
3646        public void setInteractionHandler(MethodItem method, MethodItem handler) {
3647            if (!handler.isStatic())
3648                error("handler method must be static");
3649            else
3650                method.setAttribute(INTERACTION_HANDLER, handler);
3651        }
3652    
3653        public static MethodItem getInteractionHandler(AbstractMethodItem method) {
3654            return (MethodItem) method.getAttribute(INTERACTION_HANDLER);
3655        }
3656    
3657        /**
3658         * Returns the fields the views a class depend on.
3659         * @param cli the class
3660         * @return a collection of FieldItem
3661         * @see #addViewFieldDependency(ClassItem,String)
3662         */
3663        public static Collection getDependentFields(ClassItem cli) {
3664            return (Collection) cli.getAttribute(FIELD_DEPENDENCIES);
3665        }
3666    
3667        public static long dialogTimeout = 1000 * 60 * 20; // 20 minutes
3668        public void setDialogTimeout(long timeout) {
3669            dialogTimeout = timeout;
3670        }
3671    
3672        static String labelAdd = "add";
3673        public void setLabelAdd(String label) {
3674            labelAdd = label;
3675        }
3676        public static String getLabelAdd() {
3677            return labelAdd;
3678        }
3679    
3680        static String labelNew = "new";
3681        public void setLabelNew(String label) {
3682            labelNew = label;
3683        }
3684        public static String getLabelNew() {
3685            return labelNew;
3686        }
3687    
3688        static String labelCancel = "Cancel";
3689        public void setLabelCancel(String label) {
3690            labelCancel = label;
3691        }
3692        public static String getLabelCancel() {
3693            return labelCancel;
3694        }
3695    
3696        static String labelOK = "OK";
3697        public void setLabelOK(String label) {
3698            labelOK = label;
3699        }
3700        public static String getLabelOK() {
3701            return labelOK;
3702        }
3703    
3704        static String labelClose = "Close";
3705        public void setLabelClose(String label) {
3706            labelClose = label;
3707        }
3708        public static String getLabelClose() {
3709            return labelClose;
3710        }
3711    
3712        static String labelNone = "None";
3713        public void setLabelNone(String label) {
3714            labelNone = label;
3715        }
3716        public static String getLabelNone() {
3717            return labelNone;
3718        }
3719    
3720        static String labelAll = "All";
3721        public void setLabelAll(String label) {
3722            labelAll = label;
3723        }
3724        public static String getLabelAll() {
3725            return labelAll;
3726        }
3727    
3728        public void selectWithIndexedField(
3729            ClassItem cl,
3730            CollectionItem collection,
3731            String repositoryName) 
3732        {
3733            cl.setAttribute(INDEXED_FIELD_SELECTOR, collection);
3734            cl.setAttribute(REPOSITORY_NAME, repositoryName);
3735        }
3736    
3737        public void setIndexNotFoundHandler(ClassItem cl, MethodItem handler) {
3738            cl.setAttribute(INDEX_NOT_FOUND_HANDLER, handler);
3739        }
3740    
3741        /**
3742         * Gets the repository object of a class
3743         * @param cl the class
3744         * @see #selectWithIndexedField(ClassItem,CollectionItem,String)
3745         */
3746        public static Object getRepository(ClassItem cl) {
3747            String repositoryName = (String) cl.getAttribute(REPOSITORY_NAME);
3748            if (repositoryName != null) {
3749                return NameRepository.get().getObject(repositoryName);
3750            } else {
3751                return null;
3752            }
3753        }
3754    
3755        static String encoding = "UTF-8";
3756        public void setEncoding(String encoding) {
3757            this.encoding = encoding;
3758        }
3759        public static String getEncoding() {
3760            return encoding;
3761        }
3762    }