package cyrille.hibernate.temporal.sinistre; import java.sql.Timestamp; import java.util.ArrayList; import java.util.List; import java.util.SortedSet; import java.util.TreeSet; import javax.persistence.Basic; import javax.persistence.CascadeType; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id; import javax.persistence.JoinColumn; import javax.persistence.ManyToOne; import javax.persistence.OneToMany; import javax.persistence.OneToOne; import javax.persistence.Table; import org.apache.commons.lang.builder.CompareToBuilder; import org.apache.commons.lang.builder.EqualsBuilder; import org.apache.commons.lang.builder.HashCodeBuilder; import org.apache.commons.lang.builder.ToStringBuilder; import org.hibernate.annotations.Sort; import org.hibernate.annotations.SortType; /** * <p> * Sinistre avec versionnage par pattern <a * href="http://martinfowler.com/ap2/temporalObject.html">Temporal Object</a> * </p> * * @author <a href="mailto:cleclerc@xebia.fr">Cyrille Le Clerc</a> */ @Entity @org.hibernate.annotations.Entity(mutable = true) @Table(name = "sinistre") public class SinistreFullHistory implements Comparable<SinistreFullHistory> { @Id @GeneratedValue protected Long id; @Basic @Column(name = "numero_declaration") protected String numeroDeclaration; @Basic @Column(name = "numero_sinistre") protected String numeroSinistre; @ManyToOne(optional = false) @JoinColumn(name = "last_sinistre_id", nullable = false) protected SinistreVersion lastSinistreVersion; @OneToMany(cascade = CascadeType.ALL) @JoinColumn(name = "sinistre_id") @Sort(type = SortType.NATURAL) protected SortedSet<SinistreVersion> sinistreVersions = new TreeSet<SinistreVersion>(); @OneToMany(cascade = CascadeType.ALL, mappedBy = "sinistre") protected List<Evenement> evenements = new ArrayList<Evenement>(); transient protected SinistreVersion workingCopy; public SinistreFullHistory() { super(); } public SinistreFullHistory(String numeroSinistre, String numeroDeclaration) { super(); this.numeroDeclaration = numeroDeclaration; this.numeroSinistre = numeroSinistre; } /** * Comparaison sur {@link #getNumeroSinistre()}. */ public int compareTo(SinistreFullHistory other) { return new CompareToBuilder().append(this.numeroSinistre, other.numeroSinistre).toComparison(); } @Override public boolean equals(Object obj) { if (false == (obj instanceof SinistreFullHistory)) { return false; } final SinistreFullHistory other = (SinistreFullHistory) obj; return new EqualsBuilder().append(this.id, other.id).isEquals(); } public String getCodeAssureur() { return getCurrentSinistreVersion().getCodeAssureur(); } protected SinistreVersion getCurrentSinistreVersion() { return getSinistreVersion(new Timestamp(System.currentTimeMillis())); } public Timestamp getDateSituation() { return getCurrentSinistreVersion().getDateSituation(); } public String getDescription() { return getCurrentSinistreVersion().getDescription(); } public String getDescription(Timestamp dateEffectivite) { return getSinistreVersion(dateEffectivite).getDescription(); } public Long getId() { return id; } public String getNumeroDeclaration() { return numeroDeclaration; } public String getNumeroSinistre() { return numeroSinistre; } /** * <p> * Retourne le {@link SinistreVersion} effectif � la date donnee. * </p> * <p> * Regle : <code> * sinistreVersion.dateSituation <= dateEffectivite && * (sinistreVersion.nextSituation.dateSituation < dateEffectivite || * sinistreVersion.nextSituation == null) * </code> * </p> */ protected SinistreVersion getSinistreVersion(Timestamp dateEffectivite) { SinistreVersion result = null; for (SinistreVersion sinistreVersion : this.sinistreVersions) { if (dateEffectivite.getTime() >= sinistreVersion.getDateSituation().getTime()) { result = sinistreVersion; } } return result; } public SortedSet<SinistreVersion> getSinistreVersions() { return sinistreVersions; } public synchronized SinistreVersion getWorkingCopy() { if (this.workingCopy == null) { SinistreVersion currentSinistreVersion = getCurrentSinistreVersion(); SinistreVersion newWorkingCopy; if (currentSinistreVersion == null) { newWorkingCopy = new SinistreVersion(); } else { newWorkingCopy = currentSinistreVersion.copy(); } newWorkingCopy.setDateSituation(new Timestamp(System.currentTimeMillis())); // add forward linking here // no exception during working copy initialization, associate this.sinistreVersions.add(newWorkingCopy); this.workingCopy = newWorkingCopy; } return workingCopy; } @Override public int hashCode() { return new HashCodeBuilder().append(this.id).toHashCode(); } public void setCodeAssureur(String codeAssureur) { getWorkingCopy().setCodeAssureur(codeAssureur); } public void setDescription(String description) { getWorkingCopy().setDescription(description); } public void setId(Long id) { this.id = id; } public void setNumeroDeclaration(String numeroDeclaration) { this.numeroDeclaration = numeroDeclaration; } public void setNumeroSinistre(String numeroSinistre) { this.numeroSinistre = numeroSinistre; } public void setSinistreVersions(SortedSet<SinistreVersion> sinistreVersions) { this.sinistreVersions = sinistreVersions; } @Override public String toString() { return new ToStringBuilder(this).append("id", this.id).append("numeroSinistre", this.numeroSinistre).append("numeroDeclaration", this.numeroDeclaration).toString(); } public List<Evenement> getEvenements() { return evenements; } public void setEvenements(List<Evenement> evenements) { this.evenements = evenements; } }