From 4ee2837c72d94adbb39850838b02d9e26f25b7ca Mon Sep 17 00:00:00 2001 From: fred-fri <fred-fri@dsv.su.se> Date: Tue, 29 May 2012 11:49:20 +0900 Subject: [PATCH] refactored addUnexistingUnitsAsKeywords method to use new Unit entity --- .../dsv/scipro/io/facade/ImporterFacade.java | 1207 +++++++++-------- .../dsv/scipro/springdata/repos/UnitRepo.java | 2 +- .../serviceimpls/UnitServiceImpl.java | 11 + .../springdata/services/UnitService.java | 5 +- 4 files changed, 629 insertions(+), 596 deletions(-) diff --git a/src/main/java/se/su/dsv/scipro/io/facade/ImporterFacade.java b/src/main/java/se/su/dsv/scipro/io/facade/ImporterFacade.java index 8faffac2e3..d34bea52a4 100644 --- a/src/main/java/se/su/dsv/scipro/io/facade/ImporterFacade.java +++ b/src/main/java/se/su/dsv/scipro/io/facade/ImporterFacade.java @@ -44,168 +44,178 @@ import se.su.dsv.scipro.match.dao.interfaces.KeywordTypeDao; import se.su.dsv.scipro.match.dao.interfaces.SupervisorDao; import se.su.dsv.scipro.match.dataobject.Keyword; import se.su.dsv.scipro.springdata.services.MessageBoardService; +import se.su.dsv.scipro.springdata.services.UnitService; /** * Main service facade for all importing operations. - * The intent is that methods attached to this facade persists and merges incoming DTO-style objects into locally managed DomainObjects. + * The intent is that methods attached to this facade persists and merges incoming DTO-style objects into locally managed DomainObjects. */ @Service public class ImporterFacade { - @Autowired - private UserDao userDao; - @Autowired - private RoleDao roleDao; - @Autowired - private ProjectDao projectDao; - @Autowired - private UsernameDao usernameDao; - @Autowired - private ProjectClassDao projectClassDao; - @Autowired - private ProjectFollowerDao projectFollowerDao; - @Autowired - private SupervisorDao supervisorDao; - @Autowired - private ExternalImporter externalImporter; - @Autowired - private FinalSeminarDao finalSeminarDao; - @Autowired - private KeywordDao keywordDao; - @Autowired - private KeywordTypeDao keywordTypeDao; - @Autowired - private FinalSeminarActiveParticipationDao finalSeminarActiveParticipationDao; - @Autowired - private FinalSeminarOppositionDao finalSeminarOppositionDao; + + @Autowired + private UnitService unitService; + + @Autowired + private UserDao userDao; + @Autowired + private RoleDao roleDao; + @Autowired + private ProjectDao projectDao; + @Autowired + private UsernameDao usernameDao; + @Autowired + private ProjectClassDao projectClassDao; + @Autowired + private ProjectFollowerDao projectFollowerDao; + @Autowired + private SupervisorDao supervisorDao; + @Autowired + private ExternalImporter externalImporter; + @Autowired + private FinalSeminarDao finalSeminarDao; + @Autowired + private KeywordDao keywordDao; + @Autowired + private KeywordTypeDao keywordTypeDao; + @Autowired + private FinalSeminarActiveParticipationDao finalSeminarActiveParticipationDao; + @Autowired + private FinalSeminarOppositionDao finalSeminarOppositionDao; @Autowired MessageBoardService messageBoardService; - @PersistenceContext - private EntityManager entityManager; - private transient Logger logger = Logger.getLogger(ImporterFacade.class); + @PersistenceContext + private EntityManager entityManager; + private transient Logger logger = Logger.getLogger(ImporterFacade.class); /** - * If the supplied user is null, a new one will be created and persisted. - * Does not handle transient User instances, you probably have to do a dao-query for it before running this method. - * @param user hte user - * @param dtoUser the dtoUser - */ - @Transactional - public void mergeUser(final User user, final UserDTO dtoUser){ - User userToMerge = (user!=null?user:new User()); - if(userToMerge.getId() == null) //New user - userToMerge = userDao.save(userToMerge); - userFromDTO(userToMerge,dtoUser,true); - } - @Transactional - public void mergeProject(final Project project, final ProjectDTO dtoProject){ - Project projectToMerge = (project!=null?project:new Project()); - projectFromDTO(projectToMerge,dtoProject,true); - } - /** - * Utility method for translating between DTO/DomainObject. - */ - private void userFromDTO(final User user,final UserDTO userDTO, boolean mergeLinkedEntities){ - user.setEmailAddress(userDTO.email); - user.setFirstName(userDTO.firstName); - user.setLastName(userDTO.lastName); - user.setIdentifier(userDTO.id); - if(mergeLinkedEntities){ - mergeLinkedUsernames(user,userDTO.usernames); - mergeLinkedProjects(userDTO.projects); - mergeLinkedRoles(user,userDTO.roles); - mergeLinkedResearchAreas(user, userDTO.researchAreas); - } - } - - private void mergeLinkedUsernames(final User user, final Set<UsernameDTO> userNames){ - final Set<Username> currentUserNames = user.getUserNames(); - final Set<UsernameDTO> userNamesInput = new HashSet<UsernameDTO>(userNames);//Defensive copy - final Set<Username> usernamesToRemove = new HashSet<Username>(); - logger.debug("Current usernames: " + currentUserNames); - for(Username curUname:currentUserNames){ - final UsernameDTO translatedCurUname = dtoFromUsername(curUname); - if(userNamesInput.contains(translatedCurUname)){ - logger.debug("The user name: " + translatedCurUname + " exists in input, skipping"); - userNamesInput.remove(translatedCurUname); - }else{ - logger.debug("The user name: " + translatedCurUname + " does not exist in input, removing"); - usernamesToRemove.add(curUname); - } - } - logger.debug("List to remove:" + usernamesToRemove); - logger.debug("List to add: " + userNamesInput); - //Remove unwanted usernames - for(Username unameToRemove : usernamesToRemove){ - usernameDao.delete(unameToRemove); - user.getUserNames().remove(unameToRemove); - } - //Add wanted usernames - for(UsernameDTO unameDTOToAdd : userNamesInput){ - Username unameToAdd = new Username(); - userNameFromDTO(unameToAdd,unameDTOToAdd); - unameToAdd.setUser(user); - unameToAdd = usernameDao.save(unameToAdd); - user.addUserName(unameToAdd); - } - } - private void mergeLinkedProjects(final Set<ProjectDTO> projects){ - for(final ProjectDTO projectDTO : projects){ - logger.debug("Linking users to project: '"+projectDTO+"'"); - Project project = projectDao.getProjectByIdentifier(projectDTO.id); - if(project == null){ - logger.info("External project: '"+projectDTO+"' has no local representation, creating"); - project = new Project(); - } - projectFromDTO(project,projectDTO,true); - } - } - private void mergeLinkedRoles(final User user, final Set<UserRoleDTO> roles){ - for(final UserRoleDTO roleDTO : roles){ - logger.debug("Making role: "+roleDTO.role+ " for user: "+user); - if(roleDTO.role.equals(UserRoleDTO.EXTERNAL_USER_ROLES.AUTHOR_ROLE.asExternal())){ - roleDao.makeStudent(user); - } - if(roleDTO.role.equals(UserRoleDTO.EXTERNAL_USER_ROLES.SUPERVISOR_ROLE.asExternal())){ - roleDao.makeEmployee(user); - } - if(roleDTO.role.equals(UserRoleDTO.EXTERNAL_USER_ROLES.ADMIN_ROLE.asExternal())){ - roleDao.makeAdmin(user); - } - } - } - private void projectFromDTO(Project project, final ProjectDTO projectDTO, boolean mergeLinkedEntities) { - project.setIdentifier(projectDTO.id); - SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd"); - try { - project.setDaisyStartDate(format.parse(projectDTO.startDate)); - } catch (ParseException e) { - e.printStackTrace(); - } - project.setTitle(projectDTO.title); - project.setProjectStatus(toLocalStatus(projectDTO.status)); - ProjectClass externalProjectClass = toLocalClass(projectDTO); - if(externalProjectClass == null){ - logger.warn("External project type: '"+projectDTO.type+ "' has no local representation, creating"); - externalProjectClass = new ProjectClass(); - externalProjectClass.setCode(projectDTO.type.toUpperCase().trim()); - externalProjectClass.setName(projectDTO.type); - externalProjectClass.setDescription("Externally imported project class"); - externalProjectClass = projectClassDao.save(externalProjectClass); - } - logger.debug("Using project class: "+ externalProjectClass+" to import project: "+projectDTO); - project.setProjectClass(externalProjectClass); - //Putting this here to trick the persistence api, the above assignments are mandatory, but the project is not allowed to be transient for the following to work - if(!entityManager.contains(project)){ + * If the supplied user is null, a new one will be created and persisted. + * Does not handle transient User instances, you probably have to do a dao-query for it before running this method. + * + * @param user hte user + * @param dtoUser the dtoUser + */ + @Transactional + public void mergeUser(final User user, final UserDTO dtoUser) { + User userToMerge = (user != null ? user : new User()); + if (userToMerge.getId() == null) //New user + userToMerge = userDao.save(userToMerge); + userFromDTO(userToMerge, dtoUser, true); + } + + @Transactional + public void mergeProject(final Project project, final ProjectDTO dtoProject) { + Project projectToMerge = (project != null ? project : new Project()); + projectFromDTO(projectToMerge, dtoProject, true); + } + + /** + * Utility method for translating between DTO/DomainObject. + */ + private void userFromDTO(final User user, final UserDTO userDTO, boolean mergeLinkedEntities) { + user.setEmailAddress(userDTO.email); + user.setFirstName(userDTO.firstName); + user.setLastName(userDTO.lastName); + user.setIdentifier(userDTO.id); + if (mergeLinkedEntities) { + mergeLinkedUsernames(user, userDTO.usernames); + mergeLinkedProjects(userDTO.projects); + mergeLinkedRoles(user, userDTO.roles); + mergeLinkedResearchAreas(user, userDTO.researchAreas); + } + } + + private void mergeLinkedUsernames(final User user, final Set<UsernameDTO> userNames) { + final Set<Username> currentUserNames = user.getUserNames(); + final Set<UsernameDTO> userNamesInput = new HashSet<UsernameDTO>(userNames);//Defensive copy + final Set<Username> usernamesToRemove = new HashSet<Username>(); + logger.debug("Current usernames: " + currentUserNames); + for (Username curUname : currentUserNames) { + final UsernameDTO translatedCurUname = dtoFromUsername(curUname); + if (userNamesInput.contains(translatedCurUname)) { + logger.debug("The user name: " + translatedCurUname + " exists in input, skipping"); + userNamesInput.remove(translatedCurUname); + } else { + logger.debug("The user name: " + translatedCurUname + " does not exist in input, removing"); + usernamesToRemove.add(curUname); + } + } + logger.debug("List to remove:" + usernamesToRemove); + logger.debug("List to add: " + userNamesInput); + //Remove unwanted usernames + for (Username unameToRemove : usernamesToRemove) { + usernameDao.delete(unameToRemove); + user.getUserNames().remove(unameToRemove); + } + //Add wanted usernames + for (UsernameDTO unameDTOToAdd : userNamesInput) { + Username unameToAdd = new Username(); + userNameFromDTO(unameToAdd, unameDTOToAdd); + unameToAdd.setUser(user); + unameToAdd = usernameDao.save(unameToAdd); + user.addUserName(unameToAdd); + } + } + + private void mergeLinkedProjects(final Set<ProjectDTO> projects) { + for (final ProjectDTO projectDTO : projects) { + logger.debug("Linking users to project: '" + projectDTO + "'"); + Project project = projectDao.getProjectByIdentifier(projectDTO.id); + if (project == null) { + logger.info("External project: '" + projectDTO + "' has no local representation, creating"); + project = new Project(); + } + projectFromDTO(project, projectDTO, true); + } + } + + private void mergeLinkedRoles(final User user, final Set<UserRoleDTO> roles) { + for (final UserRoleDTO roleDTO : roles) { + logger.debug("Making role: " + roleDTO.role + " for user: " + user); + if (roleDTO.role.equals(UserRoleDTO.EXTERNAL_USER_ROLES.AUTHOR_ROLE.asExternal())) { + roleDao.makeStudent(user); + } + if (roleDTO.role.equals(UserRoleDTO.EXTERNAL_USER_ROLES.SUPERVISOR_ROLE.asExternal())) { + roleDao.makeEmployee(user); + } + if (roleDTO.role.equals(UserRoleDTO.EXTERNAL_USER_ROLES.ADMIN_ROLE.asExternal())) { + roleDao.makeAdmin(user); + } + } + } + + private void projectFromDTO(Project project, final ProjectDTO projectDTO, boolean mergeLinkedEntities) { + project.setIdentifier(projectDTO.id); + SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd"); + try { + project.setDaisyStartDate(format.parse(projectDTO.startDate)); + } catch (ParseException e) { + e.printStackTrace(); + } + project.setTitle(projectDTO.title); + project.setProjectStatus(toLocalStatus(projectDTO.status)); + ProjectClass externalProjectClass = toLocalClass(projectDTO); + if (externalProjectClass == null) { + logger.warn("External project type: '" + projectDTO.type + "' has no local representation, creating"); + externalProjectClass = new ProjectClass(); + externalProjectClass.setCode(projectDTO.type.toUpperCase().trim()); + externalProjectClass.setName(projectDTO.type); + externalProjectClass.setDescription("Externally imported project class"); + externalProjectClass = projectClassDao.save(externalProjectClass); + } + logger.debug("Using project class: " + externalProjectClass + " to import project: " + projectDTO); + project.setProjectClass(externalProjectClass); + //Putting this here to trick the persistence api, the above assignments are mandatory, but the project is not allowed to be transient for the following to work + if (!entityManager.contains(project)) { boolean newProject = (project.getId() == null); project = projectDao.save(project); - if (newProject){ + if (newProject) { MessageBoard messageBoard = new MessageBoard(project); messageBoard.setTitle(project.getTitle()); messageBoard = messageBoardService.save(messageBoard); - } - else { + } else { MessageBoard messageBoard = messageBoardService.getMessageBoard(project); messageBoard.setTitle(project.getTitle()); messageBoard = messageBoardService.save(messageBoard); @@ -214,457 +224,466 @@ public class ImporterFacade { } + //Loop over all participants and assign roles + if (mergeLinkedEntities) { + checkForRemovedMembers(project, projectDTO.participants); + for (ProjectParticipantDTO projectParticipant : projectDTO.participants) { + projectParticipantFromDTO(project, projectParticipant); + } + } + } + + private void checkForRemovedMembers(final Project project, final Set<ProjectParticipantDTO> participants) { + //Get project team members. + final Set<Member> currentMembers = new HashSet<Member>(project.getMembers()); + final Set<ProjectParticipantDTO> remoteMembers = new HashSet<ProjectParticipantDTO>(participants); + final Set<Member> membersToRemove = new HashSet<Member>(); + //Check to see if some members of the projects have been removed from Daisy. If so, we need to remove from Scipro as well. + for (Member m : currentMembers) { + logger.debug("Translating member " + m + " to DTO to compare with remote participants."); + ProjectParticipantDTO translated = participantDtoFromMember(m); + if (remoteMembers.contains(translated)) { + logger.debug(m + " exists on remote system, skipping."); + remoteMembers.remove(translated); + } else { + logger.info(m + " does not exist on remote system, removing from Scipro."); + membersToRemove.add(m); + } + } + //Removing member from Scipro. + for (Member m : membersToRemove) { + switch (m.getType()) { + case AUTHOR: { + Student student = roleDao.findStudentRole(m.getUser()); + project.removeAuthor(student); + break; + } + case SUPERVISOR: { + project.removeSupervisor(); + break; + } + case CO_SUPERVISOR: { + Employee emp = supervisorDao.getFrom(m.getUser()); + ProjectFollower pf = new ProjectFollower(); + pf.setProjectRole(ProjectTeamMemberRoles.CO_SUPERVISOR); + pf.setFollower(emp); + if (project.getProjectCoSupervisors().contains(pf)) + project.removeProjectFollower(pf); + else + logger.debug("Can't find project follower to remove."); + break; + } + case REVIEWER: { + Employee emp = supervisorDao.getFrom(m.getUser()); + ProjectFollower pf = new ProjectFollower(); + pf.setProjectRole(ProjectTeamMemberRoles.REVIEWER); + pf.setFollower(emp); + if (project.getProjectReviewers().contains(pf)) + project.removeProjectFollower(pf); + else + logger.debug("Can't find project follower to remove."); + break; + } + } + } + } - //Loop over all participants and assign roles - if(mergeLinkedEntities){ - checkForRemovedMembers(project, projectDTO.participants); - for(ProjectParticipantDTO projectParticipant:projectDTO.participants){ - projectParticipantFromDTO(project,projectParticipant); - } - } - } - private void checkForRemovedMembers(final Project project, final Set<ProjectParticipantDTO> participants) { - //Get project team members. - final Set<Member> currentMembers = new HashSet<Member>(project.getMembers()); - final Set<ProjectParticipantDTO> remoteMembers = new HashSet<ProjectParticipantDTO>(participants); - final Set<Member> membersToRemove = new HashSet<Member>(); - //Check to see if some members of the projects have been removed from Daisy. If so, we need to remove from Scipro as well. - for(Member m : currentMembers) { - logger.debug("Translating member "+m+" to DTO to compare with remote participants."); - ProjectParticipantDTO translated = participantDtoFromMember(m); - if(remoteMembers.contains(translated)){ - logger.debug(m+" exists on remote system, skipping."); - remoteMembers.remove(translated); - } else { - logger.info(m+" does not exist on remote system, removing from Scipro."); - membersToRemove.add(m); - } - } - //Removing member from Scipro. - for(Member m : membersToRemove){ - switch(m.getType()){ - case AUTHOR: { - Student student = roleDao.findStudentRole(m.getUser()); - project.removeAuthor(student); - break; - } - case SUPERVISOR: { - project.removeSupervisor(); - break; - } - case CO_SUPERVISOR: { - Employee emp = supervisorDao.getFrom(m.getUser()); - ProjectFollower pf = new ProjectFollower(); - pf.setProjectRole(ProjectTeamMemberRoles.CO_SUPERVISOR); - pf.setFollower(emp); - if(project.getProjectCoSupervisors().contains(pf)) - project.removeProjectFollower(pf); - else - logger.debug("Can't find project follower to remove."); - break; - } - case REVIEWER: { - Employee emp = supervisorDao.getFrom(m.getUser()); - ProjectFollower pf = new ProjectFollower(); - pf.setProjectRole(ProjectTeamMemberRoles.REVIEWER); - pf.setFollower(emp); - if(project.getProjectReviewers().contains(pf)) - project.removeProjectFollower(pf); - else - logger.debug("Can't find project follower to remove."); - break; - } - } - } - - - } - private ProjectParticipantDTO participantDtoFromMember(Member m) { - ProjectParticipantDTO dto = new ProjectParticipantDTO(); - PersonDTO person = new PersonDTO(m.getUser().getIdentifier()); - dto.setPerson(person); - switch(m.getType()){ - case AUTHOR: - { - dto.setRole(EXTERNAL_PROJECT_ROLE.PARTICIPANT.name()); - break; - } - case SUPERVISOR: - { - dto.setRole(EXTERNAL_PROJECT_ROLE.SUPERVISOR.name()); - break; - } - case REVIEWER: - { - dto.setRole(EXTERNAL_PROJECT_ROLE.EXAMINER.name()); - break; - } - case CO_SUPERVISOR: - { - dto.setRole(EXTERNAL_PROJECT_ROLE.ASSISTANT_SUPERVISOR.name()); - break; - } - } - return dto; - } - private void projectParticipantFromDTO(final Project project, final ProjectParticipantDTO projectParticipant) { - //Use existing members to avoid duplicated roles being assigned - final List<Member> currentProjectMembers = project.getMembers(); - logger.debug("Linking: "+projectParticipant); - User linkedUser = userDao.getUserByIdentifier(projectParticipant.person.id); - if(linkedUser == null){ //Attempt to import the user if it's a new one. - externalImporter.importUser(projectParticipant.person.id, false); - linkedUser = userDao.getUserByIdentifier(projectParticipant.person.id); - if(linkedUser == null){ - logger.error("Can't import user with id: " + projectParticipant.person.id + " skipping assigning him/her to the project: "+ project); - return; - } - } - final ProjectParticipantDTO.LOCAL_PROJECT_ROLE localRole = extractLocalRole(projectParticipant.role); - if(localRole == null){//this is an unknown project role, warn and continue - logger.warn("Encountered an unknown project role ("+projectParticipant.role+") when importing project participant: "+projectParticipant.person.id +", the participant will be skipped"); - return; - } - //Assign the local role to the participant, this is a lot of boilerplate code and should be made easier. - logger.debug("Assigning the role "+localRole+" for "+linkedUser+" on project "+project); - switch(localRole){ - case PARTICIPANT: - { - //logger.debug("Assigning Participant role to "+projectParticipant.person.id); - final Member tmpMember = new Member(linkedUser,Member.Type.AUTHOR); - if(currentProjectMembers.contains(tmpMember)){ - logger.debug("Skipping already assigned "+tmpMember.getType() + " user "+tmpMember.getUser()); - return;//Skip if already assigned an author role - } - logger.debug("Making '" + linkedUser + "' an author"); - final Student stud = roleDao.makeStudent(linkedUser); - project.getProjectParticipants().add(stud); - break; - } - case ACTIVE_PARTICIPANT: - { - final List<FinalSeminar> fsList = assureFinalSeminarAvailable(project); - //logger.debug("Assigning Active participation role to " + fsList.size() + " seminars for "+projectParticipant.person.id); - for(FinalSeminar fs : fsList){ - if(userAlreadyAttachedAsParticipant(linkedUser,fs.getActiveParticipations())) - continue; - FinalSeminarActiveParticipation fsap = new FinalSeminarActiveParticipation(); - fsap.setUser(linkedUser); - fsap.setFinalSeminar(fs); - fsap.setProject(project); - fsap = finalSeminarActiveParticipationDao.save(fsap); - fs.getActiveParticipations().add(fsap); - } - break; - } - case EXAMINER: - { - ProjectFollower pf = new ProjectFollower(); - //logger.debug("Assigning Examiner role to "+projectParticipant.person.id); - final Member tmpMember = new Member(linkedUser,Member.Type.REVIEWER); - if(currentProjectMembers.contains(tmpMember)){ - logger.debug("Skipping already assigned "+tmpMember.getType() + " user "+tmpMember.getUser()); - return;//Skip if already assigned a Reviewer role - } - final Employee emp = roleDao.makeEmployee(linkedUser); - pf.setProjectRole(ProjectTeamMemberRoles.REVIEWER); - pf.setFollower(emp); - if(pf.getFollower() != null && pf.getProjectRole() != null){ - pf.setProject(project); - pf = projectFollowerDao.save(pf); - project.getProjectFollowers().add(pf); - } - break; - } - case OPPONENT: - { - final List<FinalSeminar> fsList = assureFinalSeminarAvailable(project); - //logger.debug("Assigning Opponent role to " + fsList.size() + " seminars for "+projectParticipant.person.id); - for(FinalSeminar fs : fsList){ - if(userAlreadyAttachedAsParticipant(linkedUser,fs.getOppositions())) - continue; - FinalSeminarOpposition fsop = new FinalSeminarOpposition(); - final Student stud = roleDao.makeStudent(linkedUser); - fsop.setOpponent(stud); - fsop.setFinalSeminar(fs); - fsop.setProject(project); - fsop = finalSeminarOppositionDao.save(fsop); - fs.getOppositions().add(fsop); - } - break; - } - case SUPERVISOR: - { - //logger.debug("Assigning Supervisor role to "+projectParticipant.person.id); - final Member tmpMember = new Member(linkedUser,Member.Type.SUPERVISOR); - if(currentProjectMembers.contains(tmpMember)){ - logger.debug("Skipping already assigned "+tmpMember.getType() + " user "+tmpMember.getUser()); - return;//Skip if already assigned a supervisor role - } - logger.debug("Making '" + linkedUser + "' a supervisor"); - final Employee emp = roleDao.makeEmployee(linkedUser); - project.setHeadSupervisor(emp); - break; - } - case CO_SUPERVISOR: - { - ProjectFollower pf = new ProjectFollower(); - //logger.debug("Assigning Co-supervisor role to "+projectParticipant.person.id); - final Member tmpMember = new Member(linkedUser,Member.Type.CO_SUPERVISOR); - if(currentProjectMembers.contains(tmpMember)){ - logger.debug("Skipping already assigned "+tmpMember.getType() + " user "+tmpMember.getUser()); - return;//Skip if already assigned a co-supervisor role - } - final Employee emp = roleDao.makeEmployee(linkedUser); - pf.setProjectRole(ProjectTeamMemberRoles.CO_SUPERVISOR); - pf.setFollower(emp); - //Add the assigned PF to the project and save - if(pf.getFollower() != null && pf.getProjectRole() != null){ - pf.setProject(project); - pf = projectFollowerDao.save(pf); - project.getProjectFollowers().add(pf); - } - break; - } - } - } - /* - * Translate remote roles to local ones. - */ - private LOCAL_PROJECT_ROLE extractLocalRole(final String fromRemoteRole) { - if(fromRemoteRole == null) - return null; - for(EXTERNAL_PROJECT_ROLE externalRole : EXTERNAL_PROJECT_ROLE.values()){ - if(fromRemoteRole.equalsIgnoreCase(externalRole.toString())) - return externalRole.toLocal(); - } - return null; - } - private boolean userAlreadyAttachedAsParticipant(final User user,final List<? extends FinalSeminarParticipation> participantList) { - for(final FinalSeminarParticipation participant : participantList) - if(user.equals(participant.getUser())) - return true; - return false; - } - private List<FinalSeminar> assureFinalSeminarAvailable(final Project project) { - final List<FinalSeminar> fsList = finalSeminarDao.findFinalSeminarsByProject(project); - if(fsList.size() == 0){ - logger.warn("No seminars registered for the project " + project + ", creating a default seminar dated according to start/end dates for the project"); - FinalSeminar fs = new FinalSeminar(); - fs.setProject(project); - fs.setRoom("n/a"); - fs.setStartDate(project.getDaisyStartDate()); - fs.setEndDate(project.getDaisyStartDate()); - fs = finalSeminarDao.save(fs); - fsList.add(fs); - } - return fsList; - } - private void userNameFromDTO(final Username username, final UsernameDTO usernameDTO){ - username.setUserName(usernameDTO.getUsername().toLowerCase().trim()); - username.setRealm(usernameDTO.getRealm().toUpperCase().trim()); - } - private UsernameDTO dtoFromUsername(final Username name){ - UsernameDTO dto = new UsernameDTO(); - dto.setUsername(name.getUserName().toLowerCase().trim()); - dto.setRealm(name.getRealm().toUpperCase().trim()); - return dto; - } - - private ProjectClass toLocalClass(final ProjectDTO projectDTO){ - ProjectClass pClass = null; - final String extractedType = extractProjectType(projectDTO); - pClass = projectClassDao.getProjectClass(extractedType); - return pClass; - } - private String extractProjectType(ProjectDTO projectDTO) { - String extractedType = ProjectClass.UNKNOWN; - if(projectDTO.type != null){//Find class from project - extractedType = mapToLocalProjectClass(projectDTO.type); - }else{//Find class from participants as a fallback - for(ProjectParticipantDTO projectParticipant : projectDTO.participants){ - if(projectParticipant.level != null){ - extractedType = mapToLocalProjectClass(projectParticipant.level); - break; - } - } - } - logger.debug("Returning: "+extractedType+ " as the extracted type of the project: "+projectDTO); - return extractedType; - } - private String mapToLocalProjectClass(final String input){ - if(input == null) - return null; - for(ProjectParticipantDTO.EXTERNAL_PROJECT_CLASS cls : ProjectParticipantDTO.EXTERNAL_PROJECT_CLASS.values()){ - if(input.equalsIgnoreCase(cls.toString())) - return cls.toLocal(); - } - return null; - } - private ProjectStatus toLocalStatus(String externalProjectStatus){ - if(externalProjectStatus.equals("STARTED") || externalProjectStatus.equals("LATE")){ - return ProjectStatus.ACTIVE; - }else if(externalProjectStatus.equals("FINISHED")){ - return ProjectStatus.COMPLETED; - }else{ - return ProjectStatus.INACTIVE; - } - } - - @Transactional - public void addUnitToSupervisor(PersonDTO supervisorDTO, UnitDTO unitDTO) { - User supervisorUser = userDao.getUserByIdentifier(supervisorDTO.id); - Employee supervisor = supervisorDao.getFrom(supervisorUser); - if(supervisor!=null){ - List<Keyword> currentUnits = supervisor.getKeywords().getFiltered(keywordTypeDao.findByType(KeywordTypeDao.TYPE.UNIT)); - //If supervisor is already assigned to a unit, remove to make sure only the latest unit is being added since we only allow one unit in Scipro. - //Supervisor is not going to be allowed to have more than one unit in the future, but some have two in Daisy at the moment. - if (!currentUnits.isEmpty()) { - logger.info(supervisor.getUser().getFullName() + " is already attached to a unit and this is being overwritten."); - supervisor.getKeywords().getAll().removeAll(currentUnits); - } - Keyword unitToAdd = keywordDao.getKeywordByIdentifierAndType(unitDTO.id, keywordTypeDao.findByType(KeywordTypeDao.TYPE.UNIT)); - logger.debug("Adding unit: " + unitToAdd.getKeyword() + " to supervisor: " + supervisor.getUser().getFullName()); - supervisor.getKeywords().getAll().add(unitToAdd); - } else { - logger.debug("Can't find supervisor: "+ supervisorDTO.id); - } - } - - private void mergeLinkedResearchAreas(final User user, final Set<ResearchAreaDTO> areas){ - for(final ResearchAreaDTO researchAreaDTO : areas){ - Keyword area = keywordDao.getKeywordByIdentifierAndType(researchAreaDTO.id, keywordTypeDao.findByType(KeywordTypeDao.TYPE.RESEARCH_AREA)); - if(area == null){ - logger.info("External research area: '"+researchAreaDTO+"' has no local representation, creating"); - area = new Keyword(researchAreaDTO.name, keywordTypeDao.findByType(KeywordTypeDao.TYPE.RESEARCH_AREA)); - area.setIdentifier(researchAreaDTO.id); - area = keywordDao.save(area); - } else { - logger.info("Research area " + area.getKeyword() + " already exists, skipping"); - } - addResearchAreaToUser(user, area); - } - } - - private void addResearchAreaToUser(User user, Keyword area) { - Employee supervisor = supervisorDao.getFrom(user); - logger.info("Adding research area: " + area.getKeyword() + " to supervisor " + supervisor.getUser().getFullName()); - supervisor.getKeywords().getAll().add(area); - } - - @Transactional - public void addUnexistingResearchAreas(final Set<ResearchAreaDTO> areas) { - final Set<Keyword> currentAreas = keywordDao.getKeywords(keywordTypeDao.findByType(KeywordTypeDao.TYPE.RESEARCH_AREA), true); - final Set<ResearchAreaDTO> remoteAreas = new HashSet<ResearchAreaDTO>(areas); - final Set<Keyword> areasToRemove = new HashSet<Keyword>(); - //Compare remote with database - for (Keyword currentArea : currentAreas){ - ResearchAreaDTO translatedArea = dtoFromAreaKeyword(currentArea); - if(!remoteAreas.contains(translatedArea)){ - logger.info("Area " + translatedArea.getName() + " does not exist on remote, preparing to remove."); - areasToRemove.add(currentArea); - } - } - //Delete areas that not exist on remote - for (Keyword areaToRemove : areasToRemove){ - keywordDao.delete(areaToRemove); - logger.debug("Deleted research area: " + areaToRemove.getKeyword() + " since it has been removed from remote system"); - } - //Add areas to database - for(final ResearchAreaDTO researchAreaDTO : remoteAreas){ - Keyword area = keywordDao.getKeywordByIdentifierAndType(researchAreaDTO.id, keywordTypeDao.findByType(KeywordTypeDao.TYPE.RESEARCH_AREA)); - if(area == null){ - logger.info("External research area: '"+researchAreaDTO+"' has no local representation, creating"); - area = new Keyword(researchAreaDTO.name, keywordTypeDao.findByType(KeywordTypeDao.TYPE.RESEARCH_AREA)); - area.setIdentifier(researchAreaDTO.id); - area = keywordDao.save(area); - } else if (!area.getKeyword().equals(researchAreaDTO.name)){ - logger.info("Research area " + area.getKeyword() + " has changed name, renaming to: " + researchAreaDTO.name); - area.setKeyword(researchAreaDTO.name); - } else { - logger.info("Research area " + area.getKeyword() + " already exists, skipping"); - } - if (researchAreaDTO.active.equals("false")){ - logger.info(area.getKeyword() + " is inactivated on remote system."); - area.setDeleted(true); - } - } - } - - @Transactional - public void addUnexistingUnitsAsKeywords(final Set<UnitDTO> unitsFromDTO) { - final Set<Keyword> currentUnits = keywordDao.getKeywords(keywordTypeDao.findByType(KeywordTypeDao.TYPE.UNIT), true); - final Set<UnitDTO> remoteUnits = new HashSet<UnitDTO>(unitsFromDTO); - final Set<Keyword> unitsToRemove = new HashSet<Keyword>(); - for (Keyword unit : currentUnits) { - UnitDTO translatedUnit = dtoFromUnitKeyword(unit); - if (!remoteUnits.contains(translatedUnit)) { - logger.info("Unit " + translatedUnit.getName() + " does not exist on remote, preparing to remove."); - unitsToRemove.add(unit); - } - } - //Delete units that not exist on remote - for (Keyword unitToRemove : unitsToRemove){ - keywordDao.delete(unitToRemove); - logger.debug("Deleted unit: " + unitToRemove.getKeyword() + " since it has been removed from remote system"); - } - //Add units to database - for(final UnitDTO unitDTO : remoteUnits){ - Keyword unit = keywordDao.getKeywordByIdentifierAndType(unitDTO.id, keywordTypeDao.findByType(KeywordTypeDao.TYPE.UNIT)); - if(unit == null){ - logger.info("External unit: '"+unitDTO+"' has no local representation, creating"); - unit = new Keyword(unitDTO.name, keywordTypeDao.findByType(KeywordTypeDao.TYPE.UNIT)); - unit.setIdentifier(unitDTO.id); - unit = keywordDao.save(unit); - } else if (!unit.getKeyword().equals(unitDTO.name)){ - logger.info("Unit " + unit.getKeyword() + " has changed name, renaming to: " + unitDTO.name); - unit.setKeyword(unitDTO.name); - } else { - logger.info("Unit " + unit.getKeyword() + " already exists, skipping"); - } - } - } - - public void removeUnitFromSupervisorsNotInSet(Set<PersonDTO> supervisorSet) { - final Set<Employee> supervisorsWithRemoteUnit = new HashSet<Employee>(); - final Set<Employee> currentSupervisors = new HashSet<Employee>(supervisorDao.findAll()); - - //Create SciPro Employees from DTOs. - for (PersonDTO supervisorDTO : supervisorSet) { - User supervisorUser = userDao.getUserByIdentifier(supervisorDTO.id); - Employee supervisor = supervisorDao.getFrom(supervisorUser); - supervisorsWithRemoteUnit.add(supervisor); - } - - //Remove units from supervisors that is not in the remote set. - for (Employee supervisor : currentSupervisors) { - if(!supervisorsWithRemoteUnit.contains(supervisor)) { - logger.debug(supervisor.getNameAsString()+" does not have a remote unit. Searching for local units to remove."); - List<Keyword> unitsToRemove = supervisor.getKeywords().getFiltered(keywordTypeDao.findByType(KeywordTypeDao.TYPE.UNIT)); - if(!unitsToRemove.isEmpty()){ - supervisor.getKeywords().getAll().removeAll(unitsToRemove); - logger.debug("Removed units from: " + supervisor.getNameAsString()); - } - } - } - } - - private UnitDTO dtoFromUnitKeyword(final Keyword unit){ - UnitDTO dto = new UnitDTO(); - dto.setName(unit.getKeyword()); - if(unit.getIdentifier() != null) - dto.setId(unit.getIdentifier()); - return dto; - } - - private ResearchAreaDTO dtoFromAreaKeyword(final Keyword area){ - ResearchAreaDTO dto = new ResearchAreaDTO(); - dto.setName(area.getKeyword()); - if (area.getIdentifier() != null) - dto.setId(area.getIdentifier()); - return dto; - } + private ProjectParticipantDTO participantDtoFromMember(Member m) { + ProjectParticipantDTO dto = new ProjectParticipantDTO(); + PersonDTO person = new PersonDTO(m.getUser().getIdentifier()); + dto.setPerson(person); + switch (m.getType()) { + case AUTHOR: { + dto.setRole(EXTERNAL_PROJECT_ROLE.PARTICIPANT.name()); + break; + } + case SUPERVISOR: { + dto.setRole(EXTERNAL_PROJECT_ROLE.SUPERVISOR.name()); + break; + } + case REVIEWER: { + dto.setRole(EXTERNAL_PROJECT_ROLE.EXAMINER.name()); + break; + } + case CO_SUPERVISOR: { + dto.setRole(EXTERNAL_PROJECT_ROLE.ASSISTANT_SUPERVISOR.name()); + break; + } + } + return dto; + } + + private void projectParticipantFromDTO(final Project project, final ProjectParticipantDTO projectParticipant) { + //Use existing members to avoid duplicated roles being assigned + final List<Member> currentProjectMembers = project.getMembers(); + logger.debug("Linking: " + projectParticipant); + User linkedUser = userDao.getUserByIdentifier(projectParticipant.person.id); + if (linkedUser == null) { //Attempt to import the user if it's a new one. + externalImporter.importUser(projectParticipant.person.id, false); + linkedUser = userDao.getUserByIdentifier(projectParticipant.person.id); + if (linkedUser == null) { + logger.error("Can't import user with id: " + projectParticipant.person.id + " skipping assigning him/her to the project: " + project); + return; + } + } + final ProjectParticipantDTO.LOCAL_PROJECT_ROLE localRole = extractLocalRole(projectParticipant.role); + if (localRole == null) {//this is an unknown project role, warn and continue + logger.warn("Encountered an unknown project role (" + projectParticipant.role + ") when importing project participant: " + projectParticipant.person.id + ", the participant will be skipped"); + return; + } + //Assign the local role to the participant, this is a lot of boilerplate code and should be made easier. + logger.debug("Assigning the role " + localRole + " for " + linkedUser + " on project " + project); + switch (localRole) { + case PARTICIPANT: { + //logger.debug("Assigning Participant role to "+projectParticipant.person.id); + final Member tmpMember = new Member(linkedUser, Member.Type.AUTHOR); + if (currentProjectMembers.contains(tmpMember)) { + logger.debug("Skipping already assigned " + tmpMember.getType() + " user " + tmpMember.getUser()); + return;//Skip if already assigned an author role + } + logger.debug("Making '" + linkedUser + "' an author"); + final Student stud = roleDao.makeStudent(linkedUser); + project.getProjectParticipants().add(stud); + break; + } + case ACTIVE_PARTICIPANT: { + final List<FinalSeminar> fsList = assureFinalSeminarAvailable(project); + //logger.debug("Assigning Active participation role to " + fsList.size() + " seminars for "+projectParticipant.person.id); + for (FinalSeminar fs : fsList) { + if (userAlreadyAttachedAsParticipant(linkedUser, fs.getActiveParticipations())) + continue; + FinalSeminarActiveParticipation fsap = new FinalSeminarActiveParticipation(); + fsap.setUser(linkedUser); + fsap.setFinalSeminar(fs); + fsap.setProject(project); + fsap = finalSeminarActiveParticipationDao.save(fsap); + fs.getActiveParticipations().add(fsap); + } + break; + } + case EXAMINER: { + ProjectFollower pf = new ProjectFollower(); + //logger.debug("Assigning Examiner role to "+projectParticipant.person.id); + final Member tmpMember = new Member(linkedUser, Member.Type.REVIEWER); + if (currentProjectMembers.contains(tmpMember)) { + logger.debug("Skipping already assigned " + tmpMember.getType() + " user " + tmpMember.getUser()); + return;//Skip if already assigned a Reviewer role + } + final Employee emp = roleDao.makeEmployee(linkedUser); + pf.setProjectRole(ProjectTeamMemberRoles.REVIEWER); + pf.setFollower(emp); + if (pf.getFollower() != null && pf.getProjectRole() != null) { + pf.setProject(project); + pf = projectFollowerDao.save(pf); + project.getProjectFollowers().add(pf); + } + break; + } + case OPPONENT: { + final List<FinalSeminar> fsList = assureFinalSeminarAvailable(project); + //logger.debug("Assigning Opponent role to " + fsList.size() + " seminars for "+projectParticipant.person.id); + for (FinalSeminar fs : fsList) { + if (userAlreadyAttachedAsParticipant(linkedUser, fs.getOppositions())) + continue; + FinalSeminarOpposition fsop = new FinalSeminarOpposition(); + final Student stud = roleDao.makeStudent(linkedUser); + fsop.setOpponent(stud); + fsop.setFinalSeminar(fs); + fsop.setProject(project); + fsop = finalSeminarOppositionDao.save(fsop); + fs.getOppositions().add(fsop); + } + break; + } + case SUPERVISOR: { + //logger.debug("Assigning Supervisor role to "+projectParticipant.person.id); + final Member tmpMember = new Member(linkedUser, Member.Type.SUPERVISOR); + if (currentProjectMembers.contains(tmpMember)) { + logger.debug("Skipping already assigned " + tmpMember.getType() + " user " + tmpMember.getUser()); + return;//Skip if already assigned a supervisor role + } + logger.debug("Making '" + linkedUser + "' a supervisor"); + final Employee emp = roleDao.makeEmployee(linkedUser); + project.setHeadSupervisor(emp); + break; + } + case CO_SUPERVISOR: { + ProjectFollower pf = new ProjectFollower(); + //logger.debug("Assigning Co-supervisor role to "+projectParticipant.person.id); + final Member tmpMember = new Member(linkedUser, Member.Type.CO_SUPERVISOR); + if (currentProjectMembers.contains(tmpMember)) { + logger.debug("Skipping already assigned " + tmpMember.getType() + " user " + tmpMember.getUser()); + return;//Skip if already assigned a co-supervisor role + } + final Employee emp = roleDao.makeEmployee(linkedUser); + pf.setProjectRole(ProjectTeamMemberRoles.CO_SUPERVISOR); + pf.setFollower(emp); + //Add the assigned PF to the project and save + if (pf.getFollower() != null && pf.getProjectRole() != null) { + pf.setProject(project); + pf = projectFollowerDao.save(pf); + project.getProjectFollowers().add(pf); + } + break; + } + } + } + + /* + * Translate remote roles to local ones. + */ + private LOCAL_PROJECT_ROLE extractLocalRole(final String fromRemoteRole) { + if (fromRemoteRole == null) + return null; + for (EXTERNAL_PROJECT_ROLE externalRole : EXTERNAL_PROJECT_ROLE.values()) { + if (fromRemoteRole.equalsIgnoreCase(externalRole.toString())) + return externalRole.toLocal(); + } + return null; + } + + private boolean userAlreadyAttachedAsParticipant(final User user, final List<? extends FinalSeminarParticipation> participantList) { + for (final FinalSeminarParticipation participant : participantList) + if (user.equals(participant.getUser())) + return true; + return false; + } + + private List<FinalSeminar> assureFinalSeminarAvailable(final Project project) { + final List<FinalSeminar> fsList = finalSeminarDao.findFinalSeminarsByProject(project); + if (fsList.size() == 0) { + logger.warn("No seminars registered for the project " + project + ", creating a default seminar dated according to start/end dates for the project"); + FinalSeminar fs = new FinalSeminar(); + fs.setProject(project); + fs.setRoom("n/a"); + fs.setStartDate(project.getDaisyStartDate()); + fs.setEndDate(project.getDaisyStartDate()); + fs = finalSeminarDao.save(fs); + fsList.add(fs); + } + return fsList; + } + + private void userNameFromDTO(final Username username, final UsernameDTO usernameDTO) { + username.setUserName(usernameDTO.getUsername().toLowerCase().trim()); + username.setRealm(usernameDTO.getRealm().toUpperCase().trim()); + } + + private UsernameDTO dtoFromUsername(final Username name) { + UsernameDTO dto = new UsernameDTO(); + dto.setUsername(name.getUserName().toLowerCase().trim()); + dto.setRealm(name.getRealm().toUpperCase().trim()); + return dto; + } + + private ProjectClass toLocalClass(final ProjectDTO projectDTO) { + ProjectClass pClass = null; + final String extractedType = extractProjectType(projectDTO); + pClass = projectClassDao.getProjectClass(extractedType); + return pClass; + } + + private String extractProjectType(ProjectDTO projectDTO) { + String extractedType = ProjectClass.UNKNOWN; + if (projectDTO.type != null) {//Find class from project + extractedType = mapToLocalProjectClass(projectDTO.type); + } else {//Find class from participants as a fallback + for (ProjectParticipantDTO projectParticipant : projectDTO.participants) { + if (projectParticipant.level != null) { + extractedType = mapToLocalProjectClass(projectParticipant.level); + break; + } + } + } + logger.debug("Returning: " + extractedType + " as the extracted type of the project: " + projectDTO); + return extractedType; + } + + private String mapToLocalProjectClass(final String input) { + if (input == null) + return null; + for (ProjectParticipantDTO.EXTERNAL_PROJECT_CLASS cls : ProjectParticipantDTO.EXTERNAL_PROJECT_CLASS.values()) { + if (input.equalsIgnoreCase(cls.toString())) + return cls.toLocal(); + } + return null; + } + + private ProjectStatus toLocalStatus(String externalProjectStatus) { + if (externalProjectStatus.equals("STARTED") || externalProjectStatus.equals("LATE")) { + return ProjectStatus.ACTIVE; + } else if (externalProjectStatus.equals("FINISHED")) { + return ProjectStatus.COMPLETED; + } else { + return ProjectStatus.INACTIVE; + } + } + + @Transactional + public void addUnitToSupervisor(PersonDTO supervisorDTO, UnitDTO unitDTO) { + User supervisorUser = userDao.getUserByIdentifier(supervisorDTO.id); + Employee supervisor = supervisorDao.getFrom(supervisorUser); + if (supervisor != null) { + List<Keyword> currentUnits = supervisor.getKeywords().getFiltered(keywordTypeDao.findByType(KeywordTypeDao.TYPE.UNIT)); + //If supervisor is already assigned to a unit, remove to make sure only the latest unit is being added since we only allow one unit in Scipro. + //Supervisor is not going to be allowed to have more than one unit in the future, but some have two in Daisy at the moment. + if (!currentUnits.isEmpty()) { + logger.info(supervisor.getUser().getFullName() + " is already attached to a unit and this is being overwritten."); + supervisor.getKeywords().getAll().removeAll(currentUnits); + } + Keyword unitToAdd = keywordDao.getKeywordByIdentifierAndType(unitDTO.id, keywordTypeDao.findByType(KeywordTypeDao.TYPE.UNIT)); + logger.debug("Adding unit: " + unitToAdd.getKeyword() + " to supervisor: " + supervisor.getUser().getFullName()); + supervisor.getKeywords().getAll().add(unitToAdd); + } else { + logger.debug("Can't find supervisor: " + supervisorDTO.id); + } + } + + private void mergeLinkedResearchAreas(final User user, final Set<ResearchAreaDTO> areas) { + for (final ResearchAreaDTO researchAreaDTO : areas) { + Keyword area = keywordDao.getKeywordByIdentifierAndType(researchAreaDTO.id, keywordTypeDao.findByType(KeywordTypeDao.TYPE.RESEARCH_AREA)); + if (area == null) { + logger.info("External research area: '" + researchAreaDTO + "' has no local representation, creating"); + area = new Keyword(researchAreaDTO.name, keywordTypeDao.findByType(KeywordTypeDao.TYPE.RESEARCH_AREA)); + area.setIdentifier(researchAreaDTO.id); + area = keywordDao.save(area); + } else { + logger.info("Research area " + area.getKeyword() + " already exists, skipping"); + } + addResearchAreaToUser(user, area); + } + } + + private void addResearchAreaToUser(User user, Keyword area) { + Employee supervisor = supervisorDao.getFrom(user); + logger.info("Adding research area: " + area.getKeyword() + " to supervisor " + supervisor.getUser().getFullName()); + supervisor.getKeywords().getAll().add(area); + } + + @Transactional + public void addUnexistingResearchAreas(final Set<ResearchAreaDTO> areas) { + final Set<Keyword> currentAreas = keywordDao.getKeywords(keywordTypeDao.findByType(KeywordTypeDao.TYPE.RESEARCH_AREA), true); + final Set<ResearchAreaDTO> remoteAreas = new HashSet<ResearchAreaDTO>(areas); + final Set<Keyword> areasToRemove = new HashSet<Keyword>(); + //Compare remote with database + for (Keyword currentArea : currentAreas) { + ResearchAreaDTO translatedArea = dtoFromAreaKeyword(currentArea); + if (!remoteAreas.contains(translatedArea)) { + logger.info("Area " + translatedArea.getName() + " does not exist on remote, preparing to remove."); + areasToRemove.add(currentArea); + } + } + //Delete areas that not exist on remote + for (Keyword areaToRemove : areasToRemove) { + keywordDao.delete(areaToRemove); + logger.debug("Deleted research area: " + areaToRemove.getKeyword() + " since it has been removed from remote system"); + } + //Add areas to database + for (final ResearchAreaDTO researchAreaDTO : remoteAreas) { + Keyword area = keywordDao.getKeywordByIdentifierAndType(researchAreaDTO.id, keywordTypeDao.findByType(KeywordTypeDao.TYPE.RESEARCH_AREA)); + if (area == null) { + logger.info("External research area: '" + researchAreaDTO + "' has no local representation, creating"); + area = new Keyword(researchAreaDTO.name, keywordTypeDao.findByType(KeywordTypeDao.TYPE.RESEARCH_AREA)); + area.setIdentifier(researchAreaDTO.id); + area = keywordDao.save(area); + } else if (!area.getKeyword().equals(researchAreaDTO.name)) { + logger.info("Research area " + area.getKeyword() + " has changed name, renaming to: " + researchAreaDTO.name); + area.setKeyword(researchAreaDTO.name); + } else { + logger.info("Research area " + area.getKeyword() + " already exists, skipping"); + } + if (researchAreaDTO.active.equals("false")) { + logger.info(area.getKeyword() + " is inactivated on remote system."); + area.setDeleted(true); + } + } + } + + @Transactional + public void addUnexistingUnitsAsUnits(final Set<UnitDTO> unitsFromDTO) { + + final Set<Unit> currentUnits = unitService.findAllAsSet(); + final Set<UnitDTO> remoteUnits = new HashSet<UnitDTO>(unitsFromDTO); + + final Set<Unit> unitsToRemove = new HashSet<Unit>(); + for (Unit unit : currentUnits) { + UnitDTO translatedUnit = dtoFromUnit(unit); + if (!remoteUnits.contains(translatedUnit)) { + logger.info("Unit " + translatedUnit.getName() + " does not exist on remote, preparing to remove."); + unitsToRemove.add(unit); + } + } + //Delete units that not exist on remote + for (Unit unitToRemove : unitsToRemove){ + unitService.delete(unitToRemove.getId()); + logger.debug("Deleted unit: " + unitToRemove.getTitle() + " since it has been removed from remote system"); + } + //Add units to database + for (final UnitDTO unitDTO : remoteUnits) { + Unit unit = unitService.findByIdentifier(unitDTO.getId()); + if (unit == null){ + logger.info("External unit: '" + unitDTO + "' has no local representation, creating"); + unit = new Unit(); + unit.setIdentifier(unitDTO.getId()); + unit.setTitle(unitDTO.getName()); + unit = unitService.save(unit); + } else if (!unit.getTitle().equals(unitDTO.name)) { + logger.info("Unit " + unit.getTitle() + " has changed name, renaming to: " + unitDTO.name); + unit.setTitle(unitDTO.name); + } else { + logger.info("Unit " + unit.getTitle() + " already exists, skipping"); + } + } + } + + public void removeUnitFromSupervisorsNotInSet(Set<PersonDTO> supervisorSet) { + final Set<Employee> supervisorsWithRemoteUnit = new HashSet<Employee>(); + final Set<Employee> currentSupervisors = new HashSet<Employee>(supervisorDao.findAll()); + + //Create SciPro Employees from DTOs. + for (PersonDTO supervisorDTO : supervisorSet) { + User supervisorUser = userDao.getUserByIdentifier(supervisorDTO.id); + Employee supervisor = supervisorDao.getFrom(supervisorUser); + supervisorsWithRemoteUnit.add(supervisor); + } + + //Remove units from supervisors that is not in the remote set. + for (Employee supervisor : currentSupervisors) { + if (!supervisorsWithRemoteUnit.contains(supervisor)) { + logger.debug(supervisor.getNameAsString() + " does not have a remote unit. Searching for local units to remove."); + List<Keyword> unitsToRemove = supervisor.getKeywords().getFiltered(keywordTypeDao.findByType(KeywordTypeDao.TYPE.UNIT)); + if (!unitsToRemove.isEmpty()) { + supervisor.getKeywords().getAll().removeAll(unitsToRemove); + logger.debug("Removed units from: " + supervisor.getNameAsString()); + } + } + } + } + + private UnitDTO dtoFromUnitKeyword(final Keyword unit) { + UnitDTO dto = new UnitDTO(); + dto.setName(unit.getKeyword()); + if (unit.getIdentifier() != null) + dto.setId(unit.getIdentifier()); + return dto; + } + + private UnitDTO dtoFromUnit(final Unit unit) { + UnitDTO dto = new UnitDTO(); + dto.setName(unit.getTitle()); + if (unit.getIdentifier() != null) + dto.setId(unit.getIdentifier()); + return dto; + } + + private ResearchAreaDTO dtoFromAreaKeyword(final Keyword area) { + ResearchAreaDTO dto = new ResearchAreaDTO(); + dto.setName(area.getKeyword()); + if (area.getIdentifier() != null) + dto.setId(area.getIdentifier()); + return dto; + } } diff --git a/src/main/java/se/su/dsv/scipro/springdata/repos/UnitRepo.java b/src/main/java/se/su/dsv/scipro/springdata/repos/UnitRepo.java index 7ba9656c99..0bf0a9722f 100644 --- a/src/main/java/se/su/dsv/scipro/springdata/repos/UnitRepo.java +++ b/src/main/java/se/su/dsv/scipro/springdata/repos/UnitRepo.java @@ -12,6 +12,6 @@ import se.su.dsv.scipro.data.dataobjects.Unit; @Transactional(readOnly = true) public interface UnitRepo extends JpaRepository<Unit, Long>, QueryDslPredicateExecutor<Unit> { - //nothing here yet + public Unit findByIdentifier(Long identifier); } diff --git a/src/main/java/se/su/dsv/scipro/springdata/serviceimpls/UnitServiceImpl.java b/src/main/java/se/su/dsv/scipro/springdata/serviceimpls/UnitServiceImpl.java index 9a6ba69ba1..25f33fb6fb 100644 --- a/src/main/java/se/su/dsv/scipro/springdata/serviceimpls/UnitServiceImpl.java +++ b/src/main/java/se/su/dsv/scipro/springdata/serviceimpls/UnitServiceImpl.java @@ -9,6 +9,8 @@ import se.su.dsv.scipro.springdata.repos.UnitRepo; import se.su.dsv.scipro.springdata.services.UnitService; import javax.annotation.Resource; +import java.util.HashSet; +import java.util.Set; /** * @author: fred-fri @@ -29,4 +31,13 @@ public class UnitServiceImpl extends AbstractQueryService<Unit, Long> implements System.out.println("UnitServiceImpl instantiating..."); } + @Override + public Unit findByIdentifier(Long identifier) { + return unitRepo.findByIdentifier(identifier); + } + + @Override + public Set<Unit> findAllAsSet() { + return new HashSet<Unit>(unitRepo.findAll()); + } } diff --git a/src/main/java/se/su/dsv/scipro/springdata/services/UnitService.java b/src/main/java/se/su/dsv/scipro/springdata/services/UnitService.java index d6aa40fcad..3e50ed90df 100644 --- a/src/main/java/se/su/dsv/scipro/springdata/services/UnitService.java +++ b/src/main/java/se/su/dsv/scipro/springdata/services/UnitService.java @@ -2,12 +2,15 @@ package se.su.dsv.scipro.springdata.services; import se.su.dsv.scipro.data.dataobjects.Unit; +import java.util.Set; + /** * @author: fred-fri * date: 2012 03 26 */ public interface UnitService extends GenericService<Unit, Long>, QueryService<Unit, Long> { - //nothing here yet + public Unit findByIdentifier(Long identifier); + public Set<Unit> findAllAsSet(); }