Assignment.java
/*
* The coLAB project
* Copyright (C) 2021-2024 AlbaSim, MEI, HEIG-VD, HES-SO
*
* Licensed under the MIT License
*/
package ch.colabproject.colab.api.model.team.acl;
import ch.colabproject.colab.api.exceptions.ColabMergeException;
import ch.colabproject.colab.api.model.ColabEntity;
import ch.colabproject.colab.api.model.WithWebsocketChannels;
import ch.colabproject.colab.api.model.card.Card;
import ch.colabproject.colab.api.model.common.DeletionStatus;
import ch.colabproject.colab.api.model.common.Tracking;
import ch.colabproject.colab.api.model.team.TeamMember;
import ch.colabproject.colab.api.model.team.TeamRole;
import ch.colabproject.colab.api.model.tools.EntityHelper;
import ch.colabproject.colab.api.security.permissions.Conditions;
import ch.colabproject.colab.api.ws.channel.tool.ChannelsBuilders.ChannelsBuilder;
import ch.colabproject.colab.api.ws.channel.tool.ChannelsBuilders.EmptyChannelBuilder;
import javax.json.bind.annotation.JsonbTransient;
import javax.persistence.*;
import javax.validation.constraints.NotNull;
import static ch.colabproject.colab.api.model.team.TeamMember.TEAM_SEQUENCE_NAME;
/**
* Define the assignment a team member or a team role have to cards
*
* @author maxence
*/
@Entity
@Table(
indexes = {
@Index(columnList = "card_id,member_id,role_id", unique = true),
@Index(columnList = "card_id"),
@Index(columnList = "member_id"),
@Index(columnList = "role_id"),
}
)
public class Assignment implements ColabEntity, WithWebsocketChannels {
private static final long serialVersionUID = 1L;
// ---------------------------------------------------------------------------------------------
// fields
// ---------------------------------------------------------------------------------------------
/**
* Project ID
*/
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = TEAM_SEQUENCE_NAME)
private Long id;
/**
* creation + modification + erasure tracking data
*/
@Embedded
private Tracking trackingData;
/**
* Is it in a bin or ready to be definitely deleted. Null means active.
*/
@Enumerated(EnumType.STRING)
private DeletionStatus deletionStatus;
/**
* Involvement level = RACI level
*/
// can be null, no responsibility yet
@Enumerated(value = EnumType.STRING)
private InvolvementLevel involvementLevel;
/**
* the card this assignment is related to
*/
@ManyToOne(fetch = FetchType.LAZY)
@NotNull
@JsonbTransient
private Card card;
/**
* The member this assignment is for
*/
@ManyToOne(fetch = FetchType.LAZY)
@JsonbTransient
private TeamMember member;
/**
* The role this assignment is for
*/
// Note : currently not used on client side
@ManyToOne(fetch = FetchType.LAZY)
@JsonbTransient
private TeamRole role;
// ---------------------------------------------------------------------------------------------
// getters and setters
// ---------------------------------------------------------------------------------------------
/**
* @return the project ID
*/
@Override
public Long getId() {
return id;
}
/**
* @param id the project ID
*/
public void setId(Long id) {
this.id = id;
}
/**
* Get the tracking data
*
* @return tracking data
*/
@Override
public Tracking getTrackingData() {
return trackingData;
}
/**
* Set tracking data
*
* @param trackingData new tracking data
*/
@Override
public void setTrackingData(Tracking trackingData) {
this.trackingData = trackingData;
}
@Override
public DeletionStatus getDeletionStatus() {
return deletionStatus;
}
@Override
public void setDeletionStatus(DeletionStatus status) {
this.deletionStatus = status;
}
/**
* Get the involvement level
*
* @return the involvement level
*/
public InvolvementLevel getInvolvementLevel() {
return involvementLevel;
}
/**
* Set the involvement level
*
* @param involvementLevel the involvement level
*/
public void setInvolvementLevel(InvolvementLevel involvementLevel) {
this.involvementLevel = involvementLevel;
}
/**
* Get the card
*
* @return the card
*/
public Card getCard() {
return card;
}
/**
* Set the card
*
* @param card the card
*/
public void setCard(Card card) {
this.card = card;
}
/**
* Get id of the card, for serialization only
*
* @return id of the card
*/
public Long getCardId() {
if (this.card != null) {
return card.getId();
} else {
return null;
}
}
/**
* Get the value of member
*
* @return the value of member
*/
public TeamMember getMember() {
return member;
}
/**
* Get id of the member, for serialization only
*
* @return id of the member
*/
public Long getMemberId() {
if (this.member != null) {
return member.getId();
} else {
return null;
}
}
/**
* Set the value of member
*
* @param member new value of member
*/
public void setMember(TeamMember member) {
this.member = member;
if (member != null) {
this.setRole(null);
}
}
/**
* Get the value of role
*
* @return the value of role
*/
public TeamRole getRole() {
return role;
}
/**
* Set the value of role
*
* @param role new value of role
*/
public void setRole(TeamRole role) {
this.role = role;
if (role != null) {
this.setMember(null);
}
}
/**
* Get id of the role, for serialization only
*
* @return id of the role
*/
public Long getRoleId() {
if (this.role != null) {
return role.getId();
} else {
return null;
}
}
// ---------------------------------------------------------------------------------------------
// concerning the whole class
// ---------------------------------------------------------------------------------------------
@Override
public void mergeToUpdate(ColabEntity other) throws ColabMergeException {
if (other instanceof Assignment) {
Assignment o = (Assignment) other;
this.setDeletionStatus(o.getDeletionStatus());
// involvement level cannot be update manually. It is handled by AssignmentManager
} else {
throw new ColabMergeException(this, other);
}
}
@Override
public void mergeToDuplicate(ColabEntity other) throws ColabMergeException {
if (other instanceof Assignment) {
Assignment o = (Assignment) other;
this.setDeletionStatus(o.getDeletionStatus());
this.setInvolvementLevel(o.getInvolvementLevel());
} else {
throw new ColabMergeException(this, other);
}
}
@Override
public ChannelsBuilder getChannelsBuilder() {
if (this.getCard() != null) {
return this.getCard().getChannelsBuilder();
} else {
// such an orphan shouldn't exist...
return new EmptyChannelBuilder();
}
}
@Override
@JsonbTransient
public Conditions.Condition getReadCondition() {
if (this.getCard() != null) {
return this.getCard().getReadCondition();
} else {
return Conditions.alwaysTrue;
}
}
@Override
@JsonbTransient
public Conditions.Condition getUpdateCondition() {
if (this.getCard() != null) {
return this.getCard().getUpdateCondition();
} else {
return Conditions.alwaysTrue;
}
}
@Override
public int hashCode() {
return EntityHelper.hashCode(this);
}
@Override
@SuppressWarnings("EqualsWhichDoesntCheckParameterClass")
public boolean equals(Object obj) {
return EntityHelper.equals(this, obj);
}
@Override
public String toString() {
return "Assignment{" + "id=" + id + ", deletion=" + getDeletionStatus()
+ ", involvmt=" + involvementLevel + "}";
}
}