Clover coverage report - clover
Coverage timestamp: Sat Oct 8 2005 22:54:17 EDT
file stats: LOC: 200   Methods: 14
NCLOC: 125   Classes: 3
 
 Source file Conditionals Statements Methods TOTAL
TestHierarchy.java 87.5% 96.4% 100% 94.1%
coverage coverage
 1   
 package abbot.finder;
 2   
 
 3   
 import java.awt.*;
 4   
 import java.awt.event.*;
 5   
 import java.util.*;
 6   
 import javax.swing.SwingUtilities;
 7   
 import javax.swing.JPopupMenu;
 8   
 
 9   
 import abbot.Log;
 10   
 import abbot.util.*;
 11   
 
 12   
 /** Provide isolation of a Component hierarchy to limit consideration to only
 13   
     those Components created during the lifetime of this Hierarchy instance.
 14   
     Extant Components (and any subsequently generated subwindows) are ignored
 15   
     by default.<p>
 16   
     Implicitly auto-filters windows which are disposed (i.e. generate a
 17   
     WINDOW_CLOSED event), but also implicitly un-filters them if they should
 18   
     be shown again.  Any Window explicitly disposed with
 19   
     {@link #dispose(Window)} will be ignored permanently.<p> 
 20   
 */
 21   
 public class TestHierarchy extends AWTHierarchy {
 22   
 
 23   
     // Map of components to ignore
 24   
     private Map filtered = new WeakHashMap();
 25   
     // Map of components implicitly filtered; these will be implicitly
 26   
     // un-filtered if they are re-shown.
 27   
     private Map transientFiltered = new WeakHashMap();
 28   
 
 29   
     private static boolean trackAppletConsole =
 30   
         Boolean.getBoolean("abbot.applet.track_console");
 31   
     /** Avoid GC of the weak reference. */
 32   
     private AWTEventListener listener;
 33   
 
 34   
     /** Create a new TestHierarchy which does not contain any UI
 35   
      * Components which might already exist.
 36   
      */ 
 37  571
     public TestHierarchy() {
 38  571
         this(true);
 39   
     }
 40   
 
 41   
     /** Create a new TestHierarchy, indicating whether extant Components
 42   
      * should be omitted from the Hierarchy.  
 43   
      */
 44  571
     public TestHierarchy(boolean ignoreExisting) {
 45  571
         if (ignoreExisting)
 46  571
             ignoreExisting();
 47   
         // Watch for introduction of transient dialogs so we can automatically
 48   
         // filter them on dispose (WINDOW_CLOSED).  Don't do anything when the
 49   
         // component is simply hidden, since we can't tell whether it will be
 50   
         // re-used. 
 51  571
         listener = new TransientWindowListener();
 52   
     }
 53   
 
 54  73768
     public boolean contains(Component c) {
 55  73768
         return super.contains(c) && !isFiltered(c);
 56   
     }
 57   
 
 58   
     /** Dispose of the given Window, but only if it currently exists within
 59   
      * the hierarchy.  It will no longer appear in this Hierarchy or be
 60   
      * reachable in a hierarchy walk. 
 61   
      */
 62  632
     public void dispose(Window w) {
 63  632
         if (contains(w)) {
 64  591
             super.dispose(w);
 65  591
             setFiltered(w, true);
 66   
         }
 67   
     }
 68   
 
 69   
     /** Make all currently extant components invisible to this Hierarchy,
 70   
      * without affecting their current state.
 71   
      */
 72  571
     public void ignoreExisting() {
 73  571
         Iterator iter = getRoots().iterator();
 74  571
         while (iter.hasNext()) {
 75  2197
             setFiltered((Component)iter.next(), true);
 76   
         }
 77   
     }
 78   
 
 79   
     /** Returns all available root Windows, excluding those which have been
 80   
      * filtered.
 81   
      */
 82  4064
     public Collection getRoots() {
 83  4064
         Collection s = super.getRoots();
 84  4064
         s.removeAll(filtered.keySet());
 85  4064
         return s;
 86   
     }
 87   
 
 88   
     /** Returns all sub-components of the given Component, omitting those
 89   
      * which are currently filtered.
 90   
      */
 91  45747
     public Collection getComponents(Component c) {
 92  45747
         if (!isFiltered(c)) {
 93  45747
             Collection s = super.getComponents(c);
 94   
             // NOTE: this only removes those components which are directly
 95   
             // filtered, not necessarily those which have a filtered ancestor.
 96  45747
             s.removeAll(filtered.keySet());
 97  45747
             return s;
 98   
         }
 99  0
         return EMPTY;
 100   
     }
 101   
 
 102  98100
     private boolean isWindowFiltered(Component c) {
 103  98100
         Window w = AWT.getWindow(c);
 104  98100
         return w != null && isFiltered(w);
 105   
     }
 106   
 
 107   
     /** Returns true if the given component will not be considered when
 108   
      * walking the hierarchy.  A Component is filtered if it has explicitly
 109   
      * been filtered via {@link #setFiltered(Component,boolean)}, or if
 110   
      * any <code>Window</code> ancestor has been filtered.
 111   
      */
 112  348285
     public boolean isFiltered(Component c) {
 113  348285
         if (c == null)
 114  121212
             return false;
 115  227073
         if ("sun.plugin.ConsoleWindow".equals(c.getClass().getName()))
 116  0
             return !trackAppletConsole;
 117  227073
         return filtered.containsKey(c)
 118   
             || ((c instanceof Window) && isFiltered(c.getParent()))
 119   
             || (!(c instanceof Window) && isWindowFiltered(c));
 120   
     }
 121   
 
 122   
     /** Indicates whether the given component is to be included in the
 123   
         Hierarchy.  If the component is a Window, recursively applies the
 124   
         action to all owned Windows. 
 125   
     */
 126  4398
     public void setFiltered(Component c, boolean filter) {
 127  4398
         if (AWT.isSharedInvisibleFrame(c)) {
 128  84
             Iterator iter = getComponents(c).iterator();
 129  84
             while (iter.hasNext()) {
 130  20
                 setFiltered((Component)iter.next(), filter);
 131   
             }
 132   
         }
 133   
         else {
 134  4314
             if (filter) {
 135  4308
                 filtered.put(c, Boolean.TRUE);
 136  4308
                 transientFiltered.remove(c);
 137   
             }
 138   
             else {
 139  6
                 filtered.remove(c);
 140   
             }
 141  4314
             if (c instanceof Window) {
 142  4314
                 Window[] owned = ((Window)c).getOwnedWindows();
 143  4314
                 for (int i=0;i < owned.length;i++) {
 144  777
                     setFiltered(owned[i], filter);
 145   
                 }
 146   
             }
 147   
         }
 148   
     }
 149   
 
 150   
     /** Provides for automatic filtering of auto-generated Swing dialogs. */
 151   
     private class TransientWindowListener implements AWTEventListener {
 152   
         private class DisposeAction implements Runnable {
 153   
             private Window w;
 154  803
             public DisposeAction(Window w) {
 155  803
                 this.w = w;
 156   
             }
 157  803
             public void run() {
 158  803
                 setFiltered(w, true);
 159  803
                 transientFiltered.put(w, Boolean.TRUE);
 160  803
                 Log.debug("window " + w.getName() + " filtered");
 161   
             }
 162   
         }
 163   
 
 164  571
         public TransientWindowListener() {
 165   
             // Add a weak listener so we don't leave a listener lingering
 166   
             // about. 
 167  571
             long mask = WindowEvent.WINDOW_EVENT_MASK
 168   
                 | ComponentEvent.COMPONENT_EVENT_MASK;
 169  571
             new WeakAWTEventListener(this, mask);
 170   
         }
 171   
 
 172  45388
         public void eventDispatched(AWTEvent e) {
 173  45388
             if (e.getID() == WindowEvent.WINDOW_OPENED
 174   
                 || (e.getID() == ComponentEvent.COMPONENT_SHOWN
 175   
                     && e.getSource() instanceof Window)) {
 176  2268
                 Window w = (Window)e.getSource();
 177  2268
                 if (transientFiltered.containsKey(w)) {
 178  5
                     setFiltered(w, false);
 179   
                 }
 180   
                 // Catch new sub-windows of filtered windows (i.e. dialogs
 181   
                 // generated by a test harness UI).
 182  2263
                 else if (isFiltered(w.getParent())) {
 183  3
                     setFiltered(w, true);
 184   
                 }
 185   
             }
 186  43120
             else if (e.getID() == WindowEvent.WINDOW_CLOSED) {
 187  1364
                 final Window w = (Window)e.getSource();
 188   
                 // *Any* window disposal should result in the window being
 189   
                 // ignored, at least until it is again displayed.
 190  1364
                 if (!isFiltered(w)) {
 191   
                     // Filter only *after* any handlers for this event have
 192   
                     // finished.  
 193  803
                     Log.debug("queueing dispose of " + w.getName());
 194  803
                     SwingUtilities.invokeLater(new DisposeAction(w));
 195   
                 }
 196   
             }
 197   
         }
 198   
     }
 199   
 }
 200