Clover coverage report - clover
Coverage timestamp: Sat Oct 8 2005 22:54:17 EDT
file stats: LOC: 258   Methods: 11
NCLOC: 191   Classes: 1
 
 Source file Conditionals Statements Methods TOTAL
ComponentPropertyModel.java 75% 80.6% 72.7% 78.3%
coverage coverage
 1   
 package abbot.editor;
 2   
 
 3   
 import java.awt.*;
 4   
 import java.lang.reflect.*;
 5   
 import java.util.*;
 6   
 
 7   
 import javax.swing.JComponent;
 8   
 import javax.swing.table.DefaultTableModel;
 9   
 
 10   
 import abbot.Log;
 11   
 import abbot.i18n.Strings;
 12   
 import abbot.script.PropertyCall;
 13   
 import abbot.tester.ComponentTester;
 14   
 
 15   
 class ComponentPropertyModel extends DefaultTableModel {
 16   
         
 17   
     public static final int PROPERTY_NAME = 0;
 18   
     public static final int PROPERTY_VALUE = 1;
 19   
     public static final int METHOD_OBJECT = 3;
 20   
 
 21   
     private static Set filteredMethods = new HashSet();
 22   
 
 23   
     static {
 24   
         // Indicate things that aren't particularly interesting
 25  3
         filteredMethods.addAll(Arrays.asList(new String[] {
 26   
             // Component
 27   
             "getAccessibleContext",
 28   
             "getAlignmentX",
 29   
             "getAlignmentY",
 30   
             "getColorModel",
 31   
             "getComponentListeners",
 32   
             "getComponentOrientation",
 33   
             "getDropTarget",
 34   
             "getFocusListeners",
 35   
             "getGraphics",
 36   
             "getGraphicsConfiguration",
 37   
             "getHierarchyBoundsListeners",
 38   
             "getHierarchyListeners",
 39   
             "getInputContext",
 40   
             "getInputMethodListeners",
 41   
             "getInputMethodRequests",
 42   
             "getKeyListeners",
 43   
             "getMouseListeners",
 44   
             "getMouseMotionListeners",
 45   
             "getMouseWheelListeners",
 46   
             "getParent",
 47   
             "getPeer",
 48   
             "getToolkit",
 49   
             "getTreeLock",
 50   
             // Container
 51   
             "getComponents",
 52   
             "getContainerListeners",
 53   
             // JComponent
 54   
             "getActionMap",
 55   
             "getAncestorListeners",
 56   
             "getAutoscrolls",
 57   
             "getBufferStrategy",
 58   
             "getDebugGraphicsOptions",
 59   
             "getInputMap",
 60   
             "getInputVerifier",
 61   
             "getPropertyChangeListeners",
 62   
             "getRegisteredKeyStrokes",
 63   
             "getRootPane",
 64   
             "getTopLevelAncestor",
 65   
             "getUIClassID",
 66   
             "getVerifyInputWhenFocusTarget",
 67   
             "getVetoableChangeListeners",
 68   
             "getVisibleRect",
 69   
             "isFocusCycleRoot",
 70   
             "isOpaque",
 71   
             "isOptimizedDrawingEnabled",
 72   
             "isPaintingTile",
 73   
             "isPreferredSizeSet",
 74   
             "isRequestFocusEnabled",
 75   
             "isValidateRoot",
 76   
             // Window
 77   
             "getOwnedWindows",
 78   
             "getWindowFocusListeners",
 79   
             "getWindowListeners",
 80   
             "getWindowStateListeners",
 81   
             // Frame
 82   
             "getFrames",
 83   
         }));
 84   
     }
 85   
 
 86   
     /** Install the given filtered property method properties.  Add-on
 87   
         ComponentTester classes should invoke this for the list of property
 88   
         methods they want to appear in the filtered property list. */
 89  0
     public static void setFilteredPropertyMethods(String[] methods) {
 90  0
         filteredMethods.addAll(Arrays.asList(methods));
 91   
     }
 92   
 
 93   
     /** Create a model with two columns, the property name and the property
 94   
      * value.
 95   
      */
 96  5
     public ComponentPropertyModel() {
 97  5
         super(new Object[]{ Strings.get("Name"),
 98   
                             Strings.get("Value") }, 0);
 99   
     }
 100   
 
 101  7
     public void clear() {
 102   
         // The setNumRows() method is required to be compatible with JDK
 103   
         // 1.2.2 and should be replaced with setRowCount() for 1.3 and above.
 104   
         //propTableModel.setNumRows(0); 
 105  7
         setRowCount(0);
 106   
     }
 107   
 
 108  0
     public void setComponent(Component comp) {
 109  0
         setComponent(comp, true);
 110   
     }
 111   
     
 112   
     /** The current list of property methods and values corresponds to this
 113   
      * component.
 114   
      */
 115   
     private Component currentComponent = null;
 116   
     /** Whether the current list is filtered. */
 117   
     private boolean filtered = false;
 118   
 
 119   
     /** Update the list of property methods based on the newly selected
 120   
         component.
 121   
     */
 122  7
     public void setComponent(Component comp,
 123   
                                           boolean filter) {
 124  7
         Class cls = comp != null ? comp.getClass() : null;
 125  7
         if (currentComponent == comp
 126   
             && filter == filtered)
 127  0
             return;
 128   
 
 129  7
         clear();
 130  7
         currentComponent = comp;
 131  7
         filtered = filter;
 132  7
         Method[] all = getPropertyMethods(cls, filter);
 133  7
         Arrays.sort(all, new Comparator() {
 134  603
             public int compare(Object o1, Object o2) {
 135  603
                 String n1 = getPropertyName(((Method)o1).getName());
 136  603
                 String n2 = getPropertyName(((Method)o2).getName());
 137  603
                 return n1.compareTo(n2);
 138   
             }
 139   
         });
 140  7
         Object[] noArgs = new Object[0];
 141  7
         Object[] oneArg = new Object[] { comp };
 142  7
         for (int i=0;i < all.length;i++) {
 143  121
             Method method = all[i];
 144  121
             Object value = "";
 145  121
             try {
 146  121
                 Object target = comp;
 147  121
                 Object[] args = noArgs;
 148  121
                 if (ComponentTester.class.
 149   
                     isAssignableFrom(method.getDeclaringClass())) {
 150  0
                     target = ComponentTester.getTester(comp);
 151  0
                     args = oneArg;
 152   
                 }
 153  121
                 value = method.invoke(target, args);
 154   
             }
 155   
             catch(IllegalArgumentException e) {
 156  0
                 value = "<illegal argument>";
 157  0
                 Log.debug(e);
 158   
             }
 159   
             catch(InvocationTargetException e) {
 160  1
                 value = "<target exception>";
 161  1
                 Log.debug(e);
 162   
             }
 163   
             catch(IllegalAccessException e) {
 164   
                 // method was somehow protected?
 165  0
                 value = "<not accessible>";
 166  0
                 Log.debug(e);
 167   
             }
 168  121
             addRow(new Object[] { method, value });
 169   
         }
 170  7
         fireTableDataChanged();
 171   
     }
 172   
     
 173  8
     Method[] getPropertyMethods(Class cls, boolean filter) {
 174  8
         if (cls == null) 
 175  5
             return new Method[0];
 176   
 
 177   
         // Make sure we only get one of each named method 
 178  3
         HashMap processed = new HashMap();
 179  3
         Method[] methods = cls.getMethods();
 180  3
         for(int i = 0; i < methods.length; i++) {
 181  858
             if (isGetterMethod(methods[i], false)
 182   
                 && !processed.containsKey(methods[i].getName())) {
 183  274
                 if (filter
 184   
                     && filteredMethods.contains(methods[i].getName())) {
 185  92
                     continue;
 186   
                 }
 187  182
                 processed.put(methods[i].getName(), methods[i]);
 188   
             }
 189   
         }
 190   
         // Now look up propert accessors provided by the corresponding
 191   
         // ComponentTester class.
 192  3
         ComponentTester tester = ComponentTester.getTester(cls);
 193  3
         methods = tester.getPropertyMethods();
 194  3
         for (int i=0;i < methods.length;i++) {
 195  0
             if (!processed.containsKey(methods[i].getName())) {
 196   
                 // Properties provided by the ComponentTester are never
 197   
                 // filtered. 
 198  0
                 processed.put(methods[i].getName(), methods[i]);
 199   
             }
 200   
         }
 201   
         
 202  3
         return (Method[])processed.values().toArray(new Method[processed.size()]);
 203   
     }
 204   
     
 205   
     /**
 206   
      * Method to check if the method specified on the class
 207   
      * is a "getter" for an attribute of that class
 208   
      *
 209   
      * @param method The method to be tested
 210   
      * @return true if the method is a "getter"
 211   
      */
 212  858
     private boolean isGetterMethod(Method method, boolean isTester) {
 213  858
         Class[] types = method.getParameterTypes();
 214  858
         int argc = types.length;
 215  858
         return ((isTester && argc == 1
 216   
                  && Component.class.isAssignableFrom(types[0]))
 217   
                 || (!isTester && argc == 0))
 218   
             && PropertyCall.isPropertyMethod(method);
 219   
     }
 220   
 
 221   
     /**
 222   
      * Method to "extract" the property name from the method name
 223   
      * following the convention specified for a bean
 224   
      *
 225   
      * @param methodName The name of the method
 226   
      * @return The name of the attribute
 227   
      */
 228  1334
     private String getPropertyName(String methodName) {
 229  1334
         String propName = methodName;
 230  1334
         if (methodName.startsWith("get")
 231   
             || methodName.startsWith("has")) {
 232  912
             propName = methodName.substring(3);
 233   
         }
 234  422
         else if(methodName.startsWith("is")) {
 235  422
             propName = methodName.substring(2);
 236   
         }
 237  1334
         return propName.substring(0, 1).toLowerCase() + propName.substring(1);
 238   
     }
 239   
 
 240  0
     public boolean isCellEditable(int row, int col) {
 241  0
         return false;
 242   
     }
 243   
 
 244   
     /** Display the property name column apropriately. */
 245  135
     public Object getValueAt(int row, int col) {
 246   
         // The Method object is in column zero, we want only the property part
 247   
         // to appear. 
 248  135
         if (col == PROPERTY_NAME) {
 249  128
             Method m = (Method)super.getValueAt(row, col);
 250  128
             return getPropertyName(m.getName());
 251   
         }
 252  7
         if (col == METHOD_OBJECT) {
 253  0
             return (Method)super.getValueAt(row, 0);
 254   
         }
 255  7
         return super.getValueAt(row, col);
 256   
     }
 257   
 }
 258