/*
* 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