Merge branch 'm3_supervisor_project_ideas' into develop

This commit is contained in:
Emil Siverhall 2012-07-26 10:39:09 +02:00
commit 98f58cc4f2
68 changed files with 3010 additions and 79 deletions
resources/db_update_scripts
src
main/java/se/su/dsv/scipro
SciProApplication.java
admin/pages/match
components/menuhighlighting
data/dataobjects
datatables
io/facade
match
project
springdata
supervisor
test/java/se/su/dsv/scipro

@ -0,0 +1,74 @@
CREATE TABLE `supervisoridea` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`dateCreated` datetime NOT NULL,
`lastModified` datetime NOT NULL,
`version` int(11) NOT NULL,
`title` varchar(255) NOT NULL,
`practicalHow` varchar(4000) NOT NULL,
`theoryHow` varchar(4000) NOT NULL,
`what` varchar(4000) NOT NULL,
`why` varchar(4000) NOT NULL,
`creator_id` bigint(20) NOT NULL,
`project_id` bigint(20) DEFAULT NULL,
`projectClass_id` bigint(20) NOT NULL,
`applicationPeriod_id` bigint(20) NOT NULL,
`description` varchar(4000) NOT NULL,
`requirements` varchar(1024) NOT NULL,
`ideaStatus` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `IDEAPROJECTKEY` (`project_id`),
KEY `IDEAPROJECTCLASSKEY` (`projectClass_id`),
KEY `IDEAPERIODKEY` (`applicationPeriod_id`),
KEY `IDEACREATORKEY` (`creator_id`),
CONSTRAINT `IDEAPROJECTCLASSKEY` FOREIGN KEY (`projectClass_id`) REFERENCES `project_class` (`id`),
CONSTRAINT `IDEAPERIODKEY` FOREIGN KEY (`applicationPeriod_id`) REFERENCES `applicationperiod` (`id`),
CONSTRAINT `IDEAPROJECTKEY` FOREIGN KEY (`project_id`) REFERENCES `project` (`id`),
CONSTRAINT `IDEACREATORKEY` FOREIGN KEY (`creator_id`) REFERENCES `role` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
CREATE TABLE `supervisoridea_keyword` (
`supervisoridea_id` bigint(20) NOT NULL,
`keywords_id` bigint(20) NOT NULL,
PRIMARY KEY (`supervisoridea_id`,`keywords_id`),
KEY `supervisoridea_keyword_key` (`supervisoridea_id`),
KEY `supervisoridea_keyword_key2` (`keywords_id`),
CONSTRAINT `supervisoridea_keyword_key` FOREIGN KEY (`supervisoridea_id`) REFERENCES `supervisoridea` (`id`),
CONSTRAINT `supervisoridea_keyword_key2` FOREIGN KEY (`keywords_id`) REFERENCES `keyword` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
CREATE TABLE `idea_student` (
`role_id` bigint(20) NOT NULL,
`supervisoridea_id` bigint(20) NOT NULL,
`confirmed` bit(1) NOT NULL,
PRIMARY KEY (`role_id`,`supervisoridea_id`),
KEY `fk_role_id` (`role_id`),
KEY `fk_supervisoridea_id` (`supervisoridea_id`),
CONSTRAINT `fk_role_id` FOREIGN KEY (`role_id`) REFERENCES `role` (`id`),
CONSTRAINT `fk_supervisoridea_id` FOREIGN KEY (`supervisoridea_id`) REFERENCES `supervisoridea` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
ALTER TABLE `applicationperiod` ADD `courseStartDate` datetime NOT NULL;
CREATE TABLE `researcharea` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`dateCreated` datetime NOT NULL,
`lastModified` datetime NOT NULL,
`identifier` bigint(20) DEFAULT NULL,
`title` varchar(255) NOT NULL,
`version` int(4) NOT NULL DEFAULT '0',
`deleted` bit(1) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `identifier` (`identifier`),
KEY `deleted_index` (`deleted`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
CREATE TABLE `employee_researcharea` (
`role_id` bigint(20) NOT NULL,
`researchAreas_id` bigint(20) NOT NULL,
PRIMARY KEY (`role_id`,`researchAreas_id`),
KEY `employee_researcharea_key` (`role_id`),
KEY `employee_researcharea_key2` (`researchAreas_id`),
CONSTRAINT `employee_researcharea_key` FOREIGN KEY (`role_id`) REFERENCES `role` (`id`),
CONSTRAINT `employee_researcharea_key2` FOREIGN KEY (`researchAreas_id`) REFERENCES `researcharea` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

@ -180,7 +180,7 @@ public class SciProApplication extends RepositoryApplication implements IThemabl
mountBookmarkablePage("noproject", NoActiveProjectPage.class);
mountBookmarkablePage("project/checklist", ProjectChecklistPage.class);
mountBookmarkablePage("project/checklist/viewchecklist", ProjectViewCheckListPage.class);
mountBookmarkablePage("projectideas", ProjectIdeaPage.class);
mountBookmarkablePage("projectideas", MyProjectIdeasPage.class);
mountBookmarkablePage("projectideas/submit", ProjectIdeaSubmissionPage.class);
/*
* Supervisor pages

@ -13,6 +13,7 @@
<tr>
<th class="rounded-left-top">Start</th>
<th>End</th>
<th>Course start</th>
<th>Project types</th>
<th>Name</th>
<th>Edit</th>
@ -21,13 +22,14 @@
</thead>
<tfoot>
<tr>
<td colspan="6" class="rounded-foot">&nbsp;</td>
<td colspan="7" class="rounded-foot">&nbsp;</td>
</tr>
</tfoot>
<tbody>
<tr wicket:id="repeatingView">
<td><span wicket:id="startDate"></span></td>
<td><span wicket:id="endDate"></span></td>
<td><span wicket:id="courseStartDate"></span></td>
<td><span wicket:id="type"></span></td>
<td><span wicket:id="name"></span></td>
<td><a href=# wicket:id="editLink"><img wicket:id="editIcon" alt="" /></a></td>

@ -89,6 +89,7 @@ public class AdminMatchPeriodsPanel extends Panel {
final ApplicationPeriod appPeriod = item.getModelObject();
item.add(new DateFormatter(DateFormatter.FORMAT.EXTENDED).createFormattedDateLabel("startDate", appPeriod.getStartDate()));
item.add(new DateFormatter(DateFormatter.FORMAT.EXTENDED).createFormattedDateLabel("endDate", appPeriod.getEndDate()));
item.add(new DateFormatter(DateFormatter.FORMAT.EXTENDED).createFormattedDateLabel("courseStartDate", appPeriod.getCourseStartDate()));
item.add(new Label("type",appPeriod.getProjectClass().toString()));
item.add(new Label("name",appPeriod.getName()));
final boolean linksAreEnabled = !applicationPeriodFacade.projectIdeasExists(appPeriod);

@ -0,0 +1,9 @@
package se.su.dsv.scipro.components.menuhighlighting;
/**
* Used to highlight hierarchy for My Projects in Supervisor view.
*
*/
public interface MenuHighlightSupervisorProjectIdea extends MenuHighlight {
}

@ -8,7 +8,6 @@ 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;
@ -21,7 +20,6 @@ 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;
/**
@ -61,6 +59,10 @@ public class Employee extends ProjectTeamMember {
@AssociationOverride(name="keywords", joinTable=@JoinTable(name="Employee_Keyword"))
private Keywords keywords = new Keywords();
@ManyToMany
@JoinTable(name="employee_researcharea")
private Set<ResearchArea> researchAreas = new HashSet<ResearchArea>();
public Keywords getKeywords() {
return keywords;
}
@ -114,7 +116,24 @@ public class Employee extends ProjectTeamMember {
return true;
}
private static final long serialVersionUID = -2570983581219033271L;
public void setResearchAreas(Set<ResearchArea> researchAreas) {
this.researchAreas = researchAreas;
}
public Set<ResearchArea> getResearchAreas() {
return researchAreas;
}
public Set<ResearchArea> getActiveResearchAreas() {
Set<ResearchArea> activeAreas = new HashSet<ResearchArea>();
for(ResearchArea area : getResearchAreas()){
if(!area.isDeleted())
activeAreas.add(area);
}
return activeAreas;
}
private static final long serialVersionUID = -2570983581219033271L;
@Embeddable
public static class Capabilities implements Serializable {

@ -0,0 +1,54 @@
package se.su.dsv.scipro.data.dataobjects;
import org.hibernate.annotations.Cache;
import org.hibernate.annotations.CacheConcurrencyStrategy;
import se.su.dsv.scipro.dataproviders.SortableField;
import javax.persistence.*;
@Entity
@Table(name="researcharea")
@Cacheable(true)
@Cache(usage= CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
public class ResearchArea extends LazyDeletableDomainObject {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue
private Long id;
@Column(unique=true)
private Long identifier;
@Column(length=255)
@Basic(optional=false)
@SortableField
private String title;
public ResearchArea(){}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public Long getIdentifier() {
return identifier;
}
public void setIdentifier(Long identifier) {
this.identifier = identifier;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
}

@ -1,9 +1,12 @@
package se.su.dsv.scipro.data.dataobjects;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import javax.persistence.Cacheable;
import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.JoinTable;
@ -14,6 +17,7 @@ import org.hibernate.annotations.Cache;
import org.hibernate.annotations.CacheConcurrencyStrategy;
import se.su.dsv.scipro.match.dataobject.Exemption;
import se.su.dsv.scipro.match.dataobject.IdeaParticipation;
/**
* @author Martin Peters - mpeters@se.su.dsv
@ -30,6 +34,9 @@ public class Student extends Role {
@JoinTable(name = "Student_Exemption")
private Map<ProjectClass, Exemption> exemptions = new HashMap<ProjectClass, Exemption>();
@OneToMany(fetch = FetchType.LAZY, mappedBy = "pk.student", cascade=CascadeType.ALL, orphanRemoval=true)
private Set<IdeaParticipation> ideaParticipations = new HashSet<IdeaParticipation>();
@Override
public int hashCode() {
final int prime = 31;
@ -98,4 +105,20 @@ public class Student extends Role {
}
}
public void setIdeaParticipations(Set<IdeaParticipation> ideaParticipations) {
this.ideaParticipations = ideaParticipations;
}
public Set<IdeaParticipation> getIdeaParticipations() {
return ideaParticipations;
}
public void addIdeaParticipation(IdeaParticipation ip){
this.ideaParticipations.add(ip);
}
public void removeIdeaParticipation(IdeaParticipation ip){
this.ideaParticipations.remove(ip);
}
}

@ -39,6 +39,14 @@ public abstract class ClickableIconColumn<T> extends AbstractColumn<T> {
protected abstract void onClick(IModel<T> clicked, AjaxRequestTarget target);
/**
* Override this if you want to customize the visibility of the icon.
* e.g. the case where you wnat some specific rows editable based on certain conditions.
*/
public boolean shouldBeVisible(IModel<T> rowModel) {
return true;
}
private class LinkPanel extends Panel {
public LinkPanel(String id, IModel<T> rowModel, IModel<?>
labelModel, String iconString) {
@ -52,6 +60,7 @@ public abstract class ClickableIconColumn<T> extends AbstractColumn<T> {
};
add(link);
link.add(new ImageObject("deleteicon", ImageObject.SIXTEEN + iconString));
link.setVisible(shouldBeVisible(rowModel));
}
}
}

@ -44,6 +44,7 @@ import se.su.dsv.scipro.match.dao.interfaces.KeywordTypeDao;
import se.su.dsv.scipro.match.dao.interfaces.SupervisorDao;
import se.su.dsv.scipro.match.dataobject.Keyword;
import se.su.dsv.scipro.springdata.services.MessageBoardService;
import se.su.dsv.scipro.springdata.services.ResearchAreaService;
import se.su.dsv.scipro.springdata.services.UnitService;
/**
@ -55,7 +56,8 @@ public class ImporterFacade {
@Autowired
private UnitService unitService;
@Autowired
private ResearchAreaService researchAreaService;
@Autowired
private UserDao userDao;
@Autowired
@ -543,32 +545,34 @@ public class ImporterFacade {
private void mergeLinkedResearchAreas(final User user, final Set<ResearchAreaDTO> areas) {
for (final ResearchAreaDTO researchAreaDTO : areas) {
Keyword area = keywordDao.getKeywordByIdentifierAndType(researchAreaDTO.id, keywordTypeDao.findByType(KeywordTypeDao.TYPE.RESEARCH_AREA));
if (area == null) {
//Keyword area = keywordDao.getKeywordByIdentifierAndType(researchAreaDTO.id, keywordTypeDao.findByType(KeywordTypeDao.TYPE.RESEARCH_AREA));
ResearchArea area = researchAreaService.findByIdentifier(researchAreaDTO.id);
if (area == null) {
logger.info("External research area: '" + researchAreaDTO + "' has no local representation, creating");
area = new Keyword(researchAreaDTO.name, keywordTypeDao.findByType(KeywordTypeDao.TYPE.RESEARCH_AREA));
area = new ResearchArea();
area.setTitle(researchAreaDTO.name);
area.setIdentifier(researchAreaDTO.id);
area = keywordDao.save(area);
area = researchAreaService.save(area);
} else {
logger.info("Research area " + area.getKeyword() + " already exists, skipping");
logger.info("Research area " + area.getTitle() + " already exists, skipping");
}
addResearchAreaToUser(user, area);
}
}
private void addResearchAreaToUser(User user, Keyword area) {
private void addResearchAreaToUser(User user, ResearchArea area) {
Employee supervisor = supervisorDao.getFrom(user);
logger.info("Adding research area: " + area.getKeyword() + " to supervisor " + supervisor.getUser().getFullName());
supervisor.getKeywords().getAll().add(area);
logger.info("Adding research area: " + area.getTitle() + " to supervisor " + supervisor.getUser().getFullName());
supervisor.getResearchAreas().add(area);
}
@Transactional
public void addUnexistingResearchAreas(final Set<ResearchAreaDTO> areas) {
final Set<Keyword> currentAreas = keywordDao.getKeywords(keywordTypeDao.findByType(KeywordTypeDao.TYPE.RESEARCH_AREA), true);
final Set<ResearchArea> currentAreas = researchAreaService.findAllAsSet();
final Set<ResearchAreaDTO> remoteAreas = new HashSet<ResearchAreaDTO>(areas);
final Set<Keyword> areasToRemove = new HashSet<Keyword>();
final Set<ResearchArea> areasToRemove = new HashSet<ResearchArea>();
//Compare remote with database
for (Keyword currentArea : currentAreas) {
for (ResearchArea currentArea : currentAreas) {
ResearchAreaDTO translatedArea = dtoFromAreaKeyword(currentArea);
if (!remoteAreas.contains(translatedArea)) {
logger.info("Area " + translatedArea.getName() + " does not exist on remote, preparing to remove.");
@ -576,26 +580,27 @@ public class ImporterFacade {
}
}
//Delete areas that not exist on remote
for (Keyword areaToRemove : areasToRemove) {
keywordDao.delete(areaToRemove);
logger.debug("Deleted research area: " + areaToRemove.getKeyword() + " since it has been removed from remote system");
for (ResearchArea areaToRemove : areasToRemove) {
researchAreaService.deleteArea(areaToRemove);
logger.info("Deleted research area: " + areaToRemove.getTitle() + " since it has been removed from remote system");
}
//Add areas to database
for (final ResearchAreaDTO researchAreaDTO : remoteAreas) {
Keyword area = keywordDao.getKeywordByIdentifierAndType(researchAreaDTO.id, keywordTypeDao.findByType(KeywordTypeDao.TYPE.RESEARCH_AREA));
ResearchArea area = researchAreaService.findByIdentifier(researchAreaDTO.id);
if (area == null) {
logger.info("External research area: '" + researchAreaDTO + "' has no local representation, creating");
area = new Keyword(researchAreaDTO.name, keywordTypeDao.findByType(KeywordTypeDao.TYPE.RESEARCH_AREA));
area = new ResearchArea();
area.setTitle(researchAreaDTO.name);
area.setIdentifier(researchAreaDTO.id);
area = keywordDao.save(area);
} else if (!area.getKeyword().equals(researchAreaDTO.name)) {
logger.info("Research area " + area.getKeyword() + " has changed name, renaming to: " + researchAreaDTO.name);
area.setKeyword(researchAreaDTO.name);
area = researchAreaService.save(area);
} else if (!area.getTitle().equals(researchAreaDTO.name)) {
logger.info("Research area " + area.getTitle() + " has changed name, renaming to: " + researchAreaDTO.name);
area.setTitle(researchAreaDTO.name);
} else {
logger.info("Research area " + area.getKeyword() + " already exists, skipping");
logger.info("Research area " + area.getTitle() + " already exists, skipping");
}
if (researchAreaDTO.active.equals("false")) {
logger.info(area.getKeyword() + " is inactivated on remote system.");
logger.info(area.getTitle() + " is inactivated on remote system.");
area.setDeleted(true);
}
}
@ -669,13 +674,7 @@ public class ImporterFacade {
}
}
private UnitDTO dtoFromUnitKeyword(final Keyword unit) {
UnitDTO dto = new UnitDTO();
dto.setName(unit.getKeyword());
if (unit.getIdentifier() != null)
dto.setId(unit.getIdentifier());
return dto;
}
private UnitDTO dtoFromUnit(final Unit unit) {
UnitDTO dto = new UnitDTO();
@ -685,9 +684,9 @@ public class ImporterFacade {
return dto;
}
private ResearchAreaDTO dtoFromAreaKeyword(final Keyword area) {
private ResearchAreaDTO dtoFromAreaKeyword(final ResearchArea area) {
ResearchAreaDTO dto = new ResearchAreaDTO();
dto.setName(area.getKeyword());
dto.setName(area.getTitle());
if (area.getIdentifier() != null)
dto.setId(area.getIdentifier());
return dto;

@ -38,6 +38,9 @@ public class ApplicationPeriod extends DomainObject {
@NotNull
private Date endDate;
@NotNull
private Date courseStartDate;
public ApplicationPeriod() {
}
@ -85,4 +88,12 @@ public class ApplicationPeriod extends DomainObject {
public void setProjectClass(Set<ProjectClass> projectClass) {
this.projectClass = projectClass;
}
public void setCourseStartDate(Date courseStartDate) {
this.courseStartDate = courseStartDate;
}
public Date getCourseStartDate() {
return courseStartDate;
}
}

@ -0,0 +1,167 @@
package se.su.dsv.scipro.match.dataobject;
import java.util.HashSet;
import java.util.Set;
import javax.persistence.Column;
import javax.persistence.Embedded;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.FetchType;
import javax.persistence.ManyToMany;
import javax.persistence.ManyToOne;
import javax.persistence.MappedSuperclass;
import javax.persistence.OneToMany;
import javax.persistence.OneToOne;
import se.su.dsv.scipro.data.dataobjects.DomainObject;
import se.su.dsv.scipro.data.dataobjects.Project;
import se.su.dsv.scipro.data.dataobjects.ProjectClass;
import se.su.dsv.scipro.dataproviders.SortableField;
import com.mysema.query.annotations.QueryInit;
@MappedSuperclass
public abstract class Idea extends DomainObject {
private static final long serialVersionUID = -2016847385026874488L;
@ManyToOne(optional = false)
@SortableField
private ProjectClass projectClass;
@OneToMany(fetch = FetchType.EAGER, mappedBy = "pk.supervisorIdea")
@QueryInit("ideaParticipations.pk.student")
private Set<IdeaParticipation> ideaParticipations = new HashSet<IdeaParticipation>();
@ManyToOne(optional = true)
private ApplicationPeriod applicationPeriod;
@Column(nullable = false, length = 1024)
private String title;
@Embedded
private Watson watson = new Watson();
@ManyToMany(fetch=FetchType.EAGER)
private Set<Keyword> keywords = new HashSet<Keyword>();
@OneToOne
private Project project;
/**
* Status explanations:
*
* WAITING: Idea created by supervisor, waiting to be taken by authors
* TAKEN: Waiting idea that's been taken by author(s)
* AUTHOR_CREATED: Idea submitted by author, waiting for supervisor
* COMPLETED: Idea that has turned in to a project
*
*/
public static enum IdeaStatus {
WAITING {
public String toString() {
return "Waiting";
}
},
TAKEN {
public String toString() {
return "Taken";
}
},
COMPLETED {
public String toString() {
return "Completed";
}
},
AUTHOR_CREATED {
public String toString() {
return "Author created";
}
}
}
@Enumerated(EnumType.STRING)
private IdeaStatus ideaStatus;
public ApplicationPeriod getApplicationPeriod() {
return applicationPeriod;
}
public void setApplicationPeriod(ApplicationPeriod applicationPeriod) {
this.applicationPeriod = applicationPeriod;
}
public ProjectClass getProjectClass() {
return projectClass;
}
public void setProjectClass(ProjectClass projectClass) {
this.projectClass = projectClass;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public Project getProject() {
return project;
}
public void setProject(Project project) {
this.project = project;
}
public Watson getWatson() {
return watson;
}
public void setWatson(Watson watson) {
this.watson = watson;
}
public void setIdeaStatus(IdeaStatus ideaStatus) {
this.ideaStatus = ideaStatus;
}
public IdeaStatus getIdeaStatus() {
return ideaStatus;
}
public void setKeywords(Set<Keyword> keywords) {
this.keywords = keywords;
}
public Set<Keyword> getKeywords() {
return keywords;
}
public void addKeyword(Keyword k){
this.keywords.add(k);
}
public void removeKeyword(Keyword k){
this.keywords.remove(k);
}
public void setIdeaParticipations(Set<IdeaParticipation> ideaParticipations) {
this.ideaParticipations = ideaParticipations;
}
public Set<IdeaParticipation> getIdeaParticipations() {
return ideaParticipations;
}
public void addIdeaParticipation(IdeaParticipation ip){
this.ideaParticipations.add(ip);
}
public void removeIdeaParticipation(IdeaParticipation ip){
this.ideaParticipations.remove(ip);
}
}

@ -0,0 +1,89 @@
package se.su.dsv.scipro.match.dataobject;
import java.io.Serializable;
import javax.persistence.AssociationOverride;
import javax.persistence.AssociationOverrides;
import javax.persistence.Column;
import javax.persistence.EmbeddedId;
import javax.persistence.Entity;
import javax.persistence.JoinColumn;
import javax.persistence.Table;
import javax.persistence.Transient;
import com.mysema.query.annotations.QueryInit;
import se.su.dsv.scipro.data.dataobjects.Student;
@Entity
@Table(name = "idea_student")
@AssociationOverrides({
@AssociationOverride(name = "pk.student",
joinColumns = @JoinColumn(name = "role_id")),
@AssociationOverride(name = "pk.supervisorIdea",
joinColumns = @JoinColumn(name = "supervisoridea_id")) })
public class IdeaParticipation implements Serializable {
private static final long serialVersionUID = 4973657879468781878L;
@EmbeddedId
@QueryInit("student")
private IdeaParticipationId pk = new IdeaParticipationId();
@Column(name = "confirmed")
private boolean confirmed;
public void setConfirmed(boolean confirmed) {
this.confirmed = confirmed;
}
public boolean isConfirmed() {
return confirmed;
}
public void setPk(IdeaParticipationId pk) {
this.pk = pk;
}
public IdeaParticipationId getPk() {
return pk;
}
@Transient
public Student getStudent() {
return getPk().getStudent();
}
public void setStudent(Student student) {
getPk().setStudent(student);
}
@Transient
public SupervisorIdea getSupervisorIdea() {
return getPk().getSupervisorIdea();
}
public void setSupervisorIdea(SupervisorIdea idea) {
getPk().setSupervisorIdea(idea);
}
public boolean equals(Object o) {
if (this == o)
return true;
if(o == null || getClass() != o.getClass())
return false;
IdeaParticipation idea = (IdeaParticipation) o;
if(getPk() != null ? !getPk().equals(idea.getPk()):idea.getPk()!=null)
return false;
return true;
}
public int hashCode() {
return (getPk()!=null?getPk().hashCode() : 0);
}
}

@ -0,0 +1,65 @@
package se.su.dsv.scipro.match.dataobject;
import java.io.Serializable;
import javax.persistence.Embeddable;
import javax.persistence.ManyToOne;
import se.su.dsv.scipro.data.dataobjects.Student;
@Embeddable
public class IdeaParticipationId implements Serializable {
private static final long serialVersionUID = -5669990817168826918L;
@ManyToOne
private Student student;
@ManyToOne
private SupervisorIdea supervisorIdea;
public void setStudent(Student student) {
this.student = student;
}
public Student getStudent() {
return student;
}
public void setSupervisorIdea(SupervisorIdea supervisorIdea) {
this.supervisorIdea = supervisorIdea;
}
public SupervisorIdea getSupervisorIdea() {
return supervisorIdea;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((student == null) ? 0 : student.hashCode());
result = prime * result
+ ((supervisorIdea == null) ? 0 : supervisorIdea.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;
IdeaParticipationId other = (IdeaParticipationId) obj;
if (student == null) {
if (other.student != null)
return false;
} else if (!student.equals(other.student))
return false;
if (supervisorIdea == null) {
if (other.supervisorIdea != null)
return false;
} else if (!supervisorIdea.equals(other.supervisorIdea))
return false;
return true;
}
}

@ -0,0 +1,112 @@
package se.su.dsv.scipro.match.dataobject;
import javax.persistence.Cacheable;
import javax.persistence.Column;
import javax.persistence.Embedded;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import org.hibernate.annotations.Cache;
import org.hibernate.annotations.CacheConcurrencyStrategy;
import se.su.dsv.scipro.data.dataobjects.Employee;
@Entity
@Table(name = "supervisoridea")
@Cacheable(true)
@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
public class SupervisorIdea extends Idea {
private static final long serialVersionUID = -2016847385026874488L;
@Id
@GeneratedValue
private Long id;
@ManyToOne(optional = false)
private Employee creator;
@Column(nullable = false, length = 1024)
private String description;
@Column(nullable = false, length = 1024)
private String requirements;
@Override
public Long getId() {
return id;
}
public void setCreator(Employee creator) {
this.creator = creator;
}
public Employee getCreator() {
return creator;
}
public void setDescription(String description) {
this.description = description;
}
public String getDescription() {
return description;
}
public void setRequirements(String requirements) {
this.requirements = requirements;
}
public String getRequirements() {
return requirements;
}
@Override
public int hashCode() {
final int prime = 31;
int result = super.hashCode();
result = prime * result + ((creator == null) ? 0 : creator.hashCode());
result = prime * result
+ ((description == null) ? 0 : description.hashCode());
result = prime * result + ((id == null) ? 0 : id.hashCode());
result = prime * result
+ ((requirements == null) ? 0 : requirements.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (!super.equals(obj))
return false;
if (getClass() != obj.getClass())
return false;
SupervisorIdea other = (SupervisorIdea) obj;
if (creator == null) {
if (other.creator != null)
return false;
} else if (!creator.equals(other.creator))
return false;
if (description == null) {
if (other.description != null)
return false;
} else if (!description.equals(other.description))
return false;
if (id == null) {
if (other.id != null)
return false;
} else if (!id.equals(other.id))
return false;
if (requirements == null) {
if (other.requirements != null)
return false;
} else if (!requirements.equals(other.requirements))
return false;
return true;
}
}

@ -133,6 +133,7 @@ public class ApplicationPeriodFacade {
.append("'").append(appPeriod.getName()).append("'")
.append(" Start date : '").append(new DateFormatter(DateFormatter.FORMAT.DEFAULT).createFormattedString(appPeriod.getStartDate())).append("'")
.append(" End date : '").append(new DateFormatter(DateFormatter.FORMAT.DEFAULT).createFormattedString(appPeriod.getEndDate())).append("'")
.append(" Course start date : '").append(new DateFormatter(DateFormatter.FORMAT.DEFAULT).createFormattedString(appPeriod.getCourseStartDate())).append("'")
.append(" Levels: '").append(projectClasses.toString()).append("'").toString();
}
@ -146,6 +147,8 @@ public class ApplicationPeriodFacade {
appPeriod.setStartDate(cal.getTime());
cal.add(Calendar.MONTH, 1);
appPeriod.setEndDate(cal.getTime());
cal.add(Calendar.MONTH, 1);
appPeriod.setCourseStartDate(cal.getTime());
appPeriod.setName(name);
return appPeriod;
}
@ -157,18 +160,21 @@ public class ApplicationPeriodFacade {
appPeriod.setStartDate(cal.getTime());
cal.add(Calendar.MONTH, 1);
appPeriod.setEndDate(cal.getTime());
cal.add(Calendar.MONTH, 1);
appPeriod.setCourseStartDate(cal.getTime());
appPeriod.setProjectClass(projectClassSet);
appPeriod.setName(name);
return applicationPeriodDao.save(appPeriod);
}
// @Transactional
public ApplicationPeriod createApplicationPeriodDates(final Set<ProjectClass> projectClassSet, final Date startDate, final Date endDate, final String name) {
public ApplicationPeriod createApplicationPeriodDates(final Set<ProjectClass> projectClassSet, final Date startDate, final Date endDate, final Date courseStartDate, final String name) {
Calendar cal = Calendar.getInstance();
ApplicationPeriod appPeriod = new ApplicationPeriod();
appPeriod.setStartDate(startDate);
cal.add(Calendar.MONTH, 1);
appPeriod.setEndDate(endDate);
appPeriod.setCourseStartDate(courseStartDate);
appPeriod.setProjectClass(projectClassSet);
appPeriod.setName(name);
return applicationPeriodDao.save(appPeriod);

@ -0,0 +1,22 @@
<!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>
<div wicket:id="container">
<label for="checkGroup">Filter on level</label>
<div wicket:id="checkGroup">
<div wicket:id="levelView">
<input type="checkbox" wicket:id="levelCheckBox"></input>
<span wicket:id="levelName"></span>
</div>
</div>
</div>
</wicket:panel>
</body>
</html>

@ -0,0 +1,76 @@
package se.su.dsv.scipro.match.panel;
import java.util.ArrayList;
import java.util.List;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.ajax.form.AjaxFormChoiceComponentUpdatingBehavior;
import org.apache.wicket.markup.html.WebMarkupContainer;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.form.Check;
import org.apache.wicket.markup.html.form.CheckGroup;
import org.apache.wicket.markup.html.list.ListItem;
import org.apache.wicket.markup.html.list.ListView;
import org.apache.wicket.markup.html.panel.Panel;
import org.apache.wicket.model.CompoundPropertyModel;
import org.apache.wicket.spring.injection.annot.SpringBean;
import se.su.dsv.scipro.data.dataobjects.ProjectClass;
import se.su.dsv.scipro.springdata.services.ProjectClassService;
public abstract class FilterFormProjectClass extends Panel {
private static final long serialVersionUID = 8862892008428526067L;
@SpringBean
private ProjectClassService projectClassService;
private List<ProjectClass> projectClassList;
private final CheckGroup<ProjectClass> checkGroup;
public FilterFormProjectClass(String id) {
super(id);
projectClassList = projectClassService.findAllActive();
CompoundPropertyModel<List<ProjectClass>> levelModel = new CompoundPropertyModel<List<ProjectClass>>(projectClassList);
checkGroup = new CheckGroup<ProjectClass>("checkGroup",new ArrayList<ProjectClass>(projectClassList));
final WebMarkupContainer container = new WebMarkupContainer("container");
container.setOutputMarkupId(true);
ListView<ProjectClass> levelView = new ListView<ProjectClass>("levelView", levelModel) {
private static final long serialVersionUID = 1L;
@Override
protected void populateItem(ListItem<ProjectClass> item) {
Check<ProjectClass> levelBox = new Check<ProjectClass>("levelCheckBox", item.getModel());
item.add(levelBox);
Label levelName = new Label("levelName", item.getModelObject().toString());
item.add(levelName);
}
};
checkGroup.add(levelView);
checkGroup.setOutputMarkupId(true);
checkGroup.add(new AjaxFormChoiceComponentUpdatingBehavior(){
private static final long serialVersionUID = 3198579482664645333L;
@Override
protected void onUpdate(AjaxRequestTarget target) {
ajaxUpdate(target);
}
});
container.add(checkGroup);
add(container);
}
public List<ProjectClass> getProjectClasses(){
return (List<ProjectClass>) checkGroup.getModelObject();
}
public abstract void ajaxUpdate(AjaxRequestTarget target);
}

@ -20,6 +20,9 @@
<tr>
<td>End date: <div wicket:id="endDate"></div></td>
</tr>
<tr>
<td>Course start date: <div wicket:id="courseStartDate"></div></td>
</tr>
<tr>
<td>Name: <input type="text" wicket:id="name"></td>
</tr>

@ -84,6 +84,7 @@ public class MatchPeriodEditPanel extends Panel {
add(new CustomDateTimeField("startDate", new PropertyModel<Date>(model.getObject(),"startDate")).setEnabled(isEditable()));
add(new CustomDateTimeField("endDate", new PropertyModel<Date>(model.getObject(),"endDate")).setEnabled(isEditable()));
add(new CustomDateTimeField("courseStartDate", new PropertyModel<Date>(model.getObject(),"courseStartDate")).setEnabled(isEditable()));
final TextField<String> nameField = new TextField<String>("name", new PropertyModel<String>(model.getObject(),"name"));
nameField.setRequired(true);
nameField.setEnabled(isEditable());
@ -106,6 +107,12 @@ public class MatchPeriodEditPanel extends Panel {
target.addComponent(feedbackPanel);
return;
}
if(appPeriod.getCourseStartDate().before(appPeriod.getEndDate())) {
error("The course start date cannot be before the application period ends.");
target.addComponent(feedbackPanel);
return;
}
appPeriod.setProjectClass(pClassesToSet);
boolean isEditing = appPeriod.getId() != null;

@ -0,0 +1,11 @@
<!DOCTYPE html>
<html xmlns:wicket="http://wicket.apache.org/dtds.data/wicket-xhtml1.4-strict.dtd">
<body>
<wicket:extend>
<div class="span-24 last append-bottom">
<div wicket:id="ideaSub"></div>
</div>
<wicket:child/>
</wicket:extend>
</body>
</html>

@ -0,0 +1,38 @@
package se.su.dsv.scipro.project.pages;
import javax.servlet.http.Cookie;
import org.apache.wicket.PageParameters;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.link.BookmarkablePageLink;
import org.apache.wicket.model.IModel;
import org.apache.wicket.protocol.http.WebRequest;
import org.apache.wicket.protocol.http.WebResponse;
import org.apache.wicket.spring.injection.annot.SpringBean;
import se.su.dsv.scipro.SciProSession;
import se.su.dsv.scipro.data.DomainObjectDetachableModel;
import se.su.dsv.scipro.data.dao.interfaces.ProjectDao;
import se.su.dsv.scipro.data.dataobjects.Project;
import se.su.dsv.scipro.project.panels.ProjectIdeaTabMenuPanel;
import se.su.dsv.scipro.project.panels.ProjectSubTabMenuPanel;
/**
*
* @author Martin Peters - mpeters@dsv.su.se
*
*/
public abstract class AbstractProjectIdeaPage extends ProjectPage {
public static final String COOKIE_KEY = "authorLastVisitedPID";
public AbstractProjectIdeaPage(PageParameters pp) {
super(pp);
/**
* This is the submenu
*/
add(new ProjectIdeaTabMenuPanel("ideaSub", this.getClass()));
}
}

@ -3,15 +3,15 @@ package se.su.dsv.scipro.project.pages;
import org.apache.wicket.PageParameters;
import org.apache.wicket.markup.html.panel.FeedbackPanel;
import se.su.dsv.scipro.components.menuhighlighting.MenuHighlightProjectIdeas;
import se.su.dsv.scipro.project.panels.MyProjectIdeasPanel;
import se.su.dsv.scipro.security.auth.Authorization;
import se.su.dsv.scipro.security.auth.roles.Roles;
//@Authorization(authorizedRoles={Roles.SYSADMIN})
@Authorization(authorizedRoles={Roles.STUDENT})
public class ProjectIdeaPage extends ProjectPage {
public class MyProjectIdeasPage extends AbstractProjectIdeaPage implements MenuHighlightProjectIdeas{
public ProjectIdeaPage(PageParameters pp) {
public MyProjectIdeasPage(PageParameters pp) {
super(pp);
add(new FeedbackPanel("feedback"));
add(new MyProjectIdeasPanel("myIdeasPanel", getUser()));

@ -0,0 +1,15 @@
<!DOCTYPE html>
<html xmlns:wicket="http://wicket.apache.org/dtds.data/wicket-xhtml1.4-strict.dtd">
<body>
<wicket:extend>
<div class="prepend-top span-24 last">
<div wicket:id="feedback"></div>
<div class="info-box rounded-box last">
Application period is open from 2012-01-01 to 2013-01-01 and the
course start for the application period is 2014-05-01. (dummy data)
</div>
<div wicket:id="ideaOverview"></div>
</div>
</wicket:extend>
</body>
</html>

@ -0,0 +1,25 @@
package se.su.dsv.scipro.project.pages;
import org.apache.wicket.PageParameters;
import org.apache.wicket.markup.html.panel.FeedbackPanel;
import se.su.dsv.scipro.project.panels.ProjectIdeaOverviewPanel;
import se.su.dsv.scipro.security.auth.Authorization;
import se.su.dsv.scipro.security.auth.roles.Roles;
@Authorization(authorizedRoles={Roles.SYSADMIN})
public class ProjectIdeaStartPage extends AbstractProjectIdeaPage {
private FeedbackPanel feedbackPanel;
public ProjectIdeaStartPage(PageParameters pp) {
super(pp);
addFeedback();
add(new ProjectIdeaOverviewPanel("ideaOverview", getUser()));
}
private void addFeedback() {
add(feedbackPanel = new FeedbackPanel("feedback"));
feedbackPanel.setOutputMarkupId(true);
}
}

@ -9,7 +9,6 @@ import org.apache.wicket.spring.injection.annot.SpringBean;
import se.su.dsv.scipro.SciProApplication;
import se.su.dsv.scipro.SciProSession;
import se.su.dsv.scipro.basepages.MenuPage;
import se.su.dsv.scipro.components.menuhighlighting.MenuHighlightProjectIdeas;
import se.su.dsv.scipro.data.dataobjects.Student;
import se.su.dsv.scipro.data.dataobjects.User;
@ -21,7 +20,7 @@ import se.su.dsv.scipro.security.auth.Authorization;
import se.su.dsv.scipro.security.auth.roles.Roles;
@Authorization(authorizedRoles={Roles.STUDENT})
public class ProjectIdeaSubmissionPage extends ProjectPage implements MenuHighlightProjectIdeas {
public class ProjectIdeaSubmissionPage extends AbstractProjectIdeaPage implements MenuHighlightProjectIdeas {
@SpringBean
private ProjectIdeaDao projectIdeaDao;

@ -0,0 +1,30 @@
<!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 wicket:id="unconfirmedContainer" >
<div class="info-box rounded-box last">
You have been selected as a partner to be the author for this project<br />
<div class="prepend-top">
<input type="submit" wicket:id="partnerAccept" value="Accept"/>
<input type="submit" wicket:id="partnerDecline" value="Decline"/>
</div>
</div>
</div>
<div wicket:id="ideaDetails"></div>
<div>
<wicket:enclosure child="partnerPanel">
<b>Partner:</b><br />
<div wicket:id="partnerPanel"></div>
</wicket:enclosure>
<span class="right"><input type="submit" wicket:id="selectButton" value="Select project"/></span>
</div>
</form>
</wicket:panel>
</body>
</html>

@ -0,0 +1,111 @@
package se.su.dsv.scipro.project.panels;
import java.util.TreeSet;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.markup.html.basic.EnclosureContainer;
import org.apache.wicket.markup.html.form.Button;
import org.apache.wicket.markup.html.form.Form;
import org.apache.wicket.markup.html.panel.Panel;
import org.apache.wicket.model.IModel;
import org.apache.wicket.spring.injection.annot.SpringBean;
import se.su.dsv.scipro.data.dataobjects.ProjectClass;
import se.su.dsv.scipro.data.dataobjects.Student;
import se.su.dsv.scipro.data.dataobjects.User;
import se.su.dsv.scipro.match.dataobject.SupervisorIdea;
import se.su.dsv.scipro.reusable.AddRemoveStudentsPanel;
import se.su.dsv.scipro.springdata.services.SupervisorIdeaService;
import se.su.dsv.scipro.util.JavascriptEventConfirmation;
public class AcceptIdeaDialogPanel extends Panel {
@SpringBean
private SupervisorIdeaService ideaService;
public AcceptIdeaDialogPanel(String id, IModel<SupervisorIdea> model, final User loggedInUser, boolean unconfirmed) {
super(id, model);
add(new AcceptIdeaForm("form", model, loggedInUser, unconfirmed));
}
private static final long serialVersionUID = 29731924490786784L;
private class AcceptIdeaForm extends Form<SupervisorIdea> {
private static final long serialVersionUID = -9118352523380756043L;
private AddRemoveStudentsPanel partnerPanel;
public AcceptIdeaForm(String id, final IModel<SupervisorIdea> model, final User loggedInUser, final boolean unconfirmed) {
super(id, model);
addPartnerPanel(model, unconfirmed);
add(new ProjectIdeaDetailsPanel("ideaDetails", model, unconfirmed, false));
addUnconfirmedContainer(model, loggedInUser, unconfirmed); //Info box with accept/decline buttons
addButton(model, loggedInUser, unconfirmed);
}
private void addUnconfirmedContainer(final IModel<SupervisorIdea> model, final User loggedInUser, final boolean unconfirmed) {
Button acceptButton = new Button("partnerAccept"){
private static final long serialVersionUID = -7001493750138777577L;
@Override
public void onSubmit(){
ideaService.partnerAcceptIdea(model, loggedInUser);
getSession().info("You have accepted to be a part of the project: "+ model.getObject().getTitle());
}
};
EnclosureContainer cont = new EnclosureContainer("unconfirmedContainer", acceptButton);
acceptButton.setVisible(unconfirmed);
acceptButton.add(new JavascriptEventConfirmation("onClick", "Are you sure you want to be a part of this project?"));
Button declineButton = new Button("partnerDecline"){
private static final long serialVersionUID = -3519373023312617322L;
@Override
public void onSubmit(){
ideaService.declineIdea(model);
getSession().info("You have declined to be a part of the project: "+ model.getObject().getTitle());
}
};
declineButton.add(new JavascriptEventConfirmation("onClick", "Are you sure you want to decline this project idea?"));
cont.add(acceptButton);
cont.add(declineButton);
add(cont);
}
private void addPartnerPanel(IModel<SupervisorIdea> model, boolean unconfirmed) {
partnerPanel = new AddRemoveStudentsPanel("partnerPanel", new TreeSet<Student>()) {
private static final long serialVersionUID = 8432765543881357453L;
@Override
public void onUpdate(AjaxRequestTarget target) {
//do nothing
}
};
partnerPanel.setVisible(model.getObject().getProjectClass().getCode().equals(ProjectClass.BACHELOR) && !unconfirmed);
add(partnerPanel);
}
private void addButton(final IModel<SupervisorIdea> model, final User loggedInUser, final boolean unconfirmed) {
Button button = new Button("selectButton") {
private static final long serialVersionUID = 8805671593150004137L;
@Override
public void onSubmit() {
if(ideaService.acceptIdea(model, loggedInUser, partnerPanel.getStudentSet())){
getSession().info("You have successfully accepted this project idea");
} else {
getSession().error("Something went wrong while trying to accept the project idea");
}
}
};
button.add(new JavascriptEventConfirmation("onClick", "Are you sure you want to select this project idea?"));
button.setVisible(!unconfirmed);
add(button);
}
}
}

@ -0,0 +1,17 @@
<!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">
<span class="right"><input type="submit" wicket:id="cancelButton" value="Cancel selection of this project"/></span>
<div wicket:id="ideaDetails"></div>
<div class="prepend-top" wicket:id="watsonDetails"></div>
<input type="submit" wicket:id="saveButton" value="Save"/>
</form>
</wicket:panel>
</body>
</html>

@ -0,0 +1,69 @@
package se.su.dsv.scipro.project.panels;
import org.apache.wicket.markup.html.form.Button;
import org.apache.wicket.markup.html.form.Form;
import org.apache.wicket.markup.html.panel.Panel;
import org.apache.wicket.model.IModel;
import org.apache.wicket.spring.injection.annot.SpringBean;
import se.su.dsv.scipro.match.dataobject.SupervisorIdea;
import se.su.dsv.scipro.springdata.services.SupervisorIdeaService;
import se.su.dsv.scipro.util.JavascriptEventConfirmation;
public class CompleteIdeaDialogPanel extends Panel {
@SpringBean
private SupervisorIdeaService ideaService;
public CompleteIdeaDialogPanel(String id, IModel<SupervisorIdea> model) {
super(id, model);
add(new CompleteIdeaForm("form", model));
}
private static final long serialVersionUID = 29731924490786784L;
private class CompleteIdeaForm extends Form<SupervisorIdea> {
private static final long serialVersionUID = -9118352523380756043L;
public CompleteIdeaForm(String id, final IModel<SupervisorIdea> model) {
super(id, model);
add(new ProjectIdeaDetailsPanel("ideaDetails", model, true, false));
add(new ProjectIdeaWatsonPanel("watsonDetails", model));
addSaveButton(model);
addCancelButton(model);
}
private void addSaveButton(final IModel<SupervisorIdea> model) {
Button button = new Button("saveButton") {
private static final long serialVersionUID = 8805671593150004137L;
@Override
public void onSubmit() {
ideaService.updateIdea(model);
getSession().info("Project idea updated");
}
};
button.add(new JavascriptEventConfirmation("onClick", "Are you sure you want to save your changes?"));
add(button);
}
private void addCancelButton(final IModel<SupervisorIdea> model) {
Button button = new Button("cancelButton") {
private static final long serialVersionUID = -7066867035489876553L;
@Override
public void onSubmit() {
ideaService.declineIdea(model);
getSession().info("Project idea participation cancelled");
}
};
button.add(new JavascriptEventConfirmation("onClick", "Are you sure you want to cancel this selection?"));
add(button);
}
}
}

@ -0,0 +1,46 @@
<!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>
<div class="append-bottom"><b>Level: </b><br />
<span wicket:id="level"></span>
</div>
<div class="append-bottom"><b>Required prerequisites:</b><br />
<span wicket:id="reqs"></span>
</div>
<div class="append-bottom"><b>Title:</b><br />
<span wicket:id="title"></span>
</div>
<div class="append-bottom"><b>Description:</b><br />
<span wicket:id="description"></span>
</div>
<div class="append-bottom"><b>Research area:</b><br />
<span wicket:id="noAreaLabel"></span>
<span wicket:id="researchAreas"><span wicket:id="areaName"></span><br /></span>
</div>
<div class="append-bottom"><b>Keywords:</b><br />
<span wicket:id="noKeysLabel"></span>
<span wicket:id="keywords"><span wicket:id="keyName"></span><br /></span>
</div>
<div class="append-bottom" wicket:id="authorsEnclosure">
<b>Authors:</b><br />
<span wicket:id="authorList"><span wicket:id="authorName"></span><br /></span>
</div>
<br />
<div class="append-bottom" wicket:id="watsonEnclosure">
<b>What?</b><br />
<span wicket:id="what"></span><br /><br />
<b>Why?</b><br />
<span wicket:id="why"></span><br /><br />
<b>Theoretically how?</b><br />
<span wicket:id="theory"></span><br /><br />
<b>Practically how?</b><br />
<span wicket:id="practical"></span><br />
</div>
</wicket:panel>
</body>
</html>

@ -0,0 +1,104 @@
package se.su.dsv.scipro.project.panels;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import org.apache.wicket.markup.html.basic.EnclosureContainer;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.list.ListItem;
import org.apache.wicket.markup.html.list.ListView;
import org.apache.wicket.markup.html.panel.Panel;
import org.apache.wicket.model.IModel;
import org.apache.wicket.spring.injection.annot.SpringBean;
import se.su.dsv.scipro.data.dataobjects.Employee;
import se.su.dsv.scipro.data.dataobjects.ResearchArea;
import se.su.dsv.scipro.data.dataobjects.Student;
import se.su.dsv.scipro.match.dataobject.IdeaParticipation;
import se.su.dsv.scipro.match.dataobject.Keyword;
import se.su.dsv.scipro.match.dataobject.SupervisorIdea;
import se.su.dsv.scipro.springdata.services.SupervisorService;
public class ProjectIdeaDetailsPanel extends Panel {
private static final long serialVersionUID = -8165939637975042836L;
@SpringBean
private SupervisorService supervisorService;
public ProjectIdeaDetailsPanel(String id, IModel<SupervisorIdea> model, boolean showAuthors, boolean showWatsons) {
super(id, model);
Employee ideaCreator = supervisorService.findOne(model.getObject().getCreator().getId());
add(new Label("level", model.getObject().getProjectClass().getName()));
add(new Label("reqs", model.getObject().getRequirements()));
add(new Label("title", model.getObject().getTitle()));
add(new Label("description", model.getObject().getDescription()));
addResearchAreas(ideaCreator);
addKeywords(model);
addAuthorsEnclosure(model, showAuthors); //List of authors so the partner knows who to write with before accepting
addWatsonInfo(model, showWatsons); //Watson info when viewing in supervisor view
}
private void addResearchAreas(Employee ideaCreator) {
final Set<ResearchArea> areas = ideaCreator.getActiveResearchAreas();
ListView<ResearchArea> areaList = new ListView<ResearchArea>("researchAreas", new ArrayList<ResearchArea>(areas)) {
private static final long serialVersionUID = 1745649109195334927L;
@Override
protected void populateItem(ListItem<ResearchArea> item) {
item.add(new Label("areaName", item.getModelObject().getTitle()));
}
};
add(new Label("noAreaLabel","No research area available").setVisible(areas.isEmpty()));
add(areaList);
}
private void addKeywords(IModel<SupervisorIdea> model) {
final Set<Keyword> keywords = model.getObject().getKeywords();
ListView<Keyword> keyList = new ListView<Keyword>("keywords", new ArrayList<Keyword>(keywords)) {
private static final long serialVersionUID = 470796140309547562L;
@Override
protected void populateItem(ListItem<Keyword> item) {
item.add(new Label("keyName", item.getModelObject().getKeyword()));
}
};
add(new Label("noKeysLabel", "No keywords available").setVisible(keywords.isEmpty()));
add(keyList);
}
private void addAuthorsEnclosure(IModel<SupervisorIdea> model, boolean showAuthors) {
List<Student> authors = new ArrayList<Student>();
for (IdeaParticipation ip : model.getObject().getIdeaParticipations())
authors.add(ip.getStudent());
ListView<Student> authorList = new ListView<Student>("authorList", authors) {
private static final long serialVersionUID = -3951835080975833866L;
@Override
protected void populateItem(ListItem<Student> item) {
item.add(new Label("authorName", item.getModelObject().getNameAsString()));
}
};
authorList.setVisible(showAuthors);
EnclosureContainer authorEnclosure = new EnclosureContainer("authorsEnclosure", authorList);
authorEnclosure.add(authorList);
add(authorEnclosure);
}
private void addWatsonInfo(IModel<SupervisorIdea> model, boolean showWatsons) {
String whatString = model.getObject().getWatson().getWhat().equals("")?"Waiting for student to fill in":model.getObject().getWatson().getWhat();
String whyString = model.getObject().getWatson().getWhy().equals("")?"Waiting for student to fill in":model.getObject().getWatson().getWhy();
String theoryString = model.getObject().getWatson().getTheoryHow().equals("")?"Waiting for student to fill in":model.getObject().getWatson().getTheoryHow();
String pracString = model.getObject().getWatson().getPracticalHow().equals("")?"Waiting for student to fill in":model.getObject().getWatson().getPracticalHow();
Label what = new Label("what", whatString);
what.setVisible(showWatsons);
EnclosureContainer watsonEnclosure = new EnclosureContainer("watsonEnclosure", what);
watsonEnclosure.add(new Label("why", whyString));
watsonEnclosure.add(new Label("theory", theoryString));
watsonEnclosure.add(new Label("practical", pracString));
watsonEnclosure.add(what);
add(watsonEnclosure);
}
}

@ -0,0 +1,18 @@
<!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>
<div wicket:id="dialog">
<div wicket:id="dialogPanel"></div>
</div>
<form wicket:id="form">
<div class="span-5" wicket:id="levelFilter"></div>
</form>
<div class="span-24 prepend-top" wicket:id="dataPanel"></div>
</wicket:panel>
</body>
</html>

@ -0,0 +1,183 @@
package se.su.dsv.scipro.project.panels;
import java.util.Iterator;
import java.util.List;
import org.apache.wicket.ajax.AbstractAjaxTimerBehavior;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.extensions.markup.html.repeater.data.table.IColumn;
import org.apache.wicket.extensions.markup.html.repeater.data.table.PropertyColumn;
import org.apache.wicket.markup.html.form.Form;
import org.apache.wicket.markup.html.panel.EmptyPanel;
import org.apache.wicket.markup.html.panel.Panel;
import org.apache.wicket.model.IModel;
import org.apache.wicket.model.Model;
import org.apache.wicket.spring.injection.annot.SpringBean;
import org.apache.wicket.util.time.Duration;
import org.odlabs.wiquery.ui.dialog.Dialog;
import org.springframework.data.domain.PageRequest;
import se.su.dsv.scipro.data.dataobjects.Student;
import se.su.dsv.scipro.data.dataobjects.User;
import se.su.dsv.scipro.datatables.ClickableTitleColumn;
import se.su.dsv.scipro.datatables.GenericDataPanel;
import se.su.dsv.scipro.match.dataobject.Idea.IdeaStatus;
import se.su.dsv.scipro.match.dataobject.SupervisorIdea;
import se.su.dsv.scipro.match.panel.FilterFormProjectClass;
import se.su.dsv.scipro.springdata.services.GenericService;
import se.su.dsv.scipro.springdata.services.StudentService;
import se.su.dsv.scipro.springdata.services.SupervisorIdeaService;
public class ProjectIdeaOverviewPanel extends Panel {
private static final long serialVersionUID = 3494993579137804821L;
@SpringBean
private SupervisorIdeaService ideaService;
@SpringBean
private StudentService studentService;
private SupervisorIdeaService.FilterParams params;
private GenericDataPanel<SupervisorIdea> genericDataPanel;
private Dialog dialog;
public ProjectIdeaOverviewPanel(String id, User currentUser) {
super(id);
addDialog();
addDataTable(currentUser);
checkForUnconfirmedIdeas(currentUser);
add(new FilterForm("form"));
}
private void addDialog() {
dialog = new Dialog("dialog");
dialog.setModal(true);
dialog.setAutoOpen(false);
dialog.setWidth(500);
dialog.setHeight(600);
dialog.add(new EmptyPanel("dialogPanel"));
add(dialog);
}
private void addDataTable(final User currentUser) {
add(genericDataPanel = new GenericDataPanel<SupervisorIdea>("dataPanel") {
private static final long serialVersionUID = -4539188306454725307L;
@Override
public GenericService<SupervisorIdea, Long> getService() {
return ideaService;
}
@Override
public String getSortString() {
return "title";
}
@Override
public Iterator<SupervisorIdea> getIterator() {
return ideaService.findByStatusAndParams(IdeaStatus.WAITING, params, new PageRequest(getTable().getCurrentPage(), getTable().getRowsPerPage(), getSort())).iterator();
}
@Override
public IColumn[] getColumns() {
IColumn[] columns = new IColumn[3];
columns[0] = new PropertyColumn<SupervisorIdea>(Model.of("Date"), "dateCreated", "dateCreated");
columns[1] = new PropertyColumn<SupervisorIdea>(Model.of("Level"), "projectClass", "projectClass");
columns[2] = new ClickableTitleColumn<SupervisorIdea>(Model.of("Title"), "title", "title") {
private static final long serialVersionUID = -5826739548812884588L;
@Override
protected void onClick(IModel<SupervisorIdea> ideaModel,
AjaxRequestTarget pTarget) {
dialog.replace(new AcceptIdeaDialogPanel("dialogPanel", ideaModel, currentUser, false));
dialog.setTitle("Supervisor project idea");
pTarget.addComponent(dialog);
dialog.open(pTarget);
}
};
return columns;
}
});
}
private void checkForUnconfirmedIdeas(final User currentUser) {
boolean hasUnconfirmed = ideaService.hasTakenIdeas(currentUser, false);
if(hasUnconfirmed) {
Student author = studentService.findByUser(currentUser);
final List<SupervisorIdea> ideas = ideaService.findIdeas(IdeaStatus.TAKEN, author, false);
if(ideas.size()>1)
System.out.println("More than one unconfirmed idea");
else {
add(new AbstractAjaxTimerBehavior(Duration.milliseconds(1)) {
private static final long serialVersionUID = 8249890924500999472L;
@Override
protected void onTimer(AjaxRequestTarget target) {
dialog.replace(new AcceptIdeaDialogPanel("dialogPanel",Model.of(ideas.get(0)), currentUser, true));
dialog.setTitle("Supervisor project idea");
target.addComponent(dialog);
dialog.open(target);
stop();
}
});
}
}
else {
checkForConfirmedIdeas(currentUser);
}
}
private void checkForConfirmedIdeas(final User currentUser) {
boolean hasConfirmed = ideaService.hasTakenIdeas(currentUser, true);
if(hasConfirmed){
Student author = studentService.findByUser(currentUser);
final List<SupervisorIdea> ideas = ideaService.findIdeas(IdeaStatus.TAKEN, author, true);
add(new AbstractAjaxTimerBehavior(Duration.milliseconds(1)) {
private static final long serialVersionUID = 8249890924500999472L;
@Override
protected void onTimer(AjaxRequestTarget target) {
dialog.replace(new CompleteIdeaDialogPanel("dialogPanel",Model.of(ideas.get(0))));
dialog.setWidth(550);
dialog.setHeight(700);
dialog.setTitle("Selected supervisor project idea");
target.addComponent(dialog);
dialog.open(target);
stop();
}
});
} else
System.out.println("No confirmed ideas");
}
private class FilterForm extends Form<Void> {
private static final long serialVersionUID = -5646495880236201368L;
public FilterForm(String id) {
super(id);
params = new SupervisorIdeaService.FilterParams();
//FILTERING ON PROJECT CLASS:
final FilterFormProjectClass levelFilter = new FilterFormProjectClass("levelFilter") {
private static final long serialVersionUID = -7758850229259608443L;
@Override
public void ajaxUpdate(AjaxRequestTarget target) {
if(!getProjectClasses().isEmpty()){
params.setLevels(getProjectClasses());
}
target.addComponent(genericDataPanel.getWMC());
}
};
params.setLevels(levelFilter.getProjectClasses());
add(levelFilter);
}
}
}

@ -60,7 +60,7 @@ 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.LanguageProvidingProxy;
import se.su.dsv.scipro.project.pages.ProjectIdeaPage;
import se.su.dsv.scipro.project.pages.MyProjectIdeasPage;
import se.su.dsv.scipro.util.AutoCompleteStringFormatter;
/**
@ -315,7 +315,7 @@ public class ProjectIdeaSubmissionPanel extends Panel {
idea.setLanguages(languageSelectionPanel.getSelectedLanguages());
projectIdeaFacade.saveIdea(idea, loggedInUser, agreedSupervisorSelector.getModelObject());
setResponsePage(ProjectIdeaPage.class);
setResponsePage(MyProjectIdeasPage.class);
getSession().info("Project idea successfully submitted");
}
}

@ -0,0 +1,36 @@
package se.su.dsv.scipro.project.panels;
import java.util.ArrayList;
import java.util.List;
import org.apache.wicket.Page;
import se.su.dsv.scipro.components.AbstractMenuPanel;
import se.su.dsv.scipro.project.pages.AbstractProjectIdeaPage;
import se.su.dsv.scipro.project.pages.MyProjectIdeasPage;
import se.su.dsv.scipro.project.pages.ProjectIdeaStartPage;
import se.su.dsv.scipro.project.pages.ProjectIdeaSubmissionPage;
public class ProjectIdeaTabMenuPanel extends AbstractMenuPanel{
private static final long serialVersionUID = 1L;
public ProjectIdeaTabMenuPanel(String id, Class<? extends Page> containerClass) {
super(id, AbstractProjectIdeaPage.class, containerClass);
}
@Override
protected List<MenuItem> getItemList() {
List<MenuItem> items = new ArrayList<MenuItem>();
items.add(new MenuItem("Supervisor provided project ideas", ProjectIdeaStartPage.class));
items.add(new MenuItem("Submit own project idea", ProjectIdeaSubmissionPage.class));
items.add(new MenuItem("My project idea history", MyProjectIdeasPage.class));
return items;
}
@Override
protected MenuType getMenuType() {
return MenuType.TAB_MULTIPLE_ROWS;
}
}

@ -0,0 +1,19 @@
<!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>
<b>What?</b><br />
<textarea class="span-12" wicket:id="watsonWhat"></textarea>
<b>Why?</b><br />
<textarea class="span-12" wicket:id="watsonWhy"></textarea>
<b>Theoretically how?</b><br />
<textarea class="span-12" wicket:id="watsonHowTheory"></textarea>
<b>Practically how?</b><br />
<textarea class="span-12" wicket:id="watsonHowPrac"></textarea>
</wicket:panel>
</body>
</html>

@ -0,0 +1,36 @@
package se.su.dsv.scipro.project.panels;
import java.util.ArrayList;
import java.util.Set;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.form.TextArea;
import org.apache.wicket.markup.html.list.ListItem;
import org.apache.wicket.markup.html.list.ListView;
import org.apache.wicket.markup.html.panel.Panel;
import org.apache.wicket.model.IModel;
import org.apache.wicket.model.PropertyModel;
import org.apache.wicket.spring.injection.annot.SpringBean;
import se.su.dsv.scipro.data.dataobjects.Employee;
import se.su.dsv.scipro.data.dataobjects.ResearchArea;
import se.su.dsv.scipro.match.dataobject.Keyword;
import se.su.dsv.scipro.match.dataobject.SupervisorIdea;
import se.su.dsv.scipro.springdata.services.SupervisorService;
public class ProjectIdeaWatsonPanel extends Panel {
private static final long serialVersionUID = -8165939637975042836L;
@SpringBean
private SupervisorService supervisorService;
public ProjectIdeaWatsonPanel(String id, IModel<SupervisorIdea> model) {
super(id, model);
add(new TextArea<String>("watsonWhat", new PropertyModel<String>(model, "watson.what")));
add(new TextArea<String>("watsonWhy", new PropertyModel<String>(model, "watson.why")));
add(new TextArea<String>("watsonHowTheory", new PropertyModel<String>(model, "watson.theoryHow")));
add(new TextArea<String>("watsonHowPrac", new PropertyModel<String>(model, "watson.practicalHow")));
}
}

@ -9,7 +9,8 @@ import se.su.dsv.scipro.components.AbstractMenuPanel;
import se.su.dsv.scipro.components.menuhighlighting.MenuHighlightAuthorMyProjects;
import se.su.dsv.scipro.components.menuhighlighting.MenuHighlightProjectIdeas;
import se.su.dsv.scipro.project.pages.FinalSeminarProjectListPage;
import se.su.dsv.scipro.project.pages.ProjectIdeaPage;
import se.su.dsv.scipro.project.pages.MyProjectIdeasPage;
import se.su.dsv.scipro.project.pages.ProjectIdeaStartPage;
import se.su.dsv.scipro.project.pages.ProjectPage;
import se.su.dsv.scipro.project.pages.ProjectPartnerPage;
import se.su.dsv.scipro.project.pages.ProjectStartPage;
@ -32,7 +33,7 @@ public class ProjectTabMenuPanel extends AbstractMenuPanel {
List<MenuItem> itemList = new ArrayList<MenuItem>();
itemList.add(new MenuItem("My project(s)", ProjectStartPage.class, MenuHighlightAuthorMyProjects.class));
itemList.add(new MenuItem("My project idea(s)", ProjectIdeaPage.class, MenuHighlightProjectIdeas.class));
itemList.add(new MenuItem("Project ideas", MyProjectIdeasPage.class, MenuHighlightProjectIdeas.class));
itemList.add(new MenuItem("Project Partner", ProjectPartnerPage.class));
itemList.add(new MenuItem("All Final Seminars", FinalSeminarProjectListPage.class));

@ -20,7 +20,8 @@ import se.su.dsv.scipro.data.enums.ProjectStatus;
import se.su.dsv.scipro.data.enums.StateOfMind;
import se.su.dsv.scipro.icons.ImageIcon;
import se.su.dsv.scipro.project.pages.ProjectDetailsPage;
import se.su.dsv.scipro.project.pages.ProjectIdeaPage;
import se.su.dsv.scipro.project.pages.MyProjectIdeasPage;
import se.su.dsv.scipro.project.pages.ProjectIdeaStartPage;
import se.su.dsv.scipro.springdata.services.ProjectService;
public class ProjectsOverviewPanel extends Panel {
@ -53,7 +54,7 @@ public class ProjectsOverviewPanel extends Panel {
setResponsePage(ProjectDetailsPage.class, pp);
}
if(projects.size()==0){
setResponsePage(ProjectIdeaPage.class);
setResponsePage(MyProjectIdeasPage.class);
}
}

@ -0,0 +1,17 @@
package se.su.dsv.scipro.springdata.repos;
import java.util.List;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.querydsl.QueryDslPredicateExecutor;
import org.springframework.transaction.annotation.Transactional;
import se.su.dsv.scipro.data.dataobjects.ResearchArea;
@Transactional(readOnly = true)
public interface ResearchAreaRepo extends JpaRepository<ResearchArea, Long>, QueryDslPredicateExecutor<ResearchArea> {
public ResearchArea findByIdentifier(Long identifier);
public List<ResearchArea> findByDeleted(boolean deleted);
}

@ -0,0 +1,27 @@
package se.su.dsv.scipro.springdata.repos;
import java.util.List;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.querydsl.QueryDslPredicateExecutor;
import org.springframework.transaction.annotation.Transactional;
import se.su.dsv.scipro.data.dataobjects.Student;
import se.su.dsv.scipro.match.dataobject.SupervisorIdea;
import se.su.dsv.scipro.match.dataobject.Idea.IdeaStatus;
@Transactional(readOnly = true)
public interface SupervisorIdeaRepo extends JpaRepository<SupervisorIdea, Long>, QueryDslPredicateExecutor<SupervisorIdea> {
//Query for retrieving ideas based on author. Problems with implementing through QueryDSL with IdeaParticipation object
@Query("select idea from SupervisorIdea idea, Student author join idea.ideaParticipations ideaPart join author.ideaParticipations authorPart where ideaPart = authorPart and author = ?")
List<SupervisorIdea> findIdeasByAuthor(Student author);
//Query for retrieving ideas based on author and status. Problems with implementing through QueryDSL with IdeaParticipation object
@Query("select idea from SupervisorIdea idea, Student author join idea.ideaParticipations ideaPart join author.ideaParticipations authorPart where ideaPart = authorPart and author = ? and idea.ideaStatus = ?")
List<SupervisorIdea> findIdeasByAuthorAndStatus(Student author, IdeaStatus status);
@Query("select idea from SupervisorIdea idea, Student author join idea.ideaParticipations ideaPart join author.ideaParticipations authorPart where ideaPart = authorPart and author = ? and idea.ideaStatus = ? and ideaPart.confirmed = ?")
List<SupervisorIdea> findIdeas(Student author, IdeaStatus status, boolean confirmed);
}

@ -0,0 +1,59 @@
package se.su.dsv.scipro.springdata.serviceimpls;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import javax.annotation.Resource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import se.su.dsv.scipro.data.dataobjects.ResearchArea;
import se.su.dsv.scipro.springdata.repos.ResearchAreaRepo;
import se.su.dsv.scipro.springdata.services.ResearchAreaService;
@Service ( "researchareaService" )
@Transactional ( readOnly = true )
public class ResearchAreaServiceImpl extends AbstractQueryService<ResearchArea, Long> implements ResearchAreaService {
@Resource
private ResearchAreaRepo researchAreaRepo;
@Autowired
public ResearchAreaServiceImpl(
@Qualifier("researchAreaRepo")
ResearchAreaRepo researchAreaRepo) {
super(researchAreaRepo, researchAreaRepo);
System.out.println("ResearchAreaServiceImpl instantiating...");
}
@Override
public ResearchArea findByIdentifier(Long identifier) {
return researchAreaRepo.findByIdentifier(identifier);
}
@Override
public Set<ResearchArea> findAllAsSet() {
return new HashSet<ResearchArea>(researchAreaRepo.findAll());
}
@Override
public List<ResearchArea> findAllAsList() {
return researchAreaRepo.findAll();
}
@Override
public void deleteArea(ResearchArea area) {
researchAreaRepo.delete(area);
}
@Override
public List<ResearchArea> findAll(boolean includeDeleted) {
return researchAreaRepo.findByDeleted(includeDeleted);
}
}

@ -0,0 +1,253 @@
package se.su.dsv.scipro.springdata.serviceimpls;
import java.util.Collection;
import java.util.List;
import java.util.SortedSet;
import javax.annotation.Resource;
import org.apache.wicket.model.IModel;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import se.su.dsv.scipro.data.dataobjects.Employee;
import se.su.dsv.scipro.data.dataobjects.ProjectClass;
import se.su.dsv.scipro.data.dataobjects.Student;
import se.su.dsv.scipro.data.dataobjects.User;
import se.su.dsv.scipro.match.dataobject.Idea.IdeaStatus;
import se.su.dsv.scipro.match.dataobject.IdeaParticipation;
import se.su.dsv.scipro.match.dataobject.QSupervisorIdea;
import se.su.dsv.scipro.match.dataobject.SupervisorIdea;
import se.su.dsv.scipro.match.dataobject.Watson;
import se.su.dsv.scipro.springdata.repos.SupervisorIdeaRepo;
import se.su.dsv.scipro.springdata.services.StudentService;
import se.su.dsv.scipro.springdata.services.SupervisorIdeaService;
import com.mysema.query.BooleanBuilder;
import com.mysema.query.types.Predicate;
import com.mysema.query.types.expr.BooleanExpression;
@Service ( "supervisorIdeaService" )
@Transactional ( readOnly = true )
public class SupervisorIdeaServiceImpl extends AbstractQueryService<SupervisorIdea, Long> implements SupervisorIdeaService {
@Resource
private SupervisorIdeaRepo supervisorIdeaRepo;
@Resource
private StudentService studentService;
private int MAX_PARTNERS = 1;
@Autowired
public SupervisorIdeaServiceImpl(
@Qualifier("supervisorIdeaRepo")
SupervisorIdeaRepo supervisorIdeaRepo) {
super(supervisorIdeaRepo, supervisorIdeaRepo);
System.out.println("SupervisorIdeaServiceImpl instantiating...");
}
@Override
@Transactional ( readOnly = false )
public void saveSupervisorCreatedIdea(IModel<SupervisorIdea> model, Employee creator, SortedSet<Student> students) {
SupervisorIdea idea = model.getObject();
if(!students.isEmpty()) {
for(Student s : students) {
s = studentService.findOne(s.getId()); //Needed for lazy loading to work.
IdeaParticipation ip = new IdeaParticipation();
ip.setStudent(s);
ip.setSupervisorIdea(idea);
ip.setConfirmed(false);
s.addIdeaParticipation(ip);
}
idea.setIdeaStatus(IdeaStatus.TAKEN); //Should not be visible for selection if supervisor manually added students
} else {
idea.setIdeaStatus(IdeaStatus.WAITING);
}
idea.setCreator(creator);
save(idea);
}
@Override
@Transactional ( readOnly = false )
public void deleteWaitingIdea(IModel<SupervisorIdea> model) {
SupervisorIdea idea = supervisorIdeaRepo.findOne(model.getObject().getId());
if(!idea.getIdeaStatus().equals(IdeaStatus.WAITING)) //Should not be deleted if IdeaStatus is anything else than waiting.
return;
else
supervisorIdeaRepo.delete(idea);
}
@Override
@Transactional ( readOnly = false )
public boolean acceptIdea(IModel<SupervisorIdea> model, User mainAuthor,
SortedSet<Student> studentSet) {
if(studentSet.size()> MAX_PARTNERS){
return false; //You may not add more than a specified number of partners.
} else {
SupervisorIdea idea = supervisorIdeaRepo.findOne(model.getObject().getId());
if(idea.getProjectClass().getCode().equals(ProjectClass.BACHELOR) && studentSet.isEmpty()){
return false; //You need to select a partner if the idea is on bachelor level.
}
Student author = studentService.findByUser(mainAuthor);
if(studentSet.contains(author)) {
return false; //You may not select yourself as partner.
}
IdeaParticipation mainParticipation = new IdeaParticipation();
mainParticipation.setStudent(author);
mainParticipation.setSupervisorIdea(idea);
mainParticipation.setConfirmed(true);
author.addIdeaParticipation(mainParticipation);
for(Student s : studentSet) {
s = studentService.findOne(s.getId()); //Needed for lazy loading to work.
IdeaParticipation ip = new IdeaParticipation();
ip.setStudent(s);
ip.setSupervisorIdea(idea);
ip.setConfirmed(false);
s.addIdeaParticipation(ip);
}
idea.setIdeaStatus(IdeaStatus.TAKEN);
return true;
}
}
@Override
@Transactional (readOnly = false)
public void partnerAcceptIdea(IModel<SupervisorIdea> model, User loggedInUser) {
SupervisorIdea idea = supervisorIdeaRepo.findOne(model.getObject().getId());
Student author = studentService.findByUser(loggedInUser);
for (IdeaParticipation ip : idea.getIdeaParticipations())
if(ip.getStudent().equals(author))
ip.setConfirmed(true);
}
@Override
@Transactional ( readOnly = false )
public void declineIdea(IModel<SupervisorIdea> model) {
SupervisorIdea idea = supervisorIdeaRepo.findOne(model.getObject().getId());
//Remove participations
for (IdeaParticipation ip : idea.getIdeaParticipations()) {
Student s = ip.getStudent();
s.removeIdeaParticipation(ip);
}
//Erase watson boxes
idea.setWatson(new Watson());
//Change status back to waiting
idea.setIdeaStatus(IdeaStatus.WAITING);
}
@Override
@Transactional ( readOnly = false )
public void updateIdea(IModel<SupervisorIdea> model) {
SupervisorIdea idea = supervisorIdeaRepo.findOne(model.getObject().getId());
if(model.getObject().getWatson().getWhat()!=null)
idea.getWatson().setWhat(model.getObject().getWatson().getWhat());
if(model.getObject().getWatson().getWhy()!=null)
idea.getWatson().setWhy(model.getObject().getWatson().getWhy());
if(model.getObject().getWatson().getTheoryHow()!=null)
idea.getWatson().setTheoryHow(model.getObject().getWatson().getTheoryHow());
if(model.getObject().getWatson().getPracticalHow()!=null)
idea.getWatson().setPracticalHow(model.getObject().getWatson().getPracticalHow());
}
@Override
@Transactional
public boolean hasTakenIdeas(User authorUser, boolean confirmed) {
Student author = studentService.findByUser(authorUser);
// find unconfirmed ideas by author
List<SupervisorIdea> ideas = findIdeas(IdeaStatus.TAKEN, author, confirmed);
if(!ideas.isEmpty())
return true;
else
return false;
}
// Only editable if idea status is waiting and the current user is the creator
@Override
public boolean isIdeaEditable(IModel<SupervisorIdea> model, User currentUser) {
return model.getObject().getIdeaStatus().equals(IdeaStatus.WAITING)&&model.getObject().getCreator().getUser().equals(currentUser);
}
@Override
public Page<SupervisorIdea> findAll(FilterParams params, Pageable pageable) {
if(params!=null)
return supervisorIdeaRepo.findAll(predicateFromParams(params), pageable);
else
return supervisorIdeaRepo.findAll(pageable);
}
@Override
public Page<SupervisorIdea> findByStatus(IdeaStatus status, Pageable pageable) {
return supervisorIdeaRepo.findAll(byStatus(status), pageable);
}
@Override
public Page<SupervisorIdea> findByStatusAndParams(IdeaStatus status, FilterParams params, Pageable pageable) {
return supervisorIdeaRepo.findAll(byStatus(status).and(levelFilter(params.getLevels())), pageable);
}
@Override
public List<SupervisorIdea> findByStatusAndAuthor(IdeaStatus status, Student author) {
List<SupervisorIdea> ideas = supervisorIdeaRepo.findIdeasByAuthorAndStatus(author, status);
return ideas;
}
@Override
public List<SupervisorIdea> findIdeas(IdeaStatus status, Student author, boolean confirmed) {
List<SupervisorIdea> ideas = supervisorIdeaRepo.findIdeas(author, status, confirmed);
return ideas;
}
private Predicate predicateFromParams(FilterParams params) {
return levelFilter(params.getLevels()).and(bySupervisor(params.getSupervisor()));
}
private BooleanBuilder levelFilter(Collection<ProjectClass> levels){
BooleanBuilder e = new BooleanBuilder();
if(levels!=null && !levels.isEmpty()){
for (ProjectClass level : levels) {
e.or(byLevel(level));
}
return e;
}
else {
e.and(QSupervisorIdea.supervisorIdea.projectClass.isNull());
return e;
}
}
private BooleanExpression bySupervisor(Employee supervisor) {
if(supervisor!=null){
return QSupervisorIdea.supervisorIdea.creator.eq(supervisor);
} else {
return null;
}
}
private BooleanExpression byLevel(ProjectClass pc){
return QSupervisorIdea.supervisorIdea.projectClass.eq(pc);
}
private BooleanExpression byStatus(IdeaStatus status){
return QSupervisorIdea.supervisorIdea.ideaStatus.eq(status);
}
@Override
public Long countByStatus(IdeaStatus status) {
return supervisorIdeaRepo.count(byStatus(status));
}
}

@ -0,0 +1,20 @@
package se.su.dsv.scipro.springdata.services;
import java.util.List;
import java.util.Set;
import se.su.dsv.scipro.data.dataobjects.ResearchArea;
/**
* @author: fred-fri
* date: 2012 03 26
*/
public interface ResearchAreaService extends GenericService<ResearchArea, Long>, QueryService<ResearchArea, Long> {
public ResearchArea findByIdentifier(Long identifier);
public Set<ResearchArea> findAllAsSet();
public List<ResearchArea> findAllAsList();
public List<ResearchArea> findAll(boolean includeDeleted);
void deleteArea(ResearchArea area);
}

@ -0,0 +1,62 @@
package se.su.dsv.scipro.springdata.services;
import java.io.Serializable;
import java.util.Collection;
import java.util.List;
import java.util.SortedSet;
import org.apache.wicket.model.IModel;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import se.su.dsv.scipro.data.dataobjects.Employee;
import se.su.dsv.scipro.data.dataobjects.ProjectClass;
import se.su.dsv.scipro.data.dataobjects.Student;
import se.su.dsv.scipro.data.dataobjects.User;
import se.su.dsv.scipro.match.dataobject.Idea.IdeaStatus;
import se.su.dsv.scipro.match.dataobject.SupervisorIdea;
public interface SupervisorIdeaService extends GenericService<SupervisorIdea, Long>, QueryService<SupervisorIdea, Long> {
Page<SupervisorIdea> findAll(FilterParams params, Pageable pageable);
Page<SupervisorIdea> findByStatus(IdeaStatus status, Pageable pageable);
Page<SupervisorIdea> findByStatusAndParams(IdeaStatus status, FilterParams params, Pageable pageable);
List<SupervisorIdea> findByStatusAndAuthor(IdeaStatus status, Student author);
List<SupervisorIdea> findIdeas(IdeaStatus status, Student author, boolean confirmed);
Long countByStatus(IdeaStatus status);
void saveSupervisorCreatedIdea(IModel<SupervisorIdea> model, Employee creator, SortedSet<Student> students);
void deleteWaitingIdea(IModel<SupervisorIdea> model);
void partnerAcceptIdea(IModel<SupervisorIdea> model, User loggedInUser);
void declineIdea(IModel<SupervisorIdea> model);
void updateIdea(IModel<SupervisorIdea> model);
boolean acceptIdea(IModel<SupervisorIdea> model, User mainAuthor, SortedSet<Student> sortedSet);
boolean hasTakenIdeas(User authorUser, boolean confirmed);
boolean isIdeaEditable(IModel<SupervisorIdea> model, User currentUser);
public static class FilterParams implements Serializable {
private static final long serialVersionUID = 4981420721152104292L;
private Collection<ProjectClass> levels;
private Employee supervisor;
public void setLevels(Collection<ProjectClass> levels) {
this.levels = levels;
}
public Collection<ProjectClass> getLevels() {
return levels;
}
public void setSupervisor(Employee supervisor) {
this.supervisor = supervisor;
}
public Employee getSupervisor() {
return supervisor;
}
}
}

@ -0,0 +1,11 @@
<!DOCTYPE html>
<html xmlns:wicket="http://wicket.apache.org/dtds.data/wicket-xhtml1.4-strict.dtd">
<body>
<wicket:extend>
<div class="span-24 last append-bottom">
<div wicket:id="projectIdeaSub"></div>
</div>
<wicket:child/>
</wicket:extend>
</body>
</html>

@ -0,0 +1,20 @@
package se.su.dsv.scipro.supervisor.pages;
import org.apache.wicket.PageParameters;
import se.su.dsv.scipro.supervisor.panels.SupervisorProjectIdeaTabMenuPanel;
/**
*
* @author Martin Peters - mpeters@dsv.su.se
*
*/
public abstract class AbstractSupervisorProjectIdeaPage extends AbstractSupervisorPage {
public AbstractSupervisorProjectIdeaPage(PageParameters pp) {
super(pp);
add(new SupervisorProjectIdeaTabMenuPanel("projectIdeaSub", this.getClass()));
}
}

@ -0,0 +1,10 @@
<!DOCTYPE html>
<html
xmlns:wicket="http://wicket.apache.org/dtds.data/wicket-xhtml1.4-strict.dtd">
<body>
<wicket:extend>
<h2>Create new/edit project idea</h2>
<div class="prepend-top" wicket:id="editPanel"></div>
</wicket:extend>
</body>
</html>

@ -0,0 +1,34 @@
package se.su.dsv.scipro.supervisor.pages;
import org.apache.wicket.PageParameters;
import org.apache.wicket.model.Model;
import org.apache.wicket.spring.injection.annot.SpringBean;
import se.su.dsv.scipro.components.menuhighlighting.MenuHighlightSupervisorProjectIdea;
import se.su.dsv.scipro.match.dataobject.SupervisorIdea;
import se.su.dsv.scipro.springdata.services.SupervisorIdeaService;
import se.su.dsv.scipro.supervisor.panels.SupervisorEditIdeaPanel;
public class SupervisorIdeaSubmissionPage extends
AbstractSupervisorProjectIdeaPage implements MenuHighlightSupervisorProjectIdea{
@SpringBean
private SupervisorIdeaService ideaService;
public SupervisorIdeaSubmissionPage(PageParameters pp) {
super(pp);
Long ideaId = pp.getAsLong("idea");
SupervisorIdea idea;
boolean readOnly = pp.getAsBoolean("readOnly");
if(ideaId!=null)
idea = ideaService.findOne(ideaId);
else {
idea = new SupervisorIdea();
}
add(new SupervisorEditIdeaPanel("editPanel", getUser(), readOnly, new Model<SupervisorIdea>(idea)));
}
}

@ -0,0 +1,6 @@
descriptionField.Required=You need to describe the project idea
descriptionField.StringValidator.minimum=The description needs to be at least ${minimum} characters
requirementField.Required=You need to write some prerequisites
level.Required=The project idea needs a suitable project level
titleField.Required=The project idea needs a title
titleField.StringValidator.minimum=The title needs to be at least ${minimum} characters

@ -12,6 +12,8 @@ import org.apache.wicket.spring.injection.annot.SpringBean;
import org.odlabs.wiquery.ui.dialog.Dialog;
import org.springframework.data.domain.PageRequest;
import se.su.dsv.scipro.SciProSession;
import se.su.dsv.scipro.components.menuhighlighting.MenuHighlightSupervisorProjectIdea;
import se.su.dsv.scipro.data.dataobjects.ScheduleTemplate;
import se.su.dsv.scipro.datatables.ClickableTitleColumn;
import se.su.dsv.scipro.datatables.GenericDataPanel;
@ -28,7 +30,7 @@ import se.su.dsv.scipro.supervisor.panels.WatsonInfoPanel;
import java.util.Iterator;
@Authorization(authorizedRoles = {Roles.EMPLOYEE})
public class SupervisorInterestPage extends AbstractSupervisorPage {
public class SupervisorInterestPage extends AbstractSupervisorProjectIdeaPage {
@SpringBean
private ProjectIdeaService projectIdeaService;

@ -7,12 +7,12 @@ import org.apache.wicket.markup.html.panel.FeedbackPanel;
import se.su.dsv.scipro.SciProSession;
import se.su.dsv.scipro.supervisor.panels.SupervisorMatchedThesisPanel;
public class SupervisorProjectIdeaPage extends AbstractSupervisorPage {
public class SupervisorMyProjectIdeasPage extends AbstractSupervisorProjectIdeaPage {
public static final String MAIN_MENU_LABEL = "Supervisor";
private static final long serialVersionUID = -6146389373527384427L;
public SupervisorProjectIdeaPage(PageParameters pp) {
public SupervisorMyProjectIdeasPage(PageParameters pp) {
super(pp);
Component feedBackPanel = new FeedbackPanel("feedBackPanel");
feedBackPanel.setOutputMarkupId(true);

@ -0,0 +1,15 @@
<!DOCTYPE html>
<html
xmlns:wicket="http://wicket.apache.org/dtds.data/wicket-xhtml1.4-strict.dtd">
<body>
<wicket:extend>
<div class="info-box rounded-box last">
This info box should contain information about the current application period,
the supervisors target numbers and the supervisors current number of supervisions
</div>
<div wicket:id="feedback"></div>
<button wicket:id="ideaLink">Create new project idea</button>
<div class="prepend-top" wicket:id="ideaPanel"></div>
</wicket:extend>
</body>
</html>

@ -0,0 +1,33 @@
package se.su.dsv.scipro.supervisor.pages;
import org.apache.wicket.PageParameters;
import org.apache.wicket.markup.html.link.BookmarkablePageLink;
import org.apache.wicket.markup.html.panel.FeedbackPanel;
import se.su.dsv.scipro.security.auth.Authorization;
import se.su.dsv.scipro.security.auth.roles.Roles;
import se.su.dsv.scipro.supervisor.panels.SupervisorProjectIdeaOverviewPanel;
@Authorization(authorizedRoles={Roles.SYSADMIN})
public class SupervisorProjectIdeaStartPage extends AbstractSupervisorProjectIdeaPage {
private FeedbackPanel feedbackPanel;
public SupervisorProjectIdeaStartPage(PageParameters pp) {
super(pp);
add(feedbackPanel = new FeedbackPanel("feedback"));
feedbackPanel.setOutputMarkupId(true);
add(new SupervisorProjectIdeaOverviewPanel("ideaPanel", getUser()));
addSubmissionPageLink();
}
private void addSubmissionPageLink() {
PageParameters pp = new PageParameters();
pp.put("readOnly", false);
BookmarkablePageLink<Void> ideaLink = new BookmarkablePageLink<Void>("ideaLink", SupervisorIdeaSubmissionPage.class, pp);
add(ideaLink);
}
}

@ -18,6 +18,7 @@ import org.apache.wicket.spring.injection.annot.SpringBean;
import se.su.dsv.scipro.data.dao.interfaces.LanguageDao;
import se.su.dsv.scipro.data.dataobjects.Employee;
import se.su.dsv.scipro.data.dataobjects.Language;
import se.su.dsv.scipro.data.dataobjects.ResearchArea;
import se.su.dsv.scipro.keywords.KeywordContainer;
import se.su.dsv.scipro.keywords.SelectKeywordsPanel;
import se.su.dsv.scipro.match.dao.interfaces.KeywordDao;
@ -26,6 +27,7 @@ import se.su.dsv.scipro.match.dao.interfaces.KeywordTypeDao.TYPE;
import se.su.dsv.scipro.match.dao.interfaces.SupervisorDao;
import se.su.dsv.scipro.match.dataobject.Keyword;
import se.su.dsv.scipro.match.dataobject.KeywordType;
import se.su.dsv.scipro.springdata.services.ResearchAreaService;
/**
* Author: fred
@ -53,6 +55,8 @@ public class ProfilePanel extends Panel {
@SpringBean
KeywordTypeDao keywordTypeDao;
@SpringBean
ResearchAreaService areaService;
@SpringBean
KeywordDao keywordDao;
@ -96,25 +100,23 @@ public class ProfilePanel extends Panel {
add(new Label("unitlabel", employeeModel.getObject().getUnit().getTitle()));
}
final KeywordType areaType = keywordTypeDao.findByType(KeywordTypeDao.TYPE.RESEARCH_AREA);
boolean atLeastOneActive = false;
for (Keyword kw : employeeModel.getObject().getKeywords().getFiltered(areaType)){
if (!kw.isDeleted()){
for (ResearchArea area : employeeModel.getObject().getResearchAreas()){
if (!area.isDeleted()){
atLeastOneActive = true;
break;
}
}
add(new Label("emptylabel", "You do not have any active/existing research areas selected in Daisy. Please make sure that you select at least one active/existing research area in Daisy ASAP.").setVisible(employeeModel.getObject().getKeywords().getFiltered(areaType) == null || employeeModel.getObject().getKeywords().getFiltered(areaType).isEmpty() || !atLeastOneActive));
add(new Label("emptylabel", "You do not have any active/existing research areas selected in Daisy. Please make sure that you select at least one active/existing research area in Daisy ASAP.").setVisible(employeeModel.getObject().getResearchAreas() == null || employeeModel.getObject().getResearchAreas().isEmpty() || !atLeastOneActive));
ListView<Keyword> areaListView = new ListView<Keyword>("arealistview", new ArrayList<Keyword>(keywordDao.findAllFromType(areaType, false))){
ListView<ResearchArea> areaListView = new ListView<ResearchArea>("arealistview", new ArrayList<ResearchArea>(areaService.findAll(false))){
private static final long serialVersionUID = 1L;
@Override
protected void populateItem(ListItem<Keyword> item) {
final Keyword kw = item.getModelObject();
item.add(new Label("arealabel", kw.getKeyword()));
if (!employeeModel.getObject().getKeywords().getFiltered(areaType).contains(kw)){
protected void populateItem(ListItem<ResearchArea> item) {
final ResearchArea area = item.getModelObject();
item.add(new Label("arealabel", area.getTitle()));
if (!employeeModel.getObject().getResearchAreas().contains(area)){
item.setVisible(false);
}
}

@ -0,0 +1,33 @@
<!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 wicket:id="wmc">
<div wicket:id="feedbackPanel"></div>
<div><b>Level:</b></div>
<div class="append-bottom"><span wicket:id="level"></span></div>
<div><b>Required prerequisites:</b></div>
<div class="append-bottom"><textarea rows="3" wicket:id="requirementField"></textarea></div>
<div><b>Title:</b></div>
<div class="append-bottom"><input wicket:id="titleField"/></div>
<div><b>Description:</b></div>
<div class="append-bottom"><textarea wicket:id="descriptionField"></textarea></div>
<div><b>Research area:</b> (set automatically using the research area value from your profile)</div>
<div class="append-bottom"><span wicket:id="researchAreas"><span wicket:id="areaName"></span><br /></span></div>
<div class="append-bottom span-22" wicket:id="keywordPanel"></div>
<div class="append-bototm span-22"><b>Manually assign to students:</b>
<div wicket:id="studentPanel" class="append-bottom"></div>
</div>
<div class="span-4">
<button wicket:id="saveButton">Save</button>
</div>
</div>
</form>
</wicket:panel>
</body>
</html>

@ -0,0 +1,175 @@
package se.su.dsv.scipro.supervisor.panels;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Set;
import java.util.SortedSet;
import java.util.TreeSet;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.ajax.markup.html.form.AjaxButton;
import org.apache.wicket.markup.html.WebMarkupContainer;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.form.Form;
import org.apache.wicket.markup.html.form.RadioChoice;
import org.apache.wicket.markup.html.form.TextArea;
import org.apache.wicket.markup.html.form.TextField;
import org.apache.wicket.markup.html.list.ListItem;
import org.apache.wicket.markup.html.list.ListView;
import org.apache.wicket.markup.html.panel.FeedbackPanel;
import org.apache.wicket.markup.html.panel.Panel;
import org.apache.wicket.model.IModel;
import org.apache.wicket.model.Model;
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.data.dataobjects.Employee;
import se.su.dsv.scipro.data.dataobjects.ProjectClass;
import se.su.dsv.scipro.data.dataobjects.ResearchArea;
import se.su.dsv.scipro.data.dataobjects.Student;
import se.su.dsv.scipro.data.dataobjects.User;
import se.su.dsv.scipro.keywords.KeywordContainer;
import se.su.dsv.scipro.keywords.SelectKeywordsPanel;
import se.su.dsv.scipro.match.dao.interfaces.KeywordTypeDao.TYPE;
import se.su.dsv.scipro.match.dataobject.IdeaParticipation;
import se.su.dsv.scipro.match.dataobject.Keyword;
import se.su.dsv.scipro.match.dataobject.SupervisorIdea;
import se.su.dsv.scipro.reusable.AddRemoveStudentsPanel;
import se.su.dsv.scipro.springdata.services.ProjectClassService;
import se.su.dsv.scipro.springdata.services.SupervisorIdeaService;
import se.su.dsv.scipro.springdata.services.SupervisorService;
import se.su.dsv.scipro.supervisor.pages.SupervisorProjectIdeaStartPage;
/**
* The dialog panel where supervisors may create new project ideas for the students to pick from.
*
* @author emil-siv
*
*/
public class SupervisorEditIdeaPanel extends Panel {
private static final long serialVersionUID = -8553559034214432156L;
@SpringBean
private ProjectClassService levelService;
@SpringBean
private SupervisorIdeaService ideaService;
@SpringBean
private SupervisorService supervisorService;
public SupervisorEditIdeaPanel(String id, User currentUser, boolean readOnly,IModel<SupervisorIdea> model) {
super(id, model);
add(new IdeaForm("form", model, currentUser, readOnly).setEnabled(!readOnly));
}
private class IdeaForm extends Form<SupervisorIdea> {
private static final long serialVersionUID = 5784218491663983845L;
private WebMarkupContainer wmc;
private TextField<String> titleField;
private TextArea<String> requirementField, descriptionField;
private RadioChoice<ProjectClass> level;
private AddRemoveStudentsPanel studentsPanel;
private KeywordContainer regularKwc;
private FeedbackPanel feedbackPanel;
public IdeaForm(String id, final IModel<SupervisorIdea> model, final User currentUser, final boolean readOnly) {
super(id, model);
add(wmc = new WebMarkupContainer("wmc"));
wmc.add(feedbackPanel = new FeedbackPanel("feedbackPanel"));
feedbackPanel.setOutputMarkupId(true);
wmc.add(level = new RadioChoice<ProjectClass>("level", new PropertyModel<ProjectClass>(model.getObject(), "projectClass"), levelService.findAllActive()));
level.setRequired(true);
wmc.add(requirementField = new TextArea<String>("requirementField", new PropertyModel<String>(model, "requirements")));
requirementField.setRequired(true);
wmc.add(titleField = new TextField<String>("titleField", new PropertyModel<String>(model, "title")));
titleField.setRequired(true);
titleField.add(StringValidator.minimumLength(5)); // Title needs to be at least 5 characters
wmc.add(descriptionField = new TextArea<String>("descriptionField", new PropertyModel<String>(model, "description")));
descriptionField.setRequired(true);
descriptionField.add(StringValidator.minimumLength(10)); // Description needs to be at least 10 characters
final Employee ideaCreator = supervisorService.findByUser(currentUser);
Employee ideaSupervisor = model.getObject().getCreator();
Set<ResearchArea> areas;
if(readOnly)
areas = ideaSupervisor.getActiveResearchAreas();
else
areas = ideaCreator.getActiveResearchAreas();
ListView<ResearchArea> areaList = new ListView<ResearchArea>("researchAreas", new ArrayList<ResearchArea>(areas)) {
private static final long serialVersionUID = 1745649109195334927L;
@Override
protected void populateItem(ListItem<ResearchArea> item) {
item.add(new Label("areaName", item.getModelObject().getTitle()));
}
};
wmc.add(areaList);
regularKwc = new KeywordContainer(new HashSet<Keyword>(model.getObject().getKeywords()));
wmc.add(new SelectKeywordsPanel("keywordPanel", new Model<KeywordContainer>(regularKwc), TYPE.REGULAR, "Keywords:") {
private static final long serialVersionUID = -3244572955497357288L;
@Override
public void onUpdateRemove(AjaxRequestTarget target, Keyword removedKeyword) {
Set<Keyword> oldKeywords = new HashSet<Keyword>(regularKwc.getKeywordSet());
oldKeywords.remove(removedKeyword);
model.getObject().setKeywords(oldKeywords);
}
@Override
public void onUpdateAdd(AjaxRequestTarget target, Keyword addedKeyword) {
Set<Keyword> oldKeywords = new HashSet<Keyword>(regularKwc.getKeywordSet());
oldKeywords.add(addedKeyword);
model.getObject().setKeywords(oldKeywords);
}
});
SortedSet<Student> authors = new TreeSet<Student>();
for(IdeaParticipation ip : model.getObject().getIdeaParticipations()){
authors.add(ip.getStudent());
}
wmc.add(studentsPanel = new AddRemoveStudentsPanel("studentPanel", authors) {
private static final long serialVersionUID = 8432765543881357453L;
@Override
public void onUpdate(AjaxRequestTarget target) {
//do nothing
}
});
wmc.add(new AjaxButton("saveButton") {
private static final long serialVersionUID = 1L;
@Override
protected void onSubmit(AjaxRequestTarget target, Form<?> form) {
target.addComponent(feedbackPanel);
try {
ideaService.saveSupervisorCreatedIdea(model, ideaCreator, studentsPanel.getStudentSet());
setResponsePage(SupervisorProjectIdeaStartPage.class);
getSession().info("Idea successfully submitted");
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
protected void onError(AjaxRequestTarget target, Form<?> form) {
target.addComponent(feedbackPanel);
}
});
}
}
}

@ -0,0 +1,14 @@
<!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 wicket:id="ideaDetails"></div>
</form>
</wicket:panel>
</body>
</html>

@ -0,0 +1,30 @@
package se.su.dsv.scipro.supervisor.panels;
import org.apache.wicket.markup.html.form.Form;
import org.apache.wicket.markup.html.panel.Panel;
import org.apache.wicket.model.IModel;
import se.su.dsv.scipro.match.dataobject.SupervisorIdea;
import se.su.dsv.scipro.project.panels.ProjectIdeaDetailsPanel;
public class SupervisorIdeaDetailsPanel extends Panel {
public SupervisorIdeaDetailsPanel(String id, IModel<SupervisorIdea> model) {
super(id, model);
add(new SupervisorIdeaDetailsForm("form", model));
}
private static final long serialVersionUID = 29731924490786784L;
private class SupervisorIdeaDetailsForm extends Form<SupervisorIdea> {
private static final long serialVersionUID = -9118352523380756043L;
public SupervisorIdeaDetailsForm(String id, final IModel<SupervisorIdea> model) {
super(id, model);
add(new ProjectIdeaDetailsPanel("ideaDetails", model, true, true));
}
}
}

@ -0,0 +1,21 @@
<!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>
<div wicket:id="dialog">
<div wicket:id="dialogPanel"></div>
</div>
<form wicket:id="form">
<div class="span-5" wicket:id="levelFilter"></div>
<div class="span-5">
<label>Show only my project ideas</label> <br />
<input type="checkbox" wicket:id="supervisorCheckBox" />
</div>
</form>
<div class="span-24 prepend-top" wicket:id="dataPanel"></div>
</wicket:panel>
</body>
</html>

@ -0,0 +1,183 @@
package se.su.dsv.scipro.supervisor.panels;
import java.util.Iterator;
import org.apache.wicket.PageParameters;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.ajax.markup.html.form.AjaxCheckBox;
import org.apache.wicket.extensions.markup.html.repeater.data.table.IColumn;
import org.apache.wicket.extensions.markup.html.repeater.data.table.PropertyColumn;
import org.apache.wicket.markup.html.form.Form;
import org.apache.wicket.markup.html.panel.EmptyPanel;
import org.apache.wicket.markup.html.panel.Panel;
import org.apache.wicket.model.IModel;
import org.apache.wicket.model.Model;
import org.apache.wicket.spring.injection.annot.SpringBean;
import org.odlabs.wiquery.ui.dialog.Dialog;
import org.springframework.data.domain.PageRequest;
import se.su.dsv.scipro.data.dataobjects.Employee;
import se.su.dsv.scipro.data.dataobjects.User;
import se.su.dsv.scipro.datatables.ClickableIconColumn;
import se.su.dsv.scipro.datatables.ClickableTitleColumn;
import se.su.dsv.scipro.datatables.GenericDataPanel;
import se.su.dsv.scipro.icons.ImageIcon;
import se.su.dsv.scipro.match.dataobject.SupervisorIdea;
import se.su.dsv.scipro.match.panel.FilterFormProjectClass;
import se.su.dsv.scipro.springdata.services.GenericService;
import se.su.dsv.scipro.springdata.services.SupervisorIdeaService;
import se.su.dsv.scipro.springdata.services.SupervisorService;
import se.su.dsv.scipro.supervisor.pages.SupervisorIdeaSubmissionPage;
public class SupervisorProjectIdeaOverviewPanel extends Panel {
@SpringBean
private SupervisorIdeaService ideaService;
@SpringBean
private SupervisorService supervisorService;
private GenericDataPanel<SupervisorIdea> genericDataPanel;
private SupervisorIdeaService.FilterParams params;
private Dialog dialog;
private static final long serialVersionUID = -9010467449322120267L;
public SupervisorProjectIdeaOverviewPanel(String id, final User supervisor) {
super(id);
addDialog();
addDataTable(supervisor);
add(new FilterForm("form", supervisor));
}
private void addDialog() {
dialog = new Dialog("dialog");
dialog.setModal(true);
dialog.setAutoOpen(false);
dialog.setWidth(500);
dialog.setHeight(600);
dialog.add(new EmptyPanel("dialogPanel"));
add(dialog);
}
private void addDataTable(final User supervisor) {
add(genericDataPanel = new GenericDataPanel<SupervisorIdea>("dataPanel") {
private static final long serialVersionUID = -4539188306454725307L;
@Override
public Iterator<SupervisorIdea> getIterator() {
return ideaService.findAll(params, new PageRequest(getTable().getCurrentPage(), getTable().getRowsPerPage(), getSort())).iterator();
}
@Override
public GenericService<SupervisorIdea, Long> getService() {
return ideaService;
}
@Override
public String getSortString() {
return "dateCreated";
}
@Override
public IColumn[] getColumns() {
IColumn[] columns = new IColumn[7];
columns[0] = new PropertyColumn<SupervisorIdea>(Model.of("Date"), "dateCreated", "dateCreated");
columns[1] = new PropertyColumn<SupervisorIdea>(Model.of("Level"), "projectClass", "projectClass");
columns[2] = new ClickableTitleColumn<SupervisorIdea>(Model.of("Title"), "title", "title") {
private static final long serialVersionUID = 4667741924987868274L;
@Override
protected void onClick(IModel<SupervisorIdea> ideaModel,
AjaxRequestTarget target) {
dialog.replace(new SupervisorIdeaDetailsPanel("dialogPanel", ideaModel));
dialog.setTitle("Selected supervisor project idea");
target.addComponent(dialog);
dialog.open(target);
}
};
columns[3] = new PropertyColumn<SupervisorIdea>(Model.of("Creator"), "creator.user.lastName", "creator");
columns[4] = new PropertyColumn<SupervisorIdea>(Model.of("Status"), "ideaStatus", "ideaStatus");
columns[5] = new ClickableIconColumn<SupervisorIdea>(Model.of("Edit"), null, ImageIcon.ICON_EDIT) {
private static final long serialVersionUID = 1498638150378921520L;
@Override
protected void onClick(IModel<SupervisorIdea> clicked,
AjaxRequestTarget target) {
PageParameters pp = new PageParameters();
pp.put("idea", clicked.getObject().getId());
pp.put("readOnly", false);
setResponsePage(SupervisorIdeaSubmissionPage.class, pp);
}
@Override
public boolean shouldBeVisible(IModel<SupervisorIdea> ideaModel) {
return ideaService.isIdeaEditable(ideaModel, supervisor);
}
};
columns[6] = new ClickableIconColumn<SupervisorIdea>(Model.of("Delete"), null, ImageIcon.ICON_DELETE) {
private static final long serialVersionUID = 1718924441848355574L;
@Override
protected void onClick(IModel<SupervisorIdea> ideaModel,
AjaxRequestTarget target) {
ideaService.deleteWaitingIdea(ideaModel);
target.addComponent(getWMC());
}
@Override
public boolean shouldBeVisible(IModel<SupervisorIdea> ideaModel) {
return ideaService.isIdeaEditable(ideaModel, supervisor);
}
};
return columns;
}
});
}
private class FilterForm extends Form<Void> {
private static final long serialVersionUID = 6581597176580961782L;
public FilterForm(String id, final User supervisor) {
super(id);
params = new SupervisorIdeaService.FilterParams();
//FILTERING ON PROJECT CLASS:
final FilterFormProjectClass levelFilter = new FilterFormProjectClass("levelFilter") {
private static final long serialVersionUID = -7758850229259608443L;
@Override
public void ajaxUpdate(AjaxRequestTarget target) {
if(!getProjectClasses().isEmpty()){
params.setLevels(getProjectClasses());
}
target.addComponent(genericDataPanel.getWMC());
}
};
params.setLevels(levelFilter.getProjectClasses());
add(levelFilter);
//FILTER TO ONLY SHOW CURRENT SUPERVISORS PROJECT IDEAS;
final AjaxCheckBox supervisorProjects = new AjaxCheckBox("supervisorCheckBox", new Model<Boolean>()) {
private static final long serialVersionUID = -7624763782876907386L;
@Override
protected void onUpdate(AjaxRequestTarget target) {
if(this.getModelObject()){
Employee current = supervisorService.findByUser(supervisor);
params.setSupervisor(current);
} else {
params.setSupervisor(null);
}
target.addComponent(genericDataPanel.getWMC());
}
};
supervisorProjects.setDefaultModelObject(false);
add(supervisorProjects);
}
}
}

@ -0,0 +1,37 @@
package se.su.dsv.scipro.supervisor.panels;
import java.util.ArrayList;
import java.util.List;
import org.apache.wicket.Page;
import se.su.dsv.scipro.components.AbstractMenuPanel;
import se.su.dsv.scipro.components.menuhighlighting.MenuHighlightSupervisorProjectIdea;
import se.su.dsv.scipro.supervisor.pages.AbstractSupervisorProjectIdeaPage;
import se.su.dsv.scipro.supervisor.pages.SupervisorInterestPage;
import se.su.dsv.scipro.supervisor.pages.SupervisorMyProjectIdeasPage;
import se.su.dsv.scipro.supervisor.pages.SupervisorProjectIdeaStartPage;
public class SupervisorProjectIdeaTabMenuPanel extends AbstractMenuPanel{
private static final long serialVersionUID = 1L;
public SupervisorProjectIdeaTabMenuPanel(String id, Class<? extends Page> containerClass) {
super(id, AbstractSupervisorProjectIdeaPage.class, containerClass);
}
@Override
protected List<MenuItem> getItemList() {
List<MenuItem> items = new ArrayList<MenuItem>();
items.add(new MenuItem("Supervisor project ideas", SupervisorProjectIdeaStartPage.class, MenuHighlightSupervisorProjectIdea.class));
items.add(new MenuItem("Unmatched student project ideas", SupervisorInterestPage.class));
items.add(new MenuItem("My matched student project ideas", SupervisorMyProjectIdeasPage.class));
return items;
}
@Override
protected MenuType getMenuType() {
return MenuType.TAB_MULTIPLE_ROWS;
}
}

@ -4,6 +4,7 @@ import org.apache.wicket.Page;
import se.su.dsv.scipro.SciProSession;
import se.su.dsv.scipro.components.AbstractMenuPanel;
import se.su.dsv.scipro.components.menuhighlighting.MenuHighlightSupervisorMyProjects;
import se.su.dsv.scipro.components.menuhighlighting.MenuHighlightSupervisorProjectIdea;
import se.su.dsv.scipro.peer.pages.SupervisorPeerListPage;
import se.su.dsv.scipro.peer.pages.SupervisorPeerPortalPage;
import se.su.dsv.scipro.security.auth.roles.Roles;
@ -30,8 +31,8 @@ public class SupervisorTabMenuPanel extends AbstractMenuPanel {
List<MenuItem> items = new ArrayList<MenuItem>();
items.add(new MenuItem("My projects", SupervisorStartPage.class, MenuHighlightSupervisorMyProjects.class));
items.add(new MenuItem("My matched project ideas", SupervisorProjectIdeaPage.class));
items.add(new MenuItem("Unmatched project ideas", SupervisorInterestPage.class));
items.add(new MenuItem("Project ideas", SupervisorMyProjectIdeasPage.class, MenuHighlightSupervisorProjectIdea.class));
//items.add(new MenuItem("Unmatched project ideas", SupervisorInterestPage.class));
items.add(new MenuItem("Activity plan templates", SupervisorScheduleTemplatesPage.class));
items.add(new MenuItem("Peer portal", SupervisorPeerListPage.class));
items.add(new MenuItem("Final seminars", SupervisorProjectsFinalSeminarPage.class));

@ -116,8 +116,8 @@ public class TestApplicationPeriodDao {
Set<ProjectClass> projectClassSet = new HashSet<ProjectClass>();
projectClassSet.add(bachelor);
applicationPeriod = applicationPeriodFacade.createApplicationPeriodDates(projectClassSet, date("2011-06-14"), date("2011-07-01"), "name1");
applicationPeriod2 =applicationPeriodFacade.createApplicationPeriodDates(projectClassSet, date("2011-07-15"), date("2011-08-01"), "name2");
applicationPeriod = applicationPeriodFacade.createApplicationPeriodDates(projectClassSet, date("2011-06-14"), date("2011-07-01"), date("2011-07-12"), "name1");
applicationPeriod2 =applicationPeriodFacade.createApplicationPeriodDates(projectClassSet, date("2011-07-15"), date("2011-08-01"), date("2011-08-10"), "name2");
projectIdea1 = createProjectIdea(applicationPeriod, bachelor);
projectIdea2 = createProjectIdea(applicationPeriod, bachelor);
projectIdea3 = createProjectIdea(applicationPeriod, bachelor);
@ -202,7 +202,9 @@ public class TestApplicationPeriodDao {
final Date startDate1 = cal.getTime();
cal.add(Calendar.MONDAY, 3);
final Date endDate1 = cal.getTime();
ApplicationPeriod applicationPeriod = applicationPeriodFacade.createApplicationPeriodDates(myBachelorSet, startDate1, endDate1, "name1");
cal.add(Calendar.DAY_OF_WEEK, 5);
final Date courseStartDate = cal.getTime();
ApplicationPeriod applicationPeriod = applicationPeriodFacade.createApplicationPeriodDates(myBachelorSet, startDate1, endDate1, courseStartDate, "name1");
ProjectIdea projectIdea = createProjectIdea(applicationPeriod, bachelor);
boolean periodRemoved = applicationPeriodFacade.removeApplicationPeriod(applicationPeriod);
assertFalse(periodRemoved); // should be false
@ -224,7 +226,9 @@ public class TestApplicationPeriodDao {
final Date startDate1 = cal.getTime();
cal.add(Calendar.MONTH, 1);
final Date endDate1 = cal.getTime();
ApplicationPeriod applicationPeriod = applicationPeriodFacade.createApplicationPeriodDates(myBachelorSet, startDate1, endDate1, "name1");
cal.add(Calendar.MONTH, 1);
final Date courseStartDate = cal.getTime();
ApplicationPeriod applicationPeriod = applicationPeriodFacade.createApplicationPeriodDates(myBachelorSet, startDate1, endDate1, courseStartDate, "name1");
boolean periodRemoved = applicationPeriodFacade.removeApplicationPeriod(applicationPeriod);
assertTrue(periodRemoved); // should be true
applicationPeriod = applicationPeriodDao.reLoad(applicationPeriod);
@ -245,7 +249,9 @@ there should exist an OPEN "bachelor"application period */
final Date startDate1 = cal.getTime();
cal.add(Calendar.MONTH, 1);
final Date endDate1 = cal.getTime();
applicationPeriodFacade.createApplicationPeriodDates(myBachelorSet, startDate1, endDate1, "name1");
cal.add(Calendar.MONTH, 1);
final Date courseStartDate = cal.getTime();
applicationPeriodFacade.createApplicationPeriodDates(myBachelorSet, startDate1, endDate1, courseStartDate,"name1");
boolean exists = applicationPeriodFacade.openApplicationPeriodsExists(bachelor);
assertTrue(exists); // should exist
}
@ -263,7 +269,9 @@ there should exist an OPEN "bachelor"application period */
final Date startDate1 = cal.getTime();
cal.add(Calendar.MONTH, 1);
final Date endDate1 = cal.getTime();
applicationPeriodFacade.createApplicationPeriodDates(myMasterSet, startDate1, endDate1, "name1");
cal.add(Calendar.MONTH, 1);
final Date courseStartDate = cal.getTime();
applicationPeriodFacade.createApplicationPeriodDates(myMasterSet, startDate1, endDate1, courseStartDate,"name1");
boolean exists = applicationPeriodFacade.openApplicationPeriodsExists(bachelor);
assertFalse(exists); // should NOT exist
}
@ -282,13 +290,18 @@ there should exist an OPEN "bachelor"application period */
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();
applicationPeriodFacade.createApplicationPeriodDates(myBachelorSet, startDate1, endDate1, "name1");
cal.set(2012, Calendar.MAY, 1);
final Date courseStartDate1 = cal.getTime();
applicationPeriodFacade.createApplicationPeriodDates(myBachelorSet, startDate1, endDate1, courseStartDate1, "name1");
cal.set(2012, Calendar.APRIL, 2);
cal.set(Calendar.HOUR_OF_DAY, 14);
final Date startDate2 = cal.getTime();
cal.set(2012, Calendar.MAY, 2);
final Date endDate2 = cal.getTime();
cal.set(2012, Calendar.MAY, 20);
final Date courseStartDate2 = cal.getTime();
boolean periodOverlap = applicationPeriodFacade.doesPeriodOverlap(applicationPeriodFacade.
createApplicationPeriodDates(myBachelorSet, startDate2, endDate2, "name2"));
createApplicationPeriodDates(myBachelorSet, startDate2, endDate2, courseStartDate2, "name2"));
assertFalse(periodOverlap); // should NOT overlap
}
@ -307,7 +320,9 @@ there should exist an OPEN "bachelor"application period */
final Date startDate1 = cal.getTime();
cal.set(2012, Calendar.APRIL, 2);
final Date endDate1 = cal.getTime();
ApplicationPeriod applicationPeriod1 = applicationPeriodFacade.createApplicationPeriodDates(myBachelorSet, startDate1, endDate1, "name1");
cal.set(2012, Calendar.APRIL, 20);
final Date courseStartDate = cal.getTime();
ApplicationPeriod applicationPeriod1 = applicationPeriodFacade.createApplicationPeriodDates(myBachelorSet, startDate1, endDate1, courseStartDate, "name1");
// edit the period
applicationPeriod1.getProjectClass().add(master);
cal.set(2012, Calendar.MAY, 2);
@ -335,10 +350,12 @@ there should exist an OPEN "bachelor"application period */
final Date endDate = cal.getTime();
cal.set(Calendar.HOUR_OF_DAY, 14);
final Date endDate2 = cal.getTime();
applicationPeriodFacade.createApplicationPeriodDates(myBachelorSet, startDate, endDate, "name1");
cal.set(Calendar.APRIL, 20);
final Date courseStartDate = cal.getTime();
applicationPeriodFacade.createApplicationPeriodDates(myBachelorSet, startDate, endDate, courseStartDate, "name1");
Set<ProjectClass> myMasterSet = new HashSet<ProjectClass>();
myMasterSet.add(master);
boolean periodOverlap = applicationPeriodFacade.doesPeriodOverlap(applicationPeriodFacade.createApplicationPeriodDates(myMasterSet, startDate, endDate2, "name1"));
boolean periodOverlap = applicationPeriodFacade.doesPeriodOverlap(applicationPeriodFacade.createApplicationPeriodDates(myMasterSet, startDate, endDate2, courseStartDate, "name1"));
assertFalse(periodOverlap); // should NOT overlap
}
@ -356,12 +373,16 @@ there should exist an OPEN "bachelor"application period */
final Date startDate1 = cal.getTime();
cal.set(2012, Calendar.DECEMBER, 2);
final Date endDate1 = cal.getTime();
applicationPeriodFacade.createApplicationPeriodDates(myBachelorSet, startDate1, endDate1, "name1");
cal.set(2012, Calendar.DECEMBER, 20);
final Date courseStartDate1 = cal.getTime();
applicationPeriodFacade.createApplicationPeriodDates(myBachelorSet, startDate1, endDate1, courseStartDate1, "name1");
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(applicationPeriodFacade.createApplicationPeriodDates(myBachelorSet, startDate2, endDate2, "name1"));
cal.set(2012, Calendar.JUNE, 25);
final Date courseStartDate2 = cal.getTime();
boolean periodOverlap = applicationPeriodFacade.doesPeriodOverlap(applicationPeriodFacade.createApplicationPeriodDates(myBachelorSet, startDate2, endDate2, courseStartDate2, "name1"));
assertTrue(periodOverlap); // should overlap
}
@ -379,13 +400,16 @@ there should exist an OPEN "bachelor"application period */
final Date startDate = cal.getTime();
cal.set(2012, Calendar.APRIL, 2);
final Date endDate = cal.getTime();
applicationPeriodFacade.createApplicationPeriodDates(myBachelorSet, startDate, endDate, "name1");
cal.set(2012, Calendar.APRIL, 5);
final Date courseStartDate = cal.getTime();
applicationPeriodFacade.createApplicationPeriodDates(myBachelorSet, startDate, endDate, courseStartDate, "name1");
cal.set(2012, Calendar.APRIL, 2);
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(applicationPeriodFacade.createApplicationPeriodDates(myBachelorSet, startDate, endDate2, "name1"));
boolean periodOverlap = applicationPeriodFacade.doesPeriodOverlap(applicationPeriodFacade.createApplicationPeriodDates(myBachelorSet, startDate, endDate2, courseStartDate, "name1"));
assertTrue(periodOverlap); // should overlap
}

@ -0,0 +1,335 @@
package se.su.dsv.scipro.springdata;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;
import junit.framework.Assert;
import org.apache.wicket.model.IModel;
import org.apache.wicket.model.Model;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.test.annotation.Rollback;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.transaction.annotation.Transactional;
import se.su.dsv.scipro.data.dataobjects.Employee;
import se.su.dsv.scipro.data.dataobjects.ProjectClass;
import se.su.dsv.scipro.data.dataobjects.Student;
import se.su.dsv.scipro.data.dataobjects.User;
import se.su.dsv.scipro.match.dao.interfaces.KeywordDao;
import se.su.dsv.scipro.match.dao.interfaces.KeywordTypeDao;
import se.su.dsv.scipro.match.dataobject.ApplicationPeriod;
import se.su.dsv.scipro.match.dataobject.Idea.IdeaStatus;
import se.su.dsv.scipro.match.dataobject.IdeaParticipation;
import se.su.dsv.scipro.match.dataobject.Keyword;
import se.su.dsv.scipro.match.dataobject.KeywordType;
import se.su.dsv.scipro.match.dataobject.SupervisorIdea;
import se.su.dsv.scipro.match.facade.ApplicationPeriodFacade;
import se.su.dsv.scipro.springdata.services.ProjectClassService;
import se.su.dsv.scipro.springdata.services.RoleService;
import se.su.dsv.scipro.springdata.services.SupervisorIdeaService;
import se.su.dsv.scipro.springdata.services.SupervisorIdeaService.FilterParams;
import se.su.dsv.scipro.springdata.services.UserService;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(inheritLocations = false, locations = {
"classpath:test-applicationContext.xml"
})
public class TestSupervisorIdea {
@Autowired
private RoleService roleService;
@Autowired
private UserService userService;
@Autowired
private SupervisorIdeaService ideaService;
@Autowired
private ProjectClassService projectClassService;
@Autowired
private ApplicationPeriodFacade periodFacade;
@Autowired
private KeywordTypeDao keywordTypeDao;
@Autowired
private KeywordDao keywordDao;
private ProjectClass bachelor, master;
private User authorUser1, authorUser2, supervisorUser, supervisorUser2, unconfirmedUser;
private Student author1, author2, unconfirmedAuthor;
private Employee supervisor, supervisor2;
private SupervisorIdea waitingBachelorIdea, waitingMasterIdea, takenBachelorIdea, completedMasterIdea;
private ApplicationPeriod bachelorPeriod, masterPeriod;
private Keyword keyword1, keyword2;
@Before
public void startTransaction() throws Exception {
bachelor = new ProjectClass(ProjectClass.BACHELOR, "Bachelor", "Bachelor degree thesis project");
bachelor = projectClassService.save(bachelor);
master = new ProjectClass(ProjectClass.MASTER, "Master", "Master degree thesis project");
master = projectClassService.save(master);
Set<ProjectClass> bachelorSet = new HashSet<ProjectClass>();
bachelorSet.add(bachelor);
Set<ProjectClass> masterSet = new HashSet<ProjectClass>();
masterSet.add(master);
bachelorPeriod = periodFacade.createApplicationPeriod(new HashSet<ProjectClass>(bachelorSet), "Bachelor period");
masterPeriod = periodFacade.createApplicationPeriod(masterSet, "Master period");
supervisorUser = newUser();
supervisorUser2 = newUser();
authorUser1 = newUser();
authorUser2 = newUser();
unconfirmedUser = newUser();
supervisor = newEmployee(supervisorUser);
supervisor2 = newEmployee(supervisorUser2);
author1 = newStudent(authorUser1);
author2 = newStudent(authorUser2);
unconfirmedAuthor = newStudent(unconfirmedUser);
KeywordType type = new KeywordType("test type");
type = keywordTypeDao.save(type);
keyword1 = new Keyword("keyword 1", type);
keyword2 = new Keyword("keyword 2", type);
keyword1 = keywordDao.save(keyword1);
keyword2 = keywordDao.save(keyword2);
waitingBachelorIdea = newIdea(bachelor, bachelorPeriod, supervisor, IdeaStatus.WAITING);
waitingMasterIdea = newIdea(master, masterPeriod, supervisor, IdeaStatus.WAITING);
takenBachelorIdea = newIdea(bachelor, bachelorPeriod, supervisor, IdeaStatus.TAKEN);
completedMasterIdea = newIdea(master, masterPeriod, supervisor, IdeaStatus.COMPLETED);
}
@Test
@Transactional
@Rollback
public void testFindIdeasByStatus() {
Page<SupervisorIdea> waitingIdeaPage = ideaService.findByStatus(IdeaStatus.WAITING, new PageRequest(0, 10));
List<SupervisorIdea> waitingIdeasList = waitingIdeaPage.getContent();
Assert.assertEquals(Arrays.asList(new SupervisorIdea[]{waitingBachelorIdea, waitingMasterIdea}), waitingIdeasList);
Page<SupervisorIdea> takenIdeaPage = ideaService.findByStatus(IdeaStatus.TAKEN, new PageRequest(0, 10));
List<SupervisorIdea> takenIdeasList = takenIdeaPage.getContent();
Assert.assertEquals(Arrays.asList(new SupervisorIdea[]{takenBachelorIdea}), takenIdeasList);
Page<SupervisorIdea> completedIdeaPage = ideaService.findByStatus(IdeaStatus.COMPLETED, new PageRequest(0, 10));
List<SupervisorIdea> completedIdeasList = completedIdeaPage.getContent();
Assert.assertEquals(Arrays.asList(new SupervisorIdea[]{completedMasterIdea}), completedIdeasList);
}
@Test
@Transactional
@Rollback
public void testFindIdeasByStatusAndParamsFiltering() {
Set<ProjectClass> levelSet = new HashSet<ProjectClass>();
levelSet.add(bachelor);
FilterParams params = new FilterParams();
params.setLevels(levelSet);
Page<SupervisorIdea> waitingBachelors = ideaService.findByStatusAndParams(IdeaStatus.WAITING, params, new PageRequest(0, 10));
List<SupervisorIdea> waitingIdeasList = waitingBachelors.getContent();
Assert.assertEquals(Arrays.asList(new SupervisorIdea[]{waitingBachelorIdea}), waitingIdeasList);
levelSet.add(master);
params.setLevels(levelSet);
Page<SupervisorIdea> waitingBachelorAndMasters = ideaService.findByStatusAndParams(IdeaStatus.WAITING, params, new PageRequest(0, 10));
List<SupervisorIdea> waitingIdeas = waitingBachelorAndMasters.getContent();
Assert.assertEquals(Arrays.asList(new SupervisorIdea[]{waitingBachelorIdea, waitingMasterIdea}), waitingIdeas);
}
@Test
@Transactional
@Rollback
public void testFindIdeasByStatusAndAuthor() {
List<SupervisorIdea> ideas = ideaService.findByStatusAndAuthor(IdeaStatus.COMPLETED, author1);
Assert.assertTrue("List is not empty", ideas.isEmpty());
ideas = ideaService.findByStatusAndAuthor(IdeaStatus.WAITING, author1);
Assert.assertTrue("List is not empty", ideas.isEmpty());
IdeaParticipation ip = new IdeaParticipation();
ip.setStudent(author1);
ip.setSupervisorIdea(waitingBachelorIdea);
ip.setConfirmed(true);
author1.addIdeaParticipation(ip);
IdeaParticipation ip2 = new IdeaParticipation();
ip2.setStudent(author2);
ip2.setSupervisorIdea(waitingBachelorIdea);
ip2.setConfirmed(true);
author2.addIdeaParticipation(ip2);
ideas = ideaService.findByStatusAndAuthor(IdeaStatus.WAITING, author1);
Assert.assertTrue("Number of ideas is not 1", ideas.size()==1);
ideas = ideaService.findByStatusAndAuthor(IdeaStatus.WAITING, author2);
Assert.assertTrue("Number of ideas is not 1", ideas.size()==1);
ideas = ideaService.findByStatusAndAuthor(IdeaStatus.COMPLETED, author1);
Assert.assertTrue("List is not empty", ideas.isEmpty());
}
@Test
@Transactional
@Rollback
public void testSaveSupervisorCreatedIdea() {
Assert.assertEquals(new Long(2), ideaService.countByStatus(IdeaStatus.WAITING));
IModel<SupervisorIdea> model = newIdeaModel(bachelor);
ideaService.saveSupervisorCreatedIdea(model, supervisor, new TreeSet<Student>());
Assert.assertEquals(new Long(3), ideaService.countByStatus(IdeaStatus.WAITING));
}
@Test
@Transactional
@Rollback
public void testIfIdeaIsEditable() {
boolean shouldBeTrue = ideaService.isIdeaEditable(Model.of(waitingBachelorIdea), supervisorUser);
Assert.assertTrue("Not true", shouldBeTrue);
boolean shouldBeFalse = ideaService.isIdeaEditable(Model.of(takenBachelorIdea), supervisorUser);
Assert.assertFalse("Not false", shouldBeFalse);
waitingBachelorIdea.setCreator(supervisor2);
boolean shouldAlsoBeFalse = ideaService.isIdeaEditable(Model.of(waitingBachelorIdea), supervisorUser);
Assert.assertFalse("Not false", shouldAlsoBeFalse);
}
@Test
@Transactional
@Rollback
public void testDeleteWaitingIdea() {
Iterable<SupervisorIdea> ideas = ideaService.findAll();
List<SupervisorIdea> ideaList = constructList(ideas);
Assert.assertEquals(4, ideaList.size());
ideaService.deleteWaitingIdea(Model.of(takenBachelorIdea)); //Should not be deleted.
ideas = ideaService.findAll();
ideaList = constructList(ideas);
Assert.assertEquals(4, ideaList.size());
ideaService.deleteWaitingIdea(Model.of(waitingBachelorIdea)); //Should be deleted.
ideas = ideaService.findAll();
ideaList = constructList(ideas);
Assert.assertEquals(3, ideaList.size());
}
/**
* Test that should check if an author has not confirmed his/her participation on a project idea.
*/
@Test
@Transactional
@Rollback
public void testIfAuthorHaveUnconfirmedParticipationOnIdea() {
boolean shouldBeFalse = ideaService.hasTakenIdeas(authorUser1, false);
Assert.assertFalse("Not false",shouldBeFalse);
IdeaParticipation participation = new IdeaParticipation();
participation.setStudent(author2);
participation.setSupervisorIdea(takenBachelorIdea);
participation.setConfirmed(false);
author2.addIdeaParticipation(participation);
boolean shouldBeTrue = ideaService.hasTakenIdeas(authorUser2, false);
Assert.assertTrue("Not true",shouldBeTrue);
}
@Test
@Transactional
@Rollback
public void testIdeaParticipations() {
IdeaParticipation participation = new IdeaParticipation();
participation.setStudent(author1);
participation.setSupervisorIdea(waitingBachelorIdea);
participation.setConfirmed(false);
author1.addIdeaParticipation(participation);
Assert.assertEquals(1, author1.getIdeaParticipations().size());
}
@Test
@Transactional
@Rollback
public void testRemoveIdeaParticipation() {
IdeaParticipation participation = new IdeaParticipation();
participation.setStudent(author1);
participation.setSupervisorIdea(waitingBachelorIdea);
participation.setConfirmed(false);
author1.addIdeaParticipation(participation);
Assert.assertEquals(1, author1.getIdeaParticipations().size());
author1.removeIdeaParticipation(participation);
Assert.assertEquals(0, author1.getIdeaParticipations().size());
}
// HELPER METHODS
private SupervisorIdea newIdea(ProjectClass pc, ApplicationPeriod ap, Employee supervisor, IdeaStatus ideaStatus) {
SupervisorIdea idea = new SupervisorIdea();
idea.setProjectClass(pc);
idea.setApplicationPeriod(ap);
idea.setTitle("Title");
idea.setDescription("Description");
idea.setRequirements("Requisites");
idea.setCreator(supervisor);
idea.setIdeaStatus(ideaStatus);
return ideaService.save(idea);
}
private IModel<SupervisorIdea> newIdeaModel(ProjectClass pc) {
IModel<SupervisorIdea> model = new Model<SupervisorIdea>(new SupervisorIdea());
model.getObject().setDescription("Model description");
model.getObject().setRequirements("Model reqs");
model.getObject().setTitle("Model title");
model.getObject().setProjectClass(pc);
model.getObject().setKeywords(newKeywordSet());
return model;
}
private Set<Keyword> newKeywordSet() {
Set<Keyword> set = new HashSet<Keyword>();
set.add(keyword1);
set.add(keyword2);
return set;
}
private Student newStudent(final User user) {
Student student = new Student();
student.setUser(user);
return (Student) roleService.save(student);
}
private User newUser() {
User user = new User();
return userService.save(user);
}
private Employee newEmployee(final User user) {
Employee emp = new Employee();
emp.setUser(user);
return (Employee) roleService.save(emp);
}
private List<SupervisorIdea> constructList(Iterable<SupervisorIdea> ideas) {
List<SupervisorIdea> list = new ArrayList<SupervisorIdea>();
for (SupervisorIdea idea : ideas) {
list.add(idea);
}
return list;
}
}