Clover coverage report - JGAP 3.1
Coverage timestamp: Mo Dez 11 2006 21:16:18 CET
file stats: LOC: 387   Methods: 18
NCLOC: 140   Classes: 1
 
 Source file Conditionals Statements Methods TOTAL
BaseGene.java 95% 96,2% 100% 96,7%
coverage coverage
 1    /*
 2    * This file is part of JGAP.
 3    *
 4    * JGAP offers a dual license model containing the LGPL as well as the MPL.
 5    *
 6    * For licencing information please see the file license.txt included with JGAP
 7    * or have a look at the top of class org.jgap.Chromosome which representatively
 8    * includes the JGAP license policy applicable for any file delivered with JGAP.
 9    */
 10    package org.jgap;
 11   
 12    /**
 13    * Abstract base class for all genes. Provides default implementations.
 14    *
 15    * @author Klaus Meffert
 16    * @since 2.2
 17    */
 18    public abstract class BaseGene
 19    implements Gene {
 20    /** String containing the CVS revision. Read out via reflection!*/
 21    private final static String CVS_REVISION = "$Revision: 1.22 $";
 22   
 23    /**
 24    * Delta, useful for comparing doubles and floats.
 25    */
 26    public static final double DELTA = 0.0000001;
 27   
 28    /** Energy of a gene, see RFE 1102206*/
 29    private double m_energy;
 30   
 31    /**
 32    * Application-specific data that is attached to the Gene. This data may
 33    * assist the application in labelling this Gene.
 34    * JGAP ignores the data, aside from allowing it to be set and
 35    * retrieved and considering it in clone() and compareTo().
 36    *
 37    * @since 2.4
 38    */
 39    private Object m_applicationData;
 40   
 41    /**
 42    * Method compareTo(): Should we also consider the application data when
 43    * comparing? Default is "false" as "true" means a Gene's losing its
 44    * identity when application data is set differently!
 45    *
 46    * @since 2.4
 47    */
 48    private boolean m_compareAppData;
 49   
 50    private
 51    /*transient*/ Configuration m_configuration;
 52   
 53    /**
 54    * Constants for toString()
 55    */
 56    public final static String S_APPLICATION_DATA = "Application data";
 57   
 58    /**
 59    *
 60    * @param a_configuration the configuration to use
 61    * @throws InvalidConfigurationException
 62    *
 63    * @author Klaus Meffert
 64    * @since 3.0
 65    */
 66  126475 public BaseGene(Configuration a_configuration)
 67    throws InvalidConfigurationException {
 68  126475 if (a_configuration == null) {
 69  1 throw new InvalidConfigurationException("Configuration must not be null!");
 70    }
 71  126474 m_configuration = a_configuration;
 72    }
 73   
 74    /**
 75    * Retrieves the allele value represented by this Gene.
 76    *
 77    * @return the allele value of this Gene
 78    * @since 1.0
 79    */
 80  379722 public Object getAllele() {
 81  379722 return getInternalValue();
 82    }
 83   
 84    /**
 85    * Retrieves the hash code value for a Gene.
 86    * Override if another hashCode() implementation is necessary or more
 87    * appropriate than this default implementation.
 88    *
 89    * @return this Gene's hash code
 90    *
 91    * @author Neil Rotstan
 92    * @author Klaus Meffert
 93    * @since 1.0
 94    */
 95  9844 public int hashCode() {
 96    // If our internal value is null, then return zero. Otherwise,
 97    // just return the hash code of the allele Object.
 98    // -----------------------------------------------------------
 99  9844 if (getInternalValue() == null) {
 100  9709 return -79;
 101    }
 102    else {
 103  135 return getInternalValue().hashCode();
 104    }
 105    }
 106   
 107    /**
 108    * Executed by the genetic engine when this Gene instance is no
 109    * longer needed and should perform any necessary resource cleanup.
 110    * If you need a special cleanup, override this method.
 111    *
 112    * @author Klaus Meffert
 113    * @since 1.0
 114    */
 115  18 public void cleanup() {
 116    // No specific cleanup is necessary by default.
 117    // --------------------------------------------
 118    }
 119   
 120    /**
 121    * Retrieves a string representation of this Gene's value that
 122    * may be useful for display purposes.
 123    *
 124    * @return a string representation of this Gene's value
 125    *
 126    * @author Klaus Meffert
 127    * @since 1.0
 128    */
 129  8 public String toString() {
 130  8 String representation;
 131  8 if (getInternalValue() == null) {
 132  1 representation = "null";
 133    }
 134    else {
 135  7 representation = getInternalValue().toString();
 136    }
 137  8 String appData;
 138  8 if (getApplicationData() != null) {
 139  2 appData = getApplicationData().toString();
 140    }
 141    else {
 142  6 appData = "null";
 143    }
 144  8 representation += ", " + S_APPLICATION_DATA + ":" + appData;
 145  8 return representation;
 146    }
 147   
 148    /**
 149    * @return the size of the gene, i.e the number of atomic elements. Always 1
 150    * for non-composed Gene types. Override for composed Gene types
 151    *
 152    * @author Neil Rotstan
 153    * @since 1.0
 154    */
 155  259 public int size() {
 156  259 return 1;
 157    }
 158   
 159    /**
 160    * Compares this Gene with the given object and returns true if the other
 161    * object is a Gene of the same type and has the same value (allele) as
 162    * this Gene. Otherwise it returns false.
 163    *
 164    * @param a_other the object to compare to this Gene for equality
 165    * @return true if this Gene is equal to the given object, false otherwise
 166    *
 167    * @author Klaus Meffert
 168    * @since 1.1
 169    */
 170  130029 public boolean equals(final Object a_other) {
 171  130029 try {
 172  130029 int result = compareTo(a_other);
 173  129983 if (result == 0) {
 174  35844 if (isCompareApplicationData()) {
 175  7 Gene otherGene = (Gene) a_other;
 176  7 int resultAppData = compareApplicationData(getApplicationData(),
 177    otherGene.getApplicationData());
 178  7 return resultAppData == 0;
 179    }
 180    else {
 181  35837 return true;
 182    }
 183    }
 184    else {
 185  94139 return false;
 186    }
 187    } catch (ClassCastException e) {
 188    // If the other object isn't an Gene of current type
 189    // (like IntegerGene for IntegerGene's), then we're not equal.
 190    // -----------------------------------------------------------
 191  46 return false;
 192    }
 193    }
 194   
 195    /**
 196    * Each Gene implementation holds its own m_value object keeping the allele
 197    * value. In your Gene implementation, just return it with this method
 198    * (see {@link org.jgap.impl.BooleanGene} for example)
 199    * @return the m_value object
 200    *
 201    * @author Klaus Meffert
 202    * @since 2.2
 203    */
 204    protected abstract Object getInternalValue();
 205   
 206    /**
 207    * @return energy of the gene
 208    *
 209    * @author Klaus Meffert
 210    * @since 2.3
 211    */
 212  94443 public double getEnergy() {
 213  94443 return m_energy;
 214    }
 215   
 216    /**
 217    * Sets the energy of the gene
 218    * @param a_energy the energy to set
 219    *
 220    * @author Klaus Meffert
 221    * @since 2.3
 222    */
 223  94440 public void setEnergy(final double a_energy) {
 224  94440 m_energy = a_energy;
 225    }
 226   
 227    /**
 228    * This sets the application-specific data that is attached to this Gene.
 229    * Attaching application-specific data may be useful for
 230    * some applications when it comes time to distinguish a Gene from another.
 231    * JGAP ignores this data functionally.
 232    *
 233    * @param a_newData the new application-specific data to attach to this
 234    * Gene
 235    *
 236    * @author Klaus Meffert
 237    * @since 2.4
 238    */
 239  31 public void setApplicationData(final Object a_newData) {
 240  31 m_applicationData = a_newData;
 241    }
 242   
 243    /**
 244    * Retrieves the application-specific data that is attached to this Gene.
 245    * Attaching application-specific data may be useful for
 246    * some applications when it comes time to distinguish a Gene from another.
 247    * JGAP ignores this data functionally.
 248    *
 249    * @return the application-specific data previously attached to this Gene,
 250    * or null if there is no data attached
 251    *
 252    * @author Klaus Meffert
 253    * @since 2.4
 254    */
 255  105 public Object getApplicationData() {
 256  105 return m_applicationData;
 257    }
 258   
 259    /**
 260    * Should we also consider the application data when comparing? Default is
 261    * "false" as "true" means a Gene is losing its identity when
 262    * application data is set differently!
 263    *
 264    * @param a_doCompare true: consider application data in method compareTo
 265    *
 266    * @author Klaus Meffert
 267    * @since 2.4
 268    */
 269  29 public void setCompareApplicationData(final boolean a_doCompare) {
 270  29 m_compareAppData = a_doCompare;
 271    }
 272   
 273    /*
 274    * @return should we also consider the application data when comparing?
 275    *
 276    * @author Klaus Meffert
 277    * @since 2.4
 278    */
 279  862656 public boolean isCompareApplicationData() {
 280  862656 return m_compareAppData;
 281    }
 282   
 283  46 protected int compareApplicationData(final Object a_appdata1,
 284    final Object a_appdata2) {
 285    // Compare application data.
 286    // -------------------------
 287  46 if (a_appdata1 == null) {
 288  8 if (a_appdata2 != null) {
 289  6 return -1;
 290    }
 291    else {
 292  2 return 0;
 293    }
 294    }
 295  38 else if (a_appdata2 == null) {
 296  11 return 1;
 297    }
 298    else {
 299    // The above code is contained in the following, but for performance
 300    // issues we keep it here redundantly.
 301    // -----------------------------------------------------------------
 302  27 ICompareToHandler handler = getConfiguration().getJGAPFactory().
 303    getCompareToHandlerFor(a_appdata1, a_appdata2.getClass());
 304  27 if (handler != null) {
 305  27 try {
 306  27 return ( (Integer) handler.perform(a_appdata1, null, a_appdata2)).
 307    intValue();
 308    } catch (Exception ex) {
 309  0 throw new Error(ex);
 310    }
 311    }
 312    else {
 313  0 return 0;
 314    }
 315    }
 316    }
 317   
 318    /**
 319    * Optional helper class for checking if a given allele value to be set
 320    * for a given gene is valid. If not, the allele value may not be set for the
 321    * gene or the gene type (e.g. IntegerGene) is not allowed in general!
 322    *
 323    * @since 2.5 (moved from CompositeGene, where it was since 2.0)
 324    */
 325    private IGeneConstraintChecker m_geneAlleleChecker;
 326   
 327    /**
 328    * Sets the constraint checker to be used for this gene whenever method
 329    * setAllele(Object) is called.
 330    * @param a_constraintChecker the constraint checker to be set
 331    *
 332    * @author Klaus Meffert
 333    * @since 2.5 (moved from CompositeGene, where it was since 2.0)
 334    */
 335  99028 public void setConstraintChecker(
 336    final IGeneConstraintChecker a_constraintChecker) {
 337  99028 m_geneAlleleChecker = a_constraintChecker;
 338    }
 339   
 340    /**
 341    * @return IGeneConstraintChecker the constraint checker to be used whenever
 342    * method setAllele(Object) is called.
 343    *
 344    * @author Klaus Meffert
 345    * @since 2.5 (moved from CompositeGene, where it was since 2.0)
 346    */
 347  178365 public IGeneConstraintChecker getConstraintChecker() {
 348  178365 return m_geneAlleleChecker;
 349    }
 350   
 351    /**
 352    * Provides implementation-independent means for creating new Gene
 353    * instances. The new instance that is created and returned should be
 354    * setup with any implementation-dependent configuration that this Gene
 355    * instance is setup with (aside from the actual value, of course). For
 356    * example, if this Gene were setup with bounds on its value, then the
 357    * Gene instance returned from this method should also be setup with
 358    * those same bounds. This is important, as the JGAP core will invoke this
 359    * method on each Gene in the sample Chromosome in order to create each
 360    * new Gene in the same respective gene position for a new Chromosome.
 361    *
 362    * @return a new Gene instance of the same type and with the same setup as
 363    * this concrete Gene
 364    *
 365    * @author Neil Rostan
 366    * @author Klaus Meffert
 367    * @since 2.6 (since 1.0 in IntegerGene)
 368    */
 369  94400 public Gene newGene() {
 370  94400 Gene result = newGeneInternal();
 371  94400 result.setConstraintChecker(getConstraintChecker());
 372  94400 result.setEnergy(getEnergy());
 373  94400 return result;
 374    }
 375   
 376    protected abstract Gene newGeneInternal();
 377   
 378    /**
 379    * @return the configuration set
 380    *
 381    * @author Klaus Meffert
 382    * @since 3.0
 383    */
 384  94761 public Configuration getConfiguration() {
 385  94761 return m_configuration;
 386    }
 387    }