package no.niths.domain.school; import java.util.ArrayList; import java.util.Date; import java.util.List; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.FetchType; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.JoinColumn; import javax.persistence.JoinTable; import javax.persistence.ManyToMany; import javax.persistence.ManyToOne; import javax.persistence.OneToMany; import javax.persistence.Table; import javax.persistence.Transient; import javax.persistence.UniqueConstraint; import javax.validation.constraints.Max; import javax.validation.constraints.Min; import javax.validation.constraints.NotNull; import javax.validation.constraints.Past; import javax.validation.constraints.Pattern; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlRootElement; import javax.xml.bind.annotation.XmlTransient; import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; import no.niths.common.constants.DomainConstantNames; import no.niths.common.constants.ValidationConstants; import no.niths.common.misc.Searchable; import no.niths.domain.Domain; import no.niths.domain.adapter.JsonDateDeserializerAdapter; import no.niths.domain.adapter.JsonDateSerializerAdapter; import no.niths.domain.adapter.XmlCharAdapter; import no.niths.domain.adapter.XmlDateAdapter; import no.niths.domain.battlestation.Loan; import no.niths.domain.constraints.StudentGender; import org.codehaus.jackson.annotate.JsonIgnore; import org.codehaus.jackson.map.annotate.JsonDeserialize; import org.codehaus.jackson.map.annotate.JsonSerialize; import org.hibernate.annotations.Cascade; import org.hibernate.annotations.CascadeType; import org.hibernate.annotations.Parameter; import org.hibernate.annotations.Type; import org.hibernate.annotations.TypeDef; import org.hibernate.validator.constraints.Email; import org.jasypt.hibernate4.type.EncryptedStringType; /** * Domain class for Student * * <p> * Student has these variables: * firstName = example Ola, * lastName = example Normann, * gender = M or F, * sessionToken = example , * birthday = example 02/02/2012, * grade = example 3, * email = example email@nith.no (required), * telephoneNumber = example 81549300, * description = example super awesome, * lastLogon = 12345678 (time in ms) * </p> * <p> * And relations too: * Locker, * Loan, * Feed, * FadderGroup, * Course, * Committee, * Role, * committeeLeader, * tutorInSubject, * representativeFor (a course), * groupLeader (leader for a fadderGroup) * </p> */ @TypeDef(name = "encryptedString" , typeClass = EncryptedStringType.class, parameters = { @Parameter(name = "encryptorRegisteredName", value = "strongHibernateStringEncryptor") }) @Entity @Table(name = DomainConstantNames.STUDENTS) @XmlRootElement @JsonSerialize(include = JsonSerialize.Inclusion.NON_NULL) @XmlAccessorType(XmlAccessType.FIELD) public class Student implements Domain { @Transient private static final long serialVersionUID = 8441269238845961513L; @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; @Searchable @Column(name = "first_name") @XmlElement(name = "firstname") @Pattern( regexp = ValidationConstants.REGULAR, message = "Invalid first name (2 - 500 alphanumeric letters only") private String firstName; @Searchable @Column(name = "last_name") @XmlElement(name = "lastname") @Pattern( regexp = ValidationConstants.REGULAR, message = "Invalid last name (2 - 500 alphanumeric letters only") private String lastName; @Column @StudentGender @XmlJavaTypeAdapter(value = XmlCharAdapter.class) private Character gender; @JsonIgnore @XmlTransient @Column(name = "session_token") @Type(type="encryptedString") private String sessionToken; @Column(name = "birthday") @Past @XmlJavaTypeAdapter(XmlDateAdapter.class) private Date birthday; @Column @Max(value = 3, message = "Can not be larger then 3") @Min(value = 1, message = "Can not be smaller then 1") private Integer grade; @Searchable @Column(unique = true) @NotNull @Email(message = "Not a valid email") private String email; @Column(name = "phone_number", unique = true) @Pattern(regexp = "(^$)|([1-9][0-9]{7})", message = "Not a valid number") @XmlElement(name="telephonenumber") private String telephoneNumber; @Column @Pattern( regexp = ValidationConstants.LARGE, message = "Invalid description (2 - 500 alphanumeric letters only") private String description; @JsonIgnore @XmlTransient @Column(name = "last_logon") private Long lastLogon; @ManyToMany(fetch = FetchType.LAZY, targetEntity = Role.class) @JoinTable( name = "students_roles", joinColumns = @JoinColumn(name = "students_id"), inverseJoinColumns = @JoinColumn(name = "roles_id"), uniqueConstraints = @UniqueConstraint( columnNames = {"students_id", "roles_id" })) @Cascade(CascadeType.ALL) private List<Role> roles = new ArrayList<Role>(); @JsonIgnore @XmlTransient @ManyToMany(fetch = FetchType.LAZY, targetEntity = Committee.class) @JoinTable( name = "committee_leaders", joinColumns = @JoinColumn(name = "leaders_id"), inverseJoinColumns = @JoinColumn(name = "committees_id")) @Cascade(CascadeType.ALL) private List<Committee> committeesLeader = new ArrayList<Committee>(); @JsonIgnore @XmlTransient @ManyToMany(fetch = FetchType.LAZY, targetEntity = Subject.class) @JoinTable( name = "subjects_tutors", joinColumns = @JoinColumn(name = "tutors_id"), inverseJoinColumns = @JoinColumn(name = "subjects_id")) @Cascade(CascadeType.ALL) private List<Subject> tutorInSubjects = new ArrayList<Subject>(); @ManyToOne(fetch = FetchType.LAZY, targetEntity = Course.class) @JoinTable( name = "courses_representatives", joinColumns = @JoinColumn(name = "representatives_id"), inverseJoinColumns = @JoinColumn(name = "courses_id")) @Cascade(CascadeType.ALL) @XmlElement(name="repesentativefor") private Course representativeFor; @ManyToMany(fetch = FetchType.LAZY, targetEntity = Committee.class) @Cascade(CascadeType.ALL) private List<Committee> committees = new ArrayList<Committee>(); @ManyToMany(fetch = FetchType.LAZY, targetEntity = Course.class) @Cascade(CascadeType.ALL) private List<Course> courses = new ArrayList<Course>(); @JsonSerialize(contentAs = FadderGroup.class) @ManyToMany(fetch = FetchType.LAZY, targetEntity = FadderGroup.class) @JoinTable( name = "fadder_leaders_students", joinColumns = @JoinColumn(name = "leaders_id"), inverseJoinColumns = @JoinColumn(name = "fadder_groups_id")) @Cascade(CascadeType.ALL) private List<FadderGroup> groupLeaders = new ArrayList<FadderGroup>(); @ManyToOne(fetch = FetchType.LAZY, targetEntity = FadderGroup.class) @JoinTable( name = "fadder_children_students", joinColumns = @JoinColumn(name = "fadderChildren_id"), inverseJoinColumns = @JoinColumn(name = "fadder_groups_id")) @Cascade(CascadeType.ALL) private FadderGroup fadderGroup; @OneToMany(fetch = FetchType.LAZY) @JoinTable( name = "feeds_student", joinColumns = @JoinColumn(name = "student_id"), inverseJoinColumns = @JoinColumn(name = "feeds_id")) @Cascade(CascadeType.ALL) private List<Feed> feeds = new ArrayList<Feed>(); @OneToMany(fetch = FetchType.LAZY, targetEntity = Loan.class) @JoinTable( name = "students_loans", joinColumns = @JoinColumn(name = "student_id"), inverseJoinColumns = @JoinColumn(name = "loan_id")) @Cascade(CascadeType.ALL) private List<Loan> loans = new ArrayList<Loan>(); @JsonIgnore @XmlTransient @OneToMany(fetch = FetchType.LAZY, targetEntity = Locker.class) @JoinTable( name = "students_lockers", joinColumns = @JoinColumn(name = "locker_id"), inverseJoinColumns = @JoinColumn(name = "student_id")) @Cascade(CascadeType.ALL) private List<Locker> lockers = new ArrayList<Locker>(); public Student() { this(null, null, null, null, null, null, null); setCommittees(null); setCommitteesLeader(null); setCourses(null); setFadderGroup(null); setGroupLeaders(null); setFeeds(null); setRoles(null); setTutorInSubjects(null); setLoans(null); this.lockers = null; } public Student(String email) { this.email = email; } public Student(String email, Long lastLogon) { this(email); this.lastLogon = lastLogon; } public Student(Long id, String firstName, String lastName) { this(firstName, lastName); setId(id); } public Student(String firstName, String lastName) { this(firstName, lastName, null, null, null, null, null); } public Student(String firstName, String lastName, String email, String number) { this(firstName, lastName, null, null, email, number, null); } public Student(String firstName, String lastName, Character gender, Integer grade, String email, String telephoneNumber, String description) { this.firstName = firstName; this.lastName = lastName; this.gender = gender; this.grade = grade; this.email = email; this.telephoneNumber = telephoneNumber; this.description = description; } public Student(Long studentId) { setId(studentId); } public Long getId() { return id; } public void setId(Long id) { this.id = id; } @JsonSerialize(using = JsonDateSerializerAdapter.class) public Date getBirthday() { return birthday; } @JsonDeserialize(using = JsonDateDeserializerAdapter.class) public void setBirthday(Date birthday) { this.birthday = birthday; } public Character getGender() { return gender; } public void setGender(Character gender) { this.gender = gender; } public Integer getGrade() { return grade; } public void setGrade(Integer grade) { this.grade = grade; } public String getFirstName() { return firstName; } public void setFirstName(String firstName) { this.firstName = firstName; } public String getLastName() { return lastName; } public void setLastName(String lastName) { this.lastName = lastName; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } public String getTelephoneNumber() { return telephoneNumber; } public void setTelephoneNumber(String telephoneNumber) { this.telephoneNumber = telephoneNumber; } public String getDescription() { return description; } public void setDescription(String description) { this.description = description; } @JsonSerialize(contentAs = Course.class) public List<Course> getCourses() { return courses; } public void setCourses(List<Course> courses) { this.courses = courses; } public static long getSerialversionuid() { return serialVersionUID; } @Override public boolean equals(Object obj) { if (!(obj instanceof Student)) { return false; } Student s = (Student) obj; return s == this ? true : s.getId() == id ? true : false; } public List<Committee> getCommittees() { return committees; } public void setCommittees(List<Committee> committees) { this.committees = committees; } public List<Role> getRoles() { return roles; } public void setRoles(List<Role> roles) { this.roles = roles; } public String getSessionToken() { return sessionToken; } public void setSessionToken(String sessionToken) { this.sessionToken = sessionToken; } // FIXME Remove ASAP @JsonIgnore public boolean isEmpty() { // Do we need to check firstName and lastName? They can not be null return ( id == null && firstName == null && lastName == null && gender == null && email == null && description == null && birthday == null && telephoneNumber == null && grade == null); } public List<Committee> getCommitteesLeader() { return committeesLeader; } public void setCommitteesLeader(List<Committee> committesLeader) { this.committeesLeader = committesLeader; } @JsonSerialize(as = FadderGroup.class) public FadderGroup getFadderGroup() { return fadderGroup; } public void setFadderGroup(FadderGroup fadderGroup) { this.fadderGroup = fadderGroup; } public List<FadderGroup> getGroupLeaders() { return groupLeaders; } public void setGroupLeaders(List<FadderGroup> groupLeaders) { this.groupLeaders = groupLeaders; } public Long getLastLogon() { return lastLogon; } public void setLastLogon(Long lastLogon) { this.lastLogon = lastLogon; } public List<Feed> getFeeds() { return feeds; } public void setFeeds(List<Feed> feeds) { this.feeds = feeds; } public List<Subject> getTutorInSubjects() { return tutorInSubjects; } public void setTutorInSubjects(List<Subject> tutorInSubjects) { this.tutorInSubjects = tutorInSubjects; } @JsonSerialize(as = Course.class) public Course getRepresentativeFor() { return representativeFor; } public void setRepresentativeFor(Course representativeFor) { this.representativeFor = representativeFor; } public List<Loan> getLoans() { return loans; } public void setLoans(List<Loan> loans) { this.loans = loans; } public List<Locker> getLockers() { return lockers; } public void setLockers(List<Locker> lockers) { this.lockers = lockers; } @Override public String toString() { return String.format("[%s][%s]", id, email); } }