package org.gmod.schema.feature;
import org.genedb.db.analyzers.AllNamesAnalyzer;
import org.genedb.db.analyzers.AlphaNumericAnalyzer;
import org.gmod.schema.mapped.Feature;
import org.gmod.schema.mapped.FeatureRelationship;
import org.gmod.schema.mapped.Organism;
import org.gmod.schema.mapped.Synonym;
import org.apache.log4j.Logger;
import org.hibernate.search.annotations.Analyzer;
import org.hibernate.search.annotations.Field;
import org.hibernate.search.annotations.Index;
import org.hibernate.search.annotations.Store;
import org.springframework.util.StringUtils;
import com.google.common.collect.Lists;
import java.sql.Timestamp;import java.util.List;
import javax.persistence.Entity;
import javax.persistence.Transient;
/**
* A transcript that may have products associated with it, i.e. an mRNA or
* a PseudogenicTranscript.
*
* @author rh11
*/
@Entity
public abstract class ProductiveTranscript extends Transcript {
private transient Logger logger = Logger.getLogger(ProductiveTranscript.class);
ProductiveTranscript() {
// empty
}
public ProductiveTranscript(Organism organism, String uniqueName, boolean analysis,
boolean obsolete, Timestamp dateAccessioned) {
super(organism, uniqueName, analysis, obsolete, dateAccessioned);
}
/**
* Return the uniqueName of the associated polypeptide.
*
* Indexed as <code>protein</code> in the Lucene index.
*
* @return the uniqueName of the associated polypeptide
*/
@Transient
@Field(name = "protein", store = Store.YES)
public String getProteinUniqueName() {
Feature protein = getProtein();
if (protein == null) {
return null;
}
return protein.getUniqueName();
}
/**
* Get the associated polypeptide feature.
*
* A pseudogenic transcript may or may not have an associated
* polypeptide.Every mRNA transcript should have one, though this
* constraint cannot be enforced at the database level, so in practice
* this method may return <code>null</code> even for an mRNA, which
* indicates a curation issue with that transcript.
*
* @return
*/
@Transient
public Polypeptide getProtein() {
// Note: Overridden on MRNA to complain if there isn't a protein.
return getProteinWithoutComplaining();
}
/**
* Get the associated polypeptide, but don't worry if there isn't one.
* This method is used internally while the gene model is being built,
* and should not be public.
*
* @return
*/
protected final Polypeptide getProteinWithoutComplaining() {
for (FeatureRelationship relation : getFeatureRelationshipsForObjectId()) {
Feature feature = relation.getSubjectFeature();
// if (feature instanceof HibernateProxy) {
// feature = (Feature) ((HibernateProxy) feature).getHibernateLazyInitializer().getImplementation();
// }
if (feature instanceof Polypeptide) {
return (Polypeptide) feature;
}
}
return null;
}
@Transient
public void setProtein(Polypeptide polypeptide) {
if (getProteinWithoutComplaining() != null) {
throw new RuntimeException(String.format(
"Attempting to set a protein on transcript '%s' which already has one",
getUniqueName()));
}
addFeatureRelationship(polypeptide, "sequence", "derives_from");
}
@Transient
public List<String> getProducts() {
Polypeptide protein = getProtein();
if (protein == null) {
return null;
}
return protein.getProducts();
}
@Transient
@Analyzer(impl = AllNamesAnalyzer.class)
@Field(name = "product", index = Index.TOKENIZED, store = Store.YES)
public String getProductsAsSpaceSeparatedString() {
Polypeptide protein = getProtein();
if (protein != null) {
return protein.getProductsAsSpaceSeparatedString();
}
return null;
}
@Transient
@Analyzer(impl = AllNamesAnalyzer.class)
@Field(name = "expandedProduct", index = Index.TOKENIZED, store = Store.YES)
public String getProductsAsSeparatedString() {
Polypeptide protein = getProtein();
if (protein != null) {
return protein.getProductsAsSeparatedString();
}
return null;
}
@Transient
@Analyzer(impl = AlphaNumericAnalyzer.class)
@Field(name = "productAlphanumeric", index = Index.TOKENIZED, store = Store.YES)
public String getProductsAlphanumeric(){
Polypeptide protein = getProtein();
if (protein != null) {
return protein.getProductsAlphanumeric();
}
return null;
}
@Override
@Transient
@Field(name = "colour", index = Index.UN_TOKENIZED, store = Store.YES)
public Integer getColourId() {
Polypeptide protein = getProtein();
if (protein == null) {
return null;
}
return protein.getColourId();
}
@Override
public AbstractExon createExon(String exonUniqueName, int fmin, int fmax, Integer phase) {
Polypeptide polypeptide = getProtein();
if (polypeptide != null) {
polypeptide.lowerFminTo(fmin);
polypeptide.raiseFmaxTo(fmax);
}
return super.createExon(exonUniqueName, fmin, fmax, phase);
}
@Transient
@Field(name = "allNames", index = Index.TOKENIZED, store = Store.YES)
@Analyzer(impl = AllNamesAnalyzer.class)
public String getAllTranscriptNames() {
List<String> names = Lists.newArrayList();
//gene name like say PGKC should be indexed on it's transcript
if (gene!= null && gene.getName() != null) {
names.add(gene.getName());
names.add(gene.getUniqueName());
}
if (gene!= null && gene.getSynonyms().size()>0) {
for (Synonym synonym : gene.getSynonyms()){
names.add(synonym.getName());
}
}
//Process Unique Name
String uniqueName = getUniqueName();
names.add(uniqueName);
//if say Smp_000030.1:mRNA is uniqueName, then add Smp_000030.1
int before = uniqueName.toLowerCase().indexOf(":");
if (before != -1) {
String firstPart = uniqueName.substring(0, before);
//add something like Smp_000030.1
names.add(firstPart);
}
if (this.getGene().getTranscripts().size() > 1) {
Transcript first = getGene().getFirstTranscript();
if (first.getUniqueName().equals(getUniqueName())) {
names.add(this.getGene().getUniqueName());
}
}
String ret = allNamesSupport(names);
//System.err.println("** T "+ret);
return ret;
}
}