import java.util.HashSet;
import java.util.Set;
+import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.ManyToMany;
import javax.persistence.ManyToOne;
+import javax.persistence.OneToMany;
import javax.persistence.Transient;
-import javax.validation.constraints.Size;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlIDREF;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlSchemaType;
+import javax.xml.bind.annotation.XmlTransient;
import javax.xml.bind.annotation.XmlType;
import org.apache.log4j.Logger;
"boldProcessId",
"haplotype",
"contigFile",
- "singleReads",
+ "singleReadAlignments",
"citations"
})
@XmlRootElement(name = "Sequencing")
@XmlIDREF
@XmlSchemaType(name = "IDREF")
@ManyToOne(fetch = FetchType.LAZY)
- @Cascade({CascadeType.SAVE_UPDATE})
+ @Cascade({CascadeType.SAVE_UPDATE,CascadeType.MERGE})
private Media contigFile;
/** @see #getConsensusSequence() */
/** @see #getGeneticAccessionNumber()*/
@XmlElement(name = "GeneticAccessionNumber")
- @Size(max=20)
+ @Column(length=20)
private String geneticAccessionNumber;
/** @see #getBoldProcessId() */
@XmlElement(name = "BoldProcessId")
- @Size(max=20)
+ @Column(length=20)
private String boldProcessId;
- @XmlElementWrapper(name = "SingleReads")
- @XmlElement(name = "SingleRead")
+ @XmlElementWrapper(name = "SingleReadAlignments")
+ @XmlElement(name = "SingleReadAlignment")
@XmlIDREF
@XmlSchemaType(name = "IDREF")
- @ManyToMany(fetch = FetchType.LAZY)
- @Cascade({CascadeType.SAVE_UPDATE})
- private Set<SingleRead> singleReads = new HashSet<SingleRead>();
+ @OneToMany(mappedBy="consensusAlignment", fetch = FetchType.LAZY, orphanRemoval=true)
+ @Cascade({CascadeType.SAVE_UPDATE,CascadeType.MERGE})
+ private Set<SingleReadAlignment> singleReadAlignments = new HashSet<SingleReadAlignment>();
/** @see #getDnaMarker() */
@XmlElement(name = "DnaMarker")
/** @see #getHaplotype() */
@XmlElement(name = "Haplotype")
- @Size(max=100)
+ @Column(length=100)
private String haplotype;
/** @see #getCitations() */
@XmlIDREF
@XmlSchemaType(name = "IDREF")
@ManyToMany(fetch = FetchType.LAZY)
- @Cascade({CascadeType.SAVE_UPDATE})
+ @Cascade({CascadeType.SAVE_UPDATE,CascadeType.MERGE})
private Set<Reference> citations = new HashSet<Reference>();
// //should be calculated in case sequence is set
* @see #getConsensusSequence()
* @see #getContigFile()
*/
- public Set<SingleRead> getSingleReads() {
- return singleReads;
+ public Set<SingleReadAlignment> getSingleReadAlignments() {
+ return singleReadAlignments;
}
/**
* @see #getSingleReads()
*/
- public void addSingleRead(SingleRead singleRead) {
- this.singleReads.add(singleRead);
+ public void addSingleReadAlignment(SingleReadAlignment singleReadAlignment) {
+ this.singleReadAlignments.add(singleReadAlignment);
+ if (! this.equals(singleReadAlignment.getConsensusSequence())){
+ singleReadAlignment.setConsensusAlignment(this);
+ };
}
/**
* @see #getSingleReads()
*/
+ public void removeSingleReadAlignment(SingleReadAlignment singleReadAlignment) {
+ this.singleReadAlignments.remove(singleReadAlignment);
+ if (this.equals(singleReadAlignment.getConsensusSequence())){
+ singleReadAlignment.setConsensusAlignment(null);
+ singleReadAlignment.setSingleRead(null);
+ }
+ }
+// /**
+// * @see #getSingleReads()
+// */
+// //TODO private as long it is unclear how bidirectionality is handled
+// @SuppressWarnings("unused")
+// private void setSingleReadAlignments(Set<SingleReadAlignment> singleReadAlignments) {
+// this.singleReadAlignments = singleReadAlignments;
+// }
+
+// *********************** CONVENIENCE ***********************************/
+
+ /**
+ * Convenience method to add a single read to a consensus sequence
+ * by creating a {@link SingleReadAlignment}.
+ * @param singleRead the {@link SingleRead} to add
+ * @return the created SingleReadAlignment
+ */
+ public SingleReadAlignment addSingleRead(SingleRead singleRead) {
+ SingleReadAlignment alignment = SingleReadAlignment.NewInstance(this, singleRead);
+ return alignment;
+ }
+
public void removeSingleRead(SingleRead singleRead) {
- this.singleReads.remove(singleRead);
+ Set<SingleReadAlignment> toRemove = new HashSet<SingleReadAlignment>();
+ for (SingleReadAlignment align : this.singleReadAlignments){
+ if (align.getSingleRead() != null && align.getSingleRead().equals(singleRead)){
+ toRemove.add(align);
+ }
+ }
+ for (SingleReadAlignment align : toRemove){
+ removeSingleReadAlignment(align);
+ }
+ return;
}
+
/**
- * @see #getSingleReads()
+ * Convenience method that returns all single reads this consensus sequence
+ * is based on via {@link SingleReadAlignment}s.
+ * @return set of related single reads
*/
- //TODO private as long it is unclear how bidirectionality is handled
- private void setSingleReads(Set<SingleRead> singleReads) {
- this.singleReads = singleReads;
+ @XmlTransient
+ @Transient
+ public Set<SingleRead> getSingleReads(){
+ Set<SingleRead> singleReads = new HashSet<SingleRead>();
+ for (SingleReadAlignment align : this.singleReadAlignments){
+ if (align.getSingleRead() != null){ // == null should not happen
+ singleReads.add(align.getSingleRead());
+ }
+ }
+ return singleReads;
}
@Transient
public Set<Media> getPherograms(){
Set<Media> result = new HashSet<Media>();
- for (SingleRead singleSeq : singleReads){
- if (singleSeq.getPherogram() != null){
- result.add(singleSeq.getPherogram());
+ for (SingleReadAlignment singleReadAlign : singleReadAlignments){
+ if (singleReadAlign.getSingleRead() != null && singleReadAlign.getSingleRead().getPherogram() != null){
+ result.add(singleReadAlign.getSingleRead().getPherogram());
}
}
return result;
//single sequences
- result.singleReads = new HashSet<SingleRead>();
- for (SingleRead seq: this.singleReads){
- result.singleReads.add(seq);
+ result.singleReadAlignments = new HashSet<SingleReadAlignment>();
+ for (SingleReadAlignment singleReadAlign: this.singleReadAlignments){
+ SingleReadAlignment newAlignment = (SingleReadAlignment)singleReadAlign.clone();
+ result.singleReadAlignments.add(newAlignment);
}
//citations //TODO do we really want to copy these ??
result.citations = new HashSet<Reference>();
- for (Reference ref: this.citations){
+ for (Reference<?> ref: this.citations){
result.citations.add(ref);
}