StaticDataEntityBase.java

package com.tradecloud.common.base;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.persistence.Column;
import javax.persistence.Id;
import javax.persistence.MappedSuperclass;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.validation.constraints.NotNull;
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.XmlTransient;

import com.fasterxml.jackson.annotation.JsonIgnore;
import org.apache.commons.lang.builder.EqualsBuilder;
import org.apache.commons.lang.builder.HashCodeBuilder;

/**
 * Commonality between all our static data entities should be code, name and displayable
 *
 * Code is the ID. If there is not a unique code that can be used as an ID then the entity should use the normal persistence hiearchy
 *
 * @See PersistenceBase
 */
@MappedSuperclass
@XmlTransient
@XmlAccessorType(XmlAccessType.FIELD)
public abstract class StaticDataEntityBase implements Comparable<StaticDataEntityBase>, Serializable {

    private static final long serialVersionUID = 1L;

    @Id
    @XmlAttribute(required = true)
    @NotNull(message = "code is required")
    @Column(nullable = false)
    @Size(max = 255, message = "Code cannot be longer than 255 characters")
    private String code;

    @XmlAttribute
    @NotNull(message = "name is required")
    @Column(nullable = false)
    @Size(max = 255, message = "Name cannot be longer than 255 characters")
    private String name;

    /**
     * Entity creation timestamp. XML transient because they are not really needed there.
     */
    @Temporal(TemporalType.TIMESTAMP)
    @Column(nullable = true)
    @XmlTransient
    @JsonIgnore
    protected Date created = new Date();

    /**
     * Entity updated/changed timestamp. Populated by hibernate XML transient because they are not really needed there.
     */
    @Temporal(TemporalType.TIMESTAMP)
    @Column(nullable = true)
    @XmlTransient
    @JsonIgnore
    protected Date updated;

    public Date getCreated() {
        return created;
    }

    public Date getUpdated() {
        return updated;
    }

    public void setCreated(Date date) {
        this.created = date;
    }

    public void setUpdated(Date date) {
        this.updated = date;
    }

    /**
     * Is the entity 'active'. Should it be displayed in drop downs on the system. Used for soft deletes of entities that can't be hard deleted due to
     * referential constraints.
     */
    @XmlAttribute
    @JsonIgnore
    private Boolean active = Boolean.TRUE;

    public String getCode() {
        return code;
    }

    public StaticDataEntityBase() {
    }

    public StaticDataEntityBase(String code) {
        this.code = code;
        this.active = Boolean.TRUE;
    }

    public StaticDataEntityBase(String code, String name) {
        this.code = code;
        this.name = name;
        this.active = Boolean.TRUE;
    }

    public void setCode(String code) {
        this.code = code;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Boolean getActive() {
        return active;
    }

    public void setActive(Boolean active) {
        this.active = active;
    }

    @Override
    public int hashCode() {
        return new HashCodeBuilder().append(getCode()).toHashCode();
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }
        if (obj == null) {
            return false;
        }
        if (!HibernateUtils.proxyClassEquals(this, obj)) {
            return false;
        }
        StaticDataEntityBase other = (StaticDataEntityBase) obj;
        return new EqualsBuilder().append(getCode(), other.getCode())
                .isEquals();
    }

    /**
     * Setting this back to default toString type behaviour. Better to use the itemLabel per JSF screen depending on whether the user should see the
     * code or name value. This will depend on the entity in question.
     */
    @Override
    public String toString() {
        return "[code=" + code + ", name=" + name + ", active=" + active + "]";
    }

    @Override
    public int compareTo(StaticDataEntityBase o) {
        return this.getCode().compareTo(o.getCode());
    }

    public static <X extends StaticDataEntityBase> List<X> filterActive(List<X> col) {
        List<X> list = new ArrayList<X>();
        for ( X c : col ) {
            if ( c.getActive() ) {
                list.add(c);
            }
        }
        return list;
    }
}