OrganizationMembership.java
package access.model;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;
import jakarta.persistence.*;
import jakarta.validation.constraints.NotNull;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import org.hibernate.Hibernate;
import java.io.Serializable;
import java.time.Instant;
import java.util.*;
import java.util.stream.Collectors;
@Entity(name = "organization_memberships")
@NoArgsConstructor
@Getter
@Setter
public class OrganizationMembership implements NameHolder {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name = "created_at")
private Instant createdAt;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "user_id")
@JsonProperty(access = JsonProperty.Access.WRITE_ONLY)
private User user;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "organization_id")
@JsonProperty(access = JsonProperty.Access.WRITE_ONLY)
private Organization organization;
@Enumerated(EnumType.STRING)
@Column
@NotNull
private Authority authority = Authority.MEMBER;
@OneToMany(mappedBy = "organizationMembership", orphanRemoval = true, fetch = FetchType.LAZY, cascade = CascadeType.ALL)
private Set<ApplicationMembership> applicationMemberships = new HashSet<>();
@Transient
private String transientName;
public OrganizationMembership(Authority authority) {
this.authority = authority;
}
public OrganizationMembership(User user, Organization organization, Authority authority) {
this.user = user;
this.organization = organization;
this.authority = authority;
this.transientName = getClass().getName().concat(organization.getName()).concat(authority.name());
this.createdAt = Instant.now();
}
@JsonIgnore
public ApplicationMembership addApplicationMembership(ApplicationMembership applicationMemberships) {
this.applicationMemberships.add(applicationMemberships);
return applicationMemberships;
}
//We need organization info, but we don't want cyclic JSON deserialization
@JsonProperty(access = JsonProperty.Access.READ_ONLY, value = "organization")
public Map<String, Serializable> getOrganizationInfo() {
Organization organization = getOrganization();
Map<String, Serializable> organizationInfo = new HashMap<>();
if (organization != null && Hibernate.isInitialized(organization)) {
organizationInfo.put("id", organization.getId());
organizationInfo.put("name", organization.getName());
organizationInfo.put("manageIdentifier", organization.getManageIdentifier());
organizationInfo.put("status", organization.getStatus());
organizationInfo.put("schacHomeOrganization", organization.getSchacHomeOrganization());
}
return organizationInfo;
}
//We need user info, but we don't want cyclic JSON deserialization
@JsonProperty(access = JsonProperty.Access.READ_ONLY, value = "user")
public Map<String, Serializable> getUserInfo() {
User user = getUser();
Map<String, Serializable> userInfo = new HashMap<>();
if (user != null && Hibernate.isInitialized(user)) {
userInfo.put("id", user.getId());
userInfo.put("name", user.getName());
userInfo.put("email", user.getEmail());
userInfo.put("schacHomeOrganization", user.getSchacHomeOrganization());
}
return userInfo;
}
@JsonIgnore
public void removeApplicationMembership(ApplicationMembership applicationMembership) {
//This is required by Hibernate - children can't be dereferenced
this.removeApplicationMemberships(List.of(applicationMembership));
}
@JsonIgnore
public void removeApplicationMemberships(List<ApplicationMembership> applicationMemberships) {
//This is required by Hibernate - children can't be dereferenced
List<Long> applicationMembershipsIdentifiers = applicationMemberships.stream().map(am -> am.getId()).toList();
Set<ApplicationMembership> newApplicationMemberships = this.applicationMemberships
.stream().filter(am -> !applicationMembershipsIdentifiers.contains(am.getId())).collect(Collectors.toSet());
this.applicationMemberships.clear();
this.applicationMemberships.addAll(newApplicationMemberships);
}
@Override
@Transient
@JsonIgnore
public String getName() {
return transientName;
}
}