Initial import.

git-svn-id: svn://svn.dsv.su.se/scipro/scipro/trunk@8 73ecded7-942e-4092-bab0-0e58ef0ee984
This commit is contained in:
mpeters 2011-01-05 14:31:17 +00:00
parent 21e164db28
commit 93b9aa93ef
51 changed files with 2557 additions and 0 deletions

@ -0,0 +1,75 @@
<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"
version="2.0">
<!-- NOTE THAT THERE ARE TWO PERSISTENCE UNITS, one default and one test used for either running or unit-tests -->
<!-- A JPA Persistence Unit -->
<persistence-unit name="defaultPersistenceUnit" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<class>se.su.dsv.scipro.data.dataobjects.Username</class>
<class>se.su.dsv.scipro.data.dataobjects.User</class>
<class>se.su.dsv.scipro.data.dataobjects.LazyDeletableDomainObject</class>
<class>se.su.dsv.scipro.data.dataobjects.Event</class>
<class>se.su.dsv.scipro.data.dataobjects.DomainObject</class>
<!-- JPA entities must be registered here -->
<properties>
<!-- 2nd level cache -->
<property name="hibernate.cache.provider_class" value="org.hibernate.cache.SingletonEhCacheProvider" />
<property name="net.sf.ehcache.configurationResourceName" value="/ehcache.xml" />
<property name="hibernate.cache.use_query_cache" value="true" />
<property name="hibernate.cache.use_second_level_cache" value="true" />
<property name="hibernate.generate_statistics" value="false" />
<!-- Local mysql test database -->
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5Dialect" />
<property name="hibernate.connection.driver_class" value="com.mysql.jdbc.Driver"></property>
<property name="hibernate.connection.url" value="jdbc:mysql://localhost/scipro"></property>
<property name="hibernate.connection.username" value="root"></property>
<property name="hibernate.connection.password" value="martin"></property>
<property name="hibernate.c3p0.idle_test_period" value="3600"></property>
</properties>
</persistence-unit>
<!-- A JPA Persistence Unit used for tests -->
<persistence-unit name="testPersistenceUnit" transaction-type="RESOURCE_LOCAL">
<!-- This list of persisted Entitys IS NOT updated by eclipes JPA facet,
if some tests are failing, then copy paste exact list from the above persistence unit -->
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<class>se.su.dsv.scipro.data.dataobjects.Username</class>
<class>se.su.dsv.scipro.data.dataobjects.User</class>
<class>se.su.dsv.scipro.data.dataobjects.LazyDeletableDomainObject</class>
<class>se.su.dsv.scipro.data.dataobjects.Event</class>
<class>se.su.dsv.scipro.data.dataobjects.DomainObject</class>
<!-- JPA entities must be registered here -->
<properties>
<!-- 2nd level cache -->
<property name="hibernate.cache.provider_class" value="org.hibernate.cache.SingletonEhCacheProvider" />
<property name="net.sf.ehcache.configurationResourceName" value="/ehcache.xml" />
<property name="hibernate.cache.use_query_cache" value="false" />
<property name="hibernate.cache.use_second_level_cache" value="false" />
<property name="hibernate.generate_statistics" value="false" />
<property name="hibernate.dialect" value="org.hibernate.dialect.HSQLDialect" />
<property name="hibernate.hbm2ddl.auto" value="create" />
<property name="hibernate.connection.driver_class" value="org.hsqldb.jdbcDriver"></property>
<property name="hibernate.connection.url" value="jdbc:hsqldb:mem:test"></property>
<property name="hibernate.show_sql" value="true" />
</properties>
</persistence-unit>
</persistence>

@ -0,0 +1,32 @@
package se.su.dsv.scipro;
import se.su.dsv.scipro.data.dao.interfaces.EventDao;
import se.su.dsv.scipro.data.dataobjects.Event;
/**
* @author Richard Wilkinson - richard.wilkinson@jweekend.com
*
*/
public class DataInitialiser {
private static String[] dummyTitles = {"Wicket Event", "Party", "Breakfast At Tiffany's", "Holiday"};
private static String[] dummyLocations = {"London", "Paris", "Pub", "New York"};
public void setEventDao(EventDao eventDao) {
this.eventDao = eventDao;
}
private EventDao eventDao;
public void dataInit()
{
for(int i = 0; i < 10; i++)
{
Event event = new Event();
event.setTitle(dummyTitles[(int)(Math.random() * dummyTitles.length)]);
event.setLocation(dummyLocations[(int)(Math.random() * dummyLocations.length)]);
//eventDao.save(event);
}
}
}

@ -0,0 +1,16 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"
xmlns:wicket="http://wicket.apache.org/dtds.data/wicket-xhtml1.4-strict.dtd">
<head>
<title>LegUp: Wicket Spring JPA 2.0</title>
</head>
<body>
<div>
<strong><a href="http://jweekend.com/dev/LegUp">LegUp</a>: <a href="http://wicket.apache.org/">Wicket</a> <a href="http://www.springsource.org/">Spring</a> JPA 2.0</strong>
<br/><br/>
<a wicket:id="event">Event Page</a>
</div>
</body>
</html>

@ -0,0 +1,30 @@
package se.su.dsv.scipro;
import org.apache.wicket.PageParameters;
import org.apache.wicket.markup.html.WebPage;
import org.apache.wicket.markup.html.link.BookmarkablePageLink;
import se.su.dsv.scipro.pages.EventPage;
/**
* @author Richard Wilkinson - richard.wilkinson@jweekend.com
*
*/
public class HomePage extends WebPage {
private static final long serialVersionUID = 1L;
/**
* Constructor that is invoked when page is invoked without a em.
*
* @param parameters
* Page parameters
*/
public HomePage(final PageParameters parameters) {
// Add the simplest type of label
add(new BookmarkablePageLink<Void>("event", EventPage.class));
}
}

@ -0,0 +1,90 @@
package se.su.dsv.scipro;
import org.apache.log4j.Level;
import org.apache.log4j.Logger;
import org.apache.wicket.Page;
import org.apache.wicket.Request;
import org.apache.wicket.Response;
import org.apache.wicket.Session;
import org.apache.wicket.protocol.http.WebApplication;
import org.apache.wicket.spring.injection.annot.SpringComponentInjector;
import se.su.dsv.scipro.loginlogout.pages.LoginPage;
import se.su.dsv.scipro.loginlogout.pages.LogoutPage;
import se.su.dsv.scipro.pages.EventPage;
/**
* Application object for your web application. If you want to run this application without deploying, run the Start class.
*
* @see wicket.myproject.Start#main(String[])
*
* @author Martin Peters - mpeters@dsv.su.se
*
*/
public class SciProApplication extends WebApplication {
/*
* These strings points to the location of the kerberos configuration files
*/
private final String jaasPath = "/WEB-INF/classes/jaas.conf";
private final String krb5Path = "/WEB-INF/classes/kerb5.conf";
/**
* Constructor
*/
public SciProApplication()
{
}
protected SpringComponentInjector getSpringInjector()
{
return new SpringComponentInjector(this);
}
@Override
protected void init() {
super.init();
setKerberosConfigs();
mountBookmarkablePage("event", EventPage.class);
mountBookmarkablePage("login", LoginPage.class);
mountBookmarkablePage("logout", LogoutPage.class);
addComponentInstantiationListener(getSpringInjector());
}
@SuppressWarnings("unchecked")
protected void setKerberosConfigs(){
javax.servlet.ServletContext context = getServletContext();
Logger logger = Logger.getRootLogger();
java.util.Set<String> resources = context.getResourcePaths("/WEB-INF/classes/");
if(!resources.contains(jaasPath) || !resources.contains(krb5Path)){
logger.log(Level.FATAL, "Path to authentication config files not correct. " +
"Users will not be able to log in!");
} else {
String jaasRealPath = context.getRealPath(jaasPath);
String krb5RealPath = context.getRealPath(krb5Path);
logger.log(Level.INFO, "Setting location of jaas.conf to " + jaasRealPath);
logger.log(Level.INFO, "Setting location of kerb5.conf to " + krb5RealPath);
System.setProperty("java.security.auth.login.config", jaasRealPath);
System.setProperty("java.security.krb5.conf", krb5RealPath);
}
}
/* (non-Javadoc)
* @see org.apache.wicket.Application#getHomePage()
*/
@Override
public Class<? extends Page> getHomePage() {
return HomePage.class;
}
@Override
public Session newSession(Request request, Response response) {
return new SciProSession(request);
}
}

@ -0,0 +1,162 @@
package se.su.dsv.scipro;
import java.util.Locale;
import javax.security.auth.login.FailedLoginException;
import javax.security.auth.login.LoginException;
import javax.servlet.http.Cookie;
import org.apache.log4j.Level;
import org.apache.log4j.Logger;
import org.apache.wicket.Request;
import org.apache.wicket.Session;
import org.apache.wicket.injection.web.InjectorHolder;
import org.apache.wicket.protocol.http.WebRequest;
import org.apache.wicket.protocol.http.WebSession;
import org.apache.wicket.spring.injection.annot.SpringBean;
import se.su.dsv.scipro.auth.Authenticator;
import se.su.dsv.scipro.data.dao.interfaces.UserDao;
import se.su.dsv.scipro.data.dataobjects.User;
public class SciProSession extends WebSession {
private static final long serialVersionUID = -2655601050866343391L;
private boolean loggedIn = false;
@SpringBean
private UserDao userDao;
//private List<Role> roles = new ArrayList<Role>();
private User user = null;
private String loggedInIdentity = null;
protected SciProSession(Request request) {
super(request);
InjectorHolder.getInjector().inject(this);
Cookie cookie = ((WebRequest)request).getCookie("languagePreference");
if(cookie != null){
if(cookie.getValue().equals("en"))
this.setLocale(Locale.ENGLISH);
else if(cookie.getValue().equals("sv"))
this.setLocale(new Locale("sv","SE"));
}
}
public static SciProSession get() {
return (SciProSession) Session.get();
}
protected void setUser(User user) {
this.user = user;
}
public User getUser() {
return user;
}
protected void setLoggedInIdentity(String loggedInIdentity) {
this.loggedInIdentity = loggedInIdentity;
}
public String getLoggedInIdentity() {
return loggedInIdentity;
}
public boolean login(final String username, final String password){
final boolean loginSuccess = authenticate(username, password);
if(loginSuccess){
loggedIn = true;
}
return loginSuccess;
}
public void logout()
{
loggedIn = false;
}
public final boolean isLoggedIn() {
return loggedIn;
}
private boolean authenticate(String username, final String password) throws NullPointerException {
Authenticator auth = new Authenticator();
/*
* An administrator can log in as a different user in the system by using 'adminusername::otherusername' for login
*/
String[] tmp = username.split("::");
String loggedInAsUsername = null;
if(tmp.length > 0){
username = tmp[0];
if(tmp.length > 1)
loggedInAsUsername = tmp[1];
}
try {
auth.authenticate(username, password);
this.user = userDao.getUserByUsername(username);
if( user == null)
throw new NullPointerException("No user with this username found in the database, despite successful authentication");
setLoggedInIdentity(username+"@"+"dsv.su.se");
if(user.getEmailAddress() == null || user.getEmailAddress().trim().equals("")){
user.setEmailAddress(getLoggedInIdentity());
user = userDao.save(user);
}
/*
* Here we switch the logged in user to be that of the person chosen be the logged in admin
*/
/*
if(userDao.isAdmin(user) && loggedInAsUsername != null){
this.user = userDao.getUserByUserName(loggedInAsUsername);
if( user == null)
throw new NullPointerException("No user with this username found in the database, despite successful authentication");
}
if(userDao.isAuthor(user)){
rolesString = rolesString +"AUTHOR,";
roles.add(new AuthorRole());
}
if(userDao.isSupervisor(user)){
rolesString = rolesString +"SUPERVISOR,";
roles.add(new SupervisorRole());
}
if(userDao.isAdmin(user)){
rolesString = rolesString +"ADMIN,";
roles.add(new AdminRole());
}
if(roles.isEmpty()){
roles.add(new DefaultRole());
}
*/
Logger logger = Logger.getLogger("Application");
logger.log(Level.INFO, "User: "+getLoggedInIdentity()+ " logged in as: "+user.getFirstName()+" "+user.getLastName()+" "+user.getUserNames());
return true;
} catch (FailedLoginException e) {
//e.printStackTrace();
} catch (LoginException e) {
//e.printStackTrace();
}
return false;
}
@Override
public String toString(){
return loggedInIdentity;//+" Roles: "+rolesString;
}
}

@ -0,0 +1,66 @@
package se.su.dsv.scipro.auth;
import javax.security.auth.login.FailedLoginException;
import javax.security.auth.login.LoginContext;
import javax.security.auth.login.LoginException;
import org.apache.log4j.Level;
import org.apache.log4j.Logger;
/**
* Class that handles authentication
*
* @author Dan Kjellman <dan-kjel@dsv.su.se>
*/
public class Authenticator {
/**
* Method for authenticating users against underlying login module
*
* @param username the username
* @param password the password
* @return the authenticated username on success
* @throws LoginException if something unexpected happend
* @throws FailedLoginException if the username and password did not match
*/
public String authenticate(String username, String password)
throws LoginException, FailedLoginException {
LoginContext lc = null;
try {
//Create the callbackhandler and set username and password properties
LoginCallbackHandler loginCallback = new LoginCallbackHandler();
loginCallback.setUsername(username);
loginCallback.setPassword(password);
//Create LoginContext
lc = new LoginContext("ThesisJaasUser", loginCallback);
//Catch exceptions if
} catch (LoginException le){
Logger logger = Logger.getRootLogger();
logger.log(Level.ERROR, "System error, Failed to create logincontext:" + le.getMessage());
throw le;
} catch (SecurityException se){
throw new LoginException("System error, Failed to create logincontext:" + se.getMessage());
} catch (Exception e) {
throw new LoginException("System error:" + e.getMessage());
}
//try to authenticate
try {
lc.login();
//return username on success
return username;
//Catch LoginException if username and password did not match
} catch (LoginException le) {
throw new FailedLoginException("Autentication failed: " + le.getMessage());
//Catch all other Exceptions if something unexpected happend
} catch (Exception e) {
throw new LoginException("System error, Failed to authenticate:" + e.getMessage());
}
}
}

@ -0,0 +1,84 @@
package se.su.dsv.scipro.auth;
import java.io.IOException;
import javax.security.auth.callback.Callback;
import javax.security.auth.callback.NameCallback;
import javax.security.auth.callback.PasswordCallback;
import javax.security.auth.callback.UnsupportedCallbackException;
/**
* A Callbackhandler
* @author Dan Kjellman <dan-kjel@dsv.su.se>
*/
public class LoginCallbackHandler implements javax.security.auth.callback.CallbackHandler {
private String password;
private String username;
/**
* Constructor
*/
public LoginCallbackHandler(){}
/**
* Get the username
* @return String username
*/
public String getUsername(){
return username;
}
/**
* Set the username
*
* @param username the username
*/
public void setUsername(String username){
//If null set empty string, authentication will fail
if(username == null){
this.username = "";
}
this.username = username;
}
/**
* Get the password
* @return String password
*/
public String getPassword(){
return password;
}
/**
* Set the password
* @param password
*/
public void setPassword(String password){
//If null set empty string, authentication will fail
if(password == null){
this.password = "";
}
this.password = password;
}
/**
* Handle the callbacks
*/
public void handle(Callback[] cb) throws IOException,
UnsupportedCallbackException {
for(int i = 0; i<cb.length; i++){
Callback c = cb[i];
if(c instanceof NameCallback){
((NameCallback)c).setName(getUsername());
} else if (c instanceof PasswordCallback){
((PasswordCallback)c).setPassword(getPassword().toCharArray());
} else {
throw new UnsupportedCallbackException(c, "Unsupported callback");
}
}
}
}

@ -0,0 +1,22 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-type" content="text/html;charset=UTF-8" />
<title>SciPro 0.1 Beta</title>
<link href="styles/blueprint/screen.css" rel="stylesheet" media="screen,projection" />
<link href="styles/blueprint/print.css" rel="stylesheet" media="print" />
<link href="styles/blueprint/plugins/tabsplugin/screen.css" rel="stylesheet" media="screen,projection" />
<!--[if lt IE 8]>
<link rel="stylesheet" href="styles/blueprint/ie.css" type="text/css" media="screen, projection" />
<![endif]-->
<link href="styles/global.css" rel="stylesheet" media="screen,projection" />
</head>
<body>
<div>
<wicket:child/>
</div>
</body>
</html>

@ -0,0 +1,36 @@
package se.su.dsv.scipro.basepages;
import org.apache.wicket.PageParameters;
import org.apache.wicket.markup.html.CSSPackageResource;
import org.apache.wicket.markup.html.WebPage;
public abstract class BasePage extends WebPage {
public BasePage(){
super();
}
public BasePage(PageParameters pp){
super(pp);
}
public static String ADMIN_CSS = "admin";
public static String SUPERVISOR_CSS = "supervisor";
public static String AUTHOR_CSS = "author";
public static String GLOBAL_CSS = "global";
public static String POPUP_CSS = "popup";
public static String CSS_SUFFIX = ".css";
protected void setCss(String css){
String languageCode = "";
if(getLocale().getLanguage().equalsIgnoreCase("sv"))
languageCode = "sv";
else
languageCode = "en";
add(CSSPackageResource.getHeaderContribution("styles/" + languageCode + CSS_SUFFIX));
//add(CSSPackageResource.getHeaderContribution("styles/" + GLOBAL_CSS + CSS_SUFFIX));
add(CSSPackageResource.getHeaderContribution("styles/" + css + CSS_SUFFIX));
}
}

@ -0,0 +1,5 @@
submit: Submit
palette.available: Available
palette.selected: Selected

@ -0,0 +1,5 @@
submit: Skicka
palette.available: Valbara
palette.selected: Valda

@ -0,0 +1,23 @@
package se.su.dsv.scipro.data.dao.interfaces;
import java.io.Serializable;
import java.util.List;
import se.su.dsv.scipro.data.dataobjects.DomainObject;
/**
* @author Richard Wilkinson - richard.wilkinson@jweekend.com
*
*/
public interface Dao<T extends DomainObject>
{
public void delete(T o);
public T load(Serializable id);
public T save(T o);
public List<T> findAll();
public int countAll();
}

@ -0,0 +1,10 @@
package se.su.dsv.scipro.data.dao.interfaces;
import se.su.dsv.scipro.data.dataobjects.Event;
/**
* @author Richard Wilkinson - richard.wilkinson@jweekend.com
*
*/
public interface EventDao extends Dao<Event> {
}

@ -0,0 +1,15 @@
package se.su.dsv.scipro.data.dao.interfaces;
/**
*
* @author Martin Peters - mpeters@dsv.su.se
*
* Classes implementing this interface MUST have a member of type boolean with the name 'deleted'.
*/
public interface LazyDeletable {
public boolean isDeleted();
public void setDeleted(boolean deleted);
}

@ -0,0 +1,24 @@
package se.su.dsv.scipro.data.dao.interfaces;
import java.util.List;
import se.su.dsv.scipro.data.dataobjects.DomainObject;
/**
*
* @author Martin Peters - mpeters@dsv.su.se
*
* @param <T>
*/
public interface LazyDeleteDao<T extends DomainObject & LazyDeletable> extends Dao<T> {
public T lazyDelete(T o);
public int countAllLazyDeleted();
public List<T> findAllLazyDeleted();
public List<T> findAllLazyDeleted(final int first, final int count);
}

@ -0,0 +1,14 @@
package se.su.dsv.scipro.data.dao.interfaces;
import se.su.dsv.scipro.data.dataobjects.User;
public interface UserDao extends LazyDeleteDao<User> {
public User getUserByIdentifier(final Long identifier);
public User getUserByUsername(final String userName);
public User getUserByEmail(final String emailAddress);
}

@ -0,0 +1,12 @@
package se.su.dsv.scipro.data.dao.interfaces;
import java.util.List;
import se.su.dsv.scipro.data.dataobjects.User;
import se.su.dsv.scipro.data.dataobjects.Username;
public interface UsernameDao extends Dao<Username>{
public List<Username> getUsernamesByUser(final User user);
}

@ -0,0 +1,118 @@
package se.su.dsv.scipro.data.dao.jpa;
import java.io.Serializable;
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.orm.jpa.support.JpaDaoSupport;
import org.springframework.transaction.annotation.Transactional;
import se.su.dsv.scipro.data.dao.interfaces.Dao;
import se.su.dsv.scipro.data.dataobjects.DomainObject;
/**
*
* @author Martin Peters - mpeters@dsv.su.se
*
* @param <T>
*/
public abstract class AbstractDaoJPAImpl<T extends DomainObject> extends JpaDaoSupport implements Dao<T> {
protected Class<T> domainClass;
protected String domainClassString;
public Class<T> getDomainClass(){
return domainClass;
}
public String getDomainClassString(){
return domainClassString;
}
public AbstractDaoJPAImpl(Class<T> domainClass) {
this.domainClass = domainClass;
domainClassString = domainClass.getCanonicalName();
}
@Transactional
public void delete(T object)
{
getJpaTemplate().remove(object);
}
@Transactional
public T load(Serializable id)
{
return (T) getJpaTemplate().find(domainClass, id);
}
@Transactional
public T reLoad(T object){
if(object != null)
return load(object.getId());
else
return null;
}
@Transactional
public T save(T object)
{
return getJpaTemplate().merge(object);
}
@Transactional
public int countAll() {
return getJpaTemplate().execute(new JpaCallback<Integer>() {
public Integer doInJpa(EntityManager em) throws PersistenceException {
TypedQuery<Long> query = em.createQuery("SELECT COUNT (x) FROM "+domainClassString+" x", Long.class);
query.setHint(QueryHints.HINT_CACHEABLE, "true");
return (query.getSingleResult()).intValue();
}
});
}
@Transactional
public List<T> findAll() {
return getJpaTemplate().execute(new JpaCallback<List<T>>() {
public List<T> doInJpa(EntityManager em) throws PersistenceException {
TypedQuery<T> query = em.createQuery("SELECT x FROM "+domainClassString+" x", domainClass);
query.setHint(QueryHints.HINT_CACHEABLE, "true");
return query.getResultList();
}
});
}
@Transactional
public List<T> findAll(final int first, final int count) {
return getJpaTemplate().execute(new JpaCallback<List<T>>() {
public List<T> doInJpa(EntityManager em) throws PersistenceException {
TypedQuery<T> query = em.createQuery("SELECT x FROM "+domainClassString+" x", domainClass);
query.setFirstResult(first);
query.setMaxResults(count);
query.setHint(QueryHints.HINT_CACHEABLE, "true");
return query.getResultList();
}
});
}
@Transactional
public List<T> findAll(final int first, final int count, final String orderBy) {
return getJpaTemplate().execute(new JpaCallback<List<T>>() {
public List<T> doInJpa(EntityManager em) throws PersistenceException {
String queryString = "SELECT x FROM "+domainClassString+" x ORDER BY x."+orderBy;
TypedQuery<T> query = em.createQuery(queryString, domainClass);
query.setFirstResult(first);
query.setMaxResults(count);
query.setHint(QueryHints.HINT_CACHEABLE, "true");
return query.getResultList();
}
});
}
}

@ -0,0 +1,46 @@
package se.su.dsv.scipro.data.dao.jpa;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceException;
import javax.persistence.TypedQuery;
import org.springframework.orm.jpa.JpaCallback;
import org.springframework.transaction.annotation.Transactional;
import se.su.dsv.scipro.data.dao.interfaces.EventDao;
import se.su.dsv.scipro.data.dataobjects.Event;
/**
* @author Richard Wilkinson - richard.wilkinson@jweekend.com
*
*/
public class EventDaoJPAImp extends AbstractDaoJPAImpl<Event> implements EventDao {
public EventDaoJPAImp() {
super(Event.class);
}
@Transactional
public List<Event> findAll() {
return getJpaTemplate().execute(new JpaCallback<List<Event>>() {
public List<Event> doInJpa(EntityManager em) throws PersistenceException {
TypedQuery<Event> query = em.createQuery("select e from Event e", Event.class);
return query.getResultList();
}
});
}
@Transactional
public int countAll() {
return getJpaTemplate().execute(new JpaCallback<Integer>() {
public Integer doInJpa(EntityManager em) throws PersistenceException {
TypedQuery<Long> query = em.createQuery("select count (e) from Event e", Long.class);
return (query.getSingleResult()).intValue();
}
});
}
}

@ -0,0 +1,128 @@
package se.su.dsv.scipro.data.dao.jpa;
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.dao.interfaces.LazyDeletable;
import se.su.dsv.scipro.data.dao.interfaces.LazyDeleteDao;
import se.su.dsv.scipro.data.dataobjects.DomainObject;
/**
*
* @author Martin Peters - mpeters@dsv.su.se
*
* @param <T>
*/
public abstract class LazyDeleteAbstractDaoJPAImpl<T extends DomainObject & LazyDeletable> extends AbstractDaoJPAImpl<T> implements LazyDeleteDao<T> {
public LazyDeleteAbstractDaoJPAImpl(Class<T> domainClass) {
super(domainClass);
}
@Transactional
public T lazyDelete(T o){
o.setDeleted(true);
return save(o);
}
@Override
@Transactional
public int countAll() {
return getJpaTemplate().execute(new JpaCallback<Integer>() {
public Integer doInJpa(EntityManager em) throws PersistenceException {
TypedQuery<Long> query = em.createQuery("SELECT COUNT (x) FROM "+domainClassString+" x WHERE x.deleted = false", Long.class);
query.setHint(QueryHints.HINT_CACHEABLE, "true");
return (query.getSingleResult()).intValue();
}
});
}
@Transactional
public int countAllLazyDeleted() {
return getJpaTemplate().execute(new JpaCallback<Integer>() {
public Integer doInJpa(EntityManager em) throws PersistenceException {
TypedQuery<Long> query = em.createQuery("SELECT COUNT (x) FROM "+domainClassString+" x WHERE x.deleted = true", Long.class);
query.setHint(QueryHints.HINT_CACHEABLE, "true");
return (query.getSingleResult()).intValue();
}
});
}
@Override
@Transactional
public List<T> findAll() {
return getJpaTemplate().execute(new JpaCallback<List<T>>() {
public List<T> doInJpa(EntityManager em) throws PersistenceException {
TypedQuery<T> query = em.createQuery("SELECT x FROM "+domainClassString+" x WHERE x.deleted = false", domainClass);
query.setHint(QueryHints.HINT_CACHEABLE, "true");
return query.getResultList();
}
});
}
@Transactional
public List<T> findAllLazyDeleted() {
return getJpaTemplate().execute(new JpaCallback<List<T>>() {
public List<T> doInJpa(EntityManager em) throws PersistenceException {
TypedQuery<T> query = em.createQuery("SELECT x FROM "+domainClassString+" x WHERE x.deleted = true", domainClass);
query.setHint(QueryHints.HINT_CACHEABLE, "true");
return query.getResultList();
}
});
}
@Override
@Transactional
public List<T> findAll(final int first, final int count) {
return getJpaTemplate().execute(new JpaCallback<List<T>>() {
public List<T> doInJpa(EntityManager em) throws PersistenceException {
TypedQuery<T> query = em.createQuery("SELECT x FROM "+domainClassString+" x WHERE x.deleted = false", domainClass);
query.setFirstResult(first);
query.setMaxResults(count);
query.setHint(QueryHints.HINT_CACHEABLE, "true");
return query.getResultList();
}
});
}
@Transactional
public List<T> findAllLazyDeleted(final int first, final int count) {
return getJpaTemplate().execute(new JpaCallback<List<T>>() {
public List<T> doInJpa(EntityManager em) throws PersistenceException {
TypedQuery<T> query = em.createQuery("SELECT x FROM "+domainClassString+" x WHERE x.deleted = true", domainClass);
query.setFirstResult(first);
query.setMaxResults(count);
query.setHint(QueryHints.HINT_CACHEABLE, "true");
return query.getResultList();
}
});
}
@Override
@Transactional
public List<T> findAll(final int first, final int count, final String orderBy) {
return getJpaTemplate().execute(new JpaCallback<List<T>>() {
public List<T> doInJpa(EntityManager em) throws PersistenceException {
String queryString = "SELECT x FROM "+domainClassString+" x WHERE x.deleted = false ORDER BY x."+orderBy;
TypedQuery<T> query = em.createQuery(queryString, domainClass);
query.setFirstResult(first);
query.setMaxResults(count);
query.setHint(QueryHints.HINT_CACHEABLE, "true");
return query.getResultList();
}
});
}
}

@ -0,0 +1,70 @@
package se.su.dsv.scipro.data.dao.jpa;
import javax.persistence.EntityManager;
import javax.persistence.NoResultException;
import javax.persistence.PersistenceException;
import javax.persistence.TypedQuery;
import org.springframework.orm.jpa.JpaCallback;
import org.springframework.transaction.annotation.Transactional;
import se.su.dsv.scipro.data.dao.interfaces.UserDao;
import se.su.dsv.scipro.data.dataobjects.User;
public class UserDaoJPAImp extends LazyDeleteAbstractDaoJPAImpl<User> implements
UserDao {
public UserDaoJPAImp() {
super(User.class);
}
@Transactional
public User getUserByIdentifier(final Long identifier){
return getJpaTemplate().execute(new JpaCallback<User>() {
public User doInJpa(EntityManager em)
throws PersistenceException {
TypedQuery<User> query = em.createQuery("select u FROM User u WHERE u.identifier = :identifier", User.class);
query.setParameter("identifier", identifier);
try{
return query.getSingleResult();
} catch (NoResultException e) {
return null;
}
}
});
}
@Transactional
public User getUserByEmail(final String emailAddress){
return getJpaTemplate().execute(new JpaCallback<User>() {
public User doInJpa(EntityManager em)
throws PersistenceException {
TypedQuery<User> query = em.createQuery("select u FROM User u WHERE u.emailAddress = :email", User.class);
query.setParameter("email", emailAddress);
try{
return query.getSingleResult();
} catch (NoResultException e) {
return null;
}
}
});
}
@Transactional
public User getUserByUsername(final String username){
return getJpaTemplate().execute(new JpaCallback<User>() {
public User doInJpa(EntityManager em)
throws PersistenceException {
TypedQuery<User> query = em.createQuery("select u FROM User u, Username un WHERE un.username = :username and un.user = u", User.class);
query.setParameter("username", username);
try{
return query.getSingleResult();
} catch (NoResultException e) {
return null;
}
}
});
}
}

@ -0,0 +1,43 @@
package se.su.dsv.scipro.data.dao.jpa;
import java.util.ArrayList;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.NoResultException;
import javax.persistence.PersistenceException;
import javax.persistence.TypedQuery;
import org.springframework.orm.jpa.JpaCallback;
import org.springframework.transaction.annotation.Transactional;
import se.su.dsv.scipro.data.dao.interfaces.UsernameDao;
import se.su.dsv.scipro.data.dataobjects.User;
import se.su.dsv.scipro.data.dataobjects.Username;
public class UserNameDaoJPAImp extends AbstractDaoJPAImpl<Username> implements UsernameDao{
public UserNameDaoJPAImp() {
super(Username.class);
}
@Transactional
public List<Username> getUsernamesByUser(final User user) {
return getJpaTemplate().execute(new JpaCallback<List<Username>>() {
public List<Username> doInJpa(EntityManager em)
throws PersistenceException {
TypedQuery<Username> query = em.createQuery("select un FROM User u, Username un WHERE u = :user and un.user = u", Username.class);
query.setParameter("user", user);
try{
return query.getResultList();
} catch (NoResultException e) {
return new ArrayList<Username>(1);
}
}
});
}
}

@ -0,0 +1,18 @@
package se.su.dsv.scipro.data.dataobjects;
import javax.persistence.MappedSuperclass;
import org.apache.wicket.IClusterable;
/**
*
* @author Martin Peters - mpeters@dsv.su.se
*
*/
@MappedSuperclass
public abstract class DomainObject implements IClusterable{
private static final long serialVersionUID = 1L;
abstract public Long getId();
}

@ -0,0 +1,92 @@
package se.su.dsv.scipro.data.dataobjects;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;
/**
* @author Richard Wilkinson - richard.wilkinson@jweekend.com
*
*/
@Entity
@Table(name="Event")
public class Event extends DomainObject {
private static final long serialVersionUID = 2959377496669050427L;
@Id
@GeneratedValue
private Long id;
private String title;
private String location;
public Event() {}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getLocation() {
return location;
}
public void setLocation(String location) {
this.location = location;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((id == null) ? 0 : id.hashCode());
result = prime * result
+ ((location == null) ? 0 : location.hashCode());
result = prime * result + ((title == null) ? 0 : title.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Event other = (Event) obj;
if (id == null) {
if (other.id != null)
return false;
} else if (!id.equals(other.id))
return false;
if (location == null) {
if (other.location != null)
return false;
} else if (!location.equals(other.location))
return false;
if (title == null) {
if (other.title != null)
return false;
} else if (!title.equals(other.title))
return false;
return true;
}
@Override
public String toString() {
return String.format("Event [id=%s, location=%s, title=%s]", id, location, title);
}
}

@ -0,0 +1,36 @@
package se.su.dsv.scipro.data.dataobjects;
import javax.persistence.MappedSuperclass;
import se.su.dsv.scipro.data.dao.interfaces.LazyDeletable;
/**
*
* @author Martin Peters - mpeters@dsv.su.se
*
*/
@MappedSuperclass
public abstract class LazyDeletableDomainObject extends DomainObject implements LazyDeletable{
private static final long serialVersionUID = 1L;
private boolean deleted = false;
/**
* @param set the object to be lazily deleted or not, does not take effect until after the object being saved.
*/
public void setDeleted(boolean deleted) {
this.deleted = deleted;
}
/**
* @return if the object is lazily deleted or not
*/
public boolean isDeleted() {
return deleted;
}
}

@ -0,0 +1,122 @@
package se.su.dsv.scipro.data.dataobjects;
import java.util.HashSet;
import java.util.Set;
import javax.persistence.Cacheable;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import org.hibernate.annotations.Cache;
import org.hibernate.annotations.CacheConcurrencyStrategy;
/**
* @author Martin Peters - mpeters@dsv.su.se
*
*/
@Entity
@Table(name="User")
@Cacheable(true)
@Cache(usage= CacheConcurrencyStrategy.NONSTRICT_READ_WRITE) //Hibernate specific
public class User extends LazyDeletableDomainObject {
private static final long serialVersionUID = 8116476815877870372L;
@Id
@GeneratedValue
private Long id;
@Column(unique=true)
private Long identifier;
private String firstName;
private String lastName;
@Column(unique=true)
private String emailAddress;
@OneToMany(mappedBy="user")
private Set<Username> usernames = new HashSet<Username>();
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public void setIdentifier(Long identifier) {
this.identifier = identifier;
}
public Long getIdentifier() {
return identifier;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getFirstName() {
return firstName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getLastName() {
return lastName;
}
public void setEmailAddress(String email) {
this.emailAddress = email;
}
public String getEmailAddress() {
return emailAddress;
}
public void setUserNames(Set<Username> usernames) {
this.usernames = usernames;
}
public Set<Username> getUserNames() {
return usernames;
}
@Override
public int hashCode() {
final int weight = 31;
int result = 17;
result = weight * result + ((id == null) ? 0 : (int) (id ^ (id >>> 32)));
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (this.getClass() != obj.getClass())
return false;
User other = (User) obj;
if (id == null) {
if (other.id != null)
return false;
} else if (!id.equals(other.id))
return false;
return true;
}
}

@ -0,0 +1,122 @@
package se.su.dsv.scipro.data.dataobjects;
import javax.persistence.Basic;
import javax.persistence.Cacheable;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import javax.persistence.UniqueConstraint;
import org.hibernate.annotations.Cache;
import org.hibernate.annotations.CacheConcurrencyStrategy;
/**
* @author Martin Peters - mpeters@dsv.su.se
*
*/
@Entity
@Cacheable(true)
@Cache(usage= CacheConcurrencyStrategy.NONSTRICT_READ_WRITE) //Hibernate specific
@Table(name="Username", uniqueConstraints={@UniqueConstraint(columnNames={"username","realm"})})
public class Username extends DomainObject {
private static final long serialVersionUID = -2043481766263425696L;
@Id
@GeneratedValue
private Long id;
@Basic(optional=false)
private String username;
@Basic(optional=false)
private String realm;
@ManyToOne(optional=false)
private User user;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getUserName() {
return username;
}
public void setUserName(String userName) {
this.username = userName;
}
/**
* @param realm the realm to set
*/
public void setRealm(String realm) {
this.realm = realm;
}
/**
* @return the realm
*/
public String getRealm() {
return realm;
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
@Override
public String toString(){
return username;
}
@Override
public int hashCode() {
final int weight = 31;
int result = 17;
result = weight * result + ((id == null) ? 0 : (int) (id ^ (id >>> 32)));
result = weight * result + ((username == null) ? 0 : username.hashCode());
result = weight * result + ((realm == null) ? 0 : realm.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (obj == null)
return false;
if (this == obj)
return true;
if (this.getClass() != obj.getClass())
return false;
Username other = (Username) obj;
if (id == null) {
if (other.id != null)
return false;
} else if (!id.equals(other.id))
return false;
if (username == null) {
if (other.username != null)
return false;
} else if (!username.equals(other.username))
return false;
if (realm == null) {
if (other.realm != null)
return false;
} else if (!realm.equals(other.realm))
return false;
return true;
}
}

@ -0,0 +1,14 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"
xmlns:wicket="http://wicket.apache.org/dtds.data/wicket-xhtml1.4-strict.dtd"
>
<body>
<wicket:extend>
<div id="loginheader" class="thesis-admin-span-12">
<h1>SciPro</h1>
</div>
<div wicket:id="signInPanel"></div>
</wicket:extend>
</body>
</html>

@ -0,0 +1,30 @@
package se.su.dsv.scipro.loginlogout.pages;
import org.apache.wicket.PageParameters;
import org.apache.wicket.RestartResponseException;
import se.su.dsv.scipro.HomePage;
import se.su.dsv.scipro.SciProSession;
import se.su.dsv.scipro.basepages.BasePage;
import se.su.dsv.scipro.loginlogout.panels.LoginPanel;
/**
* Page for logging users into the system
* @param pp the page parameters
* @author Martin Peters - mpeters@dsv.su.se
*/
public class LoginPage extends BasePage {
public LoginPage(final PageParameters pp) throws Exception {
//Redirect to HomePage if user is authenticated
if(SciProSession.get().isLoggedIn()){
getRequestCycle().setRedirect(true);
throw new RestartResponseException(HomePage.class);
}
add(new LoginPanel("signInPanel", true));
}
}

@ -0,0 +1,13 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"
xmlns:wicket="http://wicket.apache.org/dtds.data/wicket-xhtml1.4-strict.dtd"
>
<body>
<wicket:extend>
<div>
<span wicket:id="message">Message here</span><a wicket:id="loginLink"><span wicket:id="linkText">Link text here</span></a>
</div>
</wicket:extend>
</body>
</html>

@ -0,0 +1,23 @@
package se.su.dsv.scipro.loginlogout.pages;
import org.apache.wicket.PageParameters;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.link.BookmarkablePageLink;
import se.su.dsv.scipro.SciProSession;
import se.su.dsv.scipro.basepages.BasePage;
public class LogoutPage extends BasePage {
public LogoutPage(final PageParameters parameters){
SciProSession session = SciProSession.get();
session.invalidate();
add(new Label("message", "You are now logged out. Log back in "));
BookmarkablePageLink<Void> bml = new BookmarkablePageLink<Void>("loginLink", LoginPage.class);
bml.add(new Label("linkText", "here"));
add(bml);
}
}

@ -0,0 +1,58 @@
<!--
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"
xmlns:wicket="http://wicket.apache.org/dtds.data/wicket-xhtml1.4-strict.dtd"
>
<body>
<wicket:panel>
<div style="margin-top: 25px;">&nbsp;</div>
<span wicket:id="feedback"/>
<p class="thesis-admin-prepend-2"><wicket:message key="loginExplanation"/></p>
<form wicket:id="signInForm">
<table class="no-bgcolor-table">
<tr>
<td class="largetext rightaligned"><wicket:message key="username"/>:</td>
<td>
<input wicket:id="username" type="text" class="thesis-admin-title" value="foo@goo.moo" size="30"/>
</td>
</tr>
<tr>
<td class="largetext rightaligned"><wicket:message key="password"/>:</td>
<td>
<input wicket:id="password" type="password" class="thesis-admin-title" value="password" size="30"/>
</td>
</tr>
<tr wicket:id="rememberMeRow">
<td></td>
<td> <input wicket:id="rememberMe" type="checkbox" /> <wicket:message key="rememberMe"/> </td>
</tr>
<tr>
<td></td>
<td>
<input type="submit" name="submit" wicket:message="value:login"/>
<input type="reset" wicket:message="value:reset"/>
</td>
</tr>
</table>
</form>
</wicket:panel>
</body>
</html>

@ -0,0 +1,248 @@
package se.su.dsv.scipro.loginlogout.panels;
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import org.apache.wicket.markup.html.WebMarkupContainer;
import org.apache.wicket.markup.html.form.CheckBox;
import org.apache.wicket.markup.html.form.PasswordTextField;
import org.apache.wicket.markup.html.form.StatelessForm;
import org.apache.wicket.markup.html.form.TextField;
import org.apache.wicket.markup.html.panel.FeedbackPanel;
import org.apache.wicket.markup.html.panel.Panel;
import org.apache.wicket.model.PropertyModel;
import org.apache.wicket.util.value.ValueMap;
import se.su.dsv.scipro.SciProSession;
/**
* Reusable user sign in panel with username and password as well as support for cookie persistence
* of the both. When the SignInPanel's form is submitted, the method signIn(String, String) is
* called, passing the username and password submitted. The signIn() method should authenticate the
* user's session. The default implementation calls AuthenticatedWebSession.get().signIn().
*
* @author Jonathan Locke
* @author Juergen Donnerstag
* @author Eelco Hillenius
*/
public class LoginPanel extends Panel
{
private static final long serialVersionUID = 1L;
/** True if the panel should display a remember-me checkbox */
private boolean includeRememberMe = true;
/** Field for password. */
private PasswordTextField password;
/** True if the user should be remembered via form persistence (cookies) */
private boolean rememberMe = true;
/** Field for user name. */
private TextField<String> username;
/**
* Sign in form.
*/
public final class SignInForm extends StatelessForm<Void>
{
private static final long serialVersionUID = 1L;
/** El-cheapo model for form. */
private final ValueMap properties = new ValueMap();
/**
* Constructor.
*
* @param id
* id of the form component
*/
public SignInForm(final String id)
{
super(id);
// Attach textfield components that edit properties map
// in lieu of a formal beans model
add(username = new TextField<String>("username", new PropertyModel<String>(properties,
"username")));
add(password = new PasswordTextField("password", new PropertyModel<String>(properties,
"password")));
username.setType(String.class);
password.setType(String.class);
// MarkupContainer row for remember me checkbox
final WebMarkupContainer rememberMeRow = new WebMarkupContainer("rememberMeRow");
add(rememberMeRow);
// Add rememberMe checkbox
rememberMeRow.add(new CheckBox("rememberMe", new PropertyModel<Boolean>(
LoginPanel.this, "rememberMe")));
// Make form values persistent
setPersistent(rememberMe);
// Show remember me checkbox?
rememberMeRow.setVisible(includeRememberMe);
}
/**
* @see org.apache.wicket.markup.html.form.Form#onSubmit()
*/
@Override
public final void onSubmit()
{
try{
if (signIn(getUsername(), getPassword()))
{
onSignInSucceeded();
}
else
{
onSignInFailed();
}
} catch(NullPointerException npe){
error("User authentication successful but user was not found in database! Please contact thesissupport@dsv.su.se or try a different username.");
}
}
}
/**
* @see org.apache.wicket.Component#Component(String)
*/
public LoginPanel(final String id)
{
this(id, true);
}
/**
* @param id
* See Component constructor
* @param includeRememberMe
* True if form should include a remember-me checkbox
* @see org.apache.wicket.Component#Component(String)
*/
public LoginPanel(final String id, final boolean includeRememberMe)
{
super(id);
this.includeRememberMe = includeRememberMe;
// Create feedback panel and add to page
final FeedbackPanel feedback = new FeedbackPanel("feedback");
add(feedback);
// Add sign-in form to page, passing feedback panel as
// validation error handler
add(new SignInForm("signInForm"));
}
/**
* Removes persisted form data for the signin panel (forget me)
*/
public final void forgetMe()
{
// Remove persisted user data. Search for child component
// of type SignInForm and remove its related persistence values.
getPage().removePersistedFormData(LoginPanel.SignInForm.class, true);
}
/**
* Convenience method to access the password.
*
* @return The password
*/
public String getPassword()
{
return password.getInput();
}
/**
* Get model object of the rememberMe checkbox
*
* @return True if user should be remembered in the future
*/
public boolean getRememberMe()
{
return rememberMe;
}
/**
* Convenience method to access the username.
*
* @return The user name
*/
public String getUsername()
{
return username.getDefaultModelObjectAsString();
}
/**
* Convenience method set persistence for username and password.
*
* @param enable
* Whether the fields should be persistent
*/
public void setPersistent(final boolean enable)
{
username.setPersistent(enable);
}
/**
* Set model object for rememberMe checkbox
*
* @param rememberMe
*/
public void setRememberMe(final boolean rememberMe)
{
this.rememberMe = rememberMe;
setPersistent(rememberMe);
}
/**
* Sign in user if possible.
*
* @param username
* The username
* @param password
* The password
* @return True if signin was successful
*/
public boolean signIn(String username, String password) throws NullPointerException
{
return SciProSession.get().login(username, password);
}
protected void onSignInFailed()
{
// Try the component based localizer first. If not found try the
// application localizer. Else use the default
error(getLocalizer().getString("loginFailed", this, "Login failed"));
}
protected void onSignInSucceeded()
{
// If login has been called because the user was not yet
// logged in, than continue to the original destination,
// otherwise to the Home page
if (!continueToOriginalDestination())
{
setResponsePage(getApplication().getHomePage());
}
}
}

@ -0,0 +1,7 @@
loginFailed: Login failed
username: Username
password: Password
rememberMe: Remember Me
login: Login
reset: Reset
loginExplanation: Log in with your kerberos credentials

@ -0,0 +1,8 @@
loginFailed: Inloggning misslyckades
signInForm.password= lösenord
username: Användarnamn
password: Lösenord
rememberMe: Kom ihåg mig
login: Logga in
reset: Rensa
loginExplanation: Logga in med ditt kerberoskonto

@ -0,0 +1,25 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"
xmlns:wicket="http://wicket.apache.org/dtds.data/wicket-xhtml1.4-strict.dtd"
>
<head>
<meta http-equiv="Content-type" content="text/html;charset=UTF-8" />
<title>LegUp: Wicket Spring JPA 2.0</title>
</head>
<body>
<strong><a href="http://jweekend.com/dev/LegUp">LegUp</a>: <a href="http://wicket.apache.org/">Wicket</a> <a href="http://www.springsource.org/">Spring</a> JPA 2.0</strong>
<h1>Event Page</h1>
<form wicket:id="eventForm">
<fieldset>
<label>Title</label><input wicket:id="title" type="text" /><br/>
<label>Location</label><input wicket:id="location" type="text"/><br/>
<a wicket:id="submit">Save</a>
</fieldset>
</form>
<ul wicket:id="listContainer">
<li wicket:id="list"><span wicket:id="eventName" /> @ <span wicket:id="eventLocation"/>
</li>
</ul>
</body>
</html>

@ -0,0 +1,71 @@
package se.su.dsv.scipro.pages;
import java.util.List;
import org.apache.wicket.PageParameters;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.ajax.markup.html.form.AjaxSubmitLink;
import org.apache.wicket.markup.html.WebMarkupContainer;
import org.apache.wicket.markup.html.WebPage;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.form.Form;
import org.apache.wicket.markup.html.form.TextField;
import org.apache.wicket.markup.html.list.ListItem;
import org.apache.wicket.markup.html.list.ListView;
import org.apache.wicket.model.CompoundPropertyModel;
import org.apache.wicket.model.PropertyModel;
import org.apache.wicket.spring.injection.annot.SpringBean;
import se.su.dsv.scipro.data.dao.interfaces.EventDao;
import se.su.dsv.scipro.data.dataobjects.Event;
/**
* @author Richard Wilkinson - richard.wilkinson@jweekend.com
*
*/
public class EventPage extends WebPage {
@SpringBean
private EventDao eventDao;
public EventPage(final PageParameters pp)
{
Form<Event> eventForm = new Form<Event>("eventForm", new CompoundPropertyModel<Event>(new Event()));
eventForm.add(new TextField<String>("title").setRequired(true));
eventForm.add(new TextField<String>("location").setRequired(true));
final WebMarkupContainer wmc = new WebMarkupContainer("listContainer");
wmc.add(new ListView<Event>("list", new PropertyModel<List<Event>>(this, "eventDao.findAll")){
private static final long serialVersionUID = 1L;
@Override
protected void populateItem(ListItem<Event> item) {
Event event = item.getModelObject();
item.add(new Label("eventName", event.getTitle()));
item.add(new Label("eventLocation", event.getLocation()));
}
});
wmc.setOutputMarkupId(true);
add(wmc);
eventForm.add(new AjaxSubmitLink("submit"){
private static final long serialVersionUID = 1L;
@Override
protected void onSubmit(AjaxRequestTarget target, Form<?> form) {
Event event = (Event) form.getModelObject();
Event newEvent = new Event();
newEvent.setLocation(event.getLocation());
newEvent.setTitle(event.getTitle());
eventDao.save(newEvent);
target.addComponent(wmc);
}
});
add(eventForm);
}
}

@ -0,0 +1,37 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd"
default-autowire="byName">
<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalEntityManagerFactoryBean">
<property name="persistenceUnitName" value="defaultPersistenceUnit" />
</bean>
<!--
enable the configuration of transactional behavior based on
annotations
-->
<tx:annotation-driven transaction-manager="transactionManager" />
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
<bean id="eventDao" class="se.su.dsv.scipro.data.dao.jpa.EventDaoJPAImp">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
<bean id="userDao" class="se.su.dsv.scipro.data.dao.jpa.UserDaoJPAImp">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
<bean class="se.su.dsv.scipro.DataInitialiser" init-method="dataInit">
<property name="eventDao" ref="eventDao"></property>
</bean>
</beans>

@ -0,0 +1,30 @@
<?xml version="1.0" encoding="UTF-8"?>
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="ehcache.xsd" >
<diskStore path="java.io.tmpdir"/>
<cache
name="org.hibernate.cache.StandardQueryCache"
maxElementsInMemory="500"
eternal="false"
timeToLiveSeconds="600"
overflowToDisk="true"/>
<defaultCache
maxElementsInMemory="10000"
eternal="false"
timeToIdleSeconds="360"
timeToLiveSeconds="600"
overflowToDisk="true"
diskPersistent="false"
diskExpiryThreadIntervalSeconds="120"
memoryStoreEvictionPolicy="LRU"/>
<cache name="se.su.dsv.scipro.data.dataobjects.Username" maxElementsInMemory="1000"/>
<cache name="se.su.dsv.scipro.data.dataobjects.User" maxElementsInMemory="1000"/>
</ehcache>

@ -0,0 +1,3 @@
ThesisJaasUser {
com.sun.security.auth.module.Krb5LoginModule required;
};

@ -0,0 +1,7 @@
[libdefaults]
default_realm = DSV.SU.SE
default_tkt_enctypes = des3-cbc-sha1
[realms]
DSV.SU.SE = {
kdc = kerberos.dsv.su.se
}

@ -0,0 +1,12 @@
log4j.appender.Stdout=org.apache.log4j.ConsoleAppender
log4j.appender.Stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.Stdout.layout.conversionPattern=%-5p - %-26.26c{1} - %m\n
log4j.rootLogger=INFO,Stdout
log4j.logger.wicket=INFO
log4j.logger.wicket.protocol.http.HttpSessionStore=INFO
log4j.logger.wicket.version=INFO
log4j.logger.wicket.RequestCycle=INFO

@ -0,0 +1,3 @@
Manifest-Version: 1.0
Class-Path:

@ -0,0 +1,55 @@
<?xml version="1.0" encoding="ISO-8859-1"?>
<web-app xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
version="2.4">
<display-name>SciPro</display-name>
<!-- Open session in view -->
<filter>
<filter-name>osiv</filter-name>
<filter-class>org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>osiv</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter>
<filter-name>wicket.WicketWarp</filter-name>
<filter-class>org.apache.wicket.protocol.http.WicketFilter</filter-class>
<init-param>
<param-name>applicationClassName</param-name>
<param-value>se.su.dsv.scipro.SciProApplication</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>wicket.WicketWarp</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- Session timeout set to 8 hours -->
<session-config>
<session-timeout>480</session-timeout>
</session-config>
<!-- Use deployment for production, development for development -->
<context-param>
<param-name>configuration</param-name>
<param-value>development</param-value>
<!-- param-value>deployment</param-value-->
</context-param>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
</web-app>

@ -0,0 +1,43 @@
package se.su.dsv.scipro;
import org.mortbay.jetty.Connector;
import org.mortbay.jetty.Server;
import org.mortbay.jetty.bio.SocketConnector;
import org.mortbay.jetty.webapp.WebAppContext;
public class Start {
public static void main(String[] args) throws Exception {
Server server = new Server();
SocketConnector connector = new SocketConnector();
connector.setPort(8080);
server.setConnectors(new Connector[] { connector });
WebAppContext bb = new WebAppContext();
bb.setServer(server);
bb.setContextPath("/");
bb.setWar("src/main/webapp");
// START JMX SERVER
// MBeanServer mBeanServer = ManagementFactory.getPlatformMBeanServer();
// MBeanContainer mBeanContainer = new MBeanContainer(mBeanServer);
// server.getContainer().addEventListener(mBeanContainer);
// mBeanContainer.start();
server.addHandler(bb);
try {
System.out.println(">>> STARTING EMBEDDED JETTY SERVER, PRESS ANY KEY TO STOP");
server.start();
while (System.in.available() == 0) {
Thread.sleep(5000);
}
server.stop();
server.join();
} catch (Exception e) {
e.printStackTrace();
System.exit(100);
}
}
}

@ -0,0 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd"
default-autowire="byName">
<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalEntityManagerFactoryBean">
<property name="persistenceUnitName" value="testPersistenceUnit" />
</bean>
<!--
enable the configuration of transactional behavior based on
annotations
-->
<tx:annotation-driven transaction-manager="transactionManager" />
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
<bean id="eventDao" class="se.su.dsv.scipro.data.dao.jpa.EventDaoJPAImp">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
</beans>

@ -0,0 +1,93 @@
package se.su.dsv.scipro.dao.jpa;
import java.util.ArrayList;
import java.util.List;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.annotation.Rollback;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.transaction.annotation.Transactional;
import se.su.dsv.scipro.data.dao.interfaces.EventDao;
import se.su.dsv.scipro.data.dataobjects.Event;
/**
* @author Richard Wilkinson - richard.wilkinson@jweekend.com
*
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration
public class TestEventDaoJPA {
@Autowired
private EventDao eventDao;
protected Event event;
@Before
public void startTransaction()
{
event = new Event();
event.setLocation("new Location");
event.setTitle("new Title");
event = eventDao.save(event);
}
/**
* Test method for {@link se.su.dsv.scipro.data.dao.jpa.EventDaoJPAImp#findAll()}.
*/
@Test
@Transactional
@Rollback
public void testFindAll() {
List<Event> events = new ArrayList<Event>();
events.add(event);
Assert.assertEquals(events, eventDao.findAll());
}
/**
* Test method for {@link se.su.dsv.scipro.data.dao.jpa.EventDaoJPAImp#countAll()}.
*/
@Test @Transactional
@Rollback
public void testCountAll() {
Assert.assertEquals(1, eventDao.countAll());
}
/**
* Test method for {@link se.su.dsv.scipro.data.dao.jpa.AbstractDaoJPAImpl#delete(? extends se.su.dsv.scipro.data.dataobjects.DomainObject)}.
*/
@Test @Transactional
@Rollback
public void testDelete() {
eventDao.delete(event);
Assert.assertEquals(0, eventDao.countAll());
}
/**
* Test method for {@link se.su.dsv.scipro.data.dao.jpa.AbstractDaoJPAImpl#load(java.io.Serializable)}.
*/
@Test @Transactional
@Rollback
public void testLoad() {
Event event2 = eventDao.load(event.getId());
Assert.assertEquals(event, event2);
}
/**
* Test method for {@link se.su.dsv.scipro.data.dao.jpa.AbstractDaoJPAImpl#save(se.su.dsv.scipro.data.dataobjects.DomainObject)}.
*/
@Test @Transactional
@Rollback
public void testSave() {
//if we have got this far then save works
}
}

@ -0,0 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd"
default-autowire="byName">
<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalEntityManagerFactoryBean">
<property name="persistenceUnitName" value="testPersistenceUnit" />
</bean>
<!--
enable the configuration of transactional behavior based on
annotations
-->
<tx:annotation-driven transaction-manager="transactionManager" />
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
<bean id="userDao" class="se.su.dsv.scipro.data.dao.jpa.UserDaoJPAImp">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
</beans>

@ -0,0 +1,137 @@
package se.su.dsv.scipro.dao.jpa;
import java.util.ArrayList;
import java.util.List;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.annotation.Rollback;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.transaction.annotation.Transactional;
import se.su.dsv.scipro.data.dao.interfaces.UserDao;
import se.su.dsv.scipro.data.dataobjects.User;
/**
*
* @author Martin Peters - mpeters@dsv.su.se
*
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration
public class TestUserDaoJPA {
@Autowired
private UserDao userDao;
protected User user;
protected User deletedUser;
@Before
public void startTransaction()
{
user = new User();
user.setEmailAddress("test@dsv.su.se");
user.setIdentifier(new Long(666));
user.setFirstName("Test");
user.setLastName("Person");
user = userDao.save(user);
deletedUser = new User();
deletedUser.setEmailAddress("testdeleted@dsv.su.se");
deletedUser.setIdentifier(new Long(777));
deletedUser.setFirstName("Test");
deletedUser.setLastName("Person");
deletedUser.setDeleted(true);
deletedUser = userDao.save(deletedUser);
}
/**
* Test method for {@link se.su.dsv.scipro.data.dao.jpa.UserDaoJPAImp#findAll()}.
*/
@Test
@Transactional
@Rollback
public void testFindAll() {
List<User> users = new ArrayList<User>();
users.add(user);
Assert.assertEquals(users, userDao.findAll());
}
/**
* Test method for {@link se.su.dsv.scipro.data.dao.jpa.UserDaoJPAImp#countAll()}.
*/
@Test @Transactional
@Rollback
public void testCountAll() {
Assert.assertEquals(1, userDao.countAll());
}
/**
* Test method for {@link se.su.dsv.scipro.data.dao.jpa.AbstractDaoJPAImpl#delete(? extends se.su.dsv.scipro.data.dataobjects.DomainObject)}.
*/
@Test @Transactional
@Rollback
public void testDelete() {
userDao.delete(user);
Assert.assertEquals(0, userDao.countAll());
}
/**
* Test method for {@link se.su.dsv.scipro.data.dao.jpa.AbstractDaoJPAImpl#load(java.io.Serializable)}.
*/
@Test @Transactional
@Rollback
public void testLazyDelete() {
user = userDao.lazyDelete(user);
Assert.assertEquals(0, userDao.countAll());
}
/**
* Test method for {@link se.su.dsv.scipro.data.dao.jpa.LazyDeleteAbstractDaoJPAImpl#lazyDelete(? extends se.su.dsv.scipro.data.dataobjects.LazyDeletableDomainObject)}.
*/
@Test @Transactional
@Rollback
public void testLoad() {
User user2 = userDao.load(user.getId());
Assert.assertEquals(user, user2);
}
/**
* Test method for {@link se.su.dsv.scipro.data.dao.jpa.AbstractDaoJPAImpl#save(se.su.dsv.scipro.data.dataobjects.DomainObject)}.
*/
@Test @Transactional
@Rollback
public void testSave() {
//if we have got this far then save works
}
/**
* Test method for {@link se.su.dsv.scipro.data.dao.jpa.LazyDeleteAbstractDaoJPAImpl#countAllLazyDeleted())}.
*/
@Test @Transactional
@Rollback
public void testCountAllLazyDeleted() {
Assert.assertEquals(1, userDao.countAllLazyDeleted());
}
/**
* Test method for {@link se.su.dsv.scipro.data.dao.jpa.LazyDeleteAbstractDaoJPAImpl#findAllLazyDeleted())}.
*/
@Test @Transactional
@Rollback
public void testFindAllLazyDeleted() {
List<User> users = new ArrayList<User>();
users.add(deletedUser);
Assert.assertEquals(users, userDao.findAllLazyDeleted());
}
}

@ -0,0 +1,66 @@
package se.su.dsv.scipro.wicket;
import org.apache.wicket.spring.injection.annot.SpringComponentInjector;
import org.apache.wicket.spring.test.ApplicationContextMock;
import org.apache.wicket.util.tester.WicketTester;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Mockito;
import se.su.dsv.scipro.HomePage;
import se.su.dsv.scipro.SciProApplication;
import se.su.dsv.scipro.data.dao.interfaces.EventDao;
import se.su.dsv.scipro.data.dao.interfaces.UserDao;
import se.su.dsv.scipro.loginlogout.pages.LoginPage;
import se.su.dsv.scipro.pages.EventPage;
/**
* @author Richard Wilkinson - richard.wilkinson@jweekend.com
*
*/
public class TestWicketPages {
protected WicketTester tester;
@Before
public void setup()
{
final ApplicationContextMock acm = new ApplicationContextMock();
EventDao eventDao = Mockito.mock(EventDao.class);
UserDao userDao = Mockito.mock(UserDao.class);
acm.putBean("eventDao", eventDao);
acm.putBean("userDao", userDao);
tester = new WicketTester(new SciProApplication(){
/* (non-Javadoc)
* @see se.su.dsv.scipro.WicketApplication#getGuiceInjector()
*/
@Override
protected SpringComponentInjector getSpringInjector() {
return new SpringComponentInjector(this, acm, true);
}
});
}
@Test
public void testStartPage()
{
tester.startPage(HomePage.class);
}
@Test
public void testEventPage()
{
tester.startPage(EventPage.class);
}
@Test
public void testLoginPage()
{
tester.startPage(LoginPage.class);
}
}