package fr.openwide.core.jpa.more.business.history.model; import java.util.Collections; import java.util.Date; import java.util.List; import java.util.Set; import javax.persistence.Basic; import javax.persistence.CascadeType; import javax.persistence.Embedded; import javax.persistence.EnumType; import javax.persistence.Enumerated; import javax.persistence.FetchType; import javax.persistence.GeneratedValue; import javax.persistence.Id; import javax.persistence.MappedSuperclass; import javax.persistence.OneToMany; import javax.persistence.OrderColumn; import javax.persistence.Temporal; import javax.persistence.TemporalType; import javax.persistence.Transient; import org.bindgen.Bindable; import org.hibernate.search.annotations.Analyze; import org.hibernate.search.annotations.Analyzer; import org.hibernate.search.annotations.Field; import org.hibernate.search.annotations.IndexedEmbedded; import org.hibernate.search.annotations.SortableField; import com.google.common.collect.Lists; import com.google.common.collect.Sets; import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import fr.openwide.core.commons.util.CloneUtils; import fr.openwide.core.commons.util.collections.CollectionUtils; import fr.openwide.core.commons.util.fieldpath.FieldPath; import fr.openwide.core.jpa.more.business.history.model.embeddable.HistoryValue; import fr.openwide.core.jpa.search.util.HibernateSearchAnalyzer; @Bindable @SuppressFBWarnings("squid:S00107") @MappedSuperclass public abstract class AbstractHistoryLog< HL extends AbstractHistoryLog<HL, HET, HD>, HET extends Enum<HET>, HD extends AbstractHistoryDifference<HD, HL>> extends AbstractHistoryElement<HL, HL> { private static final long serialVersionUID = -1146280203615151992L; public static final String DATE = "date"; private static final String SUBJECT = "subject"; private static final String SUBJECT_PREFIX = SUBJECT + "."; private static final String ALL_OBJECTS = "allObjects"; private static final String ALL_OBJECTS_PREFIX = ALL_OBJECTS + "."; private static final String MAIN_OBJECT = "mainObject"; private static final String MAIN_OBJECT_PREFIX = MAIN_OBJECT + "."; private static final String OBJECT1 = "object1"; private static final String OBJECT1_PREFIX = OBJECT1 + "."; private static final String OBJECT2 = "object2"; private static final String OBJECT2_PREFIX = OBJECT2 + "."; private static final String OBJECT3 = "object3"; private static final String OBJECT3_PREFIX = OBJECT3 + "."; private static final String OBJECT4 = "object4"; private static final String OBJECT4_PREFIX = OBJECT4 + "."; public static final String SUBJECT_REFERENCE = SUBJECT_PREFIX + HistoryValue.REFERENCE; public static final String ALL_OBJECTS_REFERENCE = ALL_OBJECTS_PREFIX + HistoryValue.REFERENCE; public static final String OBJECT1_REFERENCE = OBJECT1_PREFIX + HistoryValue.REFERENCE; public static final String OBJECT2_REFERENCE = OBJECT2_PREFIX + HistoryValue.REFERENCE; public static final String OBJECT3_REFERENCE = OBJECT3_PREFIX + HistoryValue.REFERENCE; public static final String OBJECT4_REFERENCE = OBJECT4_PREFIX + HistoryValue.REFERENCE; public static final String HAS_DIFFERENCES = "hasDifferences"; @Id @GeneratedValue private Long id; @Basic(optional = false) @Temporal(TemporalType.TIMESTAMP) @Field(name = DATE) @SortableField(forField = DATE) private Date date; @Basic(optional = false) @Enumerated(EnumType.STRING) @Field(analyzer = @Analyzer(definition = HibernateSearchAnalyzer.KEYWORD)) private HET eventType; @Embedded @IndexedEmbedded(prefix = SUBJECT_PREFIX, includePaths = {HistoryValue.REFERENCE}) private HistoryValue subject; @Embedded @IndexedEmbedded(prefix = MAIN_OBJECT_PREFIX, includePaths = {HistoryValue.REFERENCE}) private HistoryValue mainObject; @Embedded @IndexedEmbedded(prefix = OBJECT1_PREFIX, includePaths = {HistoryValue.REFERENCE}) private HistoryValue object1 = new HistoryValue(); @Embedded @IndexedEmbedded(prefix = OBJECT2_PREFIX, includePaths = {HistoryValue.REFERENCE}) private HistoryValue object2 = new HistoryValue(); @Embedded @IndexedEmbedded(prefix = OBJECT3_PREFIX, includePaths = {HistoryValue.REFERENCE}) private HistoryValue object3 = new HistoryValue(); @Embedded @IndexedEmbedded(prefix = OBJECT4_PREFIX, includePaths = {HistoryValue.REFERENCE}) private HistoryValue object4 = new HistoryValue(); @Basic private String comment; @OneToMany(mappedBy = "parentLog", cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.EAGER) @OrderColumn private List<HD> differences = Lists.newArrayList(); protected AbstractHistoryLog() { // nothing to do } protected AbstractHistoryLog(Date date, HET eventType, HistoryValue mainObject) { this.date = CloneUtils.clone(date); this.eventType = eventType; this.mainObject = mainObject; } @Override public Long getId() { return id; } @Override public void setId(Long id) { this.id = id; } @Override public String getNameForToString() { return object1 == null ? null : object1.getLabel(); } @Override public String getDisplayName() { return toString(); } @Override @SuppressWarnings("unchecked") @Transient public HL getRootLog() { return (HL) this; } @Override @Transient protected HL getParent() { return null; } @Override @Transient public FieldPath getRelativePath() { return FieldPath.ROOT; } public Date getDate() { return CloneUtils.clone(date); } public void setDate(Date date) { this.date = CloneUtils.clone(date); } public HET getEventType() { return eventType; } public void setEventType(HET action) { this.eventType = action; } public HistoryValue getSubject() { return subject; } public void setSubject(HistoryValue subject) { this.subject = subject; } public HistoryValue getMainObject() { return mainObject; } public void setMainObject(HistoryValue mainObject) { this.mainObject = mainObject; } public HistoryValue getObject1() { return object1; } public void setObject1(HistoryValue object1) { this.object1 = object1; } public HistoryValue getObject2() { return object2; } public void setObject2(HistoryValue object2) { this.object2 = object2; } public HistoryValue getObject3() { return object3; } public void setObject3(HistoryValue object3) { this.object3 = object3; } public HistoryValue getObject4() { return object4; } public void setObject4(HistoryValue object4) { this.object4 = object4; } @IndexedEmbedded(prefix = ALL_OBJECTS_PREFIX, includePaths = {HistoryValue.REFERENCE}) public Set<HistoryValue> getAllObjects() { Set<HistoryValue> result = Sets.newLinkedHashSet(); for (HistoryValue value : new HistoryValue[] {mainObject, object1, object2, object3, object4}) { if (value != null) { result.add(value); } } return result; } public String getComment() { return comment; } public void setComment(String comment) { this.comment = comment; } public List<HD> getDifferences() { return Collections.unmodifiableList(differences); } public void setDifferences(List<HD> differences) { CollectionUtils.replaceAll(this.differences, differences); } @Transient @Field(name = HAS_DIFFERENCES, analyze = Analyze.NO) public boolean isDifferencesNonEmpty() { return !differences.isEmpty(); } }