added Co Author
This commit is contained in:
		| @ -27,7 +27,7 @@ dependencies { | |||||||
| 	implementation("com.kohlschutter.junixsocket:junixsocket-core:2.9.0") | 	implementation("com.kohlschutter.junixsocket:junixsocket-core:2.9.0") | ||||||
| 	// implementation("org.springframework.session:spring-session-jdbc") | 	// implementation("org.springframework.session:spring-session-jdbc") | ||||||
| 	developmentOnly("org.springframework.boot:spring-boot-devtools") | 	developmentOnly("org.springframework.boot:spring-boot-devtools") | ||||||
| 	// developmentOnly("org.springframework.boot:spring-boot-docker-compose") | 	developmentOnly("org.springframework.boot:spring-boot-docker-compose") | ||||||
| 	runtimeOnly("org.postgresql:postgresql") | 	runtimeOnly("org.postgresql:postgresql") | ||||||
| 	testImplementation("org.springframework.boot:spring-boot-starter-test") | 	testImplementation("org.springframework.boot:spring-boot-starter-test") | ||||||
| 	testImplementation("org.springframework.boot:spring-boot-testcontainers") | 	testImplementation("org.springframework.boot:spring-boot-testcontainers") | ||||||
|  | |||||||
| @ -12,8 +12,11 @@ import lombok.Data; | |||||||
| import ovh.herisson.Clyde.Tables.ScientificPublications.Access; | import ovh.herisson.Clyde.Tables.ScientificPublications.Access; | ||||||
| import ovh.herisson.Clyde.Tables.ScientificPublications.PaperType; | import ovh.herisson.Clyde.Tables.ScientificPublications.PaperType; | ||||||
| import ovh.herisson.Clyde.Tables.ScientificPublications.Research; | import ovh.herisson.Clyde.Tables.ScientificPublications.Research; | ||||||
|  | import ovh.herisson.Clyde.Tables.ScientificPublications.Researcher; | ||||||
|  |  | ||||||
| import java.util.Date; | import java.util.Date; | ||||||
|  | import java.util.HashSet; | ||||||
|  | import java.util.Set; | ||||||
|  |  | ||||||
| @Data | @Data | ||||||
| public class ResearchDTO { | public class ResearchDTO { | ||||||
| @ -21,6 +24,7 @@ public class ResearchDTO { | |||||||
|     private long id; |     private long id; | ||||||
|     private String title; |     private String title; | ||||||
|     private ResearcherDTO researcher; |     private ResearcherDTO researcher; | ||||||
|  |     private final Set<ResearcherDTO> coAuthors; | ||||||
|     private Date releaseDate; |     private Date releaseDate; | ||||||
|     private PaperType paperType; |     private PaperType paperType; | ||||||
|     private String pdfLocation; |     private String pdfLocation; | ||||||
| @ -31,7 +35,7 @@ public class ResearchDTO { | |||||||
|     private String summary; |     private String summary; | ||||||
|     private long views; |     private long views; | ||||||
|  |  | ||||||
|     private ResearchDTO(String title, ResearcherDTO researcherDTO, Date releaseDate, PaperType paperType, String pdfLocation, String language, Access access, String domain,String bibTexLocation, String summary, long id,long views) { |     private ResearchDTO(String title, ResearcherDTO researcherDTO, Date releaseDate, PaperType paperType, String pdfLocation, String language, Access access, String domain, String bibTexLocation, String summary, Set<Researcher> coAuthors, long id, long views) { | ||||||
|         this.title = title; |         this.title = title; | ||||||
|         this.researcher = researcherDTO; |         this.researcher = researcherDTO; | ||||||
|         this.releaseDate = releaseDate; |         this.releaseDate = releaseDate; | ||||||
| @ -43,6 +47,10 @@ public class ResearchDTO { | |||||||
|         this.summary = summary; |         this.summary = summary; | ||||||
|         this.id = id; |         this.id = id; | ||||||
|         this.bibTexLocation = bibTexLocation; |         this.bibTexLocation = bibTexLocation; | ||||||
|  |         this.coAuthors = new HashSet<>(); | ||||||
|  |         for (Researcher coAuthor: coAuthors) { | ||||||
|  |             this.coAuthors.add(ResearcherDTO.construct(coAuthor)); | ||||||
|  |         } | ||||||
|         this.views = views; |         this.views = views; | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @ -50,6 +58,6 @@ public class ResearchDTO { | |||||||
|     public static ResearchDTO construct(Research research){ |     public static ResearchDTO construct(Research research){ | ||||||
|         return new ResearchDTO(research.getTitle(), ResearcherDTO.construct(research.getAuthor()), research.getReleaseDate(), |         return new ResearchDTO(research.getTitle(), ResearcherDTO.construct(research.getAuthor()), research.getReleaseDate(), | ||||||
|                 research.getPaperType(),research.getPdfLocation(),research.getLanguage(),research.getAccess(), |                 research.getPaperType(),research.getPdfLocation(),research.getLanguage(),research.getAccess(), | ||||||
|                 research.getDomain(),research.getBibTexLocation(), research.getSummary(), research.getId(), research.getViews()); |                 research.getDomain(),research.getBibTexLocation(), research.getSummary(), research.getCoAuthors(),research.getId(), research.getViews()); | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  | |||||||
| @ -19,9 +19,7 @@ import ovh.herisson.Clyde.Tables.Inscription.InscriptionRequest; | |||||||
| import ovh.herisson.Clyde.Tables.Inscription.Minerval; | import ovh.herisson.Clyde.Tables.Inscription.Minerval; | ||||||
| import ovh.herisson.Clyde.Tables.Inscription.ScholarshipRequest; | import ovh.herisson.Clyde.Tables.Inscription.ScholarshipRequest; | ||||||
|  |  | ||||||
| import java.util.ArrayList; | import java.util.*; | ||||||
| import java.util.Arrays; |  | ||||||
| import java.util.Date; |  | ||||||
|  |  | ||||||
| @RestController | @RestController | ||||||
| @CrossOrigin(originPatterns = "*", allowCredentials = "true") | @CrossOrigin(originPatterns = "*", allowCredentials = "true") | ||||||
| @ -138,24 +136,29 @@ public class MockController { | |||||||
|             // extension Publications Scientifiques |             // extension Publications Scientifiques | ||||||
|             Researcher jojoResearcherAccount = new Researcher(jojo, "3363-22555-AB33-T", null, "IT"); |             Researcher jojoResearcherAccount = new Researcher(jojo, "3363-22555-AB33-T", null, "IT"); | ||||||
|  |  | ||||||
|  |             Researcher joResearchAccount = new Researcher(joe,"N555-321213-BED-DD",null, "Physics"); | ||||||
|  |  | ||||||
|  |  | ||||||
|             Researcher output = researchesService.saveResearcher(jojoResearcherAccount); |             Researcher output = researchesService.saveResearcher(jojoResearcherAccount); | ||||||
|  |             Researcher joOutput = researchesService.saveResearcher(joResearchAccount); | ||||||
|  |  | ||||||
|  |             Set<Researcher> coAuthor = new HashSet<>(); | ||||||
|  |             coAuthor.add(joOutput); | ||||||
|  |  | ||||||
|             Research jojoResearch = new Research("Graphs : Advanced Search Algorithms", output, new Date(0), |             Research jojoResearch = new Research("Graphs : Advanced Search Algorithms", output, new Date(0), | ||||||
|                     PaperType.Article, "test.pdf", null, "english", |                     PaperType.Article, "test.pdf", null, "english", | ||||||
|                     Access.OpenSource, "IT", "This Article's title speaks for itself \n We'll discuss about advanced Graph search Algorithms"); |                     Access.OpenSource, "IT", "This Article's title speaks for itself \n We'll discuss about advanced Graph search Algorithms",coAuthor); | ||||||
|  |  | ||||||
|             Research restrictedResearch = new Research("just another Name", output, new Date(1111111111), |             Research restrictedResearch = new Research("just another Name", output, new Date(1111111111), | ||||||
|                     PaperType.Article, "restricted", null, "english", |                     PaperType.Article, "restricted", null, "english", | ||||||
|                     Access.Restricted, "Restricted", "This Article's title speaks for itself\n We'll discuss about advanced Graph search Algorithms"); |                     Access.Restricted, "Restricted", "This Article's title speaks for itself\n We'll discuss about advanced Graph search Algorithms", new HashSet<>()); | ||||||
|  |  | ||||||
|             Research privateResearch = new Research("the great Potato War", output, new Date(), |             Research privateResearch = new Research("the great Potato War", output, new Date(), | ||||||
|                     PaperType.Article, "private", null, "english", |                     PaperType.Article, "private", null, "english", | ||||||
|                     Access.Private, "private", "This Article's title speaks for itself\n We'll discuss about advanced Graph search Algorithms"); |                     Access.Private, "private", "This Article's title speaks for itself\n We'll discuss about advanced Graph search Algorithms",null); | ||||||
|  |  | ||||||
|  |  | ||||||
|             researchesService.saveResearch(restrictedResearch); |             researchesService.saveResearch(restrictedResearch); | ||||||
|             researchesService.saveResearch(privateResearch); |             researchesService.saveResearch(privateResearch); | ||||||
|  |  | ||||||
|             researchesService.saveResearch(jojoResearch); |             researchesService.saveResearch(jojoResearch); | ||||||
|  |  | ||||||
|     } |     } | ||||||
|  | |||||||
| @ -108,6 +108,7 @@ public class ResearchController { | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     /** post updates to the research |     /** post updates to the research | ||||||
|  |      * in the updates, the coAuthors have to be referenced by their ids | ||||||
|      * |      * | ||||||
|      */ |      */ | ||||||
|     @PatchMapping("/research/{id}") |     @PatchMapping("/research/{id}") | ||||||
| @ -152,81 +153,6 @@ public class ResearchController { | |||||||
|         return new ResponseEntity<>(HttpStatus.OK); |         return new ResponseEntity<>(HttpStatus.OK); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |  | ||||||
|     ///////////// |  | ||||||
|     // Co-authors Part |  | ||||||
|  |  | ||||||
|     /** get all the co-authors in a research |  | ||||||
|      * |  | ||||||
|      * @param id the research id |  | ||||||
|      * @return all the co-authors associated with the research |  | ||||||
|      */ |  | ||||||
|     @GetMapping("/research/{id}/co-authors") |  | ||||||
|     public  ResponseEntity<Iterable<ResearcherDTO>> getCoAuthors(@PathVariable long id){ |  | ||||||
|        Research research = researchesServ.getResearchById(id); |  | ||||||
|  |  | ||||||
|        if (research == null) return new ResponseEntity<>(HttpStatus.NOT_FOUND); |  | ||||||
|  |  | ||||||
|        Iterable<Researcher> researchers= researchesServ.getCoAuthors(research); |  | ||||||
|        ArrayList<ResearcherDTO> toReturn = new ArrayList<>(); |  | ||||||
|  |  | ||||||
|        for (Researcher researcher: researchers){ |  | ||||||
|            toReturn.add(ResearcherDTO.construct(researcher)); |  | ||||||
|        } |  | ||||||
|        return new ResponseEntity<>(toReturn,HttpStatus.OK); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     /** post co-authors to the research |  | ||||||
|      * |  | ||||||
|      * @param token the Authorization header |  | ||||||
|      * @param researchersId the co-authors ids |  | ||||||
|      * @param id the research id |  | ||||||
|      * @return the added researchers |  | ||||||
|      */ |  | ||||||
|     @PostMapping("/research/{id}/co-authors") |  | ||||||
|     public ResponseEntity<Iterable<ResearcherDTO>> postCoAuthor(@RequestHeader("Authorization") String token, |  | ||||||
|                                                               @RequestBody Iterable<Long> researchersId, |  | ||||||
|                                                               @PathVariable long id) |  | ||||||
|     { |  | ||||||
|         Research research = researchesServ.getResearchById(id); |  | ||||||
|         if (research == null) return new ResponseEntity<>(HttpStatus.NOT_FOUND); |  | ||||||
|  |  | ||||||
|         if (authServ.isNotIn(new Role[]{Role.Admin}, token) || research.getAuthor() != researchesServ.getResearcherByUser(authServ.getUserFromToken(token))) |  | ||||||
|             return new UnauthorizedResponse<>(null); |  | ||||||
|  |  | ||||||
|         if (!researchesServ.saveCoAuthors(researchersId,research)) |  | ||||||
|             return new ResponseEntity<>(HttpStatus.BAD_REQUEST); |  | ||||||
|  |  | ||||||
|         ArrayList<ResearcherDTO> toReturn = new ArrayList<>(); |  | ||||||
|         for (Long reId: researchersId){ |  | ||||||
|             toReturn.add(ResearcherDTO.construct(researchesServ.getResearcherById(reId))); |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         return  new ResponseEntity<>(toReturn,HttpStatus.OK); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     /** deletes the co-author with *coAuthorId* from the research with the *researchId* |  | ||||||
|      */ |  | ||||||
|     @DeleteMapping("/research/{researchId}/co-author/{coAuthorId}") |  | ||||||
|     public ResponseEntity<String> deleteCoAuthor(@RequestHeader("Authorization") String token, |  | ||||||
|                                                  @PathVariable long researchId, |  | ||||||
|                                                  @PathVariable long coAuthorId) |  | ||||||
|     { |  | ||||||
|         Research research = researchesServ.getResearchById(researchId); |  | ||||||
|         Researcher coAuthor = researchesServ.getResearcherById(coAuthorId); |  | ||||||
|  |  | ||||||
|         if (authServ.isNotIn(new Role[]{Role.Admin}, token) || research.getAuthor() != researchesServ.getResearcherByUser(authServ.getUserFromToken(token))) |  | ||||||
|             return new UnauthorizedResponse<>(null); |  | ||||||
|  |  | ||||||
|         if (coAuthor == null) return new ResponseEntity<>(HttpStatus.NOT_FOUND); |  | ||||||
|  |  | ||||||
|        if (!researchesServ.deleteCoAuthor(research, coAuthor)) |  | ||||||
|            return new ResponseEntity<>(HttpStatus.BAD_REQUEST); |  | ||||||
|  |  | ||||||
|         return new ResponseEntity<>(HttpStatus.OK); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|  |  | ||||||
|     /////// |     /////// | ||||||
|     //views part |     //views part | ||||||
|     @PostMapping("/addview/cdn/{url}") |     @PostMapping("/addview/cdn/{url}") | ||||||
|  | |||||||
| @ -1,18 +0,0 @@ | |||||||
| package ovh.herisson.Clyde.Repositories.ScientificPublications; |  | ||||||
|  |  | ||||||
| import org.springframework.data.jpa.repository.Query; |  | ||||||
| import org.springframework.data.repository.CrudRepository; |  | ||||||
| import ovh.herisson.Clyde.Tables.Course; |  | ||||||
| import ovh.herisson.Clyde.Tables.Curriculum; |  | ||||||
| import ovh.herisson.Clyde.Tables.ScientificPublications.Research; |  | ||||||
| import ovh.herisson.Clyde.Tables.ScientificPublications.ResearchCoAuthors; |  | ||||||
| import ovh.herisson.Clyde.Tables.ScientificPublications.Researcher; |  | ||||||
|  |  | ||||||
| public interface ResearchCoAuthorsRepository extends CrudRepository<ResearchCoAuthors,Long> { |  | ||||||
|    @Query("select distinct rca.coAuthor from ResearchCoAuthors rca where rca.research = ?1") |  | ||||||
|    Iterable<Researcher> findResearchCoAuthors(Research research); |  | ||||||
|  |  | ||||||
|  |  | ||||||
|    @Query("select rca from ResearchCoAuthors rca where rca.research = ?1 and rca.coAuthor =?2") |  | ||||||
|   ResearchCoAuthors findResearchCoAuthors(Research research, Researcher researcher); |  | ||||||
| } |  | ||||||
| @ -2,47 +2,33 @@ package ovh.herisson.Clyde.Services.ScientificPublications; | |||||||
|  |  | ||||||
| import lombok.AllArgsConstructor; | import lombok.AllArgsConstructor; | ||||||
| import org.springframework.stereotype.Service; | import org.springframework.stereotype.Service; | ||||||
| import ovh.herisson.Clyde.DTO.ScientificPublications.ResearchDTO; |  | ||||||
| import ovh.herisson.Clyde.Repositories.ScientificPublications.ResearchCoAuthorsRepository; |  | ||||||
| import ovh.herisson.Clyde.Repositories.ScientificPublications.ResearchRepository; | import ovh.herisson.Clyde.Repositories.ScientificPublications.ResearchRepository; | ||||||
| import ovh.herisson.Clyde.Repositories.ScientificPublications.ResearcherRepository; | import ovh.herisson.Clyde.Repositories.ScientificPublications.ResearcherRepository; | ||||||
| import ovh.herisson.Clyde.Tables.Role; | import ovh.herisson.Clyde.Tables.Role; | ||||||
| import ovh.herisson.Clyde.Tables.ScientificPublications.*; | import ovh.herisson.Clyde.Tables.ScientificPublications.*; | ||||||
| import ovh.herisson.Clyde.Tables.User; | import ovh.herisson.Clyde.Tables.User; | ||||||
|  |  | ||||||
| import java.util.ArrayList; | import java.util.*; | ||||||
| import java.util.Date; |  | ||||||
| import java.util.Map; |  | ||||||
|  |  | ||||||
| @Service | @Service | ||||||
| @AllArgsConstructor | @AllArgsConstructor | ||||||
|  | @SuppressWarnings("unchecked") | ||||||
| public class ResearchesService { | public class ResearchesService { | ||||||
|  |  | ||||||
|     private final ResearcherRepository researcherRepo; |     private final ResearcherRepository researcherRepo; | ||||||
|     private final ResearchCoAuthorsRepository researchCoAuthorsRepo; |  | ||||||
|     private final ResearchRepository articleRepo; |     private final ResearchRepository articleRepo; | ||||||
|  |  | ||||||
|     // Researchers Part |  | ||||||
|     public Researcher getResearcherByUser(User user){ |  | ||||||
|         return researcherRepo.findByUser(user); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     public boolean isCoAuthor(Research research, Researcher researcher){ |  | ||||||
|         Iterable<Researcher> coAuthors = researchCoAuthorsRepo.findResearchCoAuthors(research); |  | ||||||
|         for (Researcher coAuthor : coAuthors){ |  | ||||||
|             if (researcher == coAuthor){ |  | ||||||
|                 return true; |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|         return false; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|  |  | ||||||
|     // researches Part |     // researches Part | ||||||
|     public Research getResearchById(long id) { |     public Research getResearchById(long id) { | ||||||
|         return articleRepo.findById(id); |         return articleRepo.findById(id); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     public Research getResearchByUrl(String url) { | ||||||
|  |         return articleRepo.findByPdfLocation(url); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |  | ||||||
|     public Iterable<Research> getResearchesByAuthor(long authorId){ |     public Iterable<Research> getResearchesByAuthor(long authorId){ | ||||||
|         Researcher researcher = researcherRepo.findById(authorId); |         Researcher researcher = researcherRepo.findById(authorId); | ||||||
|         if (researcher == null) return null; |         if (researcher == null) return null; | ||||||
| @ -50,29 +36,6 @@ public class ResearchesService { | |||||||
|         return researcherRepo.findAllByAuthorId(researcher); |         return researcherRepo.findAllByAuthorId(researcher); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     public boolean hasNoAccessTo(Research research, User user){ |  | ||||||
|  |  | ||||||
|  |  | ||||||
|         if (research.getAccess() == Access.OpenSource) return false; // if the access is open source even non-users can see it |  | ||||||
|         if (user == null) return true; // else you need at least to be a user |  | ||||||
|  |  | ||||||
|         if (user.getRole() == Role.Admin) return false; |  | ||||||
|  |  | ||||||
|         if (research.getAccess() == Access.Restricted && |  | ||||||
|                 user.getRole() == Role.Secretary || |  | ||||||
|                 user.getRole() == Role.Teacher || user.getRole() == Role.InscriptionService) |  | ||||||
|             return false; // if the access is restricted only the staff member (above) can access the research |  | ||||||
|  |  | ||||||
|         Researcher researcher = getResearcherByUser(user); |  | ||||||
|  |  | ||||||
|         if (researcher==null) |  | ||||||
|             return true; |  | ||||||
|  |  | ||||||
|         return (research.getAccess() != Access.Private || research.getAuthor() != researcher) && |  | ||||||
|                 (research.getAccess() != Access.Private || !isCoAuthor(research, researcher)); |  | ||||||
|         // if the researcher is the author or one of the co-authors of the research will return false |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     public Research saveResearch(Research research) { |     public Research saveResearch(Research research) { | ||||||
|         return articleRepo.save(research); |         return articleRepo.save(research); | ||||||
|     } |     } | ||||||
| @ -98,6 +61,18 @@ public class ResearchesService { | |||||||
|                 case "access": |                 case "access": | ||||||
|                     research.setAccess(Access.valueOf((String) entry.getValue())); |                     research.setAccess(Access.valueOf((String) entry.getValue())); | ||||||
|                     break; |                     break; | ||||||
|  |                 case "coAuthors": | ||||||
|  |                     Set<Researcher> set = new HashSet<>(); | ||||||
|  |  | ||||||
|  |                     for (int id : (List<Integer>) entry.getValue()) { | ||||||
|  |  | ||||||
|  |                         Researcher r = researcherRepo.findById(id); | ||||||
|  |                         if (r != null){ | ||||||
|  |                             set.add(r); | ||||||
|  |                         } | ||||||
|  |                     } | ||||||
|  |                     research.setCoAuthors(set); | ||||||
|  |                     break; | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|         articleRepo.save(research); |         articleRepo.save(research); | ||||||
| @ -107,6 +82,12 @@ public class ResearchesService { | |||||||
|         articleRepo.delete(research); |         articleRepo.delete(research); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |     // Researchers Part | ||||||
|  |     public Researcher getResearcherByUser(User user){ | ||||||
|  |         return researcherRepo.findByUser(user); | ||||||
|  |     } | ||||||
|  |  | ||||||
|     public Iterable<Research> getAllResearches() { |     public Iterable<Research> getAllResearches() { | ||||||
|         return articleRepo.findAll(); |         return articleRepo.findAll(); | ||||||
|     } |     } | ||||||
| @ -129,41 +110,6 @@ public class ResearchesService { | |||||||
|        researcherRepo.delete(researcher); |        researcherRepo.delete(researcher); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     public boolean saveCoAuthors(Iterable<Long> researchersId, Research research) { |  | ||||||
|  |  | ||||||
|         if (researchersId == null) return false; |  | ||||||
|  |  | ||||||
|         ArrayList<Researcher> toAdd = new ArrayList<>(); |  | ||||||
|         for (long researcherId : researchersId){ |  | ||||||
|             Researcher researcher= researcherRepo.findById(researcherId); |  | ||||||
|             if (research== null){ |  | ||||||
|                 return false; |  | ||||||
|             } |  | ||||||
|             if (!toAdd.contains(researcher)) |  | ||||||
|             { |  | ||||||
|                 toAdd.add(researcher); |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|         for (Researcher researcher: toAdd){ |  | ||||||
|             researchCoAuthorsRepo.save(new ResearchCoAuthors(researcher,research)); |  | ||||||
|         } |  | ||||||
|         return true; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     public Iterable<Researcher> getCoAuthors(Research research) { |  | ||||||
|         return researchCoAuthorsRepo.findResearchCoAuthors(research); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     public boolean deleteCoAuthor(Research research,Researcher coAuthor) { |  | ||||||
|         ResearchCoAuthors result = researchCoAuthorsRepo.findResearchCoAuthors(research,coAuthor); |  | ||||||
|  |  | ||||||
|         if (result ==null) |  | ||||||
|             return false; |  | ||||||
|  |  | ||||||
|         researchCoAuthorsRepo.delete(result); |  | ||||||
|         return true; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     public void modifyResearcherData(Researcher researcher, Map<String, Object> updates) { |     public void modifyResearcherData(Researcher researcher, Map<String, Object> updates) { | ||||||
|  |  | ||||||
|         for (Map.Entry<String, Object> entry : updates.entrySet()){ |         for (Map.Entry<String, Object> entry : updates.entrySet()){ | ||||||
| @ -185,12 +131,69 @@ public class ResearchesService { | |||||||
|         researcherRepo.save(researcher); |         researcherRepo.save(researcher); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     public Research getResearchByUrl(String url) { |  | ||||||
|         return articleRepo.findByPdfLocation(url); |     //Co Author part | ||||||
|  |     public boolean saveCoAuthors(Iterable<Long> researchersId, Research research) { | ||||||
|  |  | ||||||
|  |         if (researchersId == null) return false; | ||||||
|  |  | ||||||
|  |         ArrayList<Researcher> toAdd = new ArrayList<>(); | ||||||
|  |         for (long researcherId : researchersId){ | ||||||
|  |             Researcher researcher= researcherRepo.findById(researcherId); | ||||||
|  |             if (researcher== null){ | ||||||
|  |                 return false; | ||||||
|             } |             } | ||||||
|  |             if (!toAdd.contains(researcher)) | ||||||
|  |             { | ||||||
|  |                 toAdd.add(researcher); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         research.getCoAuthors().addAll(toAdd); | ||||||
|  |         articleRepo.save(research); | ||||||
|  |         return true; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public boolean deleteCoAuthor(Research research,Researcher coAuthor) { | ||||||
|  |  | ||||||
|  |         if (!research.getCoAuthors().contains(coAuthor)) | ||||||
|  |             return false; | ||||||
|  |  | ||||||
|  |         research.getCoAuthors().remove(coAuthor); | ||||||
|  |         articleRepo.save(research); | ||||||
|  |         return true; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     // Other stuff | ||||||
|  |  | ||||||
|     public Research addView(Research research) { |     public Research addView(Research research) { | ||||||
|         research.setViews(research.getViews()+1); |         research.setViews(research.getViews()+1); | ||||||
|         return articleRepo.save(research); |         return articleRepo.save(research); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     public boolean hasNoAccessTo(Research research, User user){ | ||||||
|  |         if (research.getAccess() == Access.OpenSource) return false; // if the access is open source even non-users can see it | ||||||
|  |         if (user == null) return true; // else you need at least to be a user | ||||||
|  |  | ||||||
|  |         if (user.getRole() == Role.Admin) return false; | ||||||
|  |  | ||||||
|  |  | ||||||
|  |         Researcher researcher = getResearcherByUser(user); | ||||||
|  |         if (researcher !=null ){ | ||||||
|  |             if (research.getAuthor().getId() == researcher.getId()) | ||||||
|  |                 return false; | ||||||
|  |  | ||||||
|  |             for (Researcher coAuthor: research.getCoAuthors()){ | ||||||
|  |                 if (coAuthor.getId() == researcher.getId()) | ||||||
|  |                     return false; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         if (research.getAccess() == Access.Restricted && ( | ||||||
|  |                 user.getRole() == Role.Secretary || | ||||||
|  |                 user.getRole() == Role.Teacher || user.getRole() == Role.InscriptionService)) | ||||||
|  |             return false; // if the access is restricted only the staff member (above) can access the research | ||||||
|  |  | ||||||
|  |         return true; | ||||||
|  |         // if the researcher is the author or one of the co-authors of the research will return false | ||||||
|  |     } | ||||||
| } | } | ||||||
|  | |||||||
| @ -16,10 +16,14 @@ import org.hibernate.annotations.CreationTimestamp; | |||||||
| import org.hibernate.annotations.OnDelete; | import org.hibernate.annotations.OnDelete; | ||||||
| import org.hibernate.annotations.OnDeleteAction; | import org.hibernate.annotations.OnDeleteAction; | ||||||
| import java.util.Date; | import java.util.Date; | ||||||
|  | import java.util.List; | ||||||
|  | import java.util.Set; | ||||||
|  |  | ||||||
| @Getter | @Getter | ||||||
| @Setter | @Setter | ||||||
| @NoArgsConstructor | @NoArgsConstructor | ||||||
| @Entity | @Entity | ||||||
|  | @Table(name = "Research") | ||||||
| public class Research { | public class Research { | ||||||
|     @Id |     @Id | ||||||
|     @GeneratedValue(strategy = GenerationType.AUTO) |     @GeneratedValue(strategy = GenerationType.AUTO) | ||||||
| @ -51,8 +55,15 @@ public class Research { | |||||||
|  |  | ||||||
|     private int views; |     private int views; | ||||||
|  |  | ||||||
|  |     @ManyToMany(cascade = {CascadeType.MERGE}) | ||||||
|  |     @JoinTable(name = "ResearchCoAuhors", | ||||||
|  |             joinColumns = @JoinColumn(name = "research_id"), | ||||||
|  |             inverseJoinColumns = @JoinColumn(name = "researcher_id") | ||||||
|  |     ) | ||||||
|  |     private Set<Researcher> coAuthors; | ||||||
|  |  | ||||||
|     public Research(String title, Researcher author, Date releaseDate, PaperType paperType, |     public Research(String title, Researcher author, Date releaseDate, PaperType paperType, | ||||||
|                     String pdfLocation, String bibTexLocation, String language, Access access, String domain, String summary){ |                     String pdfLocation, String bibTexLocation, String language, Access access, String domain, String summary,Set<Researcher> coauthors){ | ||||||
|         this.author = author; |         this.author = author; | ||||||
|         this.title = title; |         this.title = title; | ||||||
|         this.releaseDate = releaseDate; |         this.releaseDate = releaseDate; | ||||||
| @ -63,6 +74,7 @@ public class Research { | |||||||
|         this.access = access; |         this.access = access; | ||||||
|         this.domain = domain; |         this.domain = domain; | ||||||
|         this.summary = summary; |         this.summary = summary; | ||||||
|  |         this.coAuthors = coauthors; | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | |||||||
| @ -1,42 +0,0 @@ | |||||||
| package ovh.herisson.Clyde.Tables.ScientificPublications; |  | ||||||
|  |  | ||||||
| /****************************************************** |  | ||||||
|  * @file ResearchCoAuthors |  | ||||||
|  * @author Maxime Bartha |  | ||||||
|  * @scope Extension Publications scientifiques |  | ||||||
|  * |  | ||||||
|  * Co-Authors List entity (will be accessed by Articles) |  | ||||||
|  * |  | ||||||
|  ******************************************************/ |  | ||||||
| import jakarta.persistence.*; |  | ||||||
| import lombok.AllArgsConstructor; |  | ||||||
| import lombok.Getter; |  | ||||||
| import lombok.NoArgsConstructor; |  | ||||||
| import lombok.Setter; |  | ||||||
| import org.hibernate.annotations.OnDelete; |  | ||||||
| import org.hibernate.annotations.OnDeleteAction; |  | ||||||
|  |  | ||||||
| @Getter |  | ||||||
| @Setter |  | ||||||
| @NoArgsConstructor |  | ||||||
| @Entity |  | ||||||
| public class ResearchCoAuthors { |  | ||||||
|  |  | ||||||
|     @Id |  | ||||||
|     @GeneratedValue(strategy = GenerationType.AUTO) |  | ||||||
|     Long id; |  | ||||||
|  |  | ||||||
|     @ManyToOne(fetch = FetchType.EAGER) |  | ||||||
|     @JoinColumn(name = "Researcher") |  | ||||||
|     private Researcher coAuthor; |  | ||||||
|  |  | ||||||
|     @ManyToOne(fetch = FetchType.EAGER) |  | ||||||
|     @OnDelete(action = OnDeleteAction.CASCADE) |  | ||||||
|     @JoinColumn(name = "Article") |  | ||||||
|     private Research research; |  | ||||||
|  |  | ||||||
|     public ResearchCoAuthors(Researcher coAuthor, Research research){ |  | ||||||
|         this.coAuthor = coAuthor; |  | ||||||
|         this.research = research; |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| @ -20,6 +20,7 @@ import ovh.herisson.Clyde.Tables.User; | |||||||
| @Setter | @Setter | ||||||
| @NoArgsConstructor | @NoArgsConstructor | ||||||
| @Entity | @Entity | ||||||
|  | @Table(name = "Researcher") | ||||||
| public class Researcher { | public class Researcher { | ||||||
|     @Id |     @Id | ||||||
|     @GeneratedValue(strategy = GenerationType.AUTO) |     @GeneratedValue(strategy = GenerationType.AUTO) | ||||||
|  | |||||||
| @ -106,7 +106,6 @@ const emit = defineEmits(["modified"]); | |||||||
| <div id="researches"> | <div id="researches"> | ||||||
|   <FilterComponent :isOpen="isFilterOpened" :allArticles="researchList" @modal-close="closeFilter" @submit="submitFilters"></FilterComponent> |   <FilterComponent :isOpen="isFilterOpened" :allArticles="researchList" @modal-close="closeFilter" @submit="submitFilters"></FilterComponent> | ||||||
|   <ArticleComponent :article="articleToDisplay" :isOpen="isResearchOpened" :manage="props.manage" @modal-close="closeResearch" @modified="emit('modified')"></ArticleComponent> |   <ArticleComponent :article="articleToDisplay" :isOpen="isResearchOpened" :manage="props.manage" @modal-close="closeResearch" @modified="emit('modified')"></ArticleComponent> | ||||||
|   <div id="researches"> |  | ||||||
|   <div id="search"> |   <div id="search"> | ||||||
|     <input v-if="!isResearcher" type="text" id="search-input" placeholder="search for researches" v-model="input"/> |     <input v-if="!isResearcher" type="text" id="search-input" placeholder="search for researches" v-model="input"/> | ||||||
|     <input v-else type="text" id="search-input" placeholder="search for researcher" v-model="input"/> |     <input v-else type="text" id="search-input" placeholder="search for researcher" v-model="input"/> | ||||||
| @ -114,6 +113,7 @@ const emit = defineEmits(["modified"]); | |||||||
|     <button v-if="!isResearcher" id="unToggledResearchButton" @click="isResearcher = !isResearcher">  Toggle Researcher Search</button> |     <button v-if="!isResearcher" id="unToggledResearchButton" @click="isResearcher = !isResearcher">  Toggle Researcher Search</button> | ||||||
|     <button v-if="isResearcher" id="toggledResearchButton" @click="isResearcher = !isResearcher">  UnToggle Researcher Search</button> |     <button v-if="isResearcher" id="toggledResearchButton" @click="isResearcher = !isResearcher">  UnToggle Researcher Search</button> | ||||||
|   </div> |   </div> | ||||||
|  |   <div id="researches"> | ||||||
|     <ul id="researchUL"> |     <ul id="researchUL"> | ||||||
|       <li id="researchLi" v-for="n in searchInList(researchList,input)"> |       <li id="researchLi" v-for="n in searchInList(researchList,input)"> | ||||||
|         <div class="vl"> {{n.title}}</div> |         <div class="vl"> {{n.title}}</div> | ||||||
| @ -128,6 +128,11 @@ const emit = defineEmits(["modified"]); | |||||||
|  |  | ||||||
| <style scoped> | <style scoped> | ||||||
|  |  | ||||||
|  | #researches{ | ||||||
|  |   width: 100%; | ||||||
|  |   height: 100%; | ||||||
|  |   overflow: scroll; | ||||||
|  | } | ||||||
| #search{ | #search{ | ||||||
|   width: 100%; |   width: 100%; | ||||||
|   height: 10%; |   height: 10%; | ||||||
|  | |||||||
| @ -64,14 +64,6 @@ async function articleClicked(){ | |||||||
|   emit('modified') |   emit('modified') | ||||||
| } | } | ||||||
|  |  | ||||||
| /** |  | ||||||
| function downloadCoAuthors(){ |  | ||||||
|   //todo |  | ||||||
|   const data = JSON.stringify(researcher.value); |  | ||||||
|   const blob = new Blob([data], {type:"application/json"}); |  | ||||||
|   return URL.createObjectURL(blob); |  | ||||||
| } **/ |  | ||||||
|  |  | ||||||
| </script> | </script> | ||||||
|  |  | ||||||
| <template> | <template> | ||||||
| @ -82,6 +74,7 @@ function downloadCoAuthors(){ | |||||||
|           <li>Article Id : {{article.id}}</li> |           <li>Article Id : {{article.id}}</li> | ||||||
|           <li>Title : {{article.title}}</li> |           <li>Title : {{article.title}}</li> | ||||||
|           <li>Author : {{article.researcher.user.lastName + " " + article.researcher.user.firstName}}</li> |           <li>Author : {{article.researcher.user.lastName + " " + article.researcher.user.firstName}}</li> | ||||||
|  |           <li> Co Authors : <ul id="coAuthors" v-for="n in article.coAuthors"> <li id="coAuthorsLi">  {{n.user.firstName}} {{n.user.lastName}}, </li></ul></li> | ||||||
|           <li>Summary : {{article.summary}}</li> |           <li>Summary : {{article.summary}}</li> | ||||||
|           <li>ReleaseDate: {{format(article.releaseDate)}}</li> |           <li>ReleaseDate: {{format(article.releaseDate)}}</li> | ||||||
|           <li>Language : {{article.language}}</li> |           <li>Language : {{article.language}}</li> | ||||||
| @ -125,7 +118,7 @@ function downloadCoAuthors(){ | |||||||
|   top: 0; |   top: 0; | ||||||
|   left: 0; |   left: 0; | ||||||
|   width: 100%; |   width: 100%; | ||||||
|   height: 100%; |   height: 120%; | ||||||
|   background-color: rgba(0, 0, 0, 0.5); |   background-color: rgba(0, 0, 0, 0.5); | ||||||
| } | } | ||||||
|  |  | ||||||
| @ -142,6 +135,15 @@ function downloadCoAuthors(){ | |||||||
|   margin-top: 9px; |   margin-top: 9px; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | #coAuthors{ | ||||||
|  |   list-style: none; | ||||||
|  |   display: inline; | ||||||
|  |   padding: 0; | ||||||
|  | } | ||||||
|  | #coAuthorsLi{ | ||||||
|  |   display: inline; | ||||||
|  |   margin-right: 2px; | ||||||
|  | } | ||||||
|  |  | ||||||
| #downloads { | #downloads { | ||||||
|   text-align: end; |   text-align: end; | ||||||
|  | |||||||
| @ -2,8 +2,13 @@ | |||||||
|  |  | ||||||
| import { ref } from "vue"; | import { ref } from "vue"; | ||||||
| import {onClickOutside} from '@vueuse/core' | import {onClickOutside} from '@vueuse/core' | ||||||
| import {uploadPdf,postResearch} from "@/rest/ScientificPublications/ManageResearch.js"; | import {uploadFile, postResearch, fetchAllResearchers} from "@/rest/ScientificPublications/ManageResearch.js"; | ||||||
| let toPost = Object.assign({}, {}); | const allResearcher = ref(await fetchAllResearchers()) | ||||||
|  |  | ||||||
|  | const coAuthors = ref([]) | ||||||
|  |  | ||||||
|  | let toPost = Object.assign({}, {coAuthors:[]}); | ||||||
|  |  | ||||||
|  |  | ||||||
| const props = defineProps({ | const props = defineProps({ | ||||||
|   isOpen: Boolean, |   isOpen: Boolean, | ||||||
| @ -12,19 +17,20 @@ const props = defineProps({ | |||||||
|  |  | ||||||
|  |  | ||||||
| async function uploadResearchPdf(pdf){ | async function uploadResearchPdf(pdf){ | ||||||
|   const data = await uploadPdf(pdf); |   const data = await uploadFile(pdf); | ||||||
|   toPost.pdfLocation = data.url; |   toPost.pdfLocation = data.url; | ||||||
| } | } | ||||||
| async function uploadBibTex(pdf){ | async function uploadBibTex(pdf){ | ||||||
|   const data = await uploadPdf(pdf); |   const data = await uploadFile(pdf); | ||||||
|   toPost.bibTexLocation = data.url; |   toPost.bibTexLocation = data.url; | ||||||
| } | } | ||||||
|  |  | ||||||
| // Date when sent!! |  | ||||||
|  |  | ||||||
| async function postNewResearch(){ | async function postNewResearch(){ | ||||||
|   toPost.releaseDate = new Date() |   toPost.releaseDate = new Date() | ||||||
|   toPost.author = props.researcher |   toPost.author = props.researcher | ||||||
|  |   toPost.coAuthors = coAuthors.value | ||||||
|  |   console.log() | ||||||
|   //the Pdf and a title are required |   //the Pdf and a title are required | ||||||
|   if (toPost.pdfLocation == null || toPost.title == null || toPost.title === "") { |   if (toPost.pdfLocation == null || toPost.title == null || toPost.title === "") { | ||||||
|     emit("modal-close") |     emit("modal-close") | ||||||
| @ -32,6 +38,7 @@ async function postNewResearch(){ | |||||||
|   } |   } | ||||||
|   await postResearch(toPost) |   await postResearch(toPost) | ||||||
|   toPost = Object.assign({}, {}); |   toPost = Object.assign({}, {}); | ||||||
|  |   coAuthors.value = [] | ||||||
|   emit("modal-close") |   emit("modal-close") | ||||||
|   emit("posted") |   emit("posted") | ||||||
| } | } | ||||||
| @ -69,6 +76,8 @@ onClickOutside(target, ()=>emit('modal-close')) | |||||||
|             <option value="Restricted">Restricted</option> |             <option value="Restricted">Restricted</option> | ||||||
|             <option value="Private">Private</option> |             <option value="Private">Private</option> | ||||||
|           </select></li> |           </select></li> | ||||||
|  |  | ||||||
|  |  | ||||||
|           <li> Research Pdf : |           <li> Research Pdf : | ||||||
|             <form novalidate enctype="multipart/form-data" class="inputBox"> |             <form novalidate enctype="multipart/form-data" class="inputBox"> | ||||||
|             <input type="file" @change="uploadResearchPdf($event.target.files);" accept="application/pdf"> |             <input type="file" @change="uploadResearchPdf($event.target.files);" accept="application/pdf"> | ||||||
| @ -79,11 +88,19 @@ onClickOutside(target, ()=>emit('modal-close')) | |||||||
|           </form></li> |           </form></li> | ||||||
|         </ul> |         </ul> | ||||||
|         </div> |         </div> | ||||||
|  |         <div id="CoAuthorList"> Co-Authors List: | ||||||
|  |         <ul style="list-style-type: none;" v-for="n in allResearcher"> | ||||||
|  |           <li v-if="n.id !== props.researcher.id"> <input type="checkbox" :value=n v-model="coAuthors"> {{n.id}} : {{n.user.firstName}} {{n.user.lastName}}</li> | ||||||
|  |         </ul> | ||||||
|  |  | ||||||
|  |       </div> | ||||||
|  |         <div></div> | ||||||
|         <div> |         <div> | ||||||
|           <button id="confirmButton" @click="postNewResearch">Confirm Publish</button> |           <button id="confirmButton" @click="postNewResearch">Confirm Publish</button> | ||||||
|           <button id="cancelButton" @click="cancelPost">Cancel Publish</button> |           <button id="cancelButton" @click="cancelPost">Cancel Publish</button> | ||||||
|         </div> |         </div> | ||||||
|       </div> |       </div> | ||||||
|  |  | ||||||
|     </div> |     </div> | ||||||
|   </div> |   </div> | ||||||
|  |  | ||||||
| @ -101,6 +118,8 @@ onClickOutside(target, ()=>emit('modal-close')) | |||||||
| } | } | ||||||
|  |  | ||||||
| .modal-container { | .modal-container { | ||||||
|  |   display: grid; | ||||||
|  |   grid-template-columns: 40% 60%; | ||||||
|   width: 70%; |   width: 70%; | ||||||
|   margin: 150px auto; |   margin: 150px auto; | ||||||
|   padding: 20px 30px; |   padding: 20px 30px; | ||||||
| @ -113,6 +132,12 @@ onClickOutside(target, ()=>emit('modal-close')) | |||||||
|   margin-top: 9px; |   margin-top: 9px; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | #coAuthorList{ | ||||||
|  |   overflow: scroll; | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
| #downloads button { | #downloads button { | ||||||
|   align-self: center; |   align-self: center; | ||||||
|   margin-left: 2px; |   margin-left: 2px; | ||||||
|  | |||||||
| @ -51,7 +51,14 @@ async function downloadArticle (research) { | |||||||
| } | } | ||||||
|  |  | ||||||
| function downloadCoAuthors(){ | function downloadCoAuthors(){ | ||||||
|   const data = JSON.stringify(researcher.value); |   let coAuthors = [] | ||||||
|  |   for (let i in researchList.value) { | ||||||
|  |     for (const j in researchList.value[i].coAuthors){ | ||||||
|  |       const coAuthor = researchList.value[i].coAuthors[j] | ||||||
|  |       coAuthors.push(coAuthor) | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |   const data = JSON.stringify(coAuthors); | ||||||
|   const blob = new Blob([data], {type:"application/json"}); |   const blob = new Blob([data], {type:"application/json"}); | ||||||
|   return URL.createObjectURL(blob); |   return URL.createObjectURL(blob); | ||||||
| } | } | ||||||
|  | |||||||
| @ -6,7 +6,7 @@ export async function deleteArticle(id){ | |||||||
| export async function patchArticle(id, data){ | export async function patchArticle(id, data){ | ||||||
|     await restPatch("/research/" + id, data) |     await restPatch("/research/" + id, data) | ||||||
| } | } | ||||||
| export async function uploadPdf(file){ | export async function uploadFile(file){ | ||||||
|     const formData = new FormData(); |     const formData = new FormData(); | ||||||
|     formData.append("file", file[0]); |     formData.append("file", file[0]); | ||||||
|  |  | ||||||
| @ -27,3 +27,6 @@ export async function getFile(url){ | |||||||
| export async function addView(url){ | export async function addView(url){ | ||||||
|     return restPost("/addview/" + url) |     return restPost("/addview/" + url) | ||||||
| } | } | ||||||
|  | export async function fetchAllResearchers(){ | ||||||
|  |     return await restGet("/researchers") | ||||||
|  | } | ||||||
		Reference in New Issue
	
	Block a user