/* * EuroCarbDB, a framework for carbohydrate bioinformatics * * Copyright (c) 2006-2009, Eurocarb project, or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU * Lesser General Public License, as published by the Free Software Foundation. * A copy of this license accompanies this distribution in the file LICENSE.txt. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * for more details. * * Last commit: $Rev: 1870 $ by $Author: david@nixbioinf.org $ on $Date:: 2010-02-23 #$ */ package org.eurocarbdb.dataaccess.core; // stdlib imports import java.util.Set; import java.util.List; import java.util.Date; import java.util.HashSet; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.io.Serializable; // 3rd party imports import org.apache.log4j.Logger; // eurocarb imports import org.eurocarbdb.dataaccess.BasicEurocarbObject; import org.eurocarbdb.dataaccess.Contributed; // static imports import static org.eurocarbdb.util.JavaUtils.checkNotNull; /* class BiologicalContext *//************************************* *<p> * A biological context represents a collation of biological source * information. A biological context is presently defined as: * 1 {@link Taxonomy}, 1 {@link TissueTaxonomy}, 0-many {@link Disease}s, * 0-many {@link Perturbation}s, and 0-many {@link Glycoconjugate}s. *</p> *<p> * *</p> * * @see Taxonomy * @see TissueTaxonomy * @see Disease * @see Perturbation * @see Glycoconjugate * * @author mjh */ public class BiologicalContext extends BasicEurocarbObject implements Cloneable, Serializable { //~~~~~~~~~~~~~~~~~~~~~~ STATIC FIELDS ~~~~~~~~~~~~~~~~~~~~~~~~// /** Logging handle. */ static final Logger log = Logger.getLogger( BiologicalContext.class ); //~~~~~~~~~~~~~~~~~~~~~~~~~~ FIELDS ~~~~~~~~~~~~~~~~~~~~~~~~~~~// /** Canonical id */ private int biologicalContextId; /** Date this context was entered into the data store - this value * is auto-generated by the database! */ private Date dateEntered; /** The taxonomy comprising this context. */ private Taxonomy taxonomy; /** The tissue taxonomy comprising this context. */ private TissueTaxonomy tissue; /** The {@link Contributor} of this context. */ private Set<BiologicalContextContributor> biologicalContextContributors=new HashSet<BiologicalContextContributor>(0); public BiologicalContextContributor getBiologicalContextContributor(int contributorId){ for(BiologicalContextContributor bcc: this.biologicalContextContributors) if( bcc.getContributor().getContributorId() == contributorId) return bcc; return null; } public Set getBiologicalContextContributors() { return this.biologicalContextContributors; } public void setBiologicalContextContributors(Set biologicalContextContributors) { this.biologicalContextContributors = biologicalContextContributors; } /** The set of (0-*) diseases comprising this context. */ private Set<DiseaseContext> diseaseContexts = new HashSet<DiseaseContext>(0); /** The set of (0-*) perturbations comprising this context. */ private Set<PerturbationContext> perturbationContexts = new HashSet<PerturbationContext>(0); /** The set of (0-*) glycoconjugates comprising this context. */ private Set<Glycoconjugate> glycoconjugates = new HashSet<Glycoconjugate>(0); /** The set of (1-*) sequence contexts associated to this context. */ private Set<GlycanSequenceContext> sequenceContexts = new HashSet<GlycanSequenceContext>(0); /** The set of (0-*) experimentContexts associated to this context. * Not publically exposed at all (yet). */ private Set<ExperimentContext> experimentContexts = new HashSet<ExperimentContext>(0); /** The set of (0-*) evidenceContexts associated to this context. */ private Set<EvidenceContext> evidenceContexts = new HashSet<EvidenceContext>(0); //~~~~~~~~~~~~~~~~~~~~~~~ CONSTRUCTORS ~~~~~~~~~~~~~~~~~~~~~~~~// /** Default constructor. */ public BiologicalContext() { // this( Taxonomy.UnknownTaxonomy(), TissueTaxonomy.UnknownTissue() ); } /** A minimal constructor. */ public BiologicalContext( Taxonomy taxonomy, TissueTaxonomy tissue ) { checkNotNull( taxonomy ); checkNotNull( tissue ); this.taxonomy = taxonomy; this.tissue = tissue; } /** * Returns the {@link Set} of {@link BiologicalContext}s that have * a unique combination of {@link BiologicalContextAssociation}s (that * is, a unique combination of {@link Taxonomy}, {@link TissueTaxonomy}, * {@link Disease}, and {@link Perturbation}). */ /* in development; don't use me yet */ static Collection<BiologicalContext> getUniqueContextsIgnoreId( Collection<BiologicalContext> contexts ) { try { Collection c = contexts.getClass().newInstance(); /* Map map = new HashMap(); for ( ) for ( BiologicalContextAssociation bca : ) */ return c; } catch ( Exception e ) { return null; } } //~~~~~~~~~~~~~~~~~~~~~~~~~ METHODS ~~~~~~~~~~~~~~~~~~~~~~~~~~~// /** * Associates the passed Disease object with this biological * context. */ public void addDiseaseAssociation( Disease d ) { assert d != null; DiseaseContext dc = new DiseaseContext(); dc.setDisease( d ); dc.setBiologicalContext( this ); this.getDiseaseContexts().add( dc ); } /** * Associates the passed Perturbation object with this biological * context. */ public void addPerturbationAssociation( Perturbation p ) { assert p != null; PerturbationContext pc = new PerturbationContext(); pc.setPerturbation( p ); pc.setBiologicalContext( this ); this.getPerturbationContexts().add( pc ); } /* clone *//*************************************************** * * Returns a shallow copy of this biological context, but with * biological context id set to zero. */ public Object clone() { BiologicalContext copy = null; try { copy = (BiologicalContext) super.clone(); } catch ( CloneNotSupportedException ignored ) {} // clear BioCon id copy.biologicalContextId = 0; return copy; } /* getBiologicalContextId *//********************************** * * Returns the canonical id for this biological context. This * value may be equal to zero if this biological context has not * been saved to a data store. */ public int getBiologicalContextId() { return this.biologicalContextId; } /** Returns the contributor of this evidence. */ // public Contributor getContributor() // { // if ( this.contributor == null ) // this.contributor = Contributor.getCurrentContributor(); // // return this.contributor; // } /** Sets the contributor of this evidence. */ // public void setContributor( Contributor c ) // { // checkNotNull( c ); // this.contributor = c; // } /** Returns the date this context was created in the data store. */ public Date getDateEntered() { return dateEntered; } /* getTissueTaxonomy *//*************************************** * * Returns the tissue taxonomy that forms part of this biological * context. */ public TissueTaxonomy getTissueTaxonomy() { if ( this.tissue == null ) this.tissue = TissueTaxonomy.UnknownTissue(); return this.tissue; } /* setTissueTaxonomy *//*************************************** * * Sets the tissue taxonomy component of this biological context. */ public void setTissueTaxonomy( TissueTaxonomy t ) { assert t != null; this.tissue = t; } /* getTaxonomy *//********************************************* * * Returns the taxonomy that forms part of this biological * context. */ public Taxonomy getTaxonomy() { if ( this.taxonomy == null ) this.taxonomy = Taxonomy.UnknownTaxonomy(); return this.taxonomy; } /* setTaxonomy *//********************************************* * * Sets the taxonomy component of this biological context. */ public void setTaxonomy( Taxonomy taxonomy ) { this.taxonomy = taxonomy; } /* appendComment *//******************************************* * * Appends the given comment onto existing comments for this context. * This method simply appends the given text directly to existing * comments but future revisions of this method might add a * timestamp/user header to the comment upon appending. */ // public void appendComment( String comment ) // { // String text = comment.trim(); // assert text != null; // assert text.length() > 0; // if ( log.isDebugEnabled() ) // log.debug( "appending the following comment to biological context:\n" // + text // ); // // setComments( getComments() + "\n\n" + text ); // } /* getComments *//********************************************* * * Returns any/all user comments provided for this biological * context at its time of creation. */ // public String getComments() // { // return this.comments; // } /* setComments *//********************************************* * * Sets a string comment for this biological context. */ // public void setComments( String comments ) // { // this.comments = comments; // } /* getDiseases *//********************************************* * * Returns the unmodifiable {@link List} of the 0-many {@link Disease}s * that comprise part of this biological context. This may range from * no diseases (an empty list) to several diseases. */ public List<Disease> getDiseases() { Set<DiseaseContext> dc_list = this.getDiseaseContexts(); if ( dc_list == null || dc_list.size() == 0 ) return Collections.emptyList(); List<Disease> d_list = new ArrayList<Disease>( dc_list.size() ); for ( DiseaseContext dc : dc_list ) d_list.add( dc.getDisease()); return d_list; } public Set<DiseaseContext> getDiseaseContexts() { return this.diseaseContexts; } public List<DiseaseContext> getDiseaseContextsList() { return new ArrayList<DiseaseContext>(this.diseaseContexts); } /* setDiseases *//********************************************* * * Sets the set of diseases that are a component of this biological * context. */ public void setDiseaseContexts( Set<DiseaseContext> diseaseContexts ) { this.diseaseContexts = diseaseContexts; } /* getGlycanSequences *//************************************** * * Returns the set of all glycan sequences that have equivalent * biological contexts to this one. That is, all sequences that * are associated with the same taxonomy, tissue taxonomy, diseases, * perturbations, and glycoconjugates that comprise this biological * context. * * @see Taxonomy * @see TissueTaxonomy * @see Disease * @see Perturbation * @see Glycoconjugate */ public Set<GlycanSequence> getGlycanSequences() { Set<GlycanSequence> sequences = new HashSet<GlycanSequence>(); for (GlycanSequenceContext context : getGlycanSequenceContexts()) { sequences.add(context.getGlycanSequence()); } return sequences; } /* getGlycanSequenceContexts *//******************************* * * Returns the set of glycan sequence contexts that are associated * with exactly this biological context. */ public Set<GlycanSequenceContext> getGlycanSequenceContexts() { return this.sequenceContexts; } /* setGlycanSequenceContexts *//******************************* * * Sets the set of glycan sequence contexts that are associated * with this biological context. */ public void setGlycanSequenceContexts( Set<GlycanSequenceContext> sequenceContexts ) { this.sequenceContexts = sequenceContexts; } public List<Perturbation> getPerturbations() { Set<PerturbationContext> pc_list = this.getPerturbationContexts(); if ( pc_list == null || pc_list.size() == 0 ) return new ArrayList<Perturbation>(); List<Perturbation> p_list = new ArrayList<Perturbation>( pc_list.size() ); for ( PerturbationContext pc : pc_list ) p_list.add( pc.getPerturbation()); return p_list; } /* getPerturbationContexts *//**************************************** * * Gets the set of perturbationContexts that form part of this biological * context. This may range from no perturbationContexts (an empty set) * to several. */ public Set<PerturbationContext> getPerturbationContexts() { return this.perturbationContexts; } /* setPerturbationContexts *//**************************************** * * Sets the set of perturbationContexts that form part of this biological * context. */ public void setPerturbationContexts( Set<PerturbationContext> perturbationContexts ) { this.perturbationContexts = perturbationContexts; } /* getGlycoconjugates *//************************************** * * Gets the set of glycoconjugates that form part of this biological * context. This may range from none (an empty set) to several. */ public Set<Glycoconjugate> getGlycoconjugates() { return this.glycoconjugates; } /* setGlycoconjugates *//************************************** * * Sets the set of glycoconjugates that form part of this biological * context. */ public void setGlycoconjugates( Set<Glycoconjugate> glycoconjugates ) { this.glycoconjugates = glycoconjugates; } /* hasAssociatedDiseases *//*********************************** * * Returns true if this biological context comprises no disease * associations. * * @see #HAS_NO_DISEASES */ public boolean hasAssociatedDiseases() { return diseaseContexts != null && diseaseContexts.size() > 0 ; } /* hasAssociatedPerturbations *//****************************** * * Returns true if this biological context comprises no perturbation * associations. * * @see #HAS_NO_DISEASES */ public boolean hasAssociatedPerturbations() { return perturbationContexts != null && perturbationContexts.size() > 0 ; } /* hasAssociatedGlycoconjugates *//**************************** * * Returns true if this biological context comprises no glycoconjugate * associations. */ public boolean hasAssociatedGlycoconjugates() { return glycoconjugates != null && glycoconjugates.size() > 0 ; } static public boolean haveSameContent( BiologicalContext a, BiologicalContext b ) { if( a==null || b==null ) return false; if( a.getBiologicalContextId()==b.getBiologicalContextId() ) return true; // compare taxonomy if( a.getTaxonomy().getTaxonomyId()!=b.getTaxonomy().getTaxonomyId() ) return false; // compare tisse if( a.getTissueTaxonomy().getTissueTaxonomyId()!=b.getTissueTaxonomy().getTissueTaxonomyId() ) return false; // compare diseases List<Disease> dal = a.getDiseases(); List<Disease> dbl = b.getDiseases(); for( Disease da : dal ) { if( !dbl.contains(da) ) return false; } // compare perturbations List<Perturbation> pal = a.getPerturbations(); List<Perturbation> pbl = b.getPerturbations(); for( Perturbation pa : pal ) { if( !pbl.contains(pa) ) return false; } return true; } //~~~~~~~~~~~~~~~~~~~~~~ PRIVATE METHODS ~~~~~~~~~~~~~~~~~~~~~~// /* setBiologicalContextId *//********************************** * * Sets the canonical id for this biological context. This * method should not generally be used by client code directly. */ void setBiologicalContextId( int biologicalContextId ) { this.biologicalContextId = biologicalContextId; } /* getExperimentContexts *//*********************************** * * Gets all experimentContexts that are associated with solely this * biological context. */ Set<ExperimentContext> getExperimentContexts() { return this.experimentContexts; } /* setExperimentContexts *//*********************************** * * Sets the set of all experimentContexts that will be associated with * this biological context. */ void setExperimentContexts( Set<ExperimentContext> experimentContexts ) { this.experimentContexts = experimentContexts; } /* getEvidenceContexts *//************************************* * * Gets an unmodifiable {@link Set} of all {@link EvidenceContext}s * that are associated with solely this {@link BiologicalContext}. * Note that biological contexts are not necessarily unique by value. */ Set<EvidenceContext> getEvidenceContexts() { return this.evidenceContexts; } /* setEvidenceContexts *//************************************* * * Sets the set of all evidenceContexts that will be associated with * this biological context. */ void setEvidenceContexts( Set<EvidenceContext> evidenceContexts ) { this.evidenceContexts = evidenceContexts; } public String toString() { return "[BiologicalContext=" + getBiologicalContextId() + "; taxonomy=" + (( taxonomy != null ) ? taxonomy.getTaxonomyId() : "null" ) + "; tissue=" + (( tissue != null ) ? tissue.getTissueTaxonomyId() : "null" ) + "]" ; } public void validate() { // check that taxonomy and tissue are set if ( this.taxonomy == null ) { log.warn("no taxonomy explicitly set for BiologicalContext," + " setting to UnknownTaxonomy"); this.taxonomy = Taxonomy.UnknownTaxonomy(); } if ( this.tissue == null ) { log.warn("no tissue explicitly set for BiologicalContext," + " setting to UnknownTissue"); this.tissue = TissueTaxonomy.UnknownTissue(); } } public void addContributor(Contributor contributor,String comment){ if(this.getBiologicalContextContributor(contributor.getContributorId())==null){ BiologicalContextContributor bcc=new BiologicalContextContributor(contributor,this); bcc.appendComment(comment); this.biologicalContextContributors.add(bcc); } } } // end class