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 java.util.Arrays;
025    import java.util.List;
026    import org.biojava3.core.sequence.Strand;
027    import org.biojava3.core.sequence.location.template.AbstractLocation;
028    import org.biojava3.core.sequence.location.template.Location;
029    import org.biojava3.core.sequence.location.template.Point;
030    
031    /**
032     * A collection of locations which are used whenever we work with INSDC; some
033     * of which could be deprecated (from INSDC's point of view) yet appear
034     * in records.
035     *
036     * @author ayates
037     */
038    public class InsdcLocations {
039    
040        /**
041         * Used to represent bond locations equivalent to bond(7,8) or bond(7).
042         * Bond locations are single position complex locations
043         */
044        public static class BondLocation extends AbstractLocation {
045    
046            public BondLocation(Location... subLocations) {
047                this(Arrays.asList(subLocations));
048            }
049    
050            public BondLocation(List<Location> subLocations) {
051                super();
052                Location min = Tools.getMin(subLocations);
053                Location max = Tools.getMax(subLocations);
054                setStart(min.getStart());
055                setEnd(max.getEnd());
056                setStrand(Strand.UNDEFINED);
057                setSubLocations(subLocations);
058                assertLocation();
059            }
060    
061            @Override
062            protected final void assertLocation() {
063                for (Location l : this) {
064                    Point start = l.getStart();
065                    Point end = l.getEnd();
066                    if (!start.equals(end)) {
067                        throw new IllegalStateException("The start "
068                                + start + " is not equal to the end "
069                                + end + ". bond locations must be a single "
070                                + "compound long");
071                    }
072                }
073            }
074        }
075    
076        /**
077         * Used to describe a 5' to 3' ordering but no firm assurance it is correct
078         */
079        public static class OrderLocation extends SimpleLocation {
080    
081            public OrderLocation(Point start, Point end, Strand strand,
082                    boolean circular, Location... subLocations) {
083                super(start, end, strand, circular, subLocations);
084            }
085    
086            public OrderLocation(Point start, Point end, Strand strand,
087                    Location... subLocations) {
088                this(start, end, strand, false, subLocations);
089            }
090    
091            public OrderLocation(int start, int end, Strand strand,
092                    Location... subLocations) {
093                this(new SimplePoint(start), new SimplePoint(end), strand, false, subLocations);
094            }
095    
096            public OrderLocation(Point start, Point end, Strand strand,
097                    boolean circular, List<Location> subLocations) {
098                super(start, end, strand, circular, subLocations);
099            }
100    
101            public OrderLocation(Point start, Point end, Strand strand,
102                    List<Location> subLocations) {
103                this(start, end, strand, false, subLocations);
104            }
105    
106            public OrderLocation(int start, int end, Strand strand,
107                    List<Location> subLocations) {
108                this(new SimplePoint(start), new SimplePoint(end), strand, false, subLocations);
109            }
110        }
111    
112        /**
113         * Deprecated in INSDC yet still appears; equivalent to the order()
114         * directive except no 5' to 3' ordering is defined. The constructor
115         * reflects this relationship and only allows the creation of complex
116         * locations
117         */
118        public static class GroupLocation extends SimpleLocation {
119    
120            public GroupLocation(Point start, Point end, Strand strand,
121                    boolean circular, Location... subLocations) {
122                super(start, end, strand, circular, subLocations);
123            }
124    
125            public GroupLocation(Point start, Point end, Strand strand,
126                    Location... subLocations) {
127                this(start, end, strand, false, subLocations);
128            }
129    
130            public GroupLocation(int start, int end, Strand strand,
131                    Location... subLocations) {
132                this(new SimplePoint(start), new SimplePoint(end), strand, false, subLocations);
133            }
134    
135            public GroupLocation(Point start, Point end, Strand strand,
136                    boolean circular, List<Location> subLocations) {
137                super(start, end, strand, circular, subLocations);
138            }
139    
140            public GroupLocation(Point start, Point end, Strand strand,
141                    List<Location> subLocations) {
142                this(start, end, strand, false, subLocations);
143            }
144    
145            public GroupLocation(int start, int end, Strand strand,
146                    List<Location> subLocations) {
147                this(new SimplePoint(start), new SimplePoint(end), strand, false, subLocations);
148            }
149        }
150    
151        /**
152         * Deprecated in INSDC; refers to a set of locations of which one
153         * location could be valid e.g. one-of(location, location, location).
154         * Originally used to describe split locations in alternative splicing
155         * or variations. Now these are dealt with in their own feature fields.
156         *
157         * The default location is chosen to be the first however if you think
158         * you need to work with this location you should use the sub-locations.
159         */
160        public static class OneOfLocation extends AbstractLocation {
161    
162            public OneOfLocation(Location... locations) {
163                this(Arrays.asList(locations));
164            }
165    
166            public OneOfLocation(List<Location> locations) {
167                super();
168                if (locations.isEmpty()) {
169                    throw new IllegalArgumentException("Need locations to build a OneOfLocation");
170                }
171                Location l = locations.get(0);
172                setStart(l.getStart());
173                setEnd(l.getEnd());
174                setStrand(l.getStrand());
175                setBetweenCompounds(l.isBetweenCompounds());
176                setCircular(l.isCircular());
177                setSubLocations(locations);
178            }
179        }
180    }