001/* 002 * BioJava development code 003 * 004 * This code may be freely distributed and modified under the 005 * terms of the GNU Lesser General Public Licence. This should 006 * be distributed with the code. If you do not have a copy, 007 * see: 008 * 009 * http://www.gnu.org/copyleft/lesser.html 010 * 011 * Copyright for this code is held jointly by the individual 012 * authors. These should be listed in @author doc comments. 013 * 014 * For more information on the BioJava project and its aims, 015 * or to join the biojava-l mailing list, visit the home page 016 * at: 017 * 018 * http://www.biojava.org/ 019 * 020 * Created on 01-21-2010 021 */ 022package org.biojava.nbio.core.sequence.location; 023 024import org.biojava.nbio.core.sequence.location.template.Point; 025import org.biojava.nbio.core.util.Equals; 026import org.biojava.nbio.core.util.Hashcoder; 027 028/** 029 * Implementation for resolving fuzzy locations. Caches the calculated 030 * value. 031 * 032 * @author ayates 033 */ 034public class FuzzyPoint extends SimplePoint { 035 036 /** 037 * Always uses the min point to resolve a location 038 */ 039 public static final Resolver<FuzzyPoint> MIN_RESOLVER = new Resolver<FuzzyPoint>() { 040 @Override 041 public int resolve(FuzzyPoint point) { 042 return point.getMin(); 043 } 044 }; 045 046 /** 047 * Always uses the max point to resolve a location 048 */ 049 public static final Resolver<FuzzyPoint> MAX_RESOLVER = new Resolver<FuzzyPoint>() { 050 @Override 051 public int resolve(FuzzyPoint point) { 052 return point.getMax(); 053 } 054 }; 055 056 /** 057 * Combines min and max and then gets the mean of it 058 */ 059 public static final Resolver<FuzzyPoint> MEAN_RESOLVER = new Resolver<FuzzyPoint>() { 060 @Override 061 public int resolve(FuzzyPoint point) { 062 return (point.getMin() + point.getMax()) / 2; 063 } 064 }; 065 066 private final int min; 067 private final int max; 068 private final Resolver<FuzzyPoint> resolver; 069 070 public FuzzyPoint(int minPoint, int maxPoint) { 071 this(minPoint, maxPoint, MEAN_RESOLVER, false, false); 072 } 073 074 public FuzzyPoint(int minPoint, int maxPoint, Resolver<FuzzyPoint> resolver) { 075 this(minPoint, maxPoint, resolver, false, false); 076 } 077 078 public FuzzyPoint(int minPoint, int maxPoint, Resolver<FuzzyPoint> resolver, boolean unknown, boolean uncertain) { 079 this.min = minPoint; 080 this.max = maxPoint; 081 this.resolver = resolver; 082 setUncertain(uncertain); 083 setUnknown(unknown); 084 setPosition(-1); //Means we have not resolved this position yet 085 } 086 087 @Override 088 public Integer getPosition() { 089 if(super.getPosition() == -1) { 090 super.setPosition(getResolver().resolve(this)); 091 } 092 return super.getPosition(); 093 } 094 095 protected Integer getMax() { 096 return max; 097 } 098 099 protected Integer getMin() { 100 return min; 101 } 102 103 protected Resolver<FuzzyPoint> getResolver() { 104 return resolver; 105 } 106 107 @Override 108 public Point reverse(int length) { 109 int revMin = reverse(getMin(), length); 110 int revMax = reverse(getMax(), length); 111 return new FuzzyPoint(revMin, revMax, getResolver(), isUnknown(), isUncertain()); 112 } 113 114 @Override 115 public Point offset(int distance) { 116 int offMin = getMin() + distance; 117 int offMax = getMax() + distance; 118 return new FuzzyPoint(offMin, offMax, getResolver(), isUnknown(), isUncertain()); 119 } 120 121 122 @Override 123 public boolean equals(Object obj) { 124 boolean equals = false; 125 if (Equals.classEqual(this, obj)) { 126 FuzzyPoint p = (FuzzyPoint) obj; 127 equals = (Equals.equal(getMin(), p.getMin()) 128 && Equals.equal(getMax(), p.getMax()) 129 && Equals.equal(isUnknown(), p.isUnknown()) 130 && Equals.equal(isUncertain(), p.isUncertain()) 131 ); 132 } 133 return equals; 134 } 135 136 @Override 137 public int hashCode() { 138 int r = Hashcoder.SEED; 139 r = Hashcoder.hash(r, getMin()); 140 r = Hashcoder.hash(r, getMax()); 141 r = Hashcoder.hash(r, isUncertain()); 142 r = Hashcoder.hash(r, isUnknown()); 143 return r; 144 } 145 146 @Override 147 public int compareTo(Point point) { 148 //If we can assign this to a FuzzyPoint then work with a bit more info 149 if(FuzzyPoint.class.isAssignableFrom(point.getClass())) { 150 FuzzyPoint fuzzy = (FuzzyPoint)point; 151 int minComparison = getMin().compareTo(fuzzy.getMin()); 152 if(minComparison != 0) 153 return minComparison; 154 return getMax().compareTo(fuzzy.getMax()); 155 } 156 //If not fuzzy then compare on position as normal 157 return super.compareTo(point); 158 } 159}