package org.nextprot.api.commons.bio.variation.prot;
import com.google.common.base.Preconditions;
import org.nextprot.api.commons.bio.AminoAcidCode;
import org.nextprot.api.commons.bio.variation.prot.impl.seqchange.AminoAcidModification;
import org.nextprot.api.commons.bio.variation.prot.seqchange.SequenceChange;
/**
* Fluent interface for building a <code>SequenceVariation</code>
*
* Created by fnikitin on 09/07/15.
*/
public interface SequenceVariationBuilder {
/** build an instance of SequenceVariation */
SequenceVariation build();
/** collect data through the process */
DataCollector getDataCollector();
/** start fluent building */
interface FluentBuilding {
/** select a single affected amino-acid residue */
ChangingAminoAcid selectAminoAcid(AminoAcidCode affectedAA, int affectedAAPos);
/** select a range of affected amino-acid residues */
ChangingAminoAcidRange selectAminoAcidRange(AminoAcidCode firstAffectedAA, int firstAffectedAAPos, AminoAcidCode lastAffectedAA, int lastAffectedAAPos);
}
/** mutations affecting only one amino-acid */
interface ChangingAminoAcid extends ChangingAminoAcidRange {
/** substitutedBy an amino-acid by another one */
SequenceVariationBuilder thenSubstituteWith(AminoAcidCode aa);
/** A frameshift appears just after the affected amino-acid leading to a codon stop in this frame */
SequenceVariationBuilder thenFrameshift(AminoAcidCode newAminoAcidCode, int newTerminationPosition);
/** modifies affected amino-acid with modification */
SequenceVariationBuilder thenAddModification(AminoAcidModification modification);
/** change translation initiation (start of stop codon) extending the normal translational reading frame at the
* N- or C-terminal end with one or more amino acids */
SequenceVariationBuilder thenInitiationExtension(int newUpstreamInitPos, AminoAcidCode newAminoAcidCode);
SequenceVariationBuilder thenTerminationExtension(int newDownstreamTermPos, AminoAcidCode newVariantTermAminoAcidCode);
}
/** mutations affecting any sequence of amino-acid */
interface ChangingAminoAcidRange {
/** delete all affected amino-acids */
SequenceVariationBuilder thenDelete();
/** inserts given aas after specific AA */
SequenceVariationBuilder thenInsert(AminoAcidCode... aas);
/** duplicates changing aas and insert right after */
SequenceVariationBuilder thenDuplicate();
/** delete all affected amino-acids and inserts given aas */
SequenceVariationBuilder thenDeleteAndInsert(AminoAcidCode... aas);
}
/**
* Collect data to build SequenceVariation
*/
class DataCollector {
private AminoAcidCode firstChangingAminoAcid;
private int firstChangingAminoAcidPos;
private AminoAcidCode lastChangingAminoAcid;
private int lastChangingAminoAcidPos;
private SequenceChange<?> sequenceChange;
public void setFirstChangingAminoAcid(AminoAcidCode firstAffectedAminoAcid, int firstAffectedAminoAcidPos) {
Preconditions.checkNotNull(firstAffectedAminoAcid);
Preconditions.checkArgument(firstAffectedAminoAcidPos > 0);
this.firstChangingAminoAcid = firstAffectedAminoAcid;
this.firstChangingAminoAcidPos = firstAffectedAminoAcidPos;
}
public AminoAcidCode getFirstChangingAminoAcid() {
return firstChangingAminoAcid;
}
public int getFirstChangingAminoAcidPos() {
return firstChangingAminoAcidPos;
}
public void setLastChangingAminoAcid(AminoAcidCode lastAffectedAminoAcid, int lastAffectedAminoAcidPos) {
Preconditions.checkNotNull(firstChangingAminoAcid);
Preconditions.checkArgument(firstChangingAminoAcidPos > 0);
this.lastChangingAminoAcid = lastAffectedAminoAcid;
this.lastChangingAminoAcidPos = lastAffectedAminoAcidPos;
}
public AminoAcidCode getLastChangingAminoAcid() {
return lastChangingAminoAcid;
}
public int getLastChangingAminoAcidPos() {
return lastChangingAminoAcidPos;
}
public SequenceChange<?> getSequenceChange() {
return sequenceChange;
}
public void setSequenceChange(SequenceChange<?> sequenceChange) {
this.sequenceChange = sequenceChange;
}
}
}