View Javadoc
1   package usecase.section;
2   
3   import media.MediaRepository;
4   import media.ReadLimitExceededException;
5   import media.validation.Image;
6   import model.entity.Section;
7   import model.entity.User;
8   import model.repository.GenericRepository;
9   import model.repository.SectionRepository;
10  import model.validation.SectionExists;
11  import model.validation.UniqueSection;
12  import usecase.auth.AdminsOnly;
13  import usecase.auth.CurrentUser;
14  
15  import javax.enterprise.context.ApplicationScoped;
16  import javax.enterprise.context.RequestScoped;
17  import javax.enterprise.inject.Produces;
18  import javax.inject.Inject;
19  import javax.inject.Named;
20  import javax.transaction.Transactional;
21  import javax.validation.constraints.NotBlank;
22  import javax.validation.constraints.NotNull;
23  import javax.validation.constraints.Size;
24  import java.io.BufferedInputStream;
25  import java.io.IOException;
26  import java.time.Instant;
27  import java.time.temporal.ChronoUnit;
28  import java.util.List;
29  import java.util.Map;
30  import java.util.stream.Collectors;
31  
32  /**
33   * Classe che fornisce i servizi relativi alle sezioni.
34   */
35  @ApplicationScoped
36  @Transactional
37  public class SectionService {
38      private SectionRepository sectionRepo;
39      private GenericRepository genericRepository;
40      private MediaRepository bcRepo;
41      private CurrentUser currentUser;
42  
43      protected SectionService(){}
44  
45      @Inject
46      protected SectionService(GenericRepository genericRepository, SectionRepository sectionRepository,
47                               MediaRepository bcRepo, CurrentUser currentUser){
48          this.genericRepository = genericRepository;
49          this.sectionRepo = sectionRepository;
50          this.bcRepo = bcRepo;
51          this.currentUser = currentUser;
52      }
53  
54      /**
55       * Converte section in SectionPage.
56       * @param section sezione da convertire
57       * @return SectionPage con i dati di section
58       */
59      private SectionPage map(Section section){
60          User user = null;
61          if(currentUser.isLoggedIn()){
62              user = genericRepository.findById(User.class,currentUser.getId());
63          }
64          return SectionPage.builder().id(section.getId())
65                  .name(section.getName())
66                  .picture(section.getPicture())
67                  .description(section.getDescription())
68                  .banner(section.getBanner())
69                  .nFollowers(section.getFollowCount())
70                  .isFollowed(user != null && section.getFollow(user) != null).build();
71      }
72  
73      /**
74       * Cancella una sezione dato il suo id
75       * @param id l'id di una sezione esistente
76       */
77      @AdminsOnly
78      public void delete(@SectionExists int id){
79          genericRepository.remove(genericRepository.findById(Section.class, id));
80      }
81  
82      /**
83       * Crea una nuova sezione e ne restituisce l'id
84       * @param name Nome della sezione
85       * @param description descrizione della sezione
86       * @param picture stream relativo alla foto della sezione
87       * @param banner stream relativo al banner della sezione
88       * @return id della sezione creata
89       */
90      @AdminsOnly
91      public int newSection(@NotBlank @Size(max=50) @UniqueSection String name,
92                            @Size(max=255) String description,
93                            @Image BufferedInputStream picture,
94                            @Image BufferedInputStream banner) {
95          Section s = new Section();
96          s.setName(name);
97          s.setDescription(description);
98          try {
99              if (picture != null)
100                 s.setPicture(bcRepo.insert(picture));
101             if (banner != null)
102                 s.setBanner(bcRepo.insert(banner));
103         } catch (ReadLimitExceededException e) {
104             throw new IllegalArgumentException("Il file non deve superare i 5MB");
105         } catch (IOException e) {
106             throw new RuntimeException(e);
107         }
108         return genericRepository.insert(s).getId();
109     }
110 
111     /**
112      * Ritorna una lista di tutte le sezioni esistenti
113      * @return lista di sezioni
114      */
115     public List<SectionPage> showSections(){
116         return genericRepository.findAll(Section.class).stream().map(this::map).collect(Collectors.toList());
117     }
118 
119     /**
120      * Ritorna una mappa di tutte le sezioni esistenti
121      * @return mappa la cui chiave è l'id della sezione e il valore un entita PostPage che ne contiene i dati
122      */
123     @Named("sections")
124     @RequestScoped
125     @Produces
126     public Map<Integer,SectionPage> getSectionsMap(){
127         return genericRepository.findAll(Section.class).stream().map(this::map)
128                 .collect(Collectors.toMap(SectionPage::getId, section -> section));
129     }
130 
131     /**
132      * Ritorna un entità sezione dato un certo id
133      * @param id id di una sezione esistente
134      * @return entita SectionPage che contiene i dati della sezione
135      */
136     public SectionPage showSection(@SectionExists int id){
137        Section s =  genericRepository.findById(Section.class, id);
138        return map(s);
139     }
140 
141     /**
142      * Ritorna un entità sezione con un nome specifico
143      * @param sectionName nome di una sezione esistente
144      * @return entita SectionPage che contiene i dati della sezione
145      */
146     public SectionPage getSection(@NotNull @SectionExists String sectionName){
147         Section s = genericRepository.findByNaturalId(Section.class,sectionName);
148         return map(s);
149     }
150 
151     /**
152      * Ritorna una lista delle sezioni con più follows
153      * @return lista di sezioni
154      */
155     @Produces
156     @RequestScoped
157     @Named("topSections")
158     public List<SectionPage> getTopSections(){
159         return sectionRepo.getMostFollowedSections().stream().map(this::map).collect(Collectors.toList());
160     }
161 
162     /**
163      * Ritorna una lista delle sezioni con più follows negli ultimi 7 giorni
164      * @return lista di sezioni
165      */
166     @Produces
167     @RequestScoped
168     @Named("trendingSections")
169     public List<SectionPage> getTrendingSections(){
170         return sectionRepo.getMostFollowedSections(Instant.now().minus(7, ChronoUnit.DAYS))
171                 .stream().map(this::map).collect(Collectors.toList());
172     }
173 }