diff --git a/src/main/java/fr/lirmm/aren/model/Team.java b/src/main/java/fr/lirmm/aren/model/Team.java index 1c077dc..65cfbf0 100644 --- a/src/main/java/fr/lirmm/aren/model/Team.java +++ b/src/main/java/fr/lirmm/aren/model/Team.java @@ -16,6 +16,7 @@ import javax.xml.bind.annotation.XmlTransient; import com.fasterxml.jackson.annotation.JsonIdentityInfo; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.ObjectIdGenerators; +import fr.lirmm.aren.model.carto.CDebate; import org.hibernate.annotations.SortNatural; import org.hibernate.annotations.Where; @@ -49,6 +50,10 @@ public class Team extends AbstractEntEntity implements Serializable { @SortNatural private SortedSet debates = new TreeSet<>(); + @ManyToMany(mappedBy = "teams") + @SortNatural + private SortedSet debatesCarto = new TreeSet<>(); + @ManyToMany(mappedBy = "teams") @Where(clause = "is_active = true") @SortNatural @@ -58,6 +63,10 @@ public class Team extends AbstractEntEntity implements Serializable { @Column(name = "debates_count") private Integer debatesCount = 0; + @JsonProperty(access = JsonProperty.Access.READ_ONLY) + @Column(name = "debates_carto_count") + private Integer debatesCartoCount = 0; + @JsonProperty(access = JsonProperty.Access.READ_ONLY) @Column(name = "users_count") private Integer usersCount = 0; @@ -127,6 +136,23 @@ public class Team extends AbstractEntEntity implements Serializable { this.debates = debates; } + /** + * + * @return + */ + @XmlTransient + public SortedSet getDebatesCarto() { + return debatesCarto; + } + + /** + * + * @param debatesCarto + */ + public void setDebatesCarto(SortedSet debatesCarto) { + this.debatesCarto = debatesCarto; + } + /** * * @return diff --git a/src/main/java/fr/lirmm/aren/model/User.java b/src/main/java/fr/lirmm/aren/model/User.java index f432622..e35760a 100644 --- a/src/main/java/fr/lirmm/aren/model/User.java +++ b/src/main/java/fr/lirmm/aren/model/User.java @@ -26,6 +26,7 @@ import java.time.temporal.ChronoUnit; import javax.persistence.JoinTable; +import fr.lirmm.aren.model.carto.CDebate; import fr.lirmm.aren.model.vm.VMTeam; import org.hibernate.annotations.Filter; import org.hibernate.annotations.Filters; @@ -116,6 +117,10 @@ public class User extends AbstractEntEntity implements Serializable { @SortNatural private SortedSet invitedDebates = new TreeSet<>(); + @ManyToMany(mappedBy = "guests") + @SortNatural + private SortedSet invitedDebatesCarto = new TreeSet<>(); + @OneToMany(mappedBy = "owner") @SortNatural private SortedSet comments = new TreeSet<>(); @@ -290,6 +295,14 @@ public class User extends AbstractEntEntity implements Serializable { this.invitedDebates = invitedDebates; } + public SortedSet getInvitedDebatesCarto() { + return invitedDebatesCarto; + } + + public void setInvitedDebatesCarto(SortedSet invitedDebatesCarto) { + this.invitedDebatesCarto = invitedDebatesCarto; + } + /** * * @return diff --git a/src/main/java/fr/lirmm/aren/model/carto/CCategory.java b/src/main/java/fr/lirmm/aren/model/carto/CCategory.java new file mode 100644 index 0000000..6146620 --- /dev/null +++ b/src/main/java/fr/lirmm/aren/model/carto/CCategory.java @@ -0,0 +1,162 @@ +package fr.lirmm.aren.model.carto; + +import com.fasterxml.jackson.annotation.JsonIdentityInfo; +import com.fasterxml.jackson.annotation.ObjectIdGenerators; +import fr.lirmm.aren.model.AbstractEntity; +import org.hibernate.annotations.SortNatural; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.OneToMany; +import javax.persistence.Table; +import javax.validation.constraints.Size; +import javax.xml.bind.annotation.XmlTransient; +import java.io.Serializable; +import java.util.Date; +import java.util.SortedSet; +import java.util.TreeSet; + +/** + * @author ANDRIAMBOLAHARIMIHANTA Havana + * @created 13/10/2021 - 05:58 + * @project aren-1 + */ +@Entity +@Table(name = "categories_carto") + +@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id", scope = CCategory.class) +public class CCategory extends AbstractEntity implements Serializable { + + /** + * + */ + private static final long serialVersionUID = 4359639152649086413L; + + @Size(max = 255) + @Column(name = "name") + private String name; + + @Size(max = 2083) + @Column(name = "picture") + private String picture; + + @OneToMany(mappedBy = "category") + @SortNatural + private SortedSet documents = new TreeSet<>(); + + @Column(name = "debates_count") + private Integer debatesCount = 0; + + @Column(name = "documents_count") + private Integer documentsCount = 0; + + @Column(name = "last_comment_date") + private Date lastCommentDate; + + /** + * + * @return + */ + public String getName() { + return name; + } + + /** + * + * @param name + */ + public void setName(String name) { + this.name = name; + } + + /** + * + * @return + */ + public String getPicture() { + return picture; + } + + /** + * + * @param picture + */ + public void setPicture(String picture) { + this.picture = picture; + } + + /** + * + * @return + */ + @XmlTransient + public SortedSet getDocuments() { + return documents; + } + + /** + * + * @param documents + */ + public void setDocuments(SortedSet documents) { + this.documents = documents; + } + + /** + * + * @return + */ + public Integer getDebatesCount() { + return debatesCount; + } + + /** + * + * @param debatesCount + */ + public void setDebatesCount(Integer debatesCount) { + this.debatesCount = debatesCount; + } + + /** + * + * @return + */ + public Date getLastCommentDate() { + return lastCommentDate; + } + + /** + * + * @param lastCommentDate + */ + public void setLastCommentDate(Date lastCommentDate) { + this.lastCommentDate = lastCommentDate; + } + + /** + * + * @return + */ + public Integer getDocumentsCount() { + return documentsCount; + } + + /** + * + * @param documentsCount + */ + public void setDocumentsCount(Integer documentsCount) { + this.documentsCount = documentsCount; + } + + /** + * + * @return + */ + @Override + public boolean isRemovable() { + return documentsCount == 0; + } + +} diff --git a/src/main/java/fr/lirmm/aren/model/carto/CComment.java b/src/main/java/fr/lirmm/aren/model/carto/CComment.java new file mode 100644 index 0000000..c8e3108 --- /dev/null +++ b/src/main/java/fr/lirmm/aren/model/carto/CComment.java @@ -0,0 +1,174 @@ +package fr.lirmm.aren.model.carto; + +import com.fasterxml.jackson.annotation.JsonIdentityInfo; +import com.fasterxml.jackson.annotation.JsonIdentityReference; +import com.fasterxml.jackson.annotation.ObjectIdGenerators; +import fr.lirmm.aren.model.AbstractOwnedEntity; +import fr.lirmm.aren.model.TagSet; +import org.hibernate.annotations.SortNatural; +import org.hibernate.annotations.Type; + +import javax.persistence.*; +import javax.validation.constraints.NotNull; +import java.io.Serializable; +import java.util.SortedSet; +import java.util.TreeSet; + +/** + * @author ANDRIAMBOLAHARIMIHANTA Havana + * @created 11/10/2021 - 10:22 + * @project aren-1 + */ +@Entity +@Table(name = "comments_carto") + +@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id", scope = CComment.class) + +public class CComment extends AbstractOwnedEntity implements Serializable { + @Lob + @Type(type = "org.hibernate.type.TextType") + @Column(name = "reformulation") + private String reformulation; + + @Lob + @Type(type = "org.hibernate.type.TextType") + @Column(name = "argumentation") + private String argumentation; + + @Lob + @Type(type = "org.hibernate.type.TextType") + @Column(name = "selection") + private String selection; + + @Column(name = "start_container") + private String startContainer; + + @Column(name = "start_offset") + private Long startOffset; + + @Column(name = "end_container") + private String endContainer; + + @Column(name = "end_offset") + private Long endOffset; + + @Basic(optional = false) + @NotNull + @Column(name = "moderated") + private boolean moderated = false; + + @Basic(optional = false) + @NotNull + @Column(name = "signaled") + private boolean signaled = false; + + @OneToMany(mappedBy = "parent") + @SortNatural + private SortedSet comments = new TreeSet<>(); + + @JsonIdentityReference(alwaysAsId = true) + @JoinColumn(name = "parent_id", referencedColumnName = "id", updatable = false) + @ManyToOne + private CComment parent; + + @JsonIdentityReference(alwaysAsId = true) + @JoinColumn(name = "debate_id", referencedColumnName = "id", updatable = false) + @ManyToOne(optional = false) + private CDebate debate; + + public String getReformulation() { + return reformulation; + } + + public void setReformulation(String reformulation) { + this.reformulation = reformulation; + } + + public String getArgumentation() { + return argumentation; + } + + public void setArgumentation(String argumentation) { + this.argumentation = argumentation; + } + + public String getSelection() { + return selection; + } + + public void setSelection(String selection) { + this.selection = selection; + } + + public String getStartContainer() { + return startContainer; + } + + public void setStartContainer(String startContainer) { + this.startContainer = startContainer; + } + + public Long getStartOffset() { + return startOffset; + } + + public void setStartOffset(Long startOffset) { + this.startOffset = startOffset; + } + + public String getEndContainer() { + return endContainer; + } + + public void setEndContainer(String endContainer) { + this.endContainer = endContainer; + } + + public Long getEndOffset() { + return endOffset; + } + + public void setEndOffset(Long endOffset) { + this.endOffset = endOffset; + } + + public boolean isModerated() { + return moderated; + } + + public void setModerated(boolean moderated) { + this.moderated = moderated; + } + + public boolean isSignaled() { + return signaled; + } + + public void setSignaled(boolean signaled) { + this.signaled = signaled; + } + + public SortedSet getComments() { + return comments; + } + + public void setComments(SortedSet comments) { + this.comments = comments; + } + + public CComment getParent() { + return parent; + } + + public void setParent(CComment parent) { + this.parent = parent; + } + + public CDebate getDebate() { + return debate; + } + + public void setDebate(CDebate debate) { + this.debate = debate; + } +} diff --git a/src/main/java/fr/lirmm/aren/model/carto/CDebate.java b/src/main/java/fr/lirmm/aren/model/carto/CDebate.java new file mode 100644 index 0000000..9c786af --- /dev/null +++ b/src/main/java/fr/lirmm/aren/model/carto/CDebate.java @@ -0,0 +1,220 @@ +package fr.lirmm.aren.model.carto; + +import com.fasterxml.jackson.annotation.JsonIdentityInfo; +import com.fasterxml.jackson.annotation.ObjectIdGenerators; +import fr.lirmm.aren.model.*; +import org.hibernate.annotations.SortNatural; +import org.hibernate.annotations.Type; +import org.hibernate.annotations.Where; + +import javax.persistence.*; +import javax.validation.constraints.Size; +import java.io.Serializable; +import java.time.ZonedDateTime; +import java.util.SortedSet; +import java.util.TreeSet; + +/** + * @author ANDRIAMBOLAHARIMIHANTA Havana + * @created 11/10/2021 - 10:19 + * @project aren-1 + */ +@Entity +@Table(name = "debates_carto") + +@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id", scope = CDebate.class) + +public class CDebate extends AbstractOwnedEntity implements Serializable { + @Size(max = 255) + @Column(name = "name") + private String name; + + @Lob + @Type(type = "org.hibernate.type.TextType") + @Column(name = "map_link") + private String mapLink; + + @Column(name = "mesh_size") + private int meshSize = 1; + + @Column(name = "closed") + private ZonedDateTime closed; + + @Column(name = "is_active") + private boolean active = true; + + @JoinTable(name = "debates_teams_carto", + joinColumns = { + @JoinColumn(name = "debate_id", referencedColumnName = "id")}, + inverseJoinColumns = { + @JoinColumn(name = "team_id", referencedColumnName = "id")}) + @ManyToMany + @SortNatural + private SortedSet teams = new TreeSet<>(); + + @JoinTable(name = "debates_guests_carto", + joinColumns = { + @JoinColumn(name = "debate_id", referencedColumnName = "id")}, + inverseJoinColumns = { + @JoinColumn(name = "user_id", referencedColumnName = "id")}) + @ManyToMany + @Where(clause = "is_active = true") + @SortNatural + private SortedSet guests = new TreeSet<>(); + + @OneToMany(mappedBy = "debate") + @SortNatural + private SortedSet comments = new TreeSet<>(); + + @JoinColumn(name = "document_id", referencedColumnName = "id", updatable = false) + @ManyToOne(optional = false, fetch = FetchType.LAZY) + private CDocument document; + + @Column(name = "comments_count") + private Integer commentsCount = 0; + + @Column(name = "last_comment_date") + private ZonedDateTime lastCommentDate; + + @Column(name = "open_public") + private boolean openPublic = false; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getMapLink() { + return mapLink; + } + + public void setMapLink(String mapLink) { + this.mapLink = mapLink; + } + + public int getMeshSize() { + return meshSize; + } + + public void setMeshSize(int meshSize) { + this.meshSize = meshSize; + } + + public ZonedDateTime getClosed() { + return closed; + } + + public void setClosed(ZonedDateTime closed) { + this.closed = closed; + } + + public boolean isActive() { + return active; + } + + public void setActive(boolean active) { + this.active = active; + } + + public SortedSet getTeams() { + return teams; + } + + public void setTeams(SortedSet teams) { + this.teams = teams; + } + /** + * + * @param team + */ + public void addTeam(Team team) { + this.teams.add(team); + team.getDebatesCarto().add(this); + } + + /** + * + * @param team + */ + public void removeTeam(Team team) { + this.teams.remove(team); + team.getDebatesCarto().remove(this); + } + + public SortedSet getGuests() { + return guests; + } + + public void setGuests(SortedSet guests) { + this.guests = guests; + } + + /** + * + * @param guest + */ + public void addGuest(User guest) { + this.guests.add(guest); + guest.getInvitedDebatesCarto().add(this); + } + + /** + * + * @param guest + */ + public void removeGuest(User guest) { + this.guests.remove(guest); + guest.getInvitedDebatesCarto().remove(this); + } + + public SortedSet getComments() { + return comments; + } + + public void setComments(SortedSet comments) { + this.comments = comments; + } + + public CDocument getDocument() { + return document; + } + + public void setDocument(CDocument document) { + this.document = document; + } + + public Integer getCommentsCount() { + return commentsCount; + } + + public void setCommentsCount(Integer commentsCount) { + this.commentsCount = commentsCount; + } + + public ZonedDateTime getLastCommentDate() { + return lastCommentDate; + } + + public void setLastCommentDate(ZonedDateTime lastCommentDate) { + this.lastCommentDate = lastCommentDate; + } + + /** + * + * @return + */ + public boolean isOpenPublic() { + return openPublic; + } + + /** + * + * @param openPublic + */ + public void setOpenPublic(boolean openPublic) { + this.openPublic = openPublic; + } +} diff --git a/src/main/java/fr/lirmm/aren/model/carto/CDocument.java b/src/main/java/fr/lirmm/aren/model/carto/CDocument.java new file mode 100644 index 0000000..03eb002 --- /dev/null +++ b/src/main/java/fr/lirmm/aren/model/carto/CDocument.java @@ -0,0 +1,97 @@ +package fr.lirmm.aren.model.carto; + +import com.fasterxml.jackson.annotation.JsonIdentityInfo; +import com.fasterxml.jackson.annotation.ObjectIdGenerators; +import fr.lirmm.aren.model.AbstractDatedEntity; +import org.hibernate.annotations.SortNatural; +import org.hibernate.annotations.Type; + +import javax.persistence.*; +import javax.validation.constraints.Size; +import java.io.Serializable; +import java.util.SortedSet; +import java.util.TreeSet; + +/** + * @author ANDRIAMBOLAHARIMIHANTA Havana + * @created 11/10/2021 - 10:18 + * @project aren-1 + */ +@Entity +@Table(name = "documents_carto") + +@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id", scope = CDocument.class) + +public class CDocument extends AbstractDatedEntity implements Serializable { + @Size(max = 255) + @Column(name = "name") + private String name; + + @Size(max = 255) + @Column(name = "author") + private String author; + + @Lob + @Type(type = "org.hibernate.type.TextType") + @Column(name = "content") + private String content; + + @JoinColumn(name = "category_id", referencedColumnName = "id") + @ManyToOne(optional = false) + private CCategory category; + + @OneToMany(mappedBy = "document") + @SortNatural + private SortedSet debates = new TreeSet<>(); + + @Column(name = "debates_count") + private Integer debatesCount = 0; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getAuthor() { + return author; + } + + public void setAuthor(String author) { + this.author = author; + } + + public String getContent() { + return content; + } + + public void setContent(String content) { + this.content = content; + } + + public CCategory getCategory() { + return category; + } + + public void setCategory(CCategory category) { + this.category = category; + } + + public SortedSet getDebates() { + return debates; + } + + public void setDebates(SortedSet debates) { + this.debates = debates; + } + + public Integer getDebatesCount() { + return debatesCount; + } + + public void setDebatesCount(Integer debatesCount) { + this.debatesCount = debatesCount; + } +} diff --git a/src/main/java/fr/lirmm/aren/model/carto/CNotification.java b/src/main/java/fr/lirmm/aren/model/carto/CNotification.java new file mode 100644 index 0000000..7489ff3 --- /dev/null +++ b/src/main/java/fr/lirmm/aren/model/carto/CNotification.java @@ -0,0 +1,186 @@ +package fr.lirmm.aren.model.carto; + +import com.fasterxml.jackson.annotation.JsonIdentityInfo; +import com.fasterxml.jackson.annotation.JsonIdentityReference; +import com.fasterxml.jackson.annotation.ObjectIdGenerators; +import fr.lirmm.aren.model.*; +import fr.lirmm.aren.model.ws.Message; + +import javax.persistence.*; +import java.io.Serializable; + +/** + * @author ANDRIAMBOLAHARIMIHANTA Havana + * @created 13/10/2021 - 05:38 + * @project aren-1 + */ +@Entity +@Table(name = "notifications_carto") +@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id", scope = CNotification.class) +public class CNotification extends AbstractOwnedEntity implements Serializable { + + @Lob + private Message content; + + @Column(name = "is_unread") + private boolean unread = true; + + @JsonIdentityReference(alwaysAsId = true) + @JoinColumn(name = "debate_id", referencedColumnName = "id", updatable = false) + @ManyToOne() + private CDebate debate; + + @JsonIdentityReference(alwaysAsId = true) + @JoinColumn(name = "comment_id", referencedColumnName = "id", updatable = false) + @ManyToOne() + private CComment comment; + + /** + * + */ + public CNotification() { + } + + private CNotification(User owner, CDebate debate, CComment comment) { + this.owner = owner; + this.debate = debate; + this.comment = comment; + } + + /** + * + * @param comment + * @return + */ + public static CNotification COMMENT_MODERATED(CComment comment) { + CNotification n = new CNotification(comment.getOwner(), comment.getDebate(), comment); + n.content = new Message("comment_moderated"); + n.content.addDetail("debateName", comment.getDebate().getDocument().getName()); + return n; + } + + /** + * + * @param modo + * @param comment + * @return + */ + public static CNotification COMMENT_SINGNALED(User modo, CComment comment) { + CNotification n = new CNotification(modo, comment.getDebate(), comment); + n.content = new Message("comment_signaled"); + n.content.addDetail("debateName", comment.getDebate().getDocument().getName()); + return n; + } + + /** + * + * @param owner + * @param comment + * @return + */ + public static CNotification COMMENT_ANSWERED(User owner, CComment comment) { + CNotification n = new CNotification(owner, comment.getDebate(), comment); + n.content = new Message("comment_answered"); + n.content.addDetail("firstName", comment.getOwner().getFirstName()); + n.content.addDetail("lastName", comment.getOwner().getLastName()); + return n; + } + + /** + * + * @param owner + * @param debate + * @return + */ + public static CNotification INVITED_TO_DEBATE(User owner, CDebate debate) { + CNotification n = new CNotification(owner, debate, null); + n.content = new Message("invited_to_debate"); + n.content.addDetail("debateName", debate.getDocument().getName()); + return n; + } + + /** + * + * @param owner + * @param debate + * @param team + * @return + */ + public static CNotification TEAM_ADDED_TO_DEBATE(User owner, CDebate debate, Team team) { + CNotification n = new CNotification(owner, debate, null); + n.content = new Message("team_added_to_debate"); + n.content.addDetail("debateName", debate.getDocument().getName()); + n.content.addDetail("teamName", team.getName()); + return n; + } + + /** + * + * @return + */ + public Message getContent() { + return content; + } + + /** + * + * @param content + */ + public void setContent(Message content) { + this.content = content; + } + + /** + * + * @return + */ + public boolean isUnread() { + return unread; + } + + /** + * + * @param unread + */ + public void setUnread(boolean unread) { + this.unread = unread; + } + + /** + * + * @return + */ + public CDebate getDebate() { + return debate; + } + + /** + * + * @param debate + */ + public void setDebate(CDebate debate) { + this.debate = debate; + } + + /** + * + * @return + */ + public CComment getComment() { + return comment; + } + + /** + * + * @param comment + */ + public void setComment(CComment comment) { + this.comment = comment; + } + + @JsonIdentityReference(alwaysAsId = true) + @Override + public User getOwner() { + return super.getOwner(); + } +} diff --git a/src/main/java/fr/lirmm/aren/service/BroadcasterService.java b/src/main/java/fr/lirmm/aren/service/BroadcasterService.java index 3e0c384..52d98e5 100644 --- a/src/main/java/fr/lirmm/aren/service/BroadcasterService.java +++ b/src/main/java/fr/lirmm/aren/service/BroadcasterService.java @@ -12,6 +12,9 @@ import fr.lirmm.aren.model.AbstractEntity; import fr.lirmm.aren.model.Comment; import fr.lirmm.aren.model.Debate; import fr.lirmm.aren.model.Notification; +import fr.lirmm.aren.model.carto.CComment; +import fr.lirmm.aren.model.carto.CDebate; +import fr.lirmm.aren.model.carto.CNotification; import fr.lirmm.aren.security.AuthenticatedUserDetails; import javax.ws.rs.core.SecurityContext; import javax.ws.rs.sse.OutboundSseEvent; @@ -114,4 +117,30 @@ public class BroadcasterService { broadcastNotification(notif); }); } + + /** + * + * @param comment + */ + public void broadcastCommentCarto(CComment comment) { + broadcast(comment.getDebate().getId(), comment, CDebate.class); + } + + /** + * + * @param notif + */ + public void broadcastNotificationCarto(CNotification notif) { + broadcast(notif.getOwner().getId(), notif, CNotification.class); + } + + /** + * + * @param notifs + */ + public void broadcastNotificationCarto(List notifs) { + notifs.forEach(notif -> { + broadcastNotificationCarto(notif); + }); + } } diff --git a/src/main/java/fr/lirmm/aren/service/carto/CCategoryService.java b/src/main/java/fr/lirmm/aren/service/carto/CCategoryService.java new file mode 100644 index 0000000..aa60f63 --- /dev/null +++ b/src/main/java/fr/lirmm/aren/service/carto/CCategoryService.java @@ -0,0 +1,88 @@ +package fr.lirmm.aren.service.carto; + +import fr.lirmm.aren.model.User; +import fr.lirmm.aren.model.carto.CCategory; +import fr.lirmm.aren.service.AbstractService; + +import javax.enterprise.context.ApplicationScoped; +import javax.persistence.TypedQuery; +import javax.ws.rs.NotFoundException; +import java.util.HashSet; +import java.util.List; + +/** + * @author ANDRIAMBOLAHARIMIHANTA Havana + * @created 25/09/2021 - 06:44 + * @project aren-1 + */ +@ApplicationScoped +public class CCategoryService extends AbstractService { + + /** + * + */ + public CCategoryService() { + super(CCategory.class); + } + + private TypedQuery generateQuery(Long categoryId, User user, boolean withDocuments) { + boolean isUser = user != null && user.is(User.Authority.USER) && !user.is(User.Authority.ADMIN); + boolean onlyPublic = user != null && user.getAuthority().equals(User.Authority.GUEST); + TypedQuery query = getEntityManager().createQuery("SELECT c " + + "FROM CCategory c " + + (withDocuments || isUser || onlyPublic + ? "LEFT JOIN " + (withDocuments ? "FETCH" : "") + " c.documents do " + : "") + + (isUser || onlyPublic + ? "LEFT JOIN do.debates d " + : "") + + (categoryId != null + ? "WHERE c.id = :categoryId " + : "WHERE c.id IS NOT NULL ") + + (isUser + ? "AND (d.openPublic IS TRUE " + + "OR :user = d.owner " + + "OR :user IN (SELECT u FROM d.guests u) " + + "OR :user IN (SELECT u FROM d.teams t LEFT JOIN t.users u)) " + : (onlyPublic + ? "AND d.openPublic IS TRUE " + : "")), + CCategory.class); + if (categoryId != null) { + query.setParameter("categoryId", categoryId); + } + if (isUser) { + query.setParameter("user", user); + } + return query; + } + + public CCategory findByUser(Long categoryId, User user, boolean withDocuments) { + List results = generateQuery(categoryId, user, withDocuments).getResultList(); + if (results.isEmpty()) { + throw new NotFoundException(); + } + return results.get(0); + } + + public HashSet findAllByUser(User user, boolean withDocuments) { + return new HashSet(generateQuery(null, user, withDocuments).getResultList()); + } + + /** + * + * @param categoryId + * @return + */ + public CCategory find(Long categoryId) { + return findByUser(categoryId, null, false); + } + + /** + * + * @return + */ + public HashSet findAll() { + return findAllByUser(null, false); + } +} diff --git a/src/main/java/fr/lirmm/aren/service/carto/CCommentService.java b/src/main/java/fr/lirmm/aren/service/carto/CCommentService.java new file mode 100644 index 0000000..4140565 --- /dev/null +++ b/src/main/java/fr/lirmm/aren/service/carto/CCommentService.java @@ -0,0 +1,153 @@ +package fr.lirmm.aren.service.carto; + +import fr.lirmm.aren.model.carto.CComment; +import fr.lirmm.aren.service.AbstractService; +import fr.lirmm.aren.service.HttpRequestService; +import javax.enterprise.context.ApplicationScoped; +import javax.inject.Inject; +import javax.ws.rs.NotFoundException; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +/** + * @author ANDRIAMBOLAHARIMIHANTA Havana + * @created 11/10/2021 - 17:57 + * @project aren-1 + */ +@ApplicationScoped +public class CCommentService extends AbstractService { + @Inject + private HttpRequestService httpRequestService; + + /** + * + */ + public CCommentService() { + super(CComment.class); + } + + /** + * + * @param entity + */ + @Override + protected void afterCreate(CComment entity) { + this.updateExternaleTables(entity); + } + + /** + * + * @param entity + */ + @Override + protected void afterRemove(CComment entity) { + this.updateExternaleTables(entity); + } + + /** + * + * @param commentId + * @return + */ + public CComment find(Long commentId) { + List results = getEntityManager().createQuery("SELECT c " + + "FROM CComment c " + + "WHERE c.id = :commentId ", CComment.class) + .setParameter("commentId", commentId) + .setMaxResults(1) + .getResultList(); + if (results.isEmpty()) { + throw new NotFoundException(); + } + return results.get(0); + } + + /** + * + * @return + */ + public Set findAll() { + return new HashSet(getEntityManager().createQuery("SELECT c " + + "FROM CComment c", CComment.class) + .getResultList()); + } + + /** + * + * @param ids + * @return + */ + public Set findAll(List ids) { + return new HashSet(getEntityManager().createQuery("SELECT c " + + "FROM CComment c " + + "WHERE id IN :ids", CComment.class) + .setParameter("ids", ids) + .getResultList()); + } + + /** + * + * @param commentId + * @return + */ + public void clear(Long commentId) { + CComment comment=this.find(commentId) ; + super.remove(comment); + this.afterRemove(comment) ; + } + + public void removeTreeComment(Long id){ + System.out.println("id : "+id); + List comments = getEntityManager().createNativeQuery("WITH RECURSIVE _comments AS ( " + + "SELECT id, created,argumentation,end_container,end_offset, moderated,proposed_tags,reformulation,selection,signaled,start_container,start_offset,owner_id,debate_id,parent_id " + +"FROM comments " + + "WHERE id=?1 " + +"UNION SELECT c.id, c.created,c.argumentation,c.end_container,c.end_offset,c.moderated,c.reformulation,c.selection,c.signaled,c.start_container,c.start_offset,c.owner_id,c.debate_id,c.parent_id " + +"FROM comments_carto c " + +"INNER JOIN _comments _coms ON _coms.id=c.parent_id" + +") SELECT * FROM _comments " + +"ORDER BY id DESC", CComment.class) + .setParameter(1,id) + .getResultList(); + + + if (!comments.isEmpty()) { + //Collections.sort(comments, (c1, c2) -> (c1.getParent()!=null && c2.getParent()!=null)?c1.getParent().getId().compareTo(c1.getParent().getId()):-1); + + for(CComment comment : comments){ + this.deleteNotification(comment.getId()) ; + this.remove(comment); + } + } + } + + private void deleteNotification(Long idComment){ + this.transactionBegin(); + getEntityManager().createQuery("DELETE FROM CNotification notif " + + "WHERE notif.comment.id = :idComment") + .setParameter("idComment", idComment) + .executeUpdate(); + this.commit(); + } + + /** + * + * @param comment + */ + public void updateExternaleTables(CComment comment) { + super.transactionBegin(); + getEntityManager().createQuery("UPDATE CDebate d SET " + + "d.lastCommentDate = (SELECT MAX(c.created) FROM d.comments c), " + + "d.commentsCount = (SELECT COUNT(c) FROM d.comments c) " + + "WHERE d.id = :id") + .setParameter("id", comment.getDebate().getId()) + .executeUpdate(); + getEntityManager().createQuery("UPDATE CCategory cat SET " + + "cat.lastCommentDate = (SELECT MAX(c.created) FROM cat.documents doc LEFT JOIN doc.debates d LEFT JOIN d.comments c) " + + "WHERE cat.id = :id") + .setParameter("id", comment.getDebate().getDocument().getCategory().getId()) + .executeUpdate(); + super.commit(); + } +} diff --git a/src/main/java/fr/lirmm/aren/service/carto/CDebateService.java b/src/main/java/fr/lirmm/aren/service/carto/CDebateService.java new file mode 100644 index 0000000..6714baf --- /dev/null +++ b/src/main/java/fr/lirmm/aren/service/carto/CDebateService.java @@ -0,0 +1,229 @@ +package fr.lirmm.aren.service.carto; + +import fr.lirmm.aren.model.User; +import fr.lirmm.aren.model.carto.CDebate; +import fr.lirmm.aren.service.AbstractService; + +import javax.enterprise.context.ApplicationScoped; +import javax.persistence.TypedQuery; +import javax.ws.rs.NotFoundException; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +/** + * @author ANDRIAMBOLAHARIMIHANTA Havana + * @created 11/10/2021 - 17:56 + * @project aren-1 + */ +@ApplicationScoped +public class CDebateService extends AbstractService { + + /** + * + */ + public CDebateService() { + super(CDebate.class); + } + + /** + * + * @param entity + */ + @Override + protected void afterCreate(CDebate entity) { + this.updateExternaleTables(entity); + } + + /** + * + * @param entity + */ + @Override + protected void afterRemove(CDebate entity) { + this.updateExternaleTables(entity); + } + + /** + * + * @param entity + */ + @Override + protected void afterEdit(CDebate entity) { + this.updateExternaleTables(entity); + } + + private TypedQuery generateQuery(Long debateId, User user, Long categoryId, boolean withDocument, boolean withComments, boolean withTeams, boolean withGuests, boolean withUsers) { + boolean isUser = user != null && user.is(User.Authority.USER) && !user.is(User.Authority.ADMIN); + boolean onlyPublic = user != null && user.getAuthority().equals(User.Authority.GUEST); + TypedQuery query = getEntityManager().createQuery("SELECT d " + + "FROM CDebate d " + + (withComments + ? "LEFT JOIN FETCH d.comments c " + : "") + + (withTeams || withUsers || isUser + ? "LEFT JOIN " + (withTeams || withUsers ? "FETCH" : "") + " d.teams t " + : "") + + (withUsers || isUser + ? "LEFT JOIN " + (withUsers ? "FETCH" : "") + " t.users u " + : "") + + (withGuests || isUser + ? "LEFT JOIN " + (withGuests ? "FETCH" : "") + " d.guests g " + : "") + + (withDocument + ? "LEFT JOIN FETCH d.document do " + : "") + + (debateId != null + ? "WHERE d.id = :debateId " + : "WHERE d.id IS NOT NULL ") + + (categoryId != null + ? "AND d.document.category.id = :categoryId " + : "") + + (isUser + ? "AND (d.openPublic IS TRUE " + + "OR :user = d.owner " + + "OR :user IN g " + + "OR :user IN u) " + : (onlyPublic + ? "AND d.openPublic IS TRUE " + : "")), + CDebate.class + ); + + if (debateId != null) { + query.setParameter("debateId", debateId); + } + if (isUser) { + query.setParameter("user", user); + } + if (categoryId != null) { + query.setParameter("categoryId", categoryId); + } + return query; + } + + /** + * + * @param debateId + * @param user + * @param withDocument + * @param withComments + * @param withTeams + * @param withGuests + * @param withUsers + * @return + */ + public CDebate findByUser(Long debateId, User user, boolean withDocument, boolean withComments, boolean withTeams, boolean withGuests, boolean withUsers) { + List results = generateQuery(debateId, user, null, withDocument, withComments, withTeams, withGuests, withUsers).getResultList(); + if (results.isEmpty()) { + throw new NotFoundException(); + } + return results.get(0); + } + + public void remove(Long debateId){ + super.transactionBegin(); + try{ + getEntityManager().createNativeQuery("DELETE FROM debates_teams_carto WHERE debate_id=:debateId") + .setParameter("debateId",debateId) + .executeUpdate() ; + getEntityManager().createNativeQuery("DELETE FROM debates_guestss_carto WHERE debate_id=:debateId") + .setParameter("debateId",debateId) + .executeUpdate() ; + getEntityManager().createNativeQuery("DELETE FROM notifications_carto WHERE debate_id = :debateId") + .setParameter("debateId", debateId) + .executeUpdate(); + super.commit(); + CDebate debate=super.find(debateId) ; + super.remove(debate); + }catch (Exception e){ + e.printStackTrace(); + } + } + + /** + * + * @param user + * @param categoryId + * @param withDocument + * @param withComments + * @param withTeams + * @param withGuests + * @param withUsers + * @return + */ + public Set findAllByUser(User user, Long categoryId, boolean withDocument, boolean withComments, boolean withTeams, boolean withGuests, boolean withUsers) { + return new HashSet(generateQuery(null, user, categoryId, withDocument, withComments, withTeams, withGuests, withUsers).getResultList()); + } + + /** + * + * @param debateId + * @param withDocument + * @param withComments + * @param withTeams + * @param withGuests + * @param withUsers + * @return + */ + public CDebate find(Long debateId, boolean withDocument, boolean withComments, boolean withTeams, boolean withGuests, boolean withUsers) { + return findByUser(debateId, null, withDocument, withComments, withTeams, withGuests, withUsers); + } + + /** + * + * @param categoryId + * @param withDocument + * @param withComments + * @param withTeams + * @param withGuests + * @param withUsers + * @return + */ + public Set findAll(Long categoryId, boolean withDocument, boolean withComments, boolean withTeams, boolean withGuests, boolean withUsers) { + return findAllByUser(null, categoryId, withDocument, withComments, withTeams, withGuests, withUsers); + } + + /** + * + * @param debateId + */ + public void clearComments(Long debateId) { + this.transactionBegin(); + getEntityManager().createQuery("DELETE FROM CComment c " + + "WHERE c.debate.id = :debateId") + .setParameter("debateId", debateId) + .executeUpdate(); + getEntityManager().createQuery("UPDATE CDebate d SET " + + "d.commentsCount = 0, " + + "d.lastCommentDate = null " + + "WHERE d.id = :debateId") + .setParameter("debateId", debateId) + .executeUpdate(); + this.commit(); + } + + /** + * + * @param debate + */ + public void updateExternaleTables(CDebate debate) { + super.transactionBegin(); + getEntityManager().createQuery("UPDATE CCategory c SET " + + "c.debatesCount = (SELECT COUNT(d) FROM c.documents doc LEFT JOIN doc.debates d) " + + "WHERE c.id = :id") + .setParameter("id", debate.getDocument().getCategory().getId()) + .executeUpdate(); + getEntityManager().createQuery("UPDATE CDocument doc SET " + + "doc.debatesCount = (SELECT COUNT(d) FROM doc.debates d) " + + "WHERE doc.id = :id") + .setParameter("id", debate.getDocument().getId()) + .executeUpdate(); + getEntityManager().createQuery("UPDATE Team t SET " + + "t.debatesCount = (SELECT COUNT(d) from t.debates d) " + + "WHERE t IN (SELECT t1 FROM CDebate d LEFT JOIN d.teams t1 WHERE d.id = :id)") + .setParameter("id", debate.getId()) + .executeUpdate(); + super.commit(); + } +} diff --git a/src/main/java/fr/lirmm/aren/service/carto/CDocumentService.java b/src/main/java/fr/lirmm/aren/service/carto/CDocumentService.java new file mode 100644 index 0000000..1c62e44 --- /dev/null +++ b/src/main/java/fr/lirmm/aren/service/carto/CDocumentService.java @@ -0,0 +1,98 @@ +package fr.lirmm.aren.service.carto; + +import fr.lirmm.aren.model.carto.CDocument; +import fr.lirmm.aren.service.AbstractService; + +import javax.enterprise.context.ApplicationScoped; +import javax.persistence.TypedQuery; +import javax.ws.rs.NotFoundException; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +/** + * @author ANDRIAMBOLAHARIMIHANTA Havana + * @created 11/10/2021 - 17:56 + * @project aren-1 + */ +@ApplicationScoped +public class CDocumentService extends AbstractService { + + /** + * + */ + public CDocumentService() { + super(CDocument.class); + } + + /** + * + * @param entity + */ + @Override + protected void afterCreate(CDocument entity) { + this.updateExternaleTables(entity); + } + + /** + * + * @param entity + */ + @Override + protected void afterRemove(CDocument entity) { + this.updateExternaleTables(entity); + } + + private TypedQuery generateQuery(Long documentId, boolean withDebates) { + TypedQuery query = getEntityManager().createQuery("SELECT do " + + "FROM CDocument do " + + (withDebates + ? "LEFT JOIN FETCH do.debates d " + : "") + + (documentId != null + ? "WHERE do.id = :documentId " + : ""), + CDocument.class); + if (documentId != null) { + query.setParameter("documentId", documentId); + } + return query; + } + + /** + * + * @param debateId + * @param withDebates + * @return + */ + public CDocument find(Long debateId, boolean withDebates) { + List results = generateQuery(debateId, withDebates).getResultList(); + if (results.isEmpty()) { + throw new NotFoundException(); + } + return results.get(0); + } + + /** + * + * @param withDebates + * @return + */ + public Set findAll(boolean withDebates) { + return new HashSet(generateQuery(null, withDebates).getResultList()); + } + + /** + * + * @param document + */ + public void updateExternaleTables(CDocument document) { + super.transactionBegin(); + getEntityManager().createQuery("UPDATE CCategory c SET " + + "c.documentsCount = (SELECT COUNT(doc) FROM c.documents doc) " + + "WHERE c.id = :id") + .setParameter("id", document.getCategory().getId()) + .executeUpdate(); + super.commit(); + } +} diff --git a/src/main/java/fr/lirmm/aren/service/carto/CNotificationService.java b/src/main/java/fr/lirmm/aren/service/carto/CNotificationService.java new file mode 100644 index 0000000..e8e87f3 --- /dev/null +++ b/src/main/java/fr/lirmm/aren/service/carto/CNotificationService.java @@ -0,0 +1,91 @@ +package fr.lirmm.aren.service.carto; + +import fr.lirmm.aren.model.carto.CNotification; +import fr.lirmm.aren.service.AbstractService; + +import javax.enterprise.context.ApplicationScoped; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +/** + * @author ANDRIAMBOLAHARIMIHANTA Havana + * @created 25/09/2021 - 06:44 + * @project aren-1 + */ +@ApplicationScoped +public class CNotificationService extends AbstractService { + + /** + * + */ + public CNotificationService() { + super(CNotification.class); + } + + /** + * + * @param userId + * @return + */ + public Set findAllByUser(Long userId) { + + List notifs = getEntityManager().createQuery("SELECT n " + + "FROM CNotification n " + + "WHERE n.owner.id = :userId " + + "ORDER BY n.created DESC", CNotification.class) + .setParameter("userId", userId) + .getResultList(); + if (notifs.isEmpty()) { + return null; + } + return new HashSet(notifs); + } + + /** + * + * @param userId + * @param readenLimit + * @return + */ + public Set findAllFirstsByUser(Long userId, int readenLimit) { + return new HashSet(getEntityManager().createQuery("SELECT n1 " + + "FROM CNotification n1 " + + "WHERE n1.owner.id = :userId " + + "AND (n1.unread = true " + + "OR (SELECT COUNT(id) " + + " FROM CNotification n2 " + + " WHERE n2.owner.id = :userId " + + " AND n2.created >= n1.created) <= :readenLimit)") + .setParameter("userId", userId) + .setParameter("readenLimit", Long.valueOf(readenLimit)) + .getResultList()); + } + + /** + * + * @param userId + */ + public void readAllByUser(Long userId) { + super.transactionBegin(); + getEntityManager().createQuery("UPDATE CNotification n " + + "SET n.unread = false " + + "WHERE n.owner.id = :userId") + .setParameter("userId", userId) + .executeUpdate(); + super.commit(); + } + + /** + * + * @param userId + */ + public void removeAllByUser(Long userId) { + super.transactionBegin(); + getEntityManager().createQuery("DELETE CNotification n " + + "WHERE n.owner.id = :userId") + .setParameter("userId", userId) + .executeUpdate(); + super.commit(); + } +} \ No newline at end of file diff --git a/src/main/java/fr/lirmm/aren/ws/JerseyConfig.java b/src/main/java/fr/lirmm/aren/ws/JerseyConfig.java index 40927b0..6357cf2 100644 --- a/src/main/java/fr/lirmm/aren/ws/JerseyConfig.java +++ b/src/main/java/fr/lirmm/aren/ws/JerseyConfig.java @@ -23,6 +23,8 @@ public class JerseyConfig extends ResourceConfig { packages("fr.lirmm.aren.ws.rest"); + packages("fr.lirmm.aren.ws.rest.carto"); + packages("fr.lirmm.aren.ws.filter"); packages("fr.lirmm.aren.ws.exceptionmapper"); diff --git a/src/main/java/fr/lirmm/aren/ws/rest/NotificationRESTFacade.java b/src/main/java/fr/lirmm/aren/ws/rest/NotificationRESTFacade.java index 6bf855c..b8bcd23 100644 --- a/src/main/java/fr/lirmm/aren/ws/rest/NotificationRESTFacade.java +++ b/src/main/java/fr/lirmm/aren/ws/rest/NotificationRESTFacade.java @@ -83,5 +83,4 @@ public class NotificationRESTFacade extends AbstractRESTFacade { } return entityToUpdate; } - } diff --git a/src/main/java/fr/lirmm/aren/ws/rest/carto/CCategoryRESTFacade.java b/src/main/java/fr/lirmm/aren/ws/rest/carto/CCategoryRESTFacade.java new file mode 100644 index 0000000..c917e47 --- /dev/null +++ b/src/main/java/fr/lirmm/aren/ws/rest/carto/CCategoryRESTFacade.java @@ -0,0 +1,84 @@ +package fr.lirmm.aren.ws.rest.carto; + +import fr.lirmm.aren.model.carto.CCategory; +import fr.lirmm.aren.service.carto.CCategoryService; +import fr.lirmm.aren.ws.rest.AbstractRESTFacade; + +import javax.annotation.security.RolesAllowed; +import javax.enterprise.context.RequestScoped; +import javax.inject.Inject; +import javax.ws.rs.Path; +import java.util.HashSet; + +/** + * @author ANDRIAMBOLAHARIMIHANTA Havana + * @created 13/10/2021 - 06:59 + * @project aren-1 + */ +@RequestScoped +@Path("carto/categories") +public class CCategoryRESTFacade extends AbstractRESTFacade { + + @Inject + private CCategoryService categoryService; + + /** + * + * @return + */ + @Override + protected CCategoryService getService() { + return categoryService; + } + + /** + * + * @param category + * @return + */ + @Override + @RolesAllowed({"MODO"}) + public CCategory create(CCategory category) { + return super.create(category); + } + + /** + * + * @param category + * @return + */ + @Override + @RolesAllowed({"MODO"}) + public CCategory edit(Long id, CCategory category) { + return super.edit(id, category); + } + + /** + * + * @return + */ + @Override + @RolesAllowed({"GUEST"}) + public HashSet findAll() { + boolean withDocument = false; + if (getUser().is("MODO")) { + withDocument = this.overview == null; + } + return categoryService.findAllByUser(getUser(), withDocument); + } + + /** + * + * @param id + * @return + */ + @Override + @RolesAllowed({"GUEST"}) + public CCategory find(Long id) { + boolean withDocument = false; + if (getUser().is("MODO")) { + withDocument = this.overview == null; + } + return categoryService.findByUser(id, getUser(), withDocument); + } +} diff --git a/src/main/java/fr/lirmm/aren/ws/rest/carto/CCommentRESTFacade.java b/src/main/java/fr/lirmm/aren/ws/rest/carto/CCommentRESTFacade.java new file mode 100644 index 0000000..0d4734f --- /dev/null +++ b/src/main/java/fr/lirmm/aren/ws/rest/carto/CCommentRESTFacade.java @@ -0,0 +1,70 @@ +package fr.lirmm.aren.ws.rest.carto; + +import fr.lirmm.aren.model.TagSet; +import fr.lirmm.aren.model.carto.CComment; +import fr.lirmm.aren.service.BroadcasterService; +import fr.lirmm.aren.service.HttpRequestService; +import fr.lirmm.aren.service.carto.CCommentService; +import fr.lirmm.aren.ws.rest.AbstractRESTFacade; + +import javax.annotation.security.PermitAll; +import javax.annotation.security.RolesAllowed; +import javax.enterprise.context.RequestScoped; +import javax.inject.Inject; +import javax.ws.rs.*; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.sse.Sse; +import javax.ws.rs.sse.SseEventSink; + +/** + * @author ANDRIAMBOLAHARIMIHANTA Havana + * @created 13/10/2021 - 06:58 + * @project aren-1 + */ +@RequestScoped +@Path("carto/comments") +public class CCommentRESTFacade extends AbstractRESTFacade { + + @Inject + private CCommentService commentService; + + @Inject + private BroadcasterService broadcasterService; + + @Inject + private HttpRequestService httpRequestService; + + /** + * + * @return + */ + @Override + protected CCommentService getService() { + return commentService; + } + + /** + * + * @param comment + * @return + */ + @Override + @RolesAllowed({"USER"}) + public CComment create(CComment comment) { + return super.create(comment) ; + } + + @Override + @RolesAllowed({"USER"}) + public CComment edit(Long id, CComment comment) { + return super.edit(id, comment) ; + } + + @DELETE + @Path("/delete/{id}") + @PermitAll + public void findTreeById(@PathParam("id") Long id){ + commentService.removeTreeComment(id) ; + } +} diff --git a/src/main/java/fr/lirmm/aren/ws/rest/carto/CDebateRESTFacade.java b/src/main/java/fr/lirmm/aren/ws/rest/carto/CDebateRESTFacade.java new file mode 100644 index 0000000..9b181ec --- /dev/null +++ b/src/main/java/fr/lirmm/aren/ws/rest/carto/CDebateRESTFacade.java @@ -0,0 +1,352 @@ +package fr.lirmm.aren.ws.rest.carto; + +import fr.lirmm.aren.exception.InsertEntityException; +import fr.lirmm.aren.model.Team; +import fr.lirmm.aren.model.User; +import fr.lirmm.aren.model.carto.CComment; +import fr.lirmm.aren.model.carto.CDebate; +import fr.lirmm.aren.model.carto.CNotification; +import fr.lirmm.aren.service.*; +import fr.lirmm.aren.service.carto.CCommentService; +import fr.lirmm.aren.service.carto.CDebateService; +import fr.lirmm.aren.service.carto.CNotificationService; +import fr.lirmm.aren.ws.rest.AbstractRESTFacade; + +import javax.annotation.security.RolesAllowed; +import javax.enterprise.context.RequestScoped; +import javax.inject.Inject; +import javax.ws.rs.*; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; +import java.util.Set; + +/** + * @author ANDRIAMBOLAHARIMIHANTA Havana + * @created 13/10/2021 - 06:58 + * @project aren-1 + */ +@RequestScoped +@Path("carto/debates") +public class CDebateRESTFacade extends AbstractRESTFacade { + + @Inject + private CDebateService debateService; + + @Inject + private CNotificationService notificationService; + + @Inject + private CCommentService commentService; + + @Inject + private CCommentRESTFacade commentFacade; + + @Inject + private BroadcasterService broadcasterService; + + @Inject + private TeamService teamService; + + @Inject + private UserService userService; + + @Inject + private ODFService odfService; + + @Inject + private HttpRequestService httpRequestService; + + /** + * + */ + @QueryParam("category") + protected Long category; + + /** + * + * @return + */ + @Override + protected CDebateService getService() { + return debateService; + } + + /** + * + * @return + */ + @Override + @RolesAllowed({"GUEST"}) + public Set findAll() { + boolean withComments = (this.overview == null); + boolean isModo = getUser().is("MODO"); + return debateService.findAllByUser(getUser(), category, true, withComments, isModo, isModo, false); + } + + /** + * + * @param id + * @return + */ + @Override + @RolesAllowed({"GUEST"}) + public CDebate find(Long id) { + + boolean withComments = (this.overview == null); + return debateService.findByUser(id, getUser(), true, withComments, true, true, false); + } + + /** + * + * @param debate + * @return + */ + @Override + @RolesAllowed({"MODO"}) + public CDebate create(CDebate debate) { + Set teams = debate.getTeams(); + Set guests = debate.getGuests(); + super.create(debate); + debate.getTeams().addAll(teams); + debate.getGuests().addAll(guests); + debateService.edit(debate); + + CDebate newDebate = debateService.find(debate.getId(), false, false, true, true, true); + + List notifications = new ArrayList(); + + newDebate.getTeams().forEach((Team team) -> { + team.getUsers().forEach((User user) -> { + notifications.add(CNotification.TEAM_ADDED_TO_DEBATE(user, newDebate, team)); + }); + }); + + newDebate.getGuests().forEach((User user) -> { + notifications.add(CNotification.INVITED_TO_DEBATE(user, newDebate)); + }); + + notificationService.create(notifications); + broadcasterService.broadcastNotificationCarto(notifications); + + return newDebate; + } + + /** + * + * @param id + */ + @Override + @RolesAllowed({"ADMIN"}) + public void remove(Long id) { + debateService.clearComments(id); + debateService.remove(id); + } + + /** + * Creates a new Comment onto a Debate + * + * @param id of the debate + * @param comment to add + * @return + */ + @POST + @Path("{id}/comments") + @RolesAllowed({"USER"}) + public CComment addComment(@PathParam("id") Long id, CComment comment) { + + CDebate debate = debateService.findByUser(id, getUser(), false, false, false, false, false); + CComment parent = null; + + if (comment.getParent() != null) { + parent = commentService.getReference(comment.getParent().getId()); + if (!Objects.equals(debate, parent.getDebate())) { + throw InsertEntityException.INVALID_PARENT(); + } + } + + commentFacade.create(comment); + + List notifications = new ArrayList(); + List users = new ArrayList(); + while (parent != null) { + // Only one notification per user + // And not notify oneself + if (!users.contains(parent.getOwner()) && parent.getOwner() != getUser()) { + notifications.add(CNotification.COMMENT_ANSWERED(parent.getOwner(), comment)); + users.add(parent.getOwner()); + } + parent = parent.getParent(); + } + + notificationService.create(notifications); + broadcasterService.broadcastNotificationCarto(notifications); + broadcasterService.broadcastCommentCarto(comment); + + //commentService.updateTags(comment); // It is long + broadcasterService.broadcastCommentCarto(comment); + + return comment; + } + + /** + * Remove all the comment of a debate + * + * @param id + */ + @DELETE + @Path("{id}/comments") + @RolesAllowed({"ADMIN"}) + public void clear(@PathParam("id") Long id) { + debateService.clearComments(id); + } + + /** + * Mark a Comment in a Debate as being signaled + * + * @param id of the debate holding the comment + * @param commentId of the comment to be signaled + * @return + */ + @PUT + @Path("{id}/signal/{commentId}") + @RolesAllowed({"USER"}) + public CComment signal(@PathParam("id") Long id, @PathParam("commentId") Long commentId) { + + CDebate debate = debateService.findByUser(id, getUser(), false, false, false, false, false); + CComment comment = commentService.find(commentId); + + if (comment.getDebate().equals(debate)) { + + comment.setSignaled(!comment.isSignaled()); + commentService.edit(comment); + + Set guests = debate.getGuests(); + guests.size(); + + List notifications = new ArrayList(); + + guests.forEach((User user) -> { + if (user.is("MODO")) { + notifications.add(CNotification.COMMENT_SINGNALED(user, comment)); + } + }); + + notificationService.create(notifications); + broadcasterService.broadcastNotificationCarto(notifications); + } + return comment; + } + + /** + * Mark a Comment in a Debate as being moderated + * + * @param id of the debate holding the comment + * @param commentId of the comment to be moderated + * @return + */ + @PUT + @Path("{id}/moderate/{commentId}") + @RolesAllowed({"MODO"}) + public CComment moderate(@PathParam("id") Long id, @PathParam("commentId") Long commentId) { + + debateService.findByUser(id, getUser(), false, false, false, false, false); + + CComment comment = commentService.find(id); + comment.setModerated(!comment.isModerated()); + commentService.edit(comment); + + CNotification notif = CNotification.COMMENT_MODERATED(comment); + notificationService.create(notif); + broadcasterService.broadcastNotificationCarto(notif); + + return comment; + } + + /** + * Add a Team to participate in a Debate + * + * @param id of the debate + * @param teamId of the team + */ + @PUT + @Path("{id}/teams/{teamId}") + @RolesAllowed({"MODO"}) + public void addTeam(@PathParam("id") Long id, @PathParam("teamId") Long teamId) { + + CDebate debate = debateService.findByUser(id, getUser(), false, false, true, false, false); + + Team team = teamService.find(teamId); + debate.addTeam(team); + debateService.edit(debate); + + List notifications = new ArrayList(); + + team.getUsers().forEach((User user) -> { + notifications.add(CNotification.TEAM_ADDED_TO_DEBATE(user, debate, team)); + }); + + notificationService.create(notifications); + broadcasterService.broadcastNotificationCarto(notifications); + + } + + /** + * Remove a Team to participate in a Debate + * + * @param id of the debate + * @param teamId of the team + */ + @DELETE + @Path("{id}/teams/{teamId}") + @RolesAllowed({"MODO"}) + public void removeTeam(@PathParam("id") Long id, @PathParam("teamId") Long teamId) { + + CDebate debate = debateService.findByUser(id, getUser(), false, false, true, false, false); + + Team team = teamService.find(teamId); + debate.removeTeam(team); + debateService.edit(debate); + + } + + /** + * Add a User to participate in a Debate + * + * @param id of the debate + * @param userId of the user + */ + @PUT + @Path("{id}/users/{userId}") + @RolesAllowed({"ADMIN", "MODO"}) + public void addGuest(@PathParam("id") Long id, @PathParam("userId") Long userId) { + + CDebate debate = debateService.findByUser(id, getUser(), false, false, false, true, false); + + User user = userService.find(userId); + debate.addGuest(user); + debateService.edit(debate); + + CNotification notif = CNotification.INVITED_TO_DEBATE(user, debate); + notificationService.create(notif); + broadcasterService.broadcastNotificationCarto(notif); + } + + /** + * Remove a User to participate in a Debate + * + * @param id of the debate + * @param userId of the user + */ + @DELETE + @Path("{id}/users/{userId}") + @RolesAllowed({"MODO"}) + public void removeGuest(@PathParam("id") Long id, @PathParam("userId") Long userId) { + + CDebate debate = debateService.findByUser(id, getUser(), false, false, false, true, false); + + User user = userService.find(userId); + debate.removeGuest(user); + debateService.edit(debate); + } +} \ No newline at end of file diff --git a/src/main/java/fr/lirmm/aren/ws/rest/carto/CDocumentRESTFacade.java b/src/main/java/fr/lirmm/aren/ws/rest/carto/CDocumentRESTFacade.java new file mode 100644 index 0000000..5081920 --- /dev/null +++ b/src/main/java/fr/lirmm/aren/ws/rest/carto/CDocumentRESTFacade.java @@ -0,0 +1,84 @@ +package fr.lirmm.aren.ws.rest.carto; +import fr.lirmm.aren.model.carto.CDocument; +import fr.lirmm.aren.service.carto.CDocumentService; +import fr.lirmm.aren.ws.rest.AbstractRESTFacade; + +import javax.annotation.security.RolesAllowed; +import javax.enterprise.context.RequestScoped; +import javax.inject.Inject; +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import java.util.Set; + +/** + * @author ANDRIAMBOLAHARIMIHANTA Havana + * @created 13/10/2021 - 06:58 + * @project aren-1 + */ +@RequestScoped +@Path("carto/documents") +public class CDocumentRESTFacade extends AbstractRESTFacade { + + @Inject + private CDocumentService documentService; + + /** + * + * @return + */ + @Override + protected CDocumentService getService() { + return documentService; + } + + /** + * + * @return + */ + @Override + @RolesAllowed({"MODO"}) + public Set findAll() { + boolean withDebates = this.overview == null; + return documentService.findAll(withDebates); + } + + /** + * + * @param id + * @return + */ + @Override + @RolesAllowed({"MODO"}) + public CDocument find(Long id) { + boolean withDebates = this.overview == null; + return documentService.find(id, withDebates); + } + + /** + * + * @param doc + * @return + */ + @Override + @RolesAllowed({"MODO"}) + public CDocument create(CDocument doc) { + return super.create(doc); + } + + /** + * Ducplicate a Documents withe the the associaitons + * + * @param id of the Document to duplicate + * @return the duplicated Document + */ + @POST + @Path("{id}/duplicate") + @RolesAllowed({"MODO"}) + public CDocument duplicate(@PathParam("id") Long id) { + + CDocument document = find(id); + + return this.create(document); + } +} diff --git a/src/main/java/fr/lirmm/aren/ws/rest/carto/CNotificationRESTFacade.java b/src/main/java/fr/lirmm/aren/ws/rest/carto/CNotificationRESTFacade.java new file mode 100644 index 0000000..7518d9c --- /dev/null +++ b/src/main/java/fr/lirmm/aren/ws/rest/carto/CNotificationRESTFacade.java @@ -0,0 +1,87 @@ +package fr.lirmm.aren.ws.rest.carto; + +import fr.lirmm.aren.model.carto.CNotification; +import fr.lirmm.aren.service.carto.CNotificationService; +import fr.lirmm.aren.ws.rest.AbstractRESTFacade; + +import javax.annotation.security.RolesAllowed; +import javax.enterprise.context.RequestScoped; +import javax.inject.Inject; +import javax.ws.rs.PUT; +import javax.ws.rs.Path; +import javax.ws.rs.QueryParam; +import java.util.Set; + +/** + * @author ANDRIAMBOLAHARIMIHANTA Havana + * @created 13/10/2021 - 06:58 + * @project aren-1 + */ +@RequestScoped +@Path("carto/notifications") +public class CNotificationRESTFacade extends AbstractRESTFacade { + + @Inject + private CNotificationService notificationService; + + /** + * + */ + @QueryParam("overview") + protected String overview; + + /** + * + * @return + */ + @Override + protected CNotificationService getService() { + return notificationService; + } + + /** + * + * @return + */ + @Override + @RolesAllowed({"USER"}) + public Set findAll() { + if (overview == null) { + return notificationService.findAllByUser(this.getUser().getId()); + } else { + return notificationService.findAllFirstsByUser(this.getUser().getId(), 10); + } + } + + /** + * Mark all Notifications of the current User as read + * + * @return + */ + @PUT + @RolesAllowed({"USER"}) + public Set readAll() { + notificationService.readAllByUser(this.getUser().getId()); + return notificationService.findAllFirstsByUser(this.getUser().getId(), 10); + } + + /** + * + * @param id + * @param notification + */ + @Override + @RolesAllowed({"USER"}) + public CNotification edit(Long id, CNotification notification) { + CNotification entityToUpdate; + if (this.getUser().is("SUPERADMIN")) { + notification.setContent(null); + entityToUpdate = super.edit(id, notification); + } else { + entityToUpdate = notificationService.find(id); + entityToUpdate.setUnread(notification.isUnread()); + notificationService.edit(entityToUpdate); + } + return entityToUpdate; + } +}