Merge branch 'develop' of ssh://git.dsv.su.se/git/scipro/scipro into develop

* 'develop' of ssh://git.dsv.su.se/git/scipro/scipro:
  Added fix for auto-initialization of project-classes, not optimal.
  Semi-quick hack to support failing workerthreads.
  Removed unneeded imports
  testar commita demopage och två csser
  Modified tests to accomodate refactoring changes.
  Re-added a file required by the unit test-suite
  Refactoring of the lookup/json-mess, this is slightly experimental and the code base is so messy
  Activation of public peer review links in the Latest reviewers panel is not available through peer portal settings. + removal of unused file.
  more code cleanup in ControllerImpl.
  Minor changes in SciProApplication.properties and code cleanup in ControllerImpl.
  Rewrite of .properties file that handles notification messages. Properties now take parameters for easier modification and localization.
  Small fix to user switching, roles should be correctly reset now.
  Removed old unused data initializers, and rewrote the one in-use.
  Remote request-queries now again uses the live server, this is to ensure proper deployment configuration.
  More refactoring and a workaround to support the iPhone/android way of authenticating.
  1: Permanently Removed deprecated "getUserByUsername" methods.
  Lots of restructuring, we'll need to dive deeper into this to make the import jobs actually work
  Replaced all getRootLogger() with getLogger(this.getClass())
This commit is contained in:
Fredrik Norberg 2011-08-09 14:31:47 +02:00
commit 40cc86d41b
56 changed files with 1026 additions and 2079 deletions
src
main
java/se/su/dsv/scipro
resources
webapp/css
test/java/se/su/dsv/scipro

@ -2,36 +2,18 @@ package se.su.dsv.scipro;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import se.su.dsv.scipro.data.dao.interfaces.EventDao;
import se.su.dsv.scipro.data.dao.interfaces.ProjectClassDao; 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.ProjectFollowerDao;
import se.su.dsv.scipro.data.dao.interfaces.RoleDao; import se.su.dsv.scipro.data.dao.interfaces.RoleDao;
import se.su.dsv.scipro.data.dao.interfaces.StringResourceDao;
import se.su.dsv.scipro.data.dao.interfaces.UserDao; import se.su.dsv.scipro.data.dao.interfaces.UserDao;
import se.su.dsv.scipro.data.dao.interfaces.UsernameDao; import se.su.dsv.scipro.data.dao.interfaces.UsernameDao;
import se.su.dsv.scipro.data.dataobjects.Employee;
import se.su.dsv.scipro.data.dataobjects.Project;
import se.su.dsv.scipro.data.dataobjects.ProjectClass; import se.su.dsv.scipro.data.dataobjects.ProjectClass;
import se.su.dsv.scipro.data.dataobjects.ProjectFollower;
import se.su.dsv.scipro.data.dataobjects.StringResource;
import se.su.dsv.scipro.data.dataobjects.Student;
import se.su.dsv.scipro.data.dataobjects.User; import se.su.dsv.scipro.data.dataobjects.User;
import se.su.dsv.scipro.data.dataobjects.Username; import se.su.dsv.scipro.data.dataobjects.Username;
import se.su.dsv.scipro.data.enums.ProjectStatus;
import se.su.dsv.scipro.data.enums.ProjectTeamMemberRoles;
/** /**
* @author Richard Wilkinson - richard.wilkinson@jweekend.com * Class defines default data to be pumped into database via dao-access.
*
*/ */
public class DataInitialiser { public class DataInitialiser {
//private static String[] dummyTitles = {"Wicket Event", "Party", "Breakfast At Tiffany's", "Holiday"};
//private static String[] dummyLocations = {"London", "Paris", "Pub", "New York"};
@Autowired
private EventDao eventDao;
@Autowired @Autowired
private UserDao userDao; private UserDao userDao;
@Autowired @Autowired
@ -39,152 +21,71 @@ public class DataInitialiser {
@Autowired @Autowired
private RoleDao roleDao; private RoleDao roleDao;
@Autowired @Autowired
private ProjectDao projectDao;
@Autowired
private StringResourceDao stringResourceDao;
@Autowired
private ProjectClassDao projectClassDao; private ProjectClassDao projectClassDao;
@Autowired /**
private ProjectFollowerDao projectFollowerDao; * Creates some default table entries for empty installations.
*/
public void dataInit() { public void dataInit() {
createDefaultProjectClasses();
ProjectClass masterClass; createDefaultUsers();
ProjectClass bachelorClass; }
private void createDefaultProjectClasses(){
if(projectClassDao.countAll() < 3){ if( (projectClassDao.countAll() + projectClassDao.countAllLazyDeleted()) < 3){
ProjectClass unknownClass = new ProjectClass(ProjectClass.UNKNOWN,"Unknown","Project class is unknown or could not be determined"); final ProjectClass masterClass = new ProjectClass(ProjectClass.MASTER,"Master","Master degree thesis project");;
unknownClass = projectClassDao.save(unknownClass); final ProjectClass bachelorClass = new ProjectClass(ProjectClass.BACHELOR,"Bachelor","Bachelor degree thesis project");;
bachelorClass = new ProjectClass(ProjectClass.BACHELOR,"Bachelor","Bachelor degree thesis project"); final ProjectClass unknownClass = new ProjectClass(ProjectClass.UNKNOWN,"Unknown","Project class is unknown or could not be determined");
bachelorClass = projectClassDao.save(bachelorClass); projectClassDao.save(unknownClass);
masterClass = new ProjectClass(ProjectClass.MASTER,"Master","Master degree thesis project"); projectClassDao.save(bachelorClass);
masterClass = projectClassDao.save(masterClass); projectClassDao.save(masterClass);
} }
}
User user = null; private void createDefaultUsers(){;
Student studentRole = null;
User teacher = null;
Employee employeeRole = null;
Employee employeeRole2 = null;
if(userDao.countAll() == 0 ){ if(userDao.countAll() == 0 ){
user = new User(); //Make a regular student
user.setFirstName("Martin"); {
user.setLastName("Peters"); User user = new User();
user.setIdentifier(666L); user.setFirstName("Default");
user.setEmailAddress("martin@peters.tf"); user.setLastName("Student");
user = userDao.save(user); user.setIdentifier(null);
Username un = new Username(); user.setEmailAddress("default.student@dsv.su.se");
un.setRealm("DSV.SU.SE"); user = userDao.save(user);
un.setUserName("mpeters"); Username un = new Username();
un.setUser(user); un.setRealm("DSV.SU.SE");
un = usernameDao.save(un); un.setUserName("default.student");
studentRole = roleDao.makeStudent(user); un.setUser(user);
roleDao.makeSysAdmin(user); un = usernameDao.save(un);
roleDao.makeStudent(user);
teacher = new User();
teacher.setFirstName("Hugo");
teacher.setLastName("Lärare");
teacher.setIdentifier(99999999L);
teacher.setEmailAddress("lärare@dsv.su.se");
teacher = userDao.save(teacher);
Username un2 = new Username();
un2.setRealm("DSV.SU.SE");
un2.setUserName("superman");
un2.setUser(teacher);
un2 = usernameDao.save(un2);
employeeRole = roleDao.makeEmployee(teacher);
User extraStudent = new User();
extraStudent.setFirstName("Stefan");
extraStudent.setLastName("Student");
extraStudent = userDao.save(extraStudent);
Username eu = new Username();
eu.setUser(extraStudent);
eu.setRealm("DSV.SU.SE");
eu.setUserName("extra");
un2 = usernameDao.save(eu);
roleDao.makeStudent(extraStudent);
User teacher2 = new User();
teacher2.setFirstName("Hans");
teacher2.setLastName("Handledare");
teacher2.setIdentifier(439065363L);
teacher2.setEmailAddress("hand@dsv.su.se");
teacher2 = userDao.save(teacher2);
Username t2u = new Username();
t2u.setRealm("DSV.SU.SE");
t2u.setUserName("hand");
t2u.setUser(teacher2);
t2u = usernameDao.save(t2u);
employeeRole2 = roleDao.makeEmployee(teacher2);
}
if(projectDao.countAll() == 0 && false){
Project project = new Project();
project.addProjectParticipant(studentRole);
project.setHeadSupervisor(employeeRole);
project.setTitle("The superduper project about peer portals awesomeness");
project.setProjectClass(projectClassDao.getProjectClass(ProjectClass.BACHELOR));
project = projectDao.save(project);
project = new Project();
project.addProjectParticipant(studentRole);
project.setHeadSupervisor(employeeRole);
project.setTitle("The crappy project");
project.setProjectClass(projectClassDao.getProjectClass(ProjectClass.MASTER));
project.setProjectStatus(ProjectStatus.COMPLETED);
project = projectDao.save(project);
project = new Project();
project.addProjectParticipant(studentRole);
project.setHeadSupervisor(employeeRole2);
project.setTitle("The third project");
project.setProjectClass(projectClassDao.getProjectClass(ProjectClass.MASTER));
project.setProjectStatus(ProjectStatus.ACTIVE);
project = projectDao.save(project);
ProjectFollower pf = new ProjectFollower();
pf.setProject(project);
pf.setFollower(employeeRole);
pf.setProjectRole(ProjectTeamMemberRoles.REVIEWER);
pf = projectFollowerDao.save(pf);
project.getProjectFollowers().add(pf);
}
//doStringDefinitions();
}
private void doStringDefinitions(){
final String english = "en";
final String swedish = "sv";
String[][] en = {
//Key followed by definition
{"testKey","TestDefinitionInEnglish"},
{"button.submit", "Submit"}
};
String[][] sv = {
{"testKey","TestDefinitionInSwedish"},
{"button.submit", "Skicka"}
};
for(String[] arr : en){
String key = arr[0];
String value = arr[1];
if(!stringResourceDao.isDefined(key, english))
stringResourceDao.define(key, english, value);
}
for(String[] arr : sv){
String key = arr[0];
String value = arr[1];
if(!stringResourceDao.isDefined(key, swedish)){
StringResource sr = stringResourceDao.define(key, swedish, value);
//System.out.println(sr);
} }
//Make an employee
{
User teacher = new User();
teacher.setFirstName("Default");
teacher.setLastName("Teacher");
teacher.setIdentifier(null);
teacher.setEmailAddress("default.teacher@dsv.su.se");
teacher = userDao.save(teacher);
Username un = new Username();
un.setRealm("DSV.SU.SE");
un.setUserName("default.teacher");
un.setUser(teacher);
un = usernameDao.save(un);
roleDao.makeEmployee(teacher);
}
//Make a sysadm
{
User sysadm = new User();
sysadm.setFirstName("Default");
sysadm.setLastName("Sysadm");
sysadm.setIdentifier(null);
sysadm.setEmailAddress("default.sysadm@dsv.su.se");
sysadm = userDao.save(sysadm);
Username un = new Username();
un.setRealm("DSV.SU.SE");
un.setUserName("default.sysadm");
un.setUser(sysadm);
un = usernameDao.save(un);
roleDao.makeSysAdmin(sysadm);
}
} }
} }
} }

@ -0,0 +1,23 @@
# Properties used by the NotificationControllerImpl.
# Web notifications:
conferencePost.webNotification = ${firstName} ${lastName} posted on conference "{0}".
pm.webNotification = ${firstName} ${lastName} wrote a private message to you.
comment.webNotification = ${firstName} ${lastName} commented on a post on conference "{0}".
finalSeminarEdit.webNotification = Final seminar for project "${project}" has been edited.
finalSeminarCreated.webNotification = Head supervisor for "${project}" has created a final seminar, room ${room}, {0,date,yyyy-MM-dd HH:mm}{1,date,-HH:mm}
finalSeminarCreatedOpponent.webNotification = Head supervisor for "${project}" has created a final seminar and added you as an opponent, room ${room}, {0,date,yyyy-MM-dd HH:mm}{1,date,-HH:mm}
thesisUpload.webNotification = Thesis for the project "${project}" has been uploaded.
oppositionUpload.webNotification = Opposition report for the project "${finalSeminar.project}" has been uploaded by ${opponent.user}.
reviewAccepted.webNotification = Your peer request was accepted by {0}, he/she now has {1, number} days to complete a review.
reviewCompletedforRequester.webNotification = Your peer request has now been reviewed and is available.
reviewCompletedforRequestSupervisor.webNotification = You are getting this message because you are supervisor of "${peerRequest.project.title}". A peer review on this project has been completed and is available for you.
reviewCompletedforReviewSupervisor.webNotification = ${reviewer.user} in project: ${project.title} has performed a peer review.
reviewRated.webNotification = Your review has been rated.
# Mail notifications
mailSubject = Notification from SciPro
acceptPeerReviewSubject = Your request for peer review has been accepted
completedReviewSubject = A peer review has been completed
reviewRatedSubject = You have received a rating for a review you have done
mailNotification = Hello {0}, \n\n{1}\n\nClick on the link to see it in Scipro: \n{2} \n\nThis is an auto-generated message from SciPro.
mailBody = \n\n{0}

@ -1,6 +1,5 @@
package se.su.dsv.scipro; package se.su.dsv.scipro;
import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
@ -8,7 +7,6 @@ import java.util.List;
import javax.security.auth.login.FailedLoginException; import javax.security.auth.login.FailedLoginException;
import javax.security.auth.login.LoginException; import javax.security.auth.login.LoginException;
import org.apache.log4j.Level;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
import org.apache.wicket.Request; import org.apache.wicket.Request;
import org.apache.wicket.Session; import org.apache.wicket.Session;
@ -23,7 +21,9 @@ import se.su.dsv.scipro.data.dao.interfaces.UserSettingsDao;
import se.su.dsv.scipro.data.dataobjects.Project; import se.su.dsv.scipro.data.dataobjects.Project;
import se.su.dsv.scipro.data.dataobjects.User; import se.su.dsv.scipro.data.dataobjects.User;
import se.su.dsv.scipro.data.dataobjects.UserSettings; import se.su.dsv.scipro.data.dataobjects.UserSettings;
import se.su.dsv.scipro.json.IUserLookup; import se.su.dsv.scipro.json.IUserLookupFromUsername;
import se.su.dsv.scipro.json.RemoteLookupOptions;
import se.su.dsv.scipro.json.RemoteLookupOptions.LOOKUP_DEPTH;
import se.su.dsv.scipro.security.auth.Authenticator; import se.su.dsv.scipro.security.auth.Authenticator;
import se.su.dsv.scipro.security.auth.roles.Admin; import se.su.dsv.scipro.security.auth.roles.Admin;
import se.su.dsv.scipro.security.auth.roles.DefaultRole; import se.su.dsv.scipro.security.auth.roles.DefaultRole;
@ -33,6 +33,7 @@ import se.su.dsv.scipro.security.auth.roles.IRole;
import se.su.dsv.scipro.security.auth.roles.Roles; import se.su.dsv.scipro.security.auth.roles.Roles;
import se.su.dsv.scipro.security.auth.roles.Student; import se.su.dsv.scipro.security.auth.roles.Student;
import se.su.dsv.scipro.security.auth.roles.SysAdmin; import se.su.dsv.scipro.security.auth.roles.SysAdmin;
import se.su.dsv.scipro.util.KeyValuePair;
public class SciProSession extends WebSession { public class SciProSession extends WebSession {
@ -49,8 +50,8 @@ public class SciProSession extends WebSession {
@SpringBean @SpringBean
private UserSettingsDao userSettingsDao; private UserSettingsDao userSettingsDao;
@SpringBean(name="userFullLookup") @SpringBean
private IUserLookup userLookup; private IUserLookupFromUsername userLookupFromUsername;
private List<IRole> iRoles = new ArrayList<IRole>(); private List<IRole> iRoles = new ArrayList<IRole>();
private User user = null; private User user = null;
@ -146,14 +147,10 @@ public class SciProSession extends WebSession {
//Query for the user //Query for the user
user = userDao.getUserByUsername(username,realm); user = userDao.getUserByUsername(username,realm);
if(user == null){ if(user == null){
try{ user = doUserLookup(username,realm);
user = doUserLookup(username); if(user == null){
if(user == null){ return false;
throw new NullPointerException("No user with username "+username+" found in the database or in daisy."); }
}
} catch (NullPointerException e) {
throw e;
}
} }
//Set mail-address session attributes //Set mail-address session attributes
setLoggedInIdentity(username+"@"+realm); setLoggedInIdentity(username+"@"+realm);
@ -162,6 +159,7 @@ public class SciProSession extends WebSession {
user = userDao.save(user); user = userDao.save(user);
} }
//Assign roles //Assign roles
iRoles.clear();
if(roleDao.isStudent(user)){ if(roleDao.isStudent(user)){
iRoles.add(new Student()); iRoles.add(new Student());
} }
@ -195,7 +193,6 @@ public class SciProSession extends WebSession {
// With this userSettings.created() will return a users first login date and userSettings.modified() will return last login // With this userSettings.created() will return a users first login date and userSettings.modified() will return last login
userSettings.setLastModified(new Date()); userSettings.setLastModified(new Date());
userSettings = userSettingsDao.save(userSettings); userSettings = userSettingsDao.save(userSettings);
logger.info("User: "+getLoggedInIdentity()+ " logged in to "+this.getApplication().getClass().getSimpleName()+ logger.info("User: "+getLoggedInIdentity()+ " logged in to "+this.getApplication().getClass().getSimpleName()+
" as: "+user.getFirstName()+" "+user.getLastName()+" "+user.getUserNames()+ " at: "+new Date()); " as: "+user.getFirstName()+" "+user.getLastName()+" "+user.getUserNames()+ " at: "+new Date());
loggedIn = true; loggedIn = true;
@ -213,7 +210,6 @@ public class SciProSession extends WebSession {
return false; return false;
logger.info("Currently logged in user: '"+user.getEmailAddress()+"' attempting switch to '"+suUser+"@"+suRealm+"'"); logger.info("Currently logged in user: '"+user.getEmailAddress()+"' attempting switch to '"+suUser+"@"+suRealm+"'");
if(suUser != null && roleDao.isSysadmin(user)){ if(suUser != null && roleDao.isSysadmin(user)){
iRoles.clear();
return signInAuthenticatedUser(suUser, suRealm); return signInAuthenticatedUser(suUser, suRealm);
}else{ }else{
logger.error("User does not have the privilege to switch user"); logger.error("User does not have the privilege to switch user");
@ -269,23 +265,10 @@ public class SciProSession extends WebSession {
return true; return true;
return false; return false;
} }
private User doUserLookup(final String username, final String realm) {
private User doUserLookup(String username) throws NullPointerException { final User u = userLookupFromUsername.lookup(new KeyValuePair<String>(username,realm), new RemoteLookupOptions(LOOKUP_DEPTH.PROJECT_AND_PARTICIPANTS));
try{ if(u == null)
User u = userLookup.lookup(username); logger.warn(username + " authenticated successfully, but the user was not available from remote system.");
if(u != null){ return u;
return u;
}
Logger.getLogger("Application").log(Level.WARN, "" + username + " authenticated successfully, but the user was not found from daisy");
return null;
} catch (IOException ioe){
//TODO: Log exception
//ioe.printStackTrace();
throw new NullPointerException("Could not communicate with daisy");
} catch (Exception e) {
//TODO: Log exception
//e.printStackTrace();
throw new NullPointerException(e.getMessage());
}
} }
} }

@ -24,7 +24,11 @@
<tr> <tr>
<td><label for="numberOfLatestReviewsDisplayed">Number of reviews to show in the "Latest reviewers" panel: </label></td> <td><label for="numberOfLatestReviewsDisplayed">Number of reviews to show in the "Latest reviewers" panel: </label></td>
<td><input type="text" wicket:id="numberOfLatestReviewsDisplayed" name="numberOfLatestReviewsDisplayed" /></td> <td><input type="text" wicket:id="numberOfLatestReviewsDisplayed" name="numberOfLatestReviewsDisplayed" /></td>
</tr> </tr>
<tr>
<td><label for="publicReviewsActivated">Activate public reviews with links in "Latest reviewers" panel: </label></td>
<td><input type="checkbox" wicket:id="publicReviewsActivated" name="publicReviewsActivated" /></td>
</tr>
</table> </table>
</form> </form>
<h5 class="peer-title">Settings for levels</h5> <h5 class="peer-title">Settings for levels</h5>

@ -77,10 +77,8 @@ public class AdminPeerSettingsPage extends AbstractAdminSettingsPage {
numberOfLatestReviewsDisplayed.setRequired(true); numberOfLatestReviewsDisplayed.setRequired(true);
add(numberOfLatestReviewsDisplayed); add(numberOfLatestReviewsDisplayed);
// Checkbox for activating/inactiviting links to reviews in the Latest reviewers panel. CheckBox publicReviewsActivated = new CheckBox("publicReviewsActivated");
// add(publicReviewsActivated);
/*CheckBox publicReviewsActivated = new CheckBox("publicReviewsActivated");
add(publicReviewsActivated);*/
} }
@Override @Override
public void onSubmit(){ public void onSubmit(){

@ -1,246 +1,311 @@
<!DOCTYPE html> <!DOCTYPE html>
<html xmlns:wicket="http://wicket.apache.org/dtds.data/wicket-xhtml1.4-strict.dtd"> <html
xmlns:wicket="http://wicket.apache.org/dtds.data/wicket-xhtml1.4-strict.dtd">
<body> <body>
<wicket:extend> <wicket:extend>
<div class="info-box rounded-box span-20 last"> <div class="span-22 last">
<p>Remember to save the thingamajig before continuing.</p>
<ul> <table class="rounded-table seminar-table even-rows">
<li>Edit</li> <tr>
<li>Save</li> <th>Date</th>
<li>Continue working</li> <th>Level</th>
</ul> </tr>
</div> <tr>
<td><span class="span-2">20XX-XX-XX</span>
<div class="info-box rounded-box span-12 last"> </td>
<p>Do not leave your computer unsupervised.</p> <td>Bachelor</td>
</div> </tr>
<tr>
<div class="info-box rounded-box span-8 last"> <td><span class="span-2">20XX-XX-XX</span>
Text without p enclosed. </td>
</div> <td>Bachelor</td>
</tr>
<div class="span-22 last"> <tr>
<h2 class="section">This is a section</h2> <td><span class="span-2">20XX-XX-XX</span>
<p>Cool</p> </td>
</div> <td>Bachelor</td>
</tr>
<div class="span-18 last"> <tr>
<h3 class="section">This is a subsection</h3> <td><span class="span-2">20XX-XX-XX</span>
<p>Even cooler</p> </td>
</div> <td>Bachelor</td>
</tr>
<div id="message-list" class="span-16 last"> <tr>
<table class="rounded-table"> <td colspan="22"></td>
<tr> </tr>
<th>Subject</th> </table>
<th>From</th>
<th>Date</th> <!-- Left column -->
</tr> <div class="span-11 colborder">
<tr class="unread-message-table-row">
<td>Mötesförslag</td> <div class="append-bottom"></div>
<td>Lars Larsson</td>
<td>2011-04-01</td> <div class="append-bottom">
</tr>
<tr> <div class="box-title rounded">
<td>Urgent: Changed dates for peer-review</td> <span>Just a heading</span>
<td>Nils Nilsson</td> </div>
<td>2011-03-27</td>
</tr> </div>
<tr>
<td>Handledning 29 mars inställd</td>
<td>Hand Ledare</td> <div class="append-bottom">
<td>2011-03-26</td>
</tr> <fieldset class="rounded-fieldset">
<tr> <legend>Group view </legend>
<td colspan="3"><a href="#">All your messages...</a></td> <div>Title: SciPro</div>
</tr> <div>Level: Bachelor</div>
</table> <div>Authors: Janne</div>
</div> </fieldset>
<div id="file-list" class="span-14 last"> </div>
<table class="rounded-table">
<tr>
<th>Filename</th>
<th>Size</th>
<th>Date</th>
</tr> <div class="append-bottom">
<tr>
<td>file1.pdf</td> <div class="info-box rounded-box last">
<td>201 KiB</td> <p>Remember to save the thingamajig before continuing.</p>
<td>2011-04-01</td> <ul>
</tr> <li>Edit</li>
<tr> <li>Save</li>
<td>file2.pdf</td> <li>Continue working</li>
<td>13 KiB</td> </ul>
<td>2011-03-27</td> </div>
</tr>
<tr> </div>
<td>Total: 2</td>
<td>214 KiB</td>
<td>&nbsp;</td> <div class="append-bottom">
</tr>
</table> <div class="rounded-box">
</div>
<span class="box-title rounded">Round box <span><a
<div id="unstyled-table" class="span-18 last"> href="#" class="right-corner-resource"><img class="icon-12"
<table class="rounded-table-top"> src="images/icons/delete_16x16.png" alt="Delete" title="Delete" />
<tr> </a> </span> </span> <span>With a heading and close/delete button</span>
<th>Column A</th> </div>
<th>Column B</th>
<th>Column C</th> </div>
</tr>
<tr> <div class="append-bottom">
<td>Hej</td>
<td>Svejs</td> <div class="rounded-box">
<td>Karamelltroll</td>
</tr> <span class="box-title rounded">Round box</span> <span>With
<tr> a heading</span>
<td>Knoll</td> </div>
<td>Tott</td>
<td>Pepparlott</td> </div>
</tr>
</table>
</div> <div class="append-bottom">
<div class="span-18 last"> <div class="rounded-box">
<h3 wicket:id="tooltipDemo">MouseOver here for tooltip</h3> <span>Just a round box</span>
<h3>Highlighted form components</h3> </div>
<div wicket:id="radioChoices"></div>
</div>
<div>
<span class="hilight"> <div class="append-bottom">
<!-- Just stick a normal wicket:id onto the input to use it with wicket.
To get the highlight effect it must be contained in this span and the order of input+label is important --> <div>Lorum ipsum blabla blabla bla bla</div>
<input id="d1" type="checkbox" class="question-display"></input>
<label for="d1">Checkbox</label> </div>
</span>
<span class="hilight"> <div class="append-bottom">
<input id="d2" type="checkbox" checked class="question-display"></input> <button type="submit">Button</button>
<label for="d2">Checked Checkbox</label> </div>
</span>
<span class="hilight">
<input id="d3" type="checkbox" checked disabled class="question-display"></input>
<label for="d3">Checked Checkbox disabled</label> <div class="append-bottom">
</span> <span wicket:id="tooltipDemo">MouseOver here for tooltip</span>
</div>
<span class="hilight">
<input id="d4" type="checkbox" disabled class="question-display"></input> <div class="append-bottom">
<label for="d4">Checkbox disabled</label> <h4>Example of ExpandableMulitLineLabel:</h4>
</span> <span wicket:id="exMultiLineLabel"></span>
</div> </div>
</div>
<div class="span-5 last">
<h3>Icons</h3>
<table> </div>
<tr>
<td>Expand section</td> <div class="span-10.5 last">
<td><img wicket:id="expandIcon" /></td>
</tr> <div class="append-bottom">
<tr>
<td>Contract section</td> <table>
<td><img wicket:id="contractIcon" /></td> <tr>
</tr> <th>Date</th>
<tr> <th>Level</th>
<td>Edit</td> </tr>
<td><img wicket:id="editIcon" /></td> <tr>
</tr> <td>Blabla</td>
<tr> <td>HlaHla</td>
<td>Delete</td> </tr>
<td><img wicket:id="deleteIcon" /></td>
</tr> </table>
<tr>
<td>Add</td> </div>
<td><img wicket:id="addIcon" /></td>
</tr>
<tr>
<td>Details</td> <button>Hej</button>
<td><img wicket:id="detailsIcon" /></td>
</tr> <h3>Icons</h3>
<tr>
<td>Yes</td> <button>Hej</button>
<td><img wicket:id="yesIcon" /></td>
</tr>
<tr>
<td>No</td>
<td><img wicket:id="noIcon" /></td> <table>
</tr> <tr>
<tr> <td>Expand section</td>
<td>Check</td> <td><img wicket:id="expandIcon" />
<td><img wicket:id="checkIcon" /></td> </td>
</tr> </tr>
<tr> <tr>
<td>Arrow down</td> <td>Contract section</td>
<td><img wicket:id="arrowDownIcon" /></td> <td><img wicket:id="contractIcon" />
</tr> </td>
<tr> </tr>
<td>Arrow up</td> <tr>
<td><img wicket:id="arrowUpIcon" /></td> <td>Edit</td>
</tr> <td><img wicket:id="editIcon" />
<tr> </td>
<td>Arrow left</td> </tr>
<td><img wicket:id="arrowLeftIcon" /></td> <tr>
</tr> <td>Delete</td>
<tr> <td><img wicket:id="deleteIcon" />
<td>Arrow right</td> </td>
<td><img wicket:id="arrowRightIcon" /></td> </tr>
</tr> <tr>
<tr> <td>Add</td>
<td>Help</td> <td><img wicket:id="addIcon" />
<td><img wicket:id="helpIcon" /></td> </td>
</tr> </tr>
<tr> <tr>
<td>Home</td> <td>Details</td>
<td><img wicket:id="homeIcon" /></td> <td><img wicket:id="detailsIcon" />
</tr> </td>
<tr> </tr>
<td>Important</td> <tr>
<td><img wicket:id="importantIcon" /></td> <td>Yes</td>
</tr> <td><img wicket:id="yesIcon" />
<tr> </td>
<td>Mail</td> </tr>
<td><img wicket:id="mailIcon" /></td> <tr>
</tr> <td>No</td>
<tr> <td><img wicket:id="noIcon" />
<td>New mail</td> </td>
<td><img wicket:id="mailNewIcon" /></td> </tr>
</tr> <tr>
<tr> <td>Check</td>
<td>Settings</td> <td><img wicket:id="checkIcon" />
<td><img wicket:id="settingsIcon" /></td> </td>
</tr> </tr>
<tr> <tr>
<td>Empty</td> <td>Arrow down</td>
<td><img wicket:id="emptyIcon" /></td> <td><img wicket:id="arrowDownIcon" />
</tr> </td>
<tr> </tr>
<td>User</td> <tr>
<td><img wicket:id="userIcon" /></td> <td>Arrow up</td>
</tr> <td><img wicket:id="arrowUpIcon" />
<tr> </td>
<td>Done event</td> </tr>
<td><img wicket:id="eventDoneIcon" /></td> <tr>
</tr> <td>Arrow left</td>
<tr> <td><img wicket:id="arrowLeftIcon" />
<td>Upcoming event</td> </td>
<td><img wicket:id="eventUpcomingIcon" /></td> </tr>
</tr> <tr>
</table> <td>Arrow right</td>
<div> <td><img wicket:id="arrowRightIcon" />
<span>Example of IconizedComponent</span><br /> </td>
<span wicket:id="user"></span> </tr>
</div> <tr>
<div> <td>Help</td>
<span>Example of AjaxActionIcon: </span><img wicket:id="actionIcon" /> <td><img wicket:id="helpIcon" />
</div> </td>
</div> </tr>
<div class="prepend-1 span-8 last"> <tr>
<h4>Example of ExpandableMulitLineLabel:</h4> <td>Home</td>
<span wicket:id="exMultiLineLabel"></span> <td><img wicket:id="homeIcon" />
</div> </td>
</tr>
</wicket:extend> <tr>
<td>Important</td>
<td><img wicket:id="importantIcon" />
</td>
</tr>
<tr>
<td>Mail</td>
<td><img wicket:id="mailIcon" />
</td>
</tr>
<tr>
<td>New mail</td>
<td><img wicket:id="mailNewIcon" />
</td>
</tr>
<tr>
<td>Settings</td>
<td><img wicket:id="settingsIcon" />
</td>
</tr>
<tr>
<td>Empty</td>
<td><img wicket:id="emptyIcon" />
</td>
</tr>
<tr>
<td>User</td>
<td><img wicket:id="userIcon" />
</td>
</tr>
<tr>
<td>Done event</td>
<td><img wicket:id="eventDoneIcon" />
</td>
</tr>
<tr>
<td>Upcoming event</td>
<td><img wicket:id="eventUpcomingIcon" />
</td>
</tr>
</table>
<div>
<span>Example of IconizedComponent</span><br /> <span
wicket:id="user"></span>
</div>
<div>
<span>Example of AjaxActionIcon: </span><img wicket:id="actionIcon" />
</div>
</div>
</div>
</wicket:extend>
</body> </body>
</html> </html>

@ -26,9 +26,6 @@ public interface NotificationController {
public void notifyForComment(final User user, final String message, public void notifyForComment(final User user, final String message,
final NotificationPriority notificationPriority, final String title, final NotificationPriority notificationPriority, final String title,
final String classId, final String absolutePath); final String classId, final String absolutePath);
public void notifyReplyPrivateMessage(final User user, final String message,
final String url);
public void notifyFinalSeminarEdited(final User user, public void notifyFinalSeminarEdited(final User user,
final FinalSeminar finalSeminar, final NotificationPriority notificationPriority, final FinalSeminar finalSeminar, final NotificationPriority notificationPriority,

@ -188,11 +188,11 @@ public class FinalSeminarUploadControllerImpl implements FinalSeminarUploadContr
} }
} catch (IOException e) { } catch (IOException e) {
Logger.getRootLogger().log(Level.ERROR, Logger.getLogger(this.getClass()).log(Level.ERROR,
"Error while storing seminardocument: " + e.getMessage()); "Error while storing seminardocument: " + e.getMessage());
throw new Exception(e); throw new Exception(e);
} catch (PersistenceException e) { } catch (PersistenceException e) {
Logger.getRootLogger().log(Level.ERROR, Logger.getLogger(this.getClass()).log(Level.ERROR,
"Error while storing seminardocument : " + e.getMessage()); "Error while storing seminardocument : " + e.getMessage());
if (fd != null) { if (fd != null) {
fileDescriptionDao.delete(fd); fileDescriptionDao.delete(fd);
@ -233,11 +233,11 @@ public class FinalSeminarUploadControllerImpl implements FinalSeminarUploadContr
SupervisorProjectsFinalSeminarPage.getAbsoluteURL()); SupervisorProjectsFinalSeminarPage.getAbsoluteURL());
} }
} catch (IOException e) { } catch (IOException e) {
Logger.getRootLogger().log(Level.ERROR, Logger.getLogger(this.getClass()).log(Level.ERROR,
"Error while storing opposition report: " + e.getMessage()); "Error while storing opposition report: " + e.getMessage());
throw new Exception(e); throw new Exception(e);
} catch (PersistenceException e) { } catch (PersistenceException e) {
Logger.getRootLogger().log(Level.ERROR, Logger.getLogger(this.getClass()).log(Level.ERROR,
"Error while storing opposition: " + e.getMessage()); "Error while storing opposition: " + e.getMessage());
if (fd != null) { if (fd != null) {

@ -111,7 +111,7 @@ public class HandInControllerImpl implements HandInController, IClusterable {
return true; return true;
} catch (Exception e) { } catch (Exception e) {
//Something went wrong... //Something went wrong...
Logger.getRootLogger().log(Level.ERROR, "An error occured while storing a handin..."+ e.getMessage()); Logger.getLogger(this.getClass()).log(Level.ERROR, "An error occured while storing a handin..."+ e.getMessage());
//Delete from repository //Delete from repository
//TODO: Possible delete the hand in activity folder for the event as well if it's empty //TODO: Possible delete the hand in activity folder for the event as well if it's empty

@ -81,7 +81,7 @@ public class HandInFeedbackControllerImpl implements HandInFeedbackController {
handIn.setStatus(oldStatus); handIn.setStatus(oldStatus);
handInFeedbackDao.save(handIn.getFeedback()); handInFeedbackDao.save(handIn.getFeedback());
handInDao.save(handIn); handInDao.save(handIn);
Logger.getRootLogger().log(Level.ERROR, "Failed to store feedback " + e.getMessage()); Logger.getLogger(this.getClass()).log(Level.ERROR, "Failed to store feedback " + e.getMessage());
return false; return false;
} }
} }

@ -1,11 +1,9 @@
package se.su.dsv.scipro.data.controllers.impl; package se.su.dsv.scipro.data.controllers.impl;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Properties;
import org.apache.wicket.PageParameters; import org.apache.wicket.PageParameters;
import org.apache.wicket.RequestCycle; import org.apache.wicket.RequestCycle;
import org.apache.wicket.model.Model;
import org.apache.wicket.model.StringResourceModel;
import org.apache.wicket.protocol.http.RequestUtils; import org.apache.wicket.protocol.http.RequestUtils;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller; import org.springframework.stereotype.Controller;
@ -32,7 +30,6 @@ import se.su.dsv.scipro.peer.data.dataobjects.PeerReview;
import se.su.dsv.scipro.peer.pages.ProjectPeerReviewPage; import se.su.dsv.scipro.peer.pages.ProjectPeerReviewPage;
import se.su.dsv.scipro.peer.pages.ProjectPeerStatsPage; import se.su.dsv.scipro.peer.pages.ProjectPeerStatsPage;
import se.su.dsv.scipro.peer.pages.SupervisorPeerReviewPage; import se.su.dsv.scipro.peer.pages.SupervisorPeerReviewPage;
import se.su.dsv.scipro.util.PropsUtils;
/** /**
* TODO Think this through and do it properly, this is a rush-job implemented * TODO Think this through and do it properly, this is a rush-job implemented
@ -65,7 +62,7 @@ public class NotificationControllerImpl implements NotificationController {
String systemFromName = generalSystemSettings.getMailFromName(); String systemFromName = generalSystemSettings.getMailFromName();
String systemFromEmail = generalSystemSettings.getSystemFromMail(); String systemFromEmail = generalSystemSettings.getSystemFromMail();
boolean sendMailEnabled = generalSystemSettings.isMailNotifications(); boolean sendMailEnabled = generalSystemSettings.isMailNotifications();
// Mailnotifications // Mail notifications
if (sendMailEnabled) { if (sendMailEnabled) {
UserSettings userSettings = userSettingsDao.getUserSettings(usertoNotify); UserSettings userSettings = userSettingsDao.getUserSettings(usertoNotify);
if (userSettings == null) { if (userSettings == null) {
@ -112,7 +109,7 @@ public class NotificationControllerImpl implements NotificationController {
} }
} }
// Webnotifications // Web notifications
WebNotification notification = new WebNotification(); WebNotification notification = new WebNotification();
notification.setUser(usertoNotify); notification.setUser(usertoNotify);
notification.setInfoText(notificationMessage.getWebNotificationMessage()); notification.setInfoText(notificationMessage.getWebNotificationMessage());
@ -120,86 +117,46 @@ public class NotificationControllerImpl implements NotificationController {
notificationDao.save(notification); notificationDao.save(notification);
} }
private String generateMail(String userFirstName, String addMessage, String absoluteUrl) { /*
String message = ""; * String resources is available in file SciProApplication.properties.
*/
Properties props = null; private String generateMail(String userFirstName, String addMessage,
String absoluteUrl) {
try { return new StringResourceModel("mailNotification", null, new Object[] {
props = PropsUtils.load("notification.properties"); userFirstName, addMessage, absoluteUrl }).getString();
String twoNewLines = props.getProperty("twoNewLines");
String hello = props.getProperty("hello");
String autogenerated = props.getProperty("autogenerated");
String twoNewLinesWithComma = props.getProperty("twoNewLinesWithComma");
String linkText = props.getProperty("linkText");
message += hello;
message += userFirstName;
message += twoNewLinesWithComma;
message += addMessage;
message += twoNewLines;
message += linkText;
message += absoluteUrl;
message += twoNewLines;
message += autogenerated;
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return message;
} }
@Override @Override
public void notifyPrivateMessage(final User user, final String message, public void notifyPrivateMessage(final User user, final String message,
final String url) { final String url) {
Properties props = null;
try { String webNotificationMessage = new StringResourceModel("pm.webNotification",
props = PropsUtils.load("notification.properties"); new Model<User>(SciProSession.get().getUser())).getString();
} catch (Exception e) { String mailBody = new StringResourceModel("mailBody", null, new Object[]{message}).getString();
e.printStackTrace();
} String mailMessage = webNotificationMessage + mailBody;
String mailSubject = props.getProperty("mailSubject"); String mailSubject = new StringResourceModel("mailSubject", null).getString();
String privateMessageNotification = props.getProperty("privateMessageNotification");
String twoNewLines = props.getProperty("twoNewLines");
String webNotificationMessage = SciProSession.get().getUser() + privateMessageNotification;
String mailMessage = webNotificationMessage + twoNewLines + message;
NotificationMessage notificationMessage = new NotificationMessage(webNotificationMessage, NotificationMessage notificationMessage = new NotificationMessage(webNotificationMessage,
mailSubject, mailMessage); mailSubject, mailMessage);
processNotification(user, notificationMessage, url, NotificationPriority.MEDIUM); processNotification(user, notificationMessage, url, NotificationPriority.MEDIUM);
} }
@Override @Override
public void notifyConferencePost(final User user, final String message, public void notifyConferencePost(final User user, final String message,
final String messageboardTitle, final NotificationPriority notificationPriority, final String messageboardTitle, final NotificationPriority notificationPriority,
final String absolutePath) { final String url) {
Properties props = null; String webNotificationMessage = new StringResourceModel("conferencePost.webNotification",
try { new Model<User>(SciProSession.get().getUser()), new Object[] {messageboardTitle}).getString();
props = PropsUtils.load("notification.properties"); String mailBody = new StringResourceModel("mailBody", null, new Object[]{message}).getString();
} catch (Exception e) {
e.printStackTrace(); String mailMessage = webNotificationMessage + mailBody;
} String mailSubject = new StringResourceModel("mailSubject", null).getString();
String mailSubject = props.getProperty("mailSubject");
String conferenceNotification = props.getProperty("conferenceNotification");
String twoNewLines = props.getProperty("twoNewLines");
String quote = props.getProperty("quote");
String webNotificationMessage = SciProSession.get().getUser() + conferenceNotification
+ quote + messageboardTitle + quote;
String mailMessage = webNotificationMessage + twoNewLines + message;
NotificationMessage notificationMessage = new NotificationMessage(webNotificationMessage, NotificationMessage notificationMessage = new NotificationMessage(webNotificationMessage,
mailSubject, mailMessage); mailSubject, mailMessage);
processNotification(user, notificationMessage, absolutePath, notificationPriority); processNotification(user, notificationMessage, url, notificationPriority);
} }
@Override @Override
@ -207,20 +164,12 @@ public class NotificationControllerImpl implements NotificationController {
final NotificationPriority notificationPriority, final String title, final NotificationPriority notificationPriority, final String title,
final String classId, final String absolutePath) { final String classId, final String absolutePath) {
Properties props = null; String webNotificationMessage = new StringResourceModel("comment.webNotification",
try { new Model<User>(SciProSession.get().getUser()), new Object[] { title }).getString();
props = PropsUtils.load("notification.properties"); String mailBody = new StringResourceModel("mailBody", null, new Object[]{message}).getString();
} catch (Exception e) {
e.printStackTrace(); String mailMessage = webNotificationMessage + mailBody;
} String mailSubject = new StringResourceModel("mailSubject", null).getString();
String mailSubject = props.getProperty("mailSubject");
String conferenceNotification = props.getProperty("conferenceNotificationComment");
String twoNewLines = props.getProperty("twoNewLines");
String webNotificationMessage = SciProSession.get().getUser() + conferenceNotification
+ title;
String mailMessage = webNotificationMessage + twoNewLines + message;
NotificationMessage notificationMessage = new NotificationMessage(webNotificationMessage, NotificationMessage notificationMessage = new NotificationMessage(webNotificationMessage,
mailSubject, mailMessage); mailSubject, mailMessage);
@ -228,48 +177,14 @@ public class NotificationControllerImpl implements NotificationController {
notificationPriority); notificationPriority);
} }
@Override
public void notifyReplyPrivateMessage(final User user, final String message,
final String absolutePath) {
Properties props = null;
try {
props = PropsUtils.load("notification.properties");
} catch (Exception e) {
e.printStackTrace();
}
String mailSubject = props.getProperty("mailSubject");
String privateMessageNotification = props.getProperty("privateMessageReplyNotification");
String twoNewLines = props.getProperty("twoNewLines");
String webNotificationMessage = SciProSession.get().getUser() + privateMessageNotification;
String mailMessage = webNotificationMessage + twoNewLines + message;
NotificationMessage notificationMessage = new NotificationMessage(webNotificationMessage,
mailSubject, mailMessage);
processNotification(user, notificationMessage, absolutePath, NotificationPriority.MEDIUM);
}
@Override @Override
public void notifyFinalSeminarEdited(final User user, public void notifyFinalSeminarEdited(final User user,
final FinalSeminar finalSeminar, final NotificationPriority notificationPriority, final FinalSeminar finalSeminar, final NotificationPriority notificationPriority,
final String absolutePath) { final String absolutePath) {
Properties props = null; String webNotificationMessage = new StringResourceModel("finalSeminarEdit.webNotification", new Model<FinalSeminar>(finalSeminar)).getString();
try {
props = PropsUtils.load("notification.properties");
} catch (Exception e) {
e.printStackTrace();
}
String mailSubject = props.getProperty("mailSubject");
String finalSeminarReportEdited = props.getProperty("finalSeminarOppositionReportEdited");
String finalSeminarOppositionReportBeenEdited = props
.getProperty("finalSeminarOppositionReportBeenEdited");
String quote = props.getProperty("quote");
String webNotificationMessage = finalSeminarReportEdited + quote String mailSubject = new StringResourceModel("mailSubject", null).getString();
+ finalSeminar.getProject().getTitle() + quote
+ finalSeminarOppositionReportBeenEdited;
String mailMessage = webNotificationMessage; String mailMessage = webNotificationMessage;
NotificationMessage notificationMessage = new NotificationMessage(webNotificationMessage, NotificationMessage notificationMessage = new NotificationMessage(webNotificationMessage,
@ -279,37 +194,17 @@ public class NotificationControllerImpl implements NotificationController {
@Override @Override
public void notifyCreateFinalSeminar(final User user, public void notifyCreateFinalSeminar(final User user,
final FinalSeminar finalSemniar, final NotificationPriority notificationPriority, final FinalSeminar finalSeminar, final NotificationPriority notificationPriority,
final String absolutePath, final boolean opponent) { final String absolutePath, final boolean opponent) {
String webNotificationMessage = "";
Properties props = null;
try {
props = PropsUtils.load("notification.properties");
} catch (Exception e) {
e.printStackTrace();
}
String created = props.getProperty("finalSeminarCreated");
String mailSubject = props.getProperty("mailSubject");
String project = "";
if (!opponent) { if (!opponent) {
project = props.getProperty("finalSeminarProject"); webNotificationMessage = new StringResourceModel("finalSeminarCreated.webNotification", new Model<FinalSeminar>(finalSeminar), new Object[]{finalSeminar.getStartDate(), finalSeminar.getEndDate()}).getString();
} else { } else {
project = props.getProperty("finalSeminarProjectOpponnent"); webNotificationMessage = new StringResourceModel("finalSeminarCreatedOpponent.webNotification", new Model<FinalSeminar>(finalSeminar), new Object[]{finalSeminar.getStartDate(), finalSeminar.getEndDate()}).getString();
} }
String comma = props.getProperty("comma");
String space = props.getProperty("space");
String quote = props.getProperty("quote");
DateFormat dfFrom = new SimpleDateFormat("yyyy-MM-dd HH:mm");
DateFormat dfTo = new SimpleDateFormat("-HH:mm");
String webNotificationMessage = created + quote + finalSemniar.getProject().getTitle()
+ quote + project + finalSemniar.getRoom() + comma + space
+ dfFrom.format(finalSemniar.getStartDate())
+ dfTo.format(finalSemniar.getEndDate());
String mailMessage = webNotificationMessage; String mailMessage = webNotificationMessage;
String mailSubject = new StringResourceModel("mailSubject", null).getString();
NotificationMessage notificationMessage = new NotificationMessage(webNotificationMessage, NotificationMessage notificationMessage = new NotificationMessage(webNotificationMessage,
mailSubject, mailMessage); mailSubject, mailMessage);
@ -321,108 +216,58 @@ public class NotificationControllerImpl implements NotificationController {
final FinalSeminar finalSeminar, final NotificationPriority notificationPriority, final FinalSeminar finalSeminar, final NotificationPriority notificationPriority,
final String absolutePath) { final String absolutePath) {
Properties props = null; String webNotificationMessage = new StringResourceModel("thesisUpload.webNotification",
try { new Model<FinalSeminar>(finalSeminar)).getString();
props = PropsUtils.load("notification.properties");
} catch (Exception e) {
e.printStackTrace();
}
String mailSubject = props.getProperty("mailSubject");
String finalSeminarReportUploaded = props.getProperty("finalSeminarReportUploaded");
String finalSeminarReportBeenUploaded = props.getProperty("finalSeminarReportBeenUploaded");
String quote = props.getProperty("quote");
String webNotificationMessage = finalSeminarReportUploaded + quote
+ finalSeminar.getProject().getTitle() + quote + finalSeminarReportBeenUploaded;
String mailMessage = webNotificationMessage; String mailMessage = webNotificationMessage;
String mailSubject = new StringResourceModel("mailSubject", null).getString();
NotificationMessage notificationMessage = new NotificationMessage(webNotificationMessage, NotificationMessage notificationMessage = new NotificationMessage(webNotificationMessage,
mailSubject, mailMessage); mailSubject, mailMessage);
processNotification(user, notificationMessage, absolutePath, notificationPriority); processNotification(user, notificationMessage, absolutePath, notificationPriority);
System.out.println(generateMail(user.getFirstName(), notificationMessage.getMailMessage(), absolutePath));
} }
@Override @Override
public void notifyOppositionUploaded(final User user, public void notifyOppositionUploaded(final User user,
final FinalSeminarOpposition opposition, final FinalSeminarOpposition opposition,
final NotificationPriority notificationPriority, final String absolutePath) { final NotificationPriority notificationPriority, final String absolutePath) {
Properties props = null; String webNotificationMessage = new StringResourceModel("oppositionUpload.webNotification",
try { new Model<FinalSeminarOpposition>(opposition)).getString();
props = PropsUtils.load("notification.properties");
} catch (Exception e) {
e.printStackTrace();
}
String mailSubject = props.getProperty("mailSubject");
String finalSeminarOppositionReportUploaded = props
.getProperty("finalSeminarOppositionReportUploaded");
String finalSeminarOppositionReportBeenUploaded = props
.getProperty("finalSeminarOppositionReportBeenUploaded");
String dot = props.getProperty("dot");
String quote = props.getProperty("quote");
String space = props.getProperty("space");
String webNotificationMessage = finalSeminarOppositionReportUploaded + quote
+ opposition.getFinalSeminar().getProject().getTitle() + quote
+ finalSeminarOppositionReportBeenUploaded
+ opposition.getOpponent().getUser().getFirstName() + space
+ opposition.getOpponent().getUser().getLastName() + dot;
String mailMessage = webNotificationMessage; String mailMessage = webNotificationMessage;
String mailSubject = new StringResourceModel("mailSubject", null).getString();
NotificationMessage notificationMessage = new NotificationMessage(webNotificationMessage, NotificationMessage notificationMessage = new NotificationMessage(webNotificationMessage,
mailSubject, mailMessage); mailSubject, mailMessage);
processNotification(user, notificationMessage, absolutePath, notificationPriority); processNotification(user, notificationMessage, absolutePath, notificationPriority);
} }
public void notifyAcceptOfReview(PeerRequest request, Student student, Project project) { public void notifyAcceptOfReview(PeerRequest request, Student student, Project project) {
try {
Properties props = null; String webNotificationMessage = new StringResourceModel("reviewAccepted.webNotification", null, new Object[]{student.getUser(), project.getProjectClass().getProjectClassSettings()
.getNumDaysToSubmitPeerReview()}).getString();
String mailSubject = new StringResourceModel("acceptPeerReviewSubject", null).getString();
props = PropsUtils.load("notification.properties"); User requestingUser = request.getRequester().getUser();
String mailSubject = props.getProperty("acceptPeerReviewSubject"); String messageBody = webNotificationMessage;
String requestAccepted = props.getProperty("requestAccepted"); NotificationMessage notificationMessage = new NotificationMessage(
String heShe = props.getProperty("heShe");
String complete = props.getProperty("complete");
User requestingUser = request.getRequester().getUser();
String messageBody = requestAccepted
+ student.getUser().toString()
+ heShe
+ project.getProjectClass().getProjectClassSettings()
.getNumDaysToSubmitPeerReview() + complete;
String webNotificationMessage = requestAccepted + student.getUser().toString();
NotificationMessage notificationMessage = new NotificationMessage(
webNotificationMessage, mailSubject, messageBody); webNotificationMessage, mailSubject, messageBody);
PageParameters pp = new PageParameters(); PageParameters pp = new PageParameters();
String peerStatsUrl = RequestUtils.toAbsolutePath(RequestCycle.get() String peerStatsUrl = RequestUtils.toAbsolutePath(RequestCycle.get()
.urlFor(ProjectPeerStatsPage.class, pp).toString()); .urlFor(ProjectPeerStatsPage.class, pp).toString());
processNotification(requestingUser, notificationMessage, peerStatsUrl, processNotification(requestingUser, notificationMessage, peerStatsUrl,
NotificationPriority.MEDIUM); NotificationPriority.MEDIUM);
} catch (Exception e) {
e.printStackTrace();
} }
}
public void notifyCompletionOfReview(PeerReview review) { public void notifyCompletionOfReview(PeerReview review) {
try {
String mailSubject = new StringResourceModel("completedReviewSubject", null).getString();
Properties props = null;
props = PropsUtils.load("notification.properties");
String mailSubject = props.getProperty("completedReviewSubject");
String requestReviewed = props.getProperty("requestReviewed");
String supervisorMessageBody = props.getProperty("supervisorMessageBody");
String supervisorMessageBody2 = props.getProperty("supervisorMessageBody2");
String supervisorMessageBody3 = props.getProperty("supervisorMessageBody3");
String commaWithLinebreak = props.getProperty("commaWithLinebreak");
String inProject = props.getProperty("inProject");
String hasPerformed = props.getProperty("hasPerformed");
PeerRequest peerRequest = review.getPeerRequest(); PeerRequest peerRequest = review.getPeerRequest();
User requestingUser = peerRequest.getRequester().getUser(); User requestingUser = peerRequest.getRequester().getUser();
@ -435,21 +280,26 @@ public class NotificationControllerImpl implements NotificationController {
.urlFor(SupervisorPeerReviewPage.class, pp).toString()); .urlFor(SupervisorPeerReviewPage.class, pp).toString());
// Message for student when his/her review request is completed. // Message for student when his/her review request is completed.
String messageBody = requestReviewed; String webNotificationMessageForRequester = new StringResourceModel(
"reviewCompletedforRequester.webNotification",
new Model<PeerReview>(review)).getString();
NotificationMessage notificationMessage = new NotificationMessage(messageBody, NotificationMessage notificationMessage = new NotificationMessage(webNotificationMessageForRequester,
mailSubject, messageBody); mailSubject, webNotificationMessageForRequester);
processNotification(requestingUser, notificationMessage, reviewUrl, processNotification(requestingUser, notificationMessage, reviewUrl,
NotificationPriority.MEDIUM); NotificationPriority.MEDIUM);
// Message for supervisor of the project with a completed review. // Message for supervisor of the project with a completed review.
messageBody = supervisorMessageBody + peerRequest.getProject().getTitle()
+ supervisorMessageBody2; String webNotificationMessageForSupervisorOfProject = new StringResourceModel(
"reviewCompletedforRequestSupervisor.webNotification",
new Model<PeerReview>(review)).getString();
User requestSupervisor = peerRequest.getProject().getHeadSupervisor().getUser(); User requestSupervisor = peerRequest.getProject().getHeadSupervisor().getUser();
NotificationMessage notificationMessageSupervisorOfProject = new NotificationMessage( NotificationMessage notificationMessageSupervisorOfProject = new NotificationMessage(
messageBody, mailSubject, messageBody); webNotificationMessageForSupervisorOfProject, mailSubject, webNotificationMessageForSupervisorOfProject);
processNotification(requestSupervisor, notificationMessageSupervisorOfProject, processNotification(requestSupervisor, notificationMessageSupervisorOfProject,
supervisorReviewUrl, NotificationPriority.MEDIUM); supervisorReviewUrl, NotificationPriority.MEDIUM);
@ -457,36 +307,22 @@ public class NotificationControllerImpl implements NotificationController {
// Message for supervisor of the reviewer that have made a review // Message for supervisor of the reviewer that have made a review
// for another project. // for another project.
String webNotificationMessage = review.getReviewer().getUser().toString() + inProject String webNotificationMessageForSupervisorOfReviewer = new StringResourceModel(
+ review.getProject().getTitle() + hasPerformed; "reviewCompletedforReviewSupervisor.webNotification",
new Model<PeerReview>(review)).getString();
messageBody = supervisorMessageBody + review.getProject().getTitle()
+ commaWithLinebreak + review.getReviewer().getUser().toString()
+ supervisorMessageBody3;
User reviewSupervisor = review.getProject().getHeadSupervisor().getUser(); User reviewSupervisor = review.getProject().getHeadSupervisor().getUser();
NotificationMessage notificationMessageSupervisorOfReviewer = new NotificationMessage( NotificationMessage notificationMessageSupervisorOfReviewer = new NotificationMessage(
webNotificationMessage, mailSubject, messageBody); webNotificationMessageForSupervisorOfReviewer, mailSubject, webNotificationMessageForSupervisorOfReviewer);
processNotification(reviewSupervisor, notificationMessageSupervisorOfReviewer, processNotification(reviewSupervisor, notificationMessageSupervisorOfReviewer,
supervisorReviewUrl, NotificationPriority.MEDIUM); supervisorReviewUrl, NotificationPriority.MEDIUM);
} catch (Exception e) {
e.printStackTrace();
}
} }
/**
* TODO Rewrite
*
* @param review
*/
public void notifyOfReviewRating(PeerReview review) { public void notifyOfReviewRating(PeerReview review) {
try {
Properties props = null; String webNotificationMessage = new StringResourceModel("reviewRated.webNotification", null).getString();
props = PropsUtils.load("notification.properties"); String mailSubject = new StringResourceModel("completedReviewSubject", null).getString();
String mailSubject = props.getProperty("reviewRatedSubject");
String reviewRatedBody = props.getProperty("reviewRatedBody");
User reviewingUser = review.getReviewer().getUser(); User reviewingUser = review.getReviewer().getUser();
PageParameters pp = new PageParameters(); PageParameters pp = new PageParameters();
@ -494,16 +330,12 @@ public class NotificationControllerImpl implements NotificationController {
String projectReviewUrl = RequestUtils.toAbsolutePath(RequestCycle.get() String projectReviewUrl = RequestUtils.toAbsolutePath(RequestCycle.get()
.urlFor(ProjectPeerReviewPage.class, pp).toString()); .urlFor(ProjectPeerReviewPage.class, pp).toString());
String messageBody = reviewRatedBody; String mailMessage = webNotificationMessage;
NotificationMessage notificationMessage = new NotificationMessage(messageBody, NotificationMessage notificationMessage = new NotificationMessage(webNotificationMessage,
mailSubject, messageBody); mailSubject, mailMessage);
processNotification(reviewingUser, notificationMessage, projectReviewUrl, processNotification(reviewingUser, notificationMessage, projectReviewUrl,
NotificationPriority.MEDIUM); NotificationPriority.MEDIUM);
} catch (Exception e) {
e.printStackTrace();
}
} }
} }

@ -3,14 +3,6 @@ package se.su.dsv.scipro.data.dao.interfaces;
import java.io.Serializable; import java.io.Serializable;
import java.util.List; import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceException;
import javax.persistence.TypedQuery;
import org.hibernate.ejb.QueryHints;
import org.springframework.orm.jpa.JpaCallback;
import org.springframework.transaction.annotation.Transactional;
import se.su.dsv.scipro.data.dataobjects.DomainObject; import se.su.dsv.scipro.data.dataobjects.DomainObject;
/** /**
* @author Richard Wilkinson - richard.wilkinson@jweekend.com * @author Richard Wilkinson - richard.wilkinson@jweekend.com
@ -30,6 +22,8 @@ public interface Dao<T extends DomainObject>
public T reLoad(T object); public T reLoad(T object);
public void refresh(T object);
public List<T> findAll(int first, int count); public List<T> findAll(int first, int count);
public List<T> findAll(int first, int count, String orderBy); public List<T> findAll(int first, int count, String orderBy);

@ -4,7 +4,7 @@ import java.util.List;
import se.su.dsv.scipro.data.dataobjects.ProjectClass; import se.su.dsv.scipro.data.dataobjects.ProjectClass;
public interface ProjectClassDao extends Dao<ProjectClass>{ public interface ProjectClassDao extends LazyDeleteDao<ProjectClass>{
ProjectClass getProjectClass(String projectCode); ProjectClass getProjectClass(String projectCode);

@ -2,19 +2,13 @@ package se.su.dsv.scipro.data.dao.interfaces;
import java.util.List; import java.util.List;
import se.su.dsv.scipro.data.dataobjects.MessageBoard;
import se.su.dsv.scipro.data.dataobjects.Project;
import se.su.dsv.scipro.data.dataobjects.Role; import se.su.dsv.scipro.data.dataobjects.Role;
import se.su.dsv.scipro.data.dataobjects.User; import se.su.dsv.scipro.data.dataobjects.User;
import se.su.dsv.scipro.data.enums.ProjectStatus;
import se.su.dsv.scipro.data.enums.ProjectTeamMemberRoles;
public interface UserDao extends LazyDeleteDao<User> { public interface UserDao extends LazyDeleteDao<User> {
User getUserByIdentifier(Long identifier); User getUserByIdentifier(Long identifier);
User getUserByUsername(String userName);
User getUserByUsername(String userName, String realm); User getUserByUsername(String userName, String realm);
User getUserByEmail(String emailAddress); User getUserByEmail(String emailAddress);

@ -56,6 +56,11 @@ public abstract class AbstractDaoJPAImp<T extends DomainObject> extends JpaDaoSu
else else
return null; return null;
} }
@Transactional(readOnly=true)
public void refresh(T object){
if(object != null)
getJpaTemplate().refresh(object);
}
@Transactional( readOnly=false ) @Transactional( readOnly=false )
public T save(T object){ public T save(T object){

@ -7,10 +7,10 @@ import javax.persistence.NoResultException;
import javax.persistence.PersistenceException; import javax.persistence.PersistenceException;
import javax.persistence.TypedQuery; import javax.persistence.TypedQuery;
import org.hibernate.ejb.QueryHints;
import org.springframework.orm.jpa.JpaCallback; import org.springframework.orm.jpa.JpaCallback;
import org.springframework.stereotype.Repository; import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import se.su.dsv.scipro.data.dao.interfaces.ProjectClassDao; import se.su.dsv.scipro.data.dao.interfaces.ProjectClassDao;
import se.su.dsv.scipro.data.dataobjects.ProjectClass; import se.su.dsv.scipro.data.dataobjects.ProjectClass;
/** /**

@ -62,12 +62,6 @@ public class UserDaoJPAImp extends LazyDeleteAbstractDaoJPAImp<User> implements
}); });
} }
@Transactional
@Deprecated
public User getUserByUsername(final String username) {
return this.getUserByUsername(username, "DSV.SU.SE");
}
@Transactional(readOnly = true) @Transactional(readOnly = true)
public User getUserByUsername(final String username, final String realm) { public User getUserByUsername(final String username, final String realm) {
return getJpaTemplate().execute(new JpaCallback<User>() { return getJpaTemplate().execute(new JpaCallback<User>() {

@ -8,7 +8,6 @@ import javax.persistence.Column;
import javax.persistence.Entity; import javax.persistence.Entity;
import javax.persistence.GeneratedValue; import javax.persistence.GeneratedValue;
import javax.persistence.Id; import javax.persistence.Id;
import javax.persistence.Lob;
import javax.persistence.OneToMany; import javax.persistence.OneToMany;
import javax.persistence.Table; import javax.persistence.Table;
@ -102,6 +101,9 @@ public class User extends LazyDeletableDomainObject implements Comparable<User>,
return emailAddress; return emailAddress;
} }
public void addUserName(Username username){
this.usernames.add(username);
}
public void setUserNames(Set<Username> usernames) { public void setUserNames(Set<Username> usernames) {
this.usernames = usernames; this.usernames = usernames;

@ -73,6 +73,8 @@ public class Username extends DomainObject {
public void setUser(User user) { public void setUser(User user) {
this.user = user; this.user = user;
if(user!=null)
user.addUserName(this);
} }
@Override @Override

@ -1,382 +0,0 @@
package se.su.dsv.scipro.datainitializers;
import java.util.Date;
import java.util.Set;
import java.util.TreeSet;
import org.joda.time.DateMidnight;
import org.springframework.beans.factory.annotation.Autowired;
import se.su.dsv.scipro.data.dao.interfaces.EventDao;
import se.su.dsv.scipro.data.dao.interfaces.GroupEventDao;
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.ProjectEventDao;
import se.su.dsv.scipro.data.dao.interfaces.ProjectScheduleDao;
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.UsernameDao;
import se.su.dsv.scipro.data.dataobjects.Employee;
import se.su.dsv.scipro.data.dataobjects.GroupEvent;
import se.su.dsv.scipro.data.dataobjects.Project;
import se.su.dsv.scipro.data.dataobjects.ProjectClass;
import se.su.dsv.scipro.data.dataobjects.ProjectEvent;
import se.su.dsv.scipro.data.dataobjects.ProjectSchedule;
import se.su.dsv.scipro.data.dataobjects.Student;
import se.su.dsv.scipro.data.dataobjects.SysAdmin;
import se.su.dsv.scipro.data.dataobjects.User;
import se.su.dsv.scipro.data.dataobjects.Username;
/**
* @author Richard Wilkinson - richard.wilkinson@jweekend.com
*
*/
public class EventDataInitializer {
@Autowired
private EventDao eventDao;
@Autowired
private ProjectEventDao projectEventDao;
@Autowired
private GroupEventDao groupEventDao;
@Autowired
private ProjectScheduleDao projectScheduleDao;
@Autowired
private ProjectDao projectDao;
@Autowired
private RoleDao roleDao;
@Autowired
private UserDao userDao;
@Autowired
private ProjectClassDao projectClassDao;
@Autowired
private UsernameDao usernameDao;
private User adam;
private User groupEventCreatorUser;
private User projectUser1;
private User projectUser2;
private Project project1;
private Project project2;
protected ProjectEvent indEvent;
protected ProjectEvent deletedIndEvent;
private ProjectClass prClass;
private GroupEvent groupEvent;
private GroupEvent deletedGroupEvent;
public void dataInit() {
User dan = new User();
dan.setFirstName("Dan");
dan.setLastName("Kjellman");
dan = userDao.save(dan);
dan = userDao.save(dan);
Username un = new Username();
un.setRealm("DSV.SU.SE");
un.setUserName("dan-kjel");
un.setUser(dan);
un = usernameDao.save(un);
prClass = new ProjectClass(ProjectClass.MASTER, "Master",null);
prClass = projectClassDao.save(prClass);
Student danStudent = new Student();
danStudent.setUser(dan);
danStudent = (Student) roleDao.save(danStudent);
Employee danEmployee = new Employee();
danEmployee.setUser(dan);
danEmployee = (Employee) roleDao.save(danEmployee);
SysAdmin danSysAdmin = new SysAdmin();
danSysAdmin.setUser(dan);
danSysAdmin = (SysAdmin) roleDao.save(danSysAdmin);
adam = new User();
adam.setFirstName("Adam");
adam.setLastName("Student");
adam = userDao.save(adam);
Student adamStudent = new Student();
adamStudent.setUser(adam);
adamStudent = (Student) roleDao.save(adamStudent);
Project noScheduleProject = new Project();
noScheduleProject.setTitle("No schedule project");
noScheduleProject.addProjectParticipant(danStudent);
noScheduleProject.addProjectParticipant(adamStudent);
noScheduleProject.setProjectClass(prClass);
noScheduleProject = projectDao.save(noScheduleProject);
groupEventCreatorUser = new User();
groupEventCreatorUser.setFirstName("eventCreatorUser");
groupEventCreatorUser = userDao.save(groupEventCreatorUser);
Employee groupEventCreatorUserRole = new Employee();
groupEventCreatorUserRole.setUser(groupEventCreatorUser);
groupEventCreatorUserRole = (Employee) roleDao.save(groupEventCreatorUserRole);
projectUser1 = new User();
projectUser1.setFirstName("Nisse");
projectUser1.setLastName("Student");
projectUser1 = userDao.save(projectUser1);
Student projectUser1Role = new Student();
projectUser1Role.setUser(projectUser1);
projectUser1Role = (Student) roleDao.save(projectUser1Role);
projectUser2 = new User();
projectUser2.setFirstName("Kalle");
projectUser2.setLastName("Student");
projectUser2 = userDao.save(projectUser2);
Student projectUser2Role = new Student();
projectUser2Role.setUser(projectUser2);
projectUser2Role = (Student) roleDao.save(projectUser2Role);
project1 = new Project();
project1.setTitle("Project 1");
project1.addProjectParticipant(adamStudent);
project1.addProjectParticipant(danStudent);
project1.setProjectClass(prClass);
project1 = projectDao.save(project1);
ProjectSchedule schedule1 = new ProjectSchedule();
schedule1.setProject(project1);
schedule1 = projectScheduleDao.save(schedule1);
project2 = new Project();
project2.setTitle("Project 2");
project2.addProjectParticipant(adamStudent);
project2.addProjectParticipant(projectUser2Role);
project2.setProjectClass(prClass);
project2 = projectDao.save(project2);
ProjectSchedule schedule2 = new ProjectSchedule();
schedule2.setProject(project2);
schedule2 = projectScheduleDao.save(schedule2);
indEvent = new ProjectEvent();
indEvent.setTitle("Individual event title");
indEvent.setDescription("Individual Event Description");
indEvent.setDueDate(new Date(System.currentTimeMillis() + 100000));
Set<Student> indEventStudents = new TreeSet<Student>();
indEventStudents.add(adamStudent);
indEvent.setParticipants(indEventStudents);
indEvent.setProjectSchedule(schedule1);
indEvent.setCreator(groupEventCreatorUser);
indEvent = projectEventDao.save(indEvent);
deletedIndEvent = new ProjectEvent();
deletedIndEvent.setTitle("Deleted Individual Event title");
deletedIndEvent.setDescription("Deleted Individual Event description");
deletedIndEvent.setDueDate(new Date(System.currentTimeMillis() + 100000));
deletedIndEvent.setDeleted(true);
Set<Student> indDeletedEventStudents = new TreeSet<Student>();
indDeletedEventStudents.add(adamStudent);
indEvent.setParticipants(indDeletedEventStudents);
deletedIndEvent.setProjectSchedule(schedule1);
deletedIndEvent.setCreator(groupEventCreatorUser);
deletedIndEvent = projectEventDao.save(deletedIndEvent);
groupEvent = new GroupEvent();
groupEvent.setTitle("Group event title");
groupEvent.setDescription("Group Event Description");
groupEvent.setDueDate(new Date(System.currentTimeMillis() + 500000000));
groupEvent.addProjectSchedule(schedule1);
groupEvent.addProjectSchedule(schedule2);
groupEvent.setCreator(groupEventCreatorUser);
groupEvent = groupEventDao.save(groupEvent);
deletedGroupEvent = new GroupEvent();
deletedGroupEvent.setTitle("Deleted group Event title");
deletedGroupEvent.setDescription("Deleted group Event description");
deletedGroupEvent.setDueDate(new Date(System.currentTimeMillis() + 100000));
deletedGroupEvent.setDeleted(true);
deletedGroupEvent.addProjectSchedule(schedule1);
deletedGroupEvent.addProjectSchedule(schedule2);
deletedGroupEvent.setCreator(groupEventCreatorUser);
deletedGroupEvent = groupEventDao.save(deletedGroupEvent);
DateMidnight date1 = new DateMidnight();
int count = 0;
for(int i = 1; i < 6; i++){
date1 = date1.plusWeeks(i);
indEvent = new ProjectEvent();
indEvent.setTitle("Project event " + count++);
indEvent.setDescription("Project event description");
indEvent.setDueDate(date1.toDate());
Set<Student> students = new TreeSet<Student>();
students.add(adamStudent);
if(count % 2 == 0){
students.add(projectUser1Role);
}
indEvent.setParticipants(students);
indEvent.setProjectSchedule(schedule1);
indEvent.setCreator(groupEventCreatorUser);
indEvent = projectEventDao.save(indEvent);
}
date1 = new DateMidnight();
for(int i = 1; i < 6; i++){
date1 = date1.minusWeeks(i);
indEvent = new ProjectEvent();
indEvent.setTitle("Project event " + count++);
indEvent.setDescription("Duis quis faucibus odio. Ut ullamcorper elit eu lacus gravida pharetra. Nunc fermentum tincidunt purus, nec dignissim massa feugiat a. Quisque vestibulum, elit in convallis commodo, metus ipsum accumsan lorem, vitae pulvinar odio odio ac dolor. Donec arcu quam, consectetur scelerisque interdum eget, tempus non odio. Vestibulum pellentesque viverra diam vitae bibendum. In congue fringilla suscipit. Sed semper tortor nec ligula mollis a tempus mauris interdum. Phasellus sit amet mauris leo, ut mollis velit.");
indEvent.setDueDate(date1.toDate());
Set<Student> students = new TreeSet<Student>();
students.add(adamStudent);
if(count % 2 == 0){
students.add(projectUser1Role);
}
indEvent.setParticipants(students);
indEvent.setProjectSchedule(schedule1);
indEvent.setCreator(groupEventCreatorUser);
indEvent = projectEventDao.save(indEvent);
}
date1 = new DateMidnight();
for(int i = 1; i < 6; i++){
date1 = date1.minusWeeks(i).minusDays(1);
groupEvent = new GroupEvent();
groupEvent.setTitle("Group event " + count++);
groupEvent.setDescription("Duis quis faucibus odio. Ut ullamcorper elit eu lacus gravida pharetra. Nunc fermentum tincidunt purus, nec dignissim massa feugiat a. Quisque vestibulum, elit in convallis commodo, metus ipsum accumsan lorem, vitae pulvinar odio odio ac dolor. Donec arcu quam, consectetur scelerisque interdum eget, tempus non odio. Vestibulum pellentesque viverra diam vitae bibendum. In congue fringilla suscipit. Sed semper tortor nec ligula mollis a tempus mauris interdum. Phasellus sit amet mauris leo, ut mollis velit.");
groupEvent.setDueDate(date1.toDate());
groupEvent.addProjectSchedule(schedule1);
groupEvent.addProjectSchedule(schedule2);
groupEvent.setCreator(groupEventCreatorUser);
groupEvent = groupEventDao.save(groupEvent);
}
date1 = new DateMidnight();
for(int i = 1; i < 6; i++){
date1 = date1.plusWeeks(i).plusDays(1);
groupEvent = new GroupEvent();
groupEvent.setTitle("Group event " + count++);
groupEvent.setDescription("Group Event Description");
groupEvent.setDueDate(date1.toDate());
groupEvent.addProjectSchedule(schedule1);
groupEvent.addProjectSchedule(schedule2);
groupEvent.setCreator(groupEventCreatorUser);
groupEvent = groupEventDao.save(groupEvent);
}
date1 = new DateMidnight();
for(int i = 1; i < 6; i++){
date1 = date1.plusDays(i).plus(60 * 60 * 1000);
groupEvent = new GroupEvent();
groupEvent.setTitle("Group event " + count++);
groupEvent.setDescription("Group Event Description");
groupEvent.setDueDate(date1.toDate());
groupEvent.addProjectSchedule(schedule1);
groupEvent.addProjectSchedule(schedule2);
groupEvent.setCreator(groupEventCreatorUser);
groupEvent = groupEventDao.save(groupEvent);
date1 = new DateMidnight();
date1 = date1.plusDays(i);
indEvent = new ProjectEvent();
indEvent.setTitle("Project event " + count++);
indEvent.setDescription("Project event description");
indEvent.setDueDate(date1.toDate());
Set<Student> students = new TreeSet<Student>();
students.add(adamStudent);
if(count % 2 == 0){
students.add(projectUser1Role);
}
indEvent.setParticipants(students);
indEvent.setProjectSchedule(schedule1);
indEvent.setCreator(groupEventCreatorUser);
indEvent = projectEventDao.save(indEvent);
}
System.out.println("DONE");
}
public EventDao getEventDao() {
return eventDao;
}
public void setEventDao(EventDao eventDao) {
this.eventDao = eventDao;
}
public GroupEventDao getGroupEventDao() {
return groupEventDao;
}
public void setGroupEventDao(GroupEventDao groupEventDao) {
this.groupEventDao = groupEventDao;
}
public ProjectScheduleDao getProjectScheduleDao() {
return projectScheduleDao;
}
public void setProjectScheduleDao(ProjectScheduleDao projectScheduleDao) {
this.projectScheduleDao = projectScheduleDao;
}
public ProjectDao getProjectDao() {
return projectDao;
}
public void setProjectDao(ProjectDao projectDao) {
this.projectDao = projectDao;
}
public RoleDao getRoleDao() {
return roleDao;
}
public void setRoleDao(RoleDao roleDao) {
this.roleDao = roleDao;
}
public UserDao getUserDao() {
return userDao;
}
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
public ProjectEventDao getProjectEventDao() {
return projectEventDao;
}
public void setProjectEventDao(ProjectEventDao projectEventDao) {
this.projectEventDao = projectEventDao;
}
}

@ -1,69 +0,0 @@
package se.su.dsv.scipro.datainitializers;
import org.springframework.beans.factory.annotation.Autowired;
import se.su.dsv.scipro.data.dao.interfaces.ProjectEventTemplateDao;
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.Employee;
import se.su.dsv.scipro.data.dataobjects.ProjectEventTemplate;
import se.su.dsv.scipro.data.dataobjects.SysAdmin;
import se.su.dsv.scipro.data.dataobjects.User;
public class EventTemplatesInitializer {
@Autowired
private UserDao userDao;
@Autowired
private RoleDao roleDao;
@Autowired
private ProjectEventTemplateDao eventTemplateDao;
public void dataInit(){
User supervisorUser = new User();
supervisorUser = userDao.save(supervisorUser);
Employee supervisorRole = new Employee();
supervisorRole.setUser(supervisorUser);
supervisorRole = (Employee) roleDao.save(supervisorRole);
User sysAdminUser = new User();
sysAdminUser = userDao.save(sysAdminUser);
SysAdmin sysAdminRole = new SysAdmin();
sysAdminRole.setUser(sysAdminUser);
sysAdminRole = (SysAdmin) roleDao.save(sysAdminRole);
ProjectEventTemplate projectEventTemplate = new ProjectEventTemplate();
projectEventTemplate.setTitle("projectEventTemplate title");
projectEventTemplate.setDescription("Project event template description");
projectEventTemplate.setTemplateCreator(supervisorUser);
projectEventTemplate = (ProjectEventTemplate) eventTemplateDao.save(projectEventTemplate);
ProjectEventTemplate projectEventTemplateSysAdmin = new ProjectEventTemplate();
projectEventTemplateSysAdmin.setTitle("projectEventTemplateSysAdmin title");
projectEventTemplateSysAdmin.setDescription("projectEventTemplateSysAdmin description");
projectEventTemplateSysAdmin.setTemplateCreator(sysAdminUser);
projectEventTemplateSysAdmin = (ProjectEventTemplate) eventTemplateDao.save(projectEventTemplateSysAdmin);
User employeeAndSysAdminUser = new User();
employeeAndSysAdminUser = userDao.save(employeeAndSysAdminUser);
SysAdmin employeeAndSysAdminUserSysAdminRole = new SysAdmin();
employeeAndSysAdminUserSysAdminRole.setUser(employeeAndSysAdminUser);
employeeAndSysAdminUserSysAdminRole = (SysAdmin) roleDao.save(employeeAndSysAdminUserSysAdminRole);
Employee employeeAndSysAdminUserEmpRole = new Employee();
employeeAndSysAdminUserEmpRole.setUser(employeeAndSysAdminUser);
employeeAndSysAdminUserEmpRole = (Employee) roleDao.save(employeeAndSysAdminUserEmpRole);
ProjectEventTemplate pr1 = new ProjectEventTemplate();
pr1.setTitle("pr1 title");
pr1.setDescription("pr1 description");
pr1.setTemplateCreator(employeeAndSysAdminUser);
pr1 = (ProjectEventTemplate) eventTemplateDao.save(pr1);
}
}

@ -1,125 +0,0 @@
package se.su.dsv.scipro.datainitializers;
import org.springframework.beans.factory.annotation.Autowired;
import se.su.dsv.scipro.data.dao.interfaces.ProjectClassDao;
import se.su.dsv.scipro.data.dao.interfaces.ProjectEventTemplateDao;
import se.su.dsv.scipro.data.dao.interfaces.RoleDao;
import se.su.dsv.scipro.data.dao.interfaces.ScheduleTemplateDao;
import se.su.dsv.scipro.data.dao.interfaces.UserDao;
import se.su.dsv.scipro.data.dataobjects.Employee;
import se.su.dsv.scipro.data.dataobjects.ProjectClass;
import se.su.dsv.scipro.data.dataobjects.ProjectEventTemplate;
import se.su.dsv.scipro.data.dataobjects.ScheduleTemplate;
import se.su.dsv.scipro.data.dataobjects.Student;
import se.su.dsv.scipro.data.dataobjects.SysAdmin;
import se.su.dsv.scipro.data.dataobjects.User;
public class ScheduleTemplateInitializer {
@Autowired
private UserDao userDao;
@Autowired
private RoleDao roleDao;
@Autowired
private ScheduleTemplateDao scheduleTemplateDao;
@Autowired
private ProjectEventTemplateDao eventTemplateDao;
@Autowired
private ProjectClassDao projectClassDao;
private User supervisorUser;
private Employee supervisorRole;
private User sysAdminUser;
private SysAdmin sysAdminRole;
private ScheduleTemplate sysAdminTemplate;
private ScheduleTemplate employeeTemplate;
private ProjectEventTemplate projectEventTemplateSysAdmin;
private ProjectEventTemplate projectEventTemplate;
public void dataInit(){
supervisorUser = new User();
supervisorUser.setFirstName("Adam");
supervisorUser.setLastName("Supervisor");
supervisorUser = userDao.save(supervisorUser);
supervisorRole = new Employee();
supervisorRole.setUser(supervisorUser);
supervisorRole = (Employee) roleDao.save(supervisorRole);
sysAdminUser = new User();
sysAdminUser.setFirstName("Eva");
sysAdminUser.setLastName("SysAdmin");
sysAdminUser = userDao.save(sysAdminUser);
sysAdminRole = new SysAdmin();
sysAdminRole.setUser(sysAdminUser);
sysAdminRole = (SysAdmin) roleDao.save(sysAdminRole);
ProjectClass masterClass = new ProjectClass(ProjectClass.MASTER, "Master",null);
ProjectClass bachelorClass = new ProjectClass(ProjectClass.BACHELOR,"Bachelor",null);
masterClass = projectClassDao.save(masterClass);
bachelorClass = projectClassDao.save(bachelorClass);
for(int i = 0; i < 20; i++){
ScheduleTemplate s = new ScheduleTemplate();
s.setActive(true);
s.setTemplateName("ScheduleTemplate no " + i);
if(i % 2 == 0){
s.setCreator(supervisorUser);
s.setProjectClass(bachelorClass);
} else {
s.setCreator(sysAdminUser);
s.setSysAdminTemplate(true);
s.setProjectClass(masterClass);
}
s = scheduleTemplateDao.save(s);
}
ScheduleTemplate s = new ScheduleTemplate();
s.setActive(true);
s.setTemplateName("A test template");
s.setTemplateDescription("Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque et magna in nulla rutrum dictum. Nunc at dolor nunc. Morbi quis augue vel urna posuere pharetra at non quam. Nunc elit mauris, commodo sed gravida sed, tempus in tortor. \nPellentesque accumsan nulla ante, in pulvinar velit. Mauris in nisi mi, fermentum porttitor turpis. Vivamus non nunc ipsum. Phasellus ultricies malesuada nibh eget dapibus. Duis id ipsum at tellus bibendum eleifend id sed augue. Nunc ornare vehicula dapibus. Praesent eget arcu ut elit tempus hendrerit. Aliquam imperdiet, quam at convallis volutpat, diam orci elementum ante, at luctus nunc leo sed elit.");
s.setCreator(supervisorUser);
s.setProjectClass(bachelorClass);
s = scheduleTemplateDao.save(s);
for(int i = 0; i < 10; i++){
ProjectEventTemplate e = new ProjectEventTemplate();
e.setTemplateCreator(supervisorUser);
e.setDescription("Duis quis faucibus odio. Ut ullamcorper elit eu lacus gravida pharetra. Nunc fermentum tincidunt purus, nec dignissim massa feugiat a. Quisque vestibulum, elit in convallis commodo, metus ipsum accumsan lorem, vitae pulvinar odio odio ac dolor. Donec arcu quam, consectetur scelerisque interdum eget, tempus non odio. Vestibulum pellentesque viverra diam vitae bibendum. In congue fringilla suscipit. Sed semper tortor nec ligula mollis a tempus mauris interdum. Phasellus sit amet mauris leo, ut mollis velit.");
e.setEstimatedTimeConsumption(10);
e.setNumberInOrder(i);
e.setTitle("Event tempalte no: " + i);
s.addProjectEventTemplate(e);
}
s = scheduleTemplateDao.save(s);
User u = new User();
u.setFirstName("Dan");
u.setLastName("Allaroller");
u = userDao.save(u);
Employee us = new Employee();
us.setUser(u);
us = (Employee) roleDao.save(us);
SysAdmin usa = new SysAdmin();
usa.setUser(u);
usa = (SysAdmin) roleDao.save(usa);
Student st = new Student();
st.setUser(u);
st = (Student) roleDao.save(st);
}
}

@ -1,82 +0,0 @@
package se.su.dsv.scipro.json;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import org.apache.log4j.Level;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import se.su.dsv.scipro.ApplicationSettings;
import se.su.dsv.scipro.data.dao.interfaces.UserDao;
import se.su.dsv.scipro.data.dataobjects.User;
/**
* This class does a lookup on a username against the remote remoteLookupUrl specified in
* the applicationContext, under ApplicationSettings.
*
* This class does NOT handle Daisys merging of users and is not maintained.
*
* @author Dan Kjellman <dan-kjel@dsv.su.se>
*/
@Deprecated
@Component("userFullLookup")
public class DefaultUserFullLookup implements IUserLookup {
/*
* References populated by spring
*/
@Autowired
private UserDao userDao;
@Autowired
private JsonUserFullResponseHandler userResponseHandler;
@Autowired
private ApplicationSettings settings;
private Logger logger;
public DefaultUserFullLookup(){
logger = Logger.getRootLogger();
}
/**
* Perform lookup against remote server
*
* @param username the username to lookup
* @throws IOException if there was an error in the connection
*/
public User lookup(String username) throws IOException {
if(username == null){
logger.log(Level.ERROR, "Trying to pass null instead of a username to the userlookup");
throw new IllegalStateException("You cannot pass null as the lookup parameter");
}
logger.log(Level.INFO,"Starting lookup for username: " + username);
Map<String, String> params = new HashMap<String, String>();
//For now you can only log in with dsv.su.se accounts...
params.put("username", username);
RequestSender request = new RequestSender(userResponseHandler, settings.getRemoteLookupUrl(), params, RequestSender.REQUEST_TYPE_POST);
try{
request.processRequest();
} catch (IOException e) {
//Gets logged by the requestsender....
throw e;
}
/*
* Lookup the user and return
*/
User u = userDao.getUserByUsername(username);
if(u != null){
logger.log(Level.INFO, "Imported user/username from remote system: " + u.getFirstName() + " " + u.getLastName() + "("+username+") id: " + u.getId());
}
return u;
}
}

@ -1,80 +0,0 @@
package se.su.dsv.scipro.json;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import org.apache.log4j.Level;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import se.su.dsv.scipro.ApplicationSettings;
import se.su.dsv.scipro.data.dao.interfaces.UserDao;
import se.su.dsv.scipro.data.dataobjects.User;
/**
* This class does a lookup on a username against the remote remoteLookupUrl specified in
* the applicationContext, under ApplicationSettings.
*
* This class does NOT handle Daisys merging of users and is not maintained.
*
* @author Dan Kjellman <dan-kjel@dsv.su.se>
*/
@Component("userLookup")
public class DefaultUserLookup implements IUserLookup {
/*
* References populated by spring
*/
@Autowired
private UserDao userDao;
@Autowired
private JsonUserResponseHandler userResponseHandler;
@Autowired
private ApplicationSettings settings;
private Logger logger;
public DefaultUserLookup(){
logger = Logger.getRootLogger();
}
/**
* Perform lookup against remote server
*
* @param username the username to lookup
* @throws IOException if there was an error in the connection
*/
public User lookup(String username) throws IOException {
if(username == null){
logger.log(Level.ERROR, "Trying to pass null instead of a username to the userlookup");
throw new IllegalStateException("You cannot pass null as the lookup parameter");
}
logger.log(Level.INFO,"Starting lookup for userid: " + username);
Map<String, String> params = new HashMap<String, String>();
//For now you can only log in with dsv.su.se accounts...
params.put("userid", username);
RequestSender request = new RequestSender(userResponseHandler, settings.getRemoteLookupUrl(), params, RequestSender.REQUEST_TYPE_POST);
try{
request.processRequest();
} catch (IOException e) {
//Gets logged by the requestsender....
throw e;
}
/*
* Lookup the user and return
*/
User u = userDao.getUserByUsername(username);
if(u != null){
logger.log(Level.INFO, "Imported user/username from remote system: " + u.getFirstName() + " " + u.getLastName() + "("+username+") id: " + u.getId());
}
return u;
}
}

@ -0,0 +1,32 @@
package se.su.dsv.scipro.json;
import java.io.IOException;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import se.su.dsv.scipro.ApplicationSettings;
import se.su.dsv.scipro.data.dao.interfaces.UserDao;
/**
* Package-private Abstract base for the public UserLookups.
* This is not an ideal pattern under most circumstances, but class is package private and thus not part of exported API.
*/
abstract class DefaultUserLookupBase{
@Autowired
protected UserDao userDao;
@Autowired
private JsonUserResponseHandler userResponseHandler;
@Autowired
private ApplicationSettings settings;
protected boolean doRemoteRequest(final Map<String,String> params, final RemoteLookupOptions options){
RequestSender request = new RequestSender(userResponseHandler, settings.getRemoteLookupUrl(), params, options, RequestSender.REQUEST_TYPE.POST);
try{
request.processRequest();
} catch (final IOException e){
return false;
}
return true;
}
}

@ -0,0 +1,36 @@
package se.su.dsv.scipro.json;
import java.util.HashMap;
import java.util.Map;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Component;
import se.su.dsv.scipro.data.dataobjects.User;
/**
* Default implementation of IUserLookupFromIdentifier queries remote defined by ApplicationSettings via JSon requests.
*/
@Component("userLookupFromIdentifier")
public class DefaultUserLookupFromIdentifier extends DefaultUserLookupBase implements IUserLookupFromIdentifier {
private Logger logger = Logger.getLogger(DefaultUserLookupFromIdentifier.class);
public User lookup(final Long identifier, final RemoteLookupOptions options){
if(identifier == null){
throw new IllegalStateException("null values for user parameter not allowed");
}
logger.debug("Starting remote lookup for: " + identifier);
final Map<String, String> params = new HashMap<String, String>();
params.put("userid", identifier.toString());
if(!doRemoteRequest(params,options)){
logger.warn("Remote lookup failed for identifier: "+identifier);
return null;
}
final User u = userDao.getUserByIdentifier(identifier);
if(u != null)
logger.info("Successfully imported user/username from remote system: " + u.getId() + " " +u.getUserNames());
else
logger.warn("Failed to import a valid user from remote system: "+identifier);
return u;
}
}

@ -0,0 +1,38 @@
package se.su.dsv.scipro.json;
import java.util.HashMap;
import java.util.Map;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Component;
import se.su.dsv.scipro.data.dataobjects.User;
import se.su.dsv.scipro.util.KeyValuePair;
/**
* Default implementation of IUserLookupFromUsername, queries remote defined by ApplicationSettings via JSon requests.
*/
@Component("userLookupFromUsername")
public class DefaultUserLookupFromUsername extends DefaultUserLookupBase implements IUserLookupFromUsername {
private Logger logger = Logger.getLogger(DefaultUserLookupFromUsername.class);
public User lookup(final KeyValuePair<String> userAtRealm, final RemoteLookupOptions options){
if(userAtRealm == null || userAtRealm.getKey() == null){
throw new IllegalStateException("null values for user parameter not allowed");
}
final String user = userAtRealm.getKey();
final String realm = (userAtRealm.getValue()!=null?userAtRealm.getValue().toUpperCase():"DSV.SU.SE");
logger.debug("Starting remote lookup for: " + user + "@"+realm);
final Map<String, String> params = new HashMap<String, String>();
params.put("username", user);
params.put("realm", realm);
if(!doRemoteRequest(params,options))
return null;
final User u = userDao.getUserByUsername(user,realm);
if(u != null)
logger.info("Successfully imported user/username from remote system: " + user+"@"+realm+ " (id: " + u.getId()+") "+u.getUserNames());
else
logger.warn("Failed to import a valid user from remote system: "+userAtRealm);
return u;
}
}

@ -1,6 +1,13 @@
package se.su.dsv.scipro.json; package se.su.dsv.scipro.json;
/**
* Generic interface for Remote lookups.
* The recommended way of using this interface is to create specializations
* (see IUserLookupFromIdentifier for an example) that defines the actual parameterized types used, and implement those interfaces in concrete classes.
* @param <T> The return type specifier, implementations are urged to return a null value when a lookup fails.
* @param <E> The lookup parameter, use compound types to support querying on multiple parameters.
*/
public interface ILookup<T, E> { public interface ILookup<T, E> {
public T lookup(E lookupParam) throws Exception; public T lookup(final E lookupParam, final RemoteLookupOptions options);
} }

@ -1,5 +1,10 @@
package se.su.dsv.scipro.json; package se.su.dsv.scipro.json;
import java.io.IOException;
/**
* Interface for delegated callback handling of response-strings.
*/
public interface IResponseHandler { public interface IResponseHandler {
public void handleResponse(String response); public void handleResponse(final String response,final RemoteLookupOptions options) throws IOException;
} }

@ -1,7 +0,0 @@
package se.su.dsv.scipro.json;
import se.su.dsv.scipro.data.dataobjects.User;
public interface IUserLookup extends ILookup<User, String>{
public User lookup(String username) throws Exception;
}

@ -0,0 +1,11 @@
package se.su.dsv.scipro.json;
import se.su.dsv.scipro.data.dataobjects.User;
/**
* Lookup interface specification for remotely querying for User data.
* See ILookup for more information on the implicit contract of this interface.
*/
public interface IUserLookupFromIdentifier extends ILookup<User,Long>{
public User lookup(final Long identifier, final RemoteLookupOptions options);
}

@ -0,0 +1,13 @@
package se.su.dsv.scipro.json;
import se.su.dsv.scipro.data.dataobjects.User;
import se.su.dsv.scipro.util.KeyValuePair;
/**
* Lookup interface specification for remotely querying for User data.
* The supplied parameter is a KeyValuePair<String> where the key-field is the users username and the value-field is the users realm.
* See ILookup for more information on the implicit contract of this interface.
*/
public interface IUserLookupFromUsername extends ILookup<User,KeyValuePair<String>>{
public User lookup(final KeyValuePair<String> userAtRealm, final RemoteLookupOptions options);
}

@ -3,6 +3,8 @@ package se.su.dsv.scipro.json;
import java.lang.reflect.Type; import java.lang.reflect.Type;
import org.apache.log4j.Level; import org.apache.log4j.Level;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Component;
import se.su.dsv.scipro.jsonobjects.JsonUpdateStatsContainer; import se.su.dsv.scipro.jsonobjects.JsonUpdateStatsContainer;
import se.su.dsv.scipro.workerthreads.UserAndProjectImportWorker; import se.su.dsv.scipro.workerthreads.UserAndProjectImportWorker;
@ -12,20 +14,11 @@ import com.google.gson.reflect.TypeToken;
/** /**
* Handler for json responses regarding users (creating and updating) * Handler for json responses regarding users (creating and updating)
*
* @author Dan Kjellman <dan-kjel@dsv.su.se>
* *
*/ */
@Component
public class ImportUpdateStatsResponseHandler extends JsonResponseHandler { public class ImportUpdateStatsResponseHandler extends JsonResponseHandler {
private Logger logger = Logger.getLogger(ImportUpdateStatsResponseHandler.class);
private boolean logResult = false;
public ImportUpdateStatsResponseHandler(){
super();
}
/** /**
* Handles a json string * Handles a json string
* *
@ -34,7 +27,7 @@ public class ImportUpdateStatsResponseHandler extends JsonResponseHandler {
* *
* @param response the json string * @param response the json string
*/ */
public void handleResponse(String response) { public void handleResponse(final String response, final RemoteLookupOptions options) {
JsonUpdateStatsContainer statsContainer = null; JsonUpdateStatsContainer statsContainer = null;
try{ try{
Gson gson = new Gson(); Gson gson = new Gson();
@ -49,26 +42,5 @@ public class ImportUpdateStatsResponseHandler extends JsonResponseHandler {
UserAndProjectImportWorker.updatedUsers = statsContainer.updatedUsers.intValue(); UserAndProjectImportWorker.updatedUsers = statsContainer.updatedUsers.intValue();
UserAndProjectImportWorker.updatedTheses = statsContainer.updatedTheses.intValue(); UserAndProjectImportWorker.updatedTheses = statsContainer.updatedTheses.intValue();
} }
/*
if(logResult){
logger.log(Level.INFO, "\nResult from userimport/update:\nChecked: " + completeContainer.theses.size() + " users\n" +
"Changed users: " + changedUsers + "\n" +
"Created users: " + createdUsers + "\n" +
"Number of errors when creating users: " + userCreationErrors + "\n" +
"Num First name changes: " + getNumFirstNameChanges() + "\n" +
"Num last name changes: " + getNumLastNameChanges() + "\n" +
"Num Email changes: " + getNumEmailChanges() + "\n" +
"Num Usernames added: " + getNumUsernamesAdded() + "\n" +
"Num Supervisors created: " + getNumFirstNameChanges() + "\n");
}
*/
}
public void setLogResult(boolean logResult) {
this.logResult = logResult;
}
public boolean isLogResult() {
return logResult;
} }
} }

@ -5,36 +5,28 @@ import java.util.Date;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import org.apache.log4j.Level; import org.springframework.beans.factory.annotation.Autowired;
import org.apache.log4j.Logger; import org.springframework.stereotype.Component;
import se.su.dsv.scipro.ApplicationSettings; import se.su.dsv.scipro.ApplicationSettings;
/** /**
* This class does a lookup on a username against the remote remoteLookupUrl specified in * This class does a lookup on a username against the remote remoteLookupUrl specified in
* the applicationContext, under ApplicationSettings. * the applicationContext, under ApplicationSettings.
* *
* *
* @author Dan Kjellman <dan-kjel@dsv.su.se> * @author Dan Kjellman <dan-kjel@dsv.su.se>
*/ */
@Component
public class ImportWorkerLookup { public class ImportWorkerLookup {
public static final String USERS = "users"; public static final String USERS = "users";
public static final String THESES = "theses"; public static final String THESES = "theses";
/* @Autowired
* References populated by spring (from applicationContext) private ImportWorkerResponseHandler importWorkerResponseHandler;
*/ @Autowired
private ImportWorkerResponseHandler thesesResponseHandler; private ImportUpdateStatsResponseHandler importUpdateStatsResponseHandler;
private ImportUpdateStatsResponseHandler statsResonseHandler; @Autowired
private ApplicationSettings settings; private ApplicationSettings applicationSettings;
private Logger logger;
public ImportWorkerLookup(){
logger = Logger.getRootLogger();
}
public void lookup(Date updatedAfter, String type) throws IOException{ public void lookup(Date updatedAfter, String type) throws IOException{
lookup(-1,-1, updatedAfter, type); lookup(-1,-1, updatedAfter, type);
@ -60,7 +52,7 @@ public class ImportWorkerLookup {
}else{ }else{
//logger.log(Level.INFO,"Starting lookup for completeGet=true & type="+type+" & updatedAfter=" + updatedAfter); //logger.log(Level.INFO,"Starting lookup for completeGet=true & type="+type+" & updatedAfter=" + updatedAfter);
} }
RequestSender request = new RequestSender(thesesResponseHandler, settings.getRemoteLookupUrl(), params, RequestSender.REQUEST_TYPE_POST); RequestSender request = new RequestSender(importWorkerResponseHandler, applicationSettings.getRemoteLookupUrl(), params, new RemoteLookupOptions(), RequestSender.REQUEST_TYPE.POST);
try{ try{
request.processRequest(); request.processRequest();
} catch (IOException e) { } catch (IOException e) {
@ -74,7 +66,7 @@ public class ImportWorkerLookup {
params.put("updateStats", "true"); params.put("updateStats", "true");
params.put("updatedAfter",""+updatedAfter.getTime()); params.put("updatedAfter",""+updatedAfter.getTime());
RequestSender request = new RequestSender(statsResonseHandler, settings.getRemoteLookupUrl(), params, RequestSender.REQUEST_TYPE_POST); RequestSender request = new RequestSender(importUpdateStatsResponseHandler, applicationSettings.getRemoteLookupUrl(), params, new RemoteLookupOptions(), RequestSender.REQUEST_TYPE.POST);
try{ try{
request.processRequest(); request.processRequest();
} catch (IOException e) { } catch (IOException e) {
@ -82,34 +74,4 @@ public class ImportWorkerLookup {
throw e; throw e;
} }
} }
/*
* Getters and setters (for spring)
*/
public ImportWorkerResponseHandler getUserResponseHandler() {
return thesesResponseHandler;
}
public void setUserResponseHandler(ImportWorkerResponseHandler thesesResponseHandler) {
this.thesesResponseHandler = thesesResponseHandler;
}
public ApplicationSettings getSettings() {
return settings;
}
public void setSettings(ApplicationSettings settings) {
this.settings = settings;
}
public ImportUpdateStatsResponseHandler getStatsResonseHandler() {
return statsResonseHandler;
}
public void setStatsResonseHandler(
ImportUpdateStatsResponseHandler statsResonseHandler) {
this.statsResonseHandler = statsResonseHandler;
}
} }

@ -1,8 +1,11 @@
package se.su.dsv.scipro.json; package se.su.dsv.scipro.json;
import java.io.IOException;
import java.lang.reflect.Type; import java.lang.reflect.Type;
import org.apache.log4j.Level; import org.apache.log4j.Level;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Component;
import se.su.dsv.scipro.data.dataobjects.Project; import se.su.dsv.scipro.data.dataobjects.Project;
import se.su.dsv.scipro.data.dataobjects.User; import se.su.dsv.scipro.data.dataobjects.User;
@ -21,16 +24,9 @@ import com.google.gson.reflect.TypeToken;
* @author Dan Kjellman <dan-kjel@dsv.su.se> * @author Dan Kjellman <dan-kjel@dsv.su.se>
* *
*/ */
@Component
public class ImportWorkerResponseHandler extends JsonResponseHandler { public class ImportWorkerResponseHandler extends JsonResponseHandler {
private Logger logger = Logger.getLogger(ImportWorkerResponseHandler.class);
private boolean logResult = false;
public ImportWorkerResponseHandler(){
super();
}
/** /**
* Handles a json string * Handles a json string
* *
@ -39,7 +35,7 @@ public class ImportWorkerResponseHandler extends JsonResponseHandler {
* *
* @param response the json string * @param response the json string
*/ */
public void handleResponse(String response) { public void handleResponse(final String response, final RemoteLookupOptions options) throws IOException {
JsonCompleteGetContainer completeContainer = null; JsonCompleteGetContainer completeContainer = null;
try{ try{
Gson gson = new Gson(); Gson gson = new Gson();
@ -48,7 +44,7 @@ public class ImportWorkerResponseHandler extends JsonResponseHandler {
} catch (Exception e) { } catch (Exception e) {
logger.log(Level.FATAL, "Gson error when creating objects from json \n" + e.getMessage()); logger.log(Level.FATAL, "Gson error when creating objects from json \n" + e.getMessage());
return; throw new IOException(e);
} }
int createdUsers = 0; int createdUsers = 0;
int changedUsers = 0; int changedUsers = 0;
@ -106,7 +102,7 @@ public class ImportWorkerResponseHandler extends JsonResponseHandler {
if(user == null){ if(user == null){
createThesisUser(jsonUser, false); createThesisUser(jsonUser, new RemoteLookupOptions());
}else{ }else{
lookForChangesInUserAndSave(jsonUser); lookForChangesInUserAndSave(jsonUser);
} }
@ -117,7 +113,7 @@ public class ImportWorkerResponseHandler extends JsonResponseHandler {
if(project == null){ if(project == null){
//System.out.println("User does not exist... trying to create"); //System.out.println("User does not exist... trying to create");
if(null == checkAndCreateProject(jsonThesis)){ if(null == checkAndCreateProject(jsonThesis,options)){
thesesCreationsErrors++; thesesCreationsErrors++;
} else { } else {
thesesCreations++; thesesCreations++;
@ -129,8 +125,8 @@ public class ImportWorkerResponseHandler extends JsonResponseHandler {
} }
} }
if(logResult){ if(isLogResult()){
logger.log(Level.INFO, "\nResult from userimport/update:\nChecked: " + completeContainer.users.size() + " users\n" + logger.info("\nResult from userimport/update:\nChecked: " + completeContainer.users.size() + " users\n" +
"Changed users: " + changedUsers + "\n" + "Changed users: " + changedUsers + "\n" +
"Created users: " + createdUsers + "\n" + "Created users: " + createdUsers + "\n" +
"Number of errors when creating users: " + userCreationErrors + "\n" + "Number of errors when creating users: " + userCreationErrors + "\n" +
@ -147,12 +143,4 @@ public class ImportWorkerResponseHandler extends JsonResponseHandler {
"Number of errors when creating theses: " + thesesCreationsErrors + "\n" ); "Number of errors when creating theses: " + thesesCreationsErrors + "\n" );
} }
} }
public void setLogResult(boolean logResult) {
this.logResult = logResult;
}
public boolean isLogResult() {
return logResult;
}
} }

@ -1,16 +1,14 @@
package se.su.dsv.scipro.json; package se.su.dsv.scipro.json;
import java.io.IOException;
import java.util.Date; import java.util.Date;
import java.util.Iterator; import java.util.Iterator;
import java.util.SortedSet; import java.util.SortedSet;
import java.util.TreeSet; import java.util.TreeSet;
import org.apache.log4j.Level;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
import org.apache.wicket.spring.injection.annot.SpringBean;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component; import org.springframework.dao.DataAccessException;
import org.springframework.transaction.TransactionStatus;
import se.su.dsv.scipro.ApplicationSettings; import se.su.dsv.scipro.ApplicationSettings;
import se.su.dsv.scipro.data.dao.interfaces.ProjectClassDao; import se.su.dsv.scipro.data.dao.interfaces.ProjectClassDao;
@ -33,13 +31,11 @@ import se.su.dsv.scipro.jsonobjects.JsonThesisParticipant;
import se.su.dsv.scipro.jsonobjects.JsonUser; import se.su.dsv.scipro.jsonobjects.JsonUser;
import se.su.dsv.scipro.jsonobjects.JsonUserRole; import se.su.dsv.scipro.jsonobjects.JsonUserRole;
import se.su.dsv.scipro.jsonobjects.JsonUsername; import se.su.dsv.scipro.jsonobjects.JsonUsername;
/**
@Component * Package-private base class for JsonResponseHandlers.
public abstract class JsonResponseHandler implements IResponseHandler { * Contains a number of utility methods to lessen boilerplate code inside implementations.
*/
/* abstract class JsonResponseHandler implements IResponseHandler {
* References populated by spring
*/
@Autowired @Autowired
protected UserDao userDao; protected UserDao userDao;
@Autowired @Autowired
@ -52,12 +48,12 @@ public abstract class JsonResponseHandler implements IResponseHandler {
protected ProjectFollowerDao projectFollowerDao; protected ProjectFollowerDao projectFollowerDao;
@Autowired @Autowired
protected RoleDao roleDao; protected RoleDao roleDao;
@SpringBean(name="userLookup") @Autowired
protected IUserLookup userLookup; protected IUserLookupFromIdentifier userLookupFromIdentifier;
@Autowired
protected ApplicationSettings settings; protected ApplicationSettings applicationSettings;
protected Logger logger; private Logger logger = Logger.getLogger(JsonResponseHandler.class);
private int numUsersCreated = 0; private int numUsersCreated = 0;
private int numEmailChanges = 0; private int numEmailChanges = 0;
@ -67,169 +63,137 @@ public abstract class JsonResponseHandler implements IResponseHandler {
private int numSupervisorsCreated = 0; private int numSupervisorsCreated = 0;
private int numThesesCreated = 0; private int numThesesCreated = 0;
private int numThesesChanged = 0; private int numThesesChanged = 0;
private boolean logResult = false;
public JsonResponseHandler(){
super();
logger = Logger.getRootLogger();
}
/** /**
* Creates a thesis user from a json user * Creates and persists a User from a JsonUser
* * @param jsonUser the JsonUser to use for creation
* @param jsonUser the json user to use for creation * @param doFullCheck If true, checkAndCreateProject will be called on each project included in the query response.
* @return User the create thesisuser * @return The created User or null if it cannot be persisted.
*/ */
protected User createThesisUser(JsonUser jsonUser, boolean doFullCheck){ protected User createThesisUser(final JsonUser jsonUser, final RemoteLookupOptions options){
User user = new User();
TransactionStatus status = null; user.setFirstName(jsonUser.firstName);
User thesisUser = null; user.setLastName(jsonUser.lastName);
user.setIdentifier(jsonUser.id);
try { user.setEmailAddress(jsonUser.email);
thesisUser = new User(); try{
thesisUser.setFirstName(jsonUser.firstName); user = userDao.save(user);
thesisUser.setLastName(jsonUser.lastName); }catch(final DataAccessException dae){
thesisUser.setIdentifier(jsonUser.id); logger.error("Cannot save User with jsonuserid: " + jsonUser.id);
thesisUser.setEmailAddress(jsonUser.email); return null;
//System.out.println("Trying to save " + thesisUser.getIdentifier());
thesisUser = userDao.save(thesisUser);
/*
* Check against daisy if the user is a supervisor - if so, create a supervisor role
*/
for(JsonUserRole jur : jsonUser.roles){
if(jur.role.equals("AUTHOR")){
roleDao.makeStudent(thesisUser);
}
if(jur.role.equals("SUPERVISOR")){
roleDao.makeEmployee(thesisUser);
}
if(jur.role.equals("ADMIN")){
// roleDao.makeAdmin(thesisUser);
}
}
for(JsonUsername jsonUsername : jsonUser.usernames){
Username thesisUserName = new Username();
thesisUserName.setUserName(jsonUsername.username.toLowerCase().trim());
thesisUserName.setRealm(jsonUsername.realm.toUpperCase().trim());
thesisUserName.setUser(thesisUser);
thesisUserName = userNameDao.save(thesisUserName);
}
if(doFullCheck){
for(JsonThesis jThesis : jsonUser.theses){
checkAndCreateProject(jThesis);
}
}
numUsersCreated++;
} }
catch (Exception e){ /*
logger.log(Level.ERROR, "Cannot save jsonuser with jsonuserid: " + jsonUser.id + " - Rolling back...\n" + e.getMessage()); * Check against remote system data if the user is a supervisor - if so, create a supervisor role
throw new RuntimeException(e); */
for(JsonUserRole jur : jsonUser.roles){
if(jur.role.equals("AUTHOR")){
roleDao.makeStudent(user);
}
if(jur.role.equals("SUPERVISOR")){
roleDao.makeEmployee(user);
}
if(jur.role.equals("ADMIN")){
// roleDao.makeAdmin(thesisUser);
}
} }
return thesisUser; /*
* Create and set the user's usernames
*/
for(JsonUsername jsonUsername : jsonUser.usernames){
Username userName = new Username();
userName.setUserName(jsonUsername.username.toLowerCase().trim());
userName.setRealm(jsonUsername.realm.toUpperCase().trim());
userName.setUser(user);
userName = userNameDao.save(userName);
if(userName == null)
logger.error("Cannot save Username '"+jsonUsername.username+"' for User '"+user.getIdentifier()+"'");
}
/*
* Create any projects of which the user is a member of
*/
if(options.getLookupDepth().equals(RemoteLookupOptions.LOOKUP_DEPTH.PROJECT_AND_PARTICIPANTS)){
for(JsonThesis jThesis : jsonUser.theses){
checkAndCreateProject(jThesis, options);
}
}
numUsersCreated++;
return user;
} }
/**
* Retrieve a Project matching the given JsonThesis ID, and create a project matching the supplied JsonThesis in full if it does not already exists.
* @param jThesis
protected Project checkAndCreateProject(JsonThesis jThesis) { * @return The retrieved (or newly created) project.
*/
Project project = null; protected Project checkAndCreateProject(JsonThesis jThesis, final RemoteLookupOptions options) {
Project project = null;
//System.out.println("Creating project:" + jThesis.thesisID); project = projectDao.getProjectByIdentifier(jThesis.thesisID);
project = projectDao.getProjectByIdentifier(jThesis.thesisID); if(project == null){
if(project == null){ project = new Project();
project = new Project(); project.setIdentifier(jThesis.thesisID);
project.setIdentifier(jThesis.thesisID); project.setTitle(jThesis.title);
project.setTitle(jThesis.title); if(jThesis.status.equals("STARTED") || jThesis.status.equals("LATE")){
if(jThesis.status.equals("STARTED") || jThesis.status.equals("LATE")){ project.setProjectStatus(ProjectStatus.ACTIVE);
project.setProjectStatus(ProjectStatus.ACTIVE); }else if(jThesis.status.equals("FINISHED")){
}else if(jThesis.status.equals("FINISHED")){ project.setProjectStatus(ProjectStatus.COMPLETED);
project.setProjectStatus(ProjectStatus.COMPLETED); }else{
}else{ project.setProjectStatus(ProjectStatus.INACTIVE);
project.setProjectStatus(ProjectStatus.INACTIVE); }
} ProjectClass pc = getProjectClass(jThesis.type);
ProjectClass pc = getProjectClass(jThesis.type); project.setProjectClass(pc);
project.setProjectClass(pc); if(jThesis.daisyStartDate > 0){
if(jThesis.daisyStartDate > 0){ Date daisyStartDate = new Date(jThesis.daisyStartDate);
Date daisyStartDate = new Date(jThesis.daisyStartDate); project.setDaisyStartDate(daisyStartDate);
project.setDaisyStartDate(daisyStartDate); }
project = projectDao.save(project);
} //Synch participants
project = projectDao.save(project); if(options.getLookupDepth().equals(RemoteLookupOptions.LOOKUP_DEPTH.PROJECT_AND_PARTICIPANTS)){
for(JsonThesisParticipant jtp : jThesis.participants){ for(JsonThesisParticipant jtp : jThesis.participants){
User u = userDao.getUserByIdentifier(jtp.id); User u = userDao.getUserByIdentifier(jtp.id);
//Attempt remote lookup if no user is found
if(u == null){ if(u == null){
String id = String.valueOf(jtp.id); final Long id = Long.valueOf(jtp.id);
try { if( (u = userLookupFromIdentifier.lookup(id, new RemoteLookupOptions(RemoteLookupOptions.LOOKUP_DEPTH.NONE))) == null){
u = userLookup.lookup(id); logger.warn("Cannot create jsonuser with jsonuserid: " + jtp.id+" while adding participants for the project: "+project.getIdentifier());
} catch (Exception e) { continue;
logger.log(Level.ERROR, "Cannot save jsonuser with jsonuserid: " + jtp.id + " - Rolling back...\n" + e.getMessage());
throw new RuntimeException(e);
} }
u = userDao.getUserByIdentifier(jtp.id);
} }
//Move on, set participant roles
if(jtp.role.equals("SUPERVISOR")){
if(u != null){ Employee e = roleDao.makeEmployee(u);
if(jtp.role.equals("SUPERVISOR")){ project.setHeadSupervisor(e);
Employee e = roleDao.makeEmployee(u); }else if(jtp.role.equals("PARTICIPANT")){
project.setHeadSupervisor(e); Student s = roleDao.makeStudent(u);
}else if(jtp.role.equals("PARTICIPANT")){ project.getProjectParticipants().add(s);
Student s = roleDao.makeStudent(u); }else{
project.getProjectParticipants().add(s); ProjectFollower pf = new ProjectFollower();
if(jtp.role.equals("ASSISTANT_SUPERVISOR")){
pf.setProjectRole(ProjectTeamMemberRoles.CO_SUPERVISOR);
pf.setFollower((Employee)roleDao.makeEmployee(u));
}else if(jtp.role.equals("OPPONENT")){
//TODO: OPPONENT
}else if (jtp.role.equals("EXAMINER")){
pf.setProjectRole(ProjectTeamMemberRoles.REVIEWER);
pf.setFollower(roleDao.makeEmployee(u));
} }
else{ if(pf.getFollower() != null && pf.getProjectRole() != null){
ProjectFollower pf = new ProjectFollower(); pf.setProject(project);
pf = projectFollowerDao.save(pf);
if(jtp.role.equals("ASSISTANT_SUPERVISOR")){ project.getProjectFollowers().add(pf);
pf.setProjectRole(ProjectTeamMemberRoles.CO_SUPERVISOR);
pf.setFollower((Employee)roleDao.makeEmployee(u));
}else if(jtp.role.equals("OPPONENT")){
//TODO: OPPONENT
}else if (jtp.role.equals("EXAMINER")){
pf.setProjectRole(ProjectTeamMemberRoles.REVIEWER);
pf.setFollower(roleDao.makeEmployee(u));
}
if(pf.getFollower() != null && pf.getProjectRole() != null){
pf.setProject(project);
pf = projectFollowerDao.save(pf);
project.getProjectFollowers().add(pf);
}
} }
} }
} }
project = projectDao.save(project); project = projectDao.save(project);
/*
try{
txManager.commit(status);
}catch(TransactionException e){
logger.log(Level.ERROR, "Cannot commit transaction with projectid:"+project.getId() + " - Rolling back...\n" + e.getMessage());
txManager.rollback(status);
throw e;
}
*/
} }
project = null; }
project = projectDao.getProjectByIdentifier(jThesis.thesisID); project = projectDao.getProjectByIdentifier(jThesis.thesisID);
return project; return project;
} }
/** /**
* Look for changes in a jsonuser against a thesisuser. BEWARE: you need to be sure that * Look for changes in a jsonuser against a User.
* a corresponding thesisuser exists, or an exception will be thrown * @note you need to be sure that a corresponding User exists, or a (potentially wrapped) Runtime exception will be thrown
* * @param jsonUser
* @param daisyUser
* @return * @return
*/ */
protected boolean lookForChangesInUserAndSave(JsonUser jsonUser){ protected boolean lookForChangesInUserAndSave(JsonUser jsonUser){
@ -277,16 +241,16 @@ public abstract class JsonResponseHandler implements IResponseHandler {
try { try {
checkAndChangeProject(current, jThesis); checkAndChangeProject(current, jThesis);
} catch (Exception e) { } catch (Exception e) {
logger.log(Level.FATAL, "Error when checking project:" + current.getId()+ "when looking up user:" logger.error("Error when checking project:" + current.getId()+ "when looking up user:"
+jsonUser.firstName+ " "+jsonUser.lastName+" \n" + e.getMessage()); +jsonUser.firstName+ " "+jsonUser.lastName+" \n" + e.getMessage());
throw new RuntimeException(e); throw new RuntimeException(e);
} }
}else{ }else{
try { try {
checkAndCreateProject(jThesis); checkAndCreateProject(jThesis,new RemoteLookupOptions());
} catch (Exception e) { } catch (Exception e) {
logger.log(Level.FATAL, "Error when creating project: daisyId=" + jThesis.thesisID + "when looking up user:" logger.error("Error when creating project: daisyId=" + jThesis.thesisID + "when looking up user:"
+jsonUser.firstName+ " "+jsonUser.lastName+" \n" + e.getMessage()); +jsonUser.firstName+ " "+jsonUser.lastName+" \n" + e.getMessage());
throw new RuntimeException(e); throw new RuntimeException(e);
} }
@ -328,7 +292,7 @@ public abstract class JsonResponseHandler implements IResponseHandler {
return true; return true;
} catch (Exception e){ } catch (Exception e){
logger.log(Level.FATAL, "Failed to save changes for user:" + thesisUser.getIdentifier() + " - Rolling back...\n" + e.getMessage()); logger.error("Failed to save changes for user:" + thesisUser.getIdentifier() + " - Rolling back...\n" + e.getMessage());
throw new RuntimeException(e); throw new RuntimeException(e);
} }
} }
@ -415,11 +379,11 @@ public abstract class JsonResponseHandler implements IResponseHandler {
for(JsonThesisParticipant jtp : jThesis.participants){ for(JsonThesisParticipant jtp : jThesis.participants){
User u = userDao.getUserByIdentifier(jtp.id); User u = userDao.getUserByIdentifier(jtp.id);
if(u == null){ if(u == null){
String id = String.valueOf(jtp.id); final Long id = Long.valueOf(jtp.id);
try { try {
u = userLookup.lookup(id); u = userLookupFromIdentifier.lookup(id, new RemoteLookupOptions(RemoteLookupOptions.LOOKUP_DEPTH.NONE));
} catch (Exception e) { } catch (Exception e) {
logger.log(Level.FATAL, "Failed to save changes for project:" + current.getIdentifier() + " when looking up user whith idetifier:"+jtp.id+ logger.error("Failed to save changes for project:" + current.getIdentifier() + " when looking up user with identifier:"+jtp.id+
" Rolling back...\n" + e.getMessage()); " Rolling back...\n" + e.getMessage());
throw new RuntimeException(e); throw new RuntimeException(e);
} }
@ -442,7 +406,7 @@ public abstract class JsonResponseHandler implements IResponseHandler {
followers.add(pf); followers.add(pf);
} }
}else{ }else{
logger.log(Level.FATAL, "Failed to save changes for project:" + current.getIdentifier() + "u = null when looking up user whith idetifier:"+jtp.id+ logger.error("Failed to save changes for project:" + current.getIdentifier() + "u = null when looking up user whith idetifier:"+jtp.id+
"- \n Rolling back...\n"); "- \n Rolling back...\n");
} }
} }
@ -491,17 +455,15 @@ public abstract class JsonResponseHandler implements IResponseHandler {
projectDao.save(current); projectDao.save(current);
} }
}catch (Exception e){ }catch (Exception e){
logger.log(Level.FATAL, "Failed to save changes for project:" + current.getIdentifier() + " - Rolling back...\n" + e.getMessage()); logger.error("Failed to save changes for project:" + current.getIdentifier() + " - Rolling back...\n" + e.getMessage());
throw new RuntimeException(e); throw new RuntimeException(e);
} }
return changed; return changed;
} }
/* /*
* Force subclasses to handle the response * Force subclasses to handle the response
*/ */
public abstract void handleResponse(String response); public abstract void handleResponse(final String response, final RemoteLookupOptions options) throws IOException;
/* /*
* Getters for logging * Getters for logging
@ -510,27 +472,22 @@ public abstract class JsonResponseHandler implements IResponseHandler {
return numUsersCreated; return numUsersCreated;
} }
public int getNumEmailChanges() { public int getNumEmailChanges() {
return numEmailChanges; return numEmailChanges;
} }
public int getNumFirstNameChanges() { public int getNumFirstNameChanges() {
return numFirstNameChanges; return numFirstNameChanges;
} }
public int getNumLastNameChanges() { public int getNumLastNameChanges() {
return numLastNameChanges; return numLastNameChanges;
} }
public int getNumUsernamesAdded() { public int getNumUsernamesAdded() {
return numUsernamesAdded; return numUsernamesAdded;
} }
public int getNumSupervisorsCreated() { public int getNumSupervisorsCreated() {
return numSupervisorsCreated; return numSupervisorsCreated;
} }
@ -539,56 +496,20 @@ public abstract class JsonResponseHandler implements IResponseHandler {
return numThesesCreated; return numThesesCreated;
} }
public void setNumThesesCreated(int numThesesCreated) {
this.numThesesCreated = numThesesCreated;
}
public int getNumThesesChanged() { public int getNumThesesChanged() {
return numThesesChanged; return numThesesChanged;
} }
/**
* Sets parameter to increase logging output.
public void setNumThesesChanged(int numThesesChanged) { * @param logResult
this.numThesesChanged = numThesesChanged;
}
/*
* Getters and setters (for spring)
*/ */
public UserDao getUserDao() { public void setLogResult(boolean logResult) {
return userDao; this.logResult = logResult;
} }
/**
public void setUserDao(UserDao userDao) { * Getter for increased logging output.
this.userDao = userDao; */
} public boolean isLogResult() {
return logResult;
public UsernameDao getUsernameDao() {
return userNameDao;
}
public void setUserNameDao(UsernameDao usernameDao) {
this.userNameDao = usernameDao;
}
public ApplicationSettings getSettings() {
return settings;
}
public void setSettings(ApplicationSettings settings) {
this.settings = settings;
}
public IUserLookup getUserLookup() {
return userLookup;
}
public void setUserLookup(IUserLookup userLookup) {
this.userLookup = userLookup;
} }
} }

@ -3,6 +3,8 @@ package se.su.dsv.scipro.json;
import java.lang.reflect.Type; import java.lang.reflect.Type;
import org.apache.log4j.Level; import org.apache.log4j.Level;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Component;
import se.su.dsv.scipro.data.dataobjects.User; import se.su.dsv.scipro.data.dataobjects.User;
import se.su.dsv.scipro.data.dataobjects.Username; import se.su.dsv.scipro.data.dataobjects.Username;
@ -19,15 +21,9 @@ import com.google.gson.reflect.TypeToken;
* @author Dan Kjellman <dan-kjel@dsv.su.se> * @author Dan Kjellman <dan-kjel@dsv.su.se>
* *
*/ */
//@Component @Component
public class JsonUserFullResponseHandler extends JsonResponseHandler { public class JsonUserFullResponseHandler extends JsonResponseHandler {
private Logger logger = Logger.getLogger(JsonUserFullResponseHandler.class);
private boolean logResult = false;
public JsonUserFullResponseHandler(){
super();
}
/** /**
* Handles a json string * Handles a json string
* *
@ -36,7 +32,7 @@ public class JsonUserFullResponseHandler extends JsonResponseHandler {
* *
* @param response the json string * @param response the json string
*/ */
public void handleResponse(String response) { public void handleResponse(final String response, final RemoteLookupOptions options) {
JsonUserContainer userContainer = null; JsonUserContainer userContainer = null;
try{ try{
@ -56,13 +52,11 @@ public class JsonUserFullResponseHandler extends JsonResponseHandler {
//Loop all users in the response and look for changes... //Loop all users in the response and look for changes...
for(JsonUser jsonUser : userContainer.users){ for(JsonUser jsonUser : userContainer.users){
System.out.println("Checking: " + " id: " + jsonUser.id + " firstName: "+ jsonUser.firstName); logger.debug("Checking: " + jsonUser);
User thesisUser = userDao.getUserByIdentifier(new Long(jsonUser.id)); User thesisUser = userDao.getUserByIdentifier(new Long(jsonUser.id));
for(JsonUsername jsonUsername : jsonUser.usernames){ for(JsonUsername jsonUsername : jsonUser.usernames){
logger.debug("\t"+jsonUsername.username);
System.out.println(jsonUsername.username);
String usernameString = jsonUsername.username.toLowerCase().trim(); String usernameString = jsonUsername.username.toLowerCase().trim();
String userRealmString = jsonUsername.realm.toUpperCase().trim(); String userRealmString = jsonUsername.realm.toUpperCase().trim();
User potentialDuplicateUser = userDao.getUserByUsername(usernameString, userRealmString); User potentialDuplicateUser = userDao.getUserByUsername(usernameString, userRealmString);
@ -112,7 +106,7 @@ public class JsonUserFullResponseHandler extends JsonResponseHandler {
if(thesisUser == null){ if(thesisUser == null){
//System.out.println("User does not exist... trying to create"); //System.out.println("User does not exist... trying to create");
if(null == createThesisUser(jsonUser,true)){ if(null == createThesisUser(jsonUser,options)){
userCreationErrors++; userCreationErrors++;
} else { } else {
createdUsers++; createdUsers++;
@ -124,8 +118,7 @@ public class JsonUserFullResponseHandler extends JsonResponseHandler {
} }
} }
} }
if(isLogResult()){
if(logResult){
logger.log(Level.INFO, "\nResult from userimport/update:\nChecked: " + userContainer.users.size() + " users\n" + logger.log(Level.INFO, "\nResult from userimport/update:\nChecked: " + userContainer.users.size() + " users\n" +
"Changed users: " + changedUsers + "\n" + "Changed users: " + changedUsers + "\n" +
"Created users: " + createdUsers + "\n" + "Created users: " + createdUsers + "\n" +
@ -137,12 +130,4 @@ public class JsonUserFullResponseHandler extends JsonResponseHandler {
"Num Supervisors created: " + getNumFirstNameChanges() + "\n"); "Num Supervisors created: " + getNumFirstNameChanges() + "\n");
} }
} }
public void setLogResult(boolean logResult) {
this.logResult = logResult;
}
public boolean isLogResult() {
return logResult;
}
} }

@ -2,7 +2,7 @@ package se.su.dsv.scipro.json;
import java.lang.reflect.Type; import java.lang.reflect.Type;
import org.apache.log4j.Level; import org.apache.log4j.Logger;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import se.su.dsv.scipro.data.dataobjects.User; import se.su.dsv.scipro.data.dataobjects.User;
@ -20,13 +20,7 @@ import com.google.gson.reflect.TypeToken;
*/ */
@Component @Component
public class JsonUserResponseHandler extends JsonResponseHandler { public class JsonUserResponseHandler extends JsonResponseHandler {
private Logger logger = Logger.getLogger(JsonUserResponseHandler.class);
private boolean logResult = false;
public JsonUserResponseHandler(){
super();
}
/** /**
* Handles a json string * Handles a json string
* *
@ -35,16 +29,16 @@ public class JsonUserResponseHandler extends JsonResponseHandler {
* *
* @param response the json string * @param response the json string
*/ */
public void handleResponse(String response) { public void handleResponse(final String response, final RemoteLookupOptions options) {
JsonUserContainer userContainer = null; JsonUserContainer userContainer = null;
logger.debug(response);
try{ try{
Gson gson = new Gson(); Gson gson = new Gson();
Type type = new TypeToken<JsonUserContainer>(){}.getType(); Type type = new TypeToken<JsonUserContainer>(){}.getType();
userContainer = gson.fromJson(response, type); userContainer = gson.fromJson(response, type);
} catch (Exception e) { } catch (Exception e) {
logger.log(Level.FATAL, "Gson error when creating objects from json \n" + e.getMessage()); logger.error("Gson error when creating objects from json response" + e.getMessage());
logger.error("Full response from remote:" + response);
return; return;
} }
int createdUsers = 0; int createdUsers = 0;
@ -53,26 +47,25 @@ public class JsonUserResponseHandler extends JsonResponseHandler {
//Loop all users in the response and look for changes... //Loop all users in the response and look for changes...
for(JsonUser jsonUser : userContainer.users){ for(JsonUser jsonUser : userContainer.users){
//System.out.println("Checking: " + " id: " + daisyUser.id + " firstName: "+ daisyUser.firstName); logger.debug("Checking " + jsonUser.id);
User thesisUser = userDao.getUserByIdentifier(new Long(jsonUser.id)); User thesisUser = userDao.getUserByIdentifier(Long.valueOf(jsonUser.id));
if(thesisUser == null){ if(thesisUser == null){
//System.out.println("User does not exist... trying to create"); logger.debug("User '"+jsonUser.id+ "' does not exist locally, trying to create");
if(null == createThesisUser(jsonUser,false)){ if(null == createThesisUser(jsonUser,options)){
userCreationErrors++; userCreationErrors++;
} else { } else {
createdUsers++; createdUsers++;
} }
} else { } else {
//System.out.println("User found, looking for changes..."); logger.debug("User found, looking for changes...");
if(lookForChangesInUserAndSave(jsonUser)){ if(lookForChangesInUserAndSave(jsonUser)){
changedUsers++; changedUsers++;
} }
} }
} }
if(logResult){ if(isLogResult()){
logger.log(Level.INFO, "\nResult from userimport/update:\nChecked: " + userContainer.users.size() + " users\n" + logger.info("Result from userimport/update:\nChecked: " + userContainer.users.size() + " users\n" +
"Changed users: " + changedUsers + "\n" + "Changed users: " + changedUsers + "\n" +
"Created users: " + createdUsers + "\n" + "Created users: " + createdUsers + "\n" +
"Number of errors when creating users: " + userCreationErrors + "\n" + "Number of errors when creating users: " + userCreationErrors + "\n" +
@ -83,12 +76,4 @@ public class JsonUserResponseHandler extends JsonResponseHandler {
"Num Supervisors created: " + getNumFirstNameChanges() + "\n"); "Num Supervisors created: " + getNumFirstNameChanges() + "\n");
} }
} }
public void setLogResult(boolean logResult) {
this.logResult = logResult;
}
public boolean isLogResult() {
return logResult;
}
} }

@ -0,0 +1,19 @@
package se.su.dsv.scipro.json;
/**
* Option object for controlling remote requests, considered an anti-pattern at this point and
* needs re-design.
*/
public final class RemoteLookupOptions {
public enum LOOKUP_DEPTH{NONE,PROJECT_AND_PARTICIPANTS};
private final LOOKUP_DEPTH depth;
public RemoteLookupOptions(){
this(LOOKUP_DEPTH.NONE);
}
public RemoteLookupOptions(final LOOKUP_DEPTH depth){
this.depth = depth;
}
public LOOKUP_DEPTH getLookupDepth(){
return depth;
}
}

@ -9,8 +9,6 @@ import java.net.URL;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import javax.net.ssl.HttpsURLConnection;
import org.apache.log4j.Level; import org.apache.log4j.Level;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
@ -20,66 +18,40 @@ import org.apache.log4j.Logger;
* @author Dan Kjellman * @author Dan Kjellman
* *
*/ */
public class RequestSender { public final class RequestSender {
public static final int REQUEST_TYPE_POST = 0; public enum REQUEST_TYPE{POST,GET};
public static final int REQUEST_TYPE_GET = 1; private final REQUEST_TYPE requestType;
public static final String[] REQUEST_METHODS = new String[]{ private Logger logger = Logger.getLogger(RequestSender.class);
"POST", "GET"
};
private Logger logger;
/* /*
* The Handler for the response * The Handler for the response
*/ */
protected IResponseHandler responseHandler; private IResponseHandler responseHandler;
/* /*
* The params * The params
*/ */
protected Map<String, String> parameters; private Map<String, String> parameters;
/* /*
* The url to call * The url to call
*/ */
protected String url; private String url;
//Options for performed lookups
private final RemoteLookupOptions remoteLookupOptions;
/* public RequestSender(final IResponseHandler responseHandler, final String url, final Map<String, String> parameters, final RemoteLookupOptions options, final REQUEST_TYPE requestType){
* Type of request, use the static variables REQUEST_TYPE_POST or REQUEST_TYPE_GET
*/
protected int requestType;
public RequestSender(IResponseHandler responseHandler, String url, Map<String, String> parameters, int requestType){
logger = Logger.getRootLogger();
if(requestType != REQUEST_TYPE_GET && requestType != REQUEST_TYPE_POST){
logger.log(Level.ERROR, "Could not send request, no request type specified");
throw new IllegalArgumentException("Bad request type");
}
if(responseHandler == null){ if(responseHandler == null){
logger.log(Level.ERROR, "Could not send request, no response handler was provided"); logger.log(Level.ERROR, "Could not send request, no response handler was provided");
throw new IllegalArgumentException("You need no provide a handler for the response"); throw new IllegalArgumentException("You need no provide a handler for the response");
} }
remoteLookupOptions = (options==null?new RemoteLookupOptions():options);
this.responseHandler = responseHandler; this.responseHandler = responseHandler;
this.url = url; this.url = url;
this.parameters = parameters; this.parameters = parameters;
this.requestType = requestType; this.requestType = requestType;
} }
public RequestSender(IResponseHandler responseHandler, String url){ public RequestSender(IResponseHandler responseHandler, String url){
this(responseHandler,url,new HashMap<String,String>(),null,REQUEST_TYPE.GET);
if(responseHandler == null){
throw new IllegalArgumentException("You need no provide a handler for the response");
}
this.responseHandler = responseHandler;
this.url = url;
this.parameters = new HashMap<String, String>();
this.requestType = REQUEST_TYPE_GET;
} }
/** /**
@ -100,7 +72,7 @@ public class RequestSender {
count++; count++;
} }
if(requestType == REQUEST_TYPE_GET && parameters.size() > 0){ if(requestType == REQUEST_TYPE.GET && parameters.size() > 0){
url += "?" + parameterData; url += "?" + parameterData;
} }
@ -112,7 +84,7 @@ public class RequestSender {
URL u = new URL(url); URL u = new URL(url);
conn = (HttpURLConnection) u.openConnection(); conn = (HttpURLConnection) u.openConnection();
conn.setRequestMethod(REQUEST_METHODS[requestType]); conn.setRequestMethod(requestType.name());
/* /*
* Set connect timeout to 60 seconds and read timeout to 120 sec * Set connect timeout to 60 seconds and read timeout to 120 sec
@ -122,7 +94,7 @@ public class RequestSender {
conn.setConnectTimeout(1000 * 60); conn.setConnectTimeout(1000 * 60);
conn.setReadTimeout(1000 * 120); conn.setReadTimeout(1000 * 120);
if(requestType == REQUEST_TYPE_POST){ if(requestType == REQUEST_TYPE.POST){
conn.setDoOutput(true); conn.setDoOutput(true);
osr = new OutputStreamWriter(conn.getOutputStream()); osr = new OutputStreamWriter(conn.getOutputStream());
osr.write(parameterData); osr.write(parameterData);
@ -136,7 +108,7 @@ public class RequestSender {
while((line = br.readLine()) != null){ while((line = br.readLine()) != null){
response += line; response += line;
} }
responseHandler.handleResponse(response); responseHandler.handleResponse(response, remoteLookupOptions);
} catch (IOException e){ } catch (IOException e){
/* /*
@ -152,11 +124,9 @@ public class RequestSender {
if(conn != null){ if(conn != null){
conn.disconnect(); conn.disconnect();
} }
if(osr != null){ if(osr != null){
osr.close(); osr.close();
} }
if(br != null){ if(br != null){
br.close(); br.close();
} }

@ -34,7 +34,8 @@ public class JsonKeyAuthPage extends WebPage {
if (jsonLogin != null) { if (jsonLogin != null) {
String loginUsername = jsonLogin.username; String loginUsername = jsonLogin.username;
User user = userDao.getUserByUsername(loginUsername); //@ToDo Fix the apple-app to support non hard-coded realm
User user = userDao.getUserByUsername(loginUsername,"DSV.SU.SE");
if (user == null) { if (user == null) {
jsonOutput.addProperty("authenticated", false); jsonOutput.addProperty("authenticated", false);

@ -69,9 +69,9 @@ public class JsonLoginPage extends WebPage {
} }
if (loginUsername != null) { if (loginUsername != null) {
String username = jsonLogin.username; String username = jsonLogin.username;
User user = userDao.getUserByUsername(username); //@ToDo Fix the apple-app to support non hard-coded realm
User user = userDao.getUserByUsername(username,"DSV.SU.SE");
if (roleDao.isEmployee(user)) { if (roleDao.isEmployee(user)) {
jsonOutput.addProperty("authenticated", true); jsonOutput.addProperty("authenticated", true);
UserSettings userSettings = userSettingsDao.getUserSettings(user); UserSettings userSettings = userSettingsDao.getUserSettings(user);

@ -89,7 +89,7 @@ public class ReplyMessageModel implements IClusterable {
r.setToUser(originalMessage.getFromUser()); r.setToUser(originalMessage.getFromUser());
r.setPrivateMessage(pm); r.setPrivateMessage(pm);
r = recipientDao.save(r); r = recipientDao.save(r);
notificationController.notifyReplyPrivateMessage(originalMessage.getFromUser(), getReplySubject() +"\n\n" + getReplyText(), PrivateMessagesPage.getAbsoluteURL()); notificationController.notifyPrivateMessage(originalMessage.getFromUser(), getReplySubject() +"\n\n" + getReplyText(), PrivateMessagesPage.getAbsoluteURL());
} }

@ -237,7 +237,7 @@ public class PeerPortalControllerImpl implements PeerPortalController {
return review; return review;
} catch (Exception e) { } catch (Exception e) {
Logger.getRootLogger().log(Level.ERROR, Logger.getLogger(this.getClass()).log(Level.ERROR,
"Error while accepting peer request: " + e.getMessage()); "Error while accepting peer request: " + e.getMessage());
if (review.getId() != null) { if (review.getId() != null) {
// Something must have gone wrong while updating request status // Something must have gone wrong while updating request status
@ -286,7 +286,7 @@ public class PeerPortalControllerImpl implements PeerPortalController {
return peerRequestDao.save(request); return peerRequestDao.save(request);
} }
} catch (Exception e) { } catch (Exception e) {
Logger.getRootLogger().log(Level.ERROR, Logger.getLogger(this.getClass()).log(Level.ERROR,
"Error while storing Peer Request: " + e.getMessage()); "Error while storing Peer Request: " + e.getMessage());
if (request.getId() != null) { if (request.getId() != null) {
peerRequestDao.delete(request); peerRequestDao.delete(request);
@ -328,7 +328,7 @@ public class PeerPortalControllerImpl implements PeerPortalController {
review.setFile(fdesc.get(0)); review.setFile(fdesc.get(0));
return true; return true;
} catch (Exception e) { } catch (Exception e) {
Logger.getRootLogger().log(Level.ERROR, Logger.getLogger(this.getClass()).log(Level.ERROR,
"Error while storing file for peer review: " + e.getMessage()); "Error while storing file for peer review: " + e.getMessage());
if (review.getFile() != null) { if (review.getFile() != null) {
// Clean up the repository // Clean up the repository

@ -4,9 +4,12 @@ import java.util.ArrayList;
import java.util.List; import java.util.List;
import org.apache.wicket.PageParameters; import org.apache.wicket.PageParameters;
import org.apache.wicket.spring.injection.annot.SpringBean;
import se.su.dsv.scipro.SciProSession; import se.su.dsv.scipro.SciProSession;
import se.su.dsv.scipro.components.AbstractMenuPanel; import se.su.dsv.scipro.components.AbstractMenuPanel;
import se.su.dsv.scipro.data.dao.interfaces.GeneralSystemSettingsDao;
import se.su.dsv.scipro.data.dataobjects.GeneralSystemSettings;
import se.su.dsv.scipro.data.dataobjects.Project; import se.su.dsv.scipro.data.dataobjects.Project;
import se.su.dsv.scipro.data.dataobjects.User; import se.su.dsv.scipro.data.dataobjects.User;
import se.su.dsv.scipro.exceptions.AccessDeniedException; import se.su.dsv.scipro.exceptions.AccessDeniedException;
@ -20,6 +23,9 @@ import se.su.dsv.scipro.security.auth.roles.Roles;
@Authorization(authorizedRoles={Roles.SYSADMIN}) //TODO Hidden for initial deployment @Authorization(authorizedRoles={Roles.SYSADMIN}) //TODO Hidden for initial deployment
public abstract class AbstractProjectPeerPage extends ProjectPage { public abstract class AbstractProjectPeerPage extends ProjectPage {
@SpringBean
private GeneralSystemSettingsDao generalSystemSettingsDao;
public AbstractProjectPeerPage(final PageParameters pp) { public AbstractProjectPeerPage(final PageParameters pp) {
super(pp); super(pp);
@ -45,7 +51,7 @@ public abstract class AbstractProjectPeerPage extends ProjectPage {
} }
protected void checkAccessPrivileges(final PeerReview peerReview) { protected void checkAccessPrivileges(final PeerReview peerReview) {
GeneralSystemSettings gsettings = generalSystemSettingsDao.getGeneralSystemSettingsInstance();
final Project requestingProject = peerReview.getPeerRequest().getProject(); final Project requestingProject = peerReview.getPeerRequest().getProject();
final User user = SciProSession.get().getUser(); final User user = SciProSession.get().getUser();
if( SciProSession.get().authorizedForRole(Roles.SYSADMIN) ) //Can view any review if( SciProSession.get().authorizedForRole(Roles.SYSADMIN) ) //Can view any review
@ -55,6 +61,8 @@ public abstract class AbstractProjectPeerPage extends ProjectPage {
final Project reviewingProject = peerReview.getProject(); final Project reviewingProject = peerReview.getProject();
if( projectDao.isPartOf(user, reviewingProject) ) if( projectDao.isPartOf(user, reviewingProject) )
return; return;
if(gsettings.isPublicReviewsActivated())
return;
//If we've come this far, the user doesn't have access to the project and it's reviews //If we've come this far, the user doesn't have access to the project and it's reviews
throw new AccessDeniedException(this); throw new AccessDeniedException(this);
} }

@ -43,7 +43,7 @@ public class ExpiredReviewResetWorker extends AbstractWorker {
Date expirationDate = new DateTime().minusDays(settings.getNumDaysToSubmitPeerReview()).toDate(); Date expirationDate = new DateTime().minusDays(settings.getNumDaysToSubmitPeerReview()).toDate();
if( peerReview.getDateCreated().compareTo( expirationDate ) < 0 ) { if( peerReview.getDateCreated().compareTo( expirationDate ) < 0 ) {
Logger logger = Logger.getRootLogger(); Logger logger = Logger.getLogger(this.getClass());
logger.log(Level.INFO,"Expiring peerReview: "+peerReview+" and making "+peerRequest+" available for review again"); logger.log(Level.INFO,"Expiring peerReview: "+peerReview+" and making "+peerRequest+" available for review again");
peerReview.setAborted(true); peerReview.setAborted(true);

@ -39,7 +39,7 @@ public class Authenticator {
//Catch exceptions if //Catch exceptions if
} catch (LoginException le){ } catch (LoginException le){
Logger logger = Logger.getRootLogger(); Logger logger = Logger.getLogger(this.getClass());
logger.log(Level.ERROR, "System error, Failed to create logincontext:" + le.getMessage()); logger.log(Level.ERROR, "System error, Failed to create logincontext:" + le.getMessage());
throw le; throw le;
} catch (SecurityException se){ } catch (SecurityException se){

@ -105,7 +105,7 @@ public abstract class AbstractWorker extends Thread {
this.commitTransaction(); this.commitTransaction();
} catch ( Exception e ){ } catch ( Exception e ){
this.rollbackTransaction(); this.rollbackTransaction();
Logger logger = Logger.getRootLogger(); Logger logger = Logger.getLogger(this.getClass());
logger.log(Level.ERROR, getNameString(this.getClass())+" failed to save it's workerdata!"); logger.log(Level.ERROR, getNameString(this.getClass())+" failed to save it's workerdata!");
} }

@ -11,10 +11,8 @@ import org.springframework.stereotype.Component;
import se.su.dsv.scipro.json.ImportWorkerLookup; import se.su.dsv.scipro.json.ImportWorkerLookup;
@Component @Component
public class UserAndProjectImportWorker extends AbstractWorker{ public class UserAndProjectImportWorker extends AbstractWorker{
@Autowired @Autowired
private ImportWorkerLookup importLookup; private ImportWorkerLookup importWorkerLookup;
public static int updatedUsers; public static int updatedUsers;
public static int updatedTheses; public static int updatedTheses;
//The amount of theses or uses asked for //The amount of theses or uses asked for
@ -27,14 +25,14 @@ public class UserAndProjectImportWorker extends AbstractWorker{
@Override @Override
protected void doManualTransactionWork(){ protected void doManualTransactionWork(){
Date startDate = this.getStartedWorkingDate(); Date startDate = this.getStartedWorkingDate();
Logger logger = Logger.getRootLogger(); Logger logger = Logger.getLogger(this.getClass());
logger.log(Level.INFO,"Starting import-from-matchsystem ImportWorker:"+startDate); logger.log(Level.INFO,"Starting import-from-matchsystem ImportWorker:"+startDate);
//Get stats of how many Users and Projects changed scince last update //Get stats of how many Users and Projects changed scince last update
//Sets static params updatedUsers/updatedTheses //Sets static params updatedUsers/updatedTheses
try{ try{
beginTransaction(); beginTransaction();
importLookup.lookupUpdateStats(this.getLastRun()); importWorkerLookup.lookupUpdateStats(this.getLastRun());
commitTransaction(); commitTransaction();
} catch(Exception e){ } catch(Exception e){
rollbackTransaction(); rollbackTransaction();
@ -60,7 +58,7 @@ public class UserAndProjectImportWorker extends AbstractWorker{
try{ try{
beginTransaction(); beginTransaction();
if(endIndex > 0){ if(endIndex > 0){
importLookup.lookup(startIndex, endIndex,(this.getLastRun()),ImportWorkerLookup.USERS); importWorkerLookup.lookup(startIndex, endIndex,(this.getLastRun()),ImportWorkerLookup.USERS);
} }
commitTransaction(); commitTransaction();
@ -90,7 +88,7 @@ public class UserAndProjectImportWorker extends AbstractWorker{
try{ try{
beginTransaction(); beginTransaction();
if(endIndex > 0) if(endIndex > 0)
importLookup.lookup(startIndex, endIndex,(this.getLastRun()), importWorkerLookup.lookup(startIndex, endIndex,(this.getLastRun()),
ImportWorkerLookup.THESES); ImportWorkerLookup.THESES);
commitTransaction(); commitTransaction();

@ -0,0 +1,60 @@
<!DOCTYPE Repository
PUBLIC "-//The Apache Software Foundation//DTD Jackrabbit 1.5//EN"
"http://jackrabbit.apache.org/dtd/repository-1.5.dtd">
<Repository>
<FileSystem class="org.apache.jackrabbit.core.fs.local.LocalFileSystem">
<param name="path" value="/jackrabbit" />
</FileSystem>
<Security appName="Jackrabbit">
<AccessManager class="org.apache.jackrabbit.core.security.simple.SimpleAccessManager" />
<LoginModule class="org.apache.jackrabbit.core.security.simple.SimpleLoginModule">
<param name="anonymousId" value="anonymous" />
</LoginModule>
</Security>
<Workspaces rootPath="${rep.home}/workspaces" defaultWorkspace="default" />
<DataStore class="org.apache.jackrabbit.core.data.FileDataStore">
<param name="path" value="${rep.home}/repository/datastore"/>
<param name="minRecordLength" value="100"/>
</DataStore>
<Workspace name="${wsp.name}">
<FileSystem class="org.apache.jackrabbit.core.fs.local.LocalFileSystem">
<param name="path" value="${wsp.home}" />
</FileSystem>
<PersistenceManager class="org.apache.jackrabbit.core.persistence.bundle.BundleFsPersistenceManager">
<param name="blobFSBlockSize" value="0"/>
<param name="minBlobSize" value="4096"/>
<param name="errorHandling" value=""/>
</PersistenceManager>
<SearchIndex class="org.apache.jackrabbit.core.query.lucene.SearchIndex">
<param name="path" value="${wsp.home}/index" />
<param name="indexingConfiguration" value="${wsp.home}/index-config.xml"/>
<param name="textFilterClasses" value="
org.apache.jackrabbit.extractor.MsWordTextExtractor,
org.apache.jackrabbit.extractor.MsExcelTextExtractor,
org.apache.jackrabbit.extractor.MsPowerPointTextExtractor,
org.apache.jackrabbit.extractor.PdfTextExtractor,
org.apache.jackrabbit.extractor.OpenOfficeTextExtractor,
org.apache.jackrabbit.extractor.RTFTextExtractor,
org.apache.jackrabbit.extractor.XMLTextExtractor,
org.apache.jackrabbit.extractor.PngTextExtractor,
org.apache.jackrabbit.extractor.HTMLTextExtractor"/>
<param name="extractorPoolSize " value="2"/>
<param name="supportHighlighting" value="true"/>
</SearchIndex>
</Workspace>
<Versioning rootPath="${rep.home}/versions">
<FileSystem class="org.apache.jackrabbit.core.fs.local.LocalFileSystem">
<param name="path" value="${rep.home}/versions" />
</FileSystem>
<!-- <PersistenceManager class="org.apache.jackrabbit.core.persistence.xml.XMLPersistenceManager" />-->
<PersistenceManager class="org.apache.jackrabbit.core.persistence.bundle.BundleFsPersistenceManager">
<param name="blobFSBlockSize" value="0"/>
<param name="minBlobSize" value="4096"/>
<param name="errorHandling" value=""/>
</PersistenceManager>
</Versioning>
</Repository>

@ -22,112 +22,20 @@
annotations annotations
--> -->
<tx:annotation-driven transaction-manager="transactionManager" /> <tx:annotation-driven transaction-manager="transactionManager" />
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager"> <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" /> <property name="entityManagerFactory" ref="entityManagerFactory" />
</bean> </bean>
<!-- Load data initializer for default table-data -->
<!-- Autowired
"eventDao"
"projectEventDao"
"groupEventDao"
"userDao"
"roleDao"
"projectDao"
"projectClassDao"
"projectScheduleDao"
"projectFollowerDao"
"checkListDao"
"checkListQuestion"
"checkListTemplate"
"checkListAnswer"
"stringResourceDao"
"fileDescriptionDao"
"projectEventTemplateDao"
"scheduleTemplateDao"
"commmentDao"
"boardMessageDao"
"messageBoardDao"
"ratingDao"
"privateMessageDao"
"recipientDao"
"resourceDao"
"supervisorBoardMessageDao"
"supervisorMessageBoardDao"
"tagDao"
"commentThreadDao"
"fileResourceDao"
"linkResourceDao"
"embedResourceDao"
-->
<!-- Peer-related beans, autowired-->
<!--
"answerDao"
"peerQueueDao"
"peerRequestDao"
"peerReviewDao"
"questionDao"
"questionOptionDao"
"reviewRatingDao"
"reviewTemplateDao"
-->
<!-- End of Peer-stuff -->
<bean class="se.su.dsv.scipro.DataInitialiser" init-method="dataInit" /> <bean class="se.su.dsv.scipro.DataInitialiser" init-method="dataInit" />
<!-- Defines global settings for the application --> <!-- Defines global settings for the application -->
<bean id="applicationSettings" class="se.su.dsv.scipro.ApplicationSettings"> <bean id="applicationSettings" class="se.su.dsv.scipro.ApplicationSettings">
<!-- Set this line to true if you want to do lookup against daisy if username was not found in db <!-- Set this line to true if you want to do lookup against daisy if username was not found in db
By default it's turned off since we don't have access to the daisy search yet By default it's turned off since we don't have access to the daisy search yet
--> -->
<property name="enableRemoteUserLookup" value="true"></property> <property name="enableRemoteUserLookup" value="true"></property>
<!-- This property points to the location of the daisy json search --> <!-- This property points to the location of the remote system used for json requests -->
<property name="remoteLookupUrl" value="https://thesis.dsv.su.se/match/json" /> <property name="remoteLookupUrl" value="https://thesis.dsv.su.se/match/json" />
<!-- External auth support (via J2EE standard mechanism REMOTE_USER), if true: other authentication mechanics will be bypassed.--> <!-- External auth support (via J2EE standard mechanism REMOTE_USER), if true: other authentication mechanics will be bypassed.-->
<property name="acceptExternalAuthentication" value="true"/> <property name="acceptExternalAuthentication" value="true"/>
</bean> </bean>
<!-- Defines the class used for lookup in username against a remote server NOW AUTOWIRED AND DEPRECATED, NOT MAINTAINED-->
<!-- <bean id="userFullLookup" class="se.su.dsv.scipro.json.DefaultUserFullLookup">-->
<!-- <property name="userDao" ref="userDao" />-->
<!-- <property name="settings" ref="applicationSettings" />-->
<!-- <property name="userResponseHandler" ref="jsonUserFullResponseHandler" />-->
<!-- </bean> -->
<!-- Defines the class used for lookup in username against a remote server -->
<bean id="importWorkerLookup" class="se.su.dsv.scipro.json.ImportWorkerLookup">
<property name="settings" ref="applicationSettings" />
<property name="userResponseHandler" ref="importWorkerResponseHandler" />
<property name="statsResonseHandler" ref="importStatsResponseHandler" />
</bean>
<!-- The abstract handler for json responses -->
<bean id="jsonResponseHandler" abstract="true" class="se.su.dsv.scipro.json.JsonResponseHandler">
<property name="settings" ref="applicationSettings" />
<property name="userLookup" ref="userLookup" />
</bean>
<!-- Defines the class used for lookup in username against a remote server NOW AUTOWIRED AND DEPRECATED, NOT MAINTAINED -->
<!-- <bean id="userLookup" class="se.su.dsv.scipro.json.DefaultUserLookup">-->
<!-- <property name="userDao" ref="userDao" />-->
<!-- <property name="settings" ref="applicationSettings" />-->
<!-- <property name="userResponseHandler" ref="jsonUserResponseHandler" />-->
<!-- </bean> -->
<!-- Handler for json responses regarding users -->
<bean id="jsonUserResponseHandler" parent="jsonResponseHandler" class="se.su.dsv.scipro.json.JsonUserResponseHandler" />
<bean id="jsonUserFullResponseHandler" parent="jsonResponseHandler" class="se.su.dsv.scipro.json.JsonUserFullResponseHandler" />
<bean id="importWorkerResponseHandler" parent="jsonResponseHandler" class="se.su.dsv.scipro.json.ImportWorkerResponseHandler" />
<bean id="importStatsResponseHandler" parent="jsonResponseHandler" class="se.su.dsv.scipro.json.ImportUpdateStatsResponseHandler" />
<!-- <bean class="se.su.dsv.scipro.datainitializers.EventTemplatesInitializer" init-method="dataInit" /> -->
<!-- <bean class="se.su.dsv.scipro.datainitializers.ScheduleTemplateInitializer" init-method="dataInit" />-->
<!-- <bean class="se.su.dsv.scipro.datainitializers.EventDataInitializer" init-method="dataInit" />-->
</beans> </beans>

@ -1,52 +0,0 @@
#General
twoNewLines=\n\n
twoNewLinesWithComma=,\n\n
linkText = Click on the link to see it in SciPro:\n
mailSubject=Notification for SciPro
hello=Hello
autogenerated=This is an auto-generated message from SciPro
colon=:
comma=,
dot=.
space=\
quote="
#Conference
conferenceNotification=\ posted on conference
conferenceNotificationComment=\ commented on conference
#Private message
privateMessageNotification=\ wrote a private message to you.
#Private message reply
privateMessageReplyNotification=\ replied with a private message to you.
#Peer accepted
acceptPeerReviewSubject=Your request for peer-review has been accepted
requestAccepted=Your peer request was accepted by
heShe=, he/she now has
complete=\ days to complete a review.
#Peer completed
completedReviewSubject=A peer review has been completed!
requestReviewed=Your peer request has now been reviewed and is available.
supervisorMessageBody=You are getting this message because you are supervisor of "
#Peer completed supervisor of project
supervisorMessageBody2=".\nA peer review on this project has been completed and is available for you.
#Peer completed supervisor of reviewer
supervisorMessageBody3=\ has performed a peer review on someone elses work which is available for you.
#Peer completed webnotification
inProject=in project:
hasPerformed=\ has performed a peer review.
commaWithLinebreak=".\n
#Peer rated
reviewRatedSubject=You have received a rating for a review you have done!
reviewRatedBody=Your review has been rated.
#Final seminar created
finalSeminarCreated=Head supervisor for
finalSeminarProject=\ has created a final seminar, room
finalSeminarProjectOpponnent=\ has created a final seminar and added you as an opponent, room
#Final seminar report uploaded
finalSeminarReportUploaded=Thesis for the project
finalSeminarReportBeenUploaded=\ has been uploaded.
#Final seminar opposition report uploaded
finalSeminarOppositionReportUploaded=Opposition-report for the project
finalSeminarOppositionReportBeenUploaded=\ has been uploaded by
#Final seminar edited
finalSeminarOppositionReportEdited=Final seminar for project
finalSeminarOppositionReportBeenEdited=\ has been edited.

@ -118,6 +118,7 @@ form.inline p {margin-bottom:0;}
.span-8 {width:310px;} .span-8 {width:310px;}
.span-9 {width:350px;} .span-9 {width:350px;}
.span-10 {width:390px;} .span-10 {width:390px;}
.span-10.5 {width:429}
.span-11 {width:430px;} .span-11 {width:430px;}
.span-12 {width:470px;} .span-12 {width:470px;}
.span-13 {width:510px;} .span-13 {width:510px;}

@ -1,6 +1,6 @@
@IMPORT url("menu.css"); @IMPORT url("menu.css");
/* är det såhär man aktiverar plugins? */ /* är det såhär man aktiverar plugins? */
@IMPORT url("blueprint/plugins/buttons/screen.css"); /* @IMPORT url("blueprint/plugins/buttons/screen.css"); */
/* BASE */ /* BASE */
@ -120,6 +120,23 @@ img.department-logotype {
.inline-link-list li a { display: block; padding: 5px 10px; text-decoration: none; } .inline-link-list li a { display: block; padding: 5px 10px; text-decoration: none; }
.inline-link-list li:hover > a { text-decoration: underline; } .inline-link-list li:hover > a { text-decoration: underline; }
.rounded-fieldset {
padding:1em;
-webkit-border-radius: 6px;
-moz-border-radius: 6px;
border-radius: 6px;
}
.rounded {
-webkit-border-radius: 6px;
-moz-border-radius: 6px;
border-radius: 6px;
}
.rounded-box { .rounded-box {
font-size: 0.9em; font-size: 0.9em;
padding:1.5em; padding:1.5em;

@ -32,15 +32,19 @@ import se.su.dsv.scipro.data.dataobjects.Student;
import se.su.dsv.scipro.data.dataobjects.SysAdmin; import se.su.dsv.scipro.data.dataobjects.SysAdmin;
import se.su.dsv.scipro.data.dataobjects.User; import se.su.dsv.scipro.data.dataobjects.User;
import se.su.dsv.scipro.data.dataobjects.Username; import se.su.dsv.scipro.data.dataobjects.Username;
import se.su.dsv.scipro.json.IUserLookup; import se.su.dsv.scipro.json.IUserLookupFromIdentifier;
import se.su.dsv.scipro.json.IUserLookupFromUsername;
import se.su.dsv.scipro.json.RemoteLookupOptions;
import se.su.dsv.scipro.repository.util.RepositoryManager; import se.su.dsv.scipro.repository.util.RepositoryManager;
import se.su.dsv.scipro.util.KeyValuePair;
public class TestAuthRoutines { public class TestAuthRoutines {
private SciProSession session; private SciProSession session;
private WicketTester wt; private WicketTester wt;
private User user; private User user;
private Role sysAdm; private Role sysAdm;
private IUserLookup fixedLookup; private IUserLookupFromIdentifier fixedLookupFromIdentifier;
private IUserLookupFromUsername fixedLookupFromUsername;
private ApplicationSettings appSettings; private ApplicationSettings appSettings;
@Before @Before
public void init(){ public void init(){
@ -49,10 +53,19 @@ public class TestAuthRoutines {
appSettings = new ApplicationSettings(); appSettings = new ApplicationSettings();
appSettings.setAcceptExternalAuthentication(true); appSettings.setAcceptExternalAuthentication(true);
//Fake a lookup mechanism //Fake a lookup mechanism
fixedLookup = new IUserLookup(){ fixedLookupFromUsername = new IUserLookupFromUsername(){
@Override @Override
public User lookup(String username) throws Exception{ public User lookup(final KeyValuePair<String> userAtRealm, final RemoteLookupOptions options){
if(username.equals("kalle-kula")) if(userAtRealm.getKey().equals("kalle-kula"))
return user;
else
return null;
}
};
fixedLookupFromIdentifier = new IUserLookupFromIdentifier(){
@Override
public User lookup(final Long identifier, final RemoteLookupOptions options){
if(identifier.equals(666))
return user; return user;
else else
return null; return null;
@ -98,7 +111,8 @@ public class TestAuthRoutines {
ac.putBean("roleDao",mockedRoleDao); ac.putBean("roleDao",mockedRoleDao);
ac.putBean("projectDao",Mockito.mock(ProjectDao.class)); ac.putBean("projectDao",Mockito.mock(ProjectDao.class));
ac.putBean("userSettingsDao",Mockito.mock(UserSettingsDao.class)); ac.putBean("userSettingsDao",Mockito.mock(UserSettingsDao.class));
ac.putBean("userFullLookup",fixedLookup); ac.putBean("userLookupFromUsername",fixedLookupFromUsername);
ac.putBean("userLookupFromIdentifier",fixedLookupFromIdentifier);
//Create tester //Create tester
wt = new WicketTester(new SciProApplication(){ wt = new WicketTester(new SciProApplication(){
@Override @Override
@ -147,7 +161,7 @@ public class TestAuthRoutines {
//At this point, an exception should be thrown //At this point, an exception should be thrown
new ExternalAuthenticationRequestHelper(null); new ExternalAuthenticationRequestHelper(null);
} }
@Test(expected=NullPointerException.class) @Test
public void testSessionSignInAndSu(){ public void testSessionSignInAndSu(){
ExternalAuthenticationRequestHelper helper = new ExternalAuthenticationRequestHelper(new HttpServletRequestWrapper(wt.getServletRequest()){ ExternalAuthenticationRequestHelper helper = new ExternalAuthenticationRequestHelper(new HttpServletRequestWrapper(wt.getServletRequest()){
@Override @Override
@ -169,10 +183,9 @@ public class TestAuthRoutines {
user.setRoles(roles); user.setRoles(roles);
Assert.assertTrue(session.switchAuthenticatedUser("kalle-kula", "dsv.su.se")); Assert.assertTrue(session.switchAuthenticatedUser("kalle-kula", "dsv.su.se"));
Assert.assertTrue(session.getUser().getIdentifier().equals(user.getIdentifier())); Assert.assertTrue(session.getUser().getIdentifier().equals(user.getIdentifier()));
//This should fail with an exception, there is no such user Assert.assertFalse(session.switchAuthenticatedUser("somebody","somewhere.se"));
session.switchAuthenticatedUser("somebody","somewhere.se");
} }
@Test(expected=NullPointerException.class) @Test
public void testFailedAuthenticatedSignIn(){ public void testFailedAuthenticatedSignIn(){
ExternalAuthenticationRequestHelper helper = new ExternalAuthenticationRequestHelper(new HttpServletRequestWrapper(wt.getServletRequest()){ ExternalAuthenticationRequestHelper helper = new ExternalAuthenticationRequestHelper(new HttpServletRequestWrapper(wt.getServletRequest()){
@Override @Override
@ -180,8 +193,7 @@ public class TestAuthRoutines {
return "some-dude@ki.se"; return "some-dude@ki.se";
} }
}); });
//This should throw exceptions, not sure about this interface (throwing exceptions when authentication passes but no user can be located). Assert.assertFalse(helper.signIn(session));
helper.signIn(session);
} }
@Test @Test
public void testFailedSwitchAuthentitedUser(){ public void testFailedSwitchAuthentitedUser(){

@ -8,7 +8,6 @@ import org.apache.wicket.Session;
import org.apache.wicket.spring.injection.annot.SpringComponentInjector; import org.apache.wicket.spring.injection.annot.SpringComponentInjector;
import org.apache.wicket.spring.test.ApplicationContextMock; import org.apache.wicket.spring.test.ApplicationContextMock;
import org.apache.wicket.util.tester.WicketTester; import org.apache.wicket.util.tester.WicketTester;
import org.junit.Before;
import org.junit.Ignore; import org.junit.Ignore;
import org.mockito.Mock; import org.mockito.Mock;
import org.mockito.Mockito; import org.mockito.Mockito;
@ -50,6 +49,7 @@ import se.su.dsv.scipro.data.dao.interfaces.WorkerDataDao;
import se.su.dsv.scipro.data.dataobjects.GeneralSystemSettings; import se.su.dsv.scipro.data.dataobjects.GeneralSystemSettings;
import se.su.dsv.scipro.data.dataobjects.Project; import se.su.dsv.scipro.data.dataobjects.Project;
import se.su.dsv.scipro.data.dataobjects.User; import se.su.dsv.scipro.data.dataobjects.User;
import se.su.dsv.scipro.json.DefaultUserLookupFromUsername;
import se.su.dsv.scipro.peer.data.dao.controllers.PeerPortalController; import se.su.dsv.scipro.peer.data.dao.controllers.PeerPortalController;
import se.su.dsv.scipro.peer.data.dao.interfaces.PeerRequestDao; import se.su.dsv.scipro.peer.data.dao.interfaces.PeerRequestDao;
import se.su.dsv.scipro.peer.data.dao.interfaces.PeerReviewDao; import se.su.dsv.scipro.peer.data.dao.interfaces.PeerReviewDao;
@ -104,6 +104,7 @@ public abstract class BaseWicketTest {
@Mock ProjectPartnerDao projectPartnerDao; @Mock ProjectPartnerDao projectPartnerDao;
@Mock WebNotificationDao webNotificationDao; @Mock WebNotificationDao webNotificationDao;
@Mock NotificationController notificationController; @Mock NotificationController notificationController;
@Mock DefaultUserLookupFromUsername userLookupFromUsername;
@Mock ApplicationSettings applicationSettings; @Mock ApplicationSettings applicationSettings;