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.datasourceaware.variation; 023 024import java.util.ArrayList; 025import java.util.HashMap; 026import java.util.HashSet; 027import java.util.List; 028import java.util.Set; 029import org.slf4j.Logger; 030import org.slf4j.LoggerFactory; 031import uk.ac.roslin.ensembl.config.EnsemblCoordSystemType; 032import uk.ac.roslin.ensembl.dao.factory.DAOVariationFactory; 033import uk.ac.roslin.ensembl.datasourceaware.DAObject; 034import uk.ac.roslin.ensembl.exception.NonUniqueException; 035import uk.ac.roslin.ensembl.model.Mapping; 036import uk.ac.roslin.ensembl.model.MappingSet; 037import uk.ac.roslin.ensembl.model.ObjectType; 038import uk.ac.roslin.ensembl.model.core.Chromosome; 039import uk.ac.roslin.ensembl.model.variation.Variation; 040import uk.ac.roslin.ensembl.model.variation.VariationType; 041 042/** 043 * 044 * @author tpaterso 045 */ 046public class DAVariation extends DAObject implements Variation { 047 048 final static Logger LOGGER = LoggerFactory.getLogger(DAVariation.class); 049 //use the target comparator for these as will have multiple identical source mappings! 050 protected MappingSet mappings = new MappingSet(Mapping.mappingOnTargetComparator); 051 protected HashMap<ObjectType, MappingSet> objectTypeMappings = new HashMap<ObjectType, MappingSet>(); 052 protected Set<ObjectType> mappedObjectTypes = new HashSet<ObjectType>(); 053 protected String name; 054 protected String synonym; 055 protected List<String> synonyms = new ArrayList<String>(); 056 protected String ancestralAllele; 057 protected DAVariationXRef xref; 058 protected VariationType varType; 059 protected Boolean somatic = false; 060 protected Boolean flipped = false; 061 protected int occurrences; 062 private Boolean initOK = false; 063 064 public DAVariation() { 065 super(); 066 } 067 068 public DAVariation(DAOVariationFactory factory) { 069 super(factory); 070 } 071 072 /** 073 * This is a hack to classigy the loaded mapping by type, because MyBatis 074 * apparently sets 'mappings' by reflection, not 075 * with the setter, so objectTypeMappings is not initialized by the MyBatis call. 076 */ 077 public void checkInitialized() { 078 if (!initOK) { 079 for (Mapping mapping : mappings) { 080 ObjectType t = mapping.getTargetType(); 081 082 if (t != null) { 083 if (!this.objectTypeMappings.containsKey(t)) { 084 this.objectTypeMappings.put(t, new MappingSet()); 085 } 086 this.objectTypeMappings.get(t).add((Mapping) mapping); 087 } 088 } 089 } 090 initOK = true; 091 } 092 093 @Override 094 public DAOVariationFactory getDaoFactory() { 095 return (DAOVariationFactory) daoFactory; 096 } 097 098 @Override 099 public VariationType getType() { 100 return varType; 101 } 102 103 public void setVarType(VariationType varType) { 104 this.varType = varType; 105 } 106 107 @Override 108 public void addMappedObjectType(ObjectType mappedType) { 109 mappedObjectTypes.add(mappedType); 110 } 111 112 @Override 113 public Boolean isObjectTypeMapped(ObjectType mappedType) { 114 return mappedObjectTypes.contains(mappedType); 115 } 116 117 @Override 118 public Boolean isCurrent() { 119 throw new UnsupportedOperationException("Not supported yet."); 120 } 121 122 /** 123 * Utility method to pull back a single mapping of this Feature on a Given 124 * chromosome. This should be the mapping stored at initialisation. If the 125 * Feature has implemented a reinitialize method this may be called. 126 * 127 * @param chr 128 * @return a single Mapping 129 * @throws NonUniqueException if more than one mapping for the chromosome 130 */ 131 @Override 132 public Mapping getChromosomeMapping(Chromosome chr) throws NonUniqueException { 133 134 if (chr == null) { 135 return null; 136 } 137 138 Mapping uniqueMapping = null; 139 140 MappingSet s = this.getLoadedMappings(EnsemblCoordSystemType.chromosome); 141 142 if (s == null || s.isEmpty()) { 143 return null; 144 } 145 146 boolean found = false; 147 148 for (Mapping m : s) { 149 if (m.getTarget() == chr) { 150 if (found) { 151 throw new NonUniqueException(); 152 } 153 uniqueMapping = m; 154 found = true; 155 } 156 } 157 return uniqueMapping; 158 } 159 160 /** 161 * Utility method to pull back a unique chromosomal mapping of this Feature. 162 * This should be the mapping stored at initialisation. If the Feature has 163 * implemented a reinitialize method this may be called. 164 * 165 * @return a single Mapping 166 * @throws NonUniqueException if more than one mapping for the chromosome 167 */ 168 @Override 169 public Mapping getChromosomeMapping() throws NonUniqueException { 170 171 Mapping uniqueMapping = null; 172 MappingSet s = this.getLoadedMappings(EnsemblCoordSystemType.chromosome); 173 174 if (s == null || s.isEmpty()) { 175 return null; 176 } 177 178 if (s.size() > 1) { 179 throw new NonUniqueException(); 180 } 181 182 return s.first(); 183 } 184 185 /** 186 * Method to return all chromosomal mappings for this feature. In most 187 * circumstances there should be only one mapping. If the Feature has 188 * implemented a re-initialize method this may be called. 189 * 190 * @return MappingSet ordered set of chromosomal mappings 191 */ 192 @Override 193 public MappingSet getChromosomeMappings() { 194 195 return this.getLoadedMappings(EnsemblCoordSystemType.chromosome); 196 } 197 198 //Should Be Private?? and call by named object type methods ?? 199 @Override 200 public MappingSet getLoadedMappings(ObjectType targetType) { 201 this.checkInitialized(); 202 if (this.objectTypeMappings.containsKey(targetType)) { 203 return this.objectTypeMappings.get(targetType); 204 } else if (this.isObjectTypeMapped(targetType)) { 205 this.objectTypeMappings.put(targetType, new MappingSet()); 206 return this.objectTypeMappings.get(targetType); 207 } else { 208 return new MappingSet(); 209 } 210 } 211 212 @Override 213 public MappingSet getLoadedMappings() { 214 //we haven't got the lazy load working here yet 215 return (MappingSet) this.mappings; 216 } 217 218 //added for MyBatis - but it fails to use it - sets by reflection instead 219 public MappingSet getMappings() { 220 //we haven't got the lazy load working here yet 221 return (MappingSet) this.mappings; 222 } 223 224 @Override 225 public Boolean addMapping(Mapping mapping) { 226 //if we fail to add the mapping this will be false 227 if (this.mappings.add((VariationMapping) mapping)) { 228 229 ObjectType t = mapping.getTargetType(); 230 231 if (t != null) { 232 if (!this.objectTypeMappings.containsKey(t)) { 233 this.objectTypeMappings.put(t, new MappingSet()); 234 } 235 236 this.objectTypeMappings.get(t).add((Mapping) mapping); 237 } 238 return true; 239 } 240 241 return false; 242 } 243 244 public void setMappings(MappingSet mappings) { 245 for (Mapping m : mappings) { 246 this.addMapping(m); 247 } 248 initOK = true; 249 } 250 251 @Override 252 public void clearAllMappings() { 253 mappings.clear(); 254 mappedObjectTypes.clear(); 255 objectTypeMappings.clear(); 256 initOK = false; 257 } 258 259 @Override 260 public String getName() { 261 return this.name; 262 } 263 264 @Override 265 public void setName(String name) { 266 this.name = name; 267 } 268 269 @Override 270 public DAVariationXRef getXRef() { 271 return xref; 272 } 273 274 public void setXRef(DAVariationXRef xref) { 275 this.xref = xref; 276 } 277 278 @Override 279 public Boolean isSomatic() { 280 return this.somatic; 281 } 282 283 public void setSomatic(Boolean somatic) { 284 this.somatic = somatic; 285 } 286 287 @Override 288 public Boolean isFlipped() { 289 return this.flipped; 290 } 291 292 public void setFlipped(Boolean flipped) { 293 this.flipped = flipped; 294 } 295 296 @Override 297 public String getAncestralAllele() { 298 return this.ancestralAllele; 299 } 300 301 public void setAncestralAllele(String ancestralAllele) { 302 this.ancestralAllele = ancestralAllele; 303 } 304 305 @Override 306 public int getOccurrences() { 307 return this.occurrences; 308 } 309 310 public void setOccurrences(int count) { 311 this.occurrences = count; 312 } 313 314 @Override 315 public String getSynonym() { 316 return this.synonym; 317 } 318 319 @Override 320 public List<String> getAllSynonyms() { 321 return this.synonyms; 322 } 323 324 @Override 325 public void setSynonym(String altname) { 326 this.synonym = altname; 327 this.synonyms.add(altname); 328 } 329}