| 1 18 19 package org.objectweb.jac.aspects.gui; 20 21 import java.lang.reflect.Array; 22 import java.text.SimpleDateFormat; 23 import java.util.Arrays; 24 import java.util.Collection; 25 import java.util.Date; 26 import java.util.Enumeration; 27 import java.util.HashMap; 28 import java.util.Hashtable; 29 import java.util.Iterator; 30 import java.util.List; 31 import java.util.Map; 32 import java.util.StringTokenizer; 33 import java.util.Vector; 34 import org.apache.log4j.Level; 35 import org.apache.log4j.Logger; 36 import org.objectweb.jac.aspects.session.SessionAC; 37 import org.objectweb.jac.core.AspectComponent; 38 import org.objectweb.jac.core.Collaboration; 39 import org.objectweb.jac.core.Display; 40 import org.objectweb.jac.core.Interaction; 41 import org.objectweb.jac.core.Jac; 42 import org.objectweb.jac.core.NameRepository; 43 import org.objectweb.jac.core.ObjectRepository; 44 import org.objectweb.jac.core.Wrappee; 45 import org.objectweb.jac.core.Wrapping; 46 import org.objectweb.jac.core.dist.Distd; 47 import org.objectweb.jac.core.dist.RemoteContainer; 48 import org.objectweb.jac.core.rtti.AbstractMethodItem; 49 import org.objectweb.jac.core.rtti.ClassItem; 50 import org.objectweb.jac.core.rtti.ClassRepository; 51 import org.objectweb.jac.core.rtti.CollectionItem; 52 import org.objectweb.jac.core.rtti.FieldItem; 53 import org.objectweb.jac.core.rtti.MemberItem; 54 import org.objectweb.jac.core.rtti.MetaItem; 55 import org.objectweb.jac.core.rtti.MethodItem; 56 import org.objectweb.jac.core.rtti.NamingConventions; 57 import org.objectweb.jac.core.rtti.NoSuchMethodException; 58 import org.objectweb.jac.core.rtti.RttiAC; 59 import org.objectweb.jac.core.rtti.VirtualClassItem; 60 import org.objectweb.jac.util.Enum; 61 import org.objectweb.jac.util.ExtArrays; 62 import org.objectweb.jac.util.ExtBoolean; 63 import org.objectweb.jac.util.InvalidIndexException; 64 import org.objectweb.jac.util.Stack; 65 66 81 82 public class GuiAC extends AspectComponent implements GuiConf { 83 static Logger logger = Logger.getLogger("gui"); 84 static Logger loggerContext = Logger.getLogger("gui.context"); 85 static Logger loggerDisplay = Logger.getLogger("gui.display"); 86 static Logger loggerApp = Logger.getLogger("application"); 87 static Logger loggerWuni = Logger.getLogger("gui.wuni"); 88 static Logger loggerTable = Logger.getLogger("gui.table"); 89 static Logger loggerMenu = Logger.getLogger("gui.menu"); 90 static Logger loggerFactory = Logger.getLogger("gui.factory"); 91 92 93 public static final String DEFAULT_VIEW = "default"; 94 95 96 public static final String AUTOCREATE_VIEW = "autocreate"; 97 98 99 protected static Hashtable displays = new Hashtable(); 100 101 102 protected static Hashtable cguis = new Hashtable(); 103 104 public static final String VIEWS = "GuiAC.VIEWS"; 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"; 115 public static final String AUTO_CREATE_INITIALIZER = "GuiAC.AUTO_CREATE_INITIALIZER"; 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"; public static final String EDITABLE_DEFAULT_VALUES = "GuiAC.EDITABLE_DEFAULT_VALUES"; 122 public static final String FILTERED_COLUMNS = "GuiAC.FILTERED_COLUMNS"; 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_EDITOR = "GuiAC.EMBEDDED_EDITOR"; 129 public static final String VISIBLE = "GuiAC.VISIBLE"; public static final String EDITABLE = "GuiAC.EDITABLE"; public static final String ADDABLE = "GuiAC.ADDABLE"; public static final String REMOVABLE = "GuiAC.REMOVABLE"; public static final String CREATABLE = "GuiAC.CREATABLE"; 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"; public static final String POST_INVOKE_HOOKS= "GuiAC.POST_INVOKE_HOOKS"; public static final String VIEW_HEIGHT = "GuiAC.VIEW_HEIGHT"; public static final String VIEW_WIDTH = "GuiAC.VIEW_WIDTH"; public static final String EDITOR_HEIGHT = "GuiAC.EDITOR_HEIGHT"; public static final String EDITOR_WIDTH = "GuiAC.EDITOR_WIDTH"; public static final String EDITOR_SMALL_WIDTH = "GuiAC.EDITOR_SMALL_WIDTH"; public static final String EDITOR_SMALL_HEIGHT = "GuiAC.EDITOR_SMALL_HEIGHT"; public static final String HIDDEN_TREE_RELATION = "GuiAC.HIDDEN_TREE_RELATION"; 167 public static final String BORDER = "GuiAC.BORDER"; 168 public static final String DESCRIPTION = "GuiAC.DESCRIPTION"; 169 public static final String ICON = "GuiAC.ICON"; 170 public static final String DYNAMIC_ICON = "GuiAC.DYNAMIC_ICON"; 171 public static final String MENU = "GuiAC.MENU"; 172 public static final String DISPLAY_LABEL = "GuiAC.DISPLAY_LABEL"; public static final String LABEL = "GuiAC.LABEL"; public static final String MNEMONICS = "GuiAC.MNEMONICS"; public static final String CONTEXTUAL_LABEL = "GuiAC.CONTEXTUAL_LABEL"; 176 public static final String STYLE = "GuiAC.STYLE"; public static final String NEW_WINDOW = "GuiAC.NEW_WINDOW"; 178 public static final String NUM_ROWS_PER_PAGE = "GuiAC.NUM_ROWS_PER_PAGE"; public static final String AVAILABLE_NUM_ROWS_PER_PAGE = "GuiAC.AVAILABLE_NUM_ROWS_PER_PAGE"; public static final String AUTO_CREATED_STATE = "GuiAC.AUTO_CREATED_STATE"; 181 public static final String SMALL_TARGET_CONTAINER = "GuiAC.SMALL_TARGET_CONTAINER"; 182 public static final String NAVBAR = "GuiAC.NAVBAR"; 183 public static final String FIELD_DEPENDENCIES = "GuiAC.FIELD_DEPENDENCIES"; 184 public static final String LINE_BREAKS = "GuiAC.LINE_BREAKS"; 185 public static final String DIRECT_COLLECTION_METHODS = "GuiAC.DIRECT_COLLECTION_METHODS"; 186 public static final String DATE_FORMAT = "GuiAC.DATE_FORMAT"; 187 public static final String DATEHOUR_FORMAT = "GuiAC.DATEHOUR_FORMAT"; 188 public static final String FLOAT_FORMAT = "GuiAC.FLOATFORMAT"; 189 public static final String INT_FORMAT = "GuiAC.INT_FORMAT"; 190 public static final String FORMAT = "GuiAC.FORMAT"; 191 192 public static final String ASKING_SEQUENCE = "GuiAC.ASKING_SEQUENCE"; 193 194 public static final String DESKTOP_VIEW = "GuiAC.DESKTOP_VIEW"; public static final String FILE_SELECTION_MODE = 196 "GuiAC.FILE_SELECTION_MODE"; 197 public static final String FILE_EXTENSIONS = "GuiAC.FILE_EXTENSIONS"; 199 public static final String FILE_EXTENSIONS_DESCRIPTION = 201 "GuiAC.FILE_EXTENSIONS_DESCRIPTION"; 202 public static final String FILE_CHOOSER_VIEW = "GuiAC.FILE_CHOOSER_VIEW"; 204 public static final String FILE_EDITOR_CONFIG = "GuiAC.FILE_EDITOR_CONFIG"; 205 206 public static final String INDEXED_FIELD_SELECTOR = 207 "GuiAC.INDEXED_FIELD_SELECTOR"; 208 public static final String INDEX_NOT_FOUND_HANDLER = 210 "RttiAC.INDEX_NOT_FOUND_HANDLER"; 211 213 public static final String REPOSITORY_NAME = "GuiAC.REPOSITORY_NAME"; 214 215 217 public static final String DISPLAY_CONTEXT = "GuiAC.DISPLAY"; 218 219 public static final String ASK_FOR_PARAMETERS = "GuiAC.ASK_FOR_PARAMETERS"; 220 221 public static final String INVOKED_METHOD = "GuiAC.INVOKED_METHOD"; 222 public static final String AUTO_CREATION = "GuiAC.AUTO_CREATION"; 223 public static final String AUTOCREATE_REASON = "GuiAC.AUTOCREATE_REASON"; 224 226 public static final String SMALL_VIEW = "GuiAC.SMALL_VIEW"; public static final String OPPOSITE_ROLE = "GuiAC.OPPOSITE_ROLE"; 230 public static final String VIEW = "GuiAC.VIEW"; 232 public static final String OPEN_VIEW = "GuiAC.OPEN_VIEW"; public static final String GRAPHIC_CONTEXT = "GuiAC.GRAPHIC_CONTEXT"; 234 235 236 public static final String START_INDEXES = "GuiAC.START_INDEXES"; 237 238 public static final int THUMB_MAX_WIDTH = 100; 239 public static final int THUMB_MAX_HEIGHT = 50; 240 public static final int THUMB_QUALITY = 70; 241 242 public static final String SORT_COLUMN = "GuiAC.SORT_COLUMN"; public static final String DEF_SORT = "GuiAC.DEF_SORT"; 245 246 public static final String TABLE_FILTER = "GuiAC.TABLE_FILTER"; 248 249 250 251 253 254 public static final String SUBSTANCE = "GuiAC.SUBSTANCE"; 256 257 public static final String REMOVED_NODE = "GuiAC.REMOVED_NODE"; 258 259 static String parseFormatExpression( 260 String formatExpr, 261 Object o, 262 String beforeString, 263 String afterString) 264 { 265 final String delim = "%"; 266 StringBuffer result = new StringBuffer(); 267 String subString = null; 268 ClassItem cl = ClassRepository.get().getClass(o); 269 StringTokenizer st = new StringTokenizer(formatExpr, delim, true); 270 while (st.hasMoreTokens()) { 271 boolean firstDelim = false; 272 String cur = st.nextToken(); 273 if (!cur.equals(delim)) { 275 result.append(cur); 276 continue; 277 } 278 if (cur.equals(delim)) { 280 cur = st.nextToken(); 281 if (cur.equals(delim)) { 283 result.append(delim); 284 continue; 285 } 286 if (cur.indexOf("()") == -1) { 287 try { 289 FieldItem field = cl.getField(cur); 290 Object value = field.getThroughAccessor(o); 291 if (beforeString != null) { 292 result.append(beforeString); 293 } 294 if (field != null) 295 result.append(GuiAC.toString(field, value)); 296 else 297 result.append("<bad field: " + cur + ">"); 298 if (afterString != null) { 299 result.append(afterString); 300 } 301 } catch (Exception e) { 302 result.append("<bad field: " + cur + ">"); 304 } 305 } else { 306 try { 308 Object value = 309 ClassRepository.invokeDirect( 310 cl.getActualClass(), 311 cur.substring(0, cur.length() - 2), 312 o, 313 ExtArrays.emptyObjectArray); 314 ; 315 if (beforeString != null) { 316 result.append(beforeString); 317 } 318 result.append(GuiAC.toString(value)); 319 if (afterString != null) { 320 result.append(afterString); 321 } 322 } catch (Exception e) { 323 result.append( 325 "<bad method: " 326 + cur.substring(0, cur.length() - 2) 327 + ">"); 328 } 329 } 330 cur = st.nextToken(); 332 } 333 } 334 return result.toString(); 335 } 336 337 public static String toString(Object o) { 338 return toString(o, null); 339 } 340 341 public static String toString(float value) { 342 return toString(new Float(value), null); 343 } 344 345 public static String toString(double value) { 346 return toString(new Double(value), null); 347 } 348 349 355 public static String toString(Object o, Stack context) { 356 if (o == null) 357 return "null"; 358 ClassItem cl = ClassRepository.get().getClass(o); 359 360 String formatExpr = (String) cl.getAttribute(TO_STRING); 361 if (context != null) { 362 formatExpr = 363 (String) getContextAttribute(cl, 364 CONTEXTUAL_TO_STRING, 365 context, 366 formatExpr); 367 } 368 if (formatExpr == null) { 369 if (o instanceof java.awt.Point) { 370 java.awt.Point p = (java.awt.Point) o; 371 return "(" + p.x + "," + p.y + ")"; 372 } else if (o instanceof java.awt.Dimension) { 373 java.awt.Dimension d = (java.awt.Dimension) o; 374 return d.width + "x" + d.height; 375 } else if (o instanceof Date) { 376 return new SimpleDateFormat(getDateFormat()).format((Date) o); 377 } else if (o instanceof Collection) { 378 String string = ""; 379 Iterator it = ((Collection) o).iterator(); 380 while (it.hasNext()) { 381 string += toString(it.next(), context); 382 if (it.hasNext()) 383 string += ", "; 384 } 385 return string; 386 } else if (o instanceof Wrappee) { 387 return NameRepository.get().getName(o); 388 } else { 389 return o.toString(); 390 } 391 } else { 392 return parseFormatExpression(formatExpr, o, null, null); 393 } 394 } 395 396 403 public static String getToolTip(Object o, Stack context) { 404 if (o == null) 405 return null; 406 ClassItem cl = ClassRepository.get().getClass(o); 407 408 String formatExpr = (String) cl.getAttribute(TOOLTIP); 409 if (context != null) { 410 formatExpr = 411 (String) getContextAttribute(cl, 412 CONTEXTUAL_TOOLTIP, 413 context, 414 formatExpr); 415 } 416 if (formatExpr == null) { 417 return null; 418 } else { 419 return parseFormatExpression(formatExpr, o, null, null); 420 } 421 } 422 423 428 public static Object getContextAttribute( 429 MetaItem item, 430 String attribute, 431 Stack context, 432 Object defaultValue) 433 { 434 loggerContext.debug("getContextAttribute " + item + "," + attribute); 435 Map rules = (Map) item.getAttribute(attribute); 436 if (rules == null) { 437 loggerContext.debug("No attribute " + attribute); 438 return defaultValue; 439 } else { 440 if (context != null) { 441 loggerContext.debug("rules = " + rules); 442 for (int i = 0; i < context.size(); i++) { 443 MetaItem elt = (MetaItem) context.peek(i); 444 Iterator it = rules.keySet().iterator(); 445 while (it.hasNext()) { 446 MetaItem selector = (MetaItem) it.next(); 447 if (selector instanceof ClassItem) { 448 ClassItem cl = (ClassItem) selector; 449 if ((elt instanceof ClassItem 450 && ((ClassItem) elt).isSubClassOf(cl)) 451 || (elt instanceof MemberItem 452 && ((MemberItem) elt) 453 .getClassItem() 454 .isSubClassOf(cl))) { 455 loggerContext.debug(elt + " matches " + selector 456 + " -> " + rules.get(selector)); 457 return rules.get(selector); 458 } 459 } else if (selector instanceof MemberItem) { 460 MemberItem member = (MemberItem) selector; 461 if (elt instanceof MemberItem) { 462 if (((MemberItem) elt) 463 .getClassItem() 464 .isSubClassOf(member.getClassItem()) 465 && member.getName().equals(elt.getName())) { 466 loggerContext.debug(elt + " matches " + selector 467 + " -> " + rules.get(selector)); 468 return rules.get(selector); 469 } 470 } 471 } 472 } 473 } 474 return defaultValue; 475 } else { 476 loggerContext.debug("No graphic context"); 477 return defaultValue; 478 } 479 } 480 } 481 482 public static void pushGraphicContext(MetaItem value) { 483 Collaboration collab = Collaboration.get(); 484 Stack gc = (Stack) collab.getAttribute(GRAPHIC_CONTEXT); 485 if (gc == null) { 486 gc = new Stack(); 487 collab.addAttribute(GRAPHIC_CONTEXT, gc); 488 } 489 loggerContext.debug("push " + value); 490 gc.push(value); 491 } 492 493 public static MetaItem popGraphicContext() { 494 Stack gc = (Stack) Collaboration.get().getAttribute(GRAPHIC_CONTEXT); 495 if (gc == null) { 496 loggerContext.error( 497 "No GRAPHIC_CONTEXT in current context, cannot popGraphicContext"); 498 return null; 499 } else { 500 loggerContext.debug("pop " + gc.peek()); 501 return (MetaItem) gc.pop(); 502 } 503 } 504 505 public static Stack getGraphicContext() { 506 return (Stack) Collaboration.get().getAttribute(GRAPHIC_CONTEXT); 507 } 508 509 515 public static String toString(FieldItem field, Object value) { 516 if (value == null) { 517 return "null"; 518 } 519 Enum enum = getEnum(field); 520 if (enum != null) { 521 try { 522 return value != null 523 ? enum.int2string(((Integer) value).intValue()) 524 : ""; 525 } catch (InvalidIndexException e) { 526 return ""; 527 } 528 } else if (value instanceof Date) { 529 return new SimpleDateFormat(getDateFormat()).format((Date) value); 530 } else { 531 return toString(value); 532 } 533 } 534 535 541 public static String toString(FieldItem field, int value) { 542 return toString(field, new Integer(value)); 543 } 544 545 550 551 public static final Display getDisplay(String displayID) { 552 return (Display) displays.get(displayID); 553 } 554 555 561 public static final CustomizedGUI getCustomized(String customizedID) { 562 return (CustomizedGUI) cguis.get(customizedID); 563 } 564 565 573 public static Display createDisplay(String displayID, 574 Class displayType, 575 ViewFactory factory) 576 throws Exception 577 { 578 Display ret = null; 579 loggerDisplay.debug("createDisplay(" + displayType.getName() + "," + displayType + ")"); 580 if ((ret = getDisplay(displayID)) != null) { 581 loggerDisplay.warn("Display " + displayID + " is already registered"); 582 return ret; 583 } 584 try { 585 ret = 586 (Display) displayType 587 .getDeclaredConstructor(new Class[] { ViewFactory.class }) 588 .newInstance(new Object[] { factory }); 589 590 ret.setDisplayID(displayID); 591 addDisplay(displayID, ret); 592 } catch (Exception e) { 593 logger.error( 594 "createDisplay("+displayID+","+ 595 displayType.getName()+","+factory+ 596 ") failed to instantiate display: "+e); 597 throw e; 598 } 599 return ret; 600 } 601 602 public void createSwingDisplays(String[] customizedIDs) { 603 loggerDisplay.debug("createSwingDisplays(" + Arrays.asList(customizedIDs) + ")"); 604 for (int i=0; i<customizedIDs.length; i++) { 605 try { 606 if (customizedIDs[i].equals("admin")) { 607 } else { 609 showCustomizedSwing(customizedIDs[i], customizedIDs[i]); 610 } 611 } catch(Exception e) { 612 logger.error("Failed to create swing display \""+customizedIDs[i]+'"',e); 613 } 614 } 615 } 616 617 public void createWebDisplays(String[] customizedIDs) { 618 int port = 8088; 619 try { 620 logger.info( 621 "createWebDisplays "+Arrays.asList(customizedIDs)+ 622 " for application " + application); 623 org.objectweb.jac.aspects.gui.web.WebDisplay.startWebServer( 624 application, 625 customizedIDs, 626 port); 627 } catch (Exception e) { 628 loggerDisplay.error("Failed to start webgui : " + e); 629 loggerDisplay.error("Check that another server is not running on port " + port); 630 } 631 } 632 633 639 public static void addDisplay(String displayID, Display newDisplay) { 640 loggerDisplay.debug("addDisplay(" + newDisplay.getClass().getName() + ")"); 641 displays.put(displayID, newDisplay); 642 } 643 644 649 650 public static void removeDisplay(Display display) { 651 if (display.getDisplayID() != null) 652 displays.remove(display.getDisplayID()); 653 } 654 655 666 public static void registerDisplay(String name, 667 String displayType, 668 String guiType) 669 throws Exception 670 { 671 if (getDisplay(name) != null) { 672 loggerDisplay.warn("display " + name + " is already launched"); 673 return; 674 } 675 createDisplay( 676 name, 677 Class.forName(displayType),
|