Clover coverage report - clover
Coverage timestamp: Sat Oct 8 2005 22:54:17 EDT
file stats: LOC: 175   Methods: 14
NCLOC: 87   Classes: 1
 
 Source file Conditionals Statements Methods TOTAL
ComponentLocation.java 64.3% 79.4% 92.9% 79%
coverage coverage
 1   
 package abbot.tester;
 2   
 
 3   
 import java.awt.*;
 4   
 import java.util.StringTokenizer;
 5   
 
 6   
 import abbot.i18n.Strings;
 7   
 
 8   
 /** Provides encapsulation of a visible Component-relative location.    
 9   
  * "Visible" in this context means currently accessible by the pointer 
 10   
  * (possibly via scrolling).  A hidden node in a collapsed tree path 
 11   
  * would <strong>not</strong> be considered visible.
 12   
  * <p>
 13   
  * This class the specifics of location so that {@link ComponentTester} 
 14   
  * primitives
 15   
  * ({@link ComponentTester#actionClick(Component,ComponentLocation)},
 16   
  * {@link ComponentTester#actionShowPopupMenu(Component,ComponentLocation)},
 17   
  * etc) may be directed to specific elements of  
 18   
  * substructure on a <code>Component</code> (list rows, tree paths, table
 19   
  * cells, substructure values, etc.).
 20   
  * <p>
 21   
  * Classes derived from <code>ComponentLocation</code> should provide
 22   
  * constructors for each type of location indication, e.g. value, index, and
 23   
  * {@link Point}.  The {@link #toString()} method should provide an encoded
 24   
  * {@link String} suitable for use by the {@link #parse(String)} method, which
 25   
  * must convert the {@link String} encoding back into a proper
 26   
  * <code>ComponentLocation</code>. 
 27   
  * <p>
 28   
  * By convention, {@link Point} locations are specified with (x,y) notation.
 29   
  * Indexed locations should use square brackets, e.g. [i] or [r,c] and
 30   
  * value locations should use a quoted {@link String}, e.g.
 31   
  * '"cuckoo for cocoa puffs"'.  The specific syntax allowed will vary by
 32   
  * specific <code>ComponentLocation</code> type.  The base
 33   
  * <code>ComponentLocation</code> implementation
 34   
  * supports only the explicit (x,y) notation.
 35   
  * <p>
 36   
  * Recorders
 37   
  * should use the {@link String} value by default for consistency.  The
 38   
  * special value {@link #CENTER} is provided to indicate the center of a
 39   
  * {@link Component}.
 40   
  * <p>
 41   
  * The method {@link #badFormat(String)} should provide usage-like information
 42   
  * indicating the acceptable forms of input for this class.
 43   
  *
 44   
  * @see JListLocation
 45   
  * @see JTreeLocation
 46   
  * @see JTableLocation
 47   
  */
 48   
 public class ComponentLocation {
 49   
 
 50   
     /** Special <code>ComponentLocation</code> encoding which represents
 51   
         the center of the component.
 52   
     */
 53   
     public static final String CENTER = "(center)";
 54   
 
 55   
     private Point where = null;
 56   
 
 57   
     /** Create a simple location which represents the center of a component. */
 58  350
     public ComponentLocation() { }
 59   
 
 60   
     /** Create a simple location. */
 61  113
     public ComponentLocation(Point where) {
 62  113
         this.where = new Point(where);
 63   
     }
 64   
 
 65   
     /** Convert the abstract location into a concrete one.  Returns
 66   
      * a {@link Point} relative to the given {@link Component}.
 67   
      */
 68  161
     public Point getPoint(Component c)
 69   
         throws LocationUnavailableException {
 70  161
         return where != null 
 71   
             ? new Point(where) : new Point(c.getWidth()/2, c.getHeight()/2);
 72   
     }
 73   
 
 74   
     /** Convert the abstract location into a concrete area, relative
 75   
      * to the given <code>Component</code>.  If a point has
 76   
      * been specified, returns a 1x1 rectangle, otherwise returns the
 77   
      * a rectangle at (0, 0) of the Component's size.
 78   
      */
 79  117
     public Rectangle getBounds(Component c)
 80   
         throws LocationUnavailableException {
 81  117
         if (where == null)
 82  53
             return new Rectangle(0, 0, c.getWidth(), c.getHeight());
 83  64
         return new Rectangle(where.x, where.y, 1, 1);
 84   
     }
 85   
 
 86   
     /** Returns whether the given object is an equivalent 
 87   
      * <code>ComponentLocation</code>.
 88   
      */
 89  9
     public boolean equals(Object o) {
 90  9
         if (o instanceof ComponentLocation) {
 91  9
             ComponentLocation loc = (ComponentLocation)o;
 92  9
             return (where == null && loc.where == null)
 93   
                 || (where != null && where.equals(loc.where));
 94   
         }
 95  0
         return false;
 96   
     }
 97   
 
 98  13
     public String toString() {
 99  13
         if (where != null)
 100  13
             return "(" + where.x + "," + where.y + ")";
 101  0
         return CENTER;
 102   
     }
 103   
 
 104  0
     protected String badFormat(String encoded) {
 105  0
         return Strings.get("location.component.bad_format",
 106   
                            new Object[] { encoded });
 107   
     }
 108   
 
 109  4
     protected String encodeIndex(int index) {
 110  4
         return "[" + index + "]";
 111   
     }
 112   
 
 113   
     /** Returns whether the given (trimmed) <code>String</code> is an encoded
 114   
         index.
 115   
     */
 116  19
     protected boolean isIndex(String encoded) {
 117  19
         return encoded.startsWith("[") && encoded.endsWith("]");
 118   
     }
 119   
 
 120   
     /** Extract the encoded index. */
 121  11
     protected int parseIndex(String encoded) {
 122  11
         try {
 123  11
             return Integer.parseInt(encoded.
 124   
                                     substring(1, encoded.length()-1).trim());
 125   
         }
 126   
         catch(NumberFormatException e) {
 127  0
             throw new IllegalArgumentException(badFormat(encoded));
 128   
         }
 129   
     }
 130   
 
 131  44
     protected String encodeValue(String value) {
 132  44
         return "\"" + value + "\"";
 133   
     }
 134   
 
 135   
     /** Returns whether the given (trimmed) <code>String</code> is an encoded
 136   
         value.
 137   
     */
 138  23
     protected boolean isValue(String encoded) {
 139  23
         return encoded.startsWith("\"") && encoded.endsWith("\"");
 140   
     }
 141   
 
 142   
     /** Extract the encoded value. */
 143  7
     protected String parseValue(String encoded) {
 144  7
         return encoded.substring(1, encoded.length()-1);
 145   
     }
 146   
 
 147   
     /** Convert the given encoding into the proper location.
 148   
         Allowed formats: (x, y)
 149   
         <p>
 150   
      */
 151  9
     public ComponentLocation parse(String encoded) {
 152  9
         encoded = encoded.trim();
 153  9
         if (encoded.equals(CENTER)) {
 154  0
             where = null;
 155  0
             return this;
 156   
         }
 157  9
         if (encoded.startsWith("(") && encoded.endsWith(")")) {
 158  9
             StringTokenizer st =
 159   
                 new StringTokenizer(encoded.substring(1, encoded.length()-1),
 160   
                                     ",");
 161  9
             if (st.countTokens() == 2) {
 162  9
                 try {
 163  9
                     int x = Integer.parseInt(st.nextToken().trim());
 164  9
                     int y = Integer.parseInt(st.nextToken().trim());
 165  9
                     where = new Point(x, y);
 166  9
                     return this;
 167   
                 }
 168   
                 catch(NumberFormatException nfe) {
 169   
                 }
 170   
             }
 171   
         }
 172  0
         throw new IllegalArgumentException(badFormat(encoded));
 173   
     }
 174   
 }
 175