/******************************************************************* Copyright (c) 2001-2010 Apprisant Technologies Inc. All rights reserved. Apprisant Technologies permits non-exclusive royalty free use, copying and modification of this demo program source code for the purposes of evaluating the Apprisant Toolkit or building applications that use it. This software and documentation is provided "AS IS". APPRISANT TECHNOLOGIES DISCLAIMS ANY REPRESENTATIONS AND WARRANTIES, INCLUDING BUT NOT LIMITED TO ANY IMPLIED WARRANTY OF MERCHANTABILITY AND FITNESS OF THIS PRODUCT FOR ANY PARTICULAR PURPOSE. APPRISANT TECHNOLOGIES SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY ANY PARTY, INCLUDING LOST PROFITS, ARISING FROM THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ITS DERIVATIONS. ********************************************************************/ package red; import java.awt.Point; import java.awt.Dimension; import java.util.*; import apprisant.diagram.*; import apprisant.diagram.render.*; import apprisant.diagram.env.*; import apprisant.diagram.event.AGTagListener; import apprisant.treelayout.*; /** The element model for the Red demo. Creates an element for each renderer. */ class RedModel extends BasicModel { TreeLayout layout = null; /* nodeRen is the renderer whose bounds determine the node dimensions. */ public RedModel (AGRenderer nodeRen) { super(); // Configure the TreeLayout layout = new TreeLayout(); layout.setStyle(TreeLayout.Style.INLINE); layout.setInlineSpacing(18); layout.setInlineLinkOffsetRatio(.3); layout.setNodeRenderer(nodeRen); super.setLayout(layout); } /* Called by Red after the diagram has been created to enable the TreeLayout's tag listener for the open/close toggles. */ void enableStateListener() { layout.enableStateListener(true); } /** Called by Red to set the renderers to be displayed. */ void setRenderers (List renderers) { // Construct display elements for the renderers for (AGRenderer r : renderers) { RedElement e = new RedElement(getUniqueName(r), r, null, null); super.add(e); buildChildren(e); } } /** Recursively creates elements for the renderer's descendants. */ private void buildChildren (RedElement parent) { Object ren = parent.getDataObject(); RedElement e = null; if (ren instanceof ListRenderer) { ListRenderer listRen = (ListRenderer) ren; for (AGRenderer r : listRen.getRenderers()) { e = new RedElement(getUniqueName(r), r, parent, null); super.add(e); buildChildren(e); } } else if (ren instanceof ClassRenderer) { ClassRenderer classRen = (ClassRenderer) ren; for (Class cl : classRen.getClasses()) { AGRenderer r = classRen.get(cl); e = new RedElement (getUniqueName(r), r, parent, trimClassname(cl, false)); super.add(e); buildChildren(e); } } else if (ren instanceof OptionRenderer) { OptionRenderer optionRen = (OptionRenderer) ren; String attr = optionRen.getSelector(); AGConverter vc = optionRen.getConverter(attr); if (vc == null) vc = AGEnvironment.getConverter(attr); for (Object val : optionRen.getValues()) { AGRenderer r = optionRen.get(val); // Get a text representation for the attribute value String s = String.valueOf(val); if (vc != null) { try { s = vc.getAsString(val); } catch (AGException ce) { AGLog.log(Red.ME, "converting attribute", AGLog.WARNING, ce); } } e = new RedElement(getUniqueName(r), r, parent, s); super.add(e); buildChildren(e); } } else if (ren instanceof BooleanRenderer) { BooleanRenderer boolRen = (BooleanRenderer) ren; AGRenderer r = null; r = boolRen.getTrueRenderer(); if (r != null) { e = new RedElement(getUniqueName(r), r, parent, "true"); super.add(e); buildChildren(e); } r = boolRen.getFalseRenderer(); if (r != null) { e = new RedElement(getUniqueName(r), r, parent, "false"); super.add(e); buildChildren(e); } } } /** Make synthetic names for elements whose names are not unique and for elements with no renderer. */ String getUniqueName (AGRenderer r) { String name = (r != null) ? r.getId() : null; int i = 0; String newName = name; if (name == null || name.trim().length() == 0) { name = "_"; newName = name + (i++); } while (super.contains(newName)) { newName = name + (i++); } return newName; } /** Drop the package names and optionally the inner class names from the given classname. */ static String trimClassname (Class cl, boolean trimInner) { if (cl == null) return ""; String name = cl.getName(); int dot = name.lastIndexOf('.') + 1; String result = name.substring(dot); if (trimInner) { int dollar = result.lastIndexOf('$'); if (dollar > -1) { result = result.substring(0, dollar); } } return result; } /** Drop the directories from the given pathname. */ static String trimPathname (String path) { if (path == null) return null; int slash = Math.max(path.lastIndexOf('/'),path.lastIndexOf('\\')); return path.substring(slash+1); } }