Coverage Report - us.daveread.utility.formatcheck.format.DataType
 
Classes in this File Line Coverage Branch Coverage Complexity
DataType
83%
55/66
85%
11/13
1.944
 
 1  
 package us.daveread.utility.formatcheck.format;
 2  
 
 3  
 import java.util.*;
 4  
 
 5  
 /**
 6  
  * <p>Title: DataType
 7  
  * <p>Description: Represents the data type of a field.  The class is
 8  
  *     abstract.  Each data type will subclass this class and add an isValid() method
 9  
  *     which will validate the input data aginst the rules for its specific type of
 10  
  *     data.
 11  
  * <p>Copyright: Copyright (c) 2005
 12  
  * <p>This program is free software; you can redistribute it and/or modify
 13  
  * it under the terms of the GNU General Public License as published by
 14  
  * the Free Software Foundation; either version 2 of the License, or
 15  
  * (at your option) any later version.
 16  
  * <p>This program is distributed in the hope that it will be useful,
 17  
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
 18  
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 19  
  * GNU General Public License for more details.
 20  
  * <p>You should have received a copy of the GNU General Public License
 21  
  * along with this program; if not, write to the Free Software
 22  
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 23  
  * </p>
 24  
  *
 25  
  * @author David Read
 26  
  * @version $Id: DataType.java,v 1.1.1.1 2006/05/22 02:14:09 daveread Exp $
 27  
  */
 28  
 public abstract class DataType {
 29  
   /** The display name for this data type */
 30  88
   private String typeName = "UNASSIGNED TYPE NAME";
 31  
 
 32  
   /** The format pattern for the data type, required for some data types */
 33  
   private String formatDefinition;
 34  
 
 35  
   /** The display description of the data type, optional */
 36  
   private String description;
 37  
 
 38  
   /** The minimum value allowed in the field, optional */
 39  
   private double minimum;
 40  
 
 41  
   /** Whether the minimum value was set */
 42  
   private boolean minimumSet;
 43  
 
 44  
   /** The maximum value allowed in the field, optional */
 45  
   private double maximum;
 46  
 
 47  
   /** Whether the maximum value was set */
 48  
   private boolean maximumSet;
 49  
 
 50  
   /** The set of accepted values the field may contain, optional */
 51  
   private AcceptedValue acceptedValues[];
 52  
 
 53  
   /**
 54  
    * Expects the format definition and description for the data type.  These
 55  
    * are both optional, though the format definition is required by some
 56  
    * concrete data type implementations.
 57  
    *
 58  
    * @param aFormatDefinition String The format definition appropriate to the
 59  
    *   data type.
 60  
    * @param aDescription String The display description of the data type.
 61  
    */
 62  88
   public DataType(String aFormatDefinition, String aDescription) {
 63  88
     setFormatDefinition(aFormatDefinition);
 64  88
     setDescription(aDescription);
 65  88
     acceptedValues = new AcceptedValue[0];
 66  
 
 67  
     // Assign somewhat useful value if subclass fails to call setName()
 68  88
     setTypeName(this.getClass().getName());
 69  88
   }
 70  
 
 71  
   /**
 72  
    * Checks the content of the field against its allowed values.
 73  
    * Uses the isValid method, overridden in subclasses, to determine
 74  
    * that data is valid.
 75  
    *
 76  
    * @param fieldValue String containing value in the input record
 77  
    * @return String Null if the data is fine, otherwise an error message
 78  
    */
 79  
   public String validate(String fieldValue) {
 80  
     String message;
 81  
 
 82  52
     message = null;
 83  
 
 84  52
     if (getNumAcceptedValues() > 0) {
 85  13
       if (!isAcceptedValue(fieldValue)) {
 86  6
         message = "is not in accepted value list (";
 87  12
         for (int value = 0; value < getNumAcceptedValues(); ++value) {
 88  6
           if (value > 0) {
 89  0
             message += ", ";
 90  
           }
 91  6
           message += getAcceptedValue(value).getValue();
 92  
         }
 93  6
         message += ")";
 94  
       }
 95  
     }
 96  
 
 97  52
     if (message == null && minimumSet) {
 98  
       try {
 99  0
         if (Double.parseDouble(fieldValue) < minimum) {
 100  0
           throw new IllegalArgumentException("Value below minimum");
 101  
         }
 102  
       }
 103  0
       catch (Throwable any) {
 104  0
         message = "is below the minimum value of " + minimum;
 105  0
       }
 106  
     }
 107  
 
 108  52
     if (message == null && maximumSet) {
 109  
       try {
 110  0
         if (Double.parseDouble(fieldValue) > maximum) {
 111  0
           throw new IllegalArgumentException("Value above maximum");
 112  
         }
 113  
       }
 114  0
       catch (Throwable any) {
 115  0
         message = "is above the maximum value of " + maximum;
 116  0
       }
 117  
     }
 118  
 
 119  52
     if (message == null && !isValid(fieldValue)) {
 120  12
       message = "is not a " + getDescription();
 121  
     }
 122  
 
 123  52
     return message;
 124  
   }
 125  
 
 126  
   /**
 127  
    * Checks the value against the list of accepted values.
 128  
    *
 129  
    * @param fieldValue String containing value in the input record
 130  
    * @return boolean Whether the value was found in the list of accepted values
 131  
    */
 132  
   private boolean isAcceptedValue(String fieldValue) {
 133  
     boolean okay;
 134  
 
 135  13
     fieldValue = fieldValue.trim();
 136  
 
 137  13
     okay = false;
 138  19
     for (int value = 0; value < getNumAcceptedValues(); ++value) {
 139  13
       if (fieldValue.equals(getAcceptedValue(value).getValue())) {
 140  7
         okay = true;
 141  7
         break;
 142  
       }
 143  
     }
 144  
 
 145  13
     return okay;
 146  
   }
 147  
 
 148  
   /**
 149  
    * Checks the content of the field against its allowed values.  This
 150  
    * method is specific to the actual data type and is therefore
 151  
    * abstract in this class.  Each data type must subclass this class and
 152  
    * implement this method.
 153  
    *
 154  
    * The subclass must also call the setTypeName method to assign a display
 155  
    * name for the data type.
 156  
    *
 157  
    * @param fieldValue String containing value in the input record
 158  
    * @return boolean If the data is fine return true, otherwise false
 159  
    */
 160  
   public abstract boolean isValid(String fieldValue);
 161  
 
 162  
   /**
 163  
    * Set the display name for the data type.  Each subclass should call
 164  
    * this in its constructor.
 165  
    *
 166  
    * @param aTypeName String The display name for the data type instance.
 167  
    */
 168  
   protected void setTypeName(String aTypeName) {
 169  176
     typeName = aTypeName;
 170  176
   }
 171  
 
 172  
   /**
 173  
    * Gets the type name assigned to this data type.
 174  
    *
 175  
    * @return String The data type display name.
 176  
    */
 177  
   public String getTypeName() {
 178  13
     return typeName;
 179  
   }
 180  
 
 181  
   /**
 182  
    * Sets the format definition for this instance of a data type.  For instance
 183  
    * a date data type may allow the definition to control the format of the
 184  
    * date string, and would therefore pass that date format string into this method.
 185  
    *
 186  
    * @param aFormatDefinition String The format string for the data type.
 187  
    */
 188  
   private void setFormatDefinition(String aFormatDefinition) {
 189  88
     formatDefinition = aFormatDefinition;
 190  88
   }
 191  
 
 192  
   /**
 193  
    * Gets the format definition for this data type.  It may be null.
 194  
    *
 195  
    * @return String The format type, or null if none was supplied.
 196  
    */
 197  
   public String getFormatDefinition() {
 198  41
     return formatDefinition;
 199  
   }
 200  
 
 201  
   /**
 202  
    * Sets the display description for this data type.
 203  
    *
 204  
    * @param aDescription String The display description for this data type.
 205  
    */
 206  
   private void setDescription(String aDescription) {
 207  88
     description = aDescription;
 208  88
   }
 209  
 
 210  
   /**
 211  
    * Gets the display description for the data type.  If none was provided,
 212  
    * the returned value will be the combination of the type name and
 213  
    * format definition.
 214  
    *
 215  
    * @return String The display description for this data type.
 216  
    */
 217  
   public String getDescription() {
 218  19
     if (description == null) {
 219  4
       description = getTypeName();
 220  4
       if (getFormatDefinition() != null) {
 221  4
         description += " (" + getFormatDefinition() + ")";
 222  
       }
 223  
     }
 224  
 
 225  19
     return description;
 226  
   }
 227  
 
 228  
   /**
 229  
    * Set the maximum value allowed in the field for this data type.
 230  
    *
 231  
    * @param aMaximum double The maximum value allowed.
 232  
    */
 233  
   public void setMaximum(double aMaximum) {
 234  1
     maximum = aMaximum;
 235  1
     maximumSet = true;
 236  1
   }
 237  
 
 238  
   /**
 239  
    * Get the maximum value allowed in the field for this data type.
 240  
    *
 241  
    * @return double The maximum value allowed.
 242  
    */
 243  
   public double getMaximum() {
 244  1
     return maximum;
 245  
   }
 246  
 
 247  
   /**
 248  
    * Set the minimum value allowed in the field for this data type.
 249  
    *
 250  
    * @param aMinimum double The minimum value allowed.
 251  
    */
 252  
   public void setMinimum(double aMinimum) {
 253  1
     minimum = aMinimum;
 254  1
     minimumSet = true;
 255  1
   }
 256  
 
 257  
   /**
 258  
    * Get the minimum value allowed in the field for this data type.
 259  
    *
 260  
    * @return double The minimum value allowed.
 261  
    */
 262  
   public double getMinimum() {
 263  1
     return minimum;
 264  
   }
 265  
 
 266  
   /**
 267  
    * Add a value that will be allowed in the field.  Any arbitrary number of values
 268  
    * may be added.  If no accepted values are added, all values will be
 269  
    * allowed, and passed onto the subclass for verification.
 270  
    *
 271  
    * @param aAcceptedValue AcceptedValue An accepted value for the field.
 272  
    */
 273  
   public void addAcceptedValue(AcceptedValue aAcceptedValue) {
 274  25
     List tempAcceptedValues = new ArrayList(Arrays.asList(acceptedValues));
 275  25
     tempAcceptedValues.add(aAcceptedValue);
 276  25
     acceptedValues = (AcceptedValue[]) tempAcceptedValues.toArray(new
 277  
         AcceptedValue[tempAcceptedValues.size()]);
 278  25
   }
 279  
 
 280  
   /**
 281  
    * Get the number of accepted values associated with this data type.
 282  
    *
 283  
    * @return int The number of accepted values for this data type.
 284  
    */
 285  
   public int getNumAcceptedValues() {
 286  84
     return acceptedValues.length;
 287  
   }
 288  
 
 289  
   /**
 290  
    * Get one accepted value, located at the requested index.  The index
 291  
    * must be >= 0 and < the number of accepted values.
 292  
    *
 293  
    * @param aIndex int The index whose accepted value is to be obtained.
 294  
    * @return AcceptedValue The accepted value found at the requested index.
 295  
    */
 296  
   public AcceptedValue getAcceptedValue(int aIndex) {
 297  20
     return acceptedValues[aIndex];
 298  
   }
 299  
 
 300  
   /**
 301  
    * Convenience to report display description as default string value.
 302  
    *
 303  
    * @return String The display description for the data type.
 304  
    */
 305  
   public String toString() {
 306  2
     return getDescription();
 307  
   }
 308  
 }