001package usecase.section; 002 003import media.MediaRepository; 004import media.ReadLimitExceededException; 005import media.validation.Image; 006import model.entity.Section; 007import model.entity.User; 008import model.repository.GenericRepository; 009import model.repository.SectionRepository; 010import model.validation.SectionExists; 011import model.validation.UniqueSection; 012import usecase.auth.AdminsOnly; 013import usecase.auth.CurrentUser; 014 015import javax.enterprise.context.ApplicationScoped; 016import javax.enterprise.context.RequestScoped; 017import javax.enterprise.inject.Produces; 018import javax.inject.Inject; 019import javax.inject.Named; 020import javax.transaction.Transactional; 021import javax.validation.constraints.NotBlank; 022import javax.validation.constraints.NotNull; 023import javax.validation.constraints.Size; 024import java.io.BufferedInputStream; 025import java.io.IOException; 026import java.time.Instant; 027import java.time.temporal.ChronoUnit; 028import java.util.List; 029import java.util.Map; 030import java.util.stream.Collectors; 031 032/** 033 * Classe che fornisce i servizi relativi alle sezioni. 034 */ 035@ApplicationScoped 036@Transactional 037public class SectionService { 038 private SectionRepository sectionRepo; 039 private GenericRepository genericRepository; 040 private MediaRepository bcRepo; 041 private CurrentUser currentUser; 042 043 protected SectionService(){} 044 045 @Inject 046 protected SectionService(GenericRepository genericRepository, SectionRepository sectionRepository, 047 MediaRepository bcRepo, CurrentUser currentUser){ 048 this.genericRepository = genericRepository; 049 this.sectionRepo = sectionRepository; 050 this.bcRepo = bcRepo; 051 this.currentUser = currentUser; 052 } 053 054 /** 055 * Converte section in SectionPage. 056 * @param section sezione da convertire 057 * @return SectionPage con i dati di section 058 */ 059 private SectionPage map(Section section){ 060 User user = null; 061 if(currentUser.isLoggedIn()){ 062 user = genericRepository.findById(User.class,currentUser.getId()); 063 } 064 return SectionPage.builder().id(section.getId()) 065 .name(section.getName()) 066 .picture(section.getPicture()) 067 .description(section.getDescription()) 068 .banner(section.getBanner()) 069 .nFollowers(section.getFollowCount()) 070 .isFollowed(user != null && section.getFollow(user) != null).build(); 071 } 072 073 /** 074 * Cancella una sezione dato il suo id 075 * @param id l'id di una sezione esistente 076 */ 077 @AdminsOnly 078 public void delete(@SectionExists int id){ 079 genericRepository.remove(genericRepository.findById(Section.class, id)); 080 } 081 082 /** 083 * Crea una nuova sezione e ne restituisce l'id 084 * @param name Nome della sezione 085 * @param description descrizione della sezione 086 * @param picture stream relativo alla foto della sezione 087 * @param banner stream relativo al banner della sezione 088 * @return id della sezione creata 089 */ 090 @AdminsOnly 091 public int newSection(@NotBlank @Size(max=50) @UniqueSection String name, 092 @Size(max=255) String description, 093 @Image BufferedInputStream picture, 094 @Image BufferedInputStream banner) { 095 Section s = new Section(); 096 s.setName(name); 097 s.setDescription(description); 098 try { 099 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}