001/**
002 * Copyright (C) 2010-2015 The Roslin Institute <contact andy.law@roslin.ed.ac.uk>
003 *
004 * This file is part of JEnsembl: a Java API to Ensembl data sources developed by the
005 * Bioinformatics Group at The Roslin Institute, The Royal (Dick) School of
006 * Veterinary Studies, University of Edinburgh.
007 *
008 * Project hosted at: http://jensembl.sourceforge.net
009 *
010 * This is free software: you can redistribute it and/or modify
011 * it under the terms of the GNU General Public License (version 3) as published by
012 * the Free Software Foundation.
013 *
014 * This software is distributed in the hope that it will be useful,
015 * but WITHOUT ANY WARRANTY; without even the implied warranty of
016 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
017 * GNU General Public License for more details.
018 *
019 * You should have received a copy of the GNU General Public License
020 * in this software distribution. If not, see: http://opensource.org/licenses/gpl-3.0.html
021 */
022package uk.ac.roslin.ensembl.model;
023
024import java.io.Serializable;
025import java.util.Comparator;
026import java.util.TreeSet;
027
028/**
029 * Used to be abstract with signature
030 * public abstract class MappingSet&lt;CLAZZ extends Mapping&gt; extends TreeSet&lt;CLAZZ&gt; implements Serializable {
031 * @author tpaterso
032 */
033public class MappingSet extends TreeSet<Mapping> implements Serializable {
034
035    //this is possibly bad design - could have two subclasses, one Mapping on Source,
036    //one Mapping on Target ( and potentially other subclasses with other comparators )
037
038    /**
039     * Parameterless constructor creates a MappingSet, that is sorted using the 
040     * Mapping.mappingOnSourceComparator. 
041     */
042    public MappingSet() {
043        super(Mapping.mappingOnSourceComparator);
044
045    }
046
047    /**
048     * Alternative constructor allowing specification of an alternative comparator 
049     * for sorting (e.g. Mapping.mappingOnTargetComparator)
050     * @param differentComparator 
051     */
052    public MappingSet(Comparator differentComparator) {
053        super(differentComparator);
054    }
055
056    
057    /**
058     * Returns a Coordinate representing the extent or range of this MappingSet.
059     * This is either based on the Source Coordinates if the MappingOnSourceComparator
060     * is used, or based on the Target Coordinates if the MappingOnTArgetComparator
061     * is used
062     * @return Coordinate
063     */
064    public Coordinate getExtent() {
065        if (this.isEmpty()) {
066            return null;
067        }
068
069        //if (this.comparator() instanceof MappingOnSourceComparator) {
070        if (this.comparator().equals(Mapping.mappingOnSourceComparator)) {
071
072            Coordinate out = new Coordinate();
073            out.setStrandInt(1);
074
075            if (this.first().getSourceCoordinates()!=null) {
076                out.setStart(this.first().getSourceCoordinates().getStart());
077            }
078            Integer end = 0;
079            for (Mapping m : this) {
080                if (m.getSourceCoordinates() != null
081                        && m.getSourceCoordinates().getEnd() > end ) {
082                    end =  m.getSourceCoordinates().getEnd();
083                }
084            }
085            if (end != 0) {
086                out.setEnd(end);
087            }
088
089            return out;
090
091        //} else if (this.comparator() instanceof MappingOnTargetComparator) {
092        } else if (this.comparator().equals(Mapping.mappingOnTargetComparator)) {
093            Coordinate out = new Coordinate();
094            out.setStrandInt(1);
095            
096            if (this.first().getTargetCoordinates()!=null) {
097                out.setStart(this.first().getTargetCoordinates().getStart());
098            }
099
100            Integer end = 0;
101            for (Mapping m : this) {
102                if (m.getTargetCoordinates() != null
103                        && m.getTargetCoordinates().getEnd() > end ) {
104                    end =  m.getTargetCoordinates().getEnd();
105                }
106            }
107            if (end != 0) {
108                out.setEnd(end);
109            }
110
111            return out;
112
113        }
114
115        return null;
116    }
117    
118    /**
119     * Returns a CoordinateSet containing all of the Source Coordinates of Mappings in this MappingSet.
120     * @return CoordinateSet
121     */
122    public CoordinateSet getSourceCoordinates() {
123        CoordinateSet set = new CoordinateSet();
124        for (Mapping m: this) {
125            set.add(m.getSourceCoordinates());
126        }
127        return set;
128    }
129    
130    /**
131     * Returns a CoordinateSet containing all of the Target Coordinates of Mappings in this MappingSet.
132     * @return CoordinateSet
133     */    
134    public CoordinateSet getTargetCoordinates() {
135        CoordinateSet set = new CoordinateSet();
136        for (Mapping m: this) {
137            set.add(m.getTargetCoordinates());
138        }
139        return set;
140    }    
141}