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 */
021
022package org.biojavax.bio.seq;
023import java.util.Collections;
024import java.util.Iterator;
025import java.util.Set;
026
027import org.biojava.bio.Annotation;
028import org.biojava.bio.symbol.Location;
029import org.biojava.bio.symbol.SymbolList;
030import org.biojava.utils.ChangeVetoException;
031import org.biojava.utils.Unchangeable;
032import org.biojavax.CrossRef;
033import org.biojavax.CrossReferenceResolver;
034import org.biojavax.RichAnnotation;
035import org.biojavax.ontology.ComparableTerm;
036
037/**
038 * An Empty implementation of RichLocation. This class is intended to 
039 * act as a place holder for events like the intersection of two locations
040 * that do not overlap so that null need not be returned.
041 * @author Richard Holland
042 * @author Mark Schreiber
043 * @author George Waldon
044 * @since 1.5
045 */
046public class EmptyRichLocation extends Unchangeable implements RichLocation {
047           
048    /**
049     * {@inheritDoc} 
050     * ALWAYS RETURNS NULL
051     */
052    public RichFeature getFeature() { return null; }
053        
054    /**
055     * {@inheritDoc} 
056     * DOES NOTHING
057     */
058    public void sort() {}
059    
060    /**
061     * {@inheritDoc} 
062     * NOT IMPLEMENTED
063     */
064    public void setFeature(RichFeature feature) throws ChangeVetoException {
065        throw new ChangeVetoException("Cannot set a feature for the empty location");
066    }
067    
068    /**
069     * {@inheritDoc} 
070     * ALWAYS RETURNS NULL
071     */
072    public CrossRef getCrossRef() { return null; }
073    
074    /**
075     * {@inheritDoc}
076     * ALWAYS RETURNS THE EMPTY ANNOTATION
077     */
078    public Annotation getAnnotation() { return getRichAnnotation(); }
079
080    /**
081     * {@inheritDoc}
082     * ALWAYS RETURNS THE EMPTY ANNOTATION
083     */
084    public RichAnnotation getRichAnnotation() { return RichAnnotation.EMPTY_ANNOTATION; }
085
086    /**
087     * {@inheritDoc} 
088     * ALWAYS RETURNS THE EMPTY ANNOTATION NOTE SET
089     */
090    public Set getNoteSet() { return RichAnnotation.EMPTY_ANNOTATION.getNoteSet(); }
091    
092    /**
093     * {@inheritDoc} 
094     * NOT IMPLEMENTED
095     */
096    public void setNoteSet(Set notes) throws ChangeVetoException {
097        throw new ChangeVetoException("Cannot annotate the empty location");
098    }
099    
100    /**
101     * {@inheritDoc} 
102     * ALWAYS RETURNS NULL
103     */
104    public ComparableTerm getTerm() { return null; }
105    
106    /**
107     * {@inheritDoc} 
108     * NOT IMPLEMENTED
109     */
110    public void setTerm(ComparableTerm term) throws ChangeVetoException {
111        throw new ChangeVetoException("Cannot give a term to the empty location");
112    }
113    
114    /**
115     * {@inheritDoc}
116     * ALWAYS RETURNS ZERO
117     */
118    public int getCircularLength() { return 0; }
119    
120    /**
121     * {@inheritDoc} 
122     * NOT IMPLEMENTED
123     */
124    public void setCircularLength(int sourceSeqLength) throws ChangeVetoException {
125        throw new ChangeVetoException("Cannot make empty locations circular");
126    }
127    
128    /**
129     * {@inheritDoc} 
130     * ALWAYS RETURNS THE UNKNOWN STRAND
131     */
132    public Strand getStrand() { return Strand.UNKNOWN_STRAND; }
133        
134    /**
135     * {@inheritDoc} 
136     * ALWAYS RETURNS ZERO
137     */
138    public int getRank() { return 0; }
139    
140    /**
141     * {@inheritDoc} 
142     * NOT IMPLEMENTED
143     */
144    public void setRank(int rank) throws ChangeVetoException {
145        throw new ChangeVetoException("Cannot give a rank to the empty location");
146    }
147    
148    /**
149     * {@inheritDoc}
150     * ALWAYS RETURNS ZERO
151     */
152    public int getMax() { return 0; }
153        
154    /**
155     * {@inheritDoc}
156     * ALWAYS RETURNS ZERO
157     */
158    public int getMin() { return 0; }
159    
160    /**
161     * {@inheritDoc}
162     * ALWAYS RETURNS THE EMPTY POSITION
163     */ 
164    public Position getMinPosition() { return Position.EMPTY_POSITION; }
165    
166    /**
167     * {@inheritDoc}
168     * ALWAYS RETURNS THE EMPTY POSITION
169     */ 
170    public Position getMaxPosition() { return Position.EMPTY_POSITION; }
171    
172    /**
173     * {@inheritDoc} This method is ignored in the empty location because positions
174     * are fixed an cannot be modified.
175     */
176    public void setPositionResolver(PositionResolver p) {} // ignore
177    
178    /**
179     * {@inheritDoc}
180     * ALWAYS RETURNS THE EMPTY SET ITERATOR
181     */
182    public Iterator blockIterator() { return Collections.EMPTY_SET.iterator(); }
183    
184    /**
185     * {@inheritDoc}
186     * ALWAYS RETURNS TRUE
187     */
188    public boolean isContiguous() { return true; }
189        
190    /**
191     * {@inheritDoc}
192     * ALWAYS RETURNS FALSE
193     */
194    public boolean contains(int p) { return false; }
195    
196    /**
197     * {@inheritDoc}
198     * ALWAYS RETURNS NULL
199     */
200    public Location getDecorator(Class decoratorClass) { return null; }
201    
202    /**
203     * {@inheritDoc}
204     * ALWAYS RETURNS PASSED LOCATION
205     */
206    public Location newInstance(Location loc) { return loc; }
207    
208    /**
209     * {@inheritDoc}
210     * ALWAYS RETURNS SELF
211     */
212    public Location translate(int dist) { return this; }  
213    
214    /**
215     * {@inheritDoc}
216     * ALWAYS RETURNS FALSE
217     */
218    public boolean contains(Location l) { return false; }
219    
220    /**
221     * {@inheritDoc}
222     * ALWAYS RETURNS FALSE
223     */
224    public boolean overlaps(Location l) { return false; }
225    
226    /**
227     * {@inheritDoc} 
228     * ALWAYS RETURNS PASSED LOCATION
229     */
230    public Location union(Location l) {
231        if (l==null) throw new IllegalArgumentException("Location cannot be null");
232        if (!(l instanceof RichLocation)) l = RichLocation.Tools.enrich(l);
233        return l;
234    }
235    
236    /**
237     * {@inheritDoc}
238     * ALWAYS RETURNS SELF
239     */
240    public Location intersection(Location l) {
241        if (l==null) throw new IllegalArgumentException("Location cannot be null");
242        return this;
243    }
244       
245    
246    /**
247     * {@inheritDoc} This method is ignored in the empty location because 
248     * there is nothing to resolve.
249     */
250    public void setCrossRefResolver(CrossReferenceResolver r) {}
251    
252    /**
253     * {@inheritDoc}
254     * ALWAYS RETURNS THE EMPTY SYMBOL LIST
255     */
256    public SymbolList symbols(SymbolList seq) {
257        if (seq==null) throw new IllegalArgumentException("Sequence cannot be null");
258        return SymbolList.EMPTY_LIST;
259    }
260    
261    /**
262     * {@inheritDoc}
263     * ALWAYS RETURNS 17
264     */
265    public int hashCode() { return 17; }
266    
267    /**
268     * {@inheritDoc}
269     * Empty Rich Locations only match other Empty Rich Locations
270     */
271    public boolean equals(Object o) {
272        if (o instanceof EmptyRichLocation) return true;
273        return false;
274    }
275    
276    /**
277     * {@inheritDoc}
278     * Empty Rich Locations return 0 when compared to other Empty ones,
279     * or -1 otherwise.
280     */
281    public int compareTo(Object o) {
282        if (o instanceof EmptyRichLocation) return 0;
283        else return -1;
284    }
285    
286    /**
287     * {@inheritDoc}
288     * ALWAYS RETURNS "empty"
289     */
290    public String toString() {
291        return "empty";
292    }
293}
294