Application.java
package access.model;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;
import io.hypersistence.utils.hibernate.type.json.JsonType;
import jakarta.persistence.*;
import jakarta.validation.constraints.NotNull;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import org.hibernate.Hibernate;
import org.hibernate.annotations.Type;
import java.io.Serializable;
import java.time.Instant;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
@Entity(name = "applications")
@NoArgsConstructor
@Getter
@Setter
public class Application implements NameHolder {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column
@NotNull
private String name;
@Column(name = "logo_url")
private String logoUrl;
@Type(JsonType.class)
@Column(name = "meta_data", columnDefinition = "jsonb")
private HashMap<String, Object> metaData = new HashMap<>();
@Enumerated(EnumType.STRING)
@Column
@NotNull
private ApplicationStatus status = ApplicationStatus.OPEN;
@Column(name = "sections_complete")
private int sectionsComplete;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "organization_id")
@JsonProperty(access = JsonProperty.Access.WRITE_ONLY)
private Organization organization;
@OneToMany(mappedBy = "application", orphanRemoval = true, fetch = FetchType.LAZY)
private Set<Connection> connections = new HashSet<>();
@OneToMany(mappedBy = "application", orphanRemoval = true, fetch = FetchType.LAZY, cascade = CascadeType.ALL)
private Set<ApplicationMembership> applicationMemberships = new HashSet<>();
@Column(name = "created_at")
private Instant createdAt;
@Column
private String createdBy;
@Column(name = "signed_contract")
private boolean signedContract;
@Enumerated(EnumType.STRING)
@Column
@NotNull
private ApplicationTarget target = ApplicationTarget.SURF;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "owner_id")
@JsonProperty(access = JsonProperty.Access.WRITE_ONLY)
private User owner;
@Enumerated(EnumType.STRING)
@Column
@NotNull
private ApplicationType type = ApplicationType.APP;
@OneToOne(mappedBy = "application", fetch = FetchType.LAZY, cascade = CascadeType.ALL, orphanRemoval = true)
private Contract contract;
public Application(String name, Organization organization, String createdBy, Map<String, Object> metaData) {
this.name = name;
this.organization = organization;
this.metaData = new HashMap<>(metaData);
this.createdBy = createdBy;
this.createdAt = Instant.now();
}
//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("schacHomeOrganization", organization.getSchacHomeOrganization());
}
return organizationInfo;
}
//We need info, about the owner
@JsonProperty(access = JsonProperty.Access.READ_ONLY, value = "ownerIdentifier")
public Long getOwnerInfo() {
User appOwner = getOwner();
if (appOwner != null && Hibernate.isInitialized(appOwner)) {
return appOwner.getId();
}
return null;
}
@JsonIgnore
public void removeConnection(Connection connection) {
//This is required by Hibernate - children can't be dereferenced
Set<Connection> newConnections = this.connections
.stream().filter(conn -> !conn.getId().equals(connection.getId())).collect(Collectors.toSet());
this.connections.clear();
this.connections.addAll(newConnections);
}
public void merge(Application applicationData) {
this.name = applicationData.name;
this.metaData = applicationData.metaData;
this.type = applicationData.type;
this.target = applicationData.target;
this.logoUrl = applicationData.logoUrl;
this.signedContract = applicationData.signedContract;
this.status = applicationData.status;
}
}