package hu.sch.domain.user;
import hu.sch.domain.Group;
import hu.sch.domain.Membership;
import hu.sch.domain.enums.SvieMembershipType;
import hu.sch.domain.enums.SvieStatus;
import hu.sch.util.HungarianStringComparator;
import java.io.Serializable;
import java.nio.file.Paths;
import java.util.*;
import javax.persistence.*;
import javax.validation.constraints.*;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
/**
* Felhasználót reprezentáló entitás.
*
* @author hege
* @author tomi
*/
@Entity
@Table(name = "users")
@NamedQueries({
@NamedQuery(name = User.findWithMemberships,
query = "SELECT u FROM User u LEFT JOIN FETCH u.memberships ms LEFT JOIN FETCH ms.posts posts LEFT JOIN FETCH ms.group LEFT JOIN FETCH posts.postType WHERE u.id = :id"),
@NamedQuery(name = User.findUserByNeptunCode,
query = "SELECT u FROM User u WHERE UPPER(u.neptunCode) = UPPER(:neptun)"),
@NamedQuery(name = User.findByScreenName,
query = "SELECT u FROM User u WHERE UPPER(u.screenName) = UPPER(:screenName)"),
@NamedQuery(name = User.getAllValuatedSemesterForUser, query = "SELECT DISTINCT pr.valuation.semester FROM PointRequest pr WHERE pr.user = :user ORDER BY pr.valuation.semester DESC"),
@NamedQuery(name = User.findWithIMAccounts, query = "SELECT u FROM User u LEFT JOIN FETCH u.imAccounts WHERE u.id = :id"),
})
@SequenceGenerator(name = "users_seq", sequenceName = "users_usr_id_seq",
allocationSize = 1)
@XmlRootElement
@XmlAccessorType(XmlAccessType.NONE)
public class User implements Serializable, Comparable<User> {
private static final long serialVersionUID = 1L;
public static final String findWithMemberships = "findUserWithMemberships";
public static final String findUserByNeptunCode = "findUserByNeptunCode";
public static final String findByScreenName = "findByScreenName";
public static final String getAllValuatedSemesterForUser = "getAllValuatedSemesterForUser";
public static final String findWithIMAccounts = "User.findWithIMAccounts";
//----------------------------------------------------
@Id
@GeneratedValue(generator = "users_seq")
@Column(name = "usr_id", nullable = false)
private Long id;
//----------------------------------------------------
@NotNull
@Size(max = 50)
@Column(name = "usr_screen_name", nullable = false, length = 50)
private String screenName;
//----------------------------------------------------
@XmlElement
@Column(name = "usr_email", length = 64, columnDefinition = "varchar(64)")
private String emailAddress;
//----------------------------------------------------
@Size(max = 6, min = 6)
@Column(name = "usr_neptun", columnDefinition = "char(6)", length = 6, nullable = true)
private String neptunCode;
//----------------------------------------------------
@XmlElement
@NotNull
@Column(name = "usr_firstname", nullable = false, columnDefinition = "text")
private String firstName;
//----------------------------------------------------
@XmlElement
@NotNull
@Column(name = "usr_lastname", nullable = false, columnDefinition = "text")
private String lastName;
//----------------------------------------------------
@XmlElement
@Column(name = "usr_nickname", nullable = true, columnDefinition = "text")
private String nickName;
//----------------------------------------------------
@Column(name = "usr_date_of_birth")
@Temporal(TemporalType.DATE)
private Date dateOfBirth;
//----------------------------------------------------
@NotNull
@Enumerated(EnumType.STRING)
@Column(name = "usr_gender", nullable = false)
private Gender gender;
//----------------------------------------------------
@NotNull
@Enumerated(EnumType.STRING)
@Column(name = "usr_student_status", nullable = false)
private StudentStatus studentStatus;
//----------------------------------------------------
@Column(name = "usr_mother_name", length = 100)
private String mothersName;
//----------------------------------------------------
@Column(name = "usr_photo_path")
private String photoPath;
//----------------------------------------------------
@Column(name = "usr_webpage")
private String webpage;
//----------------------------------------------------
@Size(max = 50)
@Column(name = "usr_cell_phone")
private String cellPhone;
//----------------------------------------------------
@Column(name = "usr_home_address")
private String homeAddress;
//----------------------------------------------------
@Size(max = 10, min = 10)
@Column(name = "usr_est_grad")
private String estimatedGraduationYear;
//----------------------------------------------------
@Column(name = "usr_dormitory")
private String dormitory;
//----------------------------------------------------
@Column(name = "usr_room")
private String room;
//----------------------------------------------------
@Column(name = "usr_confirm", length = 64)
@Size(max = 64)
private String confirmationCode;
//----------------------------------------------------
@NotNull
@Enumerated(EnumType.STRING)
@Column(name = "usr_svie_state", nullable = false)
private SvieStatus svieStatus;
//----------------------------------------------------
@NotNull
@Enumerated(EnumType.STRING)
@Column(name = "usr_svie_member_type", nullable = false)
private SvieMembershipType svieMembershipType;
//----------------------------------------------------
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "usr_svie_primary_membership")
private Membership sviePrimaryMembership;
//----------------------------------------------------
@OneToMany(mappedBy = "user", fetch = FetchType.LAZY)
private List<Membership> memberships;
//----------------------------------------------------
@NotNull
@Column(name = "usr_delegated", nullable = false, columnDefinition = "boolean default false")
private boolean delegated;
//----------------------------------------------------
@Transient
private List<Group> groups;
//----------------------------------------------------
@NotNull
@Column(name = "usr_show_recommended_photo", nullable = false, columnDefinition = "boolean default false")
private boolean showRecommendedPhoto;
//----------------------------------------------------
@OneToMany(cascade = CascadeType.ALL, orphanRemoval = true)
@JoinColumn(name = "usr_id", referencedColumnName = "usr_id", nullable = false)
private Set<IMAccount> imAccounts;
//----------------------------------------------------
@Column(name = "usr_status")
@Enumerated(EnumType.STRING)
@NotNull
private UserStatus userStatus;
//----------------------------------------------------
@Column(name = "usr_password")
private String passwordDigest;
//----------------------------------------------------
@Column(name = "usr_salt")
private String salt;
public User() {
this.delegated = false;
this.showRecommendedPhoto = false;
}
/**
* Felhasználó azonosítója.
*
* @return A user virId-je
*/
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
/**
* E-mail cím
*/
public String getEmailAddress() {
return emailAddress;
}
public void setEmailAddress(String emailAddress) {
this.emailAddress = emailAddress;
}
/**
* Neptun-kód
*/
public String getNeptunCode() {
return neptunCode;
}
public void setNeptunCode(final String neptunCode) {
if (neptunCode != null) {
this.neptunCode = neptunCode.toUpperCase();
} else {
this.neptunCode = null;
}
}
/**
* Keresztnév
*/
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
/**
* Vezetéknév
*/
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
/**
* Becenév
*/
public String getNickName() {
return nickName;
}
public void setNickName(String nickName) {
this.nickName = nickName;
}
/**
* SVIE tagság státusza
*/
public SvieStatus getSvieStatus() {
return svieStatus;
}
public void setSvieStatus(SvieStatus svieStatus) {
this.svieStatus = svieStatus;
}
/**
* Összeállítja egy felhasználóhoz a SVIE tagság állapotát stringként. A
* compareToMs paraméter lehet null
*
* @param compareToMs ha nem null, akkor ehhez a tagsághoz képest adja
* vissza a tagság státuszát (kiírja, hogy ha más az elsődleges köre)
* @return
*/
public String getSvieMemberText(final Membership compareToMs) {
switch (svieStatus) {
case ELFOGADASALATT:
return SvieStatus.ELFOGADASALATT.toString();
case FELDOLGOZASALATT:
return SvieStatus.FELDOLGOZASALATT.toString();
case ELFOGADVA:
switch (svieMembershipType) {
case PARTOLOTAG:
return SvieMembershipType.PARTOLOTAG.toString();
default:
if (compareToMs == null) {
return SvieMembershipType.RENDESTAG.toString();
} else {
if (sviePrimaryMembership != null
&& sviePrimaryMembership.getGroupId().equals(compareToMs.getGroupId())) {
return SvieMembershipType.RENDESTAG.toString();
} else {
String primGroupText = getSviePrimaryMembershipText();
if (primGroupText.isEmpty()) {
return "Nincs elsődleges köre";
} else {
return "Más elsődleges kör: " + primGroupText;
}
}
}
}
default:
return SvieStatus.NEMTAG.toString();
}
}
/**
* SVIE tagság típusa
*/
public SvieMembershipType getSvieMembershipType() {
return svieMembershipType;
}
public void setSvieMembershipType(SvieMembershipType svieMembershipType) {
this.svieMembershipType = svieMembershipType;
}
/**
* Az illető küldött-e az elsődleges körében
*/
public Boolean getDelegated() {
return delegated;
}
public void setDelegated(Boolean newValue) {
this.delegated = newValue;
}
/**
* Megmutassuk-e neki, hogy van egy fotó, amit javaslunk
*/
public Boolean isShowRecommendedPhoto() {
return showRecommendedPhoto;
}
public void setShowRecommendedPhoto(boolean showRecommendedPhoto) {
this.showRecommendedPhoto = showRecommendedPhoto;
}
/**
* SVIE elsődleges kör.
*
* Rendes tagsága kell legyen a körben.
*/
public Membership getSviePrimaryMembership() {
return sviePrimaryMembership;
}
public void setSviePrimaryMembership(Membership sviePrimaryMembership) {
this.sviePrimaryMembership = sviePrimaryMembership;
}
/**
* Körtagságok.
*
* TODO: rendes fetch legyen?
*/
public List<Group> getGroups() {
if (groups == null) {
loadGroups();
}
return groups;
}
/**
* Csoporttagságok - tagsági idővel kiegészítve
*/
public List<Membership> getMemberships() {
if (memberships == null) {
memberships = new ArrayList<>();
}
return memberships;
}
public void setMemberships(List<Membership> memberships) {
this.memberships = memberships;
}
/**
* IM elérhetőségek.
*/
public Set<IMAccount> getImAccounts() {
if (imAccounts == null) {
imAccounts = new HashSet<>();
}
return imAccounts;
}
public void setImAccounts(Set<IMAccount> imAccounts) {
this.imAccounts = imAccounts;
}
public String getFullName() {
return String.format("%s %s", getLastName(), getFirstName());
}
/**
* A felhasználó választott felhasználóneve.
*
* Ezzel jelentkezik be. OpenDJ-ben 'uid' volt az attribútum neve.
*/
public String getScreenName() {
return screenName;
}
public void setScreenName(String screenName) {
this.screenName = screenName;
}
/**
* Születési dátum.
*/
public Date getDateOfBirth() {
return dateOfBirth;
}
public void setDateOfBirth(Date dateOfBirth) {
this.dateOfBirth = dateOfBirth;
}
/**
* A felhasználó neme.
*/
public Gender getGender() {
return gender;
}
public void setGender(Gender gender) {
this.gender = gender;
}
/**
* Hallgatói státusz.
*/
public StudentStatus getStudentStatus() {
return studentStatus;
}
public void setStudentStatus(StudentStatus studentStatus) {
this.studentStatus = studentStatus;
}
/**
* Anyaja neve.
*/
public String getMothersName() {
return mothersName;
}
public void setMothersName(String mothersName) {
this.mothersName = mothersName;
}
/**
* A profilkép elérési útja.
*
* Relatív a felöltött képeket tároló mappához. pl. pistike/profile.jpg
*/
public String getPhotoPath() {
return photoPath;
}
public void setPhotoPath(String photoPath) {
this.photoPath = photoPath;
}
/**
* A profilkép teljes elérési útja.
*
* @return
*/
public String getPhotoFullPath(String basePath) {
return Paths.get(basePath, getPhotoPath()).toString();
}
/**
* Azt jelzi, hogy van-e profilképe a usernek.
*
* @return
*/
public boolean hasPhoto() {
return getPhotoPath() != null;
}
/**
* A hallgató weboldala.
*/
public String getWebpage() {
return webpage;
}
public void setWebpage(String webpage) {
this.webpage = webpage;
}
/**
* Mobil szám.
*/
public String getCellPhone() {
return cellPhone;
}
public void setCellPhone(String cellPhone) {
this.cellPhone = cellPhone;
}
/**
* Otthoni cím.
*/
public String getHomeAddress() {
return homeAddress;
}
public void setHomeAddress(String homeAddress) {
this.homeAddress = homeAddress;
}
/**
* Végzés várható éve.
*
* Formátum: YYYYYYYY[12] Például: 201220132 a 2012/13-as év második féléve
*/
public String getEstimatedGraduationYear() {
return estimatedGraduationYear;
}
public void setEstimatedGraduationYear(String estimatedGraduationYear) {
this.estimatedGraduationYear = estimatedGraduationYear;
}
/**
* Kollégium neve.
*/
public String getDormitory() {
return dormitory;
}
public void setDormitory(String dormitory) {
this.dormitory = dormitory;
}
/**
* Szobaszám.
*
* String, hogy az esetlegesen betűt is tartamlazó szobákat.
*/
public String getRoom() {
return room;
}
public void setRoom(String room) {
this.room = room;
}
/**
* Gets the combined dormitory and room number.
*
* Fromat [Dormitory] [Room]
*
* @return
*/
public String getFullRoomNumber() {
if (dormitory == null && room == null) {
return "";
}
if (dormitory == null) {
return room;
}
if (room == null) {
return dormitory;
}
return String.format("%s %s", dormitory, room);
}
/**
* Regisztrációhoz szükéges megerősítő kód.
*/
public String getConfirmationCode() {
return confirmationCode;
}
public void setConfirmationCode(String confirmationCode) {
this.confirmationCode = confirmationCode;
}
/**
* Az elsődleges kör szöveges reprezentációja
*
* @return az elsődleges kör neve, ha van, különben egy üres string.
*/
public String getSviePrimaryMembershipText() {
if (sviePrimaryMembership != null) {
return sviePrimaryMembership.getGroup().getName();
}
return "";
}
/**
* A felhasználó SSO státusza.
*
* @return az felhasználó sso statusa vagy null, ha nincs kitöltve
*/
public UserStatus getUserStatus() {
return userStatus;
}
public void setUserStatus(UserStatus userStatus) {
this.userStatus = userStatus;
}
/**
* A felhasználó jelszó hash-e.
*
* @return
*/
public String getPasswordDigest() {
return passwordDigest;
}
public void setPasswordDigest(String passwordDigest) {
this.passwordDigest = passwordDigest;
}
/**
* A jelszó hash generáláshoz használt salt.
*
* @return
*/
public String getSalt() {
return salt;
}
public void setSalt(String salt) {
this.salt = salt;
}
@Override
public String toString() {
return String.format("User#%d name: %s, email: %s", getId(), getFullName(), getEmailAddress());
}
@Override
public int compareTo(User o) {
return HungarianStringComparator.scompare(getFullName(), o.getFullName());
}
public int compareToBySvieMemberText(final User u, final Membership compareToMs) {
return HungarianStringComparator.scompare(getSvieMemberText(compareToMs), u.getSvieMemberText(compareToMs));
}
/**
* Egyenlőség vizsgálat id alapján.
*
* Először referencia szerinti vizsgálatot végez. Ha az id null, akkor csak
* önmagával referencia szitnen megegyező objektumra ad vissza true-t.
*/
@Override
public boolean equals(Object obj) {
if (obj == this) {
return true;
}
if (obj == null) {
return false;
}
if (!(obj instanceof User)) {
return false;
}
final User other = (User) obj;
if (this.getId() != null) {
return this.getId().equals(other.getId());
}
return false;
}
@Override
public int hashCode() {
int hash = 7;
hash = 61 * hash + (this.id != null ? this.id.hashCode() : 0);
hash = 61 * hash + (this.neptunCode != null ? this.neptunCode.hashCode() : 0);
hash = 61 * hash + (this.firstName != null ? this.firstName.hashCode() : 0);
hash = 61 * hash + (this.lastName != null ? this.lastName.hashCode() : 0);
return hash;
}
private void loadGroups() {
groups = new ArrayList<>();
if (memberships != null) {
for (Membership m : memberships) {
groups.add(m.getGroup());
}
}
}
}