Merge remote-tracking branch 'origin/develop' into develop

This commit is contained in:
Niklas Herder 2012-02-09 16:25:13 +01:00
commit 167761d8e2
33 changed files with 995 additions and 583 deletions

@ -0,0 +1,12 @@
CREATE TABLE IF NOT EXISTS `Employee_countActiveFromDates` (
`Employee_id` bigint(20) NOT NULL,
`countActiveFromDates` datetime DEFAULT NULL,
`countActiveFromDates_KEY` bigint(20) NOT NULL,
PRIMARY KEY (`Employee_id`,`countActiveFromDates_KEY`),
KEY `FK5183E457A4585B4A` (`countActiveFromDates_KEY`),
KEY `FK5183E4575FCBC05F` (`Employee_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
ALTER TABLE `Employee_countActiveFromDates`
ADD CONSTRAINT `FK5183E4575FCBC05F` FOREIGN KEY (`Employee_id`) REFERENCES `role` (`id`),
ADD CONSTRAINT `FK5183E457A4585B4A` FOREIGN KEY (`countActiveFromDates_KEY`) REFERENCES `project_class` (`id`);

@ -339,12 +339,15 @@ public class SciProApplication extends RepositoryApplication implements IThemabl
@Override
public Class<? extends Page> getHomePage() {
if (SciProSession.get().authorizedForRole(Roles.STUDENT) && SciProSession.get().hasActualRole(Roles.STUDENT)){
if (SciProSession.get().authorizedForRole(Roles.ADMIN) && SciProSession.get().hasActualRole(Roles.ADMIN)){
return ProjectStartPage.class;
}
if (SciProSession.get().authorizedForRole(Roles.EMPLOYEE) && SciProSession.get().hasActualRole(Roles.EMPLOYEE)){
return SupervisorStartPage.class;
}
if (SciProSession.get().authorizedForRole(Roles.STUDENT) && SciProSession.get().hasActualRole(Roles.STUDENT)){
return ProjectStartPage.class;
}
else {
return HomePage.class;
}

@ -113,9 +113,12 @@ public class AdminMatchPeriodsPanel extends Panel {
private static final long serialVersionUID = 1L;
@Override
public void onClick(AjaxRequestTarget target) {
facade.removeApplicationPeriod(appPeriod);
target.addComponent(container);
Session.get().info("Removed : " + StringUtil.getApplicationPeriodData(appPeriod));
if(facade.removeApplicationPeriod(appPeriod)) {
target.addComponent(container);
Session.get().info("Removed : " + facade.getApplicationPeriodData(appPeriod));
} else {
Session.get().error("It was not possible to remove : " + facade.getApplicationPeriodData(appPeriod));
}
target.addComponent(localFeedbackPanel);
}
};

@ -1,12 +1,14 @@
package se.su.dsv.scipro.data.dataobjects;
import java.io.Serializable;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import javax.persistence.AssociationOverride;
import javax.persistence.Basic;
import javax.persistence.Cacheable;
import javax.persistence.ElementCollection;
import javax.persistence.Embeddable;
@ -19,6 +21,7 @@ import javax.persistence.ManyToMany;
import org.hibernate.annotations.Cache;
import org.hibernate.annotations.CacheConcurrencyStrategy;
import se.su.dsv.scipro.dataproviders.SortableField;
import se.su.dsv.scipro.match.dataobject.Keywords;
/**
@ -30,8 +33,27 @@ import se.su.dsv.scipro.match.dataobject.Keywords;
@Cache(usage= CacheConcurrencyStrategy.NONSTRICT_READ_WRITE) //Hibernate specific
public class Employee extends ProjectTeamMember {
@ElementCollection(fetch=FetchType.EAGER)
private Map<ProjectClass, Date> countActiveFromDates =
new HashMap<ProjectClass, Date>();
public Map<ProjectClass, Date> getCountActiveFromDates() {
return countActiveFromDates;
}
@Embedded
public void setCountActiveFromDates(Map<ProjectClass, Date> countActiveFromDates) {
this.countActiveFromDates = countActiveFromDates;
}
public Date getCountFromDate(ProjectClass projectClass){
return countActiveFromDates.get(projectClass);
}
public void setCountFromDate(ProjectClass projectClass, Date date){
countActiveFromDates.put(projectClass, date);
}
@Embedded
@AssociationOverride(name="languages", joinTable=@JoinTable(name="Employee_Language"))
private Capabilities capabilities = new Capabilities();

@ -86,11 +86,12 @@ public class ImporterFacade {
@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
* @param dtoUser
* @param user hte user
* @param dtoUser the dtoUser
*/
@Transactional
public void mergeUser(final User user, final UserDTO dtoUser){

@ -19,7 +19,7 @@ import se.su.dsv.scipro.match.dataobject.ProjectIdea;
@Component(value="GreedyMatchingAlgorithm")
public class GreedyMatchingAlgorithm implements MatchingAlgorithm {
private Logger logger = Logger.getLogger(GreedyMatchingAlgorithm.class);
private Weights weights;
@ -93,12 +93,8 @@ public class GreedyMatchingAlgorithm implements MatchingAlgorithm {
while (projectIdeaIterator.hasNext()) {
ProjectIdea projectIdea = projectIdeaIterator.next();
logger.info("Matching project idea:" + projectIdea);
Match match = new Match();
match.setSupervisor(new Employee());
match.setProjectIdea(projectIdea);
Pair matchPair = new Pair(match, new Availability(null, 1L, 1, new ProjectClass()));
Iterator<Availability> availabilityIterator = availabilityList.iterator();
Pair matchPair = null;
Iterator<Availability> availabilityIterator = availabilityList.iterator();
while (availabilityIterator.hasNext()) {
Availability availability = availabilityIterator.next();
logger.info("Matching project idea with supervisor:" + availability.getSupervisor());
@ -113,10 +109,14 @@ public class GreedyMatchingAlgorithm implements MatchingAlgorithm {
logger.info("Not possible supervisor");
continue;
}
Match match = new Match();
match.setSupervisor(availability.getSupervisor());
match.setProjectIdea(projectIdea);
matchPair = new Pair(match, new Availability(null, 1L, 1, new ProjectClass()));
matchPair = getBestMatch(matchPair, availability);
}
if (matchPair.getMatch().getPoints() != -1) {
if (matchPair != null && matchPair.getMatch().getPoints() != -1) {
matchList.add(matchPair.getMatch());
projectIdeaIterator.remove();
}

@ -25,8 +25,12 @@ public interface SupervisorDao extends QueryableDao<Employee, SupervisorDaoParam
Employee getOrCreate(User user);
List<Availability> getAvailability();
// List<Availability> getAvailability2();
Availability getAvailability(Employee supervisor, ProjectClass projectClass);
void setAvailability(Availability availability);
void resetCountFromDate(ProjectClass projectClass);
}

@ -3,7 +3,9 @@ package se.su.dsv.scipro.match.dao.jpa;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.springframework.stereotype.Repository;
import se.su.dsv.scipro.data.dao.jpa.AbstractDaoJPAImp;
@ -50,8 +52,18 @@ public class ProjectIdeaDaoJPAImp extends AbstractDaoJPAImp<ProjectIdea>
projectClasses.add(projectClass);
querySet.projectClasses(projectClasses);
}
//we dont want to include inactive, refused, rejected ideas etc
Set<Match.Status> statusesToInclude = new HashSet<Match.Status>();
statusesToInclude.add(Match.Status.PUBLISHED);
statusesToInclude.add(Match.Status.CONFIRMED);
statusesToInclude.add(Match.Status.PENDING);
return getJpaTemplate().execute(
querySet.supervisor(supervisor).projectCreated(false).countCallback());
// querySet.supervisor(supervisor).projectCreated(false).countCallback());
// querySet.supervisor(supervisor).matchDateAfter(supervisor.getBachelorTargetCountFromDate()).countCallback());
// querySet.supervisor(supervisor).matchDateAfter(supervisor.getCountFromDate(projectClass)).countCallback());
querySet.supervisor(supervisor).statuses(statusesToInclude).matchDateAfter(supervisor.getCountFromDate(projectClass)).countCallback());
}
@Override
@ -142,6 +154,16 @@ public class ProjectIdeaDaoJPAImp extends AbstractDaoJPAImp<ProjectIdea>
}
return this;
}
public QuerySet matchDateAfter(Date matchDateAfter) {
if (matchDateAfter != null) {
getQuery().combine(
new Query().join("_.match m").where(
"m.dateCreated >= :matchDateAfter").parameter("matchDateAfter",
matchDateAfter));
}
return this;
}
public QuerySet orderByMatchAge() {
getQuery().combine(

@ -2,7 +2,9 @@ package se.su.dsv.scipro.match.dao.jpa;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.persistence.EntityManager;
@ -16,6 +18,7 @@ import org.springframework.orm.jpa.JpaCallback;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;
import se.su.dsv.scipro.data.dao.interfaces.ProjectClassDao;
import se.su.dsv.scipro.data.dao.jpa.AbstractQuerySet;
import se.su.dsv.scipro.data.dao.jpa.AbstractSortableQuerySet;
import se.su.dsv.scipro.data.dao.jpa.Query;
@ -25,212 +28,241 @@ import se.su.dsv.scipro.data.dataobjects.Language;
import se.su.dsv.scipro.data.dataobjects.ProjectClass;
import se.su.dsv.scipro.data.dataobjects.User;
import se.su.dsv.scipro.match.dao.interfaces.ProjectIdeaDao;
import se.su.dsv.scipro.match.dao.interfaces.SupervisorDaoParams;
import se.su.dsv.scipro.match.dao.interfaces.SupervisorDao;
import se.su.dsv.scipro.match.dao.interfaces.SupervisorDaoParams;
import se.su.dsv.scipro.match.dataobject.Availability;
import se.su.dsv.scipro.match.dataobject.Keyword;
import se.su.dsv.scipro.match.dataobject.Match;
@Repository("supervisorDao")
public class SupervisorDaoJPAImp extends
QueryableDaoJPAImp<Employee, SupervisorDaoParams> implements
SupervisorDao {
QueryableDaoJPAImp<Employee, SupervisorDaoParams> implements
SupervisorDao {
@Autowired
private ProjectIdeaDao projectIdeaDao;
public SupervisorDaoJPAImp() {
super(Employee.class);
}
@Autowired
private ProjectIdeaDao projectIdeaDao;
@Autowired
private ProjectClassDao projectClassDao;
@Override
public Employee getOrCreate(final User user) {
Employee supervisor = getFrom(user);
if (supervisor == null) {
supervisor = new Employee();
supervisor.setUser(user);
supervisor = save(supervisor);
}
return supervisor;
}
public SupervisorDaoJPAImp() {
super(Employee.class);
}
@Override
public Employee getFrom(final User user) {
return getJpaTemplate().execute(new JpaCallback<Employee>() {
@Override
public Employee getOrCreate(final User user) {
Employee supervisor = getFrom(user);
if (supervisor == null) {
supervisor = new Employee();
supervisor.setUser(user);
supervisor = save(supervisor);
}
return supervisor;
}
@Override
public Employee doInJpa(EntityManager em)
throws PersistenceException {
TypedQuery<Employee> query =
em.createQuery(
"select e FROM Employee e WHERE e.user = :user",
Employee.class);
query.setParameter("user", user);
query.setHint(QueryHints.HINT_CACHEABLE, "true");
try {
return query.getSingleResult();
} catch (NoResultException e) {
return null;
}
}
});
@Override
public Employee getFrom(final User user) {
return getJpaTemplate().execute(new JpaCallback<Employee>() {
}
@Override
public Employee doInJpa(EntityManager em)
throws PersistenceException {
TypedQuery<Employee> query =
em.createQuery(
"select e FROM Employee e WHERE e.user = :user",
Employee.class);
query.setParameter("user", user);
query.setHint(QueryHints.HINT_CACHEABLE, "true");
try {
return query.getSingleResult();
} catch (NoResultException e) {
return null;
}
}
});
@Override
public List<Employee> getCapableSupervisors(
final ProjectClass projectClass) {
return getJpaTemplate().execute(
new QuerySet().projectClass(projectClass).fetchCallback());
}
}
public List<Employee> getCapableSupervisors(
final ProjectClass projectClass, final Set<Language> languages) {
return getJpaTemplate().execute(
new QuerySet().projectClass(projectClass).languages(languages)
.fetchCallback());
}
@Override
public List<Employee> getCapableSupervisors(
final ProjectClass projectClass) {
return getJpaTemplate().execute(
new QuerySet().projectClass(projectClass).fetchCallback());
}
public List<Employee> getAutoCompleteCapableSupervisors(
final ProjectClass projectClass, final Set<Language> languages,
final String searchString, final int limit) {
return getJpaTemplate().execute(
new QuerySet().projectClass(projectClass).languages(languages)
.nameLike(searchString).orderByUser().limit(limit)
.fetchCallback());
}
public List<Employee> getCapableSupervisors(
final ProjectClass projectClass, final Set<Language> languages) {
return getJpaTemplate().execute(
new QuerySet().projectClass(projectClass).languages(languages)
.fetchCallback());
}
protected AbstractQuerySet<Employee> createQuerySet(
SupervisorDaoParams params) {
return new QuerySet().languages(params.getLanguages())
.projectClass(params.getProjectClass())
.keywords(params.getKeywords())
.nameLike(params.getNameLike());
}
public List<Employee> getAutoCompleteCapableSupervisors(
final ProjectClass projectClass, final Set<Language> languages,
final String searchString, final int limit) {
return getJpaTemplate().execute(
new QuerySet().projectClass(projectClass).languages(languages)
.nameLike(searchString).orderByUser().limit(limit)
.fetchCallback());
}
private static class QuerySet extends AbstractSortableQuerySet<Employee> {
public QuerySet() {
super(Employee.class);
}
protected AbstractQuerySet<Employee> createQuerySet(
SupervisorDaoParams params) {
return new QuerySet().languages(params.getLanguages())
.projectClass(params.getProjectClass())
.keywords(params.getKeywords())
.nameLike(params.getNameLike());
}
public QuerySet keywords(Collection<Keyword> keywords) {
if (keywords != null) {
getQuery().combine(
new Query().join("_.keywords.keywords k").where("k in (:keywords)").parameter(
"keywords", keywords)).distinct();
}
return this;
}
private static class QuerySet extends AbstractSortableQuerySet<Employee> {
public QuerySet() {
super(Employee.class);
}
public QuerySet orderByUser() {
getQuery().combine(RoleDaoJPAImp.orderByUserQuery());
return this;
}
public QuerySet keywords(Collection<Keyword> keywords) {
if (keywords != null) {
getQuery().combine(
new Query().join("_.keywords.keywords k").where("k in (:keywords)").parameter(
"keywords", keywords)).distinct();
}
return this;
}
public QuerySet nameLike(String name) {
if (name != null) {
getQuery().combine(
new Query().combine(RoleDaoJPAImp
.autoCompleteUserNameQuery(name)));
}
return this;
}
public QuerySet orderByUser() {
getQuery().combine(RoleDaoJPAImp.orderByUserQuery());
return this;
}
public QuerySet projectClass(ProjectClass projectClass) {
if (projectClass != null) {
getQuery().combine(
new Query().join("_.capabilities.projectLimits pl").where(
"index(pl) = :projectClass AND pl > 0").parameter(
"projectClass", projectClass));
}
return this;
}
public QuerySet nameLike(String name) {
if (name != null) {
getQuery().combine(
new Query().combine(RoleDaoJPAImp
.autoCompleteUserNameQuery(name)));
}
return this;
}
public QuerySet languages(Collection<Language> languages) {
if (languages != null) {
getQuery().combine(
new Query().join("_.capabilities.languages l").where(
"l IN (:languages)").parameter("languages", languages)).distinct();
}
return this;
}
public QuerySet projectClass(ProjectClass projectClass) {
if (projectClass != null) {
getQuery().combine(
new Query().join("_.capabilities.projectLimits pl").where(
"index(pl) = :projectClass AND pl > 0").parameter(
"projectClass", projectClass));
}
return this;
}
@Override
public Query initQuery() {
return new Query().select("e").from("Employee e");
}
public QuerySet languages(Collection<Language> languages) {
if (languages != null) {
getQuery().combine(
new Query().join("_.capabilities.languages l").where(
"l IN (:languages)").parameter("languages", languages)).distinct();
}
return this;
}
}
@Override
public Query initQuery() {
return new Query().select("e").from("Employee e");
}
@Override
public List<Availability> getAvailability() {
return getJpaTemplate().execute(new JpaCallback<List<Availability>>() {
}
@Override
public List<Availability> doInJpa(EntityManager em)
throws PersistenceException {
List<Availability> availabilities = matchedProjectIdeas(em);
availabilities.addAll(unmatchedProjectIdeas(em));
return availabilities;
}
/*
* THIS IS THE OLD WAY OF GETTING AVAILABILITIES FOR MATCHING.
* Ive changed it so that we now get availabilities for the algorithm
* the same way as the GUI gets availabilities for individual supervisors.
* by Friis
*/
// @Override
// public List<Availability> getAvailability() {
// return getJpaTemplate().execute(new JpaCallback<List<Availability>>() {
//
// @Override
// public List<Availability> doInJpa(EntityManager em)
// throws PersistenceException {
// List<Availability> availabilities = matchedProjectIdeas(em);
// availabilities.addAll(unmatchedProjectIdeas(em));
// return availabilities;
// }
//
// private List<Availability> matchedProjectIdeas(EntityManager em) {
// javax.persistence.Query query =
// em.createQuery("SELECT NEW se.su.dsv.scipro.match.dataobject.Availability"
// + "(s, COUNT(m), pl, pi.projectClass) "
// + "FROM Match m JOIN m.supervisor s JOIN m.projectIdea pi JOIN s.capabilities.projectLimits pl "
// + "WHERE pi.match = m AND pi.projectClass = index(pl) AND m.status IN (:statuses) "
// + "GROUP BY s, pi.projectClass, pl, index(pl)");
//
// query.setParameter("statuses", occupiedStatuses());
// query.setHint(QueryHints.HINT_CACHEABLE, "false");
// try {
// return query.getResultList();
// } catch (NoResultException e) {
// return new ArrayList<Availability>();
// }
// }
//
// private List<Match.Status> occupiedStatuses() {
// List<Match.Status> statuses = new ArrayList<Match.Status>();
// statuses.add(Match.Status.CONFIRMED);
// statuses.add(Match.Status.PENDING);
// statuses.add(Match.Status.PUBLISHED);
// return statuses;
// }
//
// private List<Availability> unmatchedProjectIdeas(EntityManager em) {
// javax.persistence.Query query =
// em.createQuery("SELECT NEW se.su.dsv.scipro.match.dataobject.Availability"
// + "(s, 0L, pl, index(pl)) "
// + "FROM Match m RIGHT JOIN m.supervisor s JOIN s.capabilities.projectLimits pl LEFT JOIN m.projectIdea pi "
// + "WHERE m = NULL OR pi.projectClass != index(pl) OR (pi.projectClass = index(pl) AND m.status NOT IN (:statuses))");
//
// query.setParameter("statuses", occupiedStatuses());
// query.setHint(QueryHints.HINT_CACHEABLE, "false");
// try {
// return query.getResultList();
// } catch (NoResultException e) {
// return new ArrayList<Availability>();
// }
// }
// });
//
// }
private List<Availability> matchedProjectIdeas(EntityManager em) {
javax.persistence.Query query =
em.createQuery("SELECT NEW se.su.dsv.scipro.match.dataobject.Availability"
+ "(s, COUNT(m), pl, pi.projectClass) "
+ "FROM Match m JOIN m.supervisor s JOIN m.projectIdea pi JOIN s.capabilities.projectLimits pl "
+ "WHERE pi.match = m AND pi.projectClass = index(pl) AND m.status IN (:statuses) "
+ "GROUP BY s, pi.projectClass, pl, index(pl)");
@Override
public Availability getAvailability(Employee supervisor, ProjectClass projectClass) {
Integer projectLimit = supervisor.getCapabilities().getProjectLimit(projectClass);
long activeProjectIdeas = projectIdeaDao.countActiveProjectIdeas(supervisor, projectClass);
return new Availability(supervisor, activeProjectIdeas, projectLimit, projectClass);
}
query.setParameter("statuses", occupiedStatuses());
query.setHint(QueryHints.HINT_CACHEABLE, "false");
try {
return query.getResultList();
} catch (NoResultException e) {
return new ArrayList<Availability>();
}
}
private List<Match.Status> occupiedStatuses() {
List<Match.Status> statuses = new ArrayList<Match.Status>();
statuses.add(Match.Status.CONFIRMED);
statuses.add(Match.Status.PENDING);
statuses.add(Match.Status.PUBLISHED);
return statuses;
}
@Override
@Transactional(readOnly=false)
public void setAvailability(Availability availability) {
availability.getSupervisor().getCapabilities().getProjectLimits().put(
availability.getProjectClass(), availability.getNumCapable());
save(availability.getSupervisor());
}
private List<Availability> unmatchedProjectIdeas(EntityManager em) {
javax.persistence.Query query =
em.createQuery("SELECT NEW se.su.dsv.scipro.match.dataobject.Availability"
+ "(s, 0L, pl, index(pl)) "
+ "FROM Match m RIGHT JOIN m.supervisor s JOIN s.capabilities.projectLimits pl LEFT JOIN m.projectIdea pi "
+ "WHERE m = NULL OR pi.projectClass != index(pl) OR (pi.projectClass = index(pl) AND m.status NOT IN (:statuses))");
@Override
@Transactional(readOnly=false)
public void resetCountFromDate(ProjectClass projectClass) {
List<Employee> supervisors = getCapableSupervisors(projectClass);
for (Employee e : supervisors){
e.setCountFromDate(projectClass, new Date());
}
}
query.setParameter("statuses", occupiedStatuses());
query.setHint(QueryHints.HINT_CACHEABLE, "false");
try {
return query.getResultList();
} catch (NoResultException e) {
return new ArrayList<Availability>();
}
}
});
}
@Override
public Availability getAvailability(Employee supervisor, ProjectClass projectClass) {
Integer projectLimit = supervisor.getCapabilities().getProjectLimit(projectClass);
long activeProjectIdeas = projectIdeaDao.countActiveProjectIdeas(supervisor, projectClass);
return new Availability(supervisor, activeProjectIdeas, projectLimit, projectClass);
}
@Override
@Transactional(readOnly=false)
public void setAvailability(Availability availability) {
availability.getSupervisor().getCapabilities().getProjectLimits().put(
availability.getProjectClass(), availability.getNumCapable());
save(availability.getSupervisor());
}
@Override
public List<Availability> getAvailability() {
List<Availability> list = new ArrayList<Availability>();
for (ProjectClass pc : projectClassDao.findAll()){
for (Employee e : getCapableSupervisors(pc)){
list.add(getAvailability(e, pc));
System.out.println(e.getNameAsString() + " numcap " + getAvailability(e, pc).getNumCapable() + " nummatched" + getAvailability(e, pc).getNumMatched());
}
}
return list;
}
}

@ -159,12 +159,12 @@ public class Match extends DomainObject {
@Override
public String toString() {
String projectIdeaId = projectIdea != null ? projectIdea.getId().toString() : null;
String supervisorId = supervisor != null ? supervisor.getId().toString() : null;
String projectIdeaId = projectIdea != null ? String.valueOf(projectIdea.getId()) : "";
String supervisorId = supervisor != null ? supervisor.getId().toString() : "";
return "Match [id=" + id + ", projectIdea=" + projectIdeaId
+ ", supervisor=" + supervisorId + ", type=" + getType()
+ ", status=" + getStatus() + ", dateCreated=" + getDateCreated() + "]";
return "Match [id=" + (id != null ? id :"") + ", projectIdea=" + projectIdeaId
+ ", supervisor=" + (supervisorId != null ? supervisorId :"") + ", type=" + (getType() != null ? getType() :"")
+ ", status=" + (getStatus() != null ? getStatus() :"") + ", dateCreated=" + (getDateCreated() != null ? getDateCreated() :"") + "]";
}
@Override

@ -161,12 +161,11 @@ public class ProjectIdea extends DomainObject {
@Override
public String toString() {
return "ProjectIdea [id=" + id + ", projectClass=" + projectClass
+ ", authors=" + authors + ", preferredSupervisor="
+ preferredSupervisor + ", externalSupervisorInfo="
+ externalSupervisorInfo + ", keywords=" + keywords + ", title="
+ title + ", watson=" + watson + ", project=" + project
+ ", match=" + match + "]";
return "ProjectIdea [id=" + (id != null ? id : "") + ", projectClass=" + (projectClass != null ? projectClass : "")
+ ", authors=" + (authors != null ? authors : "") + ", preferredSupervisor=" + (preferredSupervisor != null ? preferredSupervisor : "")
+ ", externalSupervisorInfo=" + (externalSupervisorInfo != null ? externalSupervisorInfo : "") + ", keywords=" + (keywords != null ? keywords : "")
+ ", title="+ (title != null ? title : "") + ", watson=" + (watson != null ? watson : "")
+ ", project=" + (project != null ? project : "") + ", match=" + (match != null ? match : "") + "]";
}

@ -7,76 +7,130 @@ import org.springframework.transaction.annotation.Transactional;
import se.su.dsv.scipro.data.dataobjects.ProjectClass;
import se.su.dsv.scipro.match.dao.interfaces.ApplicationPeriodDao;
import se.su.dsv.scipro.match.dataobject.ApplicationPeriod;
import se.su.dsv.scipro.match.dataobject.ProjectIdea;
//import se.su.dsv.scipro.util.DateUtils;
import se.su.dsv.scipro.util.DateFormatter;
import java.util.*;
@Service
public class ApplicationPeriodFacade {
@Autowired
@Autowired
private ApplicationPeriodDao applicationPeriodDao;
@Transactional
@Transactional
public void saveApplicationPeriod(final ApplicationPeriod period){
applicationPeriodDao.save(period);
}
@Transactional
public void removeApplicationPeriod(ApplicationPeriod period){
period = applicationPeriodDao.reLoad(period);
applicationPeriodDao.delete(period);
/**
* Returns true when the application period has been removed successfully,
* it should only be possible to remove/edit a period if the end date is after the present date,
* That is because the history should be kept.
* @param appPeriod the period that should be removed
* @return boolean the value is true when success false when failure
*/
@Transactional
public boolean removeApplicationPeriod(ApplicationPeriod appPeriod){
appPeriod = applicationPeriodDao.reLoad(appPeriod);
if(appPeriod.getEndDate().after(Calendar.getInstance().getTime())) {
applicationPeriodDao.delete(appPeriod);
return true;
} else {
return false;
}
}
public boolean applicationPeriodExists(final ProjectIdea projectIdea) {
Calendar calendar = Calendar.getInstance();
Date today = calendar.getTime();
/**
* Returns true when an open application period exists for the submitted project class
* @param projectClass the project class that should be tested
* @return boolean the value is true when a period exists
*/
public boolean openApplicationPeriodsExists(final ProjectClass projectClass) {
Set<ProjectClass> projectClassSet = new HashSet<ProjectClass>();
projectClassSet.add(projectClass);
for(ApplicationPeriod foundPeriod : applicationPeriodDao.findAll()) {
if(foundPeriod.getProjectClass() == null || foundPeriod.getProjectClass().isEmpty() || // to avoid NPEs when using faulty test data
foundPeriod.getStartDate() == null || foundPeriod.getEndDate() == null) {
if(testForInvalidData(foundPeriod)) {
continue;
}
Set<ProjectClass> projectClassSet = new HashSet<ProjectClass>();
projectClassSet.add(projectIdea.getProjectClass());
if(projectClassMatch(foundPeriod.getProjectClass(), projectClassSet) &&
(today.equals(foundPeriod.getStartDate()) || betweenDates(today, foundPeriod.getStartDate(), foundPeriod.getEndDate()))) {
betweenDates(Calendar.getInstance().getTime(), foundPeriod.getStartDate(), foundPeriod.getEndDate())) {
return true;
}
}
return false;
}
/* returns true if the new period overlaps with some of the saved periods */
/**
* Returns true if the new period overlaps with some of the saved periods
* Different conditions that is handled is for example that a newPeriod that is edited cannot "overlap with itself" and
* that it should NOT be possible to create a period "within another period".
* @param newPeriod is the period that should be tested
* @return boolean the value is true when a period exists
*/
public boolean doesPeriodOverlap(final ApplicationPeriod newPeriod) {
for(ApplicationPeriod foundPeriod : applicationPeriodDao.findAll()) {
if(foundPeriod.getProjectClass() == null || foundPeriod.getProjectClass().isEmpty() || // to avoid NPEs when using faulty test data
foundPeriod.getStartDate() == null || foundPeriod.getEndDate() == null) {
if(testForInvalidData(foundPeriod)) {
continue;
}
if(newPeriod.getId() != null && newPeriod.equals(foundPeriod)) { // a newPeriod that is edited cannot overlap with itself
if(newPeriod.getId() != null && newPeriod.equals(foundPeriod)) {
continue;
}
if(projectClassMatch(foundPeriod.getProjectClass(), newPeriod.getProjectClass()) &&
(
(newPeriod.getStartDate().equals(foundPeriod.getStartDate()) ||
betweenDates(newPeriod.getStartDate(), foundPeriod.getStartDate(), foundPeriod.getEndDate())) ||
(newPeriod.getEndDate().equals(foundPeriod.getEndDate()) ||
betweenDates(newPeriod.getEndDate(), foundPeriod.getStartDate(), foundPeriod.getEndDate())) ||
// here we must also check if the new periods start date is (equal, which is already tested) before the old periods start date
// and the new periods end date is (equal, which is already tested, or) after the old periods end date
(newPeriod.getStartDate().before(foundPeriod.getStartDate()) && newPeriod.getEndDate().after(foundPeriod.getEndDate()))
)) {
(newPeriod.getStartDate().equals(foundPeriod.getStartDate()) || newPeriod.getEndDate().equals(foundPeriod.getEndDate()) ||
betweenDates(newPeriod.getStartDate(), foundPeriod.getStartDate(), foundPeriod.getEndDate()) ||
betweenDates(newPeriod.getEndDate(), foundPeriod.getStartDate(), foundPeriod.getEndDate()) ||
newPeriod.getStartDate().before(foundPeriod.getStartDate()) && newPeriod.getEndDate().after(foundPeriod.getEndDate()))) {
return true;
}
}
return false;
}
/**
* Used to get uniformity in the written output on the FeedbackPanels of the Classes that has done CRUD-operations on the period
* @param appPeriod the period on which a CRUD operation was done
* @return String the formatted output sent to a FeedbackPanel
*/
public String getApplicationPeriodData(final ApplicationPeriod appPeriod) {
StringBuilder projectClasses = new StringBuilder();
Iterator<ProjectClass> projectClassIterator = appPeriod.getProjectClass().iterator();
while(projectClassIterator.hasNext()) {
projectClasses.append(projectClassIterator.next().getName());
if(projectClassIterator.hasNext()) {
projectClasses.append(", ");
}
}
return new StringBuilder()
.append("'").append(appPeriod.getName()).append("'")
.append("\tStart date : '").append(new DateFormatter(DateFormatter.FORMAT.DEFAULT).createFormattedString(appPeriod.getStartDate())).append("'")
.append("\tEnd date : '").append(new DateFormatter(DateFormatter.FORMAT.DEFAULT).createFormattedString(appPeriod.getEndDate())).append("'")
.append("\tLevels: '").append(projectClasses.toString()).append("'").toString();
}
/**
* Helper that is used to initialize constructors
* @return ApplicationPeriod the object that is returned
*/
public static ApplicationPeriod createDummyApplicationPeriod(){
ApplicationPeriod appPeriod = new ApplicationPeriod();
Calendar cal = Calendar.getInstance();
appPeriod.setStartDate(cal.getTime());
cal.add(Calendar.MONTH, 1);
appPeriod.setEndDate(cal.getTime());
appPeriod.setName("...");
return appPeriod;
}
// a helper method, to avoid NPEs when using faulty test data
private boolean testForInvalidData(final ApplicationPeriod applicationPeriod) {
return (applicationPeriod.getProjectClass() == null || applicationPeriod.getProjectClass().isEmpty() ||
applicationPeriod.getStartDate() == null || applicationPeriod.getEndDate() == null);
}
/* returns true if the new date is between the old periods start date and end date */
/* the method returns true if the new date is between the old periods start date and end date */
private boolean betweenDates(final Date date, final Date startDate, final Date endDate) {
return date.after(startDate) && date.before(endDate);
}

@ -28,4 +28,19 @@ public class MatchFacade {
m.setSupervisor(null);
m = matchDao.save(m);
}
@Transactional
public void reject(Match m, User u, String reason){
if(m == null || u == null || reason == null)
throw new RenderingSafeException(new UnsupportedOperationException("Unable to recieve null"));
// matchDao.changeStatus(u, m , Status.REJECTED);
m = matchDao.reLoad(m);
m.setStatus(Match.Status.REJECTED);
m.setRejectedBy(u);
m.setType(Match.Type.AUTO);
m.setSupervisor(null);
m.setCommentForAdmin(reason);
m = matchDao.save(m);
}
}

@ -11,17 +11,23 @@
<input style="width:300px;" wicket:id="keywordField" type="text" />
<div class="span-16 prepend-top append-bottom last">
<div class="span-6">
<div class="span-5">
<label for="unitPanel">Filter by unit:</label><br />
<span wicket:id="unitPanel"></span>
</div>
<div class="span-10 last append-bottom">
<div class="span-5">
<label for="researchAreaPanel">Filter by research area:</label>
<span wicket:id="researchAreaPanel"></span>
</div>
<div class="span-5 last append-bottom">
<label>Filter</label>
<div class="append-bottom"><input wicket:id="filterButton" type="submit" /></div>
<label>DO NOT TOUCH unless you know what you're doing!</label>
<div><button wicket:id="resetAllBachelorButton">Reset all supervisor Bachelor count numbers</button></div>
<div><button wicket:id="resetAllMasterButton">Reset all supervisor Master count numbers</button></div>
</div>
<div><input wicket:id="filterButton" type="submit" />
</div>
</form>
<div wicket:id="container">
<div class="span-15 last">
@ -32,8 +38,8 @@
<th>Unit</th>
<th>Target bachelor</th>
<th>Target master</th>
<th>Current bachelor</th>
<th class="rounded-right-top">Current master</th>
<th>Bachelors (counting since)</th>
<th class="rounded-right-top">Masters (counting since)</th>
</tr>
</thead>
<tfoot>
@ -49,8 +55,8 @@
<td wicket:id="targetMaster"></td>-->
<td><select wicket:id="targetBachelor"></select></td>
<td><select wicket:id="targetMaster"></select></td>
<td wicket:id="currentBachelor"></td>
<td wicket:id="currentMaster"></td>
<td><span wicket:id="currentBachelor"></span> (<span wicket:id="bachelorDate"></span>)</td>
<td><span wicket:id="currentMaster"></span> (<span wicket:id="masterDate"></span>)</td>
</tr>
<tr>

@ -6,6 +6,7 @@ import java.util.Set;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.ajax.form.AjaxFormComponentUpdatingBehavior;
import org.apache.wicket.ajax.markup.html.AjaxLink;
import org.apache.wicket.ajax.markup.html.form.AjaxButton;
import org.apache.wicket.markup.html.WebMarkupContainer;
import org.apache.wicket.markup.html.basic.Label;
@ -23,7 +24,6 @@ import org.apache.wicket.model.Model;
import org.apache.wicket.model.PropertyModel;
import org.apache.wicket.spring.injection.annot.SpringBean;
import se.su.dsv.scipro.admin.panels.match.AdminEditProjectIdeaPanel;
import se.su.dsv.scipro.data.dao.interfaces.ProjectClassDao;
import se.su.dsv.scipro.data.dataobjects.Employee;
import se.su.dsv.scipro.dataproviders.QueryableDataProvider;
@ -34,6 +34,8 @@ import se.su.dsv.scipro.match.dao.interfaces.SupervisorDaoParams;
import se.su.dsv.scipro.match.dataobject.Availability;
import se.su.dsv.scipro.match.dataobject.Keyword;
import se.su.dsv.scipro.match.dataobject.KeywordType;
import se.su.dsv.scipro.util.DateFormatter;
import se.su.dsv.scipro.util.JavascriptEventConfirmation;
public class AdminManageSupervisorPanel extends Panel {
@ -109,8 +111,22 @@ public class AdminManageSupervisorPanel extends Panel {
item.add(new Label("unit", new Model<String>(unit)));
item.add(createDropDown(new Model<Availability>(bachelorAvalibality), "numCapable", "targetBachelor"));
item.add(createDropDown(new Model<Availability>(masterAvalibality), "numCapable", "targetMaster"));
item.add(new Label("currentBachelor", new Model<Integer>((bachelorAvalibality.getNumMatched().intValue()))));
if(supervisor.getCountFromDate(projectClassDao.getProjectClass("BACHELOR"))!=null){
item.add(new DateFormatter(DateFormatter.FORMAT.EXTENDED).createFormattedDateLabel("bachelorDate", supervisor.getCountFromDate(projectClassDao.getProjectClass("BACHELOR"))));
}
else {
item.add(new Label("bachelorDate", "no date"));
}
item.add(new Label("currentMaster", new Model<Integer>(masterAvalibality.getNumMatched().intValue())));
if(supervisor.getCountFromDate(projectClassDao.getProjectClass("MASTER"))!=null){
item.add(new DateFormatter(DateFormatter.FORMAT.EXTENDED).createFormattedDateLabel("masterDate", supervisor.getCountFromDate(projectClassDao.getProjectClass("MASTER"))));
}
else {
item.add(new Label("masterDate", "no date"));
}
}
};
@ -219,6 +235,31 @@ public class AdminManageSupervisorPanel extends Panel {
add(researchAreaPanel);
add(filterButton);
AjaxLink resetAllBachelor = new AjaxLink("resetAllBachelorButton"){
@Override
public void onClick(AjaxRequestTarget target) {
supervisorDao.resetCountFromDate(projectClassDao.getProjectClass("BACHELOR"));
target.addComponent(container);
}
};
resetAllBachelor.add(new JavascriptEventConfirmation("onclick", "Are you sure you want to reset all supervisors bachelor counts?"));
add(resetAllBachelor);
AjaxLink resetAllMaster = new AjaxLink("resetAllMasterButton"){
@Override
public void onClick(AjaxRequestTarget target) {
supervisorDao.resetCountFromDate(projectClassDao.getProjectClass("MASTER"));
target.addComponent(container);
}
};
resetAllMaster.add(new JavascriptEventConfirmation("onclick", "Are you sure you want to reset all supervisors master counts?"));
add(resetAllMaster);
}
}
}

@ -77,7 +77,7 @@ public class AdminRejectedProjectIdeaPanel extends Panel {
item.add(new Label("author", new Model<String>(authorString)));
item.add(new Label("title", new Model<String>(idea.getTitle())));
item.add(new Label("rejectedBy", new Model<String>(idea.getMatch().getRejectedBy() != null ? idea.getMatch().getRejectedBy().getFullName():"")));
item.add(new Label("comment", new Model<String>(idea.getMatch().getCommentForStudent())));
item.add(new Label("comment", new Model<String>(idea.getMatch().getCommentForAdmin())));
AjaxLink<Void> dialogLink = new AjaxLink<Void>("editDialog") {
private static final long serialVersionUID = 1L;

@ -32,47 +32,42 @@ import se.su.dsv.scipro.util.StringUtil;
public class MatchPeriodEditPanel extends Panel {
private static final long serialVersionUID = 1L;
private Form<ApplicationPeriod> formWrapper;
private Component feedbackPanel;
@SpringBean
private ApplicationPeriodFacade facade;
@SpringBean
private ProjectClassDao projectClassDao;
private WebMarkupContainer containerForUpdate;
private Component feedbackPanel;
public MatchPeriodEditPanel(final String id, final WebMarkupContainer container) {
this(id, new Model<ApplicationPeriod>(createDummyApplicationPeriod()), container);
this(id, new Model<ApplicationPeriod>(ApplicationPeriodFacade.createDummyApplicationPeriod()), container);
}
public MatchPeriodEditPanel(String id, IModel<ApplicationPeriod> model, final WebMarkupContainer container) {
super(id);
containerForUpdate = container;
add(feedbackPanel = new FeedbackPanel("feedback").setOutputMarkupId(true));
formWrapper = new ApplicationPeriodForm("applicationPeriodForm",model);
Form<ApplicationPeriod> formWrapper = new ApplicationPeriodForm("applicationPeriodForm", model);
formWrapper.setEnabled(isEditable());
add(formWrapper);
}
/**
* Override to provide a fast and simple "view application period" or "edit application period" functionality depending on preference.
* @return
* @return boolean
*/
public boolean isEditable(){
return false;
}
private static ApplicationPeriod createDummyApplicationPeriod(){
ApplicationPeriod appPeriod = new ApplicationPeriod();
Calendar cal = Calendar.getInstance();
appPeriod.setStartDate(cal.getTime());
cal.add(Calendar.MONTH, 1);
appPeriod.setEndDate(cal.getTime());
appPeriod.setName("...");
return appPeriod;
}
private class ApplicationPeriodForm extends Form<ApplicationPeriod> {
private static final long serialVersionUID = 1L;
final CheckGroup<ProjectClass> group;
private ApplicationPeriod applicationPeriod;
public ApplicationPeriodForm(String id, final IModel<ApplicationPeriod> model) {
super(id, model);
applicationPeriod = model.getObject();
//This crap should be refactored out of here
group = new CheckGroup<ProjectClass>("checkGroup",model.getObject().getProjectClass());
add(group);
@ -85,11 +80,13 @@ public class MatchPeriodEditPanel extends Panel {
}
};
group.add(pClasses);
group.setEnabled(isEditable());
add(new CustomDateTimeField("startDate", new PropertyModel<Date>(model.getObject(),"startDate")));
add(new CustomDateTimeField("endDate", new PropertyModel<Date>(model.getObject(),"endDate")));
add(new CustomDateTimeField("startDate", new PropertyModel<Date>(model.getObject(),"startDate")).setEnabled(isEditable()));
add(new CustomDateTimeField("endDate", new PropertyModel<Date>(model.getObject(),"endDate")).setEnabled(isEditable()));
final TextField<String> nameField = new TextField<String>("name", new PropertyModel<String>(model.getObject(),"name"));
nameField.setRequired(true);
nameField.setEnabled(isEditable());
add(nameField);
add(new AjaxSubmitLink("saveButton") {
private static final long serialVersionUID = 1L;
@ -121,7 +118,7 @@ public class MatchPeriodEditPanel extends Panel {
} else {
saveMsg.append(" Saved : ");
}
Session.get().info(saveMsg.toString() + StringUtil.getApplicationPeriodData(appPeriod));
Session.get().info(saveMsg.toString() + facade.getApplicationPeriodData(appPeriod));
if(isEditing) {
setResponsePage(AdminManageMatchPeriodsPage.class); // to avoid HibernateOptimisticLockingFailureException when updating
}
@ -133,7 +130,7 @@ public class MatchPeriodEditPanel extends Panel {
} else {
errorMsg.append(" Could not create new : ");
}
Session.get().error(errorMsg.toString() + StringUtil.getApplicationPeriodData(appPeriod) + " period already exists.");
Session.get().error(errorMsg.toString() + facade.getApplicationPeriodData(appPeriod) + " period already exists.");
}
target.addComponent(containerForUpdate);
target.addComponent(feedbackPanel);
@ -148,11 +145,11 @@ public class MatchPeriodEditPanel extends Panel {
protected void onError(AjaxRequestTarget target, Form<?> form) {
final ApplicationPeriod appPeriod = ((ApplicationPeriod)form.getModelObject());
if(appPeriod.getProjectClass().size() > 0 && !appPeriod.getEndDate().before(appPeriod.getStartDate())) {
Session.get().error(" Could not add application period : " + StringUtil.getApplicationPeriodData(appPeriod));
Session.get().error(" Could not add application period : " + facade.getApplicationPeriodData(appPeriod));
target.addComponent(feedbackPanel);
}
}
});
}.setEnabled(isEditable()));
AjaxButton cancelButton = new AjaxButton("closeButton", new Model<String>("Close")){
private static final long serialVersionUID = 1L;
@ -161,10 +158,13 @@ public class MatchPeriodEditPanel extends Panel {
protected void onSubmit(AjaxRequestTarget target, Form<?> form) {
setResponsePage(AdminManageMatchPeriodsPage.class);
}
};
cancelButton.setDefaultFormProcessing(false);
cancelButton.setDefaultFormProcessing(false).setEnabled(true);
add(cancelButton);
}
private boolean isEditable() {
return applicationPeriod.getEndDate().after(Calendar.getInstance().getTime());
}
}
}

@ -15,9 +15,7 @@ import se.su.dsv.scipro.security.auth.roles.Roles;
@Authorization(authorizedRoles={Roles.STUDENT})
public class ProjectIdeaSubmissionPage extends ProjectPage implements MenuHighlightProjectIdeas {
private final ProjectIdea idea;
@SpringBean
@SpringBean
private ProjectIdeaDao projectIdeaDao;
public ProjectIdeaSubmissionPage(PageParameters pp) {
@ -25,13 +23,14 @@ public class ProjectIdeaSubmissionPage extends ProjectPage implements MenuHighli
Long ideaId = pp.getAsLong("idea");
if(ideaId != null)
ProjectIdea idea;
if(ideaId != null)
idea = projectIdeaDao.load(ideaId);
else
idea = new ProjectIdea();
add(new ProjectIdeaSubmissionPanel("projectIdeaPanel", getUser(), idea));
add(new CheatSheetPanel("cheatSheetPanel"));
}
}

@ -37,7 +37,6 @@ import org.wicketstuff.objectautocomplete.ObjectReadOnlyRenderer;
import se.su.dsv.scipro.SciProSession;
import se.su.dsv.scipro.components.BooleanChoiceRenderer;
import se.su.dsv.scipro.components.ProjectClassSelector;
import se.su.dsv.scipro.data.DomainObjectDetachableModel;
import se.su.dsv.scipro.data.dataobjects.Employee;
import se.su.dsv.scipro.data.dataobjects.Language;
import se.su.dsv.scipro.data.dataobjects.ProjectClass;
@ -46,10 +45,8 @@ import se.su.dsv.scipro.data.dataobjects.User;
import se.su.dsv.scipro.data.facade.ProjectIdeaFacade;
import se.su.dsv.scipro.match.dao.interfaces.AuthorDao;
import se.su.dsv.scipro.match.dao.interfaces.ExemptionDao;
import se.su.dsv.scipro.match.dao.interfaces.ProjectIdeaDao;
import se.su.dsv.scipro.match.dao.interfaces.SupervisorDao;
import se.su.dsv.scipro.match.dataobject.Keywords;
import se.su.dsv.scipro.match.dataobject.Match;
import se.su.dsv.scipro.match.dataobject.ProjectIdea;
import se.su.dsv.scipro.match.facade.ApplicationPeriodFacade;
import se.su.dsv.scipro.match.facade.KeywordProvidingProxy;
@ -65,8 +62,8 @@ public class ProjectIdeaSubmissionPanel extends Panel {
private static final long serialVersionUID = 1L;
// @SpringBean
// private ApplicationPeriodFacade facade;
@SpringBean
private ApplicationPeriodFacade facade;
@SpringBean
private ProjectIdeaFacade projectIdeaFacade;
@SpringBean
@ -84,12 +81,13 @@ public class ProjectIdeaSubmissionPanel extends Panel {
* Identifier for the panel.
* @param user
* The current sessions user, the one that wants to submit a project idea.
* @param idea
* The project idea, that is submitted
*/
public ProjectIdeaSubmissionPanel(String id, User user, ProjectIdea idea) {
super(id);
add(new FeedbackPanel("feedback"));
add(new ProjectIdeaForm("projectIdeaForm", user, new Model<ProjectIdea>(idea)));
dialogSetup();
}
@ -305,7 +303,7 @@ public class ProjectIdeaSubmissionPanel extends Panel {
radioChoiceContainer.setOutputMarkupId(true);
externalSupervisorContainer = new WebMarkupContainer("externalContainer");
externalSupervisorContainer.setOutputMarkupId(true);
List<Boolean> BOOLEAN_OPTIONS = Arrays.asList(new Boolean[]{Boolean.FALSE, Boolean.TRUE});
List<Boolean> BOOLEAN_OPTIONS = Arrays.asList(Boolean.FALSE, Boolean.TRUE);
try {
if(ideaModel.getObject().getMatch().getSupervisor().getId() != null) {
@ -508,20 +506,16 @@ public class ProjectIdeaSubmissionPanel extends Panel {
}
/**
* A project idea is editable if an open application period exists + no match object exists or match status is refused AND the idea creator is the logged in user.
* @return
* A project idea is editable if an open application period exists AND the idea creator is the logged in user.
* @return boolean
*/
private boolean isEditable() {
//return facade.applicationPeriodExists(ideaModel.getObject());
return (ideaModel.getObject().getMatch() == null ||
ideaModel.getObject().getMatch().getStatus() == null ||
ideaModel.getObject().getMatch().getStatus().equals(Match.Status.REFUSED)) && isCreator();
return (ideaModel.getObject() == null || facade.openApplicationPeriodsExists(ideaModel.getObject().getProjectClass()) && isCreator());
}
/**
* Check to see if the signed in author has exemption to write thesis alone for the selected project class.
* @return
* @return boolean
*/
private boolean isExemptionGranted() {
return exemptionDao.getByAuthorAndClass(signedInAuthor, projectClassModel.getObject()) != null;
@ -529,11 +523,10 @@ public class ProjectIdeaSubmissionPanel extends Panel {
/**
* Check to see if the signed-in user is creator of an already existing idea, or if it is a new idea.
* @return
* @return boolean
*/
private boolean isCreator() {
return ideaModel.getObject().getAuthors().isEmpty() || ideaModel.getObject().getAuthors().get(0).equals(signedInAuthor);
return ideaModel.getObject().getAuthors().isEmpty() || ideaModel.getObject().getAuthors().get(0).equals(signedInAuthor);
}
}
}

@ -0,0 +1,20 @@
<!DOCTYPE html>
<html
xmlns:wicket="http://wicket.apache.org/dtds.data/wicket-xhtml1.4-strict.dtd">
<head>
<meta http-equiv="Content-type" content="text/html;charset=UTF-8" />
</head>
<body>
<wicket:panel>
<form wicket:id="form">
<div class="append-bottom"><button wicket:id="acceptButton">Accept to supervise</button></div>
<!-- <div class="append-bottom"><input type="button" value="Accept to supervise"></div> -->
<div class="append-top">Or enter a reason to decline: (at least
5 characters)</div>
<textarea wicket:id="reason" rows="5" style="width: 100%;"></textarea>
<button wicket:id="declineButton"
style="float: right; margin-top: 1em;">Decline</button>
</form>
</wicket:panel>
</body>
</html>

@ -0,0 +1,95 @@
package se.su.dsv.scipro.supervisor.panels;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.ajax.markup.html.AjaxLink;
import org.apache.wicket.ajax.markup.html.form.AjaxButton;
import org.apache.wicket.markup.html.form.Form;
import org.apache.wicket.markup.html.form.TextArea;
import org.apache.wicket.markup.html.panel.Panel;
import org.apache.wicket.model.LoadableDetachableModel;
import org.apache.wicket.model.PropertyModel;
import org.apache.wicket.spring.injection.annot.SpringBean;
import org.apache.wicket.validation.validator.StringValidator;
import se.su.dsv.scipro.SciProSession;
import se.su.dsv.scipro.match.dao.interfaces.MatchDao;
import se.su.dsv.scipro.match.dataobject.Match;
import se.su.dsv.scipro.match.dataobject.Match.Status;
import se.su.dsv.scipro.match.facade.MatchFacade;
public abstract class SupervisorAcceptDeclinePanel2 extends Panel {
@SpringBean
private MatchDao matchDao;
@SpringBean
private MatchFacade matchFacade;
private static final long serialVersionUID = 1L;
private long matchId;
public abstract void onUpdate(AjaxRequestTarget target);
public SupervisorAcceptDeclinePanel2(String id, Match match) {
super(id);
matchId = match.getId();
final LoadableDetachableModel<Match> matchModel = new LoadableDetachableModel<Match>() {
private static final long serialVersionUID = 1L;
@Override
protected Match load() {
return matchDao.load(matchId);
}
};
add(new SupervisorAcceptDeclineForm("form", matchModel));
}
private class SupervisorAcceptDeclineForm extends Form<Void> {
private static final long serialVersionUID = 1L;
private TextArea<String> reason;
private String reasonString;
private LoadableDetachableModel<Match> matchModel;
public SupervisorAcceptDeclineForm(String id, final LoadableDetachableModel<Match> matchModel) {
super(id);
this.matchModel = matchModel;
add(new AjaxLink("acceptButton"){
private static final long serialVersionUID = 1L;
@Override
public void onClick(AjaxRequestTarget target) {
matchDao.changeStatus(SciProSession.get().getUser(), matchModel.getObject(), Status.CONFIRMED);
onUpdate(target);
System.out.println("accept");
}
});
reason = new TextArea<String>("reason", new PropertyModel<String>(this, "reasonString"));
reason.setRequired(true);
reason.add(StringValidator.minimumLength(5));
add(reason);
add(new AjaxButton("declineButton"){
private static final long serialVersionUID = 1L;
@Override
protected void onSubmit(AjaxRequestTarget target, Form<?> form) {
if (reason.getModelObject() != null && reason.getModelObject().length() > 4){
matchFacade.reject(matchModel.getObject(), SciProSession.get().getUser(), reasonString);
onUpdate(target);
}
}
});
}
// @Override
// protected void onSubmit() {
// matchDao.changeStatus(SciProSession.get().getUser(), matchModel.getObject(), Status.CONFIRMED);
// }
}
}

@ -115,7 +115,17 @@ public class SupervisorMatchedThesisPanel extends Panel {
if(panelType.equalsIgnoreCase("Admin")){
item.add(new AdminEditProjectIdeaPanel("dialogLink", item.getModel()));
}else if (panelType.equalsIgnoreCase("Supervisor")){
item.add(new SupervisorProjectIdeaDialogPanel("dialogLink", item.getModelObject().getMatch()));
item.add(new SupervisorProjectIdeaDialogPanel("dialogLink", item.getModelObject().getMatch()){
private static final long serialVersionUID = 1L;
@Override
public void onUpdateUpdate(AjaxRequestTarget target) {
emptyLabel.setVisible(provider.size()==0);
target.addComponent(dataViewContainer);
target.addComponent(emptyLabel);
}
});
}
item.add(new Label("authors", StringUtil.getAuthorsFormated(projectIdea.getAuthors())));
}

@ -5,10 +5,12 @@
<a href="#" wicket:id="dialogLink">
<span wicket:id="linkLabel"></span>
</a>
<div wicket:id="dialog">
<div wicket:id="dialog">
<div wicket:id="watsonPanel"></div>
<div wicket:id="acceptDeclinePanel"></div>
</div>
</div>
</wicket:panel>
</body>
</html>

@ -2,6 +2,7 @@ package se.su.dsv.scipro.supervisor.panels;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.ajax.markup.html.AjaxLink;
import org.apache.wicket.markup.html.WebMarkupContainer;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.panel.Panel;
import org.apache.wicket.model.LoadableDetachableModel;
@ -11,7 +12,7 @@ import org.odlabs.wiquery.ui.dialog.Dialog;
import se.su.dsv.scipro.match.dao.interfaces.MatchDao;
import se.su.dsv.scipro.match.dataobject.Match;
public class SupervisorProjectIdeaDialogPanel extends Panel {
public abstract class SupervisorProjectIdeaDialogPanel extends Panel {
@SpringBean
MatchDao matchDao;
@ -20,7 +21,9 @@ public class SupervisorProjectIdeaDialogPanel extends Panel {
private Dialog dialog;
private long matchId;
public abstract void onUpdateUpdate(AjaxRequestTarget target);
public SupervisorProjectIdeaDialogPanel(String id, Match match) {
super(id);
@ -37,6 +40,7 @@ public class SupervisorProjectIdeaDialogPanel extends Panel {
};
dialog = new Dialog("dialog");
dialog.setOutputMarkupId(true);
dialog.setTitle("Suggested project idea: " + matchModel.getObject().getProjectIdea().getTitle());
add(dialog);
@ -56,6 +60,17 @@ public class SupervisorProjectIdeaDialogPanel extends Panel {
add(link);
dialog.add(new WatsonInfoPanel("watsonPanel", matchModel.getObject().getProjectIdea()));
dialog.add(new SupervisorAcceptDeclinePanel("acceptDeclinePanel", matchModel.getObject()));
// dialog.add(new SupervisorAcceptDeclinePanel("acceptDeclinePanel", matchModel.getObject()));
dialog.add(new SupervisorAcceptDeclinePanel2("acceptDeclinePanel", matchModel.getObject()){
private static final long serialVersionUID = 1L;
@Override
public void onUpdate(AjaxRequestTarget target) {
onUpdateUpdate(target);
dialog.close(target);
}
});
}
}

@ -1,6 +1,8 @@
package se.su.dsv.scipro.user.facade;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.springframework.beans.factory.annotation.Autowired;
@ -13,6 +15,7 @@ import se.su.dsv.scipro.data.dataobjects.Language;
import se.su.dsv.scipro.data.dataobjects.User;
import se.su.dsv.scipro.match.dao.interfaces.SupervisorDao;
import se.su.dsv.scipro.match.dataobject.Keyword;
import se.su.dsv.scipro.match.dataobject.Keywords;
@Service
public class UserFacade {
@ -28,7 +31,15 @@ public class UserFacade {
keywords = new HashSet<Keyword>();
if(languages == null)
languages = new HashSet<Language>();
employee.getKeywords().setKeywords(keywords);
Set<Keyword> oldKeywords = new HashSet<Keyword>(employee.getKeywords().getAll());
for (Keyword k : keywords){
oldKeywords.add(k);
}
employee.getKeywords().setKeywords(oldKeywords);
//the line below is why the unit disappears when saving a supervisor profile- the unit is never specified so it saves null over the existing value.
// employee.getKeywords().setKeywords(keywords);
employee.getCapabilities().setLanguages(languages);
supervisorDao.save(employee);
userDao.save(employee.getUser());

@ -34,8 +34,9 @@ public class StringUtil {
return stringBuilder.toString();
}
public static String getAuthorsFormated(List<Student> authors) {
// TODO : this should be refactored, the StringUtil class should not be aware of Student
public static String getAuthorsFormated(List<Student> authors) {
if (authors == null) {
return null;
}
@ -47,7 +48,8 @@ public class StringUtil {
return getFormatedString(stringList);
}
// TODO : this should be refactored, the StringUtil class should not be aware of Keywords
public static String getKeywordsFormated(Keywords keywords) {
List<String> stringList = new ArrayList<String>();
for (Keyword keyword : keywords.getAll()) {
@ -56,21 +58,4 @@ public class StringUtil {
return getFormatedString(stringList);
}
// TODO : this should be refactored, the StringUtil class should not be aware of ApplicationPeriods
public static String getApplicationPeriodData(final ApplicationPeriod appPeriod) {
StringBuilder projectClasses = new StringBuilder();
Iterator<ProjectClass> projectClassIterator = appPeriod.getProjectClass().iterator();
while(projectClassIterator.hasNext()) {
projectClasses.append(projectClassIterator.next().getName());
if(projectClassIterator.hasNext()) {
projectClasses.append(", ");
}
}
return new StringBuilder()
.append("'").append(appPeriod.getName()).append("'")
.append("\tStart date : '").append(new DateFormatter(DateFormatter.FORMAT.DEFAULT).createFormattedString(appPeriod.getStartDate())).append("'")
.append("\tEnd date : '").append(new DateFormatter(DateFormatter.FORMAT.DEFAULT).createFormattedString(appPeriod.getEndDate())).append("'")
.append("\tLevels: '").append(projectClasses.toString()).append("'").toString();
}
}

@ -23,7 +23,7 @@
value="true" />
<property name="hibernate.generate_statistics" value="false" />
<!-- DEVELOPMENT VARIABLE, REMOVE FOR PRODUCTION USE -->
<!-- <property name="hibernate.hbm2ddl.auto" value="update" /> -->
<!-- <property name="hibernate.hbm2ddl.auto" value="update" /> -->
<!-- production settings database -->
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQLInnoDBDialect" />
<property name="hibernate.connection.driver_class" value="com.mysql.jdbc.Driver"></property>

@ -63,6 +63,9 @@
<bean id="projectScheduleFacade" class="se.su.dsv.scipro.activityplan.facade.ProjectScheduleFacade">
</bean>
<bean id="applicationPeriodFacade" class="se.su.dsv.scipro.match.facade.ApplicationPeriodFacade">
</bean>
<bean id="projectIdeaDao" class="se.su.dsv.scipro.match.dao.jpa.ProjectIdeaDaoJPAImp">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>

@ -2,10 +2,7 @@ package se.su.dsv.scipro.match.dao;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import java.util.*;
import org.junit.Assert;
import org.junit.Before;
@ -30,6 +27,7 @@ import se.su.dsv.scipro.match.dao.interfaces.ApplicationPeriodDao;
import se.su.dsv.scipro.match.dao.interfaces.ProjectIdeaDao;
import se.su.dsv.scipro.match.dataobject.ApplicationPeriod;
import se.su.dsv.scipro.match.dataobject.ProjectIdea;
import se.su.dsv.scipro.match.facade.ApplicationPeriodFacade;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration
@ -41,22 +39,26 @@ public class TestApplicationPeriodDao {
@Autowired
private RoleDao roleDao;
private ApplicationPeriodDao target;
@Autowired
private ApplicationPeriodDao applicationPeriodDao;
@Autowired
private ApplicationPeriodFacade applicationPeriodFacade;
@Autowired
private ProjectClassDao projectClassDao;
@Autowired
private ApplicationPeriodDao applicationPeriodDao;
private ProjectDao projectDao;
@Autowired
private ProjectIdeaDao projectIdeaDao;
private ProjectClass bachelor;
private ApplicationPeriod applicationPeriod;
private ApplicationPeriod applicationPeriod2;
@Autowired
private ProjectIdeaDao projectIdeaDao;
private ProjectIdea projectIdea1;
@ -64,14 +66,8 @@ public class TestApplicationPeriodDao {
private Project project;
@Autowired
private ProjectDao projectDao;
private User student1;
private Role student1Role;
private Student student1Author;
SimpleDateFormat date = new SimpleDateFormat("yyyy-MM-dd", Locale.ENGLISH);
private ProjectClass master;
@ -80,12 +76,14 @@ public class TestApplicationPeriodDao {
private ProjectClass phd;
private ApplicationPeriodDao target;
@Before
public void startTransaction() throws Exception {
student1 = new User();
User student1 = new User();
student1 = userDao.save(student1);
student1Role = new Student();
Role student1Role = new Student();
student1Role.setUser(student1);
student1Role = roleDao.save(student1Role);
/*
@ -215,4 +213,285 @@ public class TestApplicationPeriodDao {
ApplicationPeriod ap = target.getNextPeriodByClass(bachelor, currentTime);
Assert.assertEquals(applicationPeriod2, ap);
}
/* create an application period with the end date before the date of TODAY, then it should NOT be possible to remove the application period */
@Test
@Transactional
@Rollback
public void notAbleToRemovePeriod() {
Set<ProjectClass> myBachelorSet = new HashSet<ProjectClass>();
myBachelorSet.add(bachelor);
Calendar cal = Calendar.getInstance();
cal.set(2011, Calendar.DECEMBER, 2);
final Date startDate1 = cal.getTime();
cal.set(2011, Calendar.DECEMBER, 7);
cal.set(Calendar.HOUR_OF_DAY, 13);
final Date endDate1 = cal.getTime();
ApplicationPeriod applicationPeriod = applicationPeriodDao.save(createApplicationPeriod(myBachelorSet, startDate1, endDate1));
boolean periodRemoved = applicationPeriodFacade.removeApplicationPeriod(applicationPeriod);
Assert.assertFalse(periodRemoved); // should be false
}
/* create an application period with the end date before after the date of "TODAY", then it should be possible to remove */
@Test
@Transactional
@Rollback
public void canRemovePeriod() {
Set<ProjectClass> myBachelorSet = new HashSet<ProjectClass>();
myBachelorSet.add(bachelor);
Calendar cal = Calendar.getInstance();
cal.set(2011, Calendar.DECEMBER, 2);
final Date startDate1 = cal.getTime();
cal.set(2051, Calendar.DECEMBER, 7);
cal.set(Calendar.HOUR_OF_DAY, 13);
final Date endDate1 = cal.getTime();
ApplicationPeriod applicationPeriod = applicationPeriodDao.save(createApplicationPeriod(myBachelorSet, startDate1, endDate1));
boolean periodRemoved = applicationPeriodFacade.removeApplicationPeriod(applicationPeriod);
Assert.assertTrue(periodRemoved); // should be true
}
/* 1. create an application period from TODAY and one month forward, the PROJECT CLASSES are THE SAME in this case
2. test if there exists any OPEN application period for the project class in the argument */
@Test
@Transactional
@Rollback
public void applicationPeriodExists() {
Set<ProjectClass> myBachelorSet = new HashSet<ProjectClass>();
myBachelorSet.add(bachelor);
Calendar cal = Calendar.getInstance();
final Date startDate1 = cal.getTime();
cal.set(2012, Calendar.APRIL, 2);
final Date endDate1 = cal.getTime();
applicationPeriodDao.save(createApplicationPeriod(myBachelorSet, startDate1, endDate1));
boolean exists = applicationPeriodFacade.openApplicationPeriodsExists(bachelor);
Assert.assertTrue(exists); // should exist
}
/* 1. create an application period from TODAY and one month forward, the PROJECT CLASSES are DIFFERENT in this case
2. test if there exists any OPEN application period for the project class in the argument */
@Test
@Transactional
@Rollback
public void missingApplicationPeriod_1() {
Set<ProjectClass> myMasterSet = new HashSet<ProjectClass>();
myMasterSet.add(master);
Calendar cal = Calendar.getInstance();
final Date startDate1 = cal.getTime();
cal.set(2012, Calendar.APRIL, 2);
final Date endDate1 = cal.getTime();
applicationPeriodDao.save(createApplicationPeriod(myMasterSet, startDate1, endDate1));
boolean exists = applicationPeriodFacade.openApplicationPeriodsExists(bachelor);
Assert.assertFalse(exists); // should NOT exist
}
/* 1. create an application period from ONE DAY AFTER TODAY and one month forward, the PROJECT CLASSES are SAME in this case
2. test if there exists any OPEN application period for the project class in the argument */
@Test
@Transactional
@Rollback
public void missingApplicationPeriod_2() {
Set<ProjectClass> myMasterSet = new HashSet<ProjectClass>();
myMasterSet.add(master);
Calendar cal = Calendar.getInstance();
cal.add(Calendar.DAY_OF_YEAR, 1);
final Date startDate1 = cal.getTime();
cal.set(2012, Calendar.APRIL, 2);
final Date endDate1 = cal.getTime();
applicationPeriodDao.save(createApplicationPeriod(myMasterSet, startDate1, endDate1));
boolean exists = applicationPeriodFacade.openApplicationPeriodsExists(bachelor);
Assert.assertFalse(exists); // should NOT exist
}
/* the same project classes, the same date, the first period: 10.00 - 11.59,
the second period: 12.00 - 13.59,
should NOT overlap. */
@Test
@Transactional
@Rollback
public void notOverlappingBasedOnTimeLimits() {
Set<ProjectClass> myBachelorSet = new HashSet<ProjectClass>();
myBachelorSet.add(bachelor);
applicationPeriodDao.save(createApplicationPeriod(myBachelorSet, createStartDate_1(), createEndDate_1()));
boolean periodOverlap = applicationPeriodFacade.doesPeriodOverlap(createApplicationPeriod(myBachelorSet, createStartDate_2(), createEndDate_2()));
Assert.assertFalse(periodOverlap); // should NOT overlap
}
/* the same project classes, the date of the first time period ends when the date of the second time period starts, should NOT overlap */
@Test
@Transactional
@Rollback
public void notOverlappingBasedOnDatePeriods() {
Set<ProjectClass> myBachelorSet = new HashSet<ProjectClass>();
myBachelorSet.add(bachelor);
Calendar cal = Calendar.getInstance();
cal.set(2012, Calendar.MARCH, 2);
final Date startDate1 = cal.getTime();
cal.set(2012, Calendar.APRIL, 2);
cal.set(Calendar.HOUR_OF_DAY, 13); // HOUR_OF_DAY is used for the 24 hour clock
final Date endDate1 = cal.getTime();
applicationPeriodDao.save(createApplicationPeriod(myBachelorSet, startDate1, endDate1));
cal.set(Calendar.HOUR_OF_DAY, 14);
final Date startDate2 = cal.getTime();
cal.set(2012, Calendar.MAY, 2);
final Date endDate2 = cal.getTime();
boolean periodOverlap = applicationPeriodFacade.doesPeriodOverlap(createApplicationPeriod(myBachelorSet, startDate2, endDate2));
Assert.assertFalse(periodOverlap); // should NOT overlap
}
/* the same project classes, first create an application period and save it,
then try to edit the new period, it should NOT overlap even if the start or end date and/or project class are the same */
@Test
@Transactional
@Rollback
public void notOverlappingWhenUpdating() {
Set<ProjectClass> myBachelorSet = new HashSet<ProjectClass>();
myBachelorSet.add(bachelor);
Calendar cal = Calendar.getInstance();
cal.set(2012, Calendar.MARCH, 2);
final Date startDate1 = cal.getTime();
cal.set(2012, Calendar.APRIL, 2);
final Date endDate1 = cal.getTime();
ApplicationPeriod applicationPeriod1 = applicationPeriodDao.save(createApplicationPeriod(myBachelorSet, startDate1, endDate1));
// edit the period
applicationPeriod1.getProjectClass().add(master);
cal.set(2012, Calendar.MAY, 2);
final Date changedEndDate = cal.getTime();
applicationPeriod1.setEndDate(changedEndDate);
boolean periodOverlap = applicationPeriodFacade.doesPeriodOverlap(applicationPeriod1);
Assert.assertFalse(periodOverlap); // should NOT overlap
}
/* same time periods, with different project classes, should NOT overlap */
@Test
@Transactional
@Rollback
public void notOverlappingDifferentProjectClasses() {
Set<ProjectClass> myBachelorSet = new HashSet<ProjectClass>();
myBachelorSet.add(bachelor);
Calendar cal = Calendar.getInstance();
cal.set(2012, Calendar.MARCH, 2);
final Date startDate = cal.getTime();
cal.set(2012, Calendar.APRIL, 2);
cal.set(Calendar.HOUR_OF_DAY, 13); // HOUR_OF_DAY is used for the 24 hour clock
final Date endDate = cal.getTime();
cal.set(Calendar.HOUR_OF_DAY, 14);
final Date endDate2 = cal.getTime();
applicationPeriodDao.save(createApplicationPeriod(myBachelorSet, startDate, endDate));
Set<ProjectClass> myMasterSet = new HashSet<ProjectClass>();
myMasterSet.add(master);
boolean periodOverlap = applicationPeriodFacade.doesPeriodOverlap(createApplicationPeriod(myMasterSet, startDate, endDate2));
Assert.assertFalse(periodOverlap); // should NOT overlap
}
/* one long time period, with same project classes, shorter time periods within this long time period should overlap */
@Test
@Transactional
@Rollback
public void overlappingPeriods() {
Set<ProjectClass> myBachelorSet = new HashSet<ProjectClass>();
myBachelorSet.add(bachelor);
Calendar cal = Calendar.getInstance();
cal.set(2012, Calendar.MARCH, 2);
final Date startDate1 = cal.getTime();
cal.set(2012, Calendar.DECEMBER, 2);
final Date endDate1 = cal.getTime();
applicationPeriodDao.save(createApplicationPeriod(myBachelorSet, startDate1, endDate1));
cal.set(2012, Calendar.MAY, 2);
final Date startDate2 = cal.getTime();
cal.set(2012, Calendar.JUNE, 2);
final Date endDate2 = cal.getTime();
boolean periodOverlap = applicationPeriodFacade.doesPeriodOverlap(createApplicationPeriod(myBachelorSet, startDate2, endDate2));
Assert.assertTrue(periodOverlap); // should overlap
}
/* same time periods, with same project classes, should overlap */
@Test
@Transactional
@Rollback
public void overlappingSameProjectClasses() {
Set<ProjectClass> myBachelorSet = new HashSet<ProjectClass>();
myBachelorSet.add(bachelor);
Calendar cal = Calendar.getInstance();
cal.set(2012, Calendar.MARCH, 2);
final Date startDate = cal.getTime();
cal.set(2012, Calendar.APRIL, 2);
final Date endDate = cal.getTime();
cal.set(Calendar.HOUR_OF_DAY, 13);
final Date endDate2 = cal.getTime();
applicationPeriodDao.save(createApplicationPeriod(myBachelorSet, startDate, endDate));
boolean periodOverlap = applicationPeriodFacade.doesPeriodOverlap(createApplicationPeriod(myBachelorSet, startDate, endDate2));
Assert.assertTrue(periodOverlap); // should overlap
}
/* the same time periods, with different sets of project classes, but when one of the project classes overlaps, should overlap */
@Test
@Transactional
@Rollback
public void overlappingMultipleProjectClasses() {
Set<ProjectClass> myBachelorSet = new HashSet<ProjectClass>();
myBachelorSet.add(bachelor);
Calendar cal = Calendar.getInstance();
cal.set(2012, Calendar.MARCH, 2);
final Date startDate = cal.getTime();
cal.set(2012, Calendar.APRIL, 2);
final Date endDate = cal.getTime();
applicationPeriodDao.save(createApplicationPeriod(myBachelorSet, startDate, endDate));
cal.set(Calendar.HOUR_OF_DAY, 13);
final Date endDate2 = cal.getTime();
Set<ProjectClass> multipleProjectClasses = new HashSet<ProjectClass>();
multipleProjectClasses.add(bachelor);
multipleProjectClasses.add(master);
boolean periodOverlap = applicationPeriodFacade.doesPeriodOverlap(createApplicationPeriod(multipleProjectClasses, startDate, endDate2));
Assert.assertTrue(periodOverlap); // should overlap
}
private ApplicationPeriod createApplicationPeriod(final Set<ProjectClass> projectClassSet, final Date startDate, final Date endDate) {
ApplicationPeriod appPeriod = new ApplicationPeriod();
appPeriod.setStartDate(startDate);
appPeriod.setEndDate(endDate);
appPeriod.setProjectClass(projectClassSet);
return appPeriod;
}
Date createStartDate_1() {
Calendar cal = Calendar.getInstance();
cal.set(Calendar.HOUR_OF_DAY, 10);
cal.set(Calendar.MINUTE, 0);
cal.set(Calendar.SECOND, 0);
cal.set(Calendar.MILLISECOND, 0);
return cal.getTime();
}
Date createEndDate_1() {
Calendar cal = Calendar.getInstance();
cal.set(Calendar.HOUR_OF_DAY, 11);
cal.set(Calendar.MINUTE, 59);
cal.set(Calendar.SECOND, 59);
cal.set(Calendar.MILLISECOND, 0);
return cal.getTime();
}
Date createStartDate_2() {
Calendar cal = Calendar.getInstance();
cal.set(Calendar.HOUR_OF_DAY, 12);
cal.set(Calendar.MINUTE, 0);
cal.set(Calendar.SECOND, 0);
cal.set(Calendar.MILLISECOND, 0);
return cal.getTime();
}
Date createEndDate_2() {
Calendar cal = Calendar.getInstance();
cal.set(Calendar.HOUR_OF_DAY, 13);
cal.set(Calendar.MINUTE, 59);
cal.set(Calendar.SECOND, 0);
cal.set(Calendar.MILLISECOND, 0);
return cal.getTime();
}
}

@ -71,9 +71,6 @@
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
<bean id="applicationPeriodFacade" class="se.su.dsv.scipro.match.facade.ApplicationPeriodFacade">
</bean>
<bean id="projectIdeaDao" class="se.su.dsv.scipro.match.dao.jpa.ProjectIdeaDaoJPAImp">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>

@ -79,25 +79,13 @@ public class TestSupervisorDao {
@Autowired
private ProjectIdeaDao projectIdeaDao;
@Autowired
private ApplicationPeriodFacade applicationPeriodFacade;
private User user1;
private KeywordType standard;
private KeywordType other;
private Keyword key1;
private Keyword key2;
private KeywordType unit;
private Keyword key3;
private Set<Keyword> keywords;
private ProjectClass bachelor;
private ApplicationPeriod applicationPeriod;
private User user2;
private ProjectClass master;
@ -109,14 +97,6 @@ public class TestSupervisorDao {
private HashSet<Language> swedishSet;
private User user3;
private Username username1;
private Username username2;
private Username username3;
private Employee supervisor1;
private Employee supervisor2;
@ -126,12 +106,9 @@ public class TestSupervisorDao {
private User user4;
private User student1;
private Role student1Role;
private ProjectIdea projectIdea1;
private Student student1Author;
private ProjectIdea projectIdea2;
private ProjectIdea projectIdea3;
@ -144,7 +121,7 @@ public class TestSupervisorDao {
user1.setFirstName("User 1");
user1 = userDao.save(user1);
username1 = new Username();
Username username1 = new Username();
username1.setUser(user1);
username1.setUserName("User1");
username1.setRealm("dsv");
@ -154,11 +131,11 @@ public class TestSupervisorDao {
supervisor1.setUser(user1);
supervisor1 = (Employee) roleDao.save(supervisor1);
user2 = new User();
User user2 = new User();
user2.setFirstName("User 2");
user2 = userDao.save(user2);
username2 = new Username();
Username username2 = new Username();
username2.setUser(user2);
username2.setUserName("User2");
username2.setRealm("dsv");
@ -168,7 +145,7 @@ public class TestSupervisorDao {
supervisor2.setUser(user2);
supervisor2 = (Employee) roleDao.save(supervisor2);
user3 = new User();
User user3 = new User();
user3.setFirstName("Usa 3");
user3 = userDao.save(user3);
@ -176,11 +153,11 @@ public class TestSupervisorDao {
user4.setFirstName("sra 4");
user4 = userDao.save(user4);
username3 = new Username();
Username username3 = new Username();
username3.setUser(user3);
username3.setUserName("Usa 3");
username3.setRealm("dsv");
username3 = userNameDao.save(username3);
userNameDao.save(username3);
supervisor3 = new Employee();
supervisor3.setUser(user3);
@ -190,11 +167,11 @@ public class TestSupervisorDao {
student1.setFirstName("Student 1");
student1 = userDao.save(student1);
student1Role = new Student();
Role student1Role = new Student();
student1Role.setUser(student1);
student1Role = roleDao.save(student1Role);
student1Author = (Student) student1Role;
Student student1Author = (Student) student1Role;
swedish = new Language("Svenska");
swedish = languageDao.save(swedish);
@ -209,18 +186,18 @@ public class TestSupervisorDao {
swedishSet = new HashSet<Language>();
swedishSet.add(swedish);
standard = new KeywordType("standard");
KeywordType standard = new KeywordType("standard");
standard = keywordTypeDao.save(standard);
other = new KeywordType("other");
KeywordType other = new KeywordType("other");
other = keywordTypeDao.save(other);
unit = new KeywordType("unit");
KeywordType unit = new KeywordType("unit");
unit = keywordTypeDao.save(unit);
key1 = new Keyword("key 1", standard);
key2 = new Keyword("key 2", other);
key3 = new Keyword("key 3", unit);
Keyword key1 = new Keyword("key 1", standard);
Keyword key2 = new Keyword("key 2", other);
Keyword key3 = new Keyword("key 3", unit);
keywords = new HashSet<Keyword>();
keywords.add(key1);
@ -236,8 +213,8 @@ public class TestSupervisorDao {
"Master degree thesis project");
master = projectClassDao.save(master);
applicationPeriod = new ApplicationPeriod("appl");
applicationPeriod = applicationPeriodDao.save(applicationPeriod);
ApplicationPeriod applicationPeriod = new ApplicationPeriod("appl");
applicationPeriodDao.save(applicationPeriod);
projectIdea1 = new ProjectIdea();
projectIdea1.setTitle("Project idea 1");
@ -270,7 +247,7 @@ public class TestSupervisorDao {
supervisor.getKeywords().setKeywords(keywords);
try {
supervisor = target.save(supervisor);
target.save(supervisor);
Assert.fail();
} catch (Exception e) {
@ -637,185 +614,6 @@ public class TestSupervisorDao {
availability);
}
/* the same project classes, the same date, the first period: 10.00 - 11.59,
the second period: 12.00 - 13.59,
should NOT overlap. */
@Test
@Transactional
@Rollback
public void notOverlappingBasedOnTimeLimits() {
Set<ProjectClass> myBachelorSet = new HashSet<ProjectClass>();
myBachelorSet.add(bachelor);
applicationPeriodDao.save(createApplicationPeriod(myBachelorSet, createStartDate_1(), createEndDate_1()));
boolean periodOverlap = applicationPeriodFacade.doesPeriodOverlap(createApplicationPeriod(myBachelorSet, createStartDate_2(), createEndDate_2()));
Assert.assertFalse(periodOverlap); // should NOT overlap
}
/* the same project classes, the date of the first time period ends when the date of the second time period starts, should NOT overlap */
@Test
@Transactional
@Rollback
public void notOverlappingBasedOnDatePeriods() {
Set<ProjectClass> myBachelorSet = new HashSet<ProjectClass>();
myBachelorSet.add(bachelor);
Calendar cal = Calendar.getInstance();
cal.set(2012, Calendar.MARCH, 2);
final Date startDate1 = cal.getTime();
cal.set(2012, Calendar.APRIL, 2);
final Date endDate1 = cal.getTime();
applicationPeriodDao.save(createApplicationPeriod(myBachelorSet, startDate1, endDate1));
cal.set(2012, Calendar.MAY, 2);
final Date endDate2 = cal.getTime();
boolean periodOverlap = applicationPeriodFacade.doesPeriodOverlap(createApplicationPeriod(myBachelorSet, endDate1, endDate2));
Assert.assertFalse(periodOverlap); // should NOT overlap
}
/* the same project classes, first create an application period and save it,
then try to edit the period, it should NOT overlap even if the start or end date and/or project class are the same (as the data of the saved period) */
@Test
@Transactional
@Rollback
public void notOverlappingWhenUpdating() {
Set<ProjectClass> myBachelorSet = new HashSet<ProjectClass>();
myBachelorSet.add(bachelor);
Calendar cal = Calendar.getInstance();
cal.set(2012, Calendar.MARCH, 2);
final Date startDate1 = cal.getTime();
cal.set(2012, Calendar.APRIL, 2);
final Date endDate1 = cal.getTime();
ApplicationPeriod applicationPeriod1 = applicationPeriodDao.save(createApplicationPeriod(myBachelorSet, startDate1, endDate1));
applicationPeriod1.getProjectClass().add(master);
cal.set(2012, Calendar.MAY, 2);
final Date changedEndDate = cal.getTime();
applicationPeriod1.setEndDate(changedEndDate);
boolean periodOverlap = applicationPeriodFacade.doesPeriodOverlap(applicationPeriod1);
Assert.assertFalse(periodOverlap); // should NOT overlap
}
/* same time periods, with different project classes, should NOT overlap */
@Test
@Transactional
@Rollback
public void notOverlappingDifferentProjectClasses() {
Set<ProjectClass> myBachelorSet = new HashSet<ProjectClass>();
myBachelorSet.add(bachelor);
Calendar cal = Calendar.getInstance();
cal.set(2012, Calendar.MARCH, 2);
final Date startDate = cal.getTime();
cal.set(2012, Calendar.APRIL, 2);
final Date endDate = cal.getTime();
applicationPeriodDao.save(createApplicationPeriod(myBachelorSet, startDate, endDate));
Set<ProjectClass> myMasterSet = new HashSet<ProjectClass>();
myMasterSet.add(master);
boolean periodOverlap = applicationPeriodFacade.doesPeriodOverlap(createApplicationPeriod(myMasterSet, startDate, endDate));
Assert.assertFalse(periodOverlap); // should NOT overlap
}
/* one long time period, with same project classes, shorter time periods within this long time period should overlap */
@Test
@Transactional
@Rollback
public void overlappingPeriods() {
Set<ProjectClass> myBachelorSet = new HashSet<ProjectClass>();
myBachelorSet.add(bachelor);
Calendar cal = Calendar.getInstance();
cal.set(2012, Calendar.MARCH, 2);
final Date startDate1 = cal.getTime();
cal.set(2012, Calendar.DECEMBER, 2);
final Date endDate1 = cal.getTime();
applicationPeriodDao.save(createApplicationPeriod(myBachelorSet, startDate1, endDate1));
cal.set(2012, Calendar.MAY, 2);
final Date startDate2 = cal.getTime();
cal.set(2012, Calendar.JUNE, 2);
final Date endDate2 = cal.getTime();
boolean periodOverlap = applicationPeriodFacade.doesPeriodOverlap(createApplicationPeriod(myBachelorSet, startDate2, endDate2));
Assert.assertTrue(periodOverlap); // should overlap
}
/* same time periods, with same project classes, should overlap */
@Test
@Transactional
@Rollback
public void overlappingSameProjectClasses() {
Set<ProjectClass> myBachelorSet = new HashSet<ProjectClass>();
myBachelorSet.add(bachelor);
Calendar cal = Calendar.getInstance();
cal.set(2012, Calendar.MARCH, 2);
final Date startDate = cal.getTime();
cal.set(2012, Calendar.APRIL, 2);
final Date endDate = cal.getTime();
applicationPeriodDao.save(createApplicationPeriod(myBachelorSet, startDate, endDate));
boolean periodOverlap = applicationPeriodFacade.doesPeriodOverlap(createApplicationPeriod(myBachelorSet, startDate, endDate));
Assert.assertTrue(periodOverlap); // should overlap
}
/* the same time periods, with different sets of project classes, but when one of the project classes overlaps, should overlap */
@Test
@Transactional
@Rollback
public void overlappingMultipleProjectClasses() {
Set<ProjectClass> myBachelorSet = new HashSet<ProjectClass>();
myBachelorSet.add(bachelor);
Calendar cal = Calendar.getInstance();
cal.set(2012, Calendar.MARCH, 2);
final Date startDate = cal.getTime();
cal.set(2012, Calendar.APRIL, 2);
final Date endDate = cal.getTime();
applicationPeriodDao.save(createApplicationPeriod(myBachelorSet, startDate, endDate));
Set<ProjectClass> multipleProjectClasses = new HashSet<ProjectClass>();
multipleProjectClasses.add(bachelor);
multipleProjectClasses.add(master);
boolean periodOverlap = applicationPeriodFacade.doesPeriodOverlap(createApplicationPeriod(multipleProjectClasses, startDate, endDate));
Assert.assertTrue(periodOverlap); // should overlap
}
private ApplicationPeriod createApplicationPeriod(final Set<ProjectClass> projectClassSet, final Date startDate, final Date endDate) {
ApplicationPeriod appPeriod = new ApplicationPeriod();
appPeriod.setStartDate(startDate);
appPeriod.setEndDate(endDate);
appPeriod.setProjectClass(projectClassSet);
return appPeriod;
}
Date createStartDate_1() {
Calendar cal = Calendar.getInstance();
cal.set(Calendar.HOUR_OF_DAY, 10);
cal.set(Calendar.MINUTE, 0);
cal.set(Calendar.SECOND, 0);
cal.set(Calendar.MILLISECOND, 0);
return cal.getTime();
}
Date createEndDate_1() {
Calendar cal = Calendar.getInstance();
cal.set(Calendar.HOUR_OF_DAY, 11);
cal.set(Calendar.MINUTE, 59);
cal.set(Calendar.SECOND, 59);
cal.set(Calendar.MILLISECOND, 0);
return cal.getTime();
}
Date createStartDate_2() {
Calendar cal = Calendar.getInstance();
cal.set(Calendar.HOUR_OF_DAY, 12);
cal.set(Calendar.MINUTE, 0);
cal.set(Calendar.SECOND, 0);
cal.set(Calendar.MILLISECOND, 0);
return cal.getTime();
}
Date createEndDate_2() {
Calendar cal = Calendar.getInstance();
cal.set(Calendar.HOUR_OF_DAY, 13);
cal.set(Calendar.MINUTE, 59);
cal.set(Calendar.SECOND, 0);
cal.set(Calendar.MILLISECOND, 0);
return cal.getTime();
}
}

@ -62,56 +62,47 @@ public class TestProjectIdea {
@Autowired
private KeywordTypeDao keywordTypeDao;
private User user;
private Project project;
private ProjectClass projectClass;
private Role role;
private ProjectSchedule projectSchedule;
private ProjectIdea target;
private KeywordType standard;
private KeywordType other;
private Keyword key1;
private Keyword key2;
private KeywordType unit;
private Keyword key3;
@Before
public void startTransaction() {
user = new User();
User user = new User();
user = userDao.save(user);
role = new Student();
Role role = new Student();
role.setUser(user);
role = roleDao.save(role);
projectClass =
new ProjectClass(ProjectClass.BACHELOR, "Bachelor",
ProjectClass projectClass = new ProjectClass(ProjectClass.BACHELOR, "Bachelor",
"Bachelor degree thesis project");
projectClass = projectClassDao.save(projectClass);
project = new Project();
Project project = new Project();
project.setTitle("SomeProject");
project.setProjectClass(projectClass);
project.addProjectParticipant((Student) role);
project = projectDao.save(project);
projectSchedule = new ProjectSchedule();
ProjectSchedule projectSchedule = new ProjectSchedule();
projectSchedule.setProject(project);
projectSchedule = projectScheduleDao.save(projectSchedule);
project.setProjectSchedule(projectSchedule);
ApplicationPeriod applicationPeriod = new ApplicationPeriod("appl");
applicationPeriod = applicationPeriodDao.save(applicationPeriod);
applicationPeriodDao.save(applicationPeriod);
standard = new KeywordType("standard");
KeywordType standard = new KeywordType("standard");
standard = keywordTypeDao.save(standard);
other = new KeywordType("other");
other = keywordTypeDao.save(other);
unit = new KeywordType("unit");
KeywordType unit = new KeywordType("unit");
unit = keywordTypeDao.save(unit);
target = new ProjectIdea();
@ -119,7 +110,7 @@ public class TestProjectIdea {
target.setProjectClass(projectClass);
key1 = new Keyword("key 1", standard);
key2 = new Keyword("key 2", other);
key3 = new Keyword("key 3", unit);
Keyword key3 = new Keyword("key 3", unit);
}

@ -246,13 +246,13 @@ public class TestWicketPages extends BaseWicketTest {
// tester.assertRenderedPage(ProjectIdeaPage.class);
// }
@Test
/* @Test
public void testProjectIdeaSubmissionPage() {
Mockito.when(keywordTypeDao.findByType(KeywordTypeDao.TYPE.RESEARCH_AREA)).thenReturn(new KeywordType());
Mockito.when(keywordTypeDao.findByType(KeywordTypeDao.TYPE.REGULAR)).thenReturn(new KeywordType());
tester.startPage(ProjectIdeaSubmissionPage.class);
tester.assertRenderedPage(ProjectIdeaSubmissionPage.class);
}
}*/
@Test
public void testInternalErrorPage() {