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.ArrayList; 024import java.util.Collection; 025import java.util.Iterator; 026import java.util.List; 027 028import org.biojava.bio.symbol.Location; 029import org.biojava.utils.ChangeVetoException; 030import org.biojavax.CrossRef; 031import org.biojavax.ontology.ComparableTerm; 032 033/** 034 * An implementation of RichLocation which possibly covers multiple locations, 035 * on different strands, different circular lengths, or different sequences. 036 * @author Richard Holland 037 * @author Mark Schreiber 038 * @since 1.5 039 */ 040public class MultiSourceCompoundRichLocation extends CompoundRichLocation implements RichLocation { 041 042 /** 043 * Constructs a MultiSourceCompoundRichLocation from the given set of members, with 044 * the default term of "join". Note that you really shouldn't use this if 045 * you are unsure if your members set contains overlapping members. Use 046 * RichLocation.Tools.construct() instead. The members collection 047 * must only contain Location instances. Any that are not RichLocations will 048 * be converted using RichLocation.Tools.enrich(). 049 * @param members the members to put into the compound location. 050 * @see RichLocation.Tools 051 */ 052 public MultiSourceCompoundRichLocation(Collection members) { this(getJoinTerm(), members); } 053 054 /** 055 * Constructs a MultiSourceCompoundRichLocation from the given set of members. 056 * Note that you really shouldn't use this if 057 * you are unsure if your members set contains overlapping members. Use 058 * RichLocation.Tools.construct(members) instead. The members collection 059 * must only contain Location instances. Any that are not RichLocations will 060 * be converted using RichLocation.Tools.enrich(). 061 * @param term the term to use when describing the group of members. 062 * @param members the members to put into the compound location. 063 * @see RichLocation.Tools 064 */ 065 public MultiSourceCompoundRichLocation(ComparableTerm term, Collection members) { 066 if (term==null) throw new IllegalArgumentException("Term cannot be null"); 067 if (members==null || members.size()<2) throw new IllegalArgumentException("Must have at least two members"); 068 this.term = term; 069 this.members = new ArrayList(); 070 for (Iterator i = members.iterator(); i.hasNext(); ) { 071 // Convert each member into a RichLocation 072 Object o = i.next(); 073 if (!(o instanceof RichLocation)) o = RichLocation.Tools.enrich((Location)o); 074 // Convert 075 RichLocation rl = (RichLocation)o; 076 // Add in member 077 this.members.add(rl); 078 // Update our size 079 this.size += Math.max(rl.getMin(),rl.getMax())-Math.min(rl.getMin(),rl.getMax()); 080 } 081 } 082 083 /** 084 * {@inheritDoc} 085 * ALWAYS RETURNS NULL 086 */ 087 public CrossRef getCrossRef() { return null; } 088 089 /** 090 * {@inheritDoc} 091 * ALWAYS RETURNS ZERO 092 */ 093 public int getCircularLength() { return 0; } 094 095 /** 096 * {@inheritDoc} 097 * NOT IMPLEMENTED 098 * @throws ChangeVetoException ALWAYS 099 */ 100 public void setCircularLength(int sourceSeqLength) throws ChangeVetoException { 101 if (sourceSeqLength>0) throw new ChangeVetoException("MultiSourceCompoundRichLocations cannot be circular"); 102 } 103 104 /** 105 * {@inheritDoc} 106 */ 107 public Strand getStrand() { return Strand.UNKNOWN_STRAND; } 108 109 /** 110 * {@inheritDoc} 111 * ALWAYS RETURNS ONE 112 */ 113 public int getMin() { return 1; } 114 115 /** 116 * {@inheritDoc} 117 * ALWAYS RETURNS COMBINED LENGTH OF MEMBERS 118 */ 119 public int getMax() { return this.size; } 120 121 /** 122 * {@inheritDoc} 123 * ALWAYS RETURNS A POINT POSITION AT POINT 1 124 */ 125 public Position getMinPosition() { return new SimplePosition(false,false,1); } 126 127 /** 128 * {@inheritDoc} 129 * ALWAYS RETURNS A POINT POSITION AT POINT EQUIVALENT TO COMBINED LENGTH OF MEMBERS 130 */ 131 public Position getMaxPosition() { return new SimplePosition(false,false,this.size); } 132 133 /** 134 * {@inheritDoc} 135 * Recursively translates all members of this location. 136 */ 137 public Location translate(int dist) { 138 if (this.members.isEmpty()) return this; 139 List newmembers = new ArrayList(); 140 for (Iterator i = this.members.iterator(); i.hasNext(); ) { 141 RichLocation rl = (RichLocation)i.next(); 142 newmembers.add(rl.translate(dist)); 143 } 144 return new MultiSourceCompoundRichLocation(this.getTerm(),newmembers); 145 } 146} 147