Major merge, hopefully stuff still works...
This commit is contained in:
commit
e2277d005b
resources/db_update_scripts
src
main
java/se/su/dsv/scipro
SciProApplication.java
activityplan
facade
pages
ProjectActivityPlanPage.htmlProjectActivityPlanPage.javaSupervisorActivityPlanPage.htmlSupervisorActivityPlanPage.java
panels
admin/pages
AbstractAdminScheduleTemplatesPage.javaAdminScheduleTemplatesEditorPage.javaAdminScheduleTemplatesPage.javaProjectManagementPage.htmlProjectManagementPage.html.BACKUP.10691.htmlProjectManagementPage.html.BASE.10691.htmlProjectManagementPage.html.LOCAL.10691.htmlProjectManagementPage.html.REMOTE.10691.htmlProjectManagementPage.java
checklists/panels
components
data
dao
interfaces
jpa
dataobjects
DomainObject.javaLazyDeletableDomainObject.javaProject.javaProjectSchedule.javaProjectScheduleEvent.javaScheduleTemplate.java
facade
support
dataproviders
ProjectDataProvider.javaProjectScheduleEventDataProvider.javaSortSpecifier.javaSortableDataProvider.javaSortableField.java
json
project
pages
ProjectFilePage.javaProjectPage.javaProjectScheduleGeneratorPage.javaProjectSchedulePlannerPage.javaProjectViewCheckListPage.java
panels
repository
schedule
calendar/icon
groupevent
panels
projectevent
templates/panels
supervisor
pages
AbstractSupervisorScheduleTemplatesPage.javaSupervisorChecklistPage.javaSupervisorScheduleGeneratorPage.javaSupervisorScheduleTemplatesEditorPage.javaSupervisorScheduleTemplatesPage.javaSupervisorViewCheckListPage.java
panels
workerthreads
resources/META-INF
webapp/css
test/java/se/su/dsv/scipro
@ -1 +1,2 @@
|
||||
-- Required DDL changes for production deploy
|
||||
ALTER TABLE schedule_template DROP COLUMN active;
|
||||
|
@ -24,6 +24,7 @@ import org.odlabs.wiquery.ui.themes.IThemableApplication;
|
||||
import org.springframework.web.context.WebApplicationContext;
|
||||
import org.springframework.web.context.support.WebApplicationContextUtils;
|
||||
|
||||
import se.su.dsv.scipro.activityplan.pages.ProjectActivityPlanPage;
|
||||
import se.su.dsv.scipro.admin.pages.AdminFinalSeminarPage;
|
||||
import se.su.dsv.scipro.admin.pages.AdminPeerListPage;
|
||||
import se.su.dsv.scipro.admin.pages.AdminRolePage;
|
||||
@ -221,6 +222,7 @@ public class SciProApplication extends RepositoryApplication implements IThemabl
|
||||
* Project pages
|
||||
*/
|
||||
mountBookmarkablePage("project/conference", ProjectConferencePage.class);
|
||||
mountBookmarkablePage("project/activityplan", ProjectActivityPlanPage.class);
|
||||
mountBookmarkablePage("project/schedule/event", ProjectEventPage.class);
|
||||
mountBookmarkablePage("project/schedule/generator", ProjectScheduleGeneratorPage.class);
|
||||
mountBookmarkablePage("project/files", ProjectFilePage.class);
|
||||
|
@ -0,0 +1,283 @@
|
||||
package se.su.dsv.scipro.activityplan.facade;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Comparator;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.persistence.PersistenceException;
|
||||
|
||||
import org.apache.log4j.Logger;
|
||||
import org.apache.wicket.markup.html.form.upload.FileUpload;
|
||||
import org.joda.time.DateMidnight;
|
||||
import org.joda.time.DateTime;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import edu.emory.mathcs.backport.java.util.Collections;
|
||||
|
||||
import se.su.dsv.scipro.data.dao.interfaces.CheckListDao;
|
||||
import se.su.dsv.scipro.data.dao.interfaces.FileDescriptionDao;
|
||||
import se.su.dsv.scipro.data.dao.interfaces.ProjectScheduleDao;
|
||||
import se.su.dsv.scipro.data.dao.interfaces.ProjectScheduleEventDao;
|
||||
import se.su.dsv.scipro.data.dao.interfaces.ScheduleTemplateDao;
|
||||
import se.su.dsv.scipro.data.dataobjects.CheckList;
|
||||
import se.su.dsv.scipro.data.dataobjects.FileDescription;
|
||||
import se.su.dsv.scipro.data.dataobjects.Project;
|
||||
import se.su.dsv.scipro.data.dataobjects.ProjectClass;
|
||||
import se.su.dsv.scipro.data.dataobjects.ProjectEventTemplate;
|
||||
import se.su.dsv.scipro.data.dataobjects.ProjectSchedule;
|
||||
import se.su.dsv.scipro.data.dataobjects.ProjectScheduleEvent;
|
||||
import se.su.dsv.scipro.data.dataobjects.ScheduleTemplate;
|
||||
import se.su.dsv.scipro.data.dataobjects.User;
|
||||
import se.su.dsv.scipro.exceptions.RenderingSafeException;
|
||||
import se.su.dsv.scipro.repository.FileRepository;
|
||||
import se.su.dsv.scipro.repository.SortOrder;
|
||||
|
||||
/**
|
||||
* Service facade for project schedules and their events.
|
||||
*/
|
||||
@Service
|
||||
public class ProjectScheduleFacade {
|
||||
@Autowired
|
||||
private ProjectScheduleEventDao projectScheduleEventDao;
|
||||
@Autowired
|
||||
private ProjectScheduleDao projectScheduleDao;
|
||||
@Autowired
|
||||
private ScheduleTemplateDao scheduleTemplateDao;
|
||||
@Autowired
|
||||
private CheckListDao checkListDao;
|
||||
@Autowired
|
||||
private FileRepository fileRepository;
|
||||
@Autowired
|
||||
private FileDescriptionDao fileDescriptionDao;
|
||||
private final Logger logger = Logger.getLogger(ProjectScheduleFacade.class);
|
||||
|
||||
public static final String BASE_PATH = "schedule_events";
|
||||
|
||||
/**
|
||||
* Creates a new schedule event and makes the needed object-state linking.
|
||||
* If either parameter is null, a wrapped UnsupportedOperationException is thrown.
|
||||
* @param ps
|
||||
* @param creator
|
||||
* @param date
|
||||
* @return The newly created event.
|
||||
*/
|
||||
@Transactional
|
||||
public ProjectScheduleEvent createNewProjectScheduleEvent(final ProjectSchedule ps, final User creator, String name,
|
||||
String description, boolean uploadRequired, final Date date){
|
||||
if (ps == null || creator == null)
|
||||
throw new RenderingSafeException(new UnsupportedOperationException("Sorry, can't create schedule events without a valid schedule and creator"));
|
||||
ProjectScheduleEvent pse = new ProjectScheduleEvent();
|
||||
pse.setCreator(creator);
|
||||
pse.setProjectSchedule(ps);
|
||||
if (date == null)
|
||||
pse.setDate(new Date());
|
||||
else
|
||||
pse.setDate(date);
|
||||
|
||||
pse.setName(name);
|
||||
pse.setDescription(description);
|
||||
pse.setUploadRequired(uploadRequired);
|
||||
return projectScheduleEventDao.save(pse);
|
||||
}
|
||||
/**
|
||||
* Saves already existing (and possibly detached) schedule event.
|
||||
*/
|
||||
@Transactional
|
||||
public ProjectScheduleEvent saveProjectScheduleEvent(final ProjectScheduleEvent event){
|
||||
if(event == null || event.getProjectSchedule() == null || event.getCreator() == null)
|
||||
throw new RenderingSafeException(new UnsupportedOperationException("Sorry, object state is invalid"));
|
||||
if(event.getId() == null)//Attempt to create a new one if this is a transient entity
|
||||
return createNewProjectScheduleEvent(event.getProjectSchedule(),event.getCreator(),event.getName(),event.getDescription(),event.isUploadRequired(),event.getDate());
|
||||
return projectScheduleEventDao.save(event);
|
||||
}
|
||||
/**
|
||||
* Retrieves a project schedule for the given project, if none exists it will be silently created and returned.
|
||||
* If the project parameter is null, a wrapped UnsupportedOperationException is thrown.
|
||||
* @param p
|
||||
* @return The newly created event.
|
||||
*/
|
||||
@Transactional
|
||||
public ProjectSchedule retrieveProjectSchedule(final Project p){
|
||||
if(p == null)
|
||||
throw new RenderingSafeException(new UnsupportedOperationException("Sorry, can't create a schedule without a valid project"));
|
||||
ProjectSchedule schedule = p.getProjectSchedule();
|
||||
if(schedule == null){
|
||||
schedule = new ProjectSchedule();
|
||||
schedule.updateTimeStamps();
|
||||
schedule.setStartDate(new Date());
|
||||
schedule.setProject(p);
|
||||
schedule = projectScheduleDao.save(schedule);
|
||||
p.setProjectSchedule(schedule);
|
||||
}
|
||||
return schedule;
|
||||
}
|
||||
public ProjectScheduleEvent addChecklistToEvent(ProjectScheduleEvent event, CheckList checkList){
|
||||
event.setCheckList(checkList);
|
||||
return projectScheduleEventDao.save(event);
|
||||
}
|
||||
/**
|
||||
* Stores uploaded file and links it to an event.
|
||||
* @param file
|
||||
* @param user
|
||||
* @param event
|
||||
* @throws IOException
|
||||
*/
|
||||
@Transactional
|
||||
public void storeScheduleEventUpload(final FileUpload file, final User user, final ProjectScheduleEvent event)throws IOException{
|
||||
String path = getAbsolutePath(event);
|
||||
FileDescription fd = null;
|
||||
try {
|
||||
final String identifier = fileRepository.storeFile(file, path);
|
||||
logger.info("Checking for: " + path+ " . " +file.getClientFileName() + " identifier: "+ identifier);
|
||||
if(identifier == null || !fileRepository.existsFileByIdentifier(identifier))
|
||||
throw new IOException("Something went wrong, the file is not saved correctly");
|
||||
fd = fileRepository.retrieveFileDescriptionByIdentifier(identifier);
|
||||
setScheduleEventUpload(fd,user,event);
|
||||
} catch (IOException e) {
|
||||
logger.error("Error while storing uploaded schedule event file: " + e.getMessage());
|
||||
fileRepository.delete(path);
|
||||
throw e;
|
||||
} catch (PersistenceException e) { //If for some reason JPA freaks out, make sure the file is removed
|
||||
logger.error("Error while storing schedule event resource : " + e.getMessage());
|
||||
if (fd != null) {
|
||||
fileDescriptionDao.delete(fd);
|
||||
}
|
||||
fileRepository.delete(path);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Links a previously uploaded file to an event.
|
||||
* @param file
|
||||
* @param user
|
||||
* @param event
|
||||
*/
|
||||
@Transactional
|
||||
public void setScheduleEventUpload(FileDescription file, final User user, final ProjectScheduleEvent event){
|
||||
event.setFileUpload(file);
|
||||
file.setUserId(user.getId());
|
||||
projectScheduleEventDao.save(event);
|
||||
}
|
||||
/**
|
||||
* Attempts to delete a linked file upload from the given event, if the file is referenced from other places: only the linking is removed.
|
||||
* @param event
|
||||
*/
|
||||
@Transactional
|
||||
public void deleteSheduleEventUpload(final ProjectScheduleEvent event){
|
||||
if(event != null && event.getFileUpload() != null){
|
||||
final FileDescription fileDesc = fileDescriptionDao.reLoad(event.getFileUpload());//Reloading detached instance
|
||||
event.setFileUpload(null);
|
||||
projectScheduleEventDao.save(event);
|
||||
logger.debug("Links to this resource: " + fileDescriptionDao.countFileDescriptionByIdentifier(fileDesc.getIdentifier()));
|
||||
if(fileDescriptionDao.countFileDescriptionByIdentifier(fileDesc.getIdentifier()) == 0)//Not linked to other entity, safe to remove
|
||||
if(! fileRepository.delete(fileDesc.getPath())){
|
||||
logger.warn("Failed to remove stale file");
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Adds all schedule events from the given template to the given schedule.
|
||||
* @param schedule A null value will throw runtime exceptions
|
||||
* @param template A null value will throw runtime exceptions
|
||||
* @param user User owning the events. If the parameter is null, the template-owner will be used.
|
||||
* @param startDate Starting date for offset calculations. If the parameter is null, the current day (at midnight) will be used.
|
||||
*/
|
||||
@Transactional
|
||||
public void addProjectScheduleEventsFromTemplate(final ProjectSchedule schedule, ScheduleTemplate template, final User user, final Date startDate){
|
||||
if(schedule == null || template == null)
|
||||
throw new RenderingSafeException(new IllegalArgumentException("No null values allowed for schedule or template parameters"));
|
||||
Date startDateForEvent = (startDate!=null?startDate:new DateMidnight().toDate());
|
||||
template = scheduleTemplateDao.reLoad(template);//Reload lazily linked entities
|
||||
int accumulatedOffset = 0;
|
||||
for(final ProjectEventTemplate eventTemplate : template.getProjectEventTemplates()){
|
||||
accumulatedOffset += (int)eventTemplate.getDaysOffset();
|
||||
final Date dateForEvent = new DateTime(startDateForEvent).plusDays(accumulatedOffset).toDate();
|
||||
final User u = (user!=null?user:eventTemplate.getTemplateCreator());
|
||||
final String title = eventTemplate.getTitle()!=null?eventTemplate.getTitle():"no title";
|
||||
final String desc = eventTemplate.getDescription()!=null?eventTemplate.getDescription():"";
|
||||
createNewProjectScheduleEvent(schedule, u, title, desc, eventTemplate.isRequireHandIn(), dateForEvent);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Generates a new template from the given ProjectSchedule.
|
||||
*/
|
||||
@Transactional
|
||||
public ScheduleTemplate createTemplateFromSchedule(final ProjectSchedule schedule, final User user, final ProjectClass projectClass, final String name, final String description){
|
||||
if(schedule == null || user == null)
|
||||
throw new RenderingSafeException(new IllegalArgumentException("No null values allowed for schedule parameter"));
|
||||
final ProjectSchedule fromSchedule = projectScheduleDao.reLoad(schedule);
|
||||
final ScheduleTemplate template = new ScheduleTemplate();
|
||||
template.setCreator(user);
|
||||
template.setProjectClass(projectClass);
|
||||
template.setTemplateName(name);
|
||||
template.setTemplateDescription(description);
|
||||
template.setSysAdminTemplate(false);
|
||||
final List<ProjectEventTemplate> templateEventList = new ArrayList<ProjectEventTemplate>(fromSchedule.getEvents().size());
|
||||
final Set<ProjectScheduleEvent> eventSet = fromSchedule.getEvents();
|
||||
final List<ProjectScheduleEvent> eventList = new ArrayList<ProjectScheduleEvent>(eventSet.size());
|
||||
eventList.addAll(eventSet);
|
||||
Collections.sort(eventList,new Comparator<ProjectScheduleEvent>(){ //Elements are unordered and needs sorting on date
|
||||
@Override
|
||||
public int compare(ProjectScheduleEvent o1, ProjectScheduleEvent o2) {
|
||||
logger.info("Comparing " +o1.getName() +" to " +o2.getName());
|
||||
return o1.getDate().compareTo(o2.getDate());
|
||||
}
|
||||
});
|
||||
long startingOffset = new DateTime(schedule.getStartDate()).getMillis();
|
||||
for(final ProjectScheduleEvent event : eventList){
|
||||
ProjectEventTemplate eventTemplate = new ProjectEventTemplate();
|
||||
eventTemplate.setTitle(event.getName());
|
||||
final long currentEventTime = (new DateTime(event.getDate()).getMillis());
|
||||
final long diff = ((new DateTime(event.getDate()).getMillis()) - (startingOffset));
|
||||
startingOffset = currentEventTime;//Append mode
|
||||
final long offsetFromPrevious = diff / (24l * 60l * 60l * 1000l);//Convert to days
|
||||
eventTemplate.setdaysOffset((int)offsetFromPrevious);
|
||||
eventTemplate.setDescription(event.getDescription());
|
||||
eventTemplate.setRequireHandIn(event.isUploadRequired());
|
||||
eventTemplate.setTemplateCreator(user);
|
||||
eventTemplate.setScheduleTemplate(template);
|
||||
templateEventList.add(eventTemplate);
|
||||
}
|
||||
template.setProjectEventTemplates(templateEventList);
|
||||
return scheduleTemplateDao.save(template);
|
||||
}
|
||||
/**
|
||||
* Queries for all the available templates
|
||||
* @param project
|
||||
* @return
|
||||
*/
|
||||
@Transactional(readOnly=true)
|
||||
public List<ScheduleTemplate> getAvailableTemplates(final Project project){
|
||||
return scheduleTemplateDao.getScheduleTemplates(null,null,null); //Return active ones for the right project class, ignore other parameters
|
||||
}
|
||||
/**
|
||||
* Removes an event, calls deleteSheduleEventUpload on any linked files.
|
||||
* @param event
|
||||
*/
|
||||
@Transactional
|
||||
public void deleteSheduleEvent(ProjectScheduleEvent event){
|
||||
deleteSheduleEventUpload(event);
|
||||
if(event != null && event.getId() != null){
|
||||
event = projectScheduleEventDao.reLoad(event);
|
||||
projectScheduleEventDao.delete(event);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Returns a list of all available file resources linked to this project.
|
||||
* @param event
|
||||
* @return
|
||||
*/
|
||||
public List<FileDescription> getAvailableResources(final ProjectScheduleEvent event){
|
||||
List<FileDescription> resources = fileRepository.searchFiles(fileRepository.getProjectRootPath(event.getProjectSchedule().getProject().getId()), true);
|
||||
fileRepository.sortFileDescriptions(resources, SortOrder.CreatedDesc);
|
||||
return resources;
|
||||
}
|
||||
private String getAbsolutePath(final ProjectScheduleEvent evt){
|
||||
return (fileRepository.getProjectRootPath(evt.getProjectSchedule().getProject().getId())+BASE_PATH+"/"+evt.getId());
|
||||
}
|
||||
}
|
@ -1,8 +1,7 @@
|
||||
package se.su.dsv.scipro.util;
|
||||
package se.su.dsv.scipro.activityplan.facade;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.wicket.injection.web.InjectorHolder;
|
||||
@ -11,17 +10,15 @@ import org.joda.time.DateMidnight;
|
||||
import org.joda.time.DateTimeConstants;
|
||||
import org.joda.time.Days;
|
||||
|
||||
import se.su.dsv.scipro.SciProSession;
|
||||
import se.su.dsv.scipro.data.dao.interfaces.EventDao;
|
||||
import se.su.dsv.scipro.data.dao.interfaces.ProjectDao;
|
||||
import se.su.dsv.scipro.data.dao.interfaces.ProjectEventDao;
|
||||
import se.su.dsv.scipro.data.dao.interfaces.ScheduleTemplateDao;
|
||||
import se.su.dsv.scipro.data.dataobjects.Project;
|
||||
import se.su.dsv.scipro.data.dataobjects.ProjectEvent;
|
||||
import se.su.dsv.scipro.data.dataobjects.ProjectEventTemplate;
|
||||
import se.su.dsv.scipro.data.dataobjects.ProjectSchedule;
|
||||
import se.su.dsv.scipro.data.dataobjects.ScheduleTemplate;
|
||||
|
||||
@Deprecated
|
||||
public class ScheduleGenerator {
|
||||
|
||||
@SpringBean
|
@ -1,6 +1,5 @@
|
||||
package se.su.dsv.scipro.util;
|
||||
package se.su.dsv.scipro.activityplan.facade;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
@ -8,9 +7,9 @@ import java.util.List;
|
||||
import org.apache.wicket.IClusterable;
|
||||
|
||||
import se.su.dsv.scipro.data.dataobjects.ProjectEvent;
|
||||
import se.su.dsv.scipro.data.dataobjects.ProjectSchedule;
|
||||
import se.su.dsv.scipro.data.dataobjects.ScheduleTemplate;
|
||||
|
||||
@Deprecated
|
||||
public class ScheduleGeneratorResult implements IClusterable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
@ -1,9 +1,8 @@
|
||||
package se.su.dsv.scipro.util;
|
||||
package se.su.dsv.scipro.activityplan.facade;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.TreeSet;
|
||||
|
||||
import org.apache.wicket.injection.web.InjectorHolder;
|
||||
@ -12,7 +11,6 @@ import org.joda.time.DateMidnight;
|
||||
|
||||
import se.su.dsv.scipro.SciProSession;
|
||||
import se.su.dsv.scipro.data.dao.interfaces.ProjectDao;
|
||||
import se.su.dsv.scipro.data.dao.interfaces.ProjectScheduleDao;
|
||||
import se.su.dsv.scipro.data.dao.interfaces.ScheduleTemplateDao;
|
||||
import se.su.dsv.scipro.data.dataobjects.Project;
|
||||
import se.su.dsv.scipro.data.dataobjects.ProjectEvent;
|
||||
@ -20,6 +18,7 @@ import se.su.dsv.scipro.data.dataobjects.ProjectEventTemplate;
|
||||
import se.su.dsv.scipro.data.dataobjects.ProjectSchedule;
|
||||
import se.su.dsv.scipro.data.dataobjects.ScheduleTemplate;
|
||||
|
||||
@Deprecated
|
||||
public class TemplateGenerator { //based on ScheduleGenerator
|
||||
|
||||
/*@SpringBean
|
@ -0,0 +1,8 @@
|
||||
<!DOCTYPE html>
|
||||
<html xmlns:wicket="http://wicket.apache.org/dtds.data/wicket-xhtml1.4-strict.dtd">
|
||||
<body>
|
||||
<wicket:extend>
|
||||
<div wicket:id="activityPlan"></div>
|
||||
</wicket:extend>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,18 @@
|
||||
package se.su.dsv.scipro.activityplan.pages;
|
||||
|
||||
|
||||
import org.apache.wicket.PageParameters;
|
||||
|
||||
import se.su.dsv.scipro.activityplan.panels.ActivityPlanPanel;
|
||||
import se.su.dsv.scipro.project.pages.ProjectPage;
|
||||
import se.su.dsv.scipro.security.auth.Authorization;
|
||||
import se.su.dsv.scipro.security.auth.roles.Roles;
|
||||
|
||||
@Authorization(authorizedRoles={Roles.STUDENT})
|
||||
public class ProjectActivityPlanPage extends ProjectPage {
|
||||
|
||||
public ProjectActivityPlanPage(final PageParameters pp){
|
||||
super(pp);
|
||||
add(new ActivityPlanPanel("activityPlan",getActiveProject(),getUser()));
|
||||
}
|
||||
}
|
@ -0,0 +1,8 @@
|
||||
<!DOCTYPE html>
|
||||
<html xmlns:wicket="http://wicket.apache.org/dtds.data/wicket-xhtml1.4-strict.dtd">
|
||||
<body>
|
||||
<wicket:extend>
|
||||
<div wicket:id="activityPlan"></div>
|
||||
</wicket:extend>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,23 @@
|
||||
package se.su.dsv.scipro.activityplan.pages;
|
||||
|
||||
|
||||
import org.apache.wicket.PageParameters;
|
||||
import org.apache.wicket.markup.html.basic.Label;
|
||||
|
||||
import se.su.dsv.scipro.SciProSession;
|
||||
import se.su.dsv.scipro.activityplan.panels.SupervisorActivityPlanPanel;
|
||||
import se.su.dsv.scipro.security.auth.Authorization;
|
||||
import se.su.dsv.scipro.security.auth.roles.Roles;
|
||||
import se.su.dsv.scipro.supervisor.pages.AbstractSupervisorProjectDetailsPage;
|
||||
|
||||
@Authorization(authorizedRoles={Roles.EMPLOYEE})
|
||||
public class SupervisorActivityPlanPage extends AbstractSupervisorProjectDetailsPage {
|
||||
|
||||
public SupervisorActivityPlanPage(final PageParameters pp){
|
||||
super(pp);
|
||||
if(projectModel.getObject() == null)
|
||||
add(new Label("activityPlan","No project selected"));
|
||||
else
|
||||
add(new SupervisorActivityPlanPanel("activityPlan", projectModel.getObject(),SciProSession.get().getUser()));
|
||||
}
|
||||
}
|
@ -0,0 +1,72 @@
|
||||
<!DOCTYPE html>
|
||||
<html xmlns:wicket="http://wicket.apache.org/dtds.data/wicket-xhtml1.4-strict.dtd">
|
||||
<body>
|
||||
<wicket:panel>
|
||||
<div>
|
||||
<form wicket:id="modeForm">
|
||||
<span wicket:id="modeGroup">
|
||||
<input type="radio" wicket:id="upcoming"/>Show upcoming events<br/>
|
||||
<input type="radio" wicket:id="past"/>Show past events<br/>
|
||||
<input type="radio" wicket:id="between"/>Show events between<br/>
|
||||
<span wicket:id="dateSelection">
|
||||
<span wicket:id="dateFrom">datePicker</span><br/>
|
||||
and <br/>
|
||||
<span wicket:id="dateTo">datePicker</span><br/>
|
||||
</span>
|
||||
<input type="radio" wicket:id="all"/>Show all events<br/>
|
||||
<input type="submit" style="display:none"/>
|
||||
</span>
|
||||
</form>
|
||||
</div>
|
||||
<div wicket:id="editDialog">
|
||||
<div wicket:id="addScheduleEventPanel"></div>
|
||||
</div>
|
||||
<div wicket:id="checklistDialog">
|
||||
<div wicket:id="checkLists">
|
||||
<div wicket:id="listName"></div>
|
||||
<a href="#" wicket:id="addLink">add</a>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div><a href="#" wicket:id="createLink">create new>></a></div>
|
||||
<div wicket:id="addDialog">
|
||||
<div wicket:id="addScheduleEventPanel"></div>
|
||||
</div>
|
||||
<div><a href="#" wicket:id="addFromTemplateLink">add from template>></a></div>
|
||||
<div><a href="#" wicket:id="saveAsTemplateLink">save as template>></a></div>
|
||||
<div wicket:id=dataViewContainer>
|
||||
<div>
|
||||
<table>
|
||||
<thead class="blue-header">
|
||||
<tr>
|
||||
<td><a href="#" wicket:id="dateSort"><span wicket:id="dateLabel">date</span></a></td>
|
||||
<td><a href="#" wicket:id="nameSort"><span wicket:id="nameLabel">name</span></a></td>
|
||||
<td><a href="#" wicket:id="fileUploadSort"><span wicket:id="fileUploadLabel">fileUpload</span></a></td>
|
||||
<td>Checklist</td>
|
||||
<td>Edit</td>
|
||||
<td>Delete</td>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr class="schedule-row" wicket:id="projectScheduleEvents">
|
||||
<td><span wicket:id="date"></span></td>
|
||||
<td><span wicket:id="name"></span></td>
|
||||
<td><span wicket:id="fileUpload"></span></td>
|
||||
<td>
|
||||
<span wicket:id="checkListLabel"></span><a href="#" wicket:id="checkListLink">Checklist</a><a href="#" wicket:id="addCheckListLink">Add checklist</a>
|
||||
</td>
|
||||
<td><a href="#" wicket:id="editEventLink"><img src="images/icons/edit_16x16.png" alt="Edit"/></a></td>
|
||||
<td><a href="#" wicket:id="deleteEventLink"><img src="images/icons/delete_16x16.png" alt="Delete"/></a></td>
|
||||
</tr>
|
||||
<tr class="blue-row">
|
||||
<td colspan="9"></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div wicket:id="nav"></div>
|
||||
</div>
|
||||
<wicket:child />
|
||||
</wicket:panel>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,449 @@
|
||||
package se.su.dsv.scipro.activityplan.panels;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.apache.wicket.PageParameters;
|
||||
import org.apache.wicket.ajax.AjaxEventBehavior;
|
||||
import org.apache.wicket.ajax.AjaxRequestTarget;
|
||||
import org.apache.wicket.ajax.markup.html.AjaxLink;
|
||||
import org.apache.wicket.markup.html.WebMarkupContainer;
|
||||
import org.apache.wicket.markup.html.basic.Label;
|
||||
import org.apache.wicket.markup.html.form.Form;
|
||||
import org.apache.wicket.markup.html.form.Radio;
|
||||
import org.apache.wicket.markup.html.form.RadioGroup;
|
||||
import org.apache.wicket.markup.html.form.upload.FileUpload;
|
||||
import org.apache.wicket.markup.html.link.BookmarkablePageLink;
|
||||
import org.apache.wicket.markup.html.link.Link;
|
||||
import org.apache.wicket.markup.html.list.ListItem;
|
||||
import org.apache.wicket.markup.html.list.ListView;
|
||||
import org.apache.wicket.markup.html.navigation.paging.PagingNavigator;
|
||||
import org.apache.wicket.markup.html.panel.Panel;
|
||||
import org.apache.wicket.markup.repeater.Item;
|
||||
import org.apache.wicket.markup.repeater.data.DataView;
|
||||
import org.apache.wicket.model.IModel;
|
||||
import org.apache.wicket.model.LoadableDetachableModel;
|
||||
import org.apache.wicket.model.Model;
|
||||
import org.apache.wicket.spring.injection.annot.SpringBean;
|
||||
import org.odlabs.wiquery.ui.dialog.Dialog;
|
||||
|
||||
import se.su.dsv.scipro.activityplan.facade.ProjectScheduleFacade;
|
||||
import se.su.dsv.scipro.components.AbstractUploadForm;
|
||||
import se.su.dsv.scipro.components.CustomDateTimeField;
|
||||
import se.su.dsv.scipro.data.dataobjects.CheckList;
|
||||
import se.su.dsv.scipro.data.dataobjects.FileDescription;
|
||||
import se.su.dsv.scipro.data.dataobjects.Project;
|
||||
import se.su.dsv.scipro.data.dataobjects.ProjectScheduleEvent;
|
||||
import se.su.dsv.scipro.data.dataobjects.ScheduleTemplate;
|
||||
import se.su.dsv.scipro.data.dataobjects.User;
|
||||
import se.su.dsv.scipro.dataproviders.ProjectScheduleEventDataProvider;
|
||||
import se.su.dsv.scipro.dataproviders.SortSpecifier;
|
||||
import se.su.dsv.scipro.project.pages.ProjectViewCheckListPage;
|
||||
import se.su.dsv.scipro.repository.panels.FileViewDeletePanel;
|
||||
import se.su.dsv.scipro.util.DateFormatter;
|
||||
|
||||
public class ActivityPlanPanel extends Panel {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@SpringBean
|
||||
private ProjectScheduleFacade facade;
|
||||
|
||||
private Dialog editEventDialog, checklistDialog, addFromTemplateDialog;
|
||||
private AddScheduleEventsFromTemplatePanel addScheduleEventsFromTemplatePanel;
|
||||
private EditScheduleEventPanel editScheduleEventPanel;
|
||||
private DataView<ProjectScheduleEvent> dataView;
|
||||
private WebMarkupContainer dataViewContainer;
|
||||
private ProjectScheduleEventDataProvider sdp;
|
||||
private final Project project;
|
||||
private final User user;
|
||||
private IModel<List<CheckList>> checkListModel;
|
||||
private ListView<CheckList> checkLists;
|
||||
private ProjectScheduleEvent currentEvent = null;
|
||||
|
||||
public ActivityPlanPanel(final String id, final Project project, final User user){
|
||||
super(id);
|
||||
this.project = project;
|
||||
this.user = user;
|
||||
//Setup edit-form
|
||||
formSetup();
|
||||
//Setup pop-up dialog
|
||||
dialogSetup();
|
||||
//Setup data view
|
||||
dataViewSetup();
|
||||
//Setup the model and listview for adding checklists
|
||||
addChecklistSetup();
|
||||
//Setup the dialog window for adding checklists
|
||||
addChecklistDialogSetup();
|
||||
//Add sorting controllers
|
||||
addSortControls();
|
||||
//Add search mode controllers
|
||||
addModeControls();
|
||||
//Add navigator
|
||||
dataViewContainer.add(new PagingNavigator("nav", dataView));
|
||||
}
|
||||
protected final User getUser(){
|
||||
return user;
|
||||
}
|
||||
protected final Project getProject(){
|
||||
return project;
|
||||
}
|
||||
private void addModeControls(){
|
||||
//Create date selection fluff
|
||||
final WebMarkupContainer dateSelection = new WebMarkupContainer("dateSelection");
|
||||
final Calendar cal = Calendar.getInstance();
|
||||
final Date currentDate = cal.getTime();
|
||||
cal.add(Calendar.MONTH, 1);
|
||||
final Date futureDate = cal.getTime();
|
||||
final CustomDateTimeField dateFrom = new CustomDateTimeField("dateFrom",new Model<Date>(currentDate));
|
||||
final CustomDateTimeField dateTo = new CustomDateTimeField("dateTo",new Model<Date>(futureDate));
|
||||
dateSelection.add(dateFrom);
|
||||
dateSelection.add(dateTo);
|
||||
dateSelection.setVisible(false);//Default hidden
|
||||
dateSelection.setOutputMarkupId(true);
|
||||
//Create radio button control group
|
||||
final RadioGroup<ProjectScheduleEventDataProvider.SEARCH_MODE> modeGroup = new RadioGroup<ProjectScheduleEventDataProvider.SEARCH_MODE>("modeGroup", new Model<ProjectScheduleEventDataProvider.SEARCH_MODE>());
|
||||
modeGroup.setOutputMarkupId(true);
|
||||
modeGroup.setModel(new Model<ProjectScheduleEventDataProvider.SEARCH_MODE>(sdp.getSearchMode()));
|
||||
//Create form, should be refactored out once the CustomDatePicker supports reliable callbacks
|
||||
final Form<Void> modeForm = new Form<Void>("modeForm"){
|
||||
private static final long serialVersionUID = 1L;
|
||||
@Override
|
||||
public void onSubmit(){
|
||||
sdp.setSearchMode(modeGroup.getModelObject());
|
||||
sdp.setDateBoundaries(dateFrom.getModelObject(), dateTo.getModelObject());
|
||||
}
|
||||
};
|
||||
//Add radio button components to radio button control group based on available search-modes
|
||||
final ProjectScheduleEventDataProvider.SEARCH_MODE[] arr = ProjectScheduleEventDataProvider.SEARCH_MODE.values();
|
||||
//Java enums are stupid, why can't I just offset this with a named constant like in a "real" language ?
|
||||
for(int i=1;i<arr.length;++i){
|
||||
final ProjectScheduleEventDataProvider.SEARCH_MODE currentMode = arr[i];
|
||||
final Radio<ProjectScheduleEventDataProvider.SEARCH_MODE> radio = new Radio<ProjectScheduleEventDataProvider.SEARCH_MODE>(currentMode.toString(),new Model<ProjectScheduleEventDataProvider.SEARCH_MODE>(currentMode));
|
||||
modeGroup.add(radio);
|
||||
radio.add(new AjaxEventBehavior("onchange") {//Implement state change-behavior
|
||||
private static final long serialVersionUID = 1L;
|
||||
@Override
|
||||
protected void onEvent(final AjaxRequestTarget target) {
|
||||
ProjectScheduleEventDataProvider.SEARCH_MODE selectedMode = radio.getModelObject();
|
||||
dateSelection.setVisible(false);
|
||||
switch(selectedMode){
|
||||
case PROJECT_BETWEEN:
|
||||
dateSelection.setVisible(true);
|
||||
sdp.setDateBoundaries(dateFrom.getModelObject(), dateTo.getModelObject());
|
||||
break;
|
||||
case ALL:
|
||||
sdp.setDateBoundaries(null,null);
|
||||
break;
|
||||
case PROJECT_ALL:
|
||||
sdp.setDateBoundaries(null,null);
|
||||
break;
|
||||
case PROJECT_PAST:
|
||||
sdp.setDateBoundaries(null,new Date());
|
||||
break;
|
||||
case PROJECT_FUTURE:
|
||||
sdp.setDateBoundaries(new Date(),null);
|
||||
break;
|
||||
}
|
||||
modeGroup.setModelObject(currentMode);
|
||||
sdp.setSearchMode(currentMode);
|
||||
target.addComponent(dataViewContainer);
|
||||
target.addComponent(dateSelection);
|
||||
target.addComponent(modeForm);
|
||||
}
|
||||
});
|
||||
}
|
||||
//Add components to hierarchy
|
||||
modeGroup.add(dateSelection);
|
||||
modeForm.add(modeGroup);
|
||||
add(modeForm);
|
||||
}
|
||||
private void dialogSetup(){
|
||||
//Edit dialog
|
||||
editEventDialog = new Dialog("editDialog");
|
||||
editEventDialog.setModal(true);
|
||||
editEventDialog.setAutoOpen(false);
|
||||
editEventDialog.setWidth(500);
|
||||
editEventDialog.setHeight(500);
|
||||
editEventDialog.add(editScheduleEventPanel);
|
||||
add(editEventDialog);
|
||||
//Add from template dialog
|
||||
addFromTemplateDialog = new Dialog("addDialog");
|
||||
addFromTemplateDialog.setModal(true);
|
||||
addFromTemplateDialog.setAutoOpen(false);
|
||||
addFromTemplateDialog.setWidth(300);
|
||||
addFromTemplateDialog.setHeight(200);
|
||||
addFromTemplateDialog.add(addScheduleEventsFromTemplatePanel);
|
||||
add(addFromTemplateDialog);
|
||||
}
|
||||
private void dataViewSetup(){
|
||||
//Config provider
|
||||
dataViewContainer = new WebMarkupContainer("dataViewContainer");
|
||||
sdp = new ProjectScheduleEventDataProvider(getProject());
|
||||
sdp.setSearchMode(ProjectScheduleEventDataProvider.SEARCH_MODE.PROJECT_ALL);
|
||||
//Add data view
|
||||
dataView = new DataView<ProjectScheduleEvent>("projectScheduleEvents", sdp) {
|
||||
private static final long serialVersionUID = 1L;
|
||||
@Override
|
||||
protected void populateItem(final Item<ProjectScheduleEvent> item) {
|
||||
final ProjectScheduleEvent event = item.getModelObject();
|
||||
|
||||
Label checkListLabel = new Label("checkListLabel", "No checklist");
|
||||
PageParameters pp = new PageParameters();
|
||||
|
||||
if(event.getCheckList() != null){
|
||||
pp.put("checklist", event.getCheckList().getId());
|
||||
}
|
||||
|
||||
BookmarkablePageLink<Void> checkListLink = getBookmarkablePageLink(pp);
|
||||
|
||||
AjaxLink<Void> addCheckListLink = new AjaxLink<Void>("addCheckListLink"){
|
||||
private static final long serialVersionUID = 1L;
|
||||
@Override
|
||||
public void onClick(AjaxRequestTarget target) {
|
||||
currentEvent = event;
|
||||
checklistDialog.open(target);
|
||||
}
|
||||
};
|
||||
//new BookmarkablePageLink<Void>("checkListLink", ProjectViewCheckListPage.class, pp);
|
||||
|
||||
item.add(new DateFormatter(DateFormatter.FORMAT.EXTENDED).createFormattedDateLabel("date",event.getDate()));
|
||||
item.add(new Label("name",event.getName()));
|
||||
if(event.getFileUpload() != null){
|
||||
item.add(new FileViewDeletePanel("fileUpload",event.getFileUpload(),new FileViewDeletePanel.FileDeleteStrategy(){
|
||||
@Override
|
||||
public void handleDelete(final FileDescription fileDesc){//Delegate removal
|
||||
facade.deleteSheduleEventUpload(event);
|
||||
}
|
||||
@Override
|
||||
public boolean renderDeleteLink(){ //Only show remove links for the owner of the schedule event
|
||||
return (getUser().equals(event.getCreator()));
|
||||
}
|
||||
}));
|
||||
}else if(event.isUploadRequired())
|
||||
item.add(new ProjectScheduleEventUploadForm(event).createDefaultWrapperPanel("fileUpload"));
|
||||
else
|
||||
item.add(new Label("fileUpload","n/a"));
|
||||
|
||||
item.add(checkListLink);
|
||||
item.add(addCheckListLink);
|
||||
item.add(checkListLabel);
|
||||
|
||||
if(event.getCheckList() == null){
|
||||
checkListLink.setVisible(false);
|
||||
if(willRenderAddChecklistLink()){
|
||||
checkListLabel.setVisible(false);
|
||||
}else{
|
||||
addCheckListLink.setVisible(false);
|
||||
}
|
||||
}else{
|
||||
checkListLabel.setVisible(false);
|
||||
addCheckListLink.setVisible(false);
|
||||
}
|
||||
//add edit/delete links
|
||||
item.add(new AjaxLink<Void>("editEventLink"){
|
||||
private static final long serialVersionUID = 1L;
|
||||
@Override
|
||||
public void onClick(AjaxRequestTarget target) {
|
||||
editScheduleEventPanel.setDataFromEvent(event);
|
||||
target.addComponent(editScheduleEventPanel);
|
||||
editEventDialog.open(target);
|
||||
}
|
||||
@Override
|
||||
public boolean isVisible(){
|
||||
return (willRenderDeleteLink(event));
|
||||
}
|
||||
});
|
||||
item.add(new Link<Void>("deleteEventLink"){
|
||||
private static final long serialVersionUID = 1L;
|
||||
@Override
|
||||
public void onClick() {
|
||||
facade.deleteSheduleEvent(event);
|
||||
}
|
||||
@Override
|
||||
public boolean isVisible(){
|
||||
return (willRenderDeleteLink(event));
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
dataViewContainer.setOutputMarkupId(true);
|
||||
dataViewContainer.add(dataView);
|
||||
add(dataViewContainer);
|
||||
dataView.setItemsPerPage(10);
|
||||
}
|
||||
private void formSetup(){
|
||||
editScheduleEventPanel = new EditScheduleEventPanel("addScheduleEventPanel"){
|
||||
private static final long serialVersionUID = 1L;
|
||||
@Override
|
||||
public void handleSubmit(ProjectScheduleEvent event){
|
||||
facade.saveProjectScheduleEvent(event);
|
||||
}
|
||||
};
|
||||
editScheduleEventPanel.setOutputMarkupId(true);
|
||||
//Add create link
|
||||
add(new AjaxLink<Void>("createLink"){
|
||||
private static final long serialVersionUID = 1L;
|
||||
@Override
|
||||
public void onClick(AjaxRequestTarget target) {
|
||||
ProjectScheduleEvent dummy = new ProjectScheduleEvent();
|
||||
dummy.setDate(new Date());
|
||||
dummy.setName("new event");
|
||||
dummy.setCreator(getUser());
|
||||
dummy.setProjectSchedule(getProject().getProjectSchedule());
|
||||
editScheduleEventPanel.setDataFromEvent(dummy);
|
||||
target.addComponent(editScheduleEventPanel);
|
||||
editEventDialog.open(target);
|
||||
}
|
||||
});
|
||||
//Add template selector
|
||||
final List<ScheduleTemplate> availableTemplates = facade.getAvailableTemplates(getProject());
|
||||
addScheduleEventsFromTemplatePanel = new AddScheduleEventsFromTemplatePanel("addScheduleEventPanel",availableTemplates){
|
||||
private static final long serialVersionUID = 1L;
|
||||
@Override
|
||||
public void handleSubmit(final ScheduleTemplate template, final Date fromDate){
|
||||
facade.addProjectScheduleEventsFromTemplate(getProject().getProjectSchedule(), template, getUser(), fromDate);
|
||||
}
|
||||
};
|
||||
addScheduleEventsFromTemplatePanel.setOutputMarkupId(true);
|
||||
//Add from template link
|
||||
add(new AjaxLink<Void>("addFromTemplateLink"){
|
||||
private static final long serialVersionUID = 1L;
|
||||
@Override
|
||||
public void onClick(AjaxRequestTarget target) {
|
||||
target.addComponent(addScheduleEventsFromTemplatePanel);
|
||||
addFromTemplateDialog.open(target);
|
||||
}
|
||||
@Override
|
||||
public boolean isVisible(){
|
||||
return (availableTemplates.size() > 0);//only show if there are templates to use
|
||||
}
|
||||
});
|
||||
//Save as template link
|
||||
add(new AjaxLink<Void>("saveAsTemplateLink"){
|
||||
private static final long serialVersionUID = 1L;
|
||||
@Override
|
||||
public void onClick(AjaxRequestTarget target) {
|
||||
target.addComponent(addScheduleEventsFromTemplatePanel);
|
||||
facade.createTemplateFromSchedule(getProject().getProjectSchedule(), getUser(), getProject().getProjectClass(), "Generated template", "Generated template description");
|
||||
}
|
||||
@Override
|
||||
public boolean isVisible(){
|
||||
return (getProject().getProjectSchedule() != null && sdp.size() > 0);//only show if there is a schedule with events
|
||||
}
|
||||
});
|
||||
}
|
||||
private void addSortControls(){
|
||||
//Specify wanted sort specifier fields
|
||||
final Set<String> sortFields = new HashSet<String>();
|
||||
sortFields.add("date");
|
||||
sortFields.add("name");
|
||||
sortFields.add("fileUpload");
|
||||
//do a simple translation
|
||||
final HashMap<String, String> headerMap = new HashMap<String,String>();
|
||||
headerMap.put("date","Event Date");
|
||||
headerMap.put("name", "Event name");
|
||||
headerMap.put("fileUpload", "Event resource");
|
||||
for(final SortSpecifier spec : sdp.getAvailableSortSpecifiers(sortFields)){
|
||||
final String fieldBaseName = spec.getFieldName();
|
||||
final Link<Void> link = new Link<Void>(fieldBaseName+"Sort"){
|
||||
private static final long serialVersionUID = 1L;
|
||||
@Override
|
||||
public void onClick(){
|
||||
SortSpecifier current = sdp.getSortSpecifier();
|
||||
if(!spec.equals(current)){
|
||||
sdp.setSortSpecifier(spec);
|
||||
sdp.setAscendingOrder(false);
|
||||
}else{
|
||||
sdp.setAscendingOrder(!sdp.isAscendingOrder());
|
||||
}
|
||||
}
|
||||
};
|
||||
link.add(new Label(fieldBaseName+"Label",headerMap.get(fieldBaseName)));
|
||||
dataViewContainer.add(link);
|
||||
}
|
||||
}
|
||||
private class ProjectScheduleEventUploadForm extends AbstractUploadForm{
|
||||
private static final long serialVersionUID = 1L;
|
||||
private final ProjectScheduleEvent event;
|
||||
ProjectScheduleEventUploadForm(final ProjectScheduleEvent event){
|
||||
super();
|
||||
this.event = event;
|
||||
}
|
||||
@Override
|
||||
protected List<FileDescription> getSelectionElements(){
|
||||
List<FileDescription> availableResources = facade.getAvailableResources(event);
|
||||
return availableResources;
|
||||
}
|
||||
@Override
|
||||
protected void onNewUpload(final FileUpload fileUpload) throws IOException{
|
||||
facade.storeScheduleEventUpload(fileUpload, getUser(), event);
|
||||
}
|
||||
@Override
|
||||
protected void onNewSelection(final FileDescription desc){
|
||||
facade.setScheduleEventUpload(desc, getUser(), event);
|
||||
}
|
||||
}
|
||||
|
||||
private void addChecklistSetup(){
|
||||
checkListModel = new LoadableDetachableModel<List<CheckList>>() {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Override
|
||||
protected List<CheckList> load() {
|
||||
return project.getCheckLists();
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
checkLists = new ListView<CheckList>("checkLists", checkListModel) {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Override
|
||||
protected void populateItem(final ListItem<CheckList> item) {
|
||||
item.add(new Label("listName", item.getModel().getObject().getName()));
|
||||
item.add(new AjaxLink<Void>("addLink"){
|
||||
private static final long serialVersionUID = 1L;
|
||||
@Override
|
||||
public void onClick(AjaxRequestTarget target) {
|
||||
facade.addChecklistToEvent(currentEvent, item.getModelObject());
|
||||
target.addComponent(dataViewContainer);
|
||||
checklistDialog.close(target);
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private void addChecklistDialogSetup(){
|
||||
checklistDialog = new Dialog("checklistDialog");
|
||||
checklistDialog.setModal(true);
|
||||
checklistDialog.setAutoOpen(false);
|
||||
checklistDialog.setWidth(500);
|
||||
checklistDialog.setHeight(500);
|
||||
checklistDialog.add(checkLists);
|
||||
add(checklistDialog);
|
||||
}
|
||||
|
||||
//here comes the methods to be overriden by subclasses
|
||||
|
||||
protected BookmarkablePageLink<Void> getBookmarkablePageLink(PageParameters pp){
|
||||
return new BookmarkablePageLink<Void>("checkListLink", ProjectViewCheckListPage.class, pp);
|
||||
}
|
||||
|
||||
protected boolean willRenderDeleteLink(ProjectScheduleEvent event){
|
||||
return event.getCreator().equals(getUser());
|
||||
}
|
||||
|
||||
protected boolean willRenderAddChecklistLink(){
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
24
src/main/java/se/su/dsv/scipro/activityplan/panels/AddScheduleEventsFromTemplatePanel.html
Normal file
24
src/main/java/se/su/dsv/scipro/activityplan/panels/AddScheduleEventsFromTemplatePanel.html
Normal file
@ -0,0 +1,24 @@
|
||||
<!DOCTYPE html>
|
||||
<html
|
||||
xmlns:wicket="http://wicket.apache.org/dtds.data/wicket-xhtml1.4-strict.dtd">
|
||||
<head>
|
||||
<meta http-equiv="Content-type" content="text/html;charset=UTF-8" />
|
||||
</head>
|
||||
<body>
|
||||
<wicket:panel>
|
||||
<form wicket:id="form">
|
||||
<div class="formRow">
|
||||
<strong>From template:</strong>
|
||||
<select wicket:id="fromTemplate"></select>
|
||||
</div>
|
||||
<div class="formRow">
|
||||
<strong>Start date:</strong>
|
||||
<div wicket:id="startDate"></div>
|
||||
</div>
|
||||
<div>
|
||||
<input type="submit">Save</input>
|
||||
</div>
|
||||
</form>
|
||||
</wicket:panel>
|
||||
</body>
|
||||
</html>
|
38
src/main/java/se/su/dsv/scipro/activityplan/panels/AddScheduleEventsFromTemplatePanel.java
Normal file
38
src/main/java/se/su/dsv/scipro/activityplan/panels/AddScheduleEventsFromTemplatePanel.java
Normal file
@ -0,0 +1,38 @@
|
||||
package se.su.dsv.scipro.activityplan.panels;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.wicket.markup.html.form.DropDownChoice;
|
||||
import org.apache.wicket.markup.html.form.Form;
|
||||
import org.apache.wicket.markup.html.panel.Panel;
|
||||
import org.apache.wicket.model.Model;
|
||||
|
||||
import se.su.dsv.scipro.components.CustomDateTimeField;
|
||||
import se.su.dsv.scipro.data.dataobjects.ScheduleTemplate;
|
||||
|
||||
/**
|
||||
* Simple UI-controller panel for adding template events to a schedule.
|
||||
*/
|
||||
public abstract class AddScheduleEventsFromTemplatePanel extends Panel {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public AddScheduleEventsFromTemplatePanel(final String id, List<ScheduleTemplate> availableTemplates){
|
||||
super(id);
|
||||
final CustomDateTimeField fromDate = new CustomDateTimeField("startDate",new Model<Date>(new Date()));
|
||||
final DropDownChoice<ScheduleTemplate> dropDown = new DropDownChoice<ScheduleTemplate>("fromTemplate",new Model<ScheduleTemplate>(null),availableTemplates);
|
||||
dropDown.setRequired(true);
|
||||
fromDate.setRequired(true);
|
||||
Form<Void> form = new Form<Void>("form"){
|
||||
private static final long serialVersionUID = 1L;
|
||||
@Override
|
||||
public void onSubmit(){
|
||||
handleSubmit(dropDown.getModelObject(),fromDate.getModelObject());
|
||||
}
|
||||
};
|
||||
form.add(fromDate);
|
||||
form.add(dropDown);
|
||||
add(form);
|
||||
}
|
||||
public abstract void handleSubmit(final ScheduleTemplate template, final Date fromDate);
|
||||
}
|
@ -0,0 +1,34 @@
|
||||
<!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="formWrapper">
|
||||
<div class="formRow">
|
||||
<strong>Title:</strong><br />
|
||||
<input type="text" wicket:id="title" />
|
||||
</div>
|
||||
<div class="formRow">
|
||||
<strong>Description:</strong><br />
|
||||
<textarea wicket:id="description"></textarea>
|
||||
</div>
|
||||
<div class="formRow">
|
||||
<strong>Date:</strong>
|
||||
<div wicket:id="dateField"></div>
|
||||
</div>
|
||||
<wicket:enclosure id="requiredToggle">
|
||||
<div>
|
||||
<strong>Require hand in: </strong>
|
||||
<input type="checkbox" wicket:id="requireHandIn" />
|
||||
</div>
|
||||
</wicket:enclosure>
|
||||
<div>
|
||||
<input type="submit">Save</input>
|
||||
</div>
|
||||
</form>
|
||||
</wicket:panel>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,81 @@
|
||||
package se.su.dsv.scipro.activityplan.panels;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
import org.apache.wicket.markup.html.form.CheckBox;
|
||||
import org.apache.wicket.markup.html.form.Form;
|
||||
import org.apache.wicket.markup.html.form.TextArea;
|
||||
import org.apache.wicket.markup.html.form.TextField;
|
||||
import org.apache.wicket.markup.html.panel.Panel;
|
||||
import org.apache.wicket.model.Model;
|
||||
import org.apache.wicket.model.PropertyModel;
|
||||
|
||||
import se.su.dsv.scipro.components.CustomDateTimeField;
|
||||
import se.su.dsv.scipro.data.dataobjects.ProjectScheduleEvent;
|
||||
|
||||
/**
|
||||
* Abstract base class for handling editing/adding of ScheduleEvents
|
||||
* Subtype implementations are just required to handle submission from an internal form.
|
||||
*/
|
||||
public abstract class EditScheduleEventPanel extends Panel {
|
||||
private CustomDateTimeField dp;
|
||||
private TextField<String> title;
|
||||
private TextArea<String> description;
|
||||
private CheckBox handInRequiredCheckBox;
|
||||
private Form<ProjectScheduleEvent> formWrapper;
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public EditScheduleEventPanel(String id){
|
||||
super(id);
|
||||
this.formWrapper = new Form<ProjectScheduleEvent>("formWrapper",new Model<ProjectScheduleEvent>(new ProjectScheduleEvent())){
|
||||
private static final long serialVersionUID = 1L;
|
||||
@Override
|
||||
public void onSubmit(){
|
||||
handleSubmit(getEvent());
|
||||
}
|
||||
};
|
||||
dp = new CustomDateTimeField("dateField", new PropertyModel<Date>(formWrapper.getModelObject(),"date"));
|
||||
title = new TextField<String>("title", new PropertyModel<String>(formWrapper.getModelObject(),"name"));
|
||||
description = new TextArea<String>("description", new PropertyModel<String>(formWrapper.getModelObject(),"description"));
|
||||
handInRequiredCheckBox = new CheckBox("requireHandIn", new PropertyModel<Boolean>(formWrapper.getModelObject(),"uploadRequired")){
|
||||
private static final long serialVersionUID = 1L;
|
||||
@Override
|
||||
public boolean isVisible(){
|
||||
return (formWrapper.getModelObject().getFileUpload()==null);
|
||||
}
|
||||
};
|
||||
dp.setRequired(true);
|
||||
formWrapper.add(title);
|
||||
formWrapper.add(description);
|
||||
formWrapper.add(dp);
|
||||
formWrapper.add(handInRequiredCheckBox);
|
||||
add(formWrapper);
|
||||
}
|
||||
/**
|
||||
* Implement in subtype, is called when the wrapped form is submitted (this is where you want to handle the saved data).
|
||||
*/
|
||||
public abstract void handleSubmit(ProjectScheduleEvent event);
|
||||
/**
|
||||
* Convenience method
|
||||
* @return
|
||||
*/
|
||||
private ProjectScheduleEvent getEvent(){
|
||||
return formWrapper.getModelObject();
|
||||
}
|
||||
/**
|
||||
* Use to set data from a value object to keep the internal model updated.
|
||||
* @param fromEvent
|
||||
*/
|
||||
public void setDataFromEvent(ProjectScheduleEvent fromEvent){
|
||||
getEvent().setId(fromEvent.getId());
|
||||
getEvent().setCreator(fromEvent.getCreator());
|
||||
getEvent().setProjectSchedule(fromEvent.getProjectSchedule());
|
||||
getEvent().setDate(fromEvent.getDate());
|
||||
getEvent().setDescription(fromEvent.getDescription());
|
||||
getEvent().setName(fromEvent.getName());
|
||||
getEvent().setUploadRequired(fromEvent.isUploadRequired());
|
||||
getEvent().setVersion(fromEvent.getVersion());
|
||||
getEvent().setFileUpload(fromEvent.getFileUpload());
|
||||
}
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
<!DOCTYPE html>
|
||||
<html xmlns:wicket="http://wicket.apache.org/dtds.data/wicket-xhtml1.4-strict.dtd">
|
||||
<body>
|
||||
<wicket:panel>
|
||||
<wicket:extend>
|
||||
</wicket:extend>
|
||||
</wicket:panel>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,39 @@
|
||||
package se.su.dsv.scipro.activityplan.panels;
|
||||
|
||||
import org.apache.wicket.PageParameters;
|
||||
import org.apache.wicket.markup.html.link.BookmarkablePageLink;
|
||||
|
||||
import se.su.dsv.scipro.data.dataobjects.Project;
|
||||
import se.su.dsv.scipro.data.dataobjects.ProjectScheduleEvent;
|
||||
import se.su.dsv.scipro.data.dataobjects.User;
|
||||
import se.su.dsv.scipro.supervisor.pages.SupervisorViewCheckListPage;
|
||||
|
||||
public class SupervisorActivityPlanPanel extends ActivityPlanPanel {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public SupervisorActivityPlanPanel(final String id, final Project project, final User user){
|
||||
super(id, project, user);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected BookmarkablePageLink<Void> getBookmarkablePageLink(PageParameters pp){
|
||||
System.out.println("supervisorpageLink");
|
||||
return new BookmarkablePageLink<Void>("checkListLink", SupervisorViewCheckListPage.class, pp);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean willRenderDeleteLink(ProjectScheduleEvent event){
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean willRenderAddChecklistLink(){
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -1,12 +0,0 @@
|
||||
package se.su.dsv.scipro.admin.pages;
|
||||
|
||||
import org.apache.wicket.PageParameters;
|
||||
|
||||
|
||||
public abstract class AbstractAdminScheduleTemplatesPage extends AbstractAdminPage {
|
||||
|
||||
public AbstractAdminScheduleTemplatesPage(final PageParameters pp){
|
||||
super(pp);
|
||||
}
|
||||
|
||||
}
|
@ -9,7 +9,7 @@ import se.su.dsv.scipro.security.auth.Authorization;
|
||||
import se.su.dsv.scipro.security.auth.roles.Roles;
|
||||
|
||||
@Authorization(authorizedRoles={Roles.SYSADMIN})
|
||||
public class AdminScheduleTemplatesEditorPage extends AbstractAdminScheduleTemplatesPage {
|
||||
public class AdminScheduleTemplatesEditorPage extends AbstractAdminPage {
|
||||
|
||||
@SpringBean
|
||||
private ScheduleTemplateDao scheduleTemplateDao;
|
||||
|
@ -4,7 +4,7 @@ import org.apache.wicket.PageParameters;
|
||||
|
||||
import se.su.dsv.scipro.schedule.templates.panels.ScheduleTemplatePanel;
|
||||
|
||||
public class AdminScheduleTemplatesPage extends AbstractAdminScheduleTemplatesPage {
|
||||
public class AdminScheduleTemplatesPage extends AbstractAdminPage {
|
||||
|
||||
public static final String MAIN_MENU_LABEL = "Schedule Templates";
|
||||
|
||||
|
@ -2,34 +2,23 @@
|
||||
<html
|
||||
xmlns:wicket="http://wicket.apache.org/dtds.data/wicket-xhtml1.4-strict.dtd">
|
||||
<body>
|
||||
<wicket:extend>
|
||||
|
||||
<table class="rounded-corner">
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="rounded-left-top"><a href="#" wicket:id="sortById">Id</a></th>
|
||||
<th><a href="#" wicket:id="sortByModified">Modified</a></th>
|
||||
<th><a href="#" wicket:id="sortByTitle">Title</a></th>
|
||||
<th><a href="#" wicket:id="sortByHead">Head supervisor</a></th>
|
||||
<th class="rounded-right-top">Edit</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tfoot>
|
||||
<tr>
|
||||
<td colspan="5" class="rounded-foot"> </td>
|
||||
</tr>
|
||||
</tfoot>
|
||||
<tbody>
|
||||
<tr wicket:id="projectDataView">
|
||||
<td><span wicket:id="id">[id]</span></td>
|
||||
<td><span wicket:id="modified"></span></td>
|
||||
<td><span wicket:id="title">[title]</span></td>
|
||||
<td><span wicket:id="headSupervisor">[A Person]</span></td>
|
||||
<td><a href=# wicket:id="editLink">Edit</a></td>
|
||||
|
||||
<wicket:extend>
|
||||
<table class="rounded-corner">
|
||||
<tr>
|
||||
<th class="rounded-left-top"><a href="#" wicket:id="idSort">Id</a></th>
|
||||
<th><a href="#" wicket:id="lastModifiedSort">Modified</a></th>
|
||||
<th><a href="#" wicket:id="titleSort">Title</a></th>
|
||||
<th><a href="#" wicket:id="headSupervisorSort">Head supervisor</a></th>
|
||||
<th class="rounded-right-top">Edit</th>
|
||||
</tr>
|
||||
<tr wicket:id="projectDataView">
|
||||
<td><span wicket:id="id">[id]</span></td>
|
||||
<td><span wicket:id="modified"></span></td>
|
||||
<td><span wicket:id="title">[title]</span></td>
|
||||
<td><span wicket:id="headSupervisor">[A Person]</span></td>
|
||||
<td><a href=# wicket:id="editLink">Edit</a></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
|
||||
</table>
|
||||
|
||||
<div class="span-18 last">
|
||||
|
80
src/main/java/se/su/dsv/scipro/admin/pages/ProjectManagementPage.html.BACKUP.10691.html
Normal file
80
src/main/java/se/su/dsv/scipro/admin/pages/ProjectManagementPage.html.BACKUP.10691.html
Normal file
@ -0,0 +1,80 @@
|
||||
<!DOCTYPE html>
|
||||
<html
|
||||
xmlns:wicket="http://wicket.apache.org/dtds.data/wicket-xhtml1.4-strict.dtd">
|
||||
<body>
|
||||
<wicket:extend>
|
||||
<table class="rounded-corner">
|
||||
<tr>
|
||||
<th class="rounded-left-top"><a href="#" wicket:id="idSort">Id</a></th>
|
||||
<th><a href="#" wicket:id="lastModifiedSort">Modified</a></th>
|
||||
<th><a href="#" wicket:id="titleSort">Title</a></th>
|
||||
<th><a href="#" wicket:id="headSupervisorSort">Head supervisor</a></th>
|
||||
<th class="rounded-right-top">Edit</th>
|
||||
</tr>
|
||||
<tr wicket:id="projectDataView">
|
||||
<td><span wicket:id="id">[id]</span></td>
|
||||
<td><span wicket:id="modified"></span></td>
|
||||
<td><span wicket:id="title">[title]</span></td>
|
||||
<td><span wicket:id="headSupervisor">[A Person]</span></td>
|
||||
<td><a href=# wicket:id="editLink">Edit</a></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<div class="span-18 last">
|
||||
<span wicket:id="navigator">[dataview navigator]</span>
|
||||
</div>
|
||||
|
||||
<div class="span-18 last">
|
||||
<a href=# wicket:id="createLink">Create new project</a>
|
||||
</div>
|
||||
|
||||
<div class="span-18 last">
|
||||
<div wicket:id="feedback"></div>
|
||||
</div>
|
||||
|
||||
<div class="span-18 last form-border" wicket:id="formContainer">
|
||||
<form wicket:id="projectCreationForm">
|
||||
<div>
|
||||
<strong>Exists in Daisy/Match-system</strong>
|
||||
<div wicket:id="existsInOtherSystems">NO</div>
|
||||
</div>
|
||||
<label for="projectTitle">Project title</label>
|
||||
<div>
|
||||
<input type="text" id="projectTitle" wicket:id="titleField"
|
||||
size="60"></input>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label for="projectClass">Type of project</label>
|
||||
</div>
|
||||
<span wicket:id="projectClass"> <input type="radio"
|
||||
id="projectClass" />
|
||||
</span>
|
||||
|
||||
<div>
|
||||
<label for="students">Participating students</label>
|
||||
</div>
|
||||
<div wicket:id="projectParticipants" id="students"></div>
|
||||
|
||||
<div>
|
||||
<label for="headSupervisor">Head supervisor</label>
|
||||
</div>
|
||||
<div wicket:id="headSupervisor" id="headSupervisor"></div>
|
||||
|
||||
<div>
|
||||
<label for="followers">Add/edit project followers</label>
|
||||
</div>
|
||||
|
||||
<div wicket:id="followers" id="followers"></div>
|
||||
|
||||
|
||||
<div class="span-18 last">
|
||||
<input type="submit" name="Save" title="Save" value="Save" />
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
</wicket:extend>
|
||||
</body>
|
||||
</html>
|
74
src/main/java/se/su/dsv/scipro/admin/pages/ProjectManagementPage.html.BASE.10691.html
Normal file
74
src/main/java/se/su/dsv/scipro/admin/pages/ProjectManagementPage.html.BASE.10691.html
Normal file
@ -0,0 +1,74 @@
|
||||
<!DOCTYPE html>
|
||||
<html
|
||||
xmlns:wicket="http://wicket.apache.org/dtds.data/wicket-xhtml1.4-strict.dtd">
|
||||
<body>
|
||||
<wicket:extend>
|
||||
|
||||
<table class="rounded-table-top">
|
||||
<tr>
|
||||
<th><a href="#" wicket:id="sortById">Id</a></th>
|
||||
<th><a href="#" wicket:id="sortByModified">Modified</a></th>
|
||||
<th><a href="#" wicket:id="sortByTitle">Title</a></th>
|
||||
<th><a href="#" wicket:id="sortByHead">Head supervisor</a></th>
|
||||
<th>Edit</th>
|
||||
</tr>
|
||||
<tr wicket:id="projectDataView">
|
||||
<td><span wicket:id="id">[id]</span></td>
|
||||
<td><span wicket:id="modified"></span></td>
|
||||
<td><span wicket:id="title">[title]</span></td>
|
||||
<td><span wicket:id="headSupervisor">[A Person]</span></td>
|
||||
<td><a href=# wicket:id="editLink">Edit</a></td>
|
||||
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<div class="span-18 last">
|
||||
<span wicket:id="navigator">[dataview navigator]</span>
|
||||
</div>
|
||||
|
||||
<div class="span-18 last">
|
||||
<a href=# wicket:id="createLink">Create new project</a>
|
||||
</div>
|
||||
|
||||
<div class="span-18 last">
|
||||
<div wicket:id="feedback"></div>
|
||||
</div>
|
||||
|
||||
<div class="span-18 last form-border" wicket:id="formContainer">
|
||||
<form wicket:id="projectCreationForm">
|
||||
<div>
|
||||
<strong>Exists in Daisy/Match-system</strong>
|
||||
<div wicket:id="existsInOtherSystems">NO</div>
|
||||
</div>
|
||||
<label for="projectTitle">Project title</label>
|
||||
<div>
|
||||
<input type="text" id="projectTitle" wicket:id="titleField" size="60"></input>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label for="projectClass">Type of project</label>
|
||||
</div>
|
||||
<span wicket:id="projectClass">
|
||||
<input type="radio" id="projectClass"/>
|
||||
</span>
|
||||
|
||||
<div><label for="students">Participating students</label></div>
|
||||
<div wicket:id="projectParticipants" id="students"></div>
|
||||
|
||||
<div><label for="headSupervisor">Head supervisor</label></div>
|
||||
<div wicket:id="headSupervisor" id="headSupervisor"></div>
|
||||
|
||||
<div><label for="followers">Add/edit project followers</label></div>
|
||||
|
||||
<div wicket:id="followers" id="followers"></div>
|
||||
|
||||
|
||||
<div class="span-18 last">
|
||||
<input type="submit" name="Save" title="Save" value="Save"/>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
</wicket:extend>
|
||||
</body>
|
||||
</html>
|
91
src/main/java/se/su/dsv/scipro/admin/pages/ProjectManagementPage.html.LOCAL.10691.html
Normal file
91
src/main/java/se/su/dsv/scipro/admin/pages/ProjectManagementPage.html.LOCAL.10691.html
Normal file
@ -0,0 +1,91 @@
|
||||
<!DOCTYPE html>
|
||||
<html
|
||||
xmlns:wicket="http://wicket.apache.org/dtds.data/wicket-xhtml1.4-strict.dtd">
|
||||
<body>
|
||||
<wicket:extend>
|
||||
|
||||
<table class="rounded-corner">
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="rounded-left-top"><a href="#" wicket:id="sortById">Id</a></th>
|
||||
<th><a href="#" wicket:id="sortByModified">Modified</a></th>
|
||||
<th><a href="#" wicket:id="sortByTitle">Title</a></th>
|
||||
<th><a href="#" wicket:id="sortByHead">Head supervisor</a></th>
|
||||
<th class="rounded-right-top">Edit</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tfoot>
|
||||
<tr>
|
||||
<td colspan="5" class="rounded-foot"> </td>
|
||||
</tr>
|
||||
</tfoot>
|
||||
<tbody>
|
||||
<tr wicket:id="projectDataView">
|
||||
<td><span wicket:id="id">[id]</span></td>
|
||||
<td><span wicket:id="modified"></span></td>
|
||||
<td><span wicket:id="title">[title]</span></td>
|
||||
<td><span wicket:id="headSupervisor">[A Person]</span></td>
|
||||
<td><a href=# wicket:id="editLink">Edit</a></td>
|
||||
|
||||
</tr>
|
||||
</tbody>
|
||||
|
||||
</table>
|
||||
|
||||
<div class="span-18 last">
|
||||
<span wicket:id="navigator">[dataview navigator]</span>
|
||||
</div>
|
||||
|
||||
<div class="span-18 last">
|
||||
<a href=# wicket:id="createLink">Create new project</a>
|
||||
</div>
|
||||
|
||||
<div class="span-18 last">
|
||||
<div wicket:id="feedback"></div>
|
||||
</div>
|
||||
|
||||
<div class="span-18 last form-border" wicket:id="formContainer">
|
||||
<form wicket:id="projectCreationForm">
|
||||
<div>
|
||||
<strong>Exists in Daisy/Match-system</strong>
|
||||
<div wicket:id="existsInOtherSystems">NO</div>
|
||||
</div>
|
||||
<label for="projectTitle">Project title</label>
|
||||
<div>
|
||||
<input type="text" id="projectTitle" wicket:id="titleField"
|
||||
size="60"></input>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label for="projectClass">Type of project</label>
|
||||
</div>
|
||||
<span wicket:id="projectClass"> <input type="radio"
|
||||
id="projectClass" />
|
||||
</span>
|
||||
|
||||
<div>
|
||||
<label for="students">Participating students</label>
|
||||
</div>
|
||||
<div wicket:id="projectParticipants" id="students"></div>
|
||||
|
||||
<div>
|
||||
<label for="headSupervisor">Head supervisor</label>
|
||||
</div>
|
||||
<div wicket:id="headSupervisor" id="headSupervisor"></div>
|
||||
|
||||
<div>
|
||||
<label for="followers">Add/edit project followers</label>
|
||||
</div>
|
||||
|
||||
<div wicket:id="followers" id="followers"></div>
|
||||
|
||||
|
||||
<div class="span-18 last">
|
||||
<input type="submit" name="Save" title="Save" value="Save" />
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
</wicket:extend>
|
||||
</body>
|
||||
</html>
|
74
src/main/java/se/su/dsv/scipro/admin/pages/ProjectManagementPage.html.REMOTE.10691.html
Normal file
74
src/main/java/se/su/dsv/scipro/admin/pages/ProjectManagementPage.html.REMOTE.10691.html
Normal file
@ -0,0 +1,74 @@
|
||||
<!DOCTYPE html>
|
||||
<html
|
||||
xmlns:wicket="http://wicket.apache.org/dtds.data/wicket-xhtml1.4-strict.dtd">
|
||||
<body>
|
||||
<wicket:extend>
|
||||
|
||||
<table class="rounded-table-top">
|
||||
<tr>
|
||||
<th><a href="#" wicket:id="idSort">Id</a></th>
|
||||
<th><a href="#" wicket:id="lastModifiedSort">Modified</a></th>
|
||||
<th><a href="#" wicket:id="titleSort">Title</a></th>
|
||||
<th><a href="#" wicket:id="headSupervisorSort">Head supervisor</a></th>
|
||||
<th>Edit</th>
|
||||
</tr>
|
||||
<tr wicket:id="projectDataView">
|
||||
<td><span wicket:id="id">[id]</span></td>
|
||||
<td><span wicket:id="modified"></span></td>
|
||||
<td><span wicket:id="title">[title]</span></td>
|
||||
<td><span wicket:id="headSupervisor">[A Person]</span></td>
|
||||
<td><a href=# wicket:id="editLink">Edit</a></td>
|
||||
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<div class="span-18 last">
|
||||
<span wicket:id="navigator">[dataview navigator]</span>
|
||||
</div>
|
||||
|
||||
<div class="span-18 last">
|
||||
<a href=# wicket:id="createLink">Create new project</a>
|
||||
</div>
|
||||
|
||||
<div class="span-18 last">
|
||||
<div wicket:id="feedback"></div>
|
||||
</div>
|
||||
|
||||
<div class="span-18 last form-border" wicket:id="formContainer">
|
||||
<form wicket:id="projectCreationForm">
|
||||
<div>
|
||||
<strong>Exists in Daisy/Match-system</strong>
|
||||
<div wicket:id="existsInOtherSystems">NO</div>
|
||||
</div>
|
||||
<label for="projectTitle">Project title</label>
|
||||
<div>
|
||||
<input type="text" id="projectTitle" wicket:id="titleField" size="60"></input>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label for="projectClass">Type of project</label>
|
||||
</div>
|
||||
<span wicket:id="projectClass">
|
||||
<input type="radio" id="projectClass"/>
|
||||
</span>
|
||||
|
||||
<div><label for="students">Participating students</label></div>
|
||||
<div wicket:id="projectParticipants" id="students"></div>
|
||||
|
||||
<div><label for="headSupervisor">Head supervisor</label></div>
|
||||
<div wicket:id="headSupervisor" id="headSupervisor"></div>
|
||||
|
||||
<div><label for="followers">Add/edit project followers</label></div>
|
||||
|
||||
<div wicket:id="followers" id="followers"></div>
|
||||
|
||||
|
||||
<div class="span-18 last">
|
||||
<input type="submit" name="Save" title="Save" value="Save"/>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
</wicket:extend>
|
||||
</body>
|
||||
</html>
|
@ -1,8 +1,10 @@
|
||||
package se.su.dsv.scipro.admin.pages;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.apache.wicket.Component;
|
||||
import org.apache.wicket.PageParameters;
|
||||
@ -50,6 +52,7 @@ import se.su.dsv.scipro.data.dataobjects.ProjectTeamMember;
|
||||
import se.su.dsv.scipro.data.dataobjects.Student;
|
||||
import se.su.dsv.scipro.data.facade.ProjectFacade;
|
||||
import se.su.dsv.scipro.dataproviders.ProjectDataProvider;
|
||||
import se.su.dsv.scipro.dataproviders.SortSpecifier;
|
||||
import se.su.dsv.scipro.dataproviders.SortableDataProvider;
|
||||
import se.su.dsv.scipro.security.auth.Authorization;
|
||||
import se.su.dsv.scipro.security.auth.roles.Roles;
|
||||
@ -93,7 +96,7 @@ public class ProjectManagementPage extends AbstractAdminPage {
|
||||
formContainer.add(form);
|
||||
formContainer.setVisible(false);
|
||||
|
||||
final SortableDataProvider<Project> dataProvider = new ProjectDataProvider(SortableDataProvider.MODIFIED_DESC);
|
||||
final SortableDataProvider<Project> dataProvider = new ProjectDataProvider(/*SortableDataProvider.MODIFIED_DESC*/);
|
||||
DataView<Project> dataView = new DataView<Project>("projectDataView",dataProvider, 20) {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@ -120,43 +123,25 @@ public class ProjectManagementPage extends AbstractAdminPage {
|
||||
add(dataView);
|
||||
add(new PagingNavigator("navigator", dataView));
|
||||
|
||||
//Sorting controllers, could be made prettier
|
||||
add(new Link<Void>("sortById"){
|
||||
@Override
|
||||
public void onClick(){
|
||||
if(dataProvider.getSortSpecifier().equals(SortableDataProvider.ID_ASC))
|
||||
dataProvider.setSortSpecifier(SortableDataProvider.ID_DESC);
|
||||
else
|
||||
dataProvider.setSortSpecifier(SortableDataProvider.ID_ASC);
|
||||
}
|
||||
});
|
||||
add(new Link<Void>("sortByModified"){
|
||||
@Override
|
||||
public void onClick(){
|
||||
if(dataProvider.getSortSpecifier().equals(SortableDataProvider.MODIFIED_ASC))
|
||||
dataProvider.setSortSpecifier(SortableDataProvider.MODIFIED_DESC);
|
||||
else
|
||||
dataProvider.setSortSpecifier(SortableDataProvider.MODIFIED_ASC);
|
||||
}
|
||||
});
|
||||
add(new Link<Void>("sortByTitle"){
|
||||
@Override
|
||||
public void onClick(){
|
||||
if(dataProvider.getSortSpecifier().equals(ProjectDataProvider.TITLE_ASC))
|
||||
dataProvider.setSortSpecifier(ProjectDataProvider.TITLE_DESC);
|
||||
else
|
||||
dataProvider.setSortSpecifier(ProjectDataProvider.TITLE_ASC);
|
||||
}
|
||||
});
|
||||
add(new Link<Void>("sortByHead"){
|
||||
@Override
|
||||
public void onClick(){
|
||||
if(dataProvider.getSortSpecifier().equals(ProjectDataProvider.HEAD_ASC))
|
||||
dataProvider.setSortSpecifier(ProjectDataProvider.HEAD_DESC);
|
||||
else
|
||||
dataProvider.setSortSpecifier(ProjectDataProvider.HEAD_ASC);
|
||||
}
|
||||
});
|
||||
//Add sorting controllers
|
||||
final Set<String> wantedControllers = new HashSet<String>();
|
||||
wantedControllers.add("id");
|
||||
wantedControllers.add("lastModified");
|
||||
wantedControllers.add("title");
|
||||
wantedControllers.add("headSupervisor");
|
||||
for(final SortSpecifier spec : dataProvider.getAvailableSortSpecifiers(wantedControllers)){
|
||||
add(new Link<Void>(spec.getFieldName()+"Sort"){
|
||||
private static final long serialVersionUID = 1L;
|
||||
@Override
|
||||
public void onClick(){
|
||||
SortSpecifier current = dataProvider.getSortSpecifier();
|
||||
if(!spec.equals(current))
|
||||
dataProvider.setSortSpecifier(spec);
|
||||
else
|
||||
dataProvider.setAscendingOrder(!dataProvider.isAscendingOrder());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
AjaxLink<Void> createLink = new AjaxLink<Void>("createLink"){
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
@ -39,7 +39,7 @@
|
||||
<table class="rounded-corner">
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="rounded-left-top">Questions</th>
|
||||
<th class="rounded-left-top">Name</th>
|
||||
<th>Description</th>
|
||||
<th>Hand-in</th>
|
||||
<th>Uploaded by</th>
|
||||
|
@ -41,7 +41,7 @@ public abstract class AbstractUploadForm extends Form<Void> {
|
||||
* Default constructor, uses a fixed id to support the panel wrapper.
|
||||
*/
|
||||
public AbstractUploadForm(){
|
||||
super("uploadForm");
|
||||
this("uploadForm");
|
||||
}
|
||||
/**
|
||||
* Alternate constructor, allowing for altered behavior for enforcing required fields.
|
||||
@ -108,7 +108,8 @@ public abstract class AbstractUploadForm extends Form<Void> {
|
||||
|
||||
fileUploadField = new FileUploadField("fileUpload",new PropertyModel<FileUpload>(this,"upload"));
|
||||
add(fileUploadField);
|
||||
add(new Label("linkResourceLabel", new Model<String>("Or choose existing resource")));
|
||||
add(new Label("linkResourceLabel", new Model<String>("Link to existing resource")));
|
||||
add(new Label("uploadResourceLabel", new Model<String>("Upload new")));
|
||||
List<FileDescription> availableResources = getSelectionElements();
|
||||
final FileListSelect fileListSelect = new FileListSelect("linkResource", availableResources);
|
||||
add(fileListSelect);
|
||||
@ -130,10 +131,8 @@ public abstract class AbstractUploadForm extends Form<Void> {
|
||||
fileDesc = linkedResource;
|
||||
onNewSelection(fileDesc);
|
||||
}
|
||||
}catch(final RuntimeException re){//Allow implementations to signal failure via runtimes
|
||||
error(re.getMessage());
|
||||
}catch(final IOException ioe){//Use explicit error handling for uploading causing IOExceptions
|
||||
error("An error occured while uploading the document, please try again");
|
||||
error("An error occured while uploading the resource, please try again");
|
||||
}
|
||||
onFinished();
|
||||
}
|
||||
|
@ -7,21 +7,22 @@
|
||||
<wicket:panel>
|
||||
<form wicket:id="uploadForm">
|
||||
<div>
|
||||
<input type="file" wicket:id="fileUpload" />
|
||||
</div>
|
||||
<wicket:enclosure child="linkResource">
|
||||
<div>
|
||||
<span wicket:id="linkResourceLabel">[Or choose existing resource]</span>
|
||||
<select wicket:id="linkResource">
|
||||
<option selected value="0"></option>
|
||||
<wicket:enclosure child="linkResource">
|
||||
<span wicket:id="linkResourceLabel"></span>:
|
||||
<select wicket:id="linkResource" style="font-size:80%">
|
||||
<option selected value="0">[Link to existing resource]</option>
|
||||
<option value="somefile.txt">somefile</option>
|
||||
<option value="anotherfile.txt">anotherfile</option>
|
||||
</select>
|
||||
</wicket:enclosure>
|
||||
</div>
|
||||
</wicket:enclosure>
|
||||
<div>
|
||||
<button type="submit" wicket:id="submitButton">
|
||||
Upload report
|
||||
<span wicket:id="uploadResourceLabel">[Upload new resource]</span>:
|
||||
<input type="file" wicket:id="fileUpload" style="font-size:80%"/>
|
||||
</div>
|
||||
<div>
|
||||
<button type="submit" wicket:id="submitButton" style="font-size:80%">
|
||||
<img src="css/blueprint/plugins/buttons/icons/tick.png" alt="" style="height:10px;width:10px;"/>Save
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
|
@ -5,9 +5,7 @@ import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import se.su.dsv.scipro.data.dataobjects.Event;
|
||||
import se.su.dsv.scipro.data.dataobjects.GroupEvent;
|
||||
import se.su.dsv.scipro.data.dataobjects.Project;
|
||||
import se.su.dsv.scipro.data.dataobjects.ProjectEvent;
|
||||
import se.su.dsv.scipro.data.dataobjects.User;
|
||||
/**
|
||||
* @author Martin Peters - mpeters@dsv.su.se
|
||||
|
@ -1,11 +1,6 @@
|
||||
package se.su.dsv.scipro.data.dao.interfaces;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import se.su.dsv.scipro.data.dataobjects.Event;
|
||||
import se.su.dsv.scipro.data.dataobjects.ProjectSchedule;
|
||||
|
||||
public interface ProjectScheduleDao extends Dao<ProjectSchedule>{
|
||||
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,32 @@
|
||||
package se.su.dsv.scipro.data.dao.interfaces;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import se.su.dsv.scipro.data.dataobjects.Project;
|
||||
import se.su.dsv.scipro.data.dataobjects.ProjectScheduleEvent;
|
||||
import se.su.dsv.scipro.data.support.QueryParams;
|
||||
|
||||
public interface ProjectScheduleEventDao extends Dao<ProjectScheduleEvent>{
|
||||
/**
|
||||
* Shorthand, equivalent to calling findEventsByProject(Project,null,null,null)
|
||||
*/
|
||||
public List<ProjectScheduleEvent> findEventsByProject(final Project project);
|
||||
/**
|
||||
* Shorthand, equivalent to calling findEventsByProject(Project,null,null,QueryParams)
|
||||
*/
|
||||
public List<ProjectScheduleEvent> findEventsByProject(final Project project,final QueryParams qParams);
|
||||
/**
|
||||
* Shorthand, equivalent to calling findEventsByProject(Project,Date,Date,null)
|
||||
*/
|
||||
public List<ProjectScheduleEvent> findEventsByProject(final Project project,final Date from, final Date to);
|
||||
/**
|
||||
* Finds all Events attached to the given project, dates and query parameters are optional and will be silently ignored if null.
|
||||
*/
|
||||
public List<ProjectScheduleEvent> findEventsByProject(final Project project,final Date from, final Date to, final QueryParams qParams);
|
||||
/**
|
||||
* Counts all Events attached to the given project, supplying of dates are optional (any combination of dates can be used).
|
||||
*/
|
||||
public int countEventsByProject(final Project project,final Date from,final Date to);
|
||||
}
|
||||
|
@ -7,6 +7,5 @@ import se.su.dsv.scipro.data.dataobjects.ScheduleTemplate;
|
||||
import se.su.dsv.scipro.data.dataobjects.User;
|
||||
|
||||
public interface ScheduleTemplateDao extends Dao<ScheduleTemplate>{
|
||||
public List<ScheduleTemplate> getScheduleTemplates(final User creator, final Boolean isSysAdminTemplate,
|
||||
final Boolean active, final ProjectClass projectClass);
|
||||
public List<ScheduleTemplate> getScheduleTemplates(final User creator, final Boolean isSysAdminTemplate, final ProjectClass projectClass);
|
||||
}
|
||||
|
@ -6,6 +6,10 @@ import java.util.List;
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.persistence.PersistenceException;
|
||||
import javax.persistence.TypedQuery;
|
||||
import javax.persistence.criteria.CriteriaBuilder;
|
||||
import javax.persistence.criteria.CriteriaQuery;
|
||||
import javax.persistence.criteria.Order;
|
||||
import javax.persistence.criteria.Root;
|
||||
|
||||
import org.hibernate.ejb.QueryHints;
|
||||
import org.springframework.orm.jpa.JpaCallback;
|
||||
@ -14,6 +18,8 @@ import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import se.su.dsv.scipro.data.dao.interfaces.Dao;
|
||||
import se.su.dsv.scipro.data.dataobjects.DomainObject;
|
||||
import se.su.dsv.scipro.data.support.QueryParams;
|
||||
import se.su.dsv.scipro.exceptions.RenderingSafeException;
|
||||
|
||||
/**
|
||||
*
|
||||
@ -115,6 +121,54 @@ public abstract class AbstractDaoJPAImp<T extends DomainObject> extends JpaDaoSu
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
protected final void setQueryOrdering(final CriteriaQuery<T> query,final QueryParams qParams, final CriteriaBuilder cb,final Root<T> root){
|
||||
if(qParams != null && qParams.getSortFieldName() != null){
|
||||
final Order o = qParams.isSortFieldOrderAscending()?cb.asc(root.get(qParams.getSortFieldName())):cb.desc(root.get(qParams.getSortFieldName()));
|
||||
query.orderBy(o);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Utility method used to limit output results of a query
|
||||
* @param query
|
||||
* @param start
|
||||
* @param count
|
||||
*/
|
||||
private final void setQueryLimits(final TypedQuery<T> query,final int first, final int count){
|
||||
if(first > 0)
|
||||
query.setFirstResult(first);
|
||||
if(count >= 0)
|
||||
query.setMaxResults(count);
|
||||
}
|
||||
/**
|
||||
* Factory style utility method, creates a typed query ready for running based on input parameters.
|
||||
* @param queryString Should be a complete regular query string capable of running, without ORDER BY clause, a RenderingSafeException is thrown in case of an illegal value.
|
||||
* @param sortingFieldPath If using joins and multiple joined tables share identifiers, you will need to supply information on which identifier entity you want to sort on. If the query is a single table one, just supply null.
|
||||
* @param qParams Standard query parameters, what field to sort on etc. A null qParams will just create a regular query, a null qParams.getSortFieldName() will not perform any sorting.
|
||||
* @param em EntityManager used to create the query, supplying null is undefined.
|
||||
* @return
|
||||
* Example usage (from ProjectScheduleEventDaoJPAImp):
|
||||
* <code>
|
||||
* String queryStr = "SELECT e FROM ProjectScheduleEvent AS e JOIN e.projectSchedule AS s WHERE s.project = :project AND e.date > :from AND e.date < :to";
|
||||
* final Date dateFrom = from!=null?from:new Date(0);
|
||||
* final Date dateTo = to!=null?to:new Date(Long.MAX_VALUE);
|
||||
* TypedQuery<ProjectScheduleEvent> query = createSortedSelectQuery(queryStr,"e",qParams,em);
|
||||
* query.setParameter("project", project);
|
||||
* query.setParameter("from", dateFrom);
|
||||
* query.setParameter("to", dateTo);
|
||||
* return query.getResultList();
|
||||
* </code>
|
||||
*/
|
||||
protected final TypedQuery<T> createSortedSelectQuery(final String queryString,final String sortingFieldPath,final QueryParams qParams,final EntityManager em){
|
||||
if(queryString == null || queryString.contains("ORDER BY"))
|
||||
throw new RenderingSafeException(new IllegalStateException("Supplying null as a query string is not allowed"));
|
||||
String querySQLString = queryString;
|
||||
if(qParams != null && qParams.getSortFieldName() != null){ //Add sorting details if present
|
||||
querySQLString += (" ORDER BY "+(sortingFieldPath!=null?sortingFieldPath+".":"")+qParams.getSortFieldName()+" "+(qParams.isSortFieldOrderAscending()?" ASC":" DESC"));
|
||||
}
|
||||
final TypedQuery<T> query = em.createQuery(querySQLString,getDomainClass());
|
||||
if(qParams!=null) //Add query limits if present
|
||||
setQueryLimits(query,qParams.getFirstResultIndex(),qParams.getResultCount());
|
||||
return query;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,67 @@
|
||||
package se.su.dsv.scipro.data.dao.jpa;
|
||||
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.persistence.PersistenceException;
|
||||
import javax.persistence.TypedQuery;
|
||||
|
||||
import org.springframework.orm.jpa.JpaCallback;
|
||||
import org.springframework.stereotype.Repository;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import se.su.dsv.scipro.data.dao.interfaces.ProjectScheduleEventDao;
|
||||
import se.su.dsv.scipro.data.dataobjects.Project;
|
||||
import se.su.dsv.scipro.data.dataobjects.ProjectScheduleEvent;
|
||||
import se.su.dsv.scipro.data.support.QueryParams;
|
||||
|
||||
@Repository("projectScheduleEventDao")
|
||||
public class ProjectScheduleEventDaoJPAImp extends LazyDeleteAbstractDaoJPAImp<ProjectScheduleEvent> implements ProjectScheduleEventDao{
|
||||
public ProjectScheduleEventDaoJPAImp() {
|
||||
super(ProjectScheduleEvent.class);
|
||||
}
|
||||
@Transactional(readOnly=true)
|
||||
public List<ProjectScheduleEvent> findEventsByProject(final Project project){
|
||||
return findEventsByProject(project,null,null,null);
|
||||
}
|
||||
@Transactional(readOnly=true)
|
||||
public List<ProjectScheduleEvent> findEventsByProject(final Project project, final QueryParams qParams){
|
||||
return findEventsByProject(project,null,null,qParams);
|
||||
}
|
||||
@Transactional(readOnly=true)
|
||||
public List<ProjectScheduleEvent> findEventsByProject(final Project project, final Date from, final Date to){
|
||||
return findEventsByProject(project,from,to,null);
|
||||
}
|
||||
@Transactional(readOnly=true)
|
||||
public List<ProjectScheduleEvent> findEventsByProject(final Project project, final Date from, final Date to, final QueryParams qParams){
|
||||
return getJpaTemplate().execute(new JpaCallback<List<ProjectScheduleEvent>>() {
|
||||
public List<ProjectScheduleEvent> doInJpa(EntityManager em) throws PersistenceException {
|
||||
String queryStr = "SELECT e FROM ProjectScheduleEvent AS e JOIN e.projectSchedule AS s WHERE s.project = :project AND e.date > :from AND e.date < :to";
|
||||
final Date dateFrom = from!=null?from:new Date(0);
|
||||
final Date dateTo = to!=null?to:new Date(Long.MAX_VALUE);
|
||||
TypedQuery<ProjectScheduleEvent> query = createSortedSelectQuery(queryStr,"e",qParams,em);
|
||||
query.setParameter("project", project);
|
||||
query.setParameter("from", dateFrom);
|
||||
query.setParameter("to", dateTo);
|
||||
return query.getResultList();
|
||||
}
|
||||
});
|
||||
}
|
||||
@Transactional(readOnly=true)
|
||||
public int countEventsByProject(final Project project,final Date from,final Date to){
|
||||
return getJpaTemplate().execute(new JpaCallback<Integer>() {
|
||||
public Integer doInJpa(EntityManager em) throws PersistenceException {
|
||||
final Date dateFrom = from!=null?from:new Date(0);
|
||||
final Date dateTo = to!=null?to:new Date(Long.MAX_VALUE);
|
||||
TypedQuery<Long> query = em.createQuery("SELECT COUNT(e) FROM ProjectScheduleEvent AS e JOIN e.projectSchedule AS s WHERE s.project = :project AND e.date > :from AND e.date < :to", Long.class);
|
||||
query.setParameter("project", project);
|
||||
query.setParameter("from", dateFrom);
|
||||
query.setParameter("to", dateTo);
|
||||
return (query.getSingleResult()).intValue();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
@ -26,8 +26,7 @@ public class ScheduleTemplateDaoJPAImp extends AbstractDaoJPAImp<ScheduleTemplat
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public List<ScheduleTemplate> getScheduleTemplates(final User creator, final Boolean isSysAdminTemplate,
|
||||
final Boolean active, final ProjectClass projectClass) {
|
||||
public List<ScheduleTemplate> getScheduleTemplates(final User creator, final Boolean isSysAdminTemplate, final ProjectClass projectClass) {
|
||||
return getJpaTemplate().execute(new JpaCallback<List<ScheduleTemplate>>() {
|
||||
public List<ScheduleTemplate> doInJpa(EntityManager em)
|
||||
throws PersistenceException {
|
||||
@ -39,22 +38,15 @@ public class ScheduleTemplateDaoJPAImp extends AbstractDaoJPAImp<ScheduleTemplat
|
||||
if(isSysAdminTemplate != null){
|
||||
conditions.add("st.isSysAdminTemplate = :isSysAdminTemplate ");
|
||||
}
|
||||
|
||||
if(creator != null){
|
||||
fromClause += ", User u ";
|
||||
joinClause += "join u.roles role ";
|
||||
conditions.add("role = st.creator ");
|
||||
conditions.add("u = :user ");
|
||||
}
|
||||
|
||||
if(active != null){
|
||||
conditions.add("st.active = :active ");
|
||||
}
|
||||
|
||||
if(projectClass != null){
|
||||
conditions.add("st.projectClass = :projectClass ");
|
||||
}
|
||||
|
||||
String cond = "";
|
||||
for(String c : conditions){
|
||||
if(conditions.indexOf(c) == 0)
|
||||
@ -67,21 +59,14 @@ public class ScheduleTemplateDaoJPAImp extends AbstractDaoJPAImp<ScheduleTemplat
|
||||
|
||||
q += " order by st.templateName asc";
|
||||
|
||||
|
||||
TypedQuery<ScheduleTemplate> query = em.createQuery(q, ScheduleTemplate.class);
|
||||
|
||||
if(isSysAdminTemplate != null){
|
||||
query.setParameter("isSysAdminTemplate", isSysAdminTemplate);
|
||||
}
|
||||
|
||||
if(creator != null){
|
||||
query.setParameter("user", creator);
|
||||
}
|
||||
|
||||
if(active != null){
|
||||
query.setParameter("active", active);
|
||||
}
|
||||
|
||||
if(projectClass != null){
|
||||
query.setParameter("projectClass", projectClass);
|
||||
}
|
||||
|
@ -3,11 +3,15 @@ package se.su.dsv.scipro.data.dataobjects;
|
||||
import java.util.Date;
|
||||
|
||||
import javax.persistence.Basic;
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.MappedSuperclass;
|
||||
import javax.persistence.PrePersist;
|
||||
import javax.persistence.PreUpdate;
|
||||
import javax.persistence.Version;
|
||||
|
||||
import org.apache.wicket.IClusterable;
|
||||
|
||||
import se.su.dsv.scipro.dataproviders.SortableField;
|
||||
/**
|
||||
*
|
||||
* @author Martin Peters - mpeters@dsv.su.se
|
||||
@ -19,11 +23,17 @@ public abstract class DomainObject implements IClusterable{
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Basic(optional=false)
|
||||
@SortableField
|
||||
private Date dateCreated;
|
||||
|
||||
@Basic(optional=false)
|
||||
@SortableField
|
||||
private Date lastModified;
|
||||
|
||||
@Version
|
||||
@Column(nullable = false)
|
||||
private int version=0;
|
||||
|
||||
abstract public Long getId();
|
||||
|
||||
@PreUpdate
|
||||
@ -34,21 +44,47 @@ public abstract class DomainObject implements IClusterable{
|
||||
dateCreated = lastModified;
|
||||
}
|
||||
}
|
||||
|
||||
public Date getDateCreated() {
|
||||
return dateCreated;
|
||||
}
|
||||
|
||||
public void setDateCreated(Date dateCreated) {
|
||||
this.dateCreated = dateCreated;
|
||||
}
|
||||
|
||||
public Date getLastModified() {
|
||||
return lastModified;
|
||||
}
|
||||
|
||||
public void setLastModified(Date lastModified) {
|
||||
this.lastModified = lastModified;
|
||||
}
|
||||
|
||||
public int getVersion() {
|
||||
return version;
|
||||
}
|
||||
public void setVersion(int version) {
|
||||
this.version = version;
|
||||
}
|
||||
/**
|
||||
* Override in subtypes only if identity/hashcode differs from primary key identity.
|
||||
*/
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if(this == obj)
|
||||
return true;
|
||||
if(obj == null)
|
||||
return false;
|
||||
if(this.getClass() != obj.getClass())
|
||||
return false;
|
||||
final DomainObject other = (DomainObject) obj;
|
||||
final Long thisID = getId();
|
||||
final Long thatID = other.getId();
|
||||
return (thisID==null?thatID==null:thisID.equals(thatID));
|
||||
}
|
||||
/**
|
||||
* Override in subtypes only if identity/hashcode differs from primary key identity.
|
||||
*/
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = 17;
|
||||
result = 31 * result + (getId()==null?0:getId().hashCode());
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
@ -12,19 +12,15 @@ import se.su.dsv.scipro.data.dao.interfaces.LazyDeletable;
|
||||
*/
|
||||
@MappedSuperclass
|
||||
public abstract class LazyDeletableDomainObject extends DomainObject implements LazyDeletable{
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Index(name="deleted_index") //Hibernate specific, for performance
|
||||
private boolean deleted = false;
|
||||
|
||||
/**
|
||||
* @param set the object to be lazily deleted or not, does not take effect until after the object being saved.
|
||||
*/
|
||||
public void setDeleted(boolean deleted) {
|
||||
this.deleted = deleted;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return if the object is lazily deleted or not
|
||||
*/
|
||||
|
@ -34,7 +34,7 @@ import se.su.dsv.scipro.data.dataobjects.interfaces.Commentable;
|
||||
import se.su.dsv.scipro.data.enums.ProjectStatus;
|
||||
import se.su.dsv.scipro.data.enums.ProjectTeamMemberRoles;
|
||||
import se.su.dsv.scipro.data.enums.StateOfMind;
|
||||
import se.su.dsv.scipro.data.facade.ProjectFacade;
|
||||
import se.su.dsv.scipro.dataproviders.SortableField;
|
||||
import se.su.dsv.scipro.icons.IconPanel;
|
||||
import se.su.dsv.scipro.icons.IconizedComponent;
|
||||
import se.su.dsv.scipro.icons.ImageIcon;
|
||||
@ -62,6 +62,7 @@ public class Project extends DomainObject implements Comparable<Project>, Iconiz
|
||||
|
||||
@Column(length=255)
|
||||
@Basic(optional=false)
|
||||
@SortableField
|
||||
private String title;
|
||||
|
||||
@ManyToMany(targetEntity=Student.class)
|
||||
@ -74,19 +75,12 @@ public class Project extends DomainObject implements Comparable<Project>, Iconiz
|
||||
private SortedSet<ProjectFollower> projectFollowers = new TreeSet<ProjectFollower>();
|
||||
|
||||
@ManyToOne
|
||||
@SortableField
|
||||
private Employee headSupervisor;
|
||||
|
||||
@OneToOne(mappedBy="project")
|
||||
private Log log;
|
||||
|
||||
public Log getLog() {
|
||||
return log;
|
||||
}
|
||||
|
||||
public void setLog(Log log) {
|
||||
this.log = log;
|
||||
}
|
||||
|
||||
@Enumerated(EnumType.STRING)
|
||||
private ProjectStatus projectStatus = ProjectStatus.ACTIVE;
|
||||
|
||||
@ -160,6 +154,14 @@ public class Project extends DomainObject implements Comparable<Project>, Iconiz
|
||||
this.title = title;
|
||||
}
|
||||
|
||||
public Log getLog() {
|
||||
return log;
|
||||
}
|
||||
|
||||
public void setLog(Log log) {
|
||||
this.log = log;
|
||||
}
|
||||
|
||||
public SortedSet<Student> getProjectParticipants() {
|
||||
return projectParticipants;
|
||||
}
|
||||
|
@ -5,6 +5,7 @@ import java.util.Set;
|
||||
import java.util.TreeSet;
|
||||
|
||||
import javax.persistence.Cacheable;
|
||||
import javax.persistence.CascadeType;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.Id;
|
||||
@ -34,6 +35,9 @@ public class ProjectSchedule extends DomainObject {
|
||||
@ManyToMany(mappedBy="projectSchedules")
|
||||
private Set<GroupEvent> groupEvents = new TreeSet<GroupEvent>();
|
||||
|
||||
@OneToMany(mappedBy="projectSchedule",cascade=CascadeType.PERSIST)
|
||||
private Set<ProjectScheduleEvent> events = new TreeSet<ProjectScheduleEvent>();
|
||||
|
||||
@OneToOne(optional=false)
|
||||
private Project project;
|
||||
|
||||
@ -82,6 +86,14 @@ public class ProjectSchedule extends DomainObject {
|
||||
public void setGroupEvents(Set<GroupEvent> groupEvents) {
|
||||
this.groupEvents = groupEvents;
|
||||
}
|
||||
|
||||
public Set<ProjectScheduleEvent> getEvents() {
|
||||
return events;
|
||||
}
|
||||
|
||||
public void setEvents(Set<ProjectScheduleEvent> events) {
|
||||
this.events = events;
|
||||
}
|
||||
|
||||
public void setStartDate(Date startDate){
|
||||
this.startDate = startDate;
|
||||
@ -90,34 +102,4 @@ public class ProjectSchedule extends DomainObject {
|
||||
public Date getStartDate(){
|
||||
return startDate;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int weight = 31;
|
||||
int result = 17;
|
||||
|
||||
result = weight * result + ((id == null) ? 0 : (int) (id ^ (id >>> 32)));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null)
|
||||
return false;
|
||||
if (this.getClass() != obj.getClass())
|
||||
return false;
|
||||
|
||||
ProjectSchedule other = (ProjectSchedule) obj;
|
||||
|
||||
if (id == null) {
|
||||
if (other.id != null)
|
||||
return false;
|
||||
} else if (!id.equals(other.id))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,118 @@
|
||||
package se.su.dsv.scipro.data.dataobjects;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
import javax.persistence.Cacheable;
|
||||
import javax.persistence.CascadeType;
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.JoinColumn;
|
||||
import javax.persistence.ManyToOne;
|
||||
import javax.persistence.OneToOne;
|
||||
import javax.persistence.Table;
|
||||
|
||||
import org.hibernate.annotations.Cache;
|
||||
import org.hibernate.annotations.CacheConcurrencyStrategy;
|
||||
|
||||
import se.su.dsv.scipro.dataproviders.SortableField;
|
||||
|
||||
@Entity
|
||||
@Table(name="project_schedule_event")
|
||||
@Cacheable(true)
|
||||
@Cache(usage= CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
|
||||
public class ProjectScheduleEvent extends LazyDeletableDomainObject {
|
||||
private static final long serialVersionUID = 1L;
|
||||
@Id
|
||||
@GeneratedValue
|
||||
private Long id;
|
||||
@ManyToOne(optional=false)
|
||||
@JoinColumn (name="projectSchedule_id")
|
||||
@SortableField
|
||||
private ProjectSchedule projectSchedule;
|
||||
@ManyToOne(optional=false)
|
||||
@SortableField
|
||||
private User creator;
|
||||
@Column(nullable=false)
|
||||
@SortableField
|
||||
private Date date;
|
||||
@Column(length=50,nullable=false)
|
||||
@SortableField
|
||||
private String name;
|
||||
@Column(nullable=false,length=512)
|
||||
@SortableField
|
||||
private String description;
|
||||
@Column(nullable=false)
|
||||
@SortableField
|
||||
private boolean uploadRequired;
|
||||
@OneToOne(optional = true, orphanRemoval = true, cascade = CascadeType.ALL)
|
||||
@SortableField
|
||||
private FileDescription fileUpload;
|
||||
@ManyToOne
|
||||
private CheckList checkList;
|
||||
|
||||
public ProjectScheduleEvent() {
|
||||
this.uploadRequired = false;
|
||||
this.name = "";
|
||||
this.description = "";
|
||||
}
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
public ProjectSchedule getProjectSchedule() {
|
||||
return projectSchedule;
|
||||
}
|
||||
public void setProjectSchedule(ProjectSchedule projectSchedule) {
|
||||
this.projectSchedule = projectSchedule;
|
||||
}
|
||||
public User getCreator() {
|
||||
return creator;
|
||||
}
|
||||
public void setCreator(User creator) {
|
||||
this.creator = creator;
|
||||
}
|
||||
public Date getDate() {
|
||||
return date;
|
||||
}
|
||||
public void setDate(Date date) {
|
||||
this.date = date;
|
||||
}
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
public void setDescription(String description) {
|
||||
this.description = description;
|
||||
}
|
||||
public boolean isUploadRequired() {
|
||||
return uploadRequired;
|
||||
}
|
||||
public void setUploadRequired(boolean uploadRequired) {
|
||||
this.uploadRequired = uploadRequired;
|
||||
}
|
||||
public FileDescription getFileUpload() {
|
||||
return fileUpload;
|
||||
}
|
||||
public void setFileUpload(FileDescription fileUpload) {
|
||||
this.fileUpload = fileUpload;
|
||||
}
|
||||
public CheckList getCheckList() {
|
||||
return checkList;
|
||||
}
|
||||
public void setCheckList(CheckList checkList) {
|
||||
this.checkList = checkList;
|
||||
}
|
||||
@Override
|
||||
public String toString(){
|
||||
return "Event: "+getName()+"@"+getDate()+" on "+getProjectSchedule()+" by "+getCreator();
|
||||
}
|
||||
}
|
@ -13,7 +13,6 @@ import javax.persistence.Id;
|
||||
import javax.persistence.Lob;
|
||||
import javax.persistence.ManyToOne;
|
||||
import javax.persistence.OneToMany;
|
||||
import javax.persistence.PreRemove;
|
||||
import javax.persistence.Table;
|
||||
|
||||
import org.hibernate.annotations.Cache;
|
||||
@ -46,9 +45,6 @@ public class ScheduleTemplate extends DomainObject {
|
||||
@Column(nullable=false)
|
||||
private String templateName;
|
||||
|
||||
@Column(nullable=false)
|
||||
private Boolean active = false;
|
||||
|
||||
@Lob
|
||||
private String templateDescription;
|
||||
|
||||
@ -58,7 +54,6 @@ public class ScheduleTemplate extends DomainObject {
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
@ -67,7 +62,6 @@ public class ScheduleTemplate extends DomainObject {
|
||||
Collections.sort(projectEventTemplates);
|
||||
return projectEventTemplates;
|
||||
}
|
||||
|
||||
public void setProjectEventTemplates(List<ProjectEventTemplate> projectEventTemplates) {
|
||||
Collections.sort(projectEventTemplates);
|
||||
this.projectEventTemplates = projectEventTemplates;
|
||||
@ -76,7 +70,6 @@ public class ScheduleTemplate extends DomainObject {
|
||||
public User getCreator() {
|
||||
return creator;
|
||||
}
|
||||
|
||||
public void setCreator(User creator) {
|
||||
this.creator = creator;
|
||||
}
|
||||
@ -84,7 +77,6 @@ public class ScheduleTemplate extends DomainObject {
|
||||
public ProjectClass getProjectClass() {
|
||||
return projectClass;
|
||||
}
|
||||
|
||||
public void setProjectClass(ProjectClass projectClass) {
|
||||
this.projectClass = projectClass;
|
||||
}
|
||||
@ -92,7 +84,6 @@ public class ScheduleTemplate extends DomainObject {
|
||||
public String getTemplateName() {
|
||||
return templateName;
|
||||
}
|
||||
|
||||
public void setTemplateName(String templateName) {
|
||||
this.templateName = templateName;
|
||||
}
|
||||
@ -100,7 +91,6 @@ public class ScheduleTemplate extends DomainObject {
|
||||
public String getTemplateDescription() {
|
||||
return templateDescription;
|
||||
}
|
||||
|
||||
public void setTemplateDescription(String templateDescription) {
|
||||
this.templateDescription = templateDescription;
|
||||
}
|
||||
@ -108,54 +98,15 @@ public class ScheduleTemplate extends DomainObject {
|
||||
public void setSysAdminTemplate(boolean isSysAdminTemplate) {
|
||||
this.isSysAdminTemplate = isSysAdminTemplate;
|
||||
}
|
||||
|
||||
public boolean isSysAdminTemplate() {
|
||||
return isSysAdminTemplate;
|
||||
}
|
||||
|
||||
public void setActive(boolean active) {
|
||||
this.active = active;
|
||||
}
|
||||
|
||||
public boolean isActive() {
|
||||
return active;
|
||||
}
|
||||
|
||||
public void addProjectEventTemplate(ProjectEventTemplate e){
|
||||
e.setScheduleTemplate(this);
|
||||
projectEventTemplates.add(e);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int weight = 31;
|
||||
int result = 17;
|
||||
|
||||
result = weight * result + ((id == null) ? 0 : (int) (id ^ (id >>> 32)));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null)
|
||||
return false;
|
||||
if (this.getClass() != obj.getClass())
|
||||
return false;
|
||||
|
||||
ScheduleTemplate other = (ScheduleTemplate) obj;
|
||||
|
||||
if (id == null) {
|
||||
if (other.id != null)
|
||||
return false;
|
||||
} else if (!id.equals(other.id))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString(){
|
||||
return getTemplateName();
|
||||
|
@ -2,14 +2,12 @@ package se.su.dsv.scipro.data.facade;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.wicket.spring.injection.annot.SpringBean;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import se.su.dsv.scipro.data.dao.interfaces.CheckListDao;
|
||||
import se.su.dsv.scipro.data.dao.interfaces.CheckListQuestionDao;
|
||||
import se.su.dsv.scipro.data.dao.interfaces.CheckListTemplateDao;
|
||||
import se.su.dsv.scipro.data.dao.interfaces.ProjectDao;
|
||||
import se.su.dsv.scipro.data.dataobjects.CheckList;
|
||||
import se.su.dsv.scipro.data.dataobjects.CheckListQuestion;
|
||||
import se.su.dsv.scipro.data.dataobjects.CheckListTemplate;
|
||||
@ -28,14 +26,10 @@ public class ProjectFacade {
|
||||
@Autowired
|
||||
private CheckListQuestionDao checkListQuestionDao;
|
||||
|
||||
@Autowired
|
||||
private ProjectDao projectDao;
|
||||
|
||||
public void generateChecklists(Project project){
|
||||
List<CheckListTemplate> templates;
|
||||
|
||||
//project = projectDao.save(project);
|
||||
|
||||
if(project.getProjectClass().getCode().equals(ProjectClass.BACHELOR)){
|
||||
templates = checkListTemplateDao.findTemplatesByCategory("Bachelor");
|
||||
}else{
|
||||
|
42
src/main/java/se/su/dsv/scipro/data/support/QueryParams.java
Normal file
42
src/main/java/se/su/dsv/scipro/data/support/QueryParams.java
Normal file
@ -0,0 +1,42 @@
|
||||
package se.su.dsv.scipro.data.support;
|
||||
|
||||
/**
|
||||
* Final value class for wrapping common SQL query parameters.
|
||||
* Design is very simple, the objects are immutable and anyone accepting a QueryParams object should be prepared for handling null values in any field.
|
||||
*/
|
||||
public final class QueryParams {
|
||||
private final String sortFieldName;
|
||||
private final boolean sortFieldOrderAscending;
|
||||
private final int firstResultIndex;
|
||||
private final int resultCount;
|
||||
public QueryParams(final String sortFieldName,final boolean isAscendingOrder, final int firstResultIndex, final int resultCount){
|
||||
this.sortFieldName = sortFieldName;
|
||||
this.sortFieldOrderAscending = isAscendingOrder;
|
||||
this.firstResultIndex = firstResultIndex;
|
||||
this.resultCount = resultCount;
|
||||
}
|
||||
public QueryParams(final String sortFieldName, final int firstResultIndex, final int resultCount){
|
||||
this(sortFieldName,true,firstResultIndex,resultCount);
|
||||
}
|
||||
public QueryParams(final String sortFieldName, boolean isAscendingOrder){
|
||||
this(sortFieldName,isAscendingOrder,-1,-1);
|
||||
}
|
||||
public QueryParams(final String sortFieldName){
|
||||
this(sortFieldName,true,-1,-1);
|
||||
}
|
||||
public QueryParams(final int firstResultIndex, final int resultCount){
|
||||
this(null,true,firstResultIndex,resultCount);
|
||||
}
|
||||
public String getSortFieldName() {
|
||||
return sortFieldName;
|
||||
}
|
||||
public boolean isSortFieldOrderAscending() {
|
||||
return sortFieldOrderAscending;
|
||||
}
|
||||
public int getFirstResultIndex() {
|
||||
return firstResultIndex;
|
||||
}
|
||||
public int getResultCount() {
|
||||
return resultCount;
|
||||
}
|
||||
}
|
@ -1,8 +1,5 @@
|
||||
package se.su.dsv.scipro.dataproviders;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.wicket.spring.injection.annot.SpringBean;
|
||||
|
||||
import se.su.dsv.scipro.data.dao.interfaces.Dao;
|
||||
@ -15,11 +12,6 @@ import se.su.dsv.scipro.data.dataobjects.Project;
|
||||
*/
|
||||
public class ProjectDataProvider extends SortableDataProvider<Project>{
|
||||
private static final long serialVersionUID = 1L;
|
||||
//Custom sorting-specifiers available for project queries
|
||||
public static final SortSpecifier HEAD_ASC = new SortSpecifier("headSupervisor",true);
|
||||
public static final SortSpecifier HEAD_DESC = new SortSpecifier("headSupervisor",false);
|
||||
public static final SortSpecifier TITLE_ASC = new SortSpecifier("title",true);
|
||||
public static final SortSpecifier TITLE_DESC = new SortSpecifier("title",false);
|
||||
@SpringBean
|
||||
protected ProjectDao projectDao;
|
||||
@Override
|
||||
@ -30,15 +22,6 @@ public class ProjectDataProvider extends SortableDataProvider<Project>{
|
||||
this(null);
|
||||
}
|
||||
public ProjectDataProvider(final SortSpecifier sortSpecifier) {
|
||||
super(sortSpecifier);
|
||||
}
|
||||
@Override
|
||||
protected List<SortSpecifier> getAvailableExtensionFields(){
|
||||
List<SortSpecifier> list = new ArrayList<SortSpecifier>();
|
||||
list.add(HEAD_ASC);
|
||||
list.add(HEAD_DESC);
|
||||
list.add(TITLE_ASC);
|
||||
list.add(TITLE_DESC);
|
||||
return list;
|
||||
super(sortSpecifier,Project.class);
|
||||
}
|
||||
}
|
@ -0,0 +1,146 @@
|
||||
package se.su.dsv.scipro.dataproviders;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.Iterator;
|
||||
|
||||
import org.apache.log4j.Logger;
|
||||
import org.apache.wicket.spring.injection.annot.SpringBean;
|
||||
|
||||
import se.su.dsv.scipro.data.dao.interfaces.ProjectScheduleEventDao;
|
||||
import se.su.dsv.scipro.data.dataobjects.Project;
|
||||
import se.su.dsv.scipro.data.dataobjects.ProjectScheduleEvent;
|
||||
import se.su.dsv.scipro.data.support.QueryParams;
|
||||
|
||||
/**
|
||||
* Custom (and well behaved) SortableDataProvider implementation with Dao-injection override mechanics and custom sorting-fields.
|
||||
* @see base type for more information.
|
||||
*/
|
||||
public class ProjectScheduleEventDataProvider extends SortableDataProvider<ProjectScheduleEvent>{
|
||||
public enum SEARCH_MODE {ALL{
|
||||
public String toString() {
|
||||
return "all_unbound";
|
||||
}
|
||||
},PROJECT_ALL{
|
||||
public String toString() {
|
||||
return "all";
|
||||
}
|
||||
},PROJECT_PAST{
|
||||
public String toString() {
|
||||
return "past";
|
||||
}
|
||||
},PROJECT_FUTURE{
|
||||
public String toString() {
|
||||
return "upcoming";
|
||||
}
|
||||
},PROJECT_BETWEEN{
|
||||
public String toString() {
|
||||
return "between";
|
||||
}
|
||||
}};
|
||||
private static final long serialVersionUID = 1L;
|
||||
@SpringBean
|
||||
protected ProjectScheduleEventDao projectScheduleEventDao;
|
||||
private SEARCH_MODE currentSearchMode = SEARCH_MODE.PROJECT_ALL;
|
||||
private final Project project;
|
||||
private final transient Logger logger = Logger.getLogger(ProjectScheduleEventDataProvider.class);
|
||||
private Date fromDate;
|
||||
private Date toDate;
|
||||
@Override
|
||||
protected ProjectScheduleEventDao getDao() {
|
||||
return projectScheduleEventDao;
|
||||
}
|
||||
/**
|
||||
* Create provider for Project p.
|
||||
* You can supply null values for "p", in which case the provider will return all schedule events regardless of project ownership.
|
||||
* By default, the current date is used for date-boundaries (see setDateBoundaries).
|
||||
*/
|
||||
public ProjectScheduleEventDataProvider(final Project p) {
|
||||
this(null,p);
|
||||
}
|
||||
/**
|
||||
* Create provider with the given SortSpecifier for Project p.
|
||||
* You can supply null values for "p", in which case the provider will return all schedule events regardless of project ownership.
|
||||
* By default, the current date is used for date-boundaries (see setDateBoundaries).
|
||||
* @param sortSpecifier
|
||||
* @param p
|
||||
* @param u
|
||||
*/
|
||||
public ProjectScheduleEventDataProvider(final SortSpecifier sortSpecifier, final Project p) {
|
||||
super(sortSpecifier,ProjectScheduleEvent.class);
|
||||
this.project = p;
|
||||
setDateBoundaries(null,null);
|
||||
}
|
||||
/**
|
||||
* Sets search mode for iterator returns, if the provider has been created with a null project then the search mode will always be SEARCH_MODE.ALL.
|
||||
* @param mode
|
||||
*/
|
||||
public void setSearchMode(SEARCH_MODE mode){
|
||||
if(project == null)
|
||||
currentSearchMode = SEARCH_MODE.ALL;
|
||||
else
|
||||
currentSearchMode = mode;
|
||||
logger.debug("Now using search mode: "+currentSearchMode);
|
||||
}
|
||||
/**
|
||||
* Getter for the current search mode.
|
||||
* @return
|
||||
*/
|
||||
public SEARCH_MODE getSearchMode(){
|
||||
return currentSearchMode;
|
||||
}
|
||||
/**
|
||||
* Sets date-boundaries for the PROJECT_BETWEEN, PROJECT_PAST and PROJECT_FUTURE search mode type, not used in other modes.
|
||||
* If either parameter is null, the current date will be used for that parameter.
|
||||
*/
|
||||
public void setDateBoundaries(final Date fromDate, final Date toDate){
|
||||
this.fromDate = (fromDate!=null?fromDate:new Date());
|
||||
this.toDate = (toDate!=null?toDate:new Date());
|
||||
}
|
||||
/**
|
||||
* No backed support available for sorting yet, default facilities (with full sorting support) are used when search mode is ALL.
|
||||
*/
|
||||
@Override
|
||||
public Iterator<ProjectScheduleEvent> iterator(int first, int count) {
|
||||
Iterator<ProjectScheduleEvent> itr = null;
|
||||
switch(currentSearchMode){
|
||||
case ALL:
|
||||
itr = super.iterator(first, count);
|
||||
break;
|
||||
case PROJECT_ALL:
|
||||
itr = getDao().findEventsByProject(project,new QueryParams(getSafeSortSpecifier().getFieldName(),isAscendingOrder(),first,count)).iterator();
|
||||
break;
|
||||
case PROJECT_PAST:
|
||||
itr = getDao().findEventsByProject(project,null,toDate,new QueryParams(getSafeSortSpecifier().getFieldName(),isAscendingOrder(),first,count)).iterator();
|
||||
break;
|
||||
case PROJECT_FUTURE:
|
||||
itr = getDao().findEventsByProject(project,fromDate,null,new QueryParams(getSafeSortSpecifier().getFieldName(),isAscendingOrder(),first,count)).iterator();
|
||||
break;
|
||||
case PROJECT_BETWEEN:
|
||||
itr = getDao().findEventsByProject(project,fromDate,toDate,new QueryParams(getSafeSortSpecifier().getFieldName(),isAscendingOrder(),first,count)).iterator();
|
||||
break;
|
||||
}
|
||||
return itr;
|
||||
}
|
||||
@Override
|
||||
public int size() {
|
||||
int returnValue=0;
|
||||
switch(currentSearchMode){
|
||||
case ALL:
|
||||
returnValue = getDao().countAll();
|
||||
break;
|
||||
case PROJECT_ALL:
|
||||
returnValue = getDao().countEventsByProject(project,null,null);
|
||||
break;
|
||||
case PROJECT_PAST:
|
||||
returnValue = getDao().countEventsByProject(project,null,toDate);
|
||||
break;
|
||||
case PROJECT_FUTURE:
|
||||
returnValue = getDao().countEventsByProject(project,fromDate,null);
|
||||
break;
|
||||
case PROJECT_BETWEEN:
|
||||
returnValue = getDao().countEventsByProject(project,fromDate,toDate);
|
||||
break;
|
||||
}
|
||||
return returnValue;
|
||||
}
|
||||
}
|
@ -4,20 +4,21 @@ import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* SortingSpecifier helper value object for the SortableDataProvider mini-API.
|
||||
* Intances are guaranteed to be immutable and subclassing is not allowed, see SortableDataProvider and/or ProjectDataProvider for sample usage.
|
||||
* Instances are guaranteed to be immutable and subclassing is not allowed, see SortableDataProvider and/or ProjectDataProvider for sample usage.
|
||||
*/
|
||||
public final class SortSpecifier implements Serializable{
|
||||
private static final long serialVersionUID = 1L;
|
||||
private final String fieldName;
|
||||
private final boolean isAscendingOrder;
|
||||
public SortSpecifier(final String fieldName,final boolean isAscendingOrder){
|
||||
public SortSpecifier(final String fieldName){
|
||||
if(fieldName == null)
|
||||
throw new IllegalStateException("The fieldName parameter is not allowed NULL values");
|
||||
this.fieldName = fieldName;
|
||||
this.isAscendingOrder = isAscendingOrder;
|
||||
}
|
||||
public String getSortString(){
|
||||
return (fieldName+(isAscendingOrder?" ASC":" DESC"));
|
||||
return (fieldName);
|
||||
}
|
||||
public String getFieldName(){
|
||||
return fieldName;
|
||||
}
|
||||
@Override
|
||||
public boolean equals(Object o){
|
||||
@ -26,17 +27,16 @@ public final class SortSpecifier implements Serializable{
|
||||
if(!(o instanceof SortSpecifier))
|
||||
return false;
|
||||
SortSpecifier rhs = (SortSpecifier)o;
|
||||
return ((isAscendingOrder == rhs.isAscendingOrder) && (fieldName.equals(rhs.fieldName)));
|
||||
return (fieldName.equals(rhs.fieldName));
|
||||
}
|
||||
@Override
|
||||
public int hashCode(){
|
||||
int result = 17;
|
||||
result = 31 * result + (isAscendingOrder?1:0);
|
||||
result = 31 * result + fieldName.hashCode();
|
||||
return result;
|
||||
}
|
||||
@Override
|
||||
public String toString(){
|
||||
return fieldName+(isAscendingOrder?" ASC":" DESC");
|
||||
return fieldName;
|
||||
}
|
||||
}
|
@ -1,10 +1,14 @@
|
||||
package se.su.dsv.scipro.dataproviders;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.apache.log4j.Logger;
|
||||
import org.apache.wicket.injection.web.InjectorHolder;
|
||||
import org.apache.wicket.markup.repeater.data.IDataProvider;
|
||||
import org.apache.wicket.model.IModel;
|
||||
@ -16,11 +20,12 @@ import se.su.dsv.scipro.data.dataobjects.DomainObject;
|
||||
/**
|
||||
* SortableDataProvider for any DomainObject.
|
||||
* Provides mechanics for sorting output from a wicket IDataProvider via all fields existing in the DomainObject public API.
|
||||
* As a client of this class, you typically feed it the parameterized type and a Dao capable of fetching that type.
|
||||
* As a client of this class, you typically feed it the parameterized type, a Dao capable of fetching that type and the DomainObject.class
|
||||
* identifier (which is used to scan your class for "SortableField" annotations)
|
||||
*
|
||||
* Typical client usage:
|
||||
* <code>
|
||||
* SortableDataProvider<Project> sdp = new SortableDataProvider<Project>(projectDao);
|
||||
* SortableDataProvider<Project> sdp = new SortableDataProvider<Project>(projectDao,Project.class);
|
||||
* DataView<Project> dataView = new DataView<Project>("projectDataView",sdp, 20){....};
|
||||
* </code>
|
||||
* The available sorting-capable fields are accessible through iteration and as named constants.
|
||||
@ -28,11 +33,12 @@ import se.su.dsv.scipro.data.dataobjects.DomainObject;
|
||||
* For implementors of subtypes:
|
||||
* You will probably want use to the protected constructors and override the getDao() method if you have the need to encapsulate
|
||||
* dao-object ownership inside your implementation. See "ProjectDataProvider" for an example of this.
|
||||
* Now for the most important part: if you add SortSpecifier fields in your implementation to provide named constants (they should be "public static final"), make sure that
|
||||
* these fields are also returned by an implementation of getAvailableExtensionFields(). If you do this and follow the modifier conventions, your implementation can
|
||||
* be tested for type-safety (or rather: query-field safety) by the facilities provided in "TestSortableDataProvider" with just one line of code.
|
||||
* SpringBean-injection is guaranteed to happen before any overridable methods are called.
|
||||
*
|
||||
*
|
||||
* Now for the most important part: adding sortable fields. This is actually quite simple, the only thing
|
||||
* you have to do is to annotate the target DomainObject implementation with the "SortableField" annotation and the base class functionality
|
||||
* will take care of the rest via annotation/reflection. You don't need to do anything in the subtypes (and you probably don't want to), but if you really want to you can override
|
||||
* getAvailableExtensionFields() to provide additional sort-specifiers.
|
||||
* @param <T>
|
||||
*/
|
||||
public class SortableDataProvider<T extends DomainObject> implements IDataProvider<T> {
|
||||
@ -40,49 +46,34 @@ public class SortableDataProvider<T extends DomainObject> implements IDataProvid
|
||||
private SortSpecifier inUseSpecifier;
|
||||
private List<SortSpecifier> availableSpecifiers;
|
||||
private Dao<T> dao;
|
||||
private Class<T> domainClass;
|
||||
private boolean ascending=true;
|
||||
private transient Logger logger = Logger.getLogger(SortableDataProvider.class);
|
||||
/**
|
||||
* Named SortSpecifier constant, @see getAvailableSortSpecifiers()
|
||||
*/
|
||||
public static final SortSpecifier ID_ASC = new SortSpecifier("id",true);
|
||||
/**
|
||||
* Named SortSpecifier constant, @see getAvailableSortSpecifiers()
|
||||
*/
|
||||
public static final SortSpecifier ID_DESC = new SortSpecifier("id",false);
|
||||
/**
|
||||
* Named SortSpecifier constant, @see getAvailableSortSpecifiers()
|
||||
*/
|
||||
public static final SortSpecifier CREATED_ASC = new SortSpecifier("dateCreated",true);
|
||||
/**
|
||||
* Named SortSpecifier constant, @see getAvailableSortSpecifiers()
|
||||
*/
|
||||
public static final SortSpecifier CREATED_DESC = new SortSpecifier("dateCreated",false);
|
||||
/**
|
||||
* Named SortSpecifier constant, @see getAvailableSortSpecifiers()
|
||||
*/
|
||||
public static final SortSpecifier MODIFIED_ASC = new SortSpecifier("lastModified",true);
|
||||
/**
|
||||
* Named SortSpecifier constant, @see getAvailableSortSpecifiers()
|
||||
*/
|
||||
public static final SortSpecifier MODIFIED_DESC = new SortSpecifier("lastModified",false);
|
||||
|
||||
public static final SortSpecifier ID = new SortSpecifier("id");
|
||||
/**
|
||||
* Constructs a SortableDataProvider using the supplied Dao object.
|
||||
* A null value for the dao-parameter is not allowed and will throw an IllegalStateException.
|
||||
* A null value for the domainClass-parameter is allowed and will cause standard "DomainObject" sorters to be generated.
|
||||
* @param dao
|
||||
*/
|
||||
public SortableDataProvider(final Dao<T> dao){
|
||||
this(null,dao);
|
||||
public SortableDataProvider(final Dao<T> dao, final Class<T> domainClass){
|
||||
this(null,dao,domainClass);
|
||||
}
|
||||
/**
|
||||
* Constructs a SortableDataProvider using the supplied Dao object and SortSpecifier.
|
||||
* A null value for the SortSpecifier parameter is allowed and will cause standard "unsorted" results.
|
||||
* A null value for the dao-parameter is not allowed and will throw an IllegalStateException.
|
||||
* A null value for the domainClass-parameter is allowed and will cause standard "DomainObject" sorters to be generated.
|
||||
* @param sortSpecifier
|
||||
* @param dao
|
||||
*/
|
||||
public SortableDataProvider(final SortSpecifier sortSpecifier, final Dao<T> dao) {
|
||||
public SortableDataProvider(final SortSpecifier sortSpecifier, final Dao<T> dao, final Class<T> domainClass) {
|
||||
InjectorHolder.getInjector().inject(this);
|
||||
this.dao = dao;
|
||||
this.domainClass = domainClass;
|
||||
if(getDao() == null)//Constructed like this to allow sublasses passing null values as long as they provide a valid Dao via getDao() after IOC-injection has taken place
|
||||
throw new IllegalStateException("Sorry, you have to provide a non-null Dao object");
|
||||
populateAvailableSpecifiers();
|
||||
@ -92,13 +83,13 @@ public class SortableDataProvider<T extends DomainObject> implements IDataProvid
|
||||
* Exposed to subtypes to support certain constructs (mostly when getDao is overriden in a subtype).
|
||||
*/
|
||||
protected SortableDataProvider() {
|
||||
this(null,null);
|
||||
this(null,null,null);
|
||||
}
|
||||
/**
|
||||
* Exposed to subtypes to support certain constructs (mostly when getDao is overriden in a subtype).
|
||||
*/
|
||||
protected SortableDataProvider(final SortSpecifier sortSpecifier) {
|
||||
this(sortSpecifier,null);
|
||||
protected SortableDataProvider(final SortSpecifier sortSpecifier, Class<T> domainClass) {
|
||||
this(sortSpecifier,null,domainClass);
|
||||
}
|
||||
/**
|
||||
* Default implementation returns the Dao registered with the object at creation time, override to provide your own encapsulation mechanics.
|
||||
@ -108,9 +99,15 @@ public class SortableDataProvider<T extends DomainObject> implements IDataProvid
|
||||
return dao;
|
||||
}
|
||||
/**
|
||||
* Subtype hook to provide your own custom list of SortSpecifier's, if you have new fields you should probably override this method.
|
||||
* Make absolutely sure that it returns a list of all your declared SortSpecifiers.
|
||||
* Called once during base class construction.
|
||||
* Default implementation returns the DomainClass registered with the object at creation time, override to provide your own encapsulation mechanics.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
protected Class<T> getDomainClass(){
|
||||
return (Class<T>) (domainClass!=null?domainClass:DomainObject.class);
|
||||
}
|
||||
/**
|
||||
* Subtype hook to provide your own custom list of additional SortSpecifier's, if you have new fields not accessible via annotation scanning you should probably override this method.
|
||||
* Called once during base class construction. Duplicate sort-keys are ignored.
|
||||
* @return
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
@ -127,6 +124,12 @@ public class SortableDataProvider<T extends DomainObject> implements IDataProvid
|
||||
throw new IllegalStateException("Sorry, you are not allowed to use a non registered SortSpecifier: '"+sortSpecifier+"' as this would potentially violate runtime-safety");
|
||||
this.inUseSpecifier = sortSpecifier;
|
||||
}
|
||||
/**
|
||||
* Sets currently in-use sorting order (ascending or descending)
|
||||
*/
|
||||
public final void setAscendingOrder(boolean ascending){
|
||||
this.ascending = ascending;
|
||||
}
|
||||
/**
|
||||
* Returns the currently in-use SortSpecifier, or null if none is in use.
|
||||
* @return
|
||||
@ -134,14 +137,43 @@ public class SortableDataProvider<T extends DomainObject> implements IDataProvid
|
||||
public final SortSpecifier getSortSpecifier(){
|
||||
return inUseSpecifier;
|
||||
}
|
||||
/**
|
||||
* Shorthand method for getting a valid sortspecifier, useful since getSortSpecifier is allowed to return null values.
|
||||
* @return
|
||||
*/
|
||||
public final SortSpecifier getSafeSortSpecifier(){
|
||||
return (inUseSpecifier==null?ID:inUseSpecifier);
|
||||
}
|
||||
/**
|
||||
* Returns sort order status.
|
||||
*/
|
||||
public final boolean isAscendingOrder(){
|
||||
return ascending;
|
||||
}
|
||||
/**
|
||||
* Returns an aggregated (and immutable) list of all SortSpecifiers available for the implementation.
|
||||
* Requires subtypes to be well behaved when specifying additional sorting fields.
|
||||
* @return
|
||||
*/
|
||||
public final List<SortSpecifier> getAvailableSortSpecifiers(){
|
||||
logger.debug("Available sort specifiers: "+availableSpecifiers);
|
||||
return Collections.unmodifiableList(availableSpecifiers);
|
||||
}
|
||||
/**
|
||||
* Returns a defensive copy-list of all SortSpecifiers available for the implementation, any SortSpecifier with a getFieldName()
|
||||
* not present in the filterSet will be excluded from the returned list.
|
||||
* Requires subtypes to be well behaved when specifying additional sorting fields. Behavior when passing a null Set is undefined.
|
||||
* @return
|
||||
*/
|
||||
public final List<SortSpecifier> getAvailableSortSpecifiers(final Set<String> filterSet){
|
||||
List<SortSpecifier> returnList = new ArrayList<SortSpecifier>();
|
||||
for(final SortSpecifier spec : availableSpecifiers){
|
||||
logger.debug("Testing: " + spec);
|
||||
if(filterSet.contains(spec.getFieldName()))
|
||||
returnList.add(spec);
|
||||
}
|
||||
return returnList;
|
||||
}
|
||||
/**
|
||||
* Does nothing.
|
||||
*/
|
||||
@ -153,13 +185,13 @@ public class SortableDataProvider<T extends DomainObject> implements IDataProvid
|
||||
*/
|
||||
@Override
|
||||
public Iterator<T> iterator(int first, int count) {
|
||||
if(inUseSpecifier != null)
|
||||
return getDao().findAll(first, count, inUseSpecifier.getSortString()).iterator();
|
||||
if(getSortSpecifier() != null)
|
||||
return getDao().findAll(first, count, getSortSpecifier().getSortString() + (isAscendingOrder()?" ASC":" DESC")).iterator();
|
||||
else
|
||||
return getDao().findAll(first, count).iterator();
|
||||
}
|
||||
/**
|
||||
* Returns the size of the Dao-objects countAll.
|
||||
* Returns the size of the Dao-objects countAll by default, you will want to override this whenever you override iterator.
|
||||
*/
|
||||
@Override
|
||||
public int size() {
|
||||
@ -172,14 +204,39 @@ public class SortableDataProvider<T extends DomainObject> implements IDataProvid
|
||||
public IModel<T> model(T object) {
|
||||
return new DomainObjectDetachableModel<T>(getDao(),object);
|
||||
}
|
||||
/**
|
||||
* Utility method for querying annotated domain objects.
|
||||
* @param c
|
||||
* @return
|
||||
*/
|
||||
private List<SortSpecifier> getSortSpecifierListForTargetAnnotations(final Class<? extends DomainObject> c){
|
||||
logger.debug("Scanning for annotations in class type: "+c.getName());
|
||||
ArrayList<SortSpecifier> list = new ArrayList<SortSpecifier>();
|
||||
if(c != null){
|
||||
for(Field f : c.getDeclaredFields()){
|
||||
logger.debug("Examining: "+f.getName());
|
||||
f.getAnnotation(SortableField.class);
|
||||
SortableField a = f.getAnnotation(SortableField.class);
|
||||
if(a != null){
|
||||
logger.debug("Annotation found for field: " + f.getName());
|
||||
SortSpecifier spec = new SortSpecifier(f.getName());
|
||||
logger.debug("Adding: " +spec + " to the list of available sorting specifiers");
|
||||
list.add(spec);
|
||||
}else{
|
||||
logger.debug("Ignoring: " + f.getName());
|
||||
}
|
||||
}
|
||||
}
|
||||
logger.debug("Full returned list:" +list);
|
||||
return list;
|
||||
}
|
||||
private void populateAvailableSpecifiers(){
|
||||
availableSpecifiers = new ArrayList<SortSpecifier>();
|
||||
availableSpecifiers.add(ID_ASC);
|
||||
availableSpecifiers.add(ID_DESC);
|
||||
availableSpecifiers.add(CREATED_ASC);
|
||||
availableSpecifiers.add(CREATED_DESC);
|
||||
availableSpecifiers.add(MODIFIED_ASC);
|
||||
availableSpecifiers.add(MODIFIED_DESC);
|
||||
availableSpecifiers.addAll(getAvailableExtensionFields());
|
||||
final HashSet<SortSpecifier> specSet = new HashSet<SortSpecifier>();
|
||||
specSet.add(ID);
|
||||
specSet.addAll(getSortSpecifierListForTargetAnnotations(DomainObject.class));
|
||||
specSet.addAll(getSortSpecifierListForTargetAnnotations(getDomainClass()));
|
||||
specSet.addAll(getAvailableExtensionFields());
|
||||
availableSpecifiers.addAll(specSet);
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,16 @@
|
||||
package se.su.dsv.scipro.dataproviders;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
import java.lang.annotation.ElementType;
|
||||
|
||||
/**
|
||||
* Marker annotation used to specify sortable fields for Dao-objects.
|
||||
* This annotation is used by the SortableDataProvider API to automatically create SortSpecifiers suitable for use with the
|
||||
* parameterized DomainObject type.
|
||||
*/
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.FIELD)
|
||||
public @interface SortableField {
|
||||
}
|
@ -7,6 +7,7 @@ import java.util.SortedSet;
|
||||
import java.util.TreeSet;
|
||||
|
||||
import org.apache.log4j.Logger;
|
||||
import org.apache.wicket.spring.injection.annot.SpringBean;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.dao.DataAccessException;
|
||||
|
||||
@ -26,6 +27,7 @@ import se.su.dsv.scipro.data.dataobjects.User;
|
||||
import se.su.dsv.scipro.data.dataobjects.Username;
|
||||
import se.su.dsv.scipro.data.enums.ProjectStatus;
|
||||
import se.su.dsv.scipro.data.enums.ProjectTeamMemberRoles;
|
||||
import se.su.dsv.scipro.data.facade.ProjectFacade;
|
||||
import se.su.dsv.scipro.jsonobjects.JsonThesis;
|
||||
import se.su.dsv.scipro.jsonobjects.JsonThesisParticipant;
|
||||
import se.su.dsv.scipro.jsonobjects.JsonUser;
|
||||
@ -52,6 +54,8 @@ abstract class JsonResponseHandler implements IResponseHandler {
|
||||
protected IUserLookupFromIdentifier userLookupFromIdentifier;
|
||||
@Autowired
|
||||
protected ApplicationSettings applicationSettings;
|
||||
@Autowired
|
||||
private ProjectFacade facade;
|
||||
|
||||
private Logger logger = Logger.getLogger(JsonResponseHandler.class);
|
||||
|
||||
@ -145,7 +149,11 @@ abstract class JsonResponseHandler implements IResponseHandler {
|
||||
Date daisyStartDate = new Date(jThesis.daisyStartDate);
|
||||
project.setDaisyStartDate(daisyStartDate);
|
||||
}
|
||||
|
||||
|
||||
project = projectDao.save(project);
|
||||
facade.generateChecklists(project);
|
||||
|
||||
//Synch participants
|
||||
if(options.getLookupDepth().equals(RemoteLookupOptions.LOOKUP_DEPTH.PROJECT_AND_PARTICIPANTS)){
|
||||
for(JsonThesisParticipant jtp : jThesis.participants){
|
||||
|
@ -6,7 +6,7 @@ import se.su.dsv.scipro.repository.panels.ProjectFilePanel;
|
||||
import se.su.dsv.scipro.security.auth.Authorization;
|
||||
import se.su.dsv.scipro.security.auth.roles.Roles;
|
||||
|
||||
@Authorization(authorizedRoles={Roles.SYSADMIN}) //TODO Hidden for initial deployment
|
||||
@Authorization(authorizedRoles={Roles.STUDENT}) //TODO Hidden for initial deployment
|
||||
public class ProjectFilePage extends ProjectPage {
|
||||
|
||||
public ProjectFilePage(PageParameters pp) {
|
||||
|
@ -12,10 +12,8 @@ import se.su.dsv.scipro.basepages.MenuPage;
|
||||
import se.su.dsv.scipro.data.dao.interfaces.ProjectDao;
|
||||
import se.su.dsv.scipro.data.dao.interfaces.UserSettingsDao;
|
||||
import se.su.dsv.scipro.data.dataobjects.Project;
|
||||
import se.su.dsv.scipro.data.dataobjects.Student;
|
||||
import se.su.dsv.scipro.data.dataobjects.User;
|
||||
import se.su.dsv.scipro.data.dataobjects.UserSettings;
|
||||
import se.su.dsv.scipro.exceptions.RenderingSafeException;
|
||||
import se.su.dsv.scipro.project.panels.ProjectTabMenuPanel;
|
||||
import se.su.dsv.scipro.repository.FilePanelContainer;
|
||||
|
||||
@ -25,10 +23,12 @@ public abstract class ProjectPage extends MenuPage implements FilePanelContainer
|
||||
protected ProjectDao projectDao;
|
||||
@SpringBean
|
||||
private UserSettingsDao userSettingsDao;
|
||||
private User user;
|
||||
private Project activeProject;
|
||||
|
||||
public ProjectPage(PageParameters pp) {
|
||||
Project activeProject = SciProSession.get().getActiveProject();
|
||||
User u = SciProSession.get().getUser();
|
||||
activeProject = SciProSession.get().getActiveProject();
|
||||
user = SciProSession.get().getUser();
|
||||
|
||||
if(activeProject == null && (this.getClass() != NoActiveProjectPage.class && this.getClass() != ProjectPartnerPage.class)){
|
||||
User user = SciProSession.get().getUser();
|
||||
@ -39,13 +39,12 @@ public abstract class ProjectPage extends MenuPage implements FilePanelContainer
|
||||
UserSettings userSettings = userSettingsDao.getUserSettings(user);
|
||||
userSettings.setActiveProject(activeProject);
|
||||
userSettings = userSettingsDao.save(userSettings);
|
||||
}
|
||||
else {
|
||||
}else{
|
||||
throw new RestartResponseException(NoActiveProjectPage.class);
|
||||
}
|
||||
} else if(activeProject != null){
|
||||
/* Make sure we're still part of the project */
|
||||
if(!projectDao.isPartOf(u, activeProject)) {
|
||||
if(!projectDao.isPartOf(user, activeProject)) {
|
||||
SciProSession.get().setActiveProject(null);
|
||||
activeProject = null;
|
||||
throw new RestartResponseException(NoActiveProjectPage.class);
|
||||
@ -54,7 +53,20 @@ public abstract class ProjectPage extends MenuPage implements FilePanelContainer
|
||||
|
||||
add(new ProjectTabMenuPanel("tabMenu", this.getClass() ));
|
||||
}
|
||||
|
||||
/**
|
||||
* Exposes current user to subclasses.
|
||||
* @return
|
||||
*/
|
||||
protected User getUser(){
|
||||
return user;
|
||||
}
|
||||
/**
|
||||
* Exposes current project to subclasses.
|
||||
* @return
|
||||
*/
|
||||
protected Project getActiveProject(){
|
||||
return activeProject;
|
||||
}
|
||||
@Override
|
||||
public Class<? extends WebPage> getSurroundingPageClass() {
|
||||
return this.getClass();
|
||||
|
@ -6,6 +6,7 @@ import org.apache.wicket.PageParameters;
|
||||
import se.su.dsv.scipro.SciProSession;
|
||||
import se.su.dsv.scipro.schedule.panels.ScheduleGeneratorPanel;
|
||||
|
||||
@Deprecated
|
||||
public class ProjectScheduleGeneratorPage extends ProjectSchedulePage {
|
||||
|
||||
public ProjectScheduleGeneratorPage(final PageParameters pp){
|
||||
|
@ -7,7 +7,7 @@ import se.su.dsv.scipro.schedule.panels.SchedulePlannerPanel;
|
||||
import se.su.dsv.scipro.security.auth.Authorization;
|
||||
import se.su.dsv.scipro.security.auth.roles.Roles;
|
||||
|
||||
@Authorization(authorizedRoles={Roles.SYSADMIN}) //TODO Hidden for initial deployment
|
||||
@Authorization(authorizedRoles={Roles.STUDENT}) //TODO Hidden for initial deployment
|
||||
public class ProjectSchedulePlannerPage extends ProjectSchedulePage {
|
||||
|
||||
public ProjectSchedulePlannerPage(PageParameters pp) {
|
||||
|
@ -2,10 +2,7 @@ package se.su.dsv.scipro.project.pages;
|
||||
|
||||
import org.apache.wicket.PageParameters;
|
||||
|
||||
import se.su.dsv.scipro.SciProSession;
|
||||
import se.su.dsv.scipro.checklists.panels.ListCheckListPanel;
|
||||
import se.su.dsv.scipro.checklists.panels.ViewCheckListPanel;
|
||||
import se.su.dsv.scipro.data.dataobjects.CheckList;
|
||||
import se.su.dsv.scipro.data.enums.CheckListRole;
|
||||
import se.su.dsv.scipro.security.auth.Authorization;
|
||||
import se.su.dsv.scipro.security.auth.roles.Roles;
|
||||
@ -15,11 +12,12 @@ import se.su.dsv.scipro.security.auth.roles.Roles;
|
||||
*
|
||||
*/
|
||||
|
||||
@Authorization(authorizedRoles={Roles.SYSADMIN})
|
||||
@Authorization(authorizedRoles={Roles.STUDENT})
|
||||
public class ProjectViewCheckListPage extends ProjectPage {
|
||||
|
||||
public ProjectViewCheckListPage(PageParameters pp) {
|
||||
super(pp);
|
||||
System.out.println(pp.getAsLong("checklist"));
|
||||
add(new ViewCheckListPanel("viewCheckListPanel", CheckListRole.AUTHOR, pp));
|
||||
}
|
||||
|
||||
|
@ -6,6 +6,7 @@ import java.util.List;
|
||||
import org.apache.wicket.Page;
|
||||
|
||||
import se.su.dsv.scipro.SciProSession;
|
||||
import se.su.dsv.scipro.activityplan.pages.ProjectActivityPlanPage;
|
||||
import se.su.dsv.scipro.components.AbstractMenuPanel;
|
||||
import se.su.dsv.scipro.conference.pages.ProjectConferencePage;
|
||||
import se.su.dsv.scipro.data.dataobjects.Project;
|
||||
@ -43,7 +44,8 @@ public class ProjectTabMenuPanel extends AbstractMenuPanel {
|
||||
|
||||
if(activeProject != null){
|
||||
itemList.add(new MenuItem("Projects details", ProjectStartPage.class));
|
||||
itemList.add(new MenuItem("Activity plan", ProjectSchedulePlannerPage.class));
|
||||
itemList.add(new MenuItem("Activity plan", ProjectSchedulePlannerPage.class));
|
||||
itemList.add(new MenuItem("New activity plan", ProjectActivityPlanPage.class));
|
||||
itemList.add(new MenuItem("Files", ProjectFilePage.class, ProjectFilePanel.getPrefabricatedPageParameters(activeProject)));
|
||||
itemList.add(new MenuItem("Opposition & Active participation", ProjectOppositionPage.class));
|
||||
itemList.add(new MenuItem("Peer portal", ProjectPeerPortalPage.class));
|
||||
|
@ -115,7 +115,7 @@ public interface FileRepository {
|
||||
* @param upload
|
||||
* @param absolutePath
|
||||
*/
|
||||
void storeFile(FileUpload upload, String absolutePath);
|
||||
String storeFile(FileUpload upload, String absolutePath);
|
||||
/**
|
||||
* Get resource stream to read a file from a FileDescription, returns null if file does not exist
|
||||
* @param fileDesc
|
||||
|
@ -312,6 +312,7 @@ public class FileRepositoryImpl implements FileRepository {
|
||||
desc.setTargetLastModified(file.getNode("jcr:content").getProperty("jcr:lastModified").getDate().getTime());
|
||||
desc.setMimeType(file.getNode("jcr:content").getProperty("jcr:mimeType").getString());
|
||||
desc.setSize(file.getNode("jcr:content").getProperty("jcr:data").getLength());
|
||||
desc.setIdentifier(identifier);
|
||||
return desc;
|
||||
|
||||
} catch (Exception e) {
|
||||
@ -330,7 +331,7 @@ public class FileRepositoryImpl implements FileRepository {
|
||||
desc.setTargetLastModified(file.getNode("jcr:content").getProperty("jcr:lastModified").getDate().getTime());
|
||||
desc.setMimeType(file.getNode("jcr:content").getProperty("jcr:mimeType").getString());
|
||||
desc.setSize(file.getNode("jcr:content").getProperty("jcr:data").getLength());
|
||||
|
||||
desc.setIdentifier(file.getIdentifier());
|
||||
return desc;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
@ -339,7 +340,7 @@ public class FileRepositoryImpl implements FileRepository {
|
||||
return null;
|
||||
}
|
||||
|
||||
public void storeFile(FileUpload upload, String absolutePath){
|
||||
public String storeFile(FileUpload upload, String absolutePath){
|
||||
try {
|
||||
if (upload != null) {
|
||||
if(!absolutePath.endsWith("/"))
|
||||
@ -355,11 +356,12 @@ public class FileRepositoryImpl implements FileRepository {
|
||||
if(mimeType != null)
|
||||
mimeString = mimeType.toString();
|
||||
String unescapedFileName = upload.getClientFileName();
|
||||
this.storeFile(absolutePath + unescapedFileName, mimeString, upload.getInputStream());
|
||||
return this.storeFile(absolutePath + unescapedFileName, mimeString, upload.getInputStream());
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}//storeFile
|
||||
|
||||
public IResourceStream getFileStream(final FileDescription fileDescription){
|
||||
|
@ -0,0 +1,18 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"
|
||||
xmlns:wicket="http://wicket.apache.org/dtds.data/wicket-xhtml1.4-strict.dtd">
|
||||
<wicket:remove>
|
||||
<link rel="stylesheet" type="text/css" href="../../../../../../../webapp/css/scipro.css"/>
|
||||
<link rel="stylesheet" type="text/css" href="../../../../../../../webapp/css/blueprint/screen.css"/>
|
||||
</wicket:remove>
|
||||
<body>
|
||||
<wicket:panel>
|
||||
<wicket:extend>
|
||||
<a href="#" wicket:id="fileDelete">
|
||||
<img src="images/icons/delete_16x16.png" alt="Delete"/>
|
||||
</a>
|
||||
</wicket:extend>
|
||||
</wicket:panel>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,58 @@
|
||||
package se.su.dsv.scipro.repository.panels;
|
||||
|
||||
import org.apache.wicket.markup.html.link.Link;
|
||||
import org.apache.wicket.spring.injection.annot.SpringBean;
|
||||
|
||||
import se.su.dsv.scipro.data.dao.interfaces.FileDescriptionDao;
|
||||
import se.su.dsv.scipro.data.dataobjects.FileDescription;
|
||||
import se.su.dsv.scipro.repository.FileRepository;
|
||||
|
||||
/**
|
||||
* Extension of FileViewPanel allowing for callback deletion of the file item.
|
||||
*/
|
||||
public final class FileViewDeletePanel extends FileViewPanel{
|
||||
@SpringBean
|
||||
private FileRepository fileRepository;
|
||||
@SpringBean
|
||||
private FileDescriptionDao fileDescriptionDao;
|
||||
/**
|
||||
* Simple callback/strategy interface.
|
||||
*/
|
||||
public interface FileDeleteStrategy{
|
||||
public void handleDelete(final FileDescription fileDesc);
|
||||
public boolean renderDeleteLink();
|
||||
}
|
||||
private final transient FileDeleteStrategy callback;
|
||||
private static final long serialVersionUID = 1L;
|
||||
private final Link<Void> fileDeleteLink;
|
||||
/**
|
||||
* Default and only constructor, if the supplied file-delete callback is null: a default implementation will be used.
|
||||
* @param id
|
||||
* @param fileDesc
|
||||
*/
|
||||
public FileViewDeletePanel(final String id, final FileDescription fileDesc, final FileDeleteStrategy callback){
|
||||
super(id,fileDesc);
|
||||
this.callback = (callback==null?new DefaultFileDeleteStrategy():callback);
|
||||
fileDeleteLink = new Link<Void>("fileDelete"){
|
||||
private static final long serialVersionUID = 1L;
|
||||
@Override
|
||||
public void onClick() {
|
||||
FileViewDeletePanel.this.callback.handleDelete(fileDesc);
|
||||
}
|
||||
};
|
||||
fileDeleteLink.setVisible(callback.renderDeleteLink());
|
||||
add(fileDeleteLink);
|
||||
}
|
||||
/**
|
||||
* Default implementation, removes the file.
|
||||
*/
|
||||
private final class DefaultFileDeleteStrategy implements FileDeleteStrategy{
|
||||
public void handleDelete(final FileDescription fileDesc){
|
||||
if(fileRepository.existsFileByPath(fileDesc.getPath()))
|
||||
fileRepository.delete(fileDesc.getPath());
|
||||
}
|
||||
public boolean renderDeleteLink(){
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
@ -8,20 +8,12 @@
|
||||
</wicket:remove>
|
||||
<body>
|
||||
<wicket:panel>
|
||||
<span wicket:id="fileName">somefile.txt</span>
|
||||
(<span wicket:id="fileCreatedTime">2011.01.01 13:37:01</span>)
|
||||
<a href="#" wicket:id="fileOpen">
|
||||
<!-- <img wicket:id="openIcon" alt="Open/Preview"/> -->
|
||||
|
||||
<img class="round-box-icon"
|
||||
src="images/icons/24/document_view.png" alt="Open" title="Open" />
|
||||
|
||||
</a>
|
||||
<a href="#" wicket:id="fileOpen"><span wicket:id="fileName">somefile.txt</span></a>
|
||||
(<span wicket:id="fileCreatedTime">2011.01.01 13:37:01</span>)
|
||||
<a href="#" wicket:id="fileDownload">
|
||||
<!-- <img wicket:id="downloadIcon" alt="Download"/> -->
|
||||
<img class="round-box-icon"
|
||||
src="images/icons/24/document_down.png" alt="Download" title="Download" />
|
||||
<img class="round-box-icon" src="images/icons/24/document_down.png" alt="Download" title="Download" />
|
||||
</a>
|
||||
<wicket:child/>
|
||||
</wicket:panel>
|
||||
</body>
|
||||
</html>
|
@ -14,7 +14,7 @@ import se.su.dsv.scipro.util.DateFormatter;
|
||||
/**
|
||||
* View panel component for displaying a single repository file based on it's FileDescription.
|
||||
*/
|
||||
public final class FileViewPanel extends Panel{
|
||||
public class FileViewPanel extends Panel{
|
||||
private static final long serialVersionUID = 1L;
|
||||
/**
|
||||
* Default and only constructor, assert-fails if the supplied fileDesc is null.
|
||||
@ -35,14 +35,14 @@ public final class FileViewPanel extends Panel{
|
||||
//Control logic for component data
|
||||
if(fileDesc != null){
|
||||
uploadNameLabel = new Label("fileName", new PropertyModel<FileDescription>(fileDesc,"name"));
|
||||
uploadTimeLabel = new DateFormatter().createFormattedDateLabel("fileCreatedTime", fileDesc.getTargetLastModified());
|
||||
uploadTimeLabel = new DateFormatter(DateFormatter.FORMAT.EXTENDED).createFormattedDateLabel("fileCreatedTime", fileDesc.getTargetLastModified());
|
||||
fileDownloadLink = new FileDownloadLink("fileDownload", new Model<FileDescription>(fileDesc),true);
|
||||
fileOpenLink = new FileOpenLink("fileOpen", new Model<FileDescription>(fileDesc),true);
|
||||
}
|
||||
//Add components
|
||||
add(uploadNameLabel);
|
||||
add(uploadTimeLabel);
|
||||
add(fileDownloadLink);
|
||||
fileOpenLink.add(uploadNameLabel);
|
||||
add(fileOpenLink);
|
||||
}
|
||||
}
|
@ -6,6 +6,7 @@ import org.apache.wicket.ResourceReference;
|
||||
import org.apache.wicket.markup.html.image.Image;
|
||||
import org.joda.time.DateTime;
|
||||
|
||||
@Deprecated
|
||||
public class CalendarIconImage extends Image {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
@ -18,6 +18,7 @@ import se.su.dsv.scipro.data.dataobjects.GroupEvent;
|
||||
import se.su.dsv.scipro.data.dataobjects.Project;
|
||||
import se.su.dsv.scipro.schedule.baseevent.EventForm;
|
||||
|
||||
@Deprecated
|
||||
public abstract class GroupEventForm extends EventForm<GroupEventFormModel>{
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
@ -7,10 +7,10 @@ import se.su.dsv.scipro.SciProSession;
|
||||
import se.su.dsv.scipro.data.dataobjects.GroupEvent;
|
||||
import se.su.dsv.scipro.data.dataobjects.HandInActivity;
|
||||
import se.su.dsv.scipro.data.dataobjects.Project;
|
||||
import se.su.dsv.scipro.data.dataobjects.ProjectEvent;
|
||||
import se.su.dsv.scipro.data.dataobjects.ProjectSchedule;
|
||||
import se.su.dsv.scipro.schedule.baseevent.EventFormModel;
|
||||
|
||||
@Deprecated
|
||||
public class GroupEventFormModel extends EventFormModel<GroupEvent> {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
@ -34,6 +34,8 @@ import org.odlabs.wiquery.ui.datepicker.DatePicker.ShowOnEnum;
|
||||
import org.odlabs.wiquery.ui.dialog.Dialog;
|
||||
|
||||
import se.su.dsv.scipro.SciProSession;
|
||||
import se.su.dsv.scipro.activityplan.facade.ScheduleGenerator;
|
||||
import se.su.dsv.scipro.activityplan.facade.ScheduleGeneratorResult;
|
||||
import se.su.dsv.scipro.components.FormFeedbackPanel;
|
||||
import se.su.dsv.scipro.data.dao.interfaces.HandInActivityDao;
|
||||
import se.su.dsv.scipro.data.dao.interfaces.ProjectDao;
|
||||
@ -51,10 +53,9 @@ import se.su.dsv.scipro.schedule.templates.panels.ScheduleTemplateDetailsPanel;
|
||||
import se.su.dsv.scipro.schedule.templates.panels.ScheduleTemplateFilterPanel;
|
||||
import se.su.dsv.scipro.schedule.templates.panels.models.ScheduleTemplatesModel;
|
||||
import se.su.dsv.scipro.util.DateFormatter;
|
||||
import se.su.dsv.scipro.util.ScheduleGenerator;
|
||||
import se.su.dsv.scipro.util.ScheduleGeneratorResult;
|
||||
import se.su.dsv.scipro.util.WiQueryCoreEffectsHelper;
|
||||
|
||||
@Deprecated
|
||||
public abstract class ScheduleGeneratorPanel extends Panel {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
@ -11,7 +11,6 @@ import org.apache.wicket.ajax.markup.html.AjaxLink;
|
||||
import org.apache.wicket.markup.html.WebMarkupContainer;
|
||||
import org.apache.wicket.markup.html.basic.Label;
|
||||
import org.apache.wicket.markup.html.form.DropDownChoice;
|
||||
import org.apache.wicket.markup.html.link.BookmarkablePageLink;
|
||||
import org.apache.wicket.markup.html.link.Link;
|
||||
import org.apache.wicket.markup.html.list.ListItem;
|
||||
import org.apache.wicket.markup.html.list.ListView;
|
||||
@ -24,6 +23,7 @@ import org.odlabs.wiquery.core.effects.EffectSpeed;
|
||||
import org.odlabs.wiquery.ui.dialog.Dialog;
|
||||
|
||||
import se.su.dsv.scipro.SciProSession;
|
||||
import se.su.dsv.scipro.activityplan.facade.TemplateGenerator;
|
||||
import se.su.dsv.scipro.components.monthpicker.IMonthChangedListener;
|
||||
import se.su.dsv.scipro.components.monthpicker.MonthPicker;
|
||||
import se.su.dsv.scipro.data.dao.interfaces.ProjectDao;
|
||||
@ -42,10 +42,8 @@ import se.su.dsv.scipro.schedule.baseevent.panels.EventSchedulePanel;
|
||||
import se.su.dsv.scipro.schedule.groupevent.panels.CreateGroupEventPanel;
|
||||
import se.su.dsv.scipro.schedule.models.EventListModel;
|
||||
import se.su.dsv.scipro.schedule.projectevent.panels.CreateProjectEventPanel;
|
||||
import se.su.dsv.scipro.schedule.templates.pages.ScheduleTemplateDetailsPage;
|
||||
import se.su.dsv.scipro.supervisor.pages.SupervisorScheduleTemplatesEditorPage;
|
||||
import se.su.dsv.scipro.util.SelectOption;
|
||||
import se.su.dsv.scipro.util.TemplateGenerator;
|
||||
import se.su.dsv.scipro.util.WiQueryCoreEffectsHelper;
|
||||
|
||||
|
||||
|
@ -17,6 +17,7 @@ import se.su.dsv.scipro.data.dataobjects.Student;
|
||||
import se.su.dsv.scipro.data.dataobjects.User;
|
||||
import se.su.dsv.scipro.schedule.baseevent.EventForm;
|
||||
|
||||
@Deprecated
|
||||
public abstract class ProjectEventForm extends EventForm<ProjectEventFormModel> {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
@ -6,11 +6,11 @@ import java.util.TreeSet;
|
||||
|
||||
import se.su.dsv.scipro.SciProSession;
|
||||
import se.su.dsv.scipro.data.dataobjects.HandInActivity;
|
||||
import se.su.dsv.scipro.data.dataobjects.Project;
|
||||
import se.su.dsv.scipro.data.dataobjects.ProjectEvent;
|
||||
import se.su.dsv.scipro.data.dataobjects.Student;
|
||||
import se.su.dsv.scipro.schedule.baseevent.EventFormModel;
|
||||
|
||||
@Deprecated
|
||||
public class ProjectEventFormModel extends EventFormModel<ProjectEvent> {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
@ -19,8 +19,8 @@
|
||||
<input type="checkbox" wicket:id="requireHandIn">
|
||||
</div>
|
||||
<div class="formRow">
|
||||
<strong>Estimated number of days:</strong><br />
|
||||
<input type="text" wicket:id="estimatedTimeConsumption" name="estimatedTimeConsumption" />
|
||||
<strong>Days from previous event:</strong><br />
|
||||
<input type="text" wicket:id="daysOffset"/>
|
||||
</div>
|
||||
<div class="formRow">
|
||||
<button type="submit" wicket:id="addEventTemplateButton">
|
||||
|
@ -58,7 +58,7 @@ public class EventTemplateFormPanel extends Panel {
|
||||
|
||||
add(new TextField<String>("title").setRequired(true));
|
||||
add(new TextArea<String>("description"));
|
||||
add(new TextField<Long>("estimatedTimeConsumption"));
|
||||
add(new TextField<Long>("daysOffset"));
|
||||
add(new CheckBox("requireHandIn"));
|
||||
|
||||
AjaxButton addEventTemplateButton = new AjaxButton("addEventTemplateButton", new Model<String>(isEdit ? "Done" : "Add")){
|
||||
|
@ -10,10 +10,6 @@
|
||||
<td>Number of events:</td>
|
||||
<td><span wicket:id="numEventTemplates">Number of events</span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Estimated days for template:</td>
|
||||
<td><span wicket:id="totalEstimatedTime">Total days</span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Creator:</td>
|
||||
<td wicket:id="templateCreator"></td>
|
||||
@ -30,10 +26,6 @@
|
||||
<td>System template:</td>
|
||||
<td><img wicket:id="isSysAdminTemplate" /></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Active:</td>
|
||||
<td><img wicket:id="isActive" /></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Direct link:</td>
|
||||
<td><a href="#" wicket:id="directLink">link</a></td>
|
||||
@ -49,7 +41,7 @@
|
||||
<span wicket:id="etDescription">Event description</span>
|
||||
</div>
|
||||
<div>
|
||||
<span>Estimated days: </span><span wicket:id="etTimeConsumption">Time consumption</span>
|
||||
<span>Offset (in days): </span><span wicket:id="etTimeConsumption">Offset</span>
|
||||
</div>
|
||||
<div>
|
||||
<span>Hand in required: </span><img wicket:id="etRequireHandIn" />
|
||||
|
@ -42,11 +42,6 @@ public class ScheduleTemplateDetailsPanel extends Panel {
|
||||
List<ProjectEventTemplate> etList = template.getProjectEventTemplates();
|
||||
|
||||
add(new Label("numEventTemplates", etList.size() + ""));
|
||||
long totalEstimatedTime = 0;
|
||||
for(ProjectEventTemplate et : etList){
|
||||
totalEstimatedTime += et.getEstimatedTimeConsumption();
|
||||
}
|
||||
add(new Label("totalEstimatedTime", totalEstimatedTime + ""));
|
||||
|
||||
add(template.getCreator().getDisplayComponent("templateCreator"));
|
||||
final DateFormatter df = new DateFormatter();
|
||||
@ -55,9 +50,6 @@ public class ScheduleTemplateDetailsPanel extends Panel {
|
||||
|
||||
ImageObject isSysAdminT = new ImageObject("isSysAdminTemplate", template.isSysAdminTemplate() ? ImageObject.THIRTYTWO + ImageObject.LIGHT_GREEN : ImageObject.THIRTYTWO + ImageObject.LIGHT_RED);
|
||||
add(isSysAdminT);
|
||||
ImageObject isActive = new ImageObject("isActive", template.isActive() ? ImageObject.THIRTYTWO + ImageObject.LIGHT_GREEN : ImageObject.THIRTYTWO + ImageObject.LIGHT_RED);
|
||||
add(isActive);
|
||||
|
||||
|
||||
final PageParameters pp = new PageParameters();
|
||||
pp.put("tid", template.getId());
|
||||
@ -73,8 +65,8 @@ public class ScheduleTemplateDetailsPanel extends Panel {
|
||||
item.setOutputMarkupId(true);
|
||||
item.add(new Label("etTitle", et.getTitle()));
|
||||
item.add(new ExpandableMultiLineLabel("etDescription", 100, et.getDescription() != null ? et.getDescription() : "", false));
|
||||
item.add(new Label("etTimeConsumption", et.getEstimatedTimeConsumption() + ""));
|
||||
item.add(new ImageObject("etRequireHandIn", et.isRequireHandIn() ? ImageObject.THIRTYTWO + ImageObject.LIGHT_GREEN : ImageObject.THIRTYTWO + ImageObject.LIGHT_RED));
|
||||
item.add(new Label("etTimeConsumption", et.getDaysOffset() + ""));
|
||||
item.add(new ImageIcon("etRequireHandIn", et.isRequireHandIn() ? ImageIcon.ICON_YES : ImageIcon.ICON_NO));
|
||||
add(item);
|
||||
}
|
||||
|
||||
|
@ -4,15 +4,12 @@ import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.wicket.ResourceReference;
|
||||
import org.apache.wicket.ajax.AjaxRequestTarget;
|
||||
import org.apache.wicket.ajax.form.AjaxFormComponentUpdatingBehavior;
|
||||
import org.apache.wicket.extensions.ajax.markup.html.AjaxIndicatorAppender;
|
||||
import org.apache.wicket.extensions.ajax.markup.html.autocomplete.DefaultCssAutocompleteTextField;
|
||||
import org.apache.wicket.markup.html.CSSPackageResource;
|
||||
import org.apache.wicket.markup.html.WebMarkupContainer;
|
||||
import org.apache.wicket.markup.html.form.DropDownChoice;
|
||||
import org.apache.wicket.markup.html.form.TextField;
|
||||
import org.apache.wicket.markup.html.panel.Panel;
|
||||
import org.apache.wicket.model.IModel;
|
||||
import org.apache.wicket.model.Model;
|
||||
@ -58,10 +55,7 @@ public abstract class ScheduleTemplateFilterPanel extends Panel {
|
||||
public ScheduleTemplateFilterPanel(String id, final ScheduleTemplatesModel templateModel, final boolean showSysAdminOptions){
|
||||
super(id);
|
||||
|
||||
if(!showSysAdminOptions){
|
||||
templateModel.setOnlyActiveTemplates(true);
|
||||
}
|
||||
|
||||
|
||||
final WebMarkupContainer sysAdminOptionsContainer = new WebMarkupContainer("sysAdminOptionsContainer"){
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@ -91,21 +85,6 @@ public abstract class ScheduleTemplateFilterPanel extends Panel {
|
||||
|
||||
@Override
|
||||
protected void onUpdate(AjaxRequestTarget target) {
|
||||
|
||||
ActiveOption selected = activeDD.getModelObject().value;
|
||||
switch(selected) {
|
||||
case ALL:
|
||||
templateModel.setOnlyActiveTemplates(null);
|
||||
break;
|
||||
case ACTIVE:
|
||||
templateModel.setOnlyActiveTemplates(true);
|
||||
break;
|
||||
case INACTIVE:
|
||||
templateModel.setOnlyActiveTemplates(false);
|
||||
break;
|
||||
default:
|
||||
templateModel.setOnlyActiveTemplates(null);
|
||||
}
|
||||
onFilterChanged(target);
|
||||
}
|
||||
|
||||
|
@ -21,13 +21,6 @@
|
||||
<strong>Description:</strong><br />
|
||||
<textarea wicket:id="templateDescription" name="templateDescription"></textarea>
|
||||
</div>
|
||||
<div class="formRow">
|
||||
<strong>Active:</strong>
|
||||
<input type="checkbox" wicket:id="active" name="active" />
|
||||
</div>
|
||||
<div class="formRow">
|
||||
<strong>Days total: </strong><strong wicket:id="totalEstimatedTime">Number of days</strong>
|
||||
</div>
|
||||
<div class="formRow">
|
||||
<button type="submit" wicket:id="saveButton">
|
||||
<img alt=""/> Save
|
||||
@ -58,7 +51,7 @@
|
||||
<img wicket:id="editEventTemplateIcon" class="right round-box-icon"></img>
|
||||
</div>
|
||||
<div>
|
||||
<span>Estimated days:</span><span wicket:id="eventTemplateTimeConsumption">Event template time consumption</span>
|
||||
<span>Offset(days):</span><span wicket:id="eventTemplateOffset">Days from previous event</span>
|
||||
</div>
|
||||
</div>
|
||||
<div wicket:id="editEventTemplateContainer">
|
||||
|
@ -9,7 +9,6 @@ import org.apache.wicket.ajax.markup.html.AjaxLink;
|
||||
import org.apache.wicket.ajax.markup.html.form.AjaxButton;
|
||||
import org.apache.wicket.markup.html.WebMarkupContainer;
|
||||
import org.apache.wicket.markup.html.basic.Label;
|
||||
import org.apache.wicket.markup.html.form.CheckBox;
|
||||
import org.apache.wicket.markup.html.form.Form;
|
||||
import org.apache.wicket.markup.html.form.TextArea;
|
||||
import org.apache.wicket.markup.html.form.TextField;
|
||||
@ -75,8 +74,6 @@ public class ScheduleTemplateFormPanel extends Panel {
|
||||
private WebMarkupContainer eventTemplateListContainer;
|
||||
private WebMarkupContainer feedbackContainer;
|
||||
private FormFeedbackPanel<ScheduleTemplate> feedbackPanel;
|
||||
private Label totalEstimatedTimeLabel;
|
||||
private Long totalEstimatedTime = (long) 0;
|
||||
|
||||
public ScheduleTemplateForm(String id, final ScheduleTemplate template, final Class<? extends MenuPage> responsePageClass) {
|
||||
super(id, new CompoundPropertyModel<ScheduleTemplate>(template));
|
||||
@ -89,19 +86,6 @@ public class ScheduleTemplateFormPanel extends Panel {
|
||||
|
||||
add(new TextField<String>("templateName").setRequired(true));
|
||||
add(new TextArea<String>("templateDescription"));
|
||||
add(new CheckBox("active"));
|
||||
|
||||
updateEstimatedTime();
|
||||
totalEstimatedTimeLabel = new Label("totalEstimatedTime", new Model<Long>(){
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public Long getObject(){
|
||||
updateEstimatedTime();
|
||||
return totalEstimatedTime;
|
||||
}
|
||||
});
|
||||
totalEstimatedTimeLabel.setOutputMarkupId(true);
|
||||
add(totalEstimatedTimeLabel);
|
||||
|
||||
eventTemplateListContainer = new WebMarkupContainer("eventTemplateListContainer");
|
||||
eventTemplateListContainer.setOutputMarkupId(true);
|
||||
@ -121,7 +105,6 @@ public class ScheduleTemplateFormPanel extends Panel {
|
||||
private static final long serialVersionUID = 1L;
|
||||
@Override
|
||||
protected void onEventTemplateAdded(AjaxRequestTarget target){
|
||||
target.addComponent(totalEstimatedTimeLabel);
|
||||
target.addComponent(eventTemplateListContainer);
|
||||
target.appendJavascript(WiQueryCoreEffectsHelper.slideUpJs(addEventTemplateContainer, EffectSpeed.SLOW));
|
||||
}
|
||||
@ -149,7 +132,7 @@ public class ScheduleTemplateFormPanel extends Panel {
|
||||
final Label evTitle = new Label("eventTemplateTitle", new PropertyModel<String>(et, "title"));
|
||||
evTitle.setOutputMarkupId(true);
|
||||
item.add(evTitle);
|
||||
final Label evEstTimeCons = new Label("eventTemplateTimeConsumption", new PropertyModel<Long>(et, "estimatedTimeConsumption"));
|
||||
final Label evEstTimeCons = new Label("eventTemplateOffset", new PropertyModel<Long>(et, "daysOffset"));
|
||||
evEstTimeCons.setOutputMarkupId(true);
|
||||
item.add(evEstTimeCons);
|
||||
|
||||
@ -169,7 +152,6 @@ public class ScheduleTemplateFormPanel extends Panel {
|
||||
eventTemplateFormContainer.replace(new EventTemplateFormPanel("editEventTemplateFormPanel", et, template, true){
|
||||
private static final long serialVersionUID = 1L;
|
||||
protected void onEventTemplateAdded(AjaxRequestTarget target){
|
||||
target.addComponent(totalEstimatedTimeLabel);
|
||||
target.addComponent(evTitle);
|
||||
target.addComponent(evEstTimeCons);
|
||||
target.appendJavascript(WiQueryCoreEffectsHelper.slideUpJs(eventTemplateFormContainer, EffectSpeed.SLOW));
|
||||
@ -198,7 +180,6 @@ public class ScheduleTemplateFormPanel extends Panel {
|
||||
evList.get(i).setNumberInOrder(i - 1);
|
||||
}
|
||||
evList.remove(et.getNumberInOrder());
|
||||
target.addComponent(totalEstimatedTimeLabel);
|
||||
target.appendJavascript(WiQueryCoreEffectsHelper.slideUpJs(item, EffectSpeed.SLOW));
|
||||
|
||||
}
|
||||
@ -294,13 +275,5 @@ public class ScheduleTemplateFormPanel extends Panel {
|
||||
cancelButton.setDefaultFormProcessing(false);
|
||||
add(cancelButton);
|
||||
}
|
||||
|
||||
private void updateEstimatedTime(){
|
||||
long acc = 0;
|
||||
for(ProjectEventTemplate e : getModelObject().getProjectEventTemplates()){
|
||||
acc += e.getEstimatedTimeConsumption();
|
||||
}
|
||||
totalEstimatedTime = acc;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2,21 +2,20 @@
|
||||
<html
|
||||
xmlns:wicket="http://wicket.apache.org/dtds.data/wicket-xhtml1.4-strict.dtd">
|
||||
<body>
|
||||
<wicket:panel>
|
||||
<div class="span-22 last">
|
||||
<div wicket:id="filterPanel" class="span-22 last append-bottom"></div>
|
||||
<div class="span-22 last append-bottom">
|
||||
<a href="#" wicket:id="createNew"> <img
|
||||
wicket:id="createNewIcon" /> Create new template
|
||||
</a>
|
||||
<div wicket:id="templateListContainer">
|
||||
<table class="rounded-corner">
|
||||
|
||||
<wicket:panel>
|
||||
<div class="span-22 last">
|
||||
<div wicket:id="filterPanel" class="span-22 last append-bottom"></div>
|
||||
<div class="span-22 last append-bottom">
|
||||
<a href="#" wicket:id="createNew">
|
||||
<img wicket:id="createNewIcon" /> Create new template
|
||||
</a>
|
||||
<div wicket:id="templateListContainer">
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="rounded-left-top">Template name</th>
|
||||
<th>System template</th>
|
||||
<th>Active</th>
|
||||
<th>Creator</th>
|
||||
<th>Last updated</th>
|
||||
<th>Details</th>
|
||||
@ -31,9 +30,8 @@
|
||||
</tfoot>
|
||||
<tbody>
|
||||
<tr wicket:id="templateList">
|
||||
<td wicket:id="templateName">TempalteName</td>
|
||||
<td wicket:id="templateName">TemplateName</td>
|
||||
<td><img wicket:id="isSysAdminTemplate"></img></td>
|
||||
<td><img wicket:id="isActive" /></td>
|
||||
<td wicket:id="templateCreator">Creator</td>
|
||||
<td wicket:id="templateUpdated">Last updated</td>
|
||||
<td><img wicket:id="detailsIcon" /></td>
|
||||
@ -54,13 +52,11 @@
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div wicket:id="templateDetailsContainer">
|
||||
<div wicket:id="templateDetailsPanel"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</wicket:panel>
|
||||
</body>
|
||||
</html>
|
@ -71,10 +71,7 @@ public class ScheduleTemplatePanel extends Panel {
|
||||
final ScheduleTemplate s = item.getModelObject();
|
||||
item.add(new Label("templateName", s.getTemplateName()));
|
||||
|
||||
ImageObject isActive = new ImageObject("isActive", s.isActive() ? ImageObject.THIRTYTWO + ImageObject.LIGHT_GREEN : ImageObject.THIRTYTWO + ImageObject.LIGHT_RED);
|
||||
item.add(isActive);
|
||||
|
||||
ImageObject isSysAdminT = new ImageObject("isSysAdminTemplate", s.isSysAdminTemplate() ? ImageObject.TWENTYFOUR + ImageObject.CHECK : ImageObject.TWENTYFOUR + ImageObject.DELETE2);
|
||||
ImageIcon isSysAdminT = new ImageIcon("isSysAdminTemplate", s.isSysAdminTemplate() ? ImageIcon.ICON_CHECK : ImageIcon.ICON_EMPTY);
|
||||
item.add(isSysAdminT);
|
||||
|
||||
item.add(s.getCreator().getDisplayComponent("templateCreator"));
|
||||
|
@ -1,6 +1,5 @@
|
||||
package se.su.dsv.scipro.schedule.templates.panels.models;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.wicket.injection.web.InjectorHolder;
|
||||
@ -27,7 +26,6 @@ public class ScheduleTemplatesModel extends LoadableDetachableModel<List<Schedul
|
||||
private UserDao userDao;
|
||||
|
||||
private ProjectClass projectClass = null;
|
||||
private Boolean onlyActiveTemplates = null;
|
||||
private User creator = null;
|
||||
private Long creatorId = null;
|
||||
private Boolean onlySysAdminTemplates = null;
|
||||
@ -38,7 +36,7 @@ public class ScheduleTemplatesModel extends LoadableDetachableModel<List<Schedul
|
||||
|
||||
@Override
|
||||
protected List<ScheduleTemplate> load() {
|
||||
return scheduleTemplateDao.getScheduleTemplates(creator, onlySysAdminTemplates, onlyActiveTemplates, projectClass);
|
||||
return scheduleTemplateDao.getScheduleTemplates(creator, onlySysAdminTemplates, projectClass);
|
||||
}
|
||||
|
||||
public void reloadModel(){
|
||||
@ -53,15 +51,6 @@ public class ScheduleTemplatesModel extends LoadableDetachableModel<List<Schedul
|
||||
return onlySysAdminTemplates;
|
||||
}
|
||||
|
||||
public Boolean isOnlyActiveTemplates() {
|
||||
return onlyActiveTemplates;
|
||||
}
|
||||
|
||||
public void setOnlyActiveTemplates(Boolean onlyActiveTemplates) {
|
||||
this.onlyActiveTemplates = onlyActiveTemplates;
|
||||
reloadModel();
|
||||
}
|
||||
|
||||
public ProjectClass getProjectClass() {
|
||||
return projectClass;
|
||||
}
|
||||
@ -82,7 +71,6 @@ public class ScheduleTemplatesModel extends LoadableDetachableModel<List<Schedul
|
||||
|
||||
public void clearFilter(boolean withReload){
|
||||
projectClass = null;
|
||||
onlyActiveTemplates = null;
|
||||
creator = null;
|
||||
onlySysAdminTemplates = null;
|
||||
if(withReload){
|
||||
|
@ -1,11 +0,0 @@
|
||||
package se.su.dsv.scipro.supervisor.pages;
|
||||
|
||||
import org.apache.wicket.PageParameters;
|
||||
|
||||
|
||||
public abstract class AbstractSupervisorScheduleTemplatesPage extends AbstractSupervisorPage {
|
||||
|
||||
public AbstractSupervisorScheduleTemplatesPage(final PageParameters pp){
|
||||
super(pp);
|
||||
}
|
||||
}
|
@ -5,17 +5,13 @@ import org.apache.wicket.PageParameters;
|
||||
import se.su.dsv.scipro.checklists.panels.ListCheckListPanel;
|
||||
import se.su.dsv.scipro.components.MenuHighlightSupervisorMyProjects;
|
||||
import se.su.dsv.scipro.data.enums.CheckListRole;
|
||||
import se.su.dsv.scipro.security.auth.Authorization;
|
||||
import se.su.dsv.scipro.security.auth.roles.Roles;
|
||||
|
||||
/**
|
||||
* @author Fredrik Norberg - fnorbe@dsv.su.se
|
||||
*
|
||||
*/
|
||||
|
||||
@Authorization(authorizedRoles={Roles.SYSADMIN})
|
||||
public class SupervisorChecklistPage extends AbstractSupervisorProjectDetailsPage implements MenuHighlightSupervisorMyProjects {
|
||||
|
||||
public SupervisorChecklistPage(PageParameters pp) {
|
||||
super(pp);
|
||||
add(new ListCheckListPanel("listCheckListPanel", CheckListRole.SUPERVISOR, pp));
|
||||
|
@ -2,8 +2,10 @@ package se.su.dsv.scipro.supervisor.pages;
|
||||
|
||||
import org.apache.wicket.Page;
|
||||
import org.apache.wicket.PageParameters;
|
||||
|
||||
import se.su.dsv.scipro.schedule.panels.ScheduleGeneratorPanel;
|
||||
|
||||
@Deprecated
|
||||
public class SupervisorScheduleGeneratorPage extends AbstractSupervisorProjectDetailsPage {
|
||||
|
||||
public SupervisorScheduleGeneratorPage(final PageParameters pp){
|
||||
|
@ -8,10 +8,8 @@ import se.su.dsv.scipro.data.dao.interfaces.ScheduleTemplateDao;
|
||||
import se.su.dsv.scipro.data.dataobjects.ScheduleTemplate;
|
||||
import se.su.dsv.scipro.exceptions.AccessDeniedException;
|
||||
import se.su.dsv.scipro.schedule.templates.panels.ScheduleTemplateFormPanel;
|
||||
import se.su.dsv.scipro.security.auth.Authorization;
|
||||
import se.su.dsv.scipro.security.auth.roles.Roles;
|
||||
|
||||
public class SupervisorScheduleTemplatesEditorPage extends AbstractSupervisorScheduleTemplatesPage {
|
||||
public class SupervisorScheduleTemplatesEditorPage extends AbstractSupervisorPage {
|
||||
|
||||
@SpringBean
|
||||
private ScheduleTemplateDao scheduleTemplateDao;
|
||||
|
@ -6,8 +6,8 @@ import se.su.dsv.scipro.schedule.templates.panels.ScheduleTemplatePanel;
|
||||
import se.su.dsv.scipro.security.auth.Authorization;
|
||||
import se.su.dsv.scipro.security.auth.roles.Roles;
|
||||
|
||||
@Authorization(authorizedRoles={Roles.SYSADMIN}) //TODO Hidden for initial deployment
|
||||
public class SupervisorScheduleTemplatesPage extends AbstractSupervisorScheduleTemplatesPage {
|
||||
@Authorization(authorizedRoles={Roles.EMPLOYEE})
|
||||
public class SupervisorScheduleTemplatesPage extends AbstractSupervisorPage {
|
||||
|
||||
public SupervisorScheduleTemplatesPage(final PageParameters pp){
|
||||
super(pp);
|
||||
|
@ -15,7 +15,7 @@ import se.su.dsv.scipro.security.auth.roles.Roles;
|
||||
*
|
||||
*/
|
||||
|
||||
@Authorization(authorizedRoles={Roles.SYSADMIN})
|
||||
@Authorization(authorizedRoles={Roles.EMPLOYEE})
|
||||
public class SupervisorViewCheckListPage extends AbstractSupervisorProjectDetailsPage {
|
||||
|
||||
public SupervisorViewCheckListPage(PageParameters pp) {
|
||||
|
@ -6,6 +6,7 @@ import java.util.List;
|
||||
import org.apache.wicket.Page;
|
||||
import org.apache.wicket.PageParameters;
|
||||
|
||||
import se.su.dsv.scipro.activityplan.pages.SupervisorActivityPlanPage;
|
||||
import se.su.dsv.scipro.components.AbstractMenuPanel;
|
||||
import se.su.dsv.scipro.conference.pages.SupervisorConferencePage;
|
||||
import se.su.dsv.scipro.data.dataobjects.Project;
|
||||
@ -36,6 +37,7 @@ public class SupervisorSubTabMenuPanel extends AbstractMenuPanel{
|
||||
List<MenuItem> items = new ArrayList<MenuItem>();
|
||||
items.add(new MenuItem("Overview", SupervisorProjectDetailsPage.class));
|
||||
items.add(new MenuItem("Activity plan", SupervisorSchedulePlannerPage.class));
|
||||
items.add(new MenuItem("New activity plan", SupervisorActivityPlanPage.class));
|
||||
items.add(new MenuItem("Notes", SupervisorLogPage.class));
|
||||
|
||||
if (projectParams.getAsLong(Project.PP_PROJECT_ID)!=null){
|
||||
|
@ -2,7 +2,6 @@ package se.su.dsv.scipro.workerthreads;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Properties;
|
||||
import java.util.Set;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
@ -10,11 +9,9 @@ import org.springframework.stereotype.Component;
|
||||
|
||||
import se.su.dsv.scipro.data.dao.interfaces.GeneralSystemSettingsDao;
|
||||
import se.su.dsv.scipro.data.dao.interfaces.MailEventDao;
|
||||
import se.su.dsv.scipro.data.dataobjects.GeneralSystemSettings;
|
||||
import se.su.dsv.scipro.data.dataobjects.MailEvent;
|
||||
import se.su.dsv.scipro.data.dataobjects.User;
|
||||
import se.su.dsv.scipro.util.Mail;
|
||||
import se.su.dsv.scipro.util.PropsUtils;
|
||||
|
||||
@Component
|
||||
public class MailEventWorker extends AbstractWorker {
|
||||
|
@ -5,211 +5,77 @@
|
||||
http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"
|
||||
version="2.0">
|
||||
|
||||
<!-- NOTE THAT THERE ARE TWO PERSISTENCE UNITS, one default and one test used for either running or unit-tests -->
|
||||
<!-- NOTE THAT THERE ARE TWO PERSISTENCE UNITS, one default and one test
|
||||
used for either running or unit-tests -->
|
||||
|
||||
<!-- A JPA Persistence Unit -->
|
||||
<persistence-unit name="defaultPersistenceUnit" transaction-type="RESOURCE_LOCAL">
|
||||
|
||||
<persistence-unit name="defaultPersistenceUnit"
|
||||
transaction-type="RESOURCE_LOCAL">
|
||||
<provider>org.hibernate.ejb.HibernatePersistence</provider>
|
||||
|
||||
<!-- JPA entities must be registered here -->
|
||||
<class>se.su.dsv.scipro.data.dataobjects.Username</class>
|
||||
<class>se.su.dsv.scipro.data.dataobjects.User</class>
|
||||
<class>se.su.dsv.scipro.data.dataobjects.LazyDeletableDomainObject</class>
|
||||
<class>se.su.dsv.scipro.data.dataobjects.Event</class>
|
||||
<class>se.su.dsv.scipro.data.dataobjects.ProjectEvent</class>
|
||||
<class>se.su.dsv.scipro.data.dataobjects.GroupEvent</class>
|
||||
<class>se.su.dsv.scipro.data.dataobjects.DomainObject</class>
|
||||
<class>se.su.dsv.scipro.data.dataobjects.Student</class>
|
||||
<class>se.su.dsv.scipro.data.dataobjects.Admin</class>
|
||||
<class>se.su.dsv.scipro.data.dataobjects.SysAdmin</class>
|
||||
<class>se.su.dsv.scipro.data.dataobjects.Employee</class>
|
||||
<class>se.su.dsv.scipro.data.dataobjects.Role</class>
|
||||
<class>se.su.dsv.scipro.data.dataobjects.Project</class>
|
||||
<class>se.su.dsv.scipro.data.dataobjects.ProjectSchedule</class>
|
||||
<class>se.su.dsv.scipro.data.dataobjects.ProjectFollower</class>
|
||||
<class>se.su.dsv.scipro.data.dataobjects.ProjectTeamMember</class>
|
||||
<class>se.su.dsv.scipro.data.dataobjects.BoardMessage</class>
|
||||
<class>se.su.dsv.scipro.data.dataobjects.MessageBoard</class>
|
||||
<class>se.su.dsv.scipro.data.dataobjects.PrivateMessage</class>
|
||||
<class>se.su.dsv.scipro.data.dataobjects.Recipient</class>
|
||||
<class>se.su.dsv.scipro.data.dataobjects.StringResource</class>
|
||||
<class>se.su.dsv.scipro.data.dataobjects.Ratable</class>
|
||||
<class>se.su.dsv.scipro.data.dataobjects.Rating</class>
|
||||
<class>se.su.dsv.scipro.data.dataobjects.Resource</class>
|
||||
<class>se.su.dsv.scipro.data.dataobjects.Tag</class>
|
||||
<class>se.su.dsv.scipro.data.dataobjects.Comment</class>
|
||||
<class>se.su.dsv.scipro.data.dataobjects.ProjectEventTemplate</class>
|
||||
<class>se.su.dsv.scipro.data.dataobjects.ProjectClass</class>
|
||||
<class>se.su.dsv.scipro.data.dataobjects.ScheduleTemplate</class>
|
||||
<class>se.su.dsv.scipro.data.dataobjects.FileDescription</class>
|
||||
<class>se.su.dsv.scipro.peer.data.dataobjects.Answer</class>
|
||||
<class>se.su.dsv.scipro.peer.data.dataobjects.PeerQueue</class>
|
||||
<class>se.su.dsv.scipro.peer.data.dataobjects.PeerReview</class>
|
||||
<class>se.su.dsv.scipro.peer.data.dataobjects.PeerRequest</class>
|
||||
<class>se.su.dsv.scipro.peer.data.dataobjects.Question</class>
|
||||
<class>se.su.dsv.scipro.peer.data.dataobjects.ReviewRating</class>
|
||||
<class>se.su.dsv.scipro.data.dataobjects.CommentThread</class>
|
||||
<class>se.su.dsv.scipro.data.dataobjects.UserSettings</class>
|
||||
<class>se.su.dsv.scipro.data.dataobjects.HandInActivity</class>
|
||||
<class>se.su.dsv.scipro.data.dataobjects.HandIn</class>
|
||||
<class>se.su.dsv.scipro.data.dataobjects.HandInFeedback</class>
|
||||
<class>se.su.dsv.scipro.data.dataobjects.Category</class>
|
||||
<class>se.su.dsv.scipro.data.dataobjects.FinalSeminar</class>
|
||||
<class>se.su.dsv.scipro.data.dataobjects.FinalSeminarOpposition</class>
|
||||
<class>se.su.dsv.scipro.data.dataobjects.FinalSeminarActiveParticipation</class>
|
||||
<class>se.su.dsv.scipro.data.dataobjects.GeneralSystemSettings</class>
|
||||
<class>se.su.dsv.scipro.data.dataobjects.WorkerData</class>
|
||||
<class>se.su.dsv.scipro.data.dataobjects.ProjectClassSettings</class>
|
||||
<class>se.su.dsv.scipro.data.dataobjects.MailEvent</class>
|
||||
<class>se.su.dsv.scipro.data.dataobjects.ProjectPartner</class>
|
||||
<class>se.su.dsv.scipro.data.dataobjects.CheckPlagiarismEvent</class>
|
||||
<class>se.su.dsv.scipro.data.dataobjects.WebNotification</class>
|
||||
<class>se.su.dsv.scipro.data.dataobjects.CheckListTemplate</class>
|
||||
<class>se.su.dsv.scipro.data.dataobjects.CheckList</class>
|
||||
<class>se.su.dsv.scipro.data.dataobjects.CheckListAnswer</class>
|
||||
<class>se.su.dsv.scipro.data.dataobjects.CheckListQuestion</class>
|
||||
<class>se.su.dsv.scipro.data.dataobjects.CheckListUpload</class>
|
||||
<class>se.su.dsv.scipro.data.dataobjects.ChecklistCategory</class>
|
||||
|
||||
<properties>
|
||||
|
||||
<!-- 2nd level cache -->
|
||||
<property name="hibernate.cache.provider_class" value="org.hibernate.cache.SingletonEhCacheProvider" />
|
||||
<property name="net.sf.ehcache.configurationResourceName" value="/ehcache.xml" />
|
||||
<property name="hibernate.cache.use_query_cache" value="true" />
|
||||
<property name="hibernate.cache.use_second_level_cache" value="true" />
|
||||
<property name="hibernate.generate_statistics" value="false" />
|
||||
|
||||
<!-- 2nd level cache -->
|
||||
<property name="hibernate.cache.provider_class"
|
||||
value="org.hibernate.cache.SingletonEhCacheProvider" />
|
||||
<property name="net.sf.ehcache.configurationResourceName"
|
||||
value="/ehcache.xml" />
|
||||
<property name="hibernate.cache.use_query_cache" value="true" />
|
||||
<property name="hibernate.cache.use_second_level_cache"
|
||||
value="true" />
|
||||
<property name="hibernate.generate_statistics" value="false" />
|
||||
<!-- DEVELOPMENT VARIABLE, REMOVE FOR PRODUCTION USE -->
|
||||
|
||||
<!--property name="hibernate.hbm2ddl.auto" value="update" /-->
|
||||
|
||||
<property name="hibernate.hbm2ddl.auto" value="update" />
|
||||
<!-- production settings database -->
|
||||
|
||||
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQLInnoDBDialect" />
|
||||
<property name="hibernate.connection.driver_class" value="com.mysql.jdbc.Driver"></property>
|
||||
<property name="hibernate.connection.driver_class" value="com.mysql.jdbc.Driver"></property>
|
||||
<property name="hibernate.connection.url" value="jdbc:mysql://localhost/scipro"></property>
|
||||
<property name="hibernate.connection.username" value="scipro"></property>
|
||||
<property name="hibernate.connection.password" value="pighleef"></property>
|
||||
<property name="hibernate.connection.provider_class" value="org.hibernate.connection.C3P0ConnectionProvider"></property>
|
||||
<property name="hibernate.connection.provider_class"
|
||||
value="org.hibernate.connection.C3P0ConnectionProvider"></property>
|
||||
<property name="hibernate.c3p0.min_size" value="3"></property>
|
||||
<property name="hibernate.c3p0.max_size" value="6"></property>
|
||||
<property name="hibernate.c3p0.timeout" value="1800"></property>
|
||||
<property name="hibernate.c3p0.acquire_increment" value="2"></property>
|
||||
<property name="hibernate.c3p0.idle_test_period" value="360"></property>
|
||||
|
||||
<!--
|
||||
<property name="hibernate.dialect" value="org.hibernate.dialect.HSQLDialect" />
|
||||
<property name="hibernate.hbm2ddl.auto" value="update" />
|
||||
<property name="hibernate.connection.driver_class" value="org.hsqldb.jdbcDriver"></property>
|
||||
<property name="hibernate.connection.url" value="jdbc:hsqldb:mem:test"></property>
|
||||
<property name="hibernate.show_sql" value="false" />
|
||||
<property name="hibernate.format_sql" value="true" />
|
||||
-->
|
||||
|
||||
|
||||
<!-- <property name="hibernate.dialect" value="org.hibernate.dialect.HSQLDialect"
|
||||
/> <property name="hibernate.hbm2ddl.auto" value="update" /> <property name="hibernate.connection.driver_class"
|
||||
value="org.hsqldb.jdbcDriver"></property> <property name="hibernate.connection.url"
|
||||
value="jdbc:hsqldb:mem:test"></property> <property name="hibernate.show_sql"
|
||||
value="false" /> <property name="hibernate.format_sql" value="true" /> -->
|
||||
</properties>
|
||||
</persistence-unit>
|
||||
|
||||
|
||||
<!-- A JPA Persistence Unit used for tests -->
|
||||
<persistence-unit name="testPersistenceUnit" transaction-type="RESOURCE_LOCAL">
|
||||
|
||||
<provider>org.hibernate.ejb.HibernatePersistence</provider>
|
||||
|
||||
<!-- This list of persisted Entitys IS NOT updated by eclipes JPA facet,
|
||||
if some tests are failing, then copy paste exact list from the above persistence unit -->
|
||||
|
||||
<!-- JPA entities must be registered here -->
|
||||
<class>se.su.dsv.scipro.data.dataobjects.Username</class>
|
||||
<class>se.su.dsv.scipro.data.dataobjects.User</class>
|
||||
<class>se.su.dsv.scipro.data.dataobjects.LazyDeletableDomainObject</class>
|
||||
<class>se.su.dsv.scipro.data.dataobjects.Event</class>
|
||||
<class>se.su.dsv.scipro.data.dataobjects.ProjectEvent</class>
|
||||
<class>se.su.dsv.scipro.data.dataobjects.GroupEvent</class>
|
||||
<class>se.su.dsv.scipro.data.dataobjects.DomainObject</class>
|
||||
<class>se.su.dsv.scipro.data.dataobjects.Student</class>
|
||||
<class>se.su.dsv.scipro.data.dataobjects.Admin</class>
|
||||
<class>se.su.dsv.scipro.data.dataobjects.SysAdmin</class>
|
||||
<class>se.su.dsv.scipro.data.dataobjects.Employee</class>
|
||||
<class>se.su.dsv.scipro.data.dataobjects.Role</class>
|
||||
<class>se.su.dsv.scipro.data.dataobjects.Project</class>
|
||||
<class>se.su.dsv.scipro.data.dataobjects.ProjectSchedule</class>
|
||||
<class>se.su.dsv.scipro.data.dataobjects.ProjectFollower</class>
|
||||
<class>se.su.dsv.scipro.data.dataobjects.ProjectTeamMember</class>
|
||||
<class>se.su.dsv.scipro.data.dataobjects.BoardMessage</class>
|
||||
<class>se.su.dsv.scipro.data.dataobjects.MessageBoard</class>
|
||||
<class>se.su.dsv.scipro.data.dataobjects.PrivateMessage</class>
|
||||
<class>se.su.dsv.scipro.data.dataobjects.Recipient</class>
|
||||
<class>se.su.dsv.scipro.data.dataobjects.StringResource</class>
|
||||
<class>se.su.dsv.scipro.data.dataobjects.Ratable</class>
|
||||
<class>se.su.dsv.scipro.data.dataobjects.Rating</class>
|
||||
<class>se.su.dsv.scipro.data.dataobjects.Resource</class>
|
||||
<class>se.su.dsv.scipro.data.dataobjects.Tag</class>
|
||||
<class>se.su.dsv.scipro.data.dataobjects.Comment</class>
|
||||
<class>se.su.dsv.scipro.data.dataobjects.ProjectEventTemplate</class>
|
||||
<class>se.su.dsv.scipro.data.dataobjects.ProjectClass</class>
|
||||
<class>se.su.dsv.scipro.data.dataobjects.ScheduleTemplate</class>
|
||||
<class>se.su.dsv.scipro.data.dataobjects.FileDescription</class>
|
||||
<class>se.su.dsv.scipro.peer.data.dataobjects.Answer</class>
|
||||
<class>se.su.dsv.scipro.peer.data.dataobjects.PeerQueue</class>
|
||||
<class>se.su.dsv.scipro.peer.data.dataobjects.PeerReview</class>
|
||||
<class>se.su.dsv.scipro.peer.data.dataobjects.PeerRequest</class>
|
||||
<class>se.su.dsv.scipro.peer.data.dataobjects.Question</class>
|
||||
<class>se.su.dsv.scipro.peer.data.dataobjects.ReviewRating</class>
|
||||
<class>se.su.dsv.scipro.data.dataobjects.CommentThread</class>
|
||||
<class>se.su.dsv.scipro.data.dataobjects.UserSettings</class>
|
||||
<class>se.su.dsv.scipro.data.dataobjects.HandInActivity</class>
|
||||
<class>se.su.dsv.scipro.data.dataobjects.HandIn</class>
|
||||
<class>se.su.dsv.scipro.data.dataobjects.HandInFeedback</class>
|
||||
<class>se.su.dsv.scipro.data.dataobjects.Category</class>
|
||||
<class>se.su.dsv.scipro.data.dataobjects.FinalSeminar</class>
|
||||
<class>se.su.dsv.scipro.data.dataobjects.FinalSeminarOpposition</class>
|
||||
<class>se.su.dsv.scipro.data.dataobjects.FinalSeminarActiveParticipation</class>
|
||||
<class>se.su.dsv.scipro.data.dataobjects.GeneralSystemSettings</class>
|
||||
<class>se.su.dsv.scipro.data.dataobjects.ProjectClassSettings</class>
|
||||
<class>se.su.dsv.scipro.data.dataobjects.WorkerData</class>
|
||||
<class>se.su.dsv.scipro.data.dataobjects.MailEvent</class>
|
||||
<class>se.su.dsv.scipro.data.dataobjects.ProjectPartner</class>
|
||||
<class>se.su.dsv.scipro.data.dataobjects.CheckPlagiarismEvent</class>
|
||||
<class>se.su.dsv.scipro.data.dataobjects.WebNotification</class>
|
||||
<class>se.su.dsv.scipro.data.dataobjects.CheckListTemplate</class>
|
||||
<class>se.su.dsv.scipro.data.dataobjects.CheckList</class>
|
||||
<class>se.su.dsv.scipro.data.dataobjects.CheckListAnswer</class>
|
||||
<class>se.su.dsv.scipro.data.dataobjects.CheckListQuestion</class>
|
||||
<class>se.su.dsv.scipro.data.dataobjects.CheckListUpload</class>
|
||||
<class>se.su.dsv.scipro.data.dataobjects.ChecklistCategory</class>
|
||||
|
||||
|
||||
<persistence-unit name="testPersistenceUnit"
|
||||
transaction-type="RESOURCE_LOCAL">
|
||||
<provider>org.hibernate.ejb.HibernatePersistence</provider>
|
||||
<properties>
|
||||
|
||||
<!-- 2nd level cache -->
|
||||
<property name="hibernate.cache.provider_class" value="org.hibernate.cache.SingletonEhCacheProvider" />
|
||||
<property name="net.sf.ehcache.configurationResourceName" value="/ehcache.xml" />
|
||||
<property name="hibernate.cache.use_query_cache" value="false" />
|
||||
<property name="hibernate.cache.use_second_level_cache" value="false" />
|
||||
<property name="hibernate.generate_statistics" value="false" />
|
||||
|
||||
<!-- 2nd level cache -->
|
||||
<property name="hibernate.cache.provider_class"
|
||||
value="org.hibernate.cache.SingletonEhCacheProvider" />
|
||||
<property name="net.sf.ehcache.configurationResourceName"
|
||||
value="/ehcache.xml" />
|
||||
<property name="hibernate.cache.use_query_cache" value="false" />
|
||||
<property name="hibernate.cache.use_second_level_cache"
|
||||
value="false" />
|
||||
<property name="hibernate.generate_statistics" value="false" />
|
||||
|
||||
<!-- DEVELOPMENT VARIABLE, REMOVE FOR PRODUCTION USE -->
|
||||
<property name="hibernate.hbm2ddl.auto" value="update" />
|
||||
|
||||
|
||||
<property name="hibernate.dialect" value="org.hibernate.dialect.HSQLDialect" />
|
||||
<property name="hibernate.connection.driver_class" value="org.hsqldb.jdbcDriver"></property>
|
||||
<property name="hibernate.connection.url" value="jdbc:hsqldb:mem:test"></property>
|
||||
<property name="hibernate.show_sql" value="false" />
|
||||
<property name="hibernate.format_sql" value="true" />
|
||||
|
||||
|
||||
<!-- Local mysql test database -->
|
||||
<!--
|
||||
<property name="hibernate.hbm2ddl.auto" value="create" />
|
||||
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5Dialect" />
|
||||
<property name="hibernate.connection.driver_class" value="com.mysql.jdbc.Driver"></property>
|
||||
<property name="hibernate.connection.url" value="jdbc:mysql://localhost/scipro"></property>
|
||||
<property name="hibernate.connection.username" value=""></property>
|
||||
<property name="hibernate.connection.password" value=""></property>
|
||||
<property name="hibernate.c3p0.idle_test_period" value="3600"></property>
|
||||
-->
|
||||
<!-- <property name="hibernate.hbm2ddl.auto" value="create" /> <property
|
||||
name="hibernate.dialect" value="org.hibernate.dialect.MySQL5Dialect" /> <property
|
||||
name="hibernate.connection.driver_class" value="com.mysql.jdbc.Driver"></property>
|
||||
<property name="hibernate.connection.url" value="jdbc:mysql://localhost/scipro"></property>
|
||||
<property name="hibernate.connection.username" value=""></property> <property
|
||||
name="hibernate.connection.password" value=""></property> <property name="hibernate.c3p0.idle_test_period"
|
||||
value="3600"></property> -->
|
||||
</properties>
|
||||
</persistence-unit>
|
||||
|
||||
</persistence>
|
||||
|
@ -1273,3 +1273,24 @@ div.wicket-aa ul li.selected {
|
||||
body {
|
||||
font: 0.8em/21px arial,sans-serif;
|
||||
}
|
||||
|
||||
thead.blue-header {
|
||||
color: white;
|
||||
background-color: #0A2C5F;
|
||||
border: 1px solid #777A91;
|
||||
padding: 0.3em 0.3em;
|
||||
margin-bottom: 0.3em;
|
||||
}
|
||||
|
||||
tr.blue-row {
|
||||
background-color: #0A2C5F;
|
||||
border: 1px solid #777A91;
|
||||
padding: 0.3em 0.3em;
|
||||
margin-bottom: 0.3em;
|
||||
height: 2em;
|
||||
}
|
||||
|
||||
tr.schedule-row {
|
||||
height: 3em;
|
||||
}
|
||||
}
|
||||
|
@ -19,17 +19,47 @@
|
||||
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
|
||||
<property name="entityManagerFactory" ref="entityManagerFactory" />
|
||||
</bean>
|
||||
|
||||
|
||||
<bean id="eventDao" class="se.su.dsv.scipro.data.dao.jpa.EventDaoJPAImp">
|
||||
|
||||
<bean id="projectScheduleDao" class="se.su.dsv.scipro.data.dao.jpa.ProjectScheduleDaoJPAImp">
|
||||
<property name="entityManagerFactory" ref="entityManagerFactory" />
|
||||
</bean>
|
||||
|
||||
<bean id="projectScheduleDao" class="se.su.dsv.scipro.data.dao.jpa.ProjectScheduleDaoJPAImp">
|
||||
<bean id="userDao" class="se.su.dsv.scipro.data.dao.jpa.UserDaoJPAImp">
|
||||
<property name="entityManagerFactory" ref="entityManagerFactory" />
|
||||
</bean>
|
||||
|
||||
<bean id="projectScheduleEventDao" class="se.su.dsv.scipro.data.dao.jpa.ProjectScheduleEventDaoJPAImp">
|
||||
<property name="entityManagerFactory" ref="entityManagerFactory" />
|
||||
</bean>
|
||||
|
||||
<bean id="scheduleTemplateDao" class="se.su.dsv.scipro.data.dao.jpa.ScheduleTemplateDaoJPAImp">
|
||||
<property name="entityManagerFactory" ref="entityManagerFactory" />
|
||||
</bean>
|
||||
|
||||
<bean id="projectDao" class="se.su.dsv.scipro.data.dao.jpa.ProjectDaoJPAImp">
|
||||
<property name="entityManagerFactory" ref="entityManagerFactory" />
|
||||
</bean>
|
||||
</beans>
|
||||
|
||||
<bean id="roleDao" class="se.su.dsv.scipro.data.dao.jpa.RoleDaoJPAImp">
|
||||
<property name="entityManagerFactory" ref="entityManagerFactory" />
|
||||
</bean>
|
||||
|
||||
<bean id="projectClassDao" class="se.su.dsv.scipro.data.dao.jpa.ProjectClassDaoJPAImp">
|
||||
<property name="entityManagerFactory" ref="entityManagerFactory" />
|
||||
</bean>
|
||||
|
||||
<bean id="CheckListDao" class="se.su.dsv.scipro.data.dao.jpa.CheckListDaoJPAImp">
|
||||
<property name="entityManagerFactory" ref="entityManagerFactory" />
|
||||
</bean>
|
||||
|
||||
<bean id="FileDescriptionDao" class="se.su.dsv.scipro.data.dao.jpa.FileDescriptionDaoJPAImp">
|
||||
<property name="entityManagerFactory" ref="entityManagerFactory" />
|
||||
</bean>
|
||||
|
||||
<bean id="FileRepository" class="se.su.dsv.scipro.repository.FileRepositoryImpl">
|
||||
</bean>
|
||||
|
||||
<bean id="projectScheduleFacade" class="se.su.dsv.scipro.activityplan.facade.ProjectScheduleFacade">
|
||||
</bean>
|
||||
|
||||
</beans>
|
@ -0,0 +1,103 @@
|
||||
/**
|
||||
*
|
||||
*/
|
||||
package se.su.dsv.scipro.dao.jpa;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
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.activityplan.facade.ProjectScheduleFacade;
|
||||
import se.su.dsv.scipro.data.dao.interfaces.ProjectClassDao;
|
||||
import se.su.dsv.scipro.data.dao.interfaces.ProjectDao;
|
||||
import se.su.dsv.scipro.data.dao.interfaces.ProjectScheduleDao;
|
||||
import se.su.dsv.scipro.data.dao.interfaces.ProjectScheduleEventDao;
|
||||
import se.su.dsv.scipro.data.dao.interfaces.RoleDao;
|
||||
import se.su.dsv.scipro.data.dao.interfaces.UserDao;
|
||||
import se.su.dsv.scipro.data.dataobjects.Project;
|
||||
import se.su.dsv.scipro.data.dataobjects.ProjectClass;
|
||||
import se.su.dsv.scipro.data.dataobjects.ProjectSchedule;
|
||||
import se.su.dsv.scipro.data.dataobjects.ProjectScheduleEvent;
|
||||
import se.su.dsv.scipro.data.dataobjects.Role;
|
||||
import se.su.dsv.scipro.data.dataobjects.Student;
|
||||
import se.su.dsv.scipro.data.dataobjects.User;
|
||||
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@ContextConfiguration
|
||||
public class TestActivityPlanDaoJPA {
|
||||
|
||||
@Autowired
|
||||
private UserDao userDao;
|
||||
@Autowired
|
||||
private ProjectScheduleDao projectScheduleDao;
|
||||
@Autowired
|
||||
private ProjectScheduleEventDao projectScheduleEventDao;
|
||||
@Autowired
|
||||
private ProjectDao projectDao;
|
||||
@Autowired
|
||||
private ProjectClassDao projectClassDao;
|
||||
@Autowired
|
||||
private ProjectScheduleFacade projectScheduleFacade;
|
||||
@Autowired
|
||||
private RoleDao roleDao;
|
||||
|
||||
private User user;
|
||||
private Project project;
|
||||
private ProjectClass projectClass;
|
||||
private Role role;
|
||||
private ProjectSchedule projectSchedule;
|
||||
|
||||
@Before
|
||||
public void startTransaction()
|
||||
{
|
||||
user = new User();
|
||||
user = userDao.save(user);
|
||||
|
||||
role = new Student();
|
||||
role.setUser(user);
|
||||
role = roleDao.save(role);
|
||||
|
||||
projectClass = new ProjectClass(ProjectClass.BACHELOR,"Bachelor","Bachelor degree thesis project");
|
||||
projectClass = projectClassDao.save(projectClass);
|
||||
|
||||
project = new Project();
|
||||
project.setTitle("SomeProject");
|
||||
project.setProjectClass(projectClass);
|
||||
project.addProjectParticipant((Student)role);
|
||||
project = projectDao.save(project);
|
||||
|
||||
projectSchedule = new ProjectSchedule();
|
||||
projectSchedule.setProject(project);
|
||||
projectSchedule = projectScheduleDao.save(projectSchedule);
|
||||
|
||||
project.setProjectSchedule(projectSchedule);
|
||||
}
|
||||
@Test
|
||||
@Transactional
|
||||
@Rollback
|
||||
public void testBaseDaoAccess() {
|
||||
Assert.assertEquals(userDao.countAll(),1);
|
||||
Assert.assertEquals(projectDao.countAll(),1);
|
||||
Assert.assertEquals(projectScheduleDao.countAll(),1);
|
||||
Assert.assertEquals(roleDao.countAll(),1);
|
||||
}
|
||||
@Test
|
||||
@Transactional
|
||||
@Rollback
|
||||
public void testFacade(){
|
||||
ProjectScheduleEvent event = projectScheduleFacade.createNewProjectScheduleEvent(projectSchedule, user, "Some event name", "Some event description", false, new Date());
|
||||
Assert.assertEquals(projectScheduleEventDao.countAll(),1);
|
||||
event.setDescription("Some other description");
|
||||
projectScheduleFacade.saveProjectScheduleEvent(event);
|
||||
Assert.assertEquals(projectScheduleEventDao.countAll(), 1);
|
||||
Assert.assertEquals(projectScheduleFacade.retrieveProjectSchedule(project),projectSchedule);
|
||||
}
|
||||
}
|
@ -1,26 +0,0 @@
|
||||
package se.su.dsv.scipro.dao.jpa;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
import org.springframework.test.annotation.Rollback;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
/**
|
||||
* @author Dan Kjellman <dan-kjel@dsv.su.se>
|
||||
*
|
||||
*/
|
||||
//@RunWith(SpringJUnit4ClassRunner.class)
|
||||
//@ContextConfiguration
|
||||
@Ignore
|
||||
public class TestProjectScheduleDaoJPA {
|
||||
|
||||
@Test @Transactional
|
||||
@Rollback
|
||||
public void testDBChange() {
|
||||
//For deploy! added a date column to projectSchedule
|
||||
Assert.assertEquals(true, false);
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -52,7 +52,6 @@ public class TestScheduleTemplateDaoJPA {
|
||||
|
||||
private ScheduleTemplate sysAdminTemplate;
|
||||
private ScheduleTemplate employeeTemplate;
|
||||
private ScheduleTemplate inactiveTemplate;
|
||||
private ScheduleTemplate masterTemplate;
|
||||
|
||||
private ProjectClass masterClass;
|
||||
@ -83,28 +82,18 @@ public class TestScheduleTemplateDaoJPA {
|
||||
sysAdminTemplate = new ScheduleTemplate();
|
||||
sysAdminTemplate.setCreator(sysAdminUser);
|
||||
sysAdminTemplate.setSysAdminTemplate(true);
|
||||
sysAdminTemplate.setActive(true);
|
||||
sysAdminTemplate.setTemplateName("sysAdminTemplate");
|
||||
sysAdminTemplate = scheduleTemplateDao.save(sysAdminTemplate);
|
||||
|
||||
employeeTemplate = new ScheduleTemplate();
|
||||
employeeTemplate.setCreator(supervisorUser);
|
||||
employeeTemplate.setSysAdminTemplate(false);
|
||||
employeeTemplate.setActive(true);
|
||||
employeeTemplate.setTemplateName("employeeTemplate");
|
||||
employeeTemplate = scheduleTemplateDao.save(employeeTemplate);
|
||||
|
||||
inactiveTemplate = new ScheduleTemplate();
|
||||
inactiveTemplate.setCreator(supervisorUser);
|
||||
inactiveTemplate.setSysAdminTemplate(false);
|
||||
inactiveTemplate.setActive(false);
|
||||
inactiveTemplate.setTemplateName("inactiveTemplate");
|
||||
inactiveTemplate = scheduleTemplateDao.save(inactiveTemplate);
|
||||
|
||||
masterTemplate = new ScheduleTemplate();
|
||||
masterTemplate.setCreator(supervisorUser);
|
||||
masterTemplate.setSysAdminTemplate(false);
|
||||
masterTemplate.setActive(true);
|
||||
masterTemplate.setProjectClass(masterClass);
|
||||
masterTemplate.setTemplateName("masterTemplate");
|
||||
masterTemplate = scheduleTemplateDao.save(masterTemplate);
|
||||
@ -140,7 +129,6 @@ public class TestScheduleTemplateDaoJPA {
|
||||
List<ScheduleTemplate> scheduleTemplates = new ArrayList<ScheduleTemplate>();
|
||||
scheduleTemplates.add(sysAdminTemplate);
|
||||
scheduleTemplates.add(employeeTemplate);
|
||||
scheduleTemplates.add(inactiveTemplate);
|
||||
scheduleTemplates.add(masterTemplate);
|
||||
Assert.assertEquals(scheduleTemplates, scheduleTemplateDao.findAll());
|
||||
List<ProjectEventTemplate> eventTemplates = new ArrayList<ProjectEventTemplate>();
|
||||
@ -156,7 +144,7 @@ public class TestScheduleTemplateDaoJPA {
|
||||
@Test @Transactional
|
||||
@Rollback
|
||||
public void testCountAll() {
|
||||
Assert.assertEquals(4, scheduleTemplateDao.countAll());
|
||||
Assert.assertEquals(3, scheduleTemplateDao.countAll());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -186,7 +174,6 @@ public class TestScheduleTemplateDaoJPA {
|
||||
scheduleTemplateDao.delete(employeeTemplate);
|
||||
scheduleTemplateDao.delete(sysAdminTemplate);
|
||||
scheduleTemplateDao.delete(masterTemplate);
|
||||
scheduleTemplateDao.delete(inactiveTemplate);
|
||||
Assert.assertEquals(0, scheduleTemplateDao.countAll());
|
||||
}
|
||||
|
||||
@ -197,7 +184,7 @@ public class TestScheduleTemplateDaoJPA {
|
||||
@Rollback
|
||||
public void testDeleteCascade() {
|
||||
scheduleTemplateDao.delete(employeeTemplate);
|
||||
Assert.assertEquals(3, scheduleTemplateDao.countAll());
|
||||
Assert.assertEquals(2, scheduleTemplateDao.countAll());
|
||||
Assert.assertEquals(1, projectEventTemplateDao.countAll());
|
||||
}
|
||||
|
||||
@ -213,30 +200,12 @@ public class TestScheduleTemplateDaoJPA {
|
||||
Assert.assertEquals(s2.getId(), employeeTemplate.getId());
|
||||
}
|
||||
|
||||
@Test @Transactional
|
||||
@Rollback
|
||||
public void testgetActiveScheduleTemplates() {
|
||||
List<ScheduleTemplate> scheduleTemplates = new ArrayList<ScheduleTemplate>();
|
||||
scheduleTemplates.add(employeeTemplate);
|
||||
scheduleTemplates.add(masterTemplate);
|
||||
scheduleTemplates.add(sysAdminTemplate);
|
||||
Assert.assertEquals(scheduleTemplates, scheduleTemplateDao.getScheduleTemplates(null, null, true, null));
|
||||
}
|
||||
|
||||
@Test @Transactional
|
||||
@Rollback
|
||||
public void testgetInactiveScheduleTemplates() {
|
||||
List<ScheduleTemplate> scheduleTemplates = new ArrayList<ScheduleTemplate>();
|
||||
scheduleTemplates.add(inactiveTemplate);
|
||||
Assert.assertEquals(scheduleTemplates, scheduleTemplateDao.getScheduleTemplates(null, null, false, null));
|
||||
}
|
||||
|
||||
@Test @Transactional
|
||||
@Rollback
|
||||
public void testgetScheduleTemplatesByClass() {
|
||||
List<ScheduleTemplate> scheduleTemplates = new ArrayList<ScheduleTemplate>();
|
||||
scheduleTemplates.add(masterTemplate);
|
||||
Assert.assertEquals(scheduleTemplates, scheduleTemplateDao.getScheduleTemplates(null, null, null, masterClass));
|
||||
Assert.assertEquals(scheduleTemplates, scheduleTemplateDao.getScheduleTemplates(null, null, masterClass));
|
||||
}
|
||||
|
||||
@Test @Transactional
|
||||
@ -252,7 +221,7 @@ public class TestScheduleTemplateDaoJPA {
|
||||
public void testgetSysAdminScheduleTemplates() {
|
||||
List<ScheduleTemplate> scheduleTemplates = new ArrayList<ScheduleTemplate>();
|
||||
scheduleTemplates.add(sysAdminTemplate);
|
||||
Assert.assertEquals(scheduleTemplates, scheduleTemplateDao.getScheduleTemplates(null, true, null, null));
|
||||
Assert.assertEquals(scheduleTemplates, scheduleTemplateDao.getScheduleTemplates(null, true, null));
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -28,4 +28,7 @@
|
||||
<bean id="userSettingsDao" class="se.su.dsv.scipro.data.dao.jpa.UserSettingsDaoJPAImp">
|
||||
<property name="entityManagerFactory" ref="entityManagerFactory" />
|
||||
</bean>
|
||||
<bean id="projectScheduleEventDao" class="se.su.dsv.scipro.data.dao.jpa.ProjectScheduleEventDaoJPAImp">
|
||||
<property name="entityManagerFactory" ref="entityManagerFactory" />
|
||||
</bean>
|
||||
</beans>
|
@ -1,10 +1,6 @@
|
||||
package se.su.dsv.scipro.dataproviders;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.wicket.protocol.http.HttpSessionStore;
|
||||
import org.apache.wicket.session.ISessionStore;
|
||||
@ -26,10 +22,10 @@ import se.su.dsv.scipro.ApplicationSettings;
|
||||
import se.su.dsv.scipro.SciProApplication;
|
||||
import se.su.dsv.scipro.data.dao.interfaces.ProjectClassDao;
|
||||
import se.su.dsv.scipro.data.dao.interfaces.ProjectDao;
|
||||
import se.su.dsv.scipro.data.dao.interfaces.ProjectScheduleEventDao;
|
||||
import se.su.dsv.scipro.data.dao.interfaces.RoleDao;
|
||||
import se.su.dsv.scipro.data.dao.interfaces.UserDao;
|
||||
import se.su.dsv.scipro.data.dao.interfaces.UserSettingsDao;
|
||||
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.json.IUserLookupFromUsername;
|
||||
@ -48,6 +44,8 @@ public class TestSortableDataProvider{
|
||||
private RoleDao roleDao;
|
||||
@Autowired
|
||||
private UserSettingsDao userSettingsDao;
|
||||
@Autowired
|
||||
private ProjectScheduleEventDao projectScheduleEventDao;
|
||||
|
||||
private Project p1,p2,p3;
|
||||
private ProjectClass pc1,pc2,pc3;
|
||||
@ -63,6 +61,7 @@ public class TestSortableDataProvider{
|
||||
ac.putBean("userDao",userDao);
|
||||
ac.putBean("roleDao",roleDao);
|
||||
ac.putBean("userSettingsDao",userSettingsDao);
|
||||
ac.putBean("projectScheduleEventDao",projectScheduleEventDao);
|
||||
//Mocked stuff of no importance
|
||||
ac.putBean("userLookupFromUsername",Mockito.mock(IUserLookupFromUsername.class));
|
||||
new WicketTester(new SciProApplication(){
|
||||
@ -112,6 +111,9 @@ public class TestSortableDataProvider{
|
||||
Assert.assertFalse(pc2.equals(pc3));
|
||||
Assert.assertFalse(pc3.equals(pc1));
|
||||
Assert.assertFalse(pc3.equals(pc2));
|
||||
Assert.assertTrue(p1.equals(p1));
|
||||
Assert.assertTrue(p2.equals(p2));
|
||||
Assert.assertTrue(p3.equals(p3));
|
||||
}
|
||||
/**
|
||||
* Tests base case of "I want a sortable data provider for any generic Dao<DomainObject>"
|
||||
@ -120,18 +122,24 @@ public class TestSortableDataProvider{
|
||||
@Transactional
|
||||
@Rollback
|
||||
public void testBase() {
|
||||
SortableDataProvider<Project> sdp = new SortableDataProvider<Project>(projectDao);
|
||||
SortableDataProvider<Project> sdp = new SortableDataProvider<Project>(projectDao,Project.class);
|
||||
Assert.assertTrue(sdp.isAscendingOrder());
|
||||
Assert.assertTrue(sdp.size() == 3);
|
||||
sdp.setSortSpecifier(SortableDataProvider.ID);
|
||||
Assert.assertTrue(sdp.isAscendingOrder());
|
||||
Assert.assertTrue(sdp.size() == 3);
|
||||
Assert.assertTrue(sdp.iterator(0, 1).next().equals(p1));
|
||||
Assert.assertTrue(sdp.iterator(1, 1).next().equals(p2));
|
||||
Assert.assertTrue(sdp.iterator(2, 1).next().equals(p3));
|
||||
sdp.setSortSpecifier(SortableDataProvider.ID_DESC);
|
||||
sdp.setSortSpecifier(SortableDataProvider.ID);
|
||||
sdp.setAscendingOrder(false);
|
||||
Assert.assertTrue(!sdp.isAscendingOrder());
|
||||
Assert.assertTrue(sdp.size() == 3);
|
||||
Assert.assertTrue(sdp.iterator(0, 1).next().equals(p3));
|
||||
Assert.assertTrue(sdp.iterator(1, 1).next().equals(p2));
|
||||
Assert.assertTrue(sdp.iterator(2, 1).next().equals(p1));
|
||||
//Iterate all available
|
||||
Assert.assertTrue(sdp.getAvailableSortSpecifiers().size() == 6);
|
||||
Assert.assertEquals(sdp.getAvailableSortSpecifiers().size(),5);
|
||||
for(final SortSpecifier spec : sdp.getAvailableSortSpecifiers()){
|
||||
sdp.setSortSpecifier(spec);
|
||||
Assert.assertTrue(sdp.size() == 3);
|
||||
@ -144,63 +152,21 @@ public class TestSortableDataProvider{
|
||||
}
|
||||
Assert.assertEquals(countMatches,3);
|
||||
}
|
||||
Assert.assertTrue(new SortableDataProviderArgumentListValidator<Project>(sdp).validate());
|
||||
}
|
||||
@Test
|
||||
@Transactional
|
||||
@Rollback
|
||||
public void testProjectExtensions(){
|
||||
ProjectDataProvider pdp = new ProjectDataProvider();
|
||||
Assert.assertTrue(pdp.size() == 3);
|
||||
Assert.assertTrue(pdp.iterator(0, 1).next().equals(p1));
|
||||
Assert.assertTrue(pdp.iterator(1, 1).next().equals(p2));
|
||||
Assert.assertTrue(pdp.iterator(2, 1).next().equals(p3));
|
||||
pdp.setSortSpecifier(ProjectDataProvider.TITLE_ASC);
|
||||
Assert.assertTrue(pdp.size() == 3);
|
||||
Assert.assertTrue(pdp.iterator(0, 1).next().equals(p2));
|
||||
Assert.assertTrue(pdp.iterator(1, 1).next().equals(p1));
|
||||
Assert.assertTrue(pdp.iterator(2, 1).next().equals(p3));
|
||||
pdp.setSortSpecifier(ProjectDataProvider.TITLE_DESC);
|
||||
Assert.assertTrue(pdp.size() == 3);
|
||||
Assert.assertTrue(pdp.iterator(0, 1).next().equals(p3));
|
||||
Assert.assertTrue(pdp.iterator(1, 1).next().equals(p1));
|
||||
Assert.assertTrue(pdp.iterator(2, 1).next().equals(p2));
|
||||
//Iterate all available, strongly recommended to do this for all new providers
|
||||
Assert.assertTrue(pdp.getAvailableSortSpecifiers().size() == 10);
|
||||
for(final SortSpecifier spec : pdp.getAvailableSortSpecifiers()){
|
||||
pdp.setSortSpecifier(spec);
|
||||
Assert.assertTrue(pdp.size() == 3);
|
||||
Iterator<Project> response = pdp.iterator(0, 3);
|
||||
int countMatches = 0;
|
||||
while(response.hasNext()){
|
||||
Project p = response.next();
|
||||
if(p.equals(p1) || p.equals(p2) || p.equals(p3))
|
||||
++countMatches;
|
||||
}
|
||||
Assert.assertEquals(countMatches,3);
|
||||
Assert.assertTrue(new SortableDataProviderArgumentListValidator<Project>(pdp).validate());
|
||||
}
|
||||
//Ensure amount of sort specifiers available, strongly recommended to do this for all new typed providers
|
||||
Assert.assertEquals(pdp.getAvailableSortSpecifiers().size(), 5);
|
||||
}
|
||||
/**
|
||||
* Please use this private helper class to validate all custom subtypes of SortableDataProvider.
|
||||
* It will validate the specification for you and confirm that the type is correctly implemented in respect
|
||||
* to the number of "public static final SortSpecifier"'s declared matching those returned from getAvailableSortSpecifiers().
|
||||
*/
|
||||
private final class SortableDataProviderArgumentListValidator<T extends DomainObject>{
|
||||
final SortableDataProvider<T> provider;
|
||||
SortableDataProviderArgumentListValidator(SortableDataProvider<T> provider){
|
||||
this.provider = provider;
|
||||
}
|
||||
boolean validate(){
|
||||
final Field[] fields = provider.getClass().getFields();
|
||||
List<Field> fieldList = new ArrayList<Field>();
|
||||
for(Field field : fields){
|
||||
final int mods = field.getModifiers();
|
||||
if(field.getType().equals(SortSpecifier.class) && Modifier.isFinal(mods) && Modifier.isPublic(mods) && Modifier.isStatic(mods)){
|
||||
fieldList.add(field);
|
||||
}
|
||||
}
|
||||
return (provider.getAvailableSortSpecifiers().size() == fieldList.size());
|
||||
}
|
||||
@Test
|
||||
@Transactional
|
||||
@Rollback
|
||||
public void testProjectScheduleEventExtensions(){
|
||||
ProjectScheduleEventDataProvider pdp = new ProjectScheduleEventDataProvider(null);
|
||||
//Ensure amount of sort specifiers available, strongly recommended to do this for all new typed providers
|
||||
Assert.assertEquals(pdp.getAvailableSortSpecifiers().size(),10);
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user