From 9bdd50215a993c8375411e34ebecb68236664811 Mon Sep 17 00:00:00 2001
From: Emil Siverhall <emil-siv@dsv.su.se>
Date: Tue, 10 Apr 2012 14:57:39 +0200
Subject: [PATCH 1/2] changes to import workers to make sure authors,
 supervisors, co-supervisors and reviewers that exist in scipro but not in
 daisy is being removed.

---
 .../dsv/scipro/data/dataobjects/Project.java  | 12 +++
 .../se/su/dsv/scipro/io/dto/PersonDTO.java    | 33 ++++++-
 .../scipro/io/dto/ProjectParticipantDTO.java  | 46 +++++++++-
 .../dsv/scipro/io/facade/ImporterFacade.java  | 85 ++++++++++++++++++-
 4 files changed, 171 insertions(+), 5 deletions(-)

diff --git a/src/main/java/se/su/dsv/scipro/data/dataobjects/Project.java b/src/main/java/se/su/dsv/scipro/data/dataobjects/Project.java
index 610861dd72..bff1b9652c 100644
--- a/src/main/java/se/su/dsv/scipro/data/dataobjects/Project.java
+++ b/src/main/java/se/su/dsv/scipro/data/dataobjects/Project.java
@@ -161,6 +161,18 @@ public class Project extends DomainObject implements Comparable<Project>, Iconiz
 	    this.projectFollowers.add(projectFollower);
 	}
 	
+	public void removeProjectFollower(ProjectFollower projectFollower) {
+		this.projectFollowers.remove(projectFollower);
+	}
+	
+	public void removeAuthor(Student student){
+		this.projectParticipants.remove(student);
+	}
+	
+	public void removeSupervisor(){
+		this.headSupervisor = null;
+	}
+	
 	public Set<ProjectFollower> getProjectReviewers(){
 		Iterator<ProjectFollower> iter = projectFollowers.iterator();
 		Set<ProjectFollower> set = new TreeSet<ProjectFollower>();
diff --git a/src/main/java/se/su/dsv/scipro/io/dto/PersonDTO.java b/src/main/java/se/su/dsv/scipro/io/dto/PersonDTO.java
index fe77ce3a20..6abddde58f 100644
--- a/src/main/java/se/su/dsv/scipro/io/dto/PersonDTO.java
+++ b/src/main/java/se/su/dsv/scipro/io/dto/PersonDTO.java
@@ -4,7 +4,7 @@ package se.su.dsv.scipro.io.dto;
 public class PersonDTO {
 
 	public long id;
-	public String firstName, lastName, email;
+	public String firstName, lastName;
 	
 	public String getFirstName() {
 		return firstName;
@@ -18,10 +18,39 @@ public class PersonDTO {
 	public void setLastName(String lastName) {
 		this.lastName = lastName;
 	}
+	
+	public long getId() {
+		return id;
+	}
+	
+	@Override
+	public int hashCode() {
+		final int prime = 31;
+		int result = 1;
+		result = prime * result + (int) (id ^ (id >>> 32));
+		return result;
+	}
+	@Override
+	public boolean equals(Object obj) {
+		if (this == obj)
+			return true;
+		if (obj == null)
+			return false;
+		if (getClass() != obj.getClass())
+			return false;
+		PersonDTO other = (PersonDTO) obj;
+		if (id != other.id)
+			return false;
+		return true;
+	}
 	public String toString(){
-		return getFirstName() + " " + getLastName();
+		return "id: "+ getId()+" name: "+getFirstName() + " " + getLastName();
 	}
 	public PersonDTO() {
 		
 	}
+
+	public PersonDTO(long id) {
+		this.id = id;
+	}
 }
diff --git a/src/main/java/se/su/dsv/scipro/io/dto/ProjectParticipantDTO.java b/src/main/java/se/su/dsv/scipro/io/dto/ProjectParticipantDTO.java
index 45d1724e20..fadd167373 100644
--- a/src/main/java/se/su/dsv/scipro/io/dto/ProjectParticipantDTO.java
+++ b/src/main/java/se/su/dsv/scipro/io/dto/ProjectParticipantDTO.java
@@ -39,11 +39,53 @@ public class ProjectParticipantDTO {
 		}};
 	@Override
 	public String toString(){
-		return id+","+role+","+level+","+person;
+		return role+","+level+","+person;
 	}
-	public long id;
+	//public long id;
 	public String role;
 	@SerializedName("type")
 	public String level;
 	public PersonDTO person;
+	
+	@Override
+	public int hashCode() {
+		final int prime = 31;
+		int result = 1;
+		result = prime * result + ((person == null) ? 0 : person.hashCode());
+		result = prime * result + ((role == null) ? 0 : role.hashCode());
+		return result;
+	}
+	@Override
+	public boolean equals(Object obj) {
+		if (this == obj)
+			return true;
+		if (obj == null)
+			return false;
+		if (getClass() != obj.getClass())
+			return false;
+		ProjectParticipantDTO other = (ProjectParticipantDTO) obj;
+		if (person == null) {
+			if (other.person != null)
+				return false;
+		} else if (!person.equals(other.person))
+			return false;
+		if (role == null) {
+			if (other.role != null)
+				return false;
+		} else if (!role.equals(other.role))
+			return false;
+		return true;
+	}
+	public String getRole() {
+		return role;
+	}
+	public void setRole(String role) {
+		this.role = role;
+	}
+	public PersonDTO getPerson() {
+		return person;
+	}
+	public void setPerson(PersonDTO person) {
+		this.person = person;
+	}
 }
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 2ad375804c..a1acf9512a 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
@@ -38,12 +38,12 @@ import se.su.dsv.scipro.data.dataobjects.interfaces.FinalSeminarParticipation;
 import se.su.dsv.scipro.data.enums.ProjectStatus;
 import se.su.dsv.scipro.data.enums.ProjectTeamMemberRoles;
 import se.su.dsv.scipro.io.ExternalImporter;
+import se.su.dsv.scipro.io.dto.PersonDTO;
 import se.su.dsv.scipro.io.dto.ProjectDTO;
 import se.su.dsv.scipro.io.dto.ProjectParticipantDTO;
 import se.su.dsv.scipro.io.dto.ProjectParticipantDTO.EXTERNAL_PROJECT_ROLE;
 import se.su.dsv.scipro.io.dto.ProjectParticipantDTO.LOCAL_PROJECT_ROLE;
 import se.su.dsv.scipro.io.dto.ResearchAreaDTO;
-import se.su.dsv.scipro.io.dto.PersonDTO;
 import se.su.dsv.scipro.io.dto.UnitDTO;
 import se.su.dsv.scipro.io.dto.UserDTO;
 import se.su.dsv.scipro.io.dto.UserRoleDTO;
@@ -205,11 +205,93 @@ public class ImporterFacade {
 			project = projectDao.save(project);
 		//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) {
+		final List<Member> currentMembers = 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.toLocal().name());
+			break;
+			}
+		case SUPERVISOR:
+			{
+			dto.setRole(EXTERNAL_PROJECT_ROLE.SUPERVISOR.toLocal().name());
+			break;
+			}
+		case REVIEWER:
+			{
+			dto.setRole(EXTERNAL_PROJECT_ROLE.EXAMINER.toLocal().name());
+			break;
+			}
+		case CO_SUPERVISOR:
+			{
+			dto.setRole(EXTERNAL_PROJECT_ROLE.ASSISTANT_SUPERVISOR.toLocal().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();
@@ -373,6 +455,7 @@ public class ImporterFacade {
 		dto.setRealm(name.getRealm().toUpperCase().trim());
 		return dto;
 	}
+	
 	private ProjectClass toLocalClass(final ProjectDTO projectDTO){
 		ProjectClass pClass = null;
 		final String extractedType = extractProjectType(projectDTO);

From 186706136c882021810c672ffd03bf0943ff57ed Mon Sep 17 00:00:00 2001
From: Emil Siverhall <emil-siv@dsv.su.se>
Date: Tue, 10 Apr 2012 16:10:59 +0200
Subject: [PATCH 2/2] removal of local participants that is not available at
 remote system now works for opponents and active participations as well.

---
 .../FinalSeminarActiveParticipationDao.java   |  2 +
 ...alSeminarActiveParticipationDaoJPAImp.java | 26 ++++++++++
 .../dsv/scipro/data/dataobjects/Member.java   | 13 ++++-
 .../dsv/scipro/io/facade/ImporterFacade.java  | 47 ++++++++++++++++++-
 4 files changed, 86 insertions(+), 2 deletions(-)

diff --git a/src/main/java/se/su/dsv/scipro/data/dao/interfaces/FinalSeminarActiveParticipationDao.java b/src/main/java/se/su/dsv/scipro/data/dao/interfaces/FinalSeminarActiveParticipationDao.java
index e5f07d252d..91eee17842 100644
--- a/src/main/java/se/su/dsv/scipro/data/dao/interfaces/FinalSeminarActiveParticipationDao.java
+++ b/src/main/java/se/su/dsv/scipro/data/dao/interfaces/FinalSeminarActiveParticipationDao.java
@@ -5,6 +5,7 @@ package se.su.dsv.scipro.data.dao.interfaces;
 
 import java.util.List;
 
+import se.su.dsv.scipro.data.dataobjects.FinalSeminar;
 import se.su.dsv.scipro.data.dataobjects.FinalSeminarActiveParticipation;
 import se.su.dsv.scipro.data.dataobjects.Project;
 import se.su.dsv.scipro.data.dataobjects.User;
@@ -18,6 +19,7 @@ import se.su.dsv.scipro.data.dataobjects.User;
 public interface FinalSeminarActiveParticipationDao extends Dao<FinalSeminarActiveParticipation>{
 	
 	public List<FinalSeminarActiveParticipation> findParticipationsByUserAndProject(final User user, final Project project);
+	public List<FinalSeminarActiveParticipation> findParticipationsByUserAndProject(final User user, final Project project, final FinalSeminar fs);
 	public int countParticipationsByProjectAndStudent(final Project project, final User user);
 
 }
diff --git a/src/main/java/se/su/dsv/scipro/data/dao/jpa/FinalSeminarActiveParticipationDaoJPAImp.java b/src/main/java/se/su/dsv/scipro/data/dao/jpa/FinalSeminarActiveParticipationDaoJPAImp.java
index 27ee00ea75..d654beffa2 100644
--- a/src/main/java/se/su/dsv/scipro/data/dao/jpa/FinalSeminarActiveParticipationDaoJPAImp.java
+++ b/src/main/java/se/su/dsv/scipro/data/dao/jpa/FinalSeminarActiveParticipationDaoJPAImp.java
@@ -13,6 +13,7 @@ import org.springframework.stereotype.Repository;
 import org.springframework.transaction.annotation.Transactional;
 
 import se.su.dsv.scipro.data.dao.interfaces.FinalSeminarActiveParticipationDao;
+import se.su.dsv.scipro.data.dataobjects.FinalSeminar;
 import se.su.dsv.scipro.data.dataobjects.FinalSeminarActiveParticipation;
 import se.su.dsv.scipro.data.dataobjects.Project;
 import se.su.dsv.scipro.data.dataobjects.User;
@@ -53,6 +54,31 @@ public class FinalSeminarActiveParticipationDaoJPAImp  extends AbstractDaoJPAImp
 		});
 	}
 	
+	@Transactional
+	public List<FinalSeminarActiveParticipation> findParticipationsByUserAndProject(final User user, final Project project, final FinalSeminar finalSeminar){
+		return getJpaTemplate().execute(new JpaCallback<List<FinalSeminarActiveParticipation>>() {
+			public List<FinalSeminarActiveParticipation> doInJpa(EntityManager em)
+			throws PersistenceException {
+				String q =  "select ap " +
+							"from FinalSeminarActiveParticipation ap " +
+							"where ap.user = :user " +
+							"and ap.project = :project " +
+							"and ap.finalSeminar = :finalSeminar";
+				
+				TypedQuery<FinalSeminarActiveParticipation> query = em.createQuery(q, FinalSeminarActiveParticipation.class);
+				query.setParameter("user", user);
+				query.setParameter("project", project);
+				query.setParameter("finalSeminar", finalSeminar);
+				
+				try {
+					return query.getResultList();
+				} catch (NoResultException e) {
+					return new ArrayList<FinalSeminarActiveParticipation>();
+				}
+			}
+		});
+	}
+	
 	@Transactional
 	public int countParticipationsByProjectAndStudent(final Project project, final User user){
 		return getJpaTemplate().execute(new JpaCallback<Integer>() {
diff --git a/src/main/java/se/su/dsv/scipro/data/dataobjects/Member.java b/src/main/java/se/su/dsv/scipro/data/dataobjects/Member.java
index afb35ef0e7..d1af54f95f 100644
--- a/src/main/java/se/su/dsv/scipro/data/dataobjects/Member.java
+++ b/src/main/java/se/su/dsv/scipro/data/dataobjects/Member.java
@@ -35,7 +35,18 @@ public class Member implements Serializable {
                 return "Co-Supervisor";
             }
         },
-
+        OPPONENT {
+            @Override
+            public String toString() {
+                return "Opponent";
+            }
+        },
+        ACTIVE_PARTICIPANT {
+            @Override
+            public String toString() {
+                return "Active Participant";
+            }
+        },
     }
     
     public Member(User user, Type type) {
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 a1acf9512a..3ad6752404 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
@@ -212,7 +212,20 @@ public class ImporterFacade {
 		}
 	}
 	private void checkForRemovedMembers(final Project project, final Set<ProjectParticipantDTO> participants) {
-		final List<Member> currentMembers = project.getMembers();
+		//Get project team members.
+		final Set<Member> currentMembers = new HashSet<Member>(project.getMembers()); 
+		final List<FinalSeminar> fsList = finalSeminarDao.findFinalSeminarsByProject(project); 
+		//Get opponents and active participants as well. 
+		if(!fsList.isEmpty()){
+			for(FinalSeminar fs : fsList) {
+				for(FinalSeminarOpposition opp : fs.getOppositions()){
+					currentMembers.add(new Member(opp.getUser(), Member.Type.OPPONENT));
+				}
+				for(FinalSeminarActiveParticipation ap : fs.getActiveParticipations()){
+					currentMembers.add(new Member(ap.getUser(), Member.Type.ACTIVE_PARTICIPANT));
+				}
+			}
+		} 
 		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.
@@ -261,8 +274,31 @@ public class ImporterFacade {
 					logger.debug("Can't find project follower to remove.");
 				break;
 			}
+			case OPPONENT: {
+				for (FinalSeminar fs : fsList) {
+					List<FinalSeminarOpposition> oppList = finalSeminarOppositionDao.findOppositionsByUserAndProject(m.getUser(), project, fs);
+						for (FinalSeminarOpposition opp : oppList) {
+							if(fs.getOppositions().contains(opp)){
+								finalSeminarOppositionDao.delete(opp);
+							}
+					}
+				}
+				break;
+			}
+			case ACTIVE_PARTICIPANT: {
+				for (FinalSeminar fs : fsList) {
+					List<FinalSeminarActiveParticipation> apList = finalSeminarActiveParticipationDao.findParticipationsByUserAndProject(m.getUser(), project, fs);
+						for (FinalSeminarActiveParticipation ap: apList) {
+							if(fs.getActiveParticipations().contains(ap))
+								finalSeminarActiveParticipationDao.delete(ap);
+						}
+				}
+				break;
+			}
 			}
 		}
+		
+		
 	}
 	private ProjectParticipantDTO participantDtoFromMember(Member m) {
 		ProjectParticipantDTO dto = new ProjectParticipantDTO();
@@ -289,6 +325,15 @@ public class ImporterFacade {
 			dto.setRole(EXTERNAL_PROJECT_ROLE.ASSISTANT_SUPERVISOR.toLocal().name());
 			break;
 			}
+		case OPPONENT:
+		{
+			dto.setRole(EXTERNAL_PROJECT_ROLE.OPPONENT.toLocal().name());
+			break;
+		}
+		case ACTIVE_PARTICIPANT:
+		{
+			dto.setRole(EXTERNAL_PROJECT_ROLE.ACTIVE_PARTICIPATION.name());
+		}
 		}
 		return dto;
 	}