View Javadoc
1   package usecase.comment;
2   
3   import model.entity.Comment;
4   import model.entity.CommentVote;
5   import model.entity.Post;
6   import model.entity.User;
7   import model.repository.CommentRepository;
8   import model.repository.GenericRepository;
9   import model.validation.CommentExists;
10  import model.validation.PostExists;
11  import usecase.auth.AuthenticationRequired;
12  import usecase.auth.AuthorizationException;
13  import usecase.auth.CurrentUser;
14  import usecase.auth.DenyBannedUsers;
15  
16  import javax.enterprise.context.ApplicationScoped;
17  import javax.inject.Inject;
18  import javax.transaction.Transactional;
19  import javax.validation.constraints.NotBlank;
20  import javax.validation.constraints.Size;
21  import java.time.Instant;
22  import java.util.List;
23  import java.util.Map;
24  
25  import static java.util.stream.Collectors.groupingBy;
26  import static java.util.stream.Collectors.toList;
27  
28  /**
29   * Classe che fornisce i servizi relativi ai commenti.
30   */
31  @ApplicationScoped
32  @Transactional
33  public class CommentService {
34      private GenericRepository genericRepository;
35      private CommentRepository commentRepo;
36      private CurrentUser currentUser;
37  
38      private static final int MAX_COMMENT_DEPTH = 4;
39  
40      protected CommentService(){}
41  
42      @Inject
43      protected CommentService(GenericRepository genericRepository, CommentRepository commentRepository,
44                                              CurrentUser currentUser){
45          this.genericRepository = genericRepository;
46          this.commentRepo = commentRepository;
47          this.currentUser = currentUser;
48      }
49  
50      /**
51       * Converte Comment in CommentDTO.
52       * @param comment commento da convertire
53       * @return commentDTO con i dati di comment
54       */
55      private CommentDTO map (Comment comment){
56          CommentVote commentVote = null;
57          if(currentUser.isLoggedIn()){
58              User user = genericRepository.findById(User.class, currentUser.getId());
59              commentVote = comment.getVote(user);
60          }
61  
62          return CommentDTO.builder()
63                  .id(comment.getId())
64                  .authorUsername(comment.getAuthor().getUsername())
65                  .authorId(comment.getAuthor().getId())
66                  .creationDate(comment.getCreationDate())
67                  .postId(comment.getPost().getId())
68                  .vote(commentVote == null ? 0 : commentVote.getVote())
69                  .content(comment.getContent())
70                  .votes(comment.getVotesCount() == null ? 0 : comment.getVotesCount())
71                  .creationDate(comment.getCreationDate()  == null ? Instant.now() : comment.getCreationDate())
72                  .parentCommentId(comment.getParentComment() == null ? 0 : comment.getParentComment().getId())
73                  .build();
74      }
75  
76      /**
77       * Ritorna una mappa la cui chiave è l'id del commento padre e il valore una lista di CommentDTO
78       * @param postId l'id di un post esistente di cui si vuole ottenere i commenti
79       * @return mappa con i commenti del post
80       */
81      public Map<Integer,List<CommentDTO>> getPostComments(@PostExists int postId){
82          List<Comment> comments = commentRepo.getByPost(genericRepository.findById(Post.class, postId), MAX_COMMENT_DEPTH);
83          return comments.stream().map(this::map).collect(groupingBy(CommentDTO::getParentCommentId, toList()));
84      }
85  
86      /**
87       * Ritorna una mappa la cui chiave è l'id del commento padre e il valore una lista di CommentDTO
88       * @param commentId l'id di un commento esistente di cui si vuole ottenere le risposte
89       * @return mappa con le risposte al commento
90       */
91      public Map<Integer, List<CommentDTO>> getReplies(@CommentExists int commentId){
92          List<Comment> comments = commentRepo.getReplies(genericRepository.findById(Comment.class, commentId), MAX_COMMENT_DEPTH);
93          return comments.stream().map(this::map).collect(groupingBy(CommentDTO::getParentCommentId, toList()));
94      }
95  
96      /**
97       * Ritorna un commento dato il suo id
98       * @param id l'id di un commento esistente
99       * @return commento avente l'id specificato
100      */
101     public CommentDTO getComment(@CommentExists int id){
102         return map(genericRepository.findById(Comment.class, id));
103     }
104 
105 
106     /**
107      * Cancella un commento dato il suo id
108      * @param id l'id di un commento esistente
109      */
110     @AuthenticationRequired
111     public void delete(@CommentExists int id){
112         Comment comment = genericRepository.findById(Comment.class, id);
113         if(currentUser.getId() != comment.getAuthor().getId() && !currentUser.isAdmin())
114             throw new AuthorizationException();
115         genericRepository.remove(genericRepository.findById(Comment.class, id));
116     }
117 
118     /**
119      * Modifica un commento dato il suo id
120      * @param id l'id di un commento esistente
121      * @param text stringa con testo da sostituire
122      */
123     @AuthenticationRequired
124     public void editComment(@CommentExists int id, @NotBlank @Size(max=65535) String text){
125         Comment comment = genericRepository.findById(Comment.class, id);
126         if(currentUser.getId() != comment.getAuthor().getId() && !currentUser.isAdmin())
127             throw new AuthorizationException();
128         comment.setContent(text);
129     }
130 
131     /**
132      * Crea un nuovo commento e ne restituisce l'id
133      * @param text una stringa non vuota di massimo 65535 caratteri
134      * @param postId id di un post esistente
135      * @return id del commento creato
136      */
137     @AuthenticationRequired
138     @DenyBannedUsers
139     public int newComment(@NotBlank @Size(max=65535) String text,
140                           @PostExists int postId){
141         User user = genericRepository.findById(User.class, currentUser.getId());
142 
143         Comment comment = new Comment();
144         comment.setAuthor(user);
145         comment.setContent(text);
146         comment.setPost(genericRepository.findById(Post.class, postId));
147         return genericRepository.insert(comment).getId();
148     }
149 
150     /**
151      * Crea una risposta a un commento e ne restituisce l'id
152      * @param text una stringa non vuota di massimo 1000 caratteri
153      * @param parentCommentId id di un commento esistente
154      * @return id del commento creato
155      */
156     @AuthenticationRequired
157     public int newCommentReply(@NotBlank @Size(max=65535) String text,
158                                @CommentExists int parentCommentId){
159         User user = genericRepository.findById(User.class, currentUser.getId());
160         Comment parent = genericRepository.findById(Comment.class, parentCommentId);
161 
162         Comment comment = new Comment();
163         comment.setAuthor(user);
164         comment.setContent(text);
165         comment.setPost(parent.getPost());
166         comment.setParentComment(parent);
167         return genericRepository.insert(comment).getId();
168     }
169 
170 }