001 /** 002 * Copyright (C) 2010 The Roslin Institute <contact andy.law@roslin.ed.ac.uk> 003 * 004 * This file is part of the Ensembl Java API demonstration project developed by the 005 * Bioinformatics Group at The Roslin Institute, The Royal (Dick) School of 006 * Veterinary Studies, University of Edinburgh. 007 * 008 * This is free software: you can redistribute it and/or modify 009 * it under the terms of the GNU General Public License (version 3) as published by 010 * the Free Software Foundation. 011 * 012 * This software is distributed in the hope that it will be useful, 013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 015 * GNU General Public License for more details. 016 * 017 * You should have received a copy of the GNU General Public License 018 * in this software distribution. If not, see <http://www.gnu.org/licenses/gpl-3.0.html/>. 019 */ 020 package uk.ac.roslin.ensembl.datasourceaware.core; 021 022 import java.util.ArrayList; 023 import java.util.Date; 024 import java.util.HashMap; 025 import java.util.HashSet; 026 import java.util.List; 027 import java.util.Set; 028 import org.apache.log4j.Logger; 029 import uk.ac.roslin.ensembl.config.EnsemblCoordSystemType; 030 import uk.ac.roslin.ensembl.config.EnsemblDBType; 031 import uk.ac.roslin.ensembl.config.FeatureType; 032 import uk.ac.roslin.ensembl.model.MappingSet; 033 import uk.ac.roslin.ensembl.dao.factory.DAOCoreFactory; 034 import uk.ac.roslin.ensembl.datasourceaware.DAXRef; 035 import uk.ac.roslin.ensembl.exception.DAOException; 036 import uk.ac.roslin.ensembl.model.Mapping; 037 import uk.ac.roslin.ensembl.model.ObjectType; 038 import uk.ac.roslin.ensembl.model.core.Chromosome; 039 import uk.ac.roslin.ensembl.model.core.CoordinateSystem; 040 import uk.ac.roslin.ensembl.model.core.Feature; 041 import uk.ac.roslin.ensembl.model.database.CollectionCoreDatabase; 042 import uk.ac.roslin.ensembl.model.database.SingleSpeciesCoreDatabase; 043 044 /** 045 * 046 * @author tpaterso 047 */ 048 public abstract class DAFeature extends DACoreObject implements Feature { 049 050 protected MappingSet mappings = new MappingSet(); 051 protected HashMap<ObjectType, MappingSet> objectTypeMappings = new HashMap<ObjectType, MappingSet>(); 052 protected Set<ObjectType> mappedObjectTypes = new HashSet<ObjectType>(); 053 protected Date creationDate = null; 054 protected Date modificationDate = null; 055 protected String description = null; 056 protected DAXRef displayXRef = null; 057 protected List<DAXRef> xrefs = new ArrayList<DAXRef>(); 058 protected String displayName = null; 059 private Status status = Status.UNKNOWN; 060 protected Boolean current = null; 061 062 final static Logger LOGGER = Logger.getLogger(DAFeature.class); 063 064 public DAFeature() { 065 super(); 066 } 067 068 public DAFeature(DAOCoreFactory factory) { 069 super(factory); 070 } 071 072 public MappingSet getMappings() { 073 //we haven't got the lazy load working here yet 074 return this.mappings; 075 } 076 077 //Should Be Private?? and call by named object type methods ?? 078 public MappingSet getMappings(ObjectType targetType) { 079 080 if (this.objectTypeMappings.containsKey(targetType)) { 081 return this.objectTypeMappings.get(targetType); 082 } else if (this.isObjectTypeMapped(targetType)) { 083 this.objectTypeMappings.put(targetType, new MappingSet()); 084 return this.objectTypeMappings.get(targetType); 085 } else { 086 try { 087 //we haven't got the lazy load working here yet 088 this.reinitialize(); 089 } catch (DAOException ex) { 090 LOGGER.warn("failed to reinitialize a feature by accessing database", ex); 091 } 092 return this.objectTypeMappings.get(targetType); 093 } 094 } 095 096 public Boolean addMapping(Mapping mapping) { 097 098 // //check we haven't already added a mapping for an object with this id! 099 // if (mapping.getTarget() != null) { 100 // 101 // for (Mapping m : this.mappings) { 102 // if (m.getTarget() != null && m.getTarget().getId().equals(mapping.getTarget().getId())) { 103 // return; 104 // } 105 // } 106 // } 107 108 //if we fail to add the mapping this will be false 109 if (this.mappings.add((Mapping) mapping)) { 110 111 ObjectType t = mapping.getTargetType(); 112 113 if (t != null) { 114 if (!this.objectTypeMappings.containsKey(t)) { 115 this.objectTypeMappings.put(t, new MappingSet()); 116 } 117 118 this.objectTypeMappings.get(t).add((Mapping) mapping); 119 } 120 return true; 121 } 122 123 return false; 124 125 } 126 127 public void addMappedObjectType(ObjectType mappedType) { 128 mappedObjectTypes.add(mappedType); 129 } 130 131 public Boolean isObjectTypeMapped(ObjectType mappedType) { 132 return mappedObjectTypes.contains(mappedType); 133 } 134 135 // can there be more than one of these? 136 public MappingSet getTopLevelMappings() throws DAOException { 137 138 CoordinateSystem topCS = null; 139 MappingSet out = new MappingSet(); 140 141 if (this.getDaoFactory()==null) { 142 throw new DAOException("No DAOFactory Set on this DAFeature"); 143 } 144 145 try { 146 if (this.getDaoFactory().getDBType().equals(EnsemblDBType.core)) { 147 148 topCS = ((SingleSpeciesCoreDatabase) this.getDaoFactory().getDatabase()).getTopLevelCoordSystem(); 149 150 } else if (this.getDaoFactory().getDBType().equals(EnsemblDBType.collection_core)) { 151 topCS = ((CollectionCoreDatabase) this.getDaoFactory().getDatabase()).getTopLevelCS(this.getSpecies()); 152 153 } 154 } catch (DAOException dex) { 155 LOGGER.warn("Failed to get the top level coordinate System for a Feature " 156 +this.getClass().getSimpleName()+ " "+this.getId(), dex); 157 throw dex; 158 } catch (Exception ex) { 159 LOGGER.warn("Failed to get the top level coordinate System for a Feature " 160 +this.getClass().getSimpleName()+ " "+this.getId(), ex); 161 throw new DAOException("Failed to retrieve top level CoordinateSystem for this CoreDatabase", ex); 162 } 163 164 if (topCS != null) { 165 166 out = this.getMappings(topCS.getType()); 167 this.addMappedObjectType(topCS.getType()); 168 } else { 169 return null; 170 } 171 172 173 return out; 174 } 175 176 /** 177 * Utility method to pull back a single mapping of this Feature on a Given chromosome. 178 * This should be the mapping stored at initialisation. 179 * If the Feature has implemented a resinitialize method this may be called. 180 * @param chr 181 * @return a single Mapping 182 */ 183 public Mapping getChromosomeMapping(Chromosome chr) { 184 185 if (chr==null) { 186 return null; 187 } 188 MappingSet s = this.getMappings(EnsemblCoordSystemType.chromosome); 189 for (Mapping m : s) { 190 if (m.getTarget()==chr) { 191 return m; 192 } 193 } 194 return null; 195 } 196 197 public MappingSet getAnnotationLevelMappings() throws DAOException { 198 199 if (this.getDaoFactory()==null) { 200 throw new DAOException("No DAOFactory Set on this DAFeature"); 201 } 202 203 Set<? extends CoordinateSystem> annotCS = null; 204 205 try { 206 if (this.getDaoFactory().getDBType().equals(EnsemblDBType.core)) { 207 208 annotCS = ((SingleSpeciesCoreDatabase) this.getDaoFactory().getDatabase()).getCSForFeature(this.getType()); 209 210 } else if (this.getDaoFactory().getDBType().equals(EnsemblDBType.collection_core)) { 211 annotCS = ((CollectionCoreDatabase) this.getDaoFactory().getDatabase()) 212 .getCSForFeature(this.getSpecies(),this.getType()); 213 } 214 } catch (DAOException dex) { 215 LOGGER.warn("Failed to get the annotation level coordinate System for a Feature " 216 +this.getClass().getSimpleName()+ " "+this.getId(), dex); 217 throw dex; 218 } catch (Exception ex) { 219 LOGGER.warn("Failed to get the annotation level coordinate System for a Feature " 220 +this.getClass().getSimpleName()+ " "+this.getId(), ex); 221 throw new DAOException("Failed to retrieve annotation level CoordinateSystem for this CoreDatabase", ex); 222 } 223 224 if (annotCS==null || annotCS.isEmpty()) { 225 LOGGER.warn("Failed to get the annotation level coordinate System for a Feature " 226 +this.getClass().getSimpleName()+ " "+this.getId()); 227 return null; 228 } 229 230 MappingSet out = new MappingSet(); 231 232 for (CoordinateSystem cs : annotCS ) { 233 234 MappingSet t = this.getMappings(cs.getType()); 235 this.addMappedObjectType(cs.getType()); 236 if (t != null) { 237 out.addAll(t); 238 } 239 240 } 241 242 return out; 243 } 244 245 public MappingSet getBuildLevelMappings() throws DAOException{ 246 247 if (this.getDaoFactory()==null) { 248 throw new DAOException("No DAOFactory Set on this DAFeature"); 249 } 250 251 MappingSet out = new MappingSet(); 252 CoordinateSystem buildCS = null; 253 254 try { 255 if (this.getDaoFactory().getDBType().equals(EnsemblDBType.core)) { 256 257 buildCS = ((SingleSpeciesCoreDatabase) this.getDaoFactory().getDatabase()).getBuildCoordSystem(this.getType().toString()); 258 259 } else if (this.getDaoFactory().getDBType().equals(EnsemblDBType.collection_core)) { 260 buildCS = ((CollectionCoreDatabase) this.getDaoFactory().getDatabase()).getBuildCoordSystem(this.getSpecies(),this.getType().toString() ); 261 262 } 263 } catch (DAOException dex) { 264 LOGGER.warn("Failed to get the build level coordinate system for this database " 265 +this.getClass().getSimpleName()+ " "+this.getId(), dex); 266 throw dex; 267 } catch (Exception ex) { 268 LOGGER.warn("Failed to get the build level coordinate system for this database " 269 +this.getClass().getSimpleName()+ " "+this.getId(), ex); 270 throw new DAOException("Failed to retrieve build level CoordinateSystem for this CoreDatabase", ex); 271 } 272 273 if (buildCS != null) { 274 275 out = this.getMappings(buildCS.getType()); 276 this.addMappedObjectType(buildCS.getType()); 277 } else { 278 return null; 279 } 280 281 return out; 282 } 283 284 public void clearAllMappings() { 285 mappings.clear(); 286 mappedObjectTypes.clear(); 287 objectTypeMappings.clear(); 288 } 289 290 public String getDescription() { 291 return description; 292 } 293 294 public void setDescription(String description) { 295 this.description = description; 296 } 297 298 public Date getCreationDate() { 299 return creationDate; 300 } 301 302 public void setCreationDate(Date creationDate) { 303 this.creationDate = creationDate; 304 } 305 306 public Date getModificationDate() { 307 return modificationDate; 308 } 309 310 public void setModificationDate(Date modificationDate) { 311 this.modificationDate = modificationDate; 312 } 313 314 public DAXRef getDisplayXRef() { 315 return displayXRef; 316 } 317 318 public void setDisplayXRef(DAXRef xref) { 319 this.displayXRef = xref; 320 if (xref!=null) { 321 this.xrefs.add(xref); 322 } 323 } 324 325 public List<DAXRef> getXRefs() { 326 return xrefs; 327 } 328 329 public void addXRefs(List<DAXRef> xrefs) { 330 this.xrefs.addAll(xrefs); 331 } 332 333 abstract void reinitialize() throws DAOException ; 334 335 public static enum Status { 336 KNOWN, 337 NOVEL, 338 PUTATIVE, 339 PREDICTED, 340 KNOWN_BY_PROJECTION, 341 UNKNOWN; 342 } 343 344 public String getStatus() { 345 return this.status.toString(); 346 } 347 348 public void setStatus(String status) { 349 try { 350 this.status = Status.valueOf(status); 351 } catch (IllegalArgumentException e) { 352 this.status = Status.UNKNOWN; 353 } 354 } 355 356 public String getDisplayName() { 357 return displayName ; 358 } 359 360 public void setDisplayName(String displayName) { 361 this.displayName = displayName; 362 } 363 364 public Boolean isCurrent() { 365 return current; 366 } 367 368 public void setCurrent(Boolean current) { 369 this.current = current; 370 } 371 372 }