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 */
022 package org.biojava3.core.sequence.location;
023
024 import org.biojava3.core.sequence.location.template.Point;
025 import org.biojava3.core.util.Equals;
026 import org.biojava3.core.util.Hashcoder;
027
028 /**
029 * Implementation for resolving fuzzy locations. Caches the calculated
030 * value.
031 *
032 * @author ayates
033 */
034 public 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 @SuppressWarnings("EqualsWhichDoesntCheckParameterClass")
124 public boolean equals(Object obj) {
125 boolean equals = false;
126 if (Equals.classEqual(this, obj)) {
127 FuzzyPoint p = (FuzzyPoint) obj;
128 equals = (Equals.equal(getMin(), p.getMin())
129 && Equals.equal(getMax(), p.getMax())
130 && Equals.equal(isUnknown(), p.isUnknown())
131 && Equals.equal(isUncertain(), p.isUncertain())
132 );
133 }
134 return equals;
135 }
136
137 @Override
138 public int hashCode() {
139 int r = Hashcoder.SEED;
140 r = Hashcoder.hash(r, getMin());
141 r = Hashcoder.hash(r, getMax());
142 r = Hashcoder.hash(r, isUncertain());
143 r = Hashcoder.hash(r, isUnknown());
144 return r;
145 }
146
147 @Override
148 public int compareTo(Point point) {
149 //If we can assign this to a FuzzyPoint then work with a bit more info
150 if(FuzzyPoint.class.isAssignableFrom(point.getClass())) {
151 FuzzyPoint fuzzy = (FuzzyPoint)point;
152 int minComparison = getMin().compareTo(fuzzy.getMin());
153 if(minComparison != 0)
154 return minComparison;
155 return getMax().compareTo(fuzzy.getMax());
156 }
157 //If not fuzzy then compare on position as normal
158 return super.compareTo(point);
159 }
160 }