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

Conflicts:
	src/test/java/se/su/dsv/scipro/configuration/TestDeployConfiguration.java
	src/test/java/se/su/dsv/scipro/dao/jpa/TestActivityPlanDaoJPA.java
	src/test/java/se/su/dsv/scipro/dao/jpa/TestBoardMessageDaoJPA.java
	src/test/java/se/su/dsv/scipro/dao/jpa/TestCategoryDaoJPA.java
	src/test/java/se/su/dsv/scipro/dao/jpa/TestCheckListTemplateDao.java
	src/test/java/se/su/dsv/scipro/dao/jpa/TestCheckPlagiarismEventDaoJPA.java
	src/test/java/se/su/dsv/scipro/dao/jpa/TestCommentThreadDaoJPA.java
	src/test/java/se/su/dsv/scipro/dao/jpa/TestFinalSeminarDaoJPA.java
	src/test/java/se/su/dsv/scipro/dao/jpa/TestMessageBoardDaoJPA.java
	src/test/java/se/su/dsv/scipro/dao/jpa/TestPeerReviewDaoJPA.java
	src/test/java/se/su/dsv/scipro/dao/jpa/TestPrivateMessageDaoJPA.java
	src/test/java/se/su/dsv/scipro/dao/jpa/TestProjectDaoJPA.java
	src/test/java/se/su/dsv/scipro/dao/jpa/TestProjectPartnerDaoJPA.java
	src/test/java/se/su/dsv/scipro/dao/jpa/TestRatableDaoJPA.java
	src/test/java/se/su/dsv/scipro/dao/jpa/TestRecipientDaoJPA.java
	src/test/java/se/su/dsv/scipro/dao/jpa/TestResourceDaoJPA.java
	src/test/java/se/su/dsv/scipro/dao/jpa/TestRoleDaoJPA.java
	src/test/java/se/su/dsv/scipro/dao/jpa/TestScheduleTemplateDaoJPA.java
	src/test/java/se/su/dsv/scipro/dao/jpa/TestStringResourceDaoJPA.java
	src/test/java/se/su/dsv/scipro/dao/jpa/TestTagDaoJPA.java
	src/test/java/se/su/dsv/scipro/dao/jpa/TestUserDaoJPA.java
	src/test/java/se/su/dsv/scipro/dao/jpa/TestWebNotificationDaoJPA.java
	src/test/java/se/su/dsv/scipro/data/dao/jpa/TestQuery.java
	src/test/java/se/su/dsv/scipro/data/dao/jpa/TestQuerySet.java
	src/test/java/se/su/dsv/scipro/dataproviders/TestSortableDataProvider.java
	src/test/java/se/su/dsv/scipro/match/TestGreedyMatchingAlgorithm.java
	src/test/java/se/su/dsv/scipro/match/TestMatcher.java
	src/test/java/se/su/dsv/scipro/match/dao/TestApplicationPeriodDao.java
	src/test/java/se/su/dsv/scipro/match/dao/TestAuthorDao.java
	src/test/java/se/su/dsv/scipro/match/dao/TestExemptionDao.java
	src/test/java/se/su/dsv/scipro/match/dao/TestKeywordDao.java
	src/test/java/se/su/dsv/scipro/match/dao/TestMatchDao.java
	src/test/java/se/su/dsv/scipro/match/dao/TestProjectIdeaDao.java
	src/test/java/se/su/dsv/scipro/match/dao/TestSupervisorDao.java
	src/test/java/se/su/dsv/scipro/match/dataobject/TestProjectIdea.java
This commit is contained in:
Tom Vahlman 2012-03-26 11:36:34 +02:00
commit 64b6b2a4ef
198 changed files with 15457 additions and 4933 deletions
pom.xml
resources/db_update_scripts
src/main/java/se/su/dsv/scipro
SciProApplication.java
activityplan/panels
admin
pages
panels
basepages
checklists/panels
commentthread/panels
components
data
icons
keywords
match

861
pom.xml

@ -1,409 +1,452 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>se.su.dsv</groupId>
<artifactId>SciPro</artifactId>
<packaging>war</packaging>
<name>Wicket Spring JPA</name>
<repositories>
<repository>
<id>jboss</id>
<name>JBoss Repository</name>
<url>https://repository.jboss.org/nexus/content/groups/public/</url>
</repository>
<repository>
<id>wiquery repository</id>
<name>wiQuery repository</name>
<url>http://wiquery.googlecode.com/svn/repo/</url>
<layout>default</layout>
</repository>
</repositories>
<dependencies>
<!-- WICKET DEPENDENCIES -->
<dependency>
<groupId>org.apache.wicket</groupId>
<artifactId>wicket</artifactId>
<version>${wicket.version}</version>
</dependency>
<dependency>
<groupId>org.apache.wicket</groupId>
<artifactId>wicket-spring</artifactId>
<version>${wicket.version}</version>
</dependency>
<!-- Servlet API, needed for compilation. -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
<scope>provided</scope>
</dependency>
<!-- Apache commons -->
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>1.5</version>
</dependency>
<!-- LOGGING DEPENDENCIES - LOG4J -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${slf4j.version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>${slf4j.version}</version>
<scope>runtime</scope>
</dependency>
<!-- since we want the jcl over slf4j, we need to bump up the version of
slf4j-api that wicket brings in -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jcl-over-slf4j</artifactId>
<version>${slf4j.version}</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.16</version>
</dependency>
<dependency>
<groupId>hsqldb</groupId>
<artifactId>hsqldb</artifactId>
<version>1.8.0.10</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.13</version>
</dependency>
<!-- Spring Deps -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${org.springframework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${org.springframework.version}</version>
<exclusions>
<exclusion>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>${org.springframework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>${org.springframework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>${org.springframework.version}</version>
</dependency>
<dependency>
<groupId>commons-dbcp</groupId>
<artifactId>commons-dbcp</artifactId>
<version>1.4</version>
<scope>runtime</scope>
</dependency>
<!-- JPA -->
<!-- Hibernate impl -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>${hibernate.version}</version>
</dependency>
<dependency>
<groupId>org.mortbay.jetty</groupId>
<artifactId>jetty</artifactId>
<version>${jetty.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.8.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>1.8.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${org.springframework.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-c3p0</artifactId>
<version>${hibernate.version}</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-ehcache</artifactId>
<version>${hibernate.version}</version>
</dependency>
<!-- Jackrabbit dependencies -->
<dependency>
<groupId>org.apache.jackrabbit</groupId>
<artifactId>jackrabbit-core</artifactId>
<version>2.2.1</version>
</dependency>
<dependency>
<groupId>javax.jcr</groupId>
<artifactId>jcr</artifactId>
<version>2.0</version>
</dependency>
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>2.6</version>
</dependency>
<dependency>
<groupId>eu.medsea.mimeutil</groupId>
<artifactId>mime-util</artifactId>
<version>2.1.3</version>
</dependency>
<!-- Additional dependencies -->
<dependency>
<groupId>org.apache.wicket</groupId>
<artifactId>wicket-extensions</artifactId>
<version>${wicket.version}</version>
</dependency>
<dependency>
<groupId>org.odlabs.wiquery</groupId>
<artifactId>wiquery</artifactId>
<version>${wiquery.version}</version>
</dependency>
<dependency>
<groupId>org.wicketstuff</groupId>
<artifactId>minis</artifactId>
<version>${wicket.version}</version>
</dependency>
<dependency>
<groupId>joda-time</groupId>
<artifactId>joda-time</artifactId>
<version>1.6.2</version>
</dependency>
<dependency>
<groupId>org.apache.wicket</groupId>
<artifactId>wicket-datetime</artifactId>
<version>${wicket.version}</version>
</dependency>
<dependency>
<groupId>org.wicketstuff</groupId>
<artifactId>objectautocomplete</artifactId>
<version>${wicket.version}</version>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>1.6</version>
</dependency>
<dependency>
<groupId>javax.mail</groupId>
<artifactId>mail</artifactId>
<version>1.4.1</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>4.1.0.Final</version>
</dependency>
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
<version>1.0.0.GA</version>
</dependency>
<dependency>
<groupId>biz.source_code</groupId>
<artifactId>base64coder</artifactId>
<version>2010-09-21</version>
</dependency>
<!-- Library with wicket components -->
<dependency>
<groupId>org.wamblee</groupId>
<artifactId>wamblee-wicket-components</artifactId>
<version>0.6</version>
</dependency>
<!-- GUI test dependencies -->
<dependency>
<!-- jsoup HTML parser library @ http://jsoup.org/ -->
<groupId>org.jsoup</groupId>
<artifactId>jsoup</artifactId>
<version>1.6.1</version>
<scope>test</scope>
</dependency>
<!-- <dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
<version>1.0.0.GA</version>
</dependency>-->
</dependencies>
<version>0.1-SNAPSHOT</version>
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**</include>
</includes>
<excludes>
<exclude>**/*.java</exclude>
</excludes>
</resource>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**</include>
</includes>
<excludes>
<exclude>**/*.java</exclude>
</excludes>
</resource>
</resources>
<testResources>
<testResource>
<directory>src/test/java</directory>
<includes>
<include>**</include>
</includes>
<excludes>
<exclude>**/*.java</exclude>
</excludes>
</testResource>
<testResource>
<directory>src/test/resources</directory>
<includes>
<include>**</include>
</includes>
<excludes>
<exclude>**/*.java</exclude>
</excludes>
</testResource>
</testResources>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.10</version>
<configuration>
<argLine>-Xmx512m</argLine>
</configuration>
</plugin>
<plugin>
<version>2.3.2</version>
<inherited>true</inherited>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.6</source>
<target>1.6</target>
</configuration>
</plugin>
<plugin>
<groupId>org.mortbay.jetty</groupId>
<artifactId>maven-jetty-plugin</artifactId>
<version>${jetty.version}</version>
</plugin>
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>2.1.1</version>
<configuration>
<packagingExcludes>WEB-INF/web.xml</packagingExcludes>
</configuration>
</plugin>
<!--
&lt;!&ndash; Used for deploying directly from Maven/Eclipse &ndash;&gt;
<plugin>
<groupId>org.codehaus.cargo</groupId>
<artifactId>cargo-maven2-plugin</artifactId>
<version>1.1.4</version>
<configuration>
&lt;!&ndash; Container configuration &ndash;&gt;
<container>
<containerId>tomcat6x</containerId>
<type>remote</type>
</container>
&lt;!&ndash; Configuration to use with the Container &ndash;&gt;
<configuration>
<type>runtime</type>
<properties>
<cargo.tomcat.manager.url>https://thesis.dsv.su.se/manager</cargo.tomcat.manager.url>
<cargo.remote.username>janne</cargo.remote.username>
<cargo.remote.password>Lai2xoo6</cargo.remote.password>
</properties>
</configuration>
&lt;!&ndash; Deployer configuration &ndash;&gt;
<deployer>
<type>remote</type>
<deployables>
<deployable>
<groupId>se.su.dsv</groupId>
<artifactId>SciPro</artifactId>
<type>war</type>
</deployable>
</deployables>
</deployer>
</configuration>
</plugin>
-->
</plugins>
<finalName>scipro2</finalName>
</build>
<properties>
<slf4j.version>1.6.1</slf4j.version>
<wicket.version>1.4.17</wicket.version>
<wiquery.version>1.2.4</wiquery.version>
<jetty.version>6.1.25</jetty.version>
<hibernate.version>3.5.1-Final</hibernate.version>
<org.springframework.version>3.0.5.RELEASE</org.springframework.version>
</properties>
</project>
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>se.su.dsv</groupId>
<artifactId>SciPro</artifactId>
<packaging>war</packaging>
<name>Wicket Spring JPA</name>
<repositories>
<repository>
<id>jboss</id>
<name>JBoss Repository</name>
<url>https://repository.jboss.org/nexus/content/groups/public/</url>
</repository>
<repository>
<id>wiquery repository</id>
<name>wiQuery repository</name>
<url>http://wiquery.googlecode.com/svn/repo/</url>
<layout>default</layout>
</repository>
</repositories>
<dependencies>
<!-- WICKET DEPENDENCIES -->
<dependency>
<groupId>org.apache.wicket</groupId>
<artifactId>wicket</artifactId>
<version>${wicket.version}</version>
</dependency>
<dependency>
<groupId>org.apache.wicket</groupId>
<artifactId>wicket-spring</artifactId>
<version>${wicket.version}</version>
</dependency>
<!-- Servlet API, needed for compilation. -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
<scope>provided</scope>
</dependency>
<!-- Apache commons -->
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>1.5</version>
</dependency>
<!-- LOGGING DEPENDENCIES - LOG4J -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${slf4j.version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>${slf4j.version}</version>
<scope>runtime</scope>
</dependency>
<!-- since we want the jcl over slf4j, we need to bump up the version of
slf4j-api that wicket brings in -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jcl-over-slf4j</artifactId>
<version>${slf4j.version}</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.16</version>
</dependency>
<dependency>
<groupId>hsqldb</groupId>
<artifactId>hsqldb</artifactId>
<version>1.8.0.10</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.13</version>
</dependency>
<!-- Spring Deps -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${org.springframework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${org.springframework.version}</version>
<exclusions>
<exclusion>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>${org.springframework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>${org.springframework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>${org.springframework.version}</version>
</dependency>
<dependency>
<groupId>commons-dbcp</groupId>
<artifactId>commons-dbcp</artifactId>
<version>1.4</version>
<scope>runtime</scope>
</dependency>
<!-- JPA -->
<!-- Hibernate impl -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>${hibernate.version}</version>
</dependency>
<dependency>
<groupId>org.mortbay.jetty</groupId>
<artifactId>jetty</artifactId>
<version>${jetty.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.8.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>1.8.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${org.springframework.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-c3p0</artifactId>
<version>${hibernate.version}</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-ehcache</artifactId>
<version>${hibernate.version}</version>
</dependency>
<!-- Jackrabbit dependencies -->
<dependency>
<groupId>org.apache.jackrabbit</groupId>
<artifactId>jackrabbit-core</artifactId>
<version>2.2.1</version>
</dependency>
<dependency>
<groupId>javax.jcr</groupId>
<artifactId>jcr</artifactId>
<version>2.0</version>
</dependency>
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>2.6</version>
</dependency>
<dependency>
<groupId>eu.medsea.mimeutil</groupId>
<artifactId>mime-util</artifactId>
<version>2.1.3</version>
</dependency>
<!-- Additional dependencies -->
<dependency>
<groupId>org.apache.wicket</groupId>
<artifactId>wicket-extensions</artifactId>
<version>${wicket.version}</version>
</dependency>
<dependency>
<groupId>org.odlabs.wiquery</groupId>
<artifactId>wiquery</artifactId>
<version>${wiquery.version}</version>
</dependency>
<dependency>
<groupId>org.wicketstuff</groupId>
<artifactId>minis</artifactId>
<version>${wicket.version}</version>
</dependency>
<dependency>
<groupId>joda-time</groupId>
<artifactId>joda-time</artifactId>
<version>1.6.2</version>
</dependency>
<dependency>
<groupId>org.apache.wicket</groupId>
<artifactId>wicket-datetime</artifactId>
<version>${wicket.version}</version>
</dependency>
<dependency>
<groupId>org.wicketstuff</groupId>
<artifactId>objectautocomplete</artifactId>
<version>${wicket.version}</version>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>1.6</version>
</dependency>
<dependency>
<groupId>javax.mail</groupId>
<artifactId>mail</artifactId>
<version>1.4.1</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>4.1.0.Final</version>
</dependency>
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
<version>1.0.0.GA</version>
</dependency>
<dependency>
<groupId>biz.source_code</groupId>
<artifactId>base64coder</artifactId>
<version>2010-09-21</version>
</dependency>
<!-- Library with wicket components -->
<dependency>
<groupId>org.wamblee</groupId>
<artifactId>wamblee-wicket-components</artifactId>
<version>0.6</version>
</dependency>
<!-- GUI test dependencies -->
<dependency>
<!-- jsoup HTML parser library @ http://jsoup.org/ -->
<groupId>org.jsoup</groupId>
<artifactId>jsoup</artifactId>
<version>1.6.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.visural</groupId>
<artifactId>visural-common</artifactId>
<version>0.4.3</version>
</dependency>
<dependency>
<groupId>com.visural</groupId>
<artifactId>visural-wicket</artifactId>
<version>0.6.5</version>
</dependency>
<dependency>
<groupId>se.su.dsv</groupId>
<artifactId>wicket-components</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
<version>0.1-SNAPSHOT</version>
<build>
<resources>
<resource>
<filtering>true</filtering>
<directory>src/main/resources</directory>
<includes>
<include>**</include>
</includes>
<excludes>
<exclude>**/*.java</exclude>
</excludes>
</resource>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**</include>
</includes>
<excludes>
<exclude>**/*.java</exclude>
</excludes>
</resource>
</resources>
<testResources>
<testResource>
<directory>src/test/java</directory>
<includes>
<include>**</include>
</includes>
<excludes>
<exclude>**/*.java</exclude>
</excludes>
</testResource>
<testResource>
<filtering>true</filtering>
<directory>src/test/resources</directory>
<includes>
<include>**</include>
</includes>
<excludes>
<exclude>**/*.java</exclude>
</excludes>
</testResource>
</testResources>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.10</version>
<configuration>
<argLine>-Xmx512m</argLine>
</configuration>
</plugin>
<plugin>
<version>2.3.2</version>
<inherited>true</inherited>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.6</source>
<target>1.6</target>
</configuration>
</plugin>
<plugin>
<groupId>org.mortbay.jetty</groupId>
<artifactId>maven-jetty-plugin</artifactId>
<version>${jetty.version}</version>
</plugin>
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>2.1.1</version>
<configuration>
<packagingExcludes>WEB-INF/web.xml</packagingExcludes>
</configuration>
</plugin>
<!--
&lt;!&ndash; Used for deploying directly from Maven/Eclipse &ndash;&gt;
<plugin>
<groupId>org.codehaus.cargo</groupId>
<artifactId>cargo-maven2-plugin</artifactId>
<version>1.1.4</version>
<configuration>
&lt;!&ndash; Container configuration &ndash;&gt;
<container>
<containerId>tomcat6x</containerId>
<type>remote</type>
</container>
&lt;!&ndash; Configuration to use with the Container &ndash;&gt;
<configuration>
<type>runtime</type>
<properties>
<cargo.tomcat.manager.url>https://thesis.dsv.su.se/manager</cargo.tomcat.manager.url>
<cargo.remote.username>janne</cargo.remote.username>
<cargo.remote.password>Lai2xoo6</cargo.remote.password>
</properties>
</configuration>
&lt;!&ndash; Deployer configuration &ndash;&gt;
<deployer>
<type>remote</type>
<deployables>
<deployable>
<groupId>se.su.dsv</groupId>
<artifactId>SciPro</artifactId>
<type>war</type>
</deployable>
</deployables>
</deployer>
</configuration>
</plugin>
-->
</plugins>
<finalName>scipro2</finalName>
</build>
<properties>
<slf4j.version>1.6.1</slf4j.version>
<wicket.version>1.4.17</wicket.version>
<wiquery.version>1.2.4</wiquery.version>
<jetty.version>6.1.25</jetty.version>
<hibernate.version>3.5.1-Final</hibernate.version>
<org.springframework.version>3.0.5.RELEASE</org.springframework.version>
</properties>
<profiles>
<profile>
<id>DEV</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<properties>
<database.showSql>true</database.showSql>
<database.generateDdl>true</database.generateDdl>
<wicket.mode>development</wicket.mode>
</properties>
</profile>
<profile>
<id>TEST</id>
<activation>
<activeByDefault>false</activeByDefault>
</activation>
<properties>
<database.showSql>true</database.showSql>
<database.generateDdl>true</database.generateDdl>
<wicket.mode>deployment</wicket.mode>
</properties>
</profile>
<profile>
<id>PROD</id>
<activation>
<activeByDefault>false</activeByDefault>
</activation>
<properties>
<database.showSql>false</database.showSql>
<database.generateDdl>false</database.generateDdl>
<wicket.mode>deployment</wicket.mode>
</properties>
</profile>
</profiles>
</project>

@ -1,3 +1 @@
ALTER TABLE projectIdea
ADD suggestedReviewer_id bigint(20),
ADD FOREIGN KEY (suggestedReviewer_id) REFERENCES role(id)
ALTER TABLE general_system_settings ADD supervisorsCanAcceptDeclinePIs bit(1) NOT NULL

@ -0,0 +1,16 @@
-- Increase limit on Watson fields
ALTER TABLE `projectIdea` CHANGE `practicalHow` `practicalHow` VARCHAR( 4000 ) CHARACTER SET latin1 COLLATE latin1_swedish_ci NOT NULL;
ALTER TABLE `projectIdea` CHANGE `theoryHow` `theoryHow` VARCHAR( 4000 ) CHARACTER SET latin1 COLLATE latin1_swedish_ci NOT NULL;
ALTER TABLE `projectIdea` CHANGE `what` `what` VARCHAR( 4000 ) CHARACTER SET latin1 COLLATE latin1_swedish_ci NOT NULL;
ALTER TABLE `projectIdea` CHANGE `why` `why` VARCHAR( 4000 ) CHARACTER SET latin1 COLLATE latin1_swedish_ci NOT NULL;
CREATE TABLE IF NOT EXISTS `weights` (
`id` bigint(20) NOT NULL,
`dateCreated` datetime NOT NULL,
`lastModified` datetime NOT NULL,
`version` int(11) NOT NULL,
`keywordPoints` int(11) NOT NULL,
`preferredSupervisorPoints` int(11) NOT NULL,
`researchAreaPoints` int(11) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

@ -0,0 +1,3 @@
ALTER TABLE projectIdea
ADD suggestedReviewer_id bigint(20),
ADD FOREIGN KEY (suggestedReviewer_id) REFERENCES role(id)

@ -1,430 +1,383 @@
package se.su.dsv.scipro;
import java.lang.reflect.InvocationTargetException;
import java.util.Set;
import javax.servlet.http.HttpServletRequest;
import org.apache.log4j.Level;
import org.apache.log4j.Logger;
import org.apache.wicket.Page;
import org.apache.wicket.Request;
import org.apache.wicket.RequestCycle;
import org.apache.wicket.ResourceReference;
import org.apache.wicket.Response;
import org.apache.wicket.Session;
import org.apache.wicket.WicketRuntimeException;
import org.apache.wicket.authorization.strategies.CompoundAuthorizationStrategy;
import org.apache.wicket.protocol.http.WebApplication;
import org.apache.wicket.protocol.http.WebRequest;
import org.apache.wicket.protocol.http.WebRequestCycle;
import org.apache.wicket.settings.IExceptionSettings;
import org.apache.wicket.util.string.Strings;
import org.odlabs.wiquery.ui.themes.IThemableApplication;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;
import se.su.dsv.scipro.activityplan.pages.ProjectActivityPlanPage;
import se.su.dsv.scipro.activityplan.pages.SupervisorActivityPlanPage;
import se.su.dsv.scipro.admin.pages.AdminCheckListPage;
import se.su.dsv.scipro.admin.pages.AdminFinalSeminarPage;
import se.su.dsv.scipro.admin.pages.AdminPeerListPage;
import se.su.dsv.scipro.admin.pages.AdminProjectPartnerPage;
import se.su.dsv.scipro.admin.pages.AdminRolePage;
import se.su.dsv.scipro.admin.pages.AdminScheduleTemplatesEditorPage;
import se.su.dsv.scipro.admin.pages.AdminScheduleTemplatesPage;
import se.su.dsv.scipro.admin.pages.AdminStartPage;
import se.su.dsv.scipro.admin.pages.ProjectManagementPage;
import se.su.dsv.scipro.admin.pages.SystemMaintenancePage;
import se.su.dsv.scipro.admin.pages.settings.AdminFinalSeminarSettingsPage;
import se.su.dsv.scipro.admin.pages.settings.AdminFinalSeminarSettingsPerProjectClassPage;
import se.su.dsv.scipro.admin.pages.settings.AdminGeneralSettingsPage;
import se.su.dsv.scipro.admin.pages.settings.AdminPeerSettingsPage;
import se.su.dsv.scipro.admin.pages.settings.AdminServerEnvironmentSettingsPage;
import se.su.dsv.scipro.basepages.DemoPage;
import se.su.dsv.scipro.basepages.errorpages.AccessDeniedPage;
import se.su.dsv.scipro.basepages.errorpages.CustomErrorPageFactory;
import se.su.dsv.scipro.basepages.errorpages.InternalErrorPage;
import se.su.dsv.scipro.basepages.errorpages.NotFoundPage;
import se.su.dsv.scipro.basepages.errorpages.PageExpiredPage;
import se.su.dsv.scipro.conference.pages.ProjectConferencePage;
import se.su.dsv.scipro.conference.pages.SupervisorConferencePage;
import se.su.dsv.scipro.exceptions.RenderingSafeException;
import se.su.dsv.scipro.json.pages.JsonDeletePrivateMessagePage;
import se.su.dsv.scipro.json.pages.JsonDeleteRecipientPage;
import se.su.dsv.scipro.json.pages.JsonLoginPage;
import se.su.dsv.scipro.json.pages.JsonMessagePage;
import se.su.dsv.scipro.json.pages.JsonMessagePageCountUnread;
import se.su.dsv.scipro.json.pages.JsonNewMessagePage;
import se.su.dsv.scipro.json.pages.JsonProjectForSupervisorPage;
import se.su.dsv.scipro.json.pages.JsonSentMessagePage;
import se.su.dsv.scipro.json.pages.JsonSetReadPage;
import se.su.dsv.scipro.json.pages.JsonSetStatusPage;
import se.su.dsv.scipro.json.pages.JsonStatusPage;
import se.su.dsv.scipro.loginlogout.pages.LoginPage;
import se.su.dsv.scipro.loginlogout.pages.LogoutPage;
import se.su.dsv.scipro.message.pages.PrivateMessagesPage;
import se.su.dsv.scipro.peer.pages.AdminPeerReviewPage;
import se.su.dsv.scipro.peer.pages.PeerRequestSubmissionPage;
import se.su.dsv.scipro.peer.pages.ProjectPeerPortalPage;
import se.su.dsv.scipro.peer.pages.ProjectPeerReviewGuidePage;
import se.su.dsv.scipro.peer.pages.ProjectPeerReviewPage;
import se.su.dsv.scipro.peer.pages.ProjectPeerStatsPage;
import se.su.dsv.scipro.peer.pages.SupervisorPeerPortalPage;
import se.su.dsv.scipro.peer.pages.SupervisorPeerReviewGuidePage;
import se.su.dsv.scipro.peer.pages.SupervisorPeerReviewPage;
import se.su.dsv.scipro.peer.pages.SupervisorPeerStatsPage;
import se.su.dsv.scipro.project.pages.FinalSeminarProjectListPage;
import se.su.dsv.scipro.project.pages.NoActiveProjectPage;
import se.su.dsv.scipro.project.pages.ProjectChecklistPage;
import se.su.dsv.scipro.project.pages.ProjectFilePage;
import se.su.dsv.scipro.project.pages.ProjectIdeaPage;
import se.su.dsv.scipro.project.pages.ProjectIdeaSubmissionPage;
import se.su.dsv.scipro.project.pages.ProjectOppositionPage;
import se.su.dsv.scipro.project.pages.ProjectStartPage;
import se.su.dsv.scipro.project.pages.ProjectViewCheckListPage;
import se.su.dsv.scipro.repository.RepositoryApplication;
import se.su.dsv.scipro.repository.pages.RepositoryDownloadPage;
import se.su.dsv.scipro.repository.pages.SysAdminFilePage;
import se.su.dsv.scipro.schedule.templates.pages.ScheduleTemplateDetailsPage;
import se.su.dsv.scipro.security.auth.ComponentSecurityLogger;
import se.su.dsv.scipro.security.auth.ExternalAuthenticationRequestHelper;
import se.su.dsv.scipro.security.auth.MetaDataActionStrategy;
import se.su.dsv.scipro.security.auth.RoleBasedAuthorizationStrategy;
import se.su.dsv.scipro.security.auth.roles.Roles;
import se.su.dsv.scipro.supervisor.pages.SupervisorAddCheckListToProjectPage;
import se.su.dsv.scipro.supervisor.pages.SupervisorAntiPlagiarismLinkPage;
import se.su.dsv.scipro.supervisor.pages.SupervisorChecklistPage;
import se.su.dsv.scipro.supervisor.pages.SupervisorFilePage;
import se.su.dsv.scipro.supervisor.pages.SupervisorFinalSeminarListingPage;
import se.su.dsv.scipro.supervisor.pages.SupervisorProfilePage;
import se.su.dsv.scipro.supervisor.pages.SupervisorProjectDetailsPage;
import se.su.dsv.scipro.supervisor.pages.SupervisorProjectsFinalSeminarPage;
import se.su.dsv.scipro.supervisor.pages.SupervisorScheduleTemplatesEditorPage;
import se.su.dsv.scipro.supervisor.pages.SupervisorScheduleTemplatesPage;
import se.su.dsv.scipro.supervisor.pages.SupervisorStartPage;
import se.su.dsv.scipro.supervisor.pages.SupervisorViewCheckListPage;
import se.su.dsv.scipro.wiquery.themes.ThemeResourceReference;
/**
* 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 RepositoryApplication implements IThemableApplication {
/*
* 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";
//private Scheduler scheduler = null;
/*
* A string setable in the sys-admin settings page that displays for example a system takedown notice
*/
private String systemNotice = null;
/**
* Logger instance.
*/
private Logger logger = Logger.getLogger(SciProApplication.class);
/**
* Constructor
*/
public SciProApplication()
{
}
@Override
protected void init() {
super.init();
setKerberosConfigs();
getMarkupSettings().setCompressWhitespace(true);
getMarkupSettings().setStripComments(true);
getMarkupSettings().setStripWicketTags(true);
getMarkupSettings().setDefaultMarkupEncoding("UTF-8");
getRequestCycleSettings().setResponseRequestEncoding("UTF-8");
/*
* Unknown pages
*/
mountBookmarkablePage("inbox", PrivateMessagesPage.class);
mountBookmarkablePage("repository/download", RepositoryDownloadPage.class);
/*
* Root pages
*/
mountBookmarkablePage("login", LoginPage.class);
mountBookmarkablePage("logout", LogoutPage.class);
mountBookmarkablePage("demo", DemoPage.class);
/*
* Pop-up pages
*/
mountBookmarkablePage("templates/details", ScheduleTemplateDetailsPage.class);
/*
* JSON pages
*/
mountBookmarkablePage("json/project", JsonProjectForSupervisorPage.class);
mountBookmarkablePage("json/message", JsonMessagePage.class);
mountBookmarkablePage("json/message/unread", JsonMessagePageCountUnread.class);
mountBookmarkablePage("json/message/setread", JsonSetReadPage.class);
mountBookmarkablePage("json/message/deleterecipient", JsonDeleteRecipientPage.class);
mountBookmarkablePage("json/message/deleteprivatemessage", JsonDeletePrivateMessagePage.class);
mountBookmarkablePage("json/message/newmessage", JsonNewMessagePage.class);
mountBookmarkablePage("json/message/sentmessages", JsonSentMessagePage.class);
mountBookmarkablePage("json/login", JsonLoginPage.class);
mountBookmarkablePage("json/status", JsonStatusPage.class);
mountBookmarkablePage("json/setstatus", JsonSetStatusPage.class);
/*
* Admin pages
*/
mountBookmarkablePage("admin/start", AdminStartPage.class);
mountBookmarkablePage("admin/templates", AdminScheduleTemplatesPage.class);
mountBookmarkablePage("admin/templates/editor", AdminScheduleTemplatesEditorPage.class);
mountBookmarkablePage("admin/maintenance", SystemMaintenancePage.class);
mountBookmarkablePage("admin/project", ProjectManagementPage.class);
mountBookmarkablePage("admin/files", SysAdminFilePage.class);
mountBookmarkablePage("admin/allfinalseminars", AdminFinalSeminarPage.class);
mountBookmarkablePage("admin/settings", AdminGeneralSettingsPage.class);
mountBookmarkablePage("admin/settings/serverenvironment", AdminServerEnvironmentSettingsPage.class);
mountBookmarkablePage("admin/settings/finalseminargeneralsettings", AdminFinalSeminarSettingsPage.class);
mountBookmarkablePage("admin/settings/finalseminarprojectlevel", AdminFinalSeminarSettingsPerProjectClassPage.class);
mountBookmarkablePage("admin/settings/peer", AdminPeerSettingsPage.class);
mountBookmarkablePage("admin/roles", AdminRolePage.class);
mountBookmarkablePage("admin/allpeers", AdminPeerListPage.class);
mountBookmarkablePage("admin/peer/review", AdminPeerReviewPage.class);
mountBookmarkablePage("admin/projectpartner", AdminProjectPartnerPage.class);
mountBookmarkablePage("admin/checklist", AdminCheckListPage.class);
/*
* Project pages
*/
mountBookmarkablePage("project/conference", ProjectConferencePage.class);
mountBookmarkablePage("project/activityplan", ProjectActivityPlanPage.class);
mountBookmarkablePage("project/files", ProjectFilePage.class);
mountBookmarkablePage("project/opposition", ProjectOppositionPage.class);
mountBookmarkablePage("project/allfinalseminars", FinalSeminarProjectListPage.class);
mountBookmarkablePage("project", ProjectStartPage.class);
mountBookmarkablePage("noproject", NoActiveProjectPage.class);
mountBookmarkablePage("project/checklist", ProjectChecklistPage.class);
mountBookmarkablePage("project/checklist/viewchecklist", ProjectViewCheckListPage.class);
mountBookmarkablePage("projectideas", ProjectIdeaPage.class);
mountBookmarkablePage("projectideas/submit", ProjectIdeaSubmissionPage.class);
/*
* Supervisor pages
*/
mountBookmarkablePage("supervisor", SupervisorStartPage.class);
mountBookmarkablePage("supervisor/finalseminars", SupervisorProjectsFinalSeminarPage.class);
mountBookmarkablePage("supervisor/allfinalseminars", SupervisorFinalSeminarListingPage.class);
mountBookmarkablePage("supervisor/templates/editor", SupervisorScheduleTemplatesEditorPage.class);
mountBookmarkablePage("supervisor/templates", SupervisorScheduleTemplatesPage.class);
mountBookmarkablePage("supervisor/project/details", SupervisorProjectDetailsPage.class);
mountBookmarkablePage("supervisor/project/details/checklist", SupervisorChecklistPage.class);
mountBookmarkablePage("supervisor/project/details/addchecklist", SupervisorAddCheckListToProjectPage.class);
mountBookmarkablePage("supervisor/antiplagiarism", SupervisorAntiPlagiarismLinkPage.class);
mountBookmarkablePage("supervisor/conference", SupervisorConferencePage.class);
mountBookmarkablePage("supervisor/checklist", SupervisorChecklistPage.class);
mountBookmarkablePage("supervisor/checklist/viewchecklist", SupervisorViewCheckListPage.class);
mountBookmarkablePage("supervisor/profile", SupervisorProfilePage.class);
mountBookmarkablePage("supervisor/project/activityplan", SupervisorActivityPlanPage.class);
mountBookmarkablePage("supervisor/project/files", SupervisorFilePage.class);
/*
* Peer pages
*/
//project
mountBookmarkablePage("project/peer/request", PeerRequestSubmissionPage.class);
mountBookmarkablePage("project/peer", ProjectPeerPortalPage.class);
//When mounted, traffic light images is not working. Needs further work.
mountBookmarkablePage("project/peer/review", ProjectPeerReviewPage.class);
mountBookmarkablePage("project/peer/stats", ProjectPeerStatsPage.class);
mountBookmarkablePage("project/peer/reviewguide", ProjectPeerReviewGuidePage.class);
//supervisor
mountBookmarkablePage("supervisor/peer", SupervisorPeerPortalPage.class);
mountBookmarkablePage("supervisor/peer/stats", SupervisorPeerStatsPage.class);
mountBookmarkablePage("supervisor/peer/review", SupervisorPeerReviewPage.class);
mountBookmarkablePage("supervisor/peer/reviewguide", SupervisorPeerReviewGuidePage.class);
/*
* Error pages, mounted mostly for testing purposes
*/
mountBookmarkablePage("404", NotFoundPage.class);
mountBookmarkablePage("403", AccessDeniedPage.class);
mountBookmarkablePage("500", InternalErrorPage.class);
mountBookmarkablePage("page_expired_error",PageExpiredPage.class);
getApplicationSettings().setAccessDeniedPage(AccessDeniedPage.class);
getApplicationSettings().setInternalErrorPage(InternalErrorPage.class);
getExceptionSettings().setUnexpectedExceptionDisplay(IExceptionSettings.SHOW_INTERNAL_ERROR_PAGE);
getApplicationSettings().setPageExpiredErrorPage(PageExpiredPage.class);
/*
* Set up automatic injection for instanced components.
*/
addComponentInstantiationListener(getSpringInjector());
/*
* Set up authorization strategies for local authentication.
*/
CompoundAuthorizationStrategy cas = new CompoundAuthorizationStrategy();
cas.add(new RoleBasedAuthorizationStrategy());
cas.add(new MetaDataActionStrategy());
getSecuritySettings().setAuthorizationStrategy(cas);
//getResourceSettings().setThrowExceptionOnMissingResource(false);
//getResourceSettings().addStringResourceLoader(new JpaStringResourceLoader());
getResourceSettings().addStringResourceLoader(new NotificationLoader());
getSecuritySettings().setUnauthorizedComponentInstantiationListener(new ComponentSecurityLogger());
/*
* Passing the applicationContext on to workerthreads-scheduler via SchedulerServletContextListener defined in web.xml
*/
WebApplicationContext ctx = WebApplicationContextUtils.getWebApplicationContext(getServletContext());
getServletContext().setAttribute("org.springframework.web.context.WebApplicationContext", ctx);
}
@SuppressWarnings("unchecked")
protected void setKerberosConfigs(){
javax.servlet.ServletContext context = getServletContext();
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);
}
}
@Override
protected void onDestroy() {
//scheduler.stopWorking();
super.onDestroy();
}
/* (non-Javadoc)
* @see org.apache.wicket.Application#getHomePage()
*/
@Override
public Class<? extends Page> getHomePage() {
if (SciProSession.get().authorizedForRole(Roles.SYSADMIN) && SciProSession.get().hasActualRole(Roles.SYSADMIN)){
return AdminStartPage.class;
}
else if (SciProSession.get().authorizedForRole(Roles.ADMIN) && SciProSession.get().hasActualRole(Roles.ADMIN)){
return AdminStartPage.class;
}
else if (SciProSession.get().authorizedForRole(Roles.EMPLOYEE) && SciProSession.get().hasActualRole(Roles.EMPLOYEE)){
return SupervisorStartPage.class;
}
else if (SciProSession.get().authorizedForRole(Roles.STUDENT) && SciProSession.get().hasActualRole(Roles.STUDENT)){
return ProjectStartPage.class;
}
else {
return HomePage.class;
}
}
@Override
public Session newSession(Request request, Response response) {
return new SciProSession(request);
}
@Override
public WebRequest newWebRequest(final HttpServletRequest request){
final WebRequest webRequest = super.newWebRequest(request);
if(attemptExternalAuthentication(webRequest)){
logger.debug("External authentication used successfully");
}
return webRequest;
}
/**
* Overrides standard request cycle procedures to support custom error pages based on the exception type.
* See CustomErrorPageFactory, RenderingSafeException and CustomErrorPage for more information.
* Other exceptions (ie: non RenderingSafeException sub types) are sent to a standard fallback page).
*/
@Override
public RequestCycle newRequestCycle(Request request, Response response){
return new WebRequestCycle(this, (WebRequest)request, response){
@Override
public Page onRuntimeException(Page page, RuntimeException e){
Throwable cause = e;
if(cause instanceof WicketRuntimeException)
cause = cause.getCause();
if(cause instanceof InvocationTargetException)
cause = cause.getCause();
if(cause instanceof RenderingSafeException){
return new CustomErrorPageFactory().dispatch((RenderingSafeException)cause);
}
getSession().error(Strings.toString(e));
return super.onRuntimeException(page,e);
}
};
}
/**
* Private utility, just to keep stuff out of the calling method.
* In short: scan incoming request for REMOTE_USER, check for a session, create one if none exists, attempt authentication and return status.
* @param usingRequest
* @return true if external auth was completed, false if not.
*/
private boolean attemptExternalAuthentication(final WebRequest usingRequest){
SciProSession session = (SciProSession)getSessionStore().lookup(usingRequest);
final ExternalAuthenticationRequestHelper helper = new ExternalAuthenticationRequestHelper(usingRequest.getHttpServletRequest());
if(helper.isExternalAuthSupported()){//Attempt external auth
if(session == null){//Can't do this without a usable session, attempt manual bind
getSessionStore().bind(usingRequest,new SciProSession(usingRequest));
session = (SciProSession)getSessionStore().lookup(usingRequest);
}
if(session != null){
if(session.isLoggedIn()){
if(!helper.isRemoteUserValid(session.getUser())){//This check may not be needed and may hinder performance, but better safe than sorry for now.
logger.debug("User is logged in as '"+session.getUser()+"', but conflicting info ('"+helper.getExternalAuthRemoteUser()+"') is supplied via external authentication protocols.");
}
}else{
//logger.info("Attempting sign in with external auth data");
if(!helper.signIn(session)){
logger.error("User '"+helper.getExternalAuthRemoteUser()+"' passes external authentication but cannot be signed in.");
}else{
logger.debug("Signed in user '"+helper.getExternalAuthRemoteUser()+"' via external authentication");
return true;
}
}
}else{
throw new IllegalStateException("External authentication was attempted, but no session was available for sign in.");
}
}
return false;
}
@Override
public ResourceReference getTheme(Session session) {
return new ThemeResourceReference();
}
public static SciProApplication get(){
return (SciProApplication) WebApplication.get();
}
public String getSystemNoticeString(){
return systemNotice;
}
public void setSystemNoticeString(String systemNotice){
this.systemNotice = systemNotice;
}
}
package se.su.dsv.scipro;
import org.apache.log4j.Level;
import org.apache.log4j.Logger;
import org.apache.wicket.*;
import org.apache.wicket.authorization.strategies.CompoundAuthorizationStrategy;
import org.apache.wicket.protocol.http.WebApplication;
import org.apache.wicket.protocol.http.WebRequest;
import org.apache.wicket.protocol.http.WebRequestCycle;
import org.apache.wicket.settings.IExceptionSettings;
import org.apache.wicket.util.string.Strings;
import org.odlabs.wiquery.ui.themes.IThemableApplication;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;
import se.su.dsv.scipro.activityplan.pages.ProjectActivityPlanPage;
import se.su.dsv.scipro.activityplan.pages.SupervisorActivityPlanPage;
import se.su.dsv.scipro.admin.pages.*;
import se.su.dsv.scipro.admin.pages.settings.*;
import se.su.dsv.scipro.basepages.DemoPage;
import se.su.dsv.scipro.basepages.errorpages.*;
import se.su.dsv.scipro.conference.pages.ProjectConferencePage;
import se.su.dsv.scipro.conference.pages.SupervisorConferencePage;
import se.su.dsv.scipro.exceptions.RenderingSafeException;
import se.su.dsv.scipro.json.pages.*;
import se.su.dsv.scipro.loginlogout.pages.LoginPage;
import se.su.dsv.scipro.loginlogout.pages.LogoutPage;
import se.su.dsv.scipro.message.pages.PrivateMessagesPage;
import se.su.dsv.scipro.peer.pages.*;
import se.su.dsv.scipro.project.pages.*;
import se.su.dsv.scipro.repository.RepositoryApplication;
import se.su.dsv.scipro.repository.pages.RepositoryDownloadPage;
import se.su.dsv.scipro.repository.pages.SysAdminFilePage;
import se.su.dsv.scipro.schedule.templates.pages.ScheduleTemplateDetailsPage;
import se.su.dsv.scipro.security.auth.ComponentSecurityLogger;
import se.su.dsv.scipro.security.auth.ExternalAuthenticationRequestHelper;
import se.su.dsv.scipro.security.auth.MetaDataActionStrategy;
import se.su.dsv.scipro.security.auth.RoleBasedAuthorizationStrategy;
import se.su.dsv.scipro.security.auth.roles.Roles;
import se.su.dsv.scipro.supervisor.pages.*;
import se.su.dsv.scipro.wiquery.themes.ThemeResourceReference;
import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.InvocationTargetException;
import java.util.Set;
/**
* Application object for your web application. If you want to run this application without deploying, run the Start class.
*
* @author Martin Peters - mpeters@dsv.su.se
* @see wicket.myproject.Start#main(String[])
*/
@Component
public class SciProApplication extends RepositoryApplication implements IThemableApplication {
/*
* 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";
//private Scheduler scheduler = null;
/*
* A string setable in the sys-admin settings page that displays for example a system takedown notice
*/
private String systemNotice = null;
@Value ( "${wicket.mode}" )
private String deploymentMode = DEVELOPMENT;
/**
* Logger instance.
*/
private Logger logger = Logger.getLogger(SciProApplication.class);
/**
* Constructor
*/
public SciProApplication() {
}
@Override
public String getConfigurationType() {
return deploymentMode;
}
@Override
protected void init() {
super.init();
setKerberosConfigs();
getMarkupSettings().setCompressWhitespace(true);
getMarkupSettings().setStripComments(true);
getMarkupSettings().setStripWicketTags(true);
getMarkupSettings().setDefaultMarkupEncoding("UTF-8");
getRequestCycleSettings().setResponseRequestEncoding("UTF-8");
/*
* Unknown pages
*/
mountBookmarkablePage("inbox", PrivateMessagesPage.class);
mountBookmarkablePage("repository/download", RepositoryDownloadPage.class);
/*
* Root pages
*/
mountBookmarkablePage("login", LoginPage.class);
mountBookmarkablePage("logout", LogoutPage.class);
mountBookmarkablePage("demo", DemoPage.class);
/*
* Pop-up pages
*/
mountBookmarkablePage("templates/details", ScheduleTemplateDetailsPage.class);
/*
* JSON pages
*/
mountBookmarkablePage("json/project", JsonProjectForSupervisorPage.class);
mountBookmarkablePage("json/message", JsonMessagePage.class);
mountBookmarkablePage("json/message/unread", JsonMessagePageCountUnread.class);
mountBookmarkablePage("json/message/setread", JsonSetReadPage.class);
mountBookmarkablePage("json/message/deleterecipient", JsonDeleteRecipientPage.class);
mountBookmarkablePage("json/message/deleteprivatemessage", JsonDeletePrivateMessagePage.class);
mountBookmarkablePage("json/message/newmessage", JsonNewMessagePage.class);
mountBookmarkablePage("json/message/sentmessages", JsonSentMessagePage.class);
mountBookmarkablePage("json/login", JsonLoginPage.class);
mountBookmarkablePage("json/status", JsonStatusPage.class);
mountBookmarkablePage("json/setstatus", JsonSetStatusPage.class);
/*
* Admin pages
*/
mountBookmarkablePage("admin/start", AdminStartPage.class);
mountBookmarkablePage("admin/templates", AdminScheduleTemplatesPage.class);
mountBookmarkablePage("admin/templates/editor", AdminScheduleTemplatesEditorPage.class);
mountBookmarkablePage("admin/maintenance", SystemMaintenancePage.class);
mountBookmarkablePage("admin/project", ProjectManagementPage.class);
mountBookmarkablePage("admin/files", SysAdminFilePage.class);
mountBookmarkablePage("admin/allfinalseminars", AdminFinalSeminarPage.class);
mountBookmarkablePage("admin/settings", AdminGeneralSettingsPage.class);
mountBookmarkablePage("admin/settings/serverenvironment", AdminServerEnvironmentSettingsPage.class);
mountBookmarkablePage("admin/settings/finalseminargeneralsettings", AdminFinalSeminarSettingsPage.class);
mountBookmarkablePage("admin/settings/finalseminarprojectlevel", AdminFinalSeminarSettingsPerProjectClassPage.class);
mountBookmarkablePage("admin/settings/peer", AdminPeerSettingsPage.class);
mountBookmarkablePage("admin/roles", AdminRolePage.class);
mountBookmarkablePage("admin/allpeers", AdminPeerListPage.class);
mountBookmarkablePage("admin/peer/review", AdminPeerReviewPage.class);
mountBookmarkablePage("admin/projectpartner", AdminProjectPartnerPage.class);
mountBookmarkablePage("admin/checklist", AdminCheckListPage.class);
/*
* Project pages
*/
mountBookmarkablePage("project/conference", ProjectConferencePage.class);
mountBookmarkablePage("project/activityplan", ProjectActivityPlanPage.class);
mountBookmarkablePage("project/files", ProjectFilePage.class);
mountBookmarkablePage("project/opposition", ProjectOppositionPage.class);
mountBookmarkablePage("project/allfinalseminars", FinalSeminarProjectListPage.class);
mountBookmarkablePage("project", ProjectStartPage.class);
mountBookmarkablePage("noproject", NoActiveProjectPage.class);
mountBookmarkablePage("project/checklist", ProjectChecklistPage.class);
mountBookmarkablePage("project/checklist/viewchecklist", ProjectViewCheckListPage.class);
mountBookmarkablePage("projectideas", ProjectIdeaPage.class);
mountBookmarkablePage("projectideas/submit", ProjectIdeaSubmissionPage.class);
/*
* Supervisor pages
*/
mountBookmarkablePage("supervisor", SupervisorStartPage.class);
mountBookmarkablePage("supervisor/finalseminars", SupervisorProjectsFinalSeminarPage.class);
mountBookmarkablePage("supervisor/allfinalseminars", SupervisorFinalSeminarListingPage.class);
mountBookmarkablePage("supervisor/templates/editor", SupervisorScheduleTemplatesEditorPage.class);
mountBookmarkablePage("supervisor/templates", SupervisorScheduleTemplatesPage.class);
mountBookmarkablePage("supervisor/project/details", SupervisorProjectDetailsPage.class);
mountBookmarkablePage("supervisor/project/details/checklist", SupervisorChecklistPage.class);
mountBookmarkablePage("supervisor/project/details/addchecklist", SupervisorAddCheckListToProjectPage.class);
mountBookmarkablePage("supervisor/antiplagiarism", SupervisorAntiPlagiarismLinkPage.class);
mountBookmarkablePage("supervisor/conference", SupervisorConferencePage.class);
mountBookmarkablePage("supervisor/checklist", SupervisorChecklistPage.class);
mountBookmarkablePage("supervisor/checklist/viewchecklist", SupervisorViewCheckListPage.class);
mountBookmarkablePage("supervisor/profile", SupervisorProfilePage.class);
mountBookmarkablePage("supervisor/project/activityplan", SupervisorActivityPlanPage.class);
mountBookmarkablePage("supervisor/project/files", SupervisorFilePage.class);
/*
* Peer pages
*/
//project
mountBookmarkablePage("project/peer/request", PeerRequestSubmissionPage.class);
mountBookmarkablePage("project/peer", ProjectPeerPortalPage.class);
//When mounted, traffic light images is not working. Needs further work.
mountBookmarkablePage("project/peer/review", ProjectPeerReviewPage.class);
mountBookmarkablePage("project/peer/stats", ProjectPeerStatsPage.class);
mountBookmarkablePage("project/peer/reviewguide", ProjectPeerReviewGuidePage.class);
//supervisor
mountBookmarkablePage("supervisor/peer", SupervisorPeerPortalPage.class);
mountBookmarkablePage("supervisor/peer/stats", SupervisorPeerStatsPage.class);
mountBookmarkablePage("supervisor/peer/review", SupervisorPeerReviewPage.class);
mountBookmarkablePage("supervisor/peer/reviewguide", SupervisorPeerReviewGuidePage.class);
/*
* Error pages, mounted mostly for testing purposes
*/
mountBookmarkablePage("404", NotFoundPage.class);
mountBookmarkablePage("403", AccessDeniedPage.class);
mountBookmarkablePage("500", InternalErrorPage.class);
mountBookmarkablePage("page_expired_error", PageExpiredPage.class);
getApplicationSettings().setAccessDeniedPage(AccessDeniedPage.class);
getApplicationSettings().setInternalErrorPage(InternalErrorPage.class);
getExceptionSettings().setUnexpectedExceptionDisplay(IExceptionSettings.SHOW_INTERNAL_ERROR_PAGE);
getApplicationSettings().setPageExpiredErrorPage(PageExpiredPage.class);
/*
* Set up automatic injection for instanced components.
*/
addComponentInstantiationListener(getSpringInjector());
/*
* Set up authorization strategies for local authentication.
*/
CompoundAuthorizationStrategy cas = new CompoundAuthorizationStrategy();
cas.add(new RoleBasedAuthorizationStrategy());
cas.add(new MetaDataActionStrategy());
getSecuritySettings().setAuthorizationStrategy(cas);
//getResourceSettings().setThrowExceptionOnMissingResource(false);
//getResourceSettings().addStringResourceLoader(new JpaStringResourceLoader());
getResourceSettings().addStringResourceLoader(new NotificationLoader());
getSecuritySettings().setUnauthorizedComponentInstantiationListener(new ComponentSecurityLogger());
/*
* Passing the applicationContext on to workerthreads-scheduler via SchedulerServletContextListener defined in web.xml
*/
WebApplicationContext ctx = WebApplicationContextUtils.getWebApplicationContext(getServletContext());
getServletContext().setAttribute("org.springframework.web.context.WebApplicationContext", ctx);
}
@SuppressWarnings ( "unchecked" )
protected void setKerberosConfigs() {
javax.servlet.ServletContext context = getServletContext();
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);
}
}
@Override
protected void onDestroy() {
//scheduler.stopWorking();
super.onDestroy();
}
/* (non-Javadoc)
* @see org.apache.wicket.Application#getHomePage()
*/
@Override
public Class<? extends Page> getHomePage() {
if (SciProSession.get().authorizedForRole(Roles.SYSADMIN) && SciProSession.get().hasActualRole(Roles.SYSADMIN)) {
return AdminStartPage.class;
}
else if (SciProSession.get().authorizedForRole(Roles.ADMIN) && SciProSession.get().hasActualRole(Roles.ADMIN)) {
return AdminStartPage.class;
}
else if (SciProSession.get().authorizedForRole(Roles.EMPLOYEE) && SciProSession.get().hasActualRole(Roles.EMPLOYEE)) {
return SupervisorStartPage.class;
}
else if (SciProSession.get().authorizedForRole(Roles.STUDENT) && SciProSession.get().hasActualRole(Roles.STUDENT)) {
return ProjectStartPage.class;
}
else {
return HomePage.class;
}
}
@Override
public Session newSession(Request request, Response response) {
return new SciProSession(request);
}
@Override
public WebRequest newWebRequest(final HttpServletRequest request) {
final WebRequest webRequest = super.newWebRequest(request);
if (attemptExternalAuthentication(webRequest)) {
logger.debug("External authentication used successfully");
}
return webRequest;
}
/**
* Overrides standard request cycle procedures to support custom error pages based on the exception type.
* See CustomErrorPageFactory, RenderingSafeException and CustomErrorPage for more information.
* Other exceptions (ie: non RenderingSafeException sub types) are sent to a standard fallback page).
*/
@Override
public RequestCycle newRequestCycle(Request request, Response response) {
return new WebRequestCycle(this, (WebRequest) request, response) {
@Override
public Page onRuntimeException(Page page, RuntimeException e) {
Throwable cause = e;
if (cause instanceof WicketRuntimeException) {
cause = cause.getCause();
}
if (cause instanceof InvocationTargetException) {
cause = cause.getCause();
}
if (cause instanceof RenderingSafeException) {
return new CustomErrorPageFactory().dispatch((RenderingSafeException) cause);
}
getSession().error(Strings.toString(e));
return super.onRuntimeException(page, e);
}
};
}
/**
* Private utility, just to keep stuff out of the calling method.
* In short: scan incoming request for REMOTE_USER, check for a session, create one if none exists, attempt authentication and return status.
*
* @param usingRequest
* @return true if external auth was completed, false if not.
*/
private boolean attemptExternalAuthentication(final WebRequest usingRequest) {
SciProSession session = (SciProSession) getSessionStore().lookup(usingRequest);
final ExternalAuthenticationRequestHelper helper = new ExternalAuthenticationRequestHelper(usingRequest.getHttpServletRequest());
if (helper.isExternalAuthSupported()) {//Attempt external auth
if (session == null) {//Can't do this without a usable session, attempt manual bind
getSessionStore().bind(usingRequest, new SciProSession(usingRequest));
session = (SciProSession) getSessionStore().lookup(usingRequest);
}
if (session != null) {
if (session.isLoggedIn()) {
if (!helper.isRemoteUserValid(session.getUser())) {//This check may not be needed and may hinder performance, but better safe than sorry for now.
logger.debug("User is logged in as '" + session.getUser() + "', but conflicting info ('" + helper.getExternalAuthRemoteUser() + "') is supplied via external authentication protocols.");
}
}
else {
//logger.info("Attempting sign in with external auth data");
if (!helper.signIn(session)) {
logger.error("User '" + helper.getExternalAuthRemoteUser() + "' passes external authentication but cannot be signed in.");
}
else {
logger.debug("Signed in user '" + helper.getExternalAuthRemoteUser() + "' via external authentication");
return true;
}
}
}
else {
throw new IllegalStateException("External authentication was attempted, but no session was available for sign in.");
}
}
return false;
}
@Override
public ResourceReference getTheme(Session session) {
return new ThemeResourceReference();
}
public static SciProApplication get() {
return (SciProApplication) WebApplication.get();
}
public String getSystemNoticeString() {
return systemNotice;
}
public void setSystemNoticeString(String systemNotice) {
this.systemNotice = systemNotice;
}
}

@ -1,24 +1,20 @@
package se.su.dsv.scipro.activityplan.panels;
import java.util.Date;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.ajax.markup.html.form.AjaxButton;
import org.apache.wicket.markup.html.form.CheckBox;
import org.apache.wicket.markup.html.form.DropDownChoice;
import org.apache.wicket.markup.html.form.Form;
import org.apache.wicket.markup.html.form.TextArea;
import org.apache.wicket.markup.html.form.TextField;
import org.apache.wicket.markup.html.form.*;
import org.apache.wicket.markup.html.panel.Panel;
import org.apache.wicket.model.PropertyModel;
import org.apache.wicket.spring.injection.annot.SpringBean;
import se.su.dsv.scipro.components.CustomDateTimeField;
import se.su.dsv.scipro.data.dao.interfaces.ProjectDao;
import se.su.dsv.scipro.data.dataobjects.CheckList;
import se.su.dsv.scipro.data.dataobjects.Project;
import se.su.dsv.scipro.data.dataobjects.ProjectScheduleEvent;
import java.util.Date;
import java.util.List;
public abstract class EditEventPanel extends Panel {
private static final long serialVersionUID = 1L;
@ -53,26 +49,33 @@ public abstract class EditEventPanel extends Panel {
add(new TextField("nameField", new PropertyModel<String>(event, "name")).setEnabled(editable));
add(new TextArea("descriptionArea", new PropertyModel<String>(event, "description")).setEnabled(editable));
add(new CustomDateTimeField("date", new PropertyModel<Date>(event, "date")).setEnabled(editable));
Project p = projectDao.reLoad(event.getProjectSchedule().getProject());
List<CheckList> cll = p.getCheckLists();
cll.add(null);
DropDownChoice checklistDropDown = new DropDownChoice<CheckList>("checklist", new PropertyModel<CheckList>(event, "checkList"), p.getCheckLists());
// checklistDropDown.setVisible(p.getCheckLists()!=null && p.getCheckLists().size()>0);
checklistDropDown.setEnabled(editable);
add(checklistDropDown);
// checklistDropDown = new DropDownChoice<CheckList>("checklist",new PropertyModel<CheckList>(formWrapper.getModelObject(),"checkList"),checkLists);
// checklistDropDown.setVisible(checkLists.size()>0);
// checklistDropDown.setChoiceRenderer(new ChoiceRenderer<CheckList>(){
// private static final long serialVersionUID = 1L;
// @Override
// public Object getDisplayValue(final CheckList checklist){
// if(checklist == null)
// return "No checklist";
// else
// return (checklist.getName());
// }
// });
checklistDropDown.setChoiceRenderer(new ChoiceRenderer<CheckList>(){
private static final long serialVersionUID = 1L;
@Override
public Object getDisplayValue(final CheckList checklist){
if(checklist == null)
return "No checklist";
else
return (checklist.getName());
}
});
add(new CheckBox("handin", new PropertyModel(event, "uploadRequired")).setEnabled(editable));

@ -3,13 +3,13 @@
xmlns:wicket="http://wicket.apache.org/dtds.data/wicket-xhtml1.4-strict.dtd">
<body>
<wicket:extend>
<div class="span-22 last append-bottom">
<div wicket:id="menuPanel"></div>
</div>
<div class="span-22 last">
<div wicket:id="feedbackPanel"></div>
<div class="span-5 append-1" wicket:id="menuPanel"></div>
<div class="span-15 last">
<wicket:child />
</div>
</div>
</wicket:extend>
</body>
</html>

@ -1,53 +1,54 @@
package se.su.dsv.scipro.admin.pages;
import java.util.ArrayList;
import java.util.List;
import org.apache.wicket.Component;
import org.apache.wicket.PageParameters;
import org.apache.wicket.markup.html.panel.FeedbackPanel;
import se.su.dsv.scipro.admin.pages.match.AdminKeywordPage;
import se.su.dsv.scipro.admin.pages.match.AdminManageMatchPeriodsPage;
import se.su.dsv.scipro.admin.pages.match.AdminManageMatchSupervisorPage;
import se.su.dsv.scipro.admin.pages.match.AdminManageProjectIdeaPage;
import se.su.dsv.scipro.admin.pages.match.AutomaticMatchPage;
import se.su.dsv.scipro.admin.pages.match.AdminExemptionPage;
import se.su.dsv.scipro.components.AbstractMenuPanel;
import se.su.dsv.scipro.security.auth.Authorization;
import se.su.dsv.scipro.security.auth.roles.Roles;
@Authorization(authorizedRoles = { Roles.SYSADMIN })
public abstract class AbstractAdminMatchPage extends AbstractAdminPage {
private Component feedBackPanel;
public Component getFeedBackPanel() {
return feedBackPanel;
}
public AbstractAdminMatchPage(PageParameters pp) {
super(pp);
add(feedBackPanel = new FeedbackPanel("feedbackPanel").setOutputMarkupId(true));
add(new AbstractMenuPanel("menuPanel", AbstractAdminMatchPage.class, this.getClass()){
private static final long serialVersionUID = 1L;
@Override
protected List<MenuItem> getItemList() {
final List<MenuItem> items = new ArrayList<MenuItem>();
items.add(new MenuItem("Project ideas", AdminManageProjectIdeaPage.class));
//items.add(new MenuItem("Author limits", AdminMatchSettingsPerProjectClassPage.class)); not implemented, commented out
items.add(new MenuItem("Automatic match", AutomaticMatchPage.class));
items.add(new MenuItem("Manage keywords", AdminKeywordPage.class));
items.add(new MenuItem("Student exemptions", AdminExemptionPage.class));
items.add(new MenuItem("Supervisor settings", AdminManageMatchSupervisorPage.class));
items.add(new MenuItem("Application periods", AdminManageMatchPeriodsPage.class));
return items;
}
@Override
protected MenuType getMenuType() {
return MenuType.VERTICAL;
}
});
}
package se.su.dsv.scipro.admin.pages;
import java.util.ArrayList;
import java.util.List;
import org.apache.wicket.Component;
import org.apache.wicket.PageParameters;
import org.apache.wicket.markup.html.panel.FeedbackPanel;
import se.su.dsv.scipro.admin.pages.match.AdminKeywordPage;
import se.su.dsv.scipro.admin.pages.match.AdminManageMatchPeriodsPage;
import se.su.dsv.scipro.admin.pages.match.AdminManageMatchSupervisorPage;
import se.su.dsv.scipro.admin.pages.match.AdminManageProjectIdeaPage;
import se.su.dsv.scipro.admin.pages.match.AdminSupervisorKeywordsPage;
import se.su.dsv.scipro.admin.pages.match.AutomaticMatchPage;
import se.su.dsv.scipro.admin.pages.match.AdminExemptionPage;
import se.su.dsv.scipro.components.AbstractMenuPanel;
import se.su.dsv.scipro.security.auth.Authorization;
import se.su.dsv.scipro.security.auth.roles.Roles;
@Authorization(authorizedRoles = { Roles.SYSADMIN })
public abstract class AbstractAdminMatchPage extends AbstractAdminPage {
private Component feedBackPanel;
public Component getFeedBackPanel() {
return feedBackPanel;
}
public AbstractAdminMatchPage(PageParameters pp) {
super(pp);
add(feedBackPanel = new FeedbackPanel("feedbackPanel").setOutputMarkupId(true));
add(new AbstractMenuPanel("menuPanel", AbstractAdminMatchPage.class, this.getClass()){
private static final long serialVersionUID = 1L;
@Override
protected List<MenuItem> getItemList() {
final List<MenuItem> items = new ArrayList<MenuItem>();
items.add(new MenuItem("Project ideas", AdminManageProjectIdeaPage.class));
//items.add(new MenuItem("Author limits", AdminMatchSettingsPerProjectClassPage.class)); not implemented, commented out
items.add(new MenuItem("Automatic match", AutomaticMatchPage.class));
items.add(new MenuItem("Manage keywords", AdminKeywordPage.class));
items.add(new MenuItem("Student exemptions", AdminExemptionPage.class));
items.add(new MenuItem("Supervisor settings", AdminManageMatchSupervisorPage.class));
items.add(new MenuItem("Application periods", AdminManageMatchPeriodsPage.class));
return items;
}
@Override
protected MenuType getMenuType() {
return MenuType.HORIZONTAL;
}
});
}
}

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

@ -0,0 +1,44 @@
package se.su.dsv.scipro.admin.pages;
import java.util.ArrayList;
import java.util.List;
import org.apache.wicket.Component;
import org.apache.wicket.PageParameters;
import org.apache.wicket.markup.html.panel.FeedbackPanel;
import se.su.dsv.scipro.admin.pages.match.AdminSupervisorKeywordsPage;
import se.su.dsv.scipro.components.AbstractMenuPanel;
import se.su.dsv.scipro.security.auth.Authorization;
import se.su.dsv.scipro.security.auth.roles.Roles;
@Authorization(authorizedRoles = { Roles.ADMIN })
public abstract class AbstractAdminStatisticsPage extends AbstractAdminPage {
private Component feedBackPanel;
public Component getFeedBackPanel() {
return feedBackPanel;
}
public AbstractAdminStatisticsPage(PageParameters pp) {
super(pp);
add(feedBackPanel = new FeedbackPanel("feedbackPanel").setOutputMarkupId(true));
add(new AbstractMenuPanel("menuPanel", AbstractAdminStatisticsPage.class, this.getClass()){
private static final long serialVersionUID = 1L;
@Override
protected List<MenuItem> getItemList() {
final List<MenuItem> items = new ArrayList<MenuItem>();
items.add(new MenuItem("Supervisor keywords", AdminSupervisorKeywordsPage.class));
items.add(new MenuItem("Project ideas", AdminProjectIdeaStatisticPage.class));
return items;
}
@Override
protected MenuType getMenuType() {
return MenuType.VERTICAL;
}
});
}
}

@ -0,0 +1,9 @@
<!DOCTYPE html>
<html
xmlns:wicket="http://wicket.apache.org/dtds.data/wicket-xhtml1.4-strict.dtd">
<body>
<wicket:extend>
<div wicket:id="projectIdeaStatisticPanel"></div>
</wicket:extend>
</body>
</html>

@ -0,0 +1,19 @@
package se.su.dsv.scipro.admin.pages;
import org.apache.wicket.PageParameters;
import se.su.dsv.scipro.admin.pages.AbstractAdminStatisticsPage;
import se.su.dsv.scipro.admin.panels.AdminProjectIdeaStatisticPanel;
import se.su.dsv.scipro.admin.panels.match.AdminSupervisorKeywordPanel;
import se.su.dsv.scipro.security.auth.Authorization;
import se.su.dsv.scipro.security.auth.roles.Roles;
@Authorization(authorizedRoles={Roles.ADMIN})
public class AdminProjectIdeaStatisticPage extends AbstractAdminStatisticsPage {
public AdminProjectIdeaStatisticPage(PageParameters pp) {
super(pp);
add(new AdminProjectIdeaStatisticPanel("projectIdeaStatisticPanel"));
}
}

@ -16,3 +16,4 @@ public class AdminScheduleTemplatesPage extends AbstractAdminPage {
}
}

@ -0,0 +1,11 @@
<!DOCTYPE html>
<html
xmlns:wicket="http://wicket.apache.org/dtds.data/wicket-xhtml1.4-strict.dtd">
<body>
<wicket:extend>
<h5 class="peer-title">Statistics</h5>
Available statistics can be found in the menu to the left.
<div wicket:id="statisticsPanel" class="prepend-top"></div>
</wicket:extend>
</body>
</html>

@ -0,0 +1,23 @@
package se.su.dsv.scipro.admin.pages;
import org.apache.wicket.PageParameters;
import org.apache.wicket.markup.html.panel.EmptyPanel;
import se.su.dsv.scipro.security.auth.Authorization;
import se.su.dsv.scipro.security.auth.roles.Roles;
@Authorization(authorizedRoles = { Roles.ADMIN })
public class AdminStatisticsPage extends AbstractAdminStatisticsPage {
public AdminStatisticsPage() {
this(new PageParameters());
}
public AdminStatisticsPage(PageParameters pp) {
super(pp);
add(new EmptyPanel("statisticsPanel"));
}
}

@ -27,12 +27,13 @@
<th>Comment</th>
<th>Level</th>
<th>Granted by</th>
<th>Date of granting</th>
<th class="rounded-right-top">Revoke exemption</th>
</tr>
</thead>
<tfoot>
<tr>
<td colspan="5" class="rounded-foot">&nbsp;</td>
<td colspan="6" class="rounded-foot">&nbsp;</td>
</tr>
</tfoot>
<tbody>
@ -41,6 +42,7 @@
<td><span wicket:id="comment"></span></td>
<td><span wicket:id="level"></span></td>
<td><span wicket:id="grantedBy"></span></td>
<td><span wicket:id="dateOfGranting"></span></td>
<td><a href=# wicket:id="removeLink"><img
wicket:id="removeIcon" alt="" /></a></td>
</tr>

@ -25,6 +25,7 @@ import se.su.dsv.scipro.match.dao.interfaces.ExemptionDao;
import se.su.dsv.scipro.match.dao.interfaces.ExemptionDaoParams;
import se.su.dsv.scipro.match.dataobject.Exemption;
import se.su.dsv.scipro.util.JavascriptEventConfirmation;
import java.text.SimpleDateFormat;
public class AdminExemptionPanel extends Panel {
@ -107,8 +108,7 @@ public class AdminExemptionPanel extends Panel {
};
public void loadUserDataView(IDataProvider<Exemption> exemptionDataProvider) {
dataView =
new DataView<Exemption>("listView", exemptionDataProvider, 10) {
dataView = new DataView<Exemption>("listView", exemptionDataProvider, 10) {
private static final long serialVersionUID =
2828792237574112923L;
@ -124,7 +124,9 @@ public class AdminExemptionPanel extends Panel {
item.add(new Label("comment", excemption.getComment()));
item.add(new Label("grantedBy", excemption.getGrantedBy()
.getFullName()));
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
item.add(new Label("dateOfGranting", formatter.format(excemption.getDateCreated())));
AjaxLink<Void> removeLink = new AjaxLink<Void>("removeLink"){
private static final long serialVersionUID = 1L;

@ -3,20 +3,18 @@
xmlns:wicket="http://wicket.apache.org/dtds.data/wicket-xhtml1.4-strict.dtd">
<body>
<wicket:extend>
<h5 class="peer-title">Manage regular keywords</h5>
<div wicket:id="manageWordKeyword"></div>
<h5 class="peer-title">Manage unit keywords</h5>
<div class="info-box rounded-box">
Unit keywords are imported from a remote system. If you rename a unit and the old name is still
available on the remote system, both units will exist in Scipro after the next import.
Unit keywords are imported from a remote system and may not be edited in Scipro.<br />To make changes to available units, please do so in Daisy.
</div>
<div wicket:id="manageUnitKeyword"></div>
<h5 class="peer-title">Manage research area keywords</h5>
<div class="info-box rounded-box">
Research area keywords are imported from a remote system. If you rename a unit and the old name is still
available on the remote system, both units will exist in Scipro after the next import.
Research area keywords are imported from a remote system and may not be edited in Scipro.<br />To make changes to available research areas, please do so in Daisy.
</div>
<div wicket:id="manageAreaKeyword"></div>
<h5 class="peer-title">Manage regular keywords</h5>
<div wicket:id="manageWordKeyword"></div>
</wicket:extend>
</body>
</html>

@ -14,9 +14,9 @@ public class AdminKeywordPage extends AbstractAdminMatchPage {
public AdminKeywordPage(PageParameters pp) {
super(pp);
add(new ManageKeywordPanel("manageUnitKeyword", keywordTypeDao.findByType(KeywordTypeDao.TYPE.UNIT)));
add(new ManageKeywordPanel("manageAreaKeyword", keywordTypeDao.findByType(KeywordTypeDao.TYPE.RESEARCH_AREA)));
add(new ManageKeywordPanel("manageWordKeyword", keywordTypeDao.findByType(KeywordTypeDao.TYPE.REGULAR)));
add(new ManageKeywordPanel("manageWordKeyword", keywordTypeDao.findByType(KeywordTypeDao.TYPE.REGULAR), true));
add(new ManageKeywordPanel("manageUnitKeyword", keywordTypeDao.findByType(KeywordTypeDao.TYPE.UNIT), false));
add(new ManageKeywordPanel("manageAreaKeyword", keywordTypeDao.findByType(KeywordTypeDao.TYPE.RESEARCH_AREA), false));
}
}

@ -3,6 +3,8 @@
xmlns:wicket="http://wicket.apache.org/dtds.data/wicket-xhtml1.4-strict.dtd">
<body>
<wicket:extend>
<!--<div wicket:id="feedbackPanel"/>-->
<div wicket:id="manageSupervisorPanel"></div>
</wicket:extend>
</body>

@ -1,8 +1,10 @@
package se.su.dsv.scipro.admin.pages.match;
import org.apache.wicket.Component;
import org.apache.wicket.PageParameters;
import org.apache.wicket.markup.html.panel.FeedbackPanel;
import se.su.dsv.scipro.admin.pages.AbstractAdminMatchPage;
import se.su.dsv.scipro.match.panel.AdminManageSupervisorPanel;
import se.su.dsv.scipro.security.auth.Authorization;
@ -11,9 +13,12 @@ import se.su.dsv.scipro.security.auth.roles.Roles;
@Authorization(authorizedRoles={Roles.ADMIN})
public class AdminManageMatchSupervisorPage extends AbstractAdminMatchPage {
public AdminManageMatchSupervisorPage(PageParameters pp) {
public AdminManageMatchSupervisorPage(PageParameters pp) {
super(pp);
add(new AdminManageSupervisorPanel("manageSupervisorPanel"));
Component feedbackPanel = new FeedbackPanel("feedbackPanel");
feedbackPanel.setOutputMarkupId(true);
// add(feedbackPanel);
add(new AdminManageSupervisorPanel("manageSupervisorPanel", feedbackPanel));
}
}

@ -4,9 +4,9 @@
<body>
<wicket:extend>
<div id="contents" >
<a href="#" wicket:id="manageProjectIdeaPanel">Search among all projects ideas </a>
<a href="#" wicket:id="rejectedProjectIdeaPanel"> Rejected project ideas </a>
<a href="#" wicket:id="waitingProjectIdeaPanel"> Top waiting projects ideas</a>
<a href="#" wicket:id="manageProjectIdeaPanel"> Search among all projects ideas </a><span> | </span>
<a href="#" wicket:id="rejectedProjectIdeaPanel"> Rejected project ideas </a><span> | </span>
<a href="#" wicket:id="waitingProjectIdeaPanel"> Top waiting projects ideas </a>
<div wicket:id="main" id="main"></div>
</div>
</wicket:extend>

@ -14,15 +14,17 @@ import org.apache.wicket.markup.html.panel.Panel;
@Authorization(authorizedRoles={Roles.ADMIN})
public class AdminManageProjectIdeaPage extends AbstractAdminMatchPage {
private AdminManageProjectIdeaPanel adminManageProjectIdeaPanel =
new AdminManageProjectIdeaPanel("main");
new AdminManageProjectIdeaPanel("main", getFeedBackPanel());
private AdminRejectedProjectIdeaPanel adminRejectedProjectIdeaPanel =
new AdminRejectedProjectIdeaPanel("main");
new AdminRejectedProjectIdeaPanel("main", getFeedBackPanel());
private AdminWaitingProjectIdeaPanel adminWaitingProjectIdeaPanel =
new AdminWaitingProjectIdeaPanel("main");
new AdminWaitingProjectIdeaPanel("main", getFeedBackPanel());
private Panel current = adminManageProjectIdeaPanel;
public AdminManageProjectIdeaPage(PageParameters pp) {
super(pp);
setOutputMarkupId(true);
add(new Link("manageProjectIdeaPanel") {
@Override
public void onClick() {

@ -5,7 +5,7 @@
<wicket:panel>
<div class="margin">
<div class="info-box rounded-box">If no application period is active, authors can not create new project ideas.
It is not possible to edit or delete an application period with connected project ideas.</div>
It is not possible to delete an application period with connected project ideas.</div>
<a href=# wicket:id="createLink"><img wicket:id="addIcon" alt="" />Create application period</a>
<div wicket:id="container">
<table class="rounded-corner">

@ -91,7 +91,7 @@ public class AdminMatchPeriodsPanel extends Panel {
item.add(new DateFormatter(DateFormatter.FORMAT.EXTENDED).createFormattedDateLabel("endDate", appPeriod.getEndDate()));
item.add(new Label("type",appPeriod.getProjectClass().toString()));
item.add(new Label("name",appPeriod.getName()));
final boolean linksAreEnabled = !applicationPeriodFacade.projectIdeasExists(appPeriod);
final boolean linksAreEnabled = !applicationPeriodFacade.projectIdeasExists(appPeriod);
final AjaxLink<Void> editLink = new AjaxLink<Void>("editLink"){
private static final long serialVersionUID = 1L;
@Override
@ -101,7 +101,7 @@ public class AdminMatchPeriodsPanel extends Panel {
private static final long serialVersionUID = 1L;
@Override
public boolean isEditable(){
return linksAreEnabled;
return true;
}
});
target.addComponent(dialog);
@ -109,7 +109,7 @@ public class AdminMatchPeriodsPanel extends Panel {
dialog.open(target);
}
};
editLink.setVisible(linksAreEnabled);
//editLink.setVisible(linksAreEnabled);
editLink.add(new ImageObject("editIcon", ImageObject.SIXTEEN + ImageObject.EDIT));
final AjaxLink<Void> removeLink = new AjaxLink<Void>("removeLink"){
private static final long serialVersionUID = 1L;

@ -0,0 +1,9 @@
<!DOCTYPE html>
<html
xmlns:wicket="http://wicket.apache.org/dtds.data/wicket-xhtml1.4-strict.dtd">
<body>
<wicket:extend>
<div wicket:id="supervisorKeywordPanel"></div>
</wicket:extend>
</body>
</html>

@ -0,0 +1,18 @@
package se.su.dsv.scipro.admin.pages.match;
import org.apache.wicket.PageParameters;
import se.su.dsv.scipro.admin.pages.AbstractAdminStatisticsPage;
import se.su.dsv.scipro.admin.panels.match.AdminSupervisorKeywordPanel;
import se.su.dsv.scipro.security.auth.Authorization;
import se.su.dsv.scipro.security.auth.roles.Roles;
@Authorization(authorizedRoles={Roles.ADMIN})
public class AdminSupervisorKeywordsPage extends AbstractAdminStatisticsPage {
public AdminSupervisorKeywordsPage(PageParameters pp) {
super(pp);
add(new AdminSupervisorKeywordPanel("supervisorKeywordPanel"));
}
}

@ -1,61 +1,86 @@
<!DOCTYPE html>
<html
xmlns:wicket="http://wicket.apache.org/dtds.data/wicket-xhtml1.4-strict.dtd">
xmlns:wicket="http://wicket.apache.org/dtds.data/wicket-xhtml1.4-strict.dtd">
<body>
<wicket:panel>
<div class="margin">
<div class="info-box rounded-box">
<p>This page is used for running the project ideas that are unmatched through the algorithm to produce matches. If the matches are good, they can be suggested to supervisors.
If the matches are not satisfactory, change the algorithm settings and run the algorithm again. You can run it as many times as you like before suggesting the matches to supervisors.
</p>
<p>
If the algorithm fails to make any matches, it could e.g. be because all supervisors with target numbers have already filled their target numbers, or that there were no supervisors with
unfilled target numbers left with matching language capabilities.
</p>
</div>
<wicket:panel>
<div class="margin">
<div class="info-box rounded-box">
<p>
<b>
NOTE: Running the matching algorithm is resource intensive and takes time. Roughly 1 minute per 100
project ideas. Be patient.
</b>
</p>
<p>This page is used for running the project ideas that are unmatched through the algorithm to produce
matches. If the matches are good, they can be suggested to supervisors.
If the matches are not satisfactory, change the algorithm settings and run the algorithm again. You can
run it as many times as you like before suggesting the matches to supervisors.
</p>
<p>
If the algorithm fails to make any matches, it could e.g. be because all supervisors with target numbers
have already filled their target numbers, or that there were no supervisors with
unfilled target numbers left with matching language capabilities.
</p>
</div>
<form wicket:id="matchingForm">
<form wicket:id="weightsForm">
<table>
<tr><td colspan="3">Algorithm settings:</td></tr>
<tr>
<td>Keyword points: <select wicket:id="keywordPoints"></select></td>
<td>Research area points: <select wicket:id="researchAreaPoints"></select></td>
<td>Preferred supervisor points: <select wicket:id="preferredSupervisorPoints"></select></td>
</tr>
</table>
<div wicket:id="wmc">
<table>
<tr>
<td colspan="3">Algorithm settings:</td>
</tr>
<tr>
<td>Keyword points: <select wicket:id="keywordPoints"></select></td>
<td>Research area points: <select wicket:id="researchAreaPoints"></select></td>
<td>Preferred supervisor points: <select wicket:id="preferredSupervisorPoints"></select>
</td>
<td>
<button wicket:id="saveButton">Save point settings</button>
</td>
</tr>
</table>
</div>
</form>
<p>There are <span wicket:id="numUnmatchedProjectIdeas"></span> unmatched project ideas that will be sent through the matching algorithm if you perform an automatic matching now.</p>
<input type="submit" wicket:id="runAlgorithm" value="Run match algorithm" />
<p>There are <span wicket:id="numUnmatchedProjectIdeas"></span> unmatched project ideas that will be sent
through the matching algorithm if you perform an automatic matching now.</p>
<input type="submit" wicket:id="runAlgorithm" value="Run match algorithm"/>
</form>
<div wicket:id="container">
<form wicket:id="suggestMatchesForm">
<button wicket:id="suggestMatches">Suggest these matches to supervisors</button>
</form>
<table class="rounded-corner">
<thead>
<tr>
<th class="rounded-left-top">Level</th>
<th>Title</th>
<th>Supervisor (Points)</th>
</tr>
</thead>
<tfoot>
<tr>
<td colspan="3" class="rounded-foot">&nbsp;</td>
</tr>
</tfoot>
<tbody>
<tr wicket:id="listView">
<td><span wicket:id="level"></span></td>
<td><span wicket:id="title"></span></td>
<td><span wicket:id="supervisor"></span> (<span wicket:id="points"></span>)</td>
</tr>
</tbody>
</table>
<div wicket:id="pagingNavigator"></div>
</div>
<div wicket:id="container">
<form wicket:id="suggestMatchesForm">
<button wicket:id="suggestMatches">Suggest these matches to supervisors</button>
<button wicket:id="suggestMatchesAtLeastOnePoints">Suggest matches with at least one points to
supervisors
</button>
</form>
<table class="rounded-corner">
<thead>
<tr>
<th class="rounded-left-top">Level</th>
<th>Title</th>
<th>Supervisor (Points)</th>
</tr>
</thead>
<tfoot>
<tr>
<td colspan="3" class="rounded-foot">&nbsp;</td>
</tr>
</tfoot>
<tbody>
<tr wicket:id="listView">
<td><span wicket:id="level"></span></td>
<td><span wicket:id="title"></span></td>
<td><span wicket:id="supervisor"></span> (<span wicket:id="points"></span>)</td>
</tr>
</tbody>
</table>
<div wicket:id="pagingNavigator"></div>
</div>
</wicket:panel>
</div>
</wicket:panel>
</body>
</html>

@ -7,6 +7,7 @@ import java.util.List;
import org.apache.log4j.Logger;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.ajax.markup.html.form.AjaxButton;
import org.apache.wicket.extensions.ajax.markup.html.AjaxEditableLabel;
import org.apache.wicket.injection.web.InjectorHolder;
import org.apache.wicket.markup.html.WebMarkupContainer;
import org.apache.wicket.markup.html.basic.Label;
@ -24,6 +25,7 @@ import org.apache.wicket.model.PropertyModel;
import org.apache.wicket.spring.injection.annot.SpringBean;
import se.su.dsv.scipro.SciProSession;
import se.su.dsv.scipro.data.dao.interfaces.WeightsDao;
import se.su.dsv.scipro.match.Matcher;
import se.su.dsv.scipro.match.Matcher.Result;
import se.su.dsv.scipro.match.Weights;
@ -38,8 +40,9 @@ public class AutomaticMatchPanel extends Panel {
@SpringBean
private MatchDao matchDao;
private MatchingForm matchingForm;
@SpringBean
private WeightsDao weightsDao;
private Form<Void> suggestMatchesForm;
private Result result;
@ -49,62 +52,67 @@ public class AutomaticMatchPanel extends Panel {
super(id);
MatchingData matchingData = new MatchingData();
matchingData.setWeights(new Weights());
// matchingData.setWeights(new Weights());
if (weightsDao.load(1L) == null) {
Weights weights = new Weights(1L);
matchingData.setWeights(weightsDao.save(weights));
} else {
Weights weights = weightsDao.load(1L);
matchingData.setWeights(weights);
}
suggestMatchesForm = new Form<Void>("suggestMatchesForm") {
{
add(new AjaxButton("suggestMatches", this) {
@Override
protected void onSubmit(AjaxRequestTarget target,
Form<?> form) {
try {
for (Match match : result.matches) {
match.setCreatedBy(SciProSession.get().getUser());
match.setStatus(Match.Status.PUBLISHED);
match = matchDao.save(match);
}
info("Saved " + result.matches.size() + " matches");
} catch (Exception e) {
error("Unable to create matches, cause: " + e.getMessage());
logger.error("Unable to create matches after automatic matching.", e);
}
protected void onSubmit(AjaxRequestTarget target, Form<?> form) {
saveMatches(result, 0L);
target.addComponent(getPage().get("feedbackPanel"));
target.addComponent(container);
hideContainer();
setResponsePage(AutomaticMatchPage.class);
}
});
add(new AjaxButton("suggestMatchesAtLeastOnePoints", this) {
@Override
protected void onSubmit(AjaxRequestTarget target, Form<?> form) {
saveMatches(result, 1L);
target.addComponent(getPage().get("feedbackPanel"));
target.addComponent(container);
hideContainer();
setResponsePage(AutomaticMatchPage.class);
}
});
}
};
suggestMatchesForm.setOutputMarkupId(true);
matchingForm = new MatchingForm("matchingForm",
new Model<MatchingData>(matchingData)) {
suggestMatchesForm.setOutputMarkupId(true);
@Override
protected void onSubmit(AjaxRequestTarget target, Form<?> form) {
Matcher matcher = getMatcher();
result = matcher.match();
if (result.matches.size() > 0) {
container.setVisible(true);
updateListView(container, result.matches);
container.add(suggestMatchesForm);
target.addComponent(container);
} else {
target.addComponent(getPage().get("feedbackPanel"));
info("No project ideas could be automatically matched.");
}
MatchingForm matchingForm = new MatchingForm("matchingForm",
new Model<MatchingData>(matchingData)) {
@Override
protected void onSubmit(AjaxRequestTarget target, Form<?> form) {
Matcher matcher = getMatcher();
result = matcher.match();
if (result.matches.size() > 0) {
container.setVisible(true);
updateListView(container, result.matches);
container.add(suggestMatchesForm);
target.addComponent(container);
} else {
target.addComponent(getPage().get("feedbackPanel"));
info("No project ideas could be automatically matched.");
}
}
};
add(matchingForm);
matchingForm.setOutputMarkupId(true);
@ -112,12 +120,25 @@ public class AutomaticMatchPanel extends Panel {
container = new WebMarkupContainer("container");
container.setOutputMarkupId(true);
hideContainer();
add(container);
}
private void saveMatches(final Result result1, final Long points) {
try {
for (Match match : result1.matches) {
if(match.getPoints() >= points) {
match.setCreatedBy(SciProSession.get().getUser());
match.setStatus(Match.Status.PUBLISHED);
match = matchDao.save(match);
}
}
info("Saved " + result1.matches.size() + " matches");
} catch (Exception e) {
error("Unable to create matches, cause: " + e.getMessage());
logger.error("Unable to create matches after automatic matching.", e);
}
}
private void hideContainer() {
container.setVisible(false).setOutputMarkupPlaceholderTag(true);
@ -217,12 +238,28 @@ public class AutomaticMatchPanel extends Panel {
private static class WeightsForm extends Form<Weights> {
private static final long serialVersionUID = 5707885553461955433L;
public WeightsForm(String id, IModel<Weights> model) {
@SpringBean
private WeightsDao weightsDao;
public WeightsForm(String id, final IModel<Weights> model) {
super(id, model);
add(createDropDown(model, "keywordPoints"));
add(createDropDown(model, "researchAreaPoints"));
add(createDropDown(model, "preferredSupervisorPoints"));
final WebMarkupContainer wmc = new WebMarkupContainer("wmc");
wmc.setOutputMarkupId(true);
add(wmc);
wmc.add(createDropDown(model, "keywordPoints"));
wmc.add(createDropDown(model, "researchAreaPoints"));
wmc.add(createDropDown(model, "preferredSupervisorPoints"));
wmc.add(new AjaxButton("saveButton"){
private static final long serialVersionUID = 1L;
@Override
protected void onSubmit(AjaxRequestTarget target, Form<?> form) {
model.setObject(weightsDao.save(model.getObject()));
target.addComponent(wmc);
}
});
}
private DropDownChoice<Integer> createDropDown(IModel<Weights> model, String weightName) {
@ -230,16 +267,10 @@ public class AutomaticMatchPanel extends Panel {
for (int i = 1; i<15; i++) {
choices.add(i);
}
DropDownChoice<Integer> dropDown =
new DropDownChoice<Integer>(weightName,
new PropertyModel<Integer>(model, weightName), choices);
DropDownChoice<Integer> dropDown = new DropDownChoice<Integer>(weightName, new PropertyModel<Integer>(model, weightName), choices);
dropDown.setNullValid(false);
dropDown.setRequired(true);
return dropDown;
}
}
}

@ -32,6 +32,14 @@
<td><input name="7" type="checkbox" wicket:id="mailNotifications" />
</td>
</tr>
<tr>
<td><label for="7">Supervisors can accept and decline project ideas:</label>
</td>
<td><input name="7" type="checkbox" wicket:id="supervisorsCanAcceptDeclinePIs" />
</td>
</tr>
</table>
<button type="submit">

@ -37,10 +37,12 @@ public class AdminGeneralSettingsPage extends AbstractAdminSettingsPage {
TextField<String> systemFromMail = new RequiredTextField<String>("systemFromMail");
TextField<String> smtpServer = new RequiredTextField<String>("smtpServer");
CheckBox mailNotifications = new CheckBox("mailNotifications");
CheckBox supervisorsCanAcceptDeclinePIs = new CheckBox("supervisorsCanAcceptDeclinePIs");
add(mailFromName);
add(systemFromMail);
add(smtpServer);
add(mailNotifications);
add(supervisorsCanAcceptDeclinePIs);
}
@Override

@ -83,7 +83,7 @@ public class AdminProjectClassSettingsPage extends AbstractAdminSettingsPage {
}
};
item.add(editLink);
editLink.add(new ImageObject("editIcon", ImageObject.TWENTYFOUR + ImageObject.EDIT));
editLink.add(new ImageObject("editIcon", ImageObject.SIXTEEN + ImageObject.EDIT));
}
};

@ -0,0 +1,39 @@
<!DOCTYPE html>
<html
xmlns:wicket="http://wicket.apache.org/dtds.data/wicket-xhtml1.4-strict.dtd">
<head>
<meta http-equiv="Content-type" content="text/html;charset=UTF-8"/>
</head>
<body>
<wicket:panel>
<form wicket:id="form">
<div>
<wicket:enclosure child="identifier">
<div class="info-box rounded-box">This project is synchronized with remote systems, changes made to it
may be overwritten if the remote system updates the projects data (external identifier: <span
wicket:id="identifier">externalId</span>)
</div>
</wicket:enclosure>
</div>
<div wicket:id="wmc">
<div wicket:id="feedbackPanel"></div>
<div><b>Title:</b></div>
<div class="append-bottom"><input wicket:id="titleField"/></div>
<div><b>Level:</b></div>
<div class="append-bottom"><span wicket:id="level"></span></div>
<div><b>Head supervisor:</b></div>
<div class="append-bottom"><input wicket:id="headsupervisorField"/></div>
<div><b>Students:</b></div>
<div wicket:id="studentPanel" class="append-bottom"></div>
<div><b>Project followers:</b></div>
<div wicket:id="followerPanel" class="append-bottom"></div>
<div>
<button wicket:id="saveButton">Save</button>
</div>
</div>
</form>
</wicket:panel>
</body>
</html>

@ -0,0 +1,150 @@
package se.su.dsv.scipro.admin.panels;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.ajax.markup.html.form.AjaxButton;
import org.apache.wicket.markup.html.WebMarkupContainer;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.form.Form;
import org.apache.wicket.markup.html.form.RadioChoice;
import org.apache.wicket.markup.html.form.TextField;
import org.apache.wicket.markup.html.panel.FeedbackPanel;
import org.apache.wicket.markup.html.panel.Panel;
import org.apache.wicket.model.IModel;
import org.apache.wicket.model.PropertyModel;
import org.apache.wicket.spring.injection.annot.SpringBean;
import se.su.dsv.scipro.data.dao.interfaces.ProjectClassDao;
import se.su.dsv.scipro.data.dao.interfaces.ProjectDao;
import se.su.dsv.scipro.data.dataobjects.Employee;
import se.su.dsv.scipro.data.dataobjects.Project;
import se.su.dsv.scipro.reusable.AddRemoveProjectFollowerPanel;
import se.su.dsv.scipro.reusable.AddRemoveStudentsPanel;
import se.su.dsv.scipro.reusable.EmployeeAutoComplete;
/**
* @author: fred-fri
* date: 2012 03 15
*/
public abstract class AdminEditProject extends Panel {
private static final long serialVersionUID = -8553559034214432156L;
@SpringBean
ProjectClassDao projectClassDao;
@SpringBean
ProjectDao projectDao;
/**
* Override this method to use AJAX
* @param target
*/
public abstract void onUpdate(AjaxRequestTarget target);
public AdminEditProject(String id, IModel<Project> model) {
super(id, model);
add(new ProjectForm("form", model));
}
private class ProjectForm extends Form {
private static final long serialVersionUID = 5784218491663983845L;
private WebMarkupContainer wmc;
private TextField<String> titleField;
private RadioChoice level;
private AddRemoveStudentsPanel studentsPanel;
private EmployeeAutoComplete headsupervisorField;
private AddRemoveProjectFollowerPanel followerPanel;
private FeedbackPanel feedbackPanel;
public ProjectForm(String id, final IModel<Project> model) {
super(id, model);
final Label externalIdentifier = new Label("identifier", String.valueOf(model.getObject().getIdentifier()));
add(externalIdentifier);
externalIdentifier.setVisible(model.getObject().getIdentifier() != null);
add(wmc = new WebMarkupContainer("wmc"));
wmc.setEnabled(isEditable());
wmc.add(feedbackPanel = new FeedbackPanel("feedbackPanel"));
feedbackPanel.setOutputMarkupId(true);
wmc.add(titleField = new TextField<String>("titleField", new PropertyModel(model.getObject(), "title")));
wmc.add(level = new RadioChoice("level", new PropertyModel(model.getObject(), "projectClass"), projectClassDao.findAll()));
wmc.add(studentsPanel = new AddRemoveStudentsPanel("studentPanel", model.getObject().getProjectParticipants()) {
@Override
public void onUpdate(AjaxRequestTarget target) {
//do nothing
}
});
//TODO: we need to set this one to the one already set in the project, how?
wmc.add(headsupervisorField = new EmployeeAutoComplete("headsupervisorField") {
@Override
public void action(AjaxRequestTarget pTarget, Employee newSelection) {
//do nothing
}
});
headsupervisorField.setModelObject(model.getObject().getHeadSupervisor());
//we need to create any follower object that doesnt already exist with projectfollowerdao AND save project
wmc.add(followerPanel = new AddRemoveProjectFollowerPanel("followerPanel", model.getObject().getProjectFollowers(), model) {
@Override
public void onUpdate(AjaxRequestTarget target) {
//do nothing
}
});
wmc.add(new AjaxButton("saveButton") {
private static final long serialVersionUID = 1L;
@Override
protected void onSubmit(AjaxRequestTarget target, Form<?> form) {
boolean hasFailed = false;
target.addComponent(feedbackPanel);
if(titleField.getModelObject() == null || titleField.getModelObject().isEmpty()){
error("Enter a title");
hasFailed = true;
}
if(level.getModelObject() == null){
error("Select a level");
hasFailed = true;
}
if (headsupervisorField.getModelObject() == null
|| headsupervisorField.getInput() == null
|| headsupervisorField.getInput().isEmpty()
|| !headsupervisorField.getInput().equals(headsupervisorField.getModelObject().getNameAsString())){
error("Select a head supervisor");
hasFailed = true;
}
if (studentsPanel.getStudentSet() == null || studentsPanel.getStudentSet().isEmpty()){
error("Add at least one student");
hasFailed = true;
}
if (hasFailed == true){
System.out.println("FAIL");
}
else {
System.out.println("GREEN LIGHT");
Project p = model.getObject();
p.setHeadSupervisor(headsupervisorField.getModelObject());
p.setProjectParticipants(studentsPanel.getStudentSet());
p.setProjectFollowers(followerPanel.getProjectFollowerSet());
model.setObject(projectDao.save(p));
onUpdate(target);
}
}
@Override
protected void onError(AjaxRequestTarget target, Form<?> form) {
target.addComponent(feedbackPanel);
}
});
}
}
public abstract boolean isEditable();
}

@ -171,7 +171,6 @@ public class AdminListCheckListTemplatePanel extends Panel{
@Override
protected void populateItem(final ListItem<CheckListTemplate> item) {
Label templateName = new Label("templateName", new PropertyModel<String>(item.getModel(),"name"));
Label templateOwner = new Label("templateOwner", new PropertyModel<String>(item.getModel(), "creator"));
Label templateOuestion = new Label("templateOuestion", new PropertyModel<String>(item.getModel(), "numberOfQuestions"));
String labelMsg = getChecklistCategoryString(item.getModelObject().getCategories());
@ -240,7 +239,7 @@ public class AdminListCheckListTemplatePanel extends Panel{
deleteLink.add(new ImageObject("deleteIcon", ImageObject.TWENTYFOUR + ImageObject.DELETE));
deleteLink.add(new ImageObject("deleteIcon", ImageObject.SIXTEEN + ImageObject.DELETE));
deleteLink.add(new JavascriptEventConfirmation("onclick", "Are you sure you want to remove this template?"));
item.add(deleteLink);
@ -295,7 +294,6 @@ public class AdminListCheckListTemplatePanel extends Panel{
};
templateLink.add(templateName);
item.add(categoriesLabel);
item.add(templateOwner);
item.add(templateOuestion);
item.add(templateLink);
}

@ -0,0 +1,31 @@
<!DOCTYPE html>
<html
xmlns:wicket="http://wicket.apache.org/dtds.data/wicket-xhtml1.4-strict.dtd">
<body>
<wicket:panel>
<div wicket:id="container">
<table class="rounded-corner">
<thead>
<tr>
<th class="rounded-left-top">Application period</th><th>End date</th><th>Number of students</th>
</tr>
</thead>
<tbody>
<tr wicket:id="periodList">
<!-- <td><span wicket:id="name"></span></</td> -->
<td wicket:id="applicationPeriodName"></td>
<td wicket:id="applicationPeriodEndDate"></td>
<td wicket:id="numberOfStudents"></td>
</tr>
</tbody>
<tfoot>
<tr>
<td colspan="5" class="rounded-foot">&nbsp;</td>
</tr>
</tfoot>
</table>
</div>
<div wicket:id="nav"></div>
</wicket:panel>
</body>
</html>

@ -0,0 +1,80 @@
package se.su.dsv.scipro.admin.panels;
import java.util.List;
import org.apache.wicket.markup.html.WebMarkupContainer;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.navigation.paging.PagingNavigator;
import org.apache.wicket.markup.html.panel.Panel;
import org.apache.wicket.markup.repeater.Item;
import org.apache.wicket.markup.repeater.data.DataView;
import org.apache.wicket.spring.injection.annot.SpringBean;
import se.su.dsv.scipro.match.dao.interfaces.ApplicationPeriodDao;
import se.su.dsv.scipro.match.dataobject.ApplicationPeriod;
import se.su.dsv.scipro.match.dataobject.ProjectIdea;
import se.su.dsv.scipro.match.dataprovider.ProjectIdeaStatisticDataProvider;
public class AdminProjectIdeaStatisticPanel extends Panel {
private static final long serialVersionUID = 1L;
@SpringBean
private ApplicationPeriodDao applicationPeriodDao;
private DataView<ApplicationPeriod> dataView;
private List<ApplicationPeriod> applicationPeriods;
private ProjectIdeaStatisticDataProvider provider;
private WebMarkupContainer container;
private PagingNavigator nav;
public AdminProjectIdeaStatisticPanel(String str) {
super(str);
setup();
setupDataview();
}
private void setup() {
container = new WebMarkupContainer("container");
container.setOutputMarkupId(true);
applicationPeriods = applicationPeriodDao.findAll();
if(!applicationPeriods.isEmpty()){
List<ProjectIdea> projectIdeas = applicationPeriodDao.getProjectIdeas(applicationPeriods.get(0));
System.out.println(applicationPeriods.get(0));
for(ProjectIdea pi : projectIdeas){
System.out.println(pi);
}
}
}
private void setupDataview(){
provider = new ProjectIdeaStatisticDataProvider();
dataView = new DataView<ApplicationPeriod>("periodList", provider, 15) {
private static final long serialVersionUID = 3572766096237883198L;
@Override
protected void populateItem(Item<ApplicationPeriod> item) {
List<ProjectIdea> projectIdeas = applicationPeriodDao.getProjectIdeas(item.getModelObject());
int students = 0;
for (ProjectIdea pi : projectIdeas){
students += pi.getAuthors().size();
}
item.add(new Label("applicationPeriodName", ""+item.getModelObject().getName()));
item.add(new Label("applicationPeriodEndDate", ""+item.getModelObject().getEndDate()));
item.add(new Label("numberOfStudents", ""+students));
}
};
container.add(dataView);
nav = new PagingNavigator("nav", dataView);
nav.setOutputMarkupId(true);
add(container);
add(nav);
}
}

@ -14,6 +14,7 @@ import se.su.dsv.scipro.admin.pages.AdminProjectPartnerPage;
import se.su.dsv.scipro.admin.pages.AdminRolePage;
import se.su.dsv.scipro.admin.pages.AdminScheduleTemplatesPage;
import se.su.dsv.scipro.admin.pages.AdminStartPage;
import se.su.dsv.scipro.admin.pages.AdminStatisticsPage;
import se.su.dsv.scipro.admin.pages.ProjectManagementPage;
import se.su.dsv.scipro.admin.pages.SystemMaintenancePage;
import se.su.dsv.scipro.admin.pages.match.AdminManageProjectIdeaPage;
@ -48,6 +49,7 @@ public class AdminTabMenuPanel extends AbstractMenuPanel {
items.add(new MenuItem("CheckList", AdminCheckListPage.class));
items.add(new MenuItem("Match", AdminManageProjectIdeaPage.class));
items.add(new MenuItem("Mail", AdminMailPage.class));
items.add(new MenuItem("Statistics", AdminStatisticsPage.class));
return items;
}

@ -52,7 +52,9 @@ public class AdminViewCheckListTemplatePanel extends Panel {
//Setup form-details
final IModel<String> templateNameModel = new Model<String>(clt.getName());
final AjaxEditableLabel<String> templateNameLabel = new AjaxEditableLabel<String>("templateName",
//REMOVED IN HTML MARKUP - SUPPOSED TO STAY?
/*final AjaxEditableLabel<String> templateNameLabel = new AjaxEditableLabel<String>("templateName",
templateNameModel){
private static final long serialVersionUID = 1L;
@Override
@ -60,7 +62,7 @@ public class AdminViewCheckListTemplatePanel extends Panel {
super.onSubmit(target);
clt.setName(templateNameModel.getObject());
}
};
};*/
questionField = new RequiredTextField<String>("questionField", new PropertyModel<String>(this, "question"));
questionField.setOutputMarkupId(true);
@ -134,7 +136,7 @@ public class AdminViewCheckListTemplatePanel extends Panel {
}
};
item.add(deleteLink);
deleteLink.add(new ImageObject("deleteIcon", ImageObject.TWENTYFOUR + ImageObject.DELETE));
deleteLink.add(new ImageObject("deleteIcon", ImageObject.SIXTEEN + ImageObject.DELETE));
deleteLink.add(new JavascriptEventConfirmation("onclick", "Are you sure you want to remove this question?"));
}
};
@ -161,7 +163,7 @@ public class AdminViewCheckListTemplatePanel extends Panel {
};
addQuestionButton.setOutputMarkupId(true);
//Add components to hierarchy
container.add(templateNameLabel);
//container.add(templateNameLabel);
container.add(listView);
add(container);
addQuestionForm.add(questionField);

@ -1,19 +1,21 @@
<!DOCTYPE html>
<html
xmlns:wicket="http://wicket.apache.org/dtds.data/wicket-xhtml1.4-strict.dtd">
xmlns:wicket="http://wicket.apache.org/dtds.data/wicket-xhtml1.4-strict.dtd">
<body>
<wicket:panel>
<div wicket:id="main"></div>
<wicket:fragment wicket:id="buttonFragment">
<button wicket:id="manualMatchButton">Match manually</button>
</wicket:fragment>
<wicket:fragment wicket:id="matchFragment">
<form wicket:id="matchForm">
Supervisor: <div wicket:id="supervisorTextField"></div>
<button type="submit">Save</button>
<button wicket:id="cancelButton">Cancel</button>
</form>
</wicket:fragment>
</wicket:panel>
<wicket:panel>
<div wicket:id="main"></div>
<wicket:fragment wicket:id="buttonFragment">
<button wicket:id="manualMatchButton">Match manually</button>
<button wicket:id="manualSuggestButton">Suggest manually</button>
</wicket:fragment>
<wicket:fragment wicket:id="matchFragment">
<form wicket:id="matchForm">
<div wicket:id ="localFeedback" />
Supervisor:<br /><input wicket:id="autoComplete" /><br />
<a href="#" wicket:id="saveButton"><input type="button" value="Save"/></a>
<button wicket:id="cancelButton">Cancel</button>
</form>
</wicket:fragment>
</wicket:panel>
</body>
</html>

@ -1,192 +1,305 @@
package se.su.dsv.scipro.admin.panels;
import java.util.List;
import java.util.Iterator;
import com.visural.wicket.component.confirmer.ConfirmerAjaxSubmitLink;
import org.apache.wicket.Component;
import org.apache.wicket.Session;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.ajax.markup.html.AjaxFallbackLink;
import org.apache.wicket.markup.html.form.ChoiceRenderer;
import org.apache.wicket.markup.html.form.Form;
import org.apache.wicket.markup.html.panel.FeedbackPanel;
import org.apache.wicket.markup.html.panel.Fragment;
import org.apache.wicket.markup.html.panel.Panel;
import org.apache.wicket.model.IModel;
import org.apache.wicket.model.LoadableDetachableModel;
import org.apache.wicket.spring.injection.annot.SpringBean;
import org.apache.wicket.util.string.Strings;
import org.odlabs.wiquery.ui.autocomplete.AutocompleteComponent;
import se.su.dsv.scipro.SciProSession;
import se.su.dsv.scipro.data.dao.interfaces.UserDao;
import se.su.dsv.scipro.admin.pages.match.AdminManageProjectIdeaPage;
import se.su.dsv.scipro.data.dataobjects.Employee;
import se.su.dsv.scipro.data.dataobjects.User;
import se.su.dsv.scipro.data.facade.ProjectIdeaFacade;
import se.su.dsv.scipro.match.dao.interfaces.MatchDao;
import se.su.dsv.scipro.match.dao.interfaces.SupervisorDao;
import se.su.dsv.scipro.match.dataobject.Match;
import se.su.dsv.scipro.match.dataobject.Match.Status;
import se.su.dsv.scipro.match.dataobject.ProjectIdea;
import se.su.dsv.wicket.components.AutoCompleteObjectField;
public class ManualMatchPanel extends Panel {
private static final long serialVersionUID = 1L;
@SpringBean
private MatchDao matchDao;
private static final long serialVersionUID = -2571670452692097554L;
@SpringBean
private MatchDao matchDao;
@SpringBean
SupervisorDao supervisorDao;
@SpringBean
UserDao userDao;
private Fragment currentFragment;
private Fragment alternateFragment;
private Form<Employee> matchForm;
private AutocompleteComponent<Employee> autocompleteSupervisorField;
private Long supervisorId;
private boolean confirmed;
public ManualMatchPanel(String id, IModel<Match> matchModel, final boolean confirmed__) {
super(id);
supervisorId = matchModel.getObject().getSupervisor() != null ? matchModel.getObject().getSupervisor().getId() : 0L;
setOutputMarkupPlaceholderTag(true);
currentFragment = createButtonFragment();
alternateFragment = createMatchFragment(matchModel);
add(currentFragment);
confirmed = confirmed__;
}
private Fragment createButtonFragment() {
Fragment buttonFragment = new Fragment("main", "buttonFragment", this) {
private static final long serialVersionUID = 1L;
@Override
protected void onBeforeRender() {
matchForm.setEnabled(false);
super.onBeforeRender();
}
};
buttonFragment.add(new AjaxFallbackLink<Object>("manualMatchButton") {
SupervisorDao supervisorDao;
private static final long serialVersionUID = 1L;
@SpringBean
ProjectIdeaFacade projectIdeaFacade;
@Override
public void onClick(AjaxRequestTarget target) {
swapFragment();
if (target != null) {
target.addComponent(currentFragment);
}
}
});
buttonFragment.setOutputMarkupPlaceholderTag(true);
return buttonFragment;
}
private Fragment createMatchFragment(final IModel<Match> matchModel) {
Fragment matchFragment = new Fragment("main", "matchFragment", this) {
private Fragment currentFragment;
private Fragment alternateFragment;
private AutoCompleteObjectField<Employee, Long> autoCompleteObjectField;
private static final long serialVersionUID = 1L;
@Override
protected void onBeforeRender() {
matchForm.setEnabled(true);
super.onBeforeRender();
}
};
autocompleteSupervisorField = createAutocompleteComponent();
autocompleteSupervisorField.setModelObject(null);
matchForm = new Form<Employee>("matchForm") {
private static final long serialVersionUID = 1L;
@Override
public void onSubmit() {
matchModel.getObject().setSupervisor(autocompleteSupervisorField.getModelObject());
if(confirmed) {
matchModel.getObject().setStatus(Status.CONFIRMED);
public ManualMatchPanel(String id, final IModel<Match> matchModel, final Component feedbackPanel, final Match.Status status) {
super(id);
Component localFeedback = new FeedbackPanel("localFeedback");
ConfirmerAjaxSubmitLink saveButton = createSubmitLink(matchModel, feedbackPanel, status, localFeedback);
autoCompleteObjectField = createDsvAutocompleteComponent(matchModel.getObject().getProjectIdea(), status, saveButton);
setOutputMarkupPlaceholderTag(true);
Form<Employee> matchForm = new Form<Employee>("matchForm");
currentFragment = createButtonFragment(status, matchForm);
currentFragment.setOutputMarkupId(true);
alternateFragment = createMatchFragment(saveButton, matchForm, localFeedback);
alternateFragment.setOutputMarkupId(true);
add(currentFragment);
}
private ConfirmerAjaxSubmitLink createSubmitLink(final IModel<Match> matchModel, final Component feedbackPanel, final Match.Status status, final Component localFeedback) {
return new ConfirmerAjaxSubmitLink("saveButton") {
private static final long serialVersionUID = -1820883998549197409L;
@Override
protected void onSubmit(AjaxRequestTarget target, Form<?> form) {
if(autoCompleteObjectField.getModelObject() == null) {
Session.get().info("No match could be created because the supervisor was incorrect.");
target.addComponent(localFeedback);
} else {
matchModel.getObject().setStatus(Status.PUBLISHED);
matchModel.getObject().setSupervisor(autoCompleteObjectField.getModelObject() != null ? autoCompleteObjectField.getModelObject():null);
matchModel.getObject().setStatus(status);
matchDao.changeStatus(SciProSession.get().getUser(), matchModel.getObject(), null);
Session.get().info(createMatchMessage(autoCompleteObjectField.getModelObject().getNameAsString(), matchModel.getObject().getProjectIdea().getTitle(), status));
setResponsePage(AdminManageProjectIdeaPage.class);
target.addComponent(feedbackPanel);
}
matchDao.changeStatus(SciProSession.get().getUser(), matchModel.getObject(), null);
}
}
@Override //Listener method invoked on form submit with errors
protected void onError(AjaxRequestTarget target, Form<?> form) {
error("The match could not be performed");
super.onError(target, form);
target.addComponent(feedbackPanel); // is only activated on "this"
}
};
}
private Fragment createButtonFragment(final Match.Status status, final Form<Employee> matchForm) {
Fragment buttonFragment = new Fragment("main", "buttonFragment", this) {
private static final long serialVersionUID = 2699118307386334814L;
@Override
protected void onBeforeRender() {
matchForm.setEnabled(false);
super.onBeforeRender();
}
};
buttonFragment.add(new AjaxFallbackLink<Object>("manualMatchButton") {
private static final long serialVersionUID = -4109797039618804359L;
@Override
public void onClick(AjaxRequestTarget target) {
swapFragment();
if (target != null) {
target.addComponent(currentFragment);
}
}
@Override
public boolean isVisible() {
return status.equals(Match.Status.CONFIRMED);
}
}.setOutputMarkupId(true).setOutputMarkupPlaceholderTag(true));
buttonFragment.add(new AjaxFallbackLink<Object>("manualSuggestButton") {
private static final long serialVersionUID = -4023839385675090195L;
@Override
public void onClick(AjaxRequestTarget target) {
swapFragment();
if (target != null) {
target.addComponent(currentFragment);
}
}
@Override
public boolean isVisible() {
return status.equals(Match.Status.PUBLISHED);
}
}.setOutputMarkupId(true).setOutputMarkupPlaceholderTag(true));
buttonFragment.setOutputMarkupPlaceholderTag(true);
return buttonFragment;
}
private Fragment createMatchFragment(final ConfirmerAjaxSubmitLink saveButton, final Form<Employee> matchForm, Component localFeedback) {
Fragment matchFragment = new Fragment("main", "matchFragment", this) {
private static final long serialVersionUID = -7770434904843562942L;
@Override
protected void onBeforeRender() {
matchForm.setEnabled(true);
super.onBeforeRender();
}
};
autoCompleteObjectField.setModelObject(null);
matchForm.add(autocompleteSupervisorField);
saveButton.setOutputMarkupId(true);
localFeedback.setOutputMarkupId(true);
matchForm.add(localFeedback);
matchForm.add(autoCompleteObjectField);
matchForm.add(saveButton);
matchForm.add(new AjaxFallbackLink<Object>("cancelButton") {
private static final long serialVersionUID = 1L;
private static final long serialVersionUID = 1L;
@Override
public void onClick(AjaxRequestTarget target) {
swapFragment();
if (target != null) {
target.addComponent(currentFragment);
}
}
@Override
public void onClick(AjaxRequestTarget target) {
swapFragment();
if (target != null) {
target.addComponent(currentFragment);
}
}
});
matchFragment.add(matchForm);
matchFragment.setOutputMarkupPlaceholderTag(true);
return matchFragment;
}
private AutocompleteComponent<Employee> createAutocompleteComponent() {
LoadableDetachableModel<List<Employee>> supervisorListModel = new LoadableDetachableModel<List<Employee>>() {
matchFragment.add(matchForm);
matchFragment.setOutputMarkupPlaceholderTag(true);
return matchFragment;
}
private static final long serialVersionUID = 1L;
public AutoCompleteObjectField<Employee, Long> createDsvAutocompleteComponent(final ProjectIdea projectIdea, final Match.Status status, final ConfirmerAjaxSubmitLink saveButton) {
return new AutoCompleteObjectField<Employee, Long>("autoComplete", Employee.class) {
private static final long serialVersionUID = 7734889540424308421L;
@Override
protected List<Employee> load() {
return supervisorDao.findAll();
}
};
LoadableDetachableModel<Employee> supervisorModel = new LoadableDetachableModel<Employee>() {
private static final long serialVersionUID = 1L;
@Override
protected Employee load() {
if(supervisorId != 0L)
return supervisorDao.load(supervisorId);
else
@Override
public Employee loadObject(Long supervisorId) {
if(supervisorId != null && supervisorId != 0L) {
return supervisorDao.load(supervisorId);
} else {
return null;
}
};
ChoiceRenderer<Employee> choiceRenderer = new ChoiceRenderer<Employee>() {
private static final long serialVersionUID = 1L;
}
}
@Override
public String getDisplayValue(Employee supervisor) {
return supervisor.getUser().getFullName();
}
@Override
public String getIdValue(Employee supervisor, int index) {
return supervisor.getId().toString();
}
};
return new AutocompleteComponent<Employee>("supervisorTextField",
supervisorModel, supervisorListModel, choiceRenderer) {
@Override
public Long convertId(String id) {
if(id != null && !id.isEmpty()) {
return Long.valueOf(id);
} else {
return 0L;
}
}
private static final long serialVersionUID = 1L;
@Override
public Employee getValueOnSearchFail(String input) {
if (Strings.isEmpty(input)) {
return null;
} else {
User tempUser = new User();
tempUser.setFirstName(input);
Employee supervisor = new Employee();
supervisor.setUser(tempUser);
return supervisor;
}
}
};
}
@Override
public Long getId(Employee employee) {
if(employee != null) {
return employee.getId();
} else {
return 0L;
}
}
@Override
public Iterator<Employee> getChoices(String input) {
return supervisorDao.getAutoCompleteCapableSupervisors(input, 6).iterator();
}
@Override
public void onNewSelection(AjaxRequestTarget pTarget, Employee newSelection) {
super.onNewSelection(pTarget, newSelection);
if (newSelection != null) {
if (pTarget != null) {
final String declineMessage = createDeclineMessage(newSelection.getUser(), projectIdea, status);
if(declineMessage != null && !declineMessage.isEmpty()) {
saveButton.setMessageContentHTML(declineMessage);
pTarget.addComponent(saveButton);
} else {
saveButton.setMessageContentHTML(createConfirmationMessage(newSelection.getUser(), status));
pTarget.addComponent(saveButton);
}
}
}
}
};
}
private void swapFragment() {
Fragment tempFragment = currentFragment;
currentFragment.replaceWith(alternateFragment);
currentFragment = alternateFragment;
alternateFragment = tempFragment;
}
/**
*
* This method is used to return a match message that an employee was matched or suggested to a project idea .
* @param employeeName the employee
* @param projectIdeaTitle from which we get the match history
* @param status the status
* @return String the confirmation message
*/
private String createMatchMessage(final String employeeName, final String projectIdeaTitle, Match.Status status) {
StringBuilder messageStr = new StringBuilder();
messageStr.append("The project idea ");
messageStr.append(projectIdeaTitle != null ? projectIdeaTitle : "");
if(status.equals(Match.Status.CONFIRMED)) {
messageStr.append(" was matched to ");
} else if (status.equals(Match.Status.PUBLISHED)) {
messageStr.append(" was suggested to ");
}
messageStr.append(employeeName != null ? employeeName : "" );
messageStr.append(".");
return messageStr.toString();
}
/**
*
* This method is used to return a decline message if an employee already has declined a Match between the employee and a specific project idea .
* @param supervisor the employee
* @param projectIdea from which we get the match history
* @param status the status
* @return String the decline message
*/
private String createDeclineMessage(User supervisor, ProjectIdea projectIdea, Match.Status status) {
if(supervisor != null && projectIdea != null) {
final String declineMessage = projectIdeaFacade.declineMessageWhenRejectedMatch(supervisor, projectIdea);
StringBuilder stringBuilder = new StringBuilder();
if(declineMessage != null && !declineMessage.isEmpty()) {
stringBuilder.append("The project idea has already been rejected by ");
stringBuilder.append(supervisor.getFullName());
stringBuilder.append(". The decline message was: '");
stringBuilder.append(declineMessage);
if(status.equals(Match.Status.CONFIRMED)) {
stringBuilder.append("'. Do you want to match the project idea anyway?");
} else if (status.equals(Match.Status.PUBLISHED)) {
stringBuilder.append("'. Do you want to suggest the project idea anyway?");
}
}
return stringBuilder.toString();
}
return null;
}
/**
*
* This method is used to return a confirmation message that you want to create a match between the employee and a specific project idea .
* @param supervisor the employee
* @param status the status
* @return String the decline message
*/
private String createConfirmationMessage(User supervisor, Match.Status status) {
StringBuilder stringBuilder = new StringBuilder();
if(status.equals(Match.Status.CONFIRMED)) {
stringBuilder.append("Confirm that you want to match the project idea to ");
} else if (status.equals(Match.Status.PUBLISHED)) {
stringBuilder.append("Confirm that you want to suggest the project idea to ");
}
stringBuilder.append(supervisor.getFullName());
stringBuilder.append(".");
return stringBuilder.toString();
}
private void swapFragment() {
Fragment tempFragment = currentFragment;
currentFragment.replaceWith(alternateFragment);
currentFragment = alternateFragment;
alternateFragment = tempFragment;
}
}

@ -5,13 +5,14 @@
<wicket:panel>
<div wicket:id="main"></div>
<wicket:fragment wicket:id="buttonFragment">
<button wicket:id="manualSetReviewerButton">Suggest reviewer</button>
<button wicket:id="manualSetReviewerButton">Suggest REVIEWER manually</button>
</wicket:fragment>
<wicket:fragment wicket:id="reviewerFragment">
<form wicket:id="reviewerForm">
Supervisor: <div wicket:id="reviewerTextField"></div>
<button type="submit" style="float: right;">Save</button>
<button wicket:id="cancelButton" style="float: right;">Cancel</button>
<div wicket:id="localFeedback" />
Reviewer: <br /><input wicket:id="reviewerTextField"/><br />
<a href="#" wicket:id="saveButton"><input type="button" value="Save"/></a>
<button wicket:id="cancelButton">Cancel</button>
</form>
</wicket:fragment>
</wicket:panel>

@ -1,57 +1,85 @@
package se.su.dsv.scipro.admin.panels;
import com.visural.wicket.component.confirmer.ConfirmerAjaxSubmitLink;
import org.apache.wicket.Component;
import org.apache.wicket.Session;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.ajax.markup.html.AjaxFallbackLink;
import org.apache.wicket.markup.html.form.ChoiceRenderer;
import org.apache.wicket.markup.html.form.Form;
import org.apache.wicket.markup.html.panel.FeedbackPanel;
import org.apache.wicket.markup.html.panel.Fragment;
import org.apache.wicket.markup.html.panel.Panel;
import org.apache.wicket.model.IModel;
import org.apache.wicket.model.LoadableDetachableModel;
import org.apache.wicket.spring.injection.annot.SpringBean;
import org.apache.wicket.util.string.Strings;
import org.odlabs.wiquery.ui.autocomplete.AutocompleteComponent;
import se.su.dsv.scipro.admin.pages.match.AdminManageProjectIdeaPage;
import se.su.dsv.scipro.data.dataobjects.Employee;
import se.su.dsv.scipro.data.dataobjects.User;
import se.su.dsv.scipro.match.dao.interfaces.ProjectIdeaDao;
import se.su.dsv.scipro.match.dao.interfaces.SupervisorDao;
import se.su.dsv.scipro.match.dataobject.ProjectIdea;
import se.su.dsv.wicket.components.AutoCompleteObjectField;
import java.util.List;
import java.util.Iterator;
public class ManualSetReviewerPanel extends Panel {
private static final long serialVersionUID = 1L;
// @SpringBean
// private MatchDao matchDao;
@SpringBean
private ProjectIdeaDao projectIdeaDao;
@SpringBean
SupervisorDao supervisorDao;
// @SpringBean
// UserDao userDao;
private Fragment currentFragment;
private Fragment alternateFragment;
private Form<Employee> reviewerForm;
private AutocompleteComponent<Employee> autocompleteReviewerField;
private Long reviewerId;
public ManualSetReviewerPanel(String id, IModel<ProjectIdea> projectIdeaModel) {
private AutoCompleteObjectField<Employee, Long> autocompleteReviewerField;
public ManualSetReviewerPanel(String id, IModel<ProjectIdea> projectIdeaModel, Component feedbackPanel) {
super(id);
reviewerId = projectIdeaModel.getObject().getSuggestedReviewer() != null ? projectIdeaModel.getObject().getSuggestedReviewer().getId() : 0L;
Component localFeedback = new FeedbackPanel("localFeedback");
ConfirmerAjaxSubmitLink saveButton = createSubmitLink(projectIdeaModel, feedbackPanel, localFeedback);
autocompleteReviewerField = createDsvAutocompleteComponent(projectIdeaModel.getObject(), saveButton);
setOutputMarkupPlaceholderTag(true);
currentFragment = createButtonFragment();
alternateFragment = createReviewerFragment(projectIdeaModel);
Form<Employee> reviewerForm = new Form<Employee>("reviewerForm");
currentFragment = createButtonFragment(reviewerForm);
alternateFragment = createReviewerFragment(saveButton, reviewerForm, localFeedback);
add(currentFragment);
}
private Fragment createButtonFragment() {
private ConfirmerAjaxSubmitLink createSubmitLink(final IModel<ProjectIdea> projectIdeaModel, final Component feedbackPanel, final Component localFeedback) {
return new ConfirmerAjaxSubmitLink("saveButton") {
private static final long serialVersionUID = -1852298712407811714L;
@Override
protected void onSubmit(AjaxRequestTarget target, Form<?> form) {
if(autocompleteReviewerField.getModelObject() == null) {
Session.get().info("No match could be created because the reviewer was incorrect.");
target.addComponent(localFeedback);
} else {
ProjectIdea projectIdea = projectIdeaModel.getObject();
projectIdea.setSuggestedReviewer(autocompleteReviewerField.getModelObject());
projectIdeaDao.save(projectIdea);
Session.get().info(getInfoMessage(projectIdea.getTitle(), autocompleteReviewerField.getModelObject().getNameAsString()));
setResponsePage(AdminManageProjectIdeaPage.class);
target.addComponent(feedbackPanel);
}
}
@Override //Listener method invoked on form submit with errors
protected void onError(AjaxRequestTarget target, Form<?> form) {
error(getErrorMessage(projectIdeaModel.getObject().getTitle(), autocompleteReviewerField.getModelObject().getNameAsString()));
super.onError(target, form);
setResponsePage(AdminManageProjectIdeaPage.class);
target.addComponent(feedbackPanel); // is only activated on "this"
}
};
}
private Fragment createButtonFragment(final Form<Employee> reviewerForm) {
Fragment buttonFragment = new Fragment("main", "buttonFragment", this) {
private static final long serialVersionUID = 1L;
private static final long serialVersionUID = 2383077895140299047L;
@Override
protected void onBeforeRender() {
@ -61,7 +89,7 @@ public class ManualSetReviewerPanel extends Panel {
};
buttonFragment.add(new AjaxFallbackLink<Object>("manualSetReviewerButton") {
private static final long serialVersionUID = 1L;
private static final long serialVersionUID = 5843396419011530582L;
@Override
public void onClick(AjaxRequestTarget target) {
@ -75,10 +103,10 @@ public class ManualSetReviewerPanel extends Panel {
return buttonFragment;
}
private Fragment createReviewerFragment(final IModel<ProjectIdea> projectIdeaModel) {
private Fragment createReviewerFragment(ConfirmerAjaxSubmitLink saveButton, final Form<Employee> reviewerForm, Component localFeedback) {
Fragment reviewerFragment = new Fragment("main", "reviewerFragment", this) {
private static final long serialVersionUID = 1L;
private static final long serialVersionUID = -1831632235479216987L;
@Override
protected void onBeforeRender() {
@ -86,23 +114,17 @@ public class ManualSetReviewerPanel extends Panel {
super.onBeforeRender();
}
};
autocompleteReviewerField = createAutocompleteComponent();
autocompleteReviewerField.setModelObject(null);
reviewerForm = new Form<Employee>("reviewerForm") {
private static final long serialVersionUID = 1L;
@Override
public void onSubmit() {
ProjectIdea projectIdea = projectIdeaModel.getObject();
projectIdea.setSuggestedReviewer(autocompleteReviewerField.getModelObject());
projectIdeaDao.save(projectIdea);
}
};
reviewerForm.add(autocompleteReviewerField);
saveButton.setOutputMarkupId(true);
localFeedback.setOutputMarkupId(true);
reviewerForm.add(localFeedback);
reviewerForm.add(saveButton);
reviewerForm.add(new AjaxFallbackLink<Object>("cancelButton") {
private static final long serialVersionUID = 1L;
private static final long serialVersionUID = 5413209640805412939L;
@Override
public void onClick(AjaxRequestTarget target) {
@ -117,64 +139,81 @@ public class ManualSetReviewerPanel extends Panel {
return reviewerFragment;
}
private AutocompleteComponent<Employee> createAutocompleteComponent() {
LoadableDetachableModel<List<Employee>> reviewerListModel = new LoadableDetachableModel<List<Employee>>() {
private static final long serialVersionUID = 1L;
public AutoCompleteObjectField<Employee, Long> createDsvAutocompleteComponent(final ProjectIdea projectIdea, final ConfirmerAjaxSubmitLink saveButton) {
return new AutoCompleteObjectField<Employee, Long>("reviewerTextField", Employee.class) {
private static final long serialVersionUID = 8639430940925886127L;
@Override
protected List<Employee> load() {
return supervisorDao.findAll();
}
};
LoadableDetachableModel<Employee> reviewerModel = new LoadableDetachableModel<Employee>() {
private static final long serialVersionUID = 1L;
@Override
protected Employee load() {
if(reviewerId != 0L)
return supervisorDao.load(reviewerId);
else
return null;
}
};
ChoiceRenderer<Employee> choiceRenderer = new ChoiceRenderer<Employee>() {
private static final long serialVersionUID = 1L;
@Override
public String getDisplayValue(Employee reviewer) {
return reviewer.getUser().getFullName();
}
@Override
public String getIdValue(Employee reviewer, int index) {
return reviewer.getId().toString();
}
};
return new AutocompleteComponent<Employee>("reviewerTextField",
reviewerModel, reviewerListModel, choiceRenderer) {
private static final long serialVersionUID = 1L;
@Override
public Employee getValueOnSearchFail(String input) {
if (Strings.isEmpty(input)) {
return null;
public Employee loadObject(Long supervisorId) {
if(supervisorId != null && supervisorId != 0L) {
return supervisorDao.load(supervisorId);
} else {
User tempUser = new User();
tempUser.setFirstName(input);
Employee reviewer = new Employee();
reviewer.setUser(tempUser);
return reviewer;
return null;
}
}
@Override
public Long convertId(String id) {
if(id != null && !id.isEmpty()) {
return Long.valueOf(id);
} else {
return 0L;
}
}
@Override
public Long getId(Employee employee) {
if(employee != null) {
return employee.getId();
} else {
return 0L;
}
}
@Override
public Iterator<Employee> getChoices(String input) {
return supervisorDao.getAutoCompleteCapableSupervisors(input, 6).iterator();
}
@Override
public void onNewSelection(AjaxRequestTarget pTarget, Employee newSelection) {
super.onNewSelection(pTarget, newSelection);
if (newSelection != null) {
if (pTarget != null) {
saveButton.setMessageContentHTML(getConfirmMessage(newSelection.getNameAsString(), projectIdea.getTitle()));
pTarget.addComponent(saveButton);
}
}
}
};
}
private String getConfirmMessage(String employeeName, String projectIdeaTitle) {
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append("Are you sure that you want to suggest ");
stringBuilder.append(employeeName);
stringBuilder.append(" as reviewer for the project idea ");
stringBuilder.append(projectIdeaTitle);
stringBuilder.append("?");
return stringBuilder.toString();
}
private String getInfoMessage(String projectIdeaTitle, String reviewerName) {
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append(reviewerName);
stringBuilder.append(" was suggested reviewer for the project idea ");
stringBuilder.append(projectIdeaTitle);
return stringBuilder.toString();
}
private String getErrorMessage(String projectIdeaTitle, String reviewerName) {
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append("An error occurred when suggesting ");
stringBuilder.append(reviewerName);
stringBuilder.append(" as reviewer for the project idea ");
stringBuilder.append(projectIdeaTitle);
return stringBuilder.toString();
}
private void swapFragment() {
Fragment tempFragment = currentFragment;

@ -5,6 +5,8 @@
<a href="#" wicket:id="actionLink">Actions</a>
|
<a href="#" wicket:id="watsonLink">Project idea details</a>
|
<a href="#" wicket:id="historyLink">Match history</a>
<div class="prepend-top" wicket:id="mainPanel"></div>
</wicket:panel>
</body>

@ -1,5 +1,6 @@
package se.su.dsv.scipro.admin.panels.match;
import org.apache.wicket.Component;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.ajax.markup.html.AjaxFallbackLink;
import org.apache.wicket.markup.html.panel.Panel;
@ -14,24 +15,23 @@ public class AdminEditProjectIdeaPanel extends Panel {
private static final long serialVersionUID = 1L;
private Panel watsonPanel;
private Panel actionPanel;
private Panel currentPanel;
private AjaxFallbackLink<Void> watsonLink;
private AjaxFallbackLink<Void> actionLink;
private Panel watsonPanel, actionPanel, historyPanel, currentPanel;
private AjaxFallbackLink<Void> watsonLink, actionLink, historyLink;
public AdminEditProjectIdeaPanel(String id, IModel<ProjectIdea> model) {
public AdminEditProjectIdeaPanel(String id, IModel<ProjectIdea> model, final Component feedbackPanel) {
super(id, model);
Match match = model.getObject().getMatch();
if (match != null) {
watsonPanel = new ManualWatsonPanel("mainPanel", model);
actionPanel = new ProjectIdeaActionPanel("mainPanel", model);
watsonPanel = new ManualWatsonPanel("mainPanel", model, feedbackPanel);
actionPanel = new ProjectIdeaActionPanel("mainPanel", model, feedbackPanel);
historyPanel = new MatchHistoryPanel("mainPanel", model, feedbackPanel);
currentPanel = actionPanel;
currentPanel.setOutputMarkupId(true);
watsonPanel.setOutputMarkupId(true);
actionPanel.setOutputMarkupId(true);
historyPanel.setOutputMarkupId(true);
watsonLink = new AjaxFallbackLink<Void>("watsonLink") {
private static final long serialVersionUID = 1L;
@ -48,6 +48,7 @@ public class AdminEditProjectIdeaPanel extends Panel {
if (target != null) {
target.addComponent(currentPanel);
target.addComponent(actionLink);
target.addComponent(historyLink);
target.addComponent(this);
}
}
@ -72,6 +73,7 @@ public class AdminEditProjectIdeaPanel extends Panel {
if (target != null) {
target.addComponent(currentPanel);
target.addComponent(watsonLink);
target.addComponent(historyLink);
target.addComponent(this);
}
}
@ -79,6 +81,30 @@ public class AdminEditProjectIdeaPanel extends Panel {
actionLink.setOutputMarkupId(true);
add(actionLink);
historyLink = new AjaxFallbackLink<Void>("historyLink") {
private static final long serialVersionUID = -9010339024625408623L;
@Override
public boolean isEnabled() {
return currentPanel != historyPanel;
}
@Override
public void onClick(AjaxRequestTarget target) {
currentPanel.replaceWith(historyPanel);
currentPanel = historyPanel;
if(target!=null){
target.addComponent(currentPanel);
target.addComponent(watsonLink);
target.addComponent(actionLink);
target.addComponent(this);
}
}
};
historyLink.setOutputMarkupId(true);
add(historyLink);
add(currentPanel);
} else {
this.setVisible(false);

@ -0,0 +1,40 @@
<!DOCTYPE html>
<html
xmlns:wicket="http://wicket.apache.org/dtds.data/wicket-xhtml1.4-strict.dtd">
<body>
<wicket:panel>
<div wicket:id="detailsDialog">
<div wicket:id="dialogContent"></div>
</div>
<div class="info-box rounded-box">
This page contains a list of all supervisors with number of research areas and keywords attached to them.
You may filter the list by searching for name of supervisor. Click on the supervisors name to see which research areas and keywords that is attached.
</div>
<form wicket:id="filterForm">
<label for="supervisorField">Filter using supervisor name:</label><br />
<input style="width:300px;" wicket:id="supervisorField" type="text" />
<input type="submit" wicket:id="filterButton" value="Filter"/>
</form>
<table wicket:id="table" class="rounded-corner">
<thead>
<tr>
<th class="rounded-left-top"><a href="#" wicket:id="nameSortLink">Name</a></th><th>Research Areas</th><th class="rounded-right-top">Regular keywords</th>
</tr>
</thead>
<tbody>
<tr wicket:id="supervisorList">
<td><a href="#" wicket:id="detailsLink"><span wicket:id="supervisorName"></span></a></td>
<td wicket:id="numberOfAreas"></td>
<td wicket:id="numberOfRegulars"></td>
</tr>
</tbody>
<tfoot>
<tr>
<td colspan="3" class="rounded-foot">&nbsp;</td>
</tr>
</tfoot>
</table>
<div wicket:id="nav"></div>
</wicket:panel>
</body>
</html>

@ -0,0 +1,158 @@
package se.su.dsv.scipro.admin.panels.match;
import java.util.List;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.ajax.markup.html.AjaxLink;
import org.apache.wicket.ajax.markup.html.form.AjaxButton;
import org.apache.wicket.markup.html.WebMarkupContainer;
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.navigation.paging.PagingNavigator;
import org.apache.wicket.markup.html.panel.EmptyPanel;
import org.apache.wicket.markup.html.panel.Panel;
import org.apache.wicket.markup.repeater.Item;
import org.apache.wicket.markup.repeater.data.DataView;
import org.apache.wicket.model.Model;
import org.apache.wicket.spring.injection.annot.SpringBean;
import org.odlabs.wiquery.ui.dialog.Dialog;
import se.su.dsv.scipro.data.dao.interfaces.Dao.SortableParams.Sort;
import se.su.dsv.scipro.data.dataobjects.Employee;
import se.su.dsv.scipro.dataproviders.QueryableDataProvider;
import se.su.dsv.scipro.match.dao.interfaces.KeywordTypeDao;
import se.su.dsv.scipro.match.dao.interfaces.SupervisorDao;
import se.su.dsv.scipro.match.dao.interfaces.SupervisorDaoParams;
import se.su.dsv.scipro.match.dataobject.Keyword;
public class AdminSupervisorKeywordPanel extends Panel {
private static final long serialVersionUID = 1L;
@SpringBean
private SupervisorDao supervisorDao;
private SupervisorDaoParams params;
private Dialog dialog;
private WebMarkupContainer tableContainer;
private QueryableDataProvider<Employee, SupervisorDaoParams> provider;
private DataView<Employee> dataView;
private TextField<String> supervisorField;
private PagingNavigator nav;
public AdminSupervisorKeywordPanel(String str) {
super(str);
setUpDialog();
setUpTable();
setUpFiltering();
}
private void setUpFiltering() {
FilterForm form = new FilterForm("filterForm");
add(form);
}
private void setUpDialog() {
dialog = new Dialog("detailsDialog");
dialog.setModal(true);
dialog.setAutoOpen(false);
dialog.setWidth(500);
dialog.setHeight(400);
dialog.setTitle("Supervisor details");
dialog.add(new EmptyPanel("dialogContent"));
dialog.setOutputMarkupId(true);
add(dialog);
}
private void setUpTable() {
tableContainer = new WebMarkupContainer("table");
tableContainer.setOutputMarkupId(true);
params = new SupervisorDaoParams();
params.setSortOn("user.lastName", Sort.ASCENDING);
provider = new QueryableDataProvider<Employee, SupervisorDaoParams>(supervisorDao, params);
dataView = new DataView<Employee>("supervisorList", provider, 15) {
private static final long serialVersionUID = 3572766096237883198L;
@Override
protected void populateItem(Item<Employee> item) {
final Employee supervisor = item.getModelObject();
List<Keyword> areaKeywords = supervisor.getKeywords().getFiltered(KeywordTypeDao.TYPE.RESEARCH_AREA.toDbName());
List<Keyword> regularKeywords = supervisor.getKeywords().getFiltered(KeywordTypeDao.TYPE.REGULAR.toDbName());
final AjaxLink<Void> detailsLink = new AjaxLink<Void>("detailsLink") {
private static final long serialVersionUID = 8902222410746133732L;
@Override
public void onClick(AjaxRequestTarget target) {
target.addComponent(dialog);
dialog.replace(new SupervisorKeywordDetailsPanel("dialogContent", supervisor) {
private static final long serialVersionUID = -7272997720134543477L;
@Override
public void onCloseButton(AjaxRequestTarget target) {
dialog.close(target);
}
});
dialog.open(target);
}
};
detailsLink.add(new Label("supervisorName", supervisor.getNameAsString()));
item.add(detailsLink);
item.add(new Label("numberOfAreas", ""+areaKeywords.size()));
item.add(new Label("numberOfRegulars", ""+regularKeywords.size()));
}
};
final AjaxLink<Void> nameSortLink = new AjaxLink<Void>("nameSortLink") {
private static final long serialVersionUID = -6459164267551936706L;
@Override
public void onClick(AjaxRequestTarget target) {
if(params.getDirection().equals(Sort.ASCENDING))
params.setSortOn("user.lastName", Sort.DESCENDING);
else
params.setSortOn("user.lastName", Sort.ASCENDING);
target.addComponent(tableContainer);
}
};
tableContainer.add(nameSortLink);
tableContainer.add(dataView);
nav = new PagingNavigator("nav", dataView);
nav.setOutputMarkupId(true);
add(nav);
add(tableContainer);
}
private class FilterForm extends Form<Void>{
private static final long serialVersionUID = 3488715734113880308L;
public FilterForm(String id) {
super(id);
supervisorField = new TextField<String>("supervisorField", new Model<String>());
AjaxButton filterButton = new AjaxButton("filterButton") {
private static final long serialVersionUID = -8216928567709372986L;
@Override
protected void onSubmit(AjaxRequestTarget target, Form<?> form) {
params.setNameLike(supervisorField.getModelObject());
target.addComponent(tableContainer);
target.addComponent(nav);
}
};
add(supervisorField);
add(filterButton);
}
}
}

@ -1,14 +0,0 @@
<!DOCTYPE html>
<html
xmlns:wicket="http://wicket.apache.org/dtds.data/wicket-xhtml1.4-strict.dtd">
<body>
<wicket:panel>
<form wicket:id="editKeywordForm">
<div><b>Name: </b><input type="text" wicket:id="name"></input></div>
<div><b>Type: </b><select wicket:id="keywordTypeSelector"></select></div>
<div><b>Active: </b><input type="checkbox" wicket:id="activeCheckbox" /></div>
<div><input wicket:id="saveButton" type="submit" value="Save" /></div>
</form>
</wicket:panel>
</body>
</html>

@ -1,71 +0,0 @@
package se.su.dsv.scipro.admin.panels.match;
import org.apache.wicket.markup.html.form.Button;
import org.apache.wicket.markup.html.form.CheckBox;
import org.apache.wicket.markup.html.form.Form;
import org.apache.wicket.markup.html.form.TextField;
import org.apache.wicket.markup.html.panel.Panel;
import org.apache.wicket.model.IModel;
import org.apache.wicket.model.Model;
import org.apache.wicket.model.PropertyModel;
import org.apache.wicket.spring.injection.annot.SpringBean;
import se.su.dsv.scipro.components.InverseBooleanModel;
import se.su.dsv.scipro.components.KeywordTypeSelector;
import se.su.dsv.scipro.match.dao.interfaces.KeywordDao;
import se.su.dsv.scipro.match.dataobject.Keyword;
import se.su.dsv.scipro.match.dataobject.KeywordType;
public class CreateKeywordPanel extends Panel {
private static final long serialVersionUID = 1L;
@SpringBean
private KeywordDao keywordDao;
public CreateKeywordPanel(String str, KeywordType keywordType) {
super(str);
Keyword keyword = new Keyword();
keyword.setType(keywordType);
add(new EditKeywordForm("editKeywordForm", new Model<Keyword>(keyword)));
}
private class EditKeywordForm extends Form<Keyword>{
private static final long serialVersionUID = 1L;
private KeywordTypeSelector keywordTypeSelector;
private TextField<String> name;
private CheckBox activeCheckbox;
public EditKeywordForm(String id, final IModel<Keyword> model) {
super(id, model);
this.setOutputMarkupId(true);
name = new TextField<String>("name",
new PropertyModel<String>(model, "keyword"));
keywordTypeSelector = new KeywordTypeSelector("keywordTypeSelector",
new PropertyModel<KeywordType>(model, "type"));
activeCheckbox = new CheckBox("activeCheckbox",
new InverseBooleanModel(new PropertyModel<Boolean>(model, "deleted")));
activeCheckbox.setOutputMarkupId(true);
Button saveButton = new Button("saveButton");
add(saveButton);
add(name);
add(keywordTypeSelector);
add(activeCheckbox);
}
@Override
protected void onSubmit() {
IModel<Keyword> model = getModel();
model.setObject(keywordDao.save(model.getObject()));
super.onSubmit();
}
}
}

@ -3,11 +3,12 @@
xmlns:wicket="http://wicket.apache.org/dtds.data/wicket-xhtml1.4-strict.dtd">
<body>
<wicket:panel>
<div wicket:id="feedbackPanel"></div>
<form wicket:id="editKeywordForm">
<div><b>Name: </b><input type="text" wicket:id="name"></input></div>
<div><b>Type: </b><select wicket:id="keywordTypeSelector"></select></div>
<div><b>Active: </b><input type="checkbox" wicket:id="activeCheckbox" /></div>
<div><input wicket:id="saveButton" type="submit" value="Save" /></div>
<div><input wicket:id="saveButton" type="button" value="Save" /></div>
</form>
</wicket:panel>
</body>

@ -1,14 +1,18 @@
package se.su.dsv.scipro.admin.panels.match;
import org.apache.wicket.markup.html.form.Button;
import org.apache.wicket.Session;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.ajax.markup.html.form.AjaxSubmitLink;
import org.apache.wicket.markup.html.form.CheckBox;
import org.apache.wicket.markup.html.form.Form;
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.IModel;
import org.apache.wicket.model.PropertyModel;
import org.apache.wicket.spring.injection.annot.SpringBean;
import se.su.dsv.scipro.admin.pages.match.AdminKeywordPage;
import se.su.dsv.scipro.components.InverseBooleanModel;
import se.su.dsv.scipro.components.KeywordTypeSelector;
import se.su.dsv.scipro.match.dao.interfaces.KeywordDao;
@ -20,9 +24,15 @@ public class EditKeywordPanel extends Panel {
@SpringBean
private KeywordDao keywordDao;
private FeedbackPanel feedbackPanel;
public EditKeywordPanel(String str, IModel<Keyword> model) {
public EditKeywordPanel(String str, IModel<Keyword> model, KeywordType kType) {
super(str, model);
feedbackPanel=new FeedbackPanel("feedbackPanel");
feedbackPanel.setOutputMarkupId(true);
add(feedbackPanel);
if(kType!=null)
model.getObject().setType(kType);
add(new EditKeywordForm("editKeywordForm", model));
}
@ -49,20 +59,29 @@ public class EditKeywordPanel extends Panel {
activeCheckbox.setOutputMarkupId(true);
Button saveButton = new Button("saveButton");
add(saveButton);
add(name);
add(keywordTypeSelector);
add(activeCheckbox);
add(new AjaxSubmitLink("saveButton") {
private static final long serialVersionUID = 3789769278943894052L;
@Override
protected void onSubmit(AjaxRequestTarget target, Form<?> form) {
final Keyword keyword = ((Keyword)form.getModelObject());
if(keyword.getKeyword()==null){
error("You need to specify a name for your keyword");
target.addComponent(feedbackPanel);
return;
} else {
keywordDao.save(keyword);
Session.get().info("Keyword '"+keyword.getKeyword()+"' created/updated");
setResponsePage(AdminKeywordPage.class);
}
}
});
}
@Override
protected void onSubmit() {
IModel<Keyword> model = getModel();
model.setObject(keywordDao.save(model.getObject()));
super.onSubmit();
}
}
}

@ -47,7 +47,7 @@ public abstract class KeywordDetailsPanel extends Panel {
container.add(totalNumberLabel);
container.add(emptyLabel);
AjaxPagingNavigator navigator = new AjaxPagingNavigator("navigator", listView);
navigator.setVisible(!listOfSupervisors.isEmpty());
navigator.setVisible(listView.getPageCount() > 1);
add(navigator);
add(container);

@ -34,7 +34,7 @@ public class ManageKeywordPanel extends Panel {
private final WebMarkupContainer tableContainer;
private final DataView<Keyword> keywordsDataView;
public ManageKeywordPanel(String str, final KeywordType keywordType) {
public ManageKeywordPanel(String str, final KeywordType keywordType, final boolean isEditable) {
super(str);
AjaxLink<Void> createLink = new AjaxLink<Void>("createLink"){
@ -42,13 +42,14 @@ public class ManageKeywordPanel extends Panel {
@Override
public void onClick(AjaxRequestTarget target) {
dialog.replace(new CreateKeywordPanel("dialogContent", keywordType));
dialog.replace(new EditKeywordPanel("dialogContent", new Model<Keyword>(new Keyword()),keywordType));
target.addComponent(dialog);
dialog.setTitle("Add Keyword...");
dialog.setTitle("Add new keyword");
dialog.open(target);
}
};
createLink.add(new ImageObject("addIcon", ImageObject.SIXTEEN + ImageObject.ADD));
createLink.setVisible(isEditable);
dialog = new Dialog("editDialog");
dialog.setModal(true);
@ -87,13 +88,13 @@ public class ManageKeywordPanel extends Panel {
target.addComponent(dialog);
dialog.setWidth(400);
dialog.setHeight(225);
dialog.setTitle("Edit keyword...");
dialog.replace(new EditKeywordPanel("dialogContent", new Model<Keyword>(item.getModelObject())));
dialog.setTitle("Edit keyword: " + item.getModelObject().getKeyword());
dialog.replace(new EditKeywordPanel("dialogContent", new Model<Keyword>(item.getModelObject()),null));
dialog.open(target);
}
};
editLink.add(editIcon);
editLink.setVisible(isEditable);
LazyDeleteAjaxLink activeLink = new LazyDeleteAjaxLink("activeLink",
new PropertyModel<Boolean>(item.getModel(), "deleted")) {
private static final long serialVersionUID = 1L;

@ -3,7 +3,7 @@
xmlns:wicket="http://wicket.apache.org/dtds.data/wicket-xhtml1.4-strict.dtd">
<body>
<wicket:panel>
<wicket:enclosure child="manual">
<wicket:enclosure child="watson">
<!--<div wicket:id="manual" class="append-bottom"></div>-->
<div wicket:id="watson"></div>
</wicket:enclosure>

@ -1,5 +1,6 @@
package se.su.dsv.scipro.admin.panels.match;
import org.apache.wicket.Component;
import org.apache.wicket.markup.html.panel.Panel;
import org.apache.wicket.model.IModel;
import org.apache.wicket.model.PropertyModel;
@ -13,10 +14,10 @@ public class ManualWatsonPanel extends Panel {
private static final long serialVersionUID = 1L;
public ManualWatsonPanel(String id, IModel<ProjectIdea> model) {
public ManualWatsonPanel(String id, IModel<ProjectIdea> model, final Component feedBack) {
super(id);
if (model.getObject()!=null){
add(new ManualMatchPanel("manual", new PropertyModel<Match>(model, "match"), true));
//add(new ManualMatchPanel("manual", new PropertyModel<Match>(model, "match"), feedBack, Match.Status.CONFIRMED));
add(new WatsonInfoPanel("watson", model.getObject().getMatch().getProjectIdea()));
}
}

@ -0,0 +1,31 @@
<!DOCTYPE html>
<html
xmlns:wicket="http://wicket.apache.org/dtds.data/wicket-xhtml1.4-strict.dtd">
<body>
<wicket:panel>
<div>
<table class="rounded-corner">
<thead>
<tr>
<th class="rounded-left-top">Date</th><th>Status</th><th>Supervisor</th><th>Rejected by</th><th class="rounded-right-top">Comment by supervisor</th>
</tr>
</thead>
<tbody>
<tr wicket:id="historyList">
<td wicket:id="date"></td>
<td wicket:id="status"></td>
<td wicket:id="supervisor"></td>
<td wicket:id="rejectedBy"></td>
<td wicket:id="comment"></td>
</tr>
</tbody>
<tfoot>
<tr>
<td colspan="5" class="rounded-foot">&nbsp;</td>
</tr>
</tfoot>
</table>
</div>
</wicket:panel>
</body>
</html>

@ -0,0 +1,50 @@
package se.su.dsv.scipro.admin.panels.match;
import java.util.List;
import org.apache.wicket.Component;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.list.ListItem;
import org.apache.wicket.markup.html.list.ListView;
import org.apache.wicket.markup.html.panel.Panel;
import org.apache.wicket.model.IModel;
import org.apache.wicket.spring.injection.annot.SpringBean;
import se.su.dsv.scipro.match.dao.interfaces.MatchDao;
import se.su.dsv.scipro.match.dataobject.Match;
import se.su.dsv.scipro.match.dataobject.ProjectIdea;
public class MatchHistoryPanel extends Panel {
@SpringBean
private MatchDao matchDao;
private static final long serialVersionUID = 1L;
public MatchHistoryPanel(String id, IModel<ProjectIdea> model, final Component feedBack) {
super(id);
if (model.getObject()!=null){
ProjectIdea pi = model.getObject();
List<Match> matchObjects = matchDao.getMatchHistory(pi);
ListView<Match> historyList = new ListView<Match>("historyList", matchObjects) {
private static final long serialVersionUID = 5246932667444626581L;
@Override
protected void populateItem(ListItem<Match> item) {
Match match = item.getModelObject();
String supervisorName = match.getSupervisor() != null ? match.getSupervisor().getNameAsString() : "";
String rejectedByName = match.getRejectedBy() != null ? match.getRejectedBy().getFullName() : "";
String comment = match.getCommentForAdmin() != null ? match.getCommentForAdmin() : "";
item.add(new Label("date", match.getDateCreated().toString()));
item.add(new Label("status", match.getStatus().toString()));
item.add(new Label("supervisor", supervisorName));
item.add(new Label("rejectedBy", rejectedByName));
item.add(new Label("comment", comment));
add(item);
}
};
add(historyList);
}
}
}

@ -7,11 +7,11 @@
<form wicket:id="form">
<div class="prepend-top">If you want to match (CONFIRM) this
idea to a supervisor or reviewer manually, you can do so.</div>
<div wicket:id="manualMatchPanel"></div>
<div class="prepend-top">If you want to suggest (PUBLISH) this
idea to a supervisor or reviewer manually, you can do so.</div>
<div wicket:id="manualSetReviewerPanel"></div>
idea to a supervisor manually, you can do so.</div>
<div><span wicket:id="manualMatchPanel"></span></div>
<div class="prepend-top">If you want to suggest (PUBLISH) this
idea to a supervisor manually, you can do so.</div>
<div><span wicket:id="manualSuggestionPanel"></span></div>
<div class="prepend-top">If this project idea is poorly
written, it should be refused, which means it will be sent back to the
authors for rewriting.</div>
@ -23,6 +23,9 @@
<div class="prepend-top">If this project idea will not be
carried out for whatever reason, it can be inactivated.</div>
<button wicket:id="cancelButton">Inactivate the project idea</button>
<div class="prepend-top">If you want to suggest a reviewer (NOT supervisor) for this
idea manually, you can do so.</div>
<div> <span wicket:id="manualSetReviewerPanel"></span></div>
</form>
</wicket:panel>
</body>

@ -1,6 +1,9 @@
package se.su.dsv.scipro.admin.panels.match;
import org.apache.wicket.markup.html.form.Button;
import org.apache.wicket.Component;
import org.apache.wicket.Session;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.ajax.markup.html.form.AjaxSubmitLink;
import org.apache.wicket.markup.html.form.Form;
import org.apache.wicket.markup.html.panel.Panel;
import org.apache.wicket.model.IModel;
@ -9,64 +12,78 @@ import org.apache.wicket.model.PropertyModel;
import org.apache.wicket.spring.injection.annot.SpringBean;
import se.su.dsv.scipro.SciProSession;
import se.su.dsv.scipro.admin.pages.match.AdminManageProjectIdeaPage;
import se.su.dsv.scipro.admin.panels.ManualMatchPanel;
import se.su.dsv.scipro.admin.panels.ManualSetReviewerPanel;
import se.su.dsv.scipro.match.dao.interfaces.MatchDao;
import se.su.dsv.scipro.match.dao.interfaces.ProjectIdeaDao;
import se.su.dsv.scipro.match.dataobject.Match;
import se.su.dsv.scipro.match.dataobject.Match.Status;
import se.su.dsv.scipro.match.dataobject.ProjectIdea;
public class ProjectIdeaActionPanel extends Panel {
private static final long serialVersionUID = 1L;
private static final long serialVersionUID = -6518785244887938888L;
@SpringBean
private MatchDao matchDao;
private ManualMatchPanel manualMatchPanel;
private ManualSetReviewerPanel manualSetReviewerPanel;
public ProjectIdeaActionPanel(String id, final IModel<ProjectIdea> projectIdeaModel) {
super(id);
final IModel<Match> matchModel = new PropertyModel<Match>(projectIdeaModel, "match");
add(new ProjectIdeaRemoveAuthorPanel("removeAuthorPanel", new Model(matchModel.getObject().getProjectIdea())).setVisible(matchModel.getObject().getProjectIdea().getAuthors().size()>1));
Form<Match> form = new Form<Match>("form", matchModel);
form.add(manualMatchPanel = new ManualMatchPanel("manualMatchPanel", matchModel, true));
form.add(manualSetReviewerPanel = new ManualSetReviewerPanel("manualSetReviewerPanel", projectIdeaModel));
public ProjectIdeaActionPanel(String id, final IModel<ProjectIdea> projectIdeaModel, final Component feedbackPanel) {
super(id);
final IModel<Match> matchModel = new PropertyModel<Match>(projectIdeaModel, "match");
//noinspection unchecked
add(new ProjectIdeaRemoveAuthorPanel("removeAuthorPanel", new Model(matchModel.getObject().getProjectIdea())).setVisible(matchModel.getObject().getProjectIdea().getAuthors().size()>1));
Form<Match> form = new Form<Match>("form", matchModel);
form.add(new Button("sendBackButton") {
private static final long serialVersionUID = 1L;
form.add(new ManualMatchPanel("manualMatchPanel", matchModel, feedbackPanel, Match.Status.CONFIRMED));
form.add(new ManualMatchPanel("manualSuggestionPanel", matchModel, feedbackPanel, Match.Status.PUBLISHED));
form.add(new ManualSetReviewerPanel("manualSetReviewerPanel", projectIdeaModel, feedbackPanel));
@Override
public void onSubmit() {
matchDao.changeStatus(SciProSession.get().getUser(), matchModel.getObject(), Status.REFUSED);
}
});
form.add(new Button("rematchButton") {
/**
*
*/
private static final long serialVersionUID = 1L;
form.add(new AjaxSubmitLink("sendBackButton") {
private static final long serialVersionUID = -1152454202773560729L;
@Override
public void onSubmit() {
matchDao.changeStatus(SciProSession.get().getUser(), matchModel.getObject(), Status.UNMATCHED);
}
});
form.add(new Button("cancelButton") {
/**
*
*/
private static final long serialVersionUID = 1L;
@Override
protected void onSubmit(AjaxRequestTarget target, Form<?> f) {
changeStatusAndQuit(target, Match.Status.REFUSED, matchModel, feedbackPanel);
}
});
@Override
public void onSubmit() {
matchDao.changeStatus(SciProSession.get().getUser(), matchModel.getObject(), Status.INACTIVE);
}
});
add(form);
}
}
form.add(new AjaxSubmitLink("rematchButton") {
private static final long serialVersionUID = 2586530227803716442L;
@Override
protected void onSubmit(AjaxRequestTarget target, Form<?> f) {
changeStatusAndQuit(target, Match.Status.UNMATCHED, matchModel, feedbackPanel);
}
});
form.add(new AjaxSubmitLink("cancelButton") {
private static final long serialVersionUID = -4912497022534275919L;
@Override
protected void onSubmit(AjaxRequestTarget target, Form<?> f) {
changeStatusAndQuit(target, Match.Status.INACTIVE, matchModel, feedbackPanel);
}
});
add(form);
}
private String createInfoMessage(final String projectIdeaTitle, final Match.Status status) {
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append("The status was set to ");
stringBuilder.append(status);
stringBuilder.append(" for the project idea ");
stringBuilder.append(projectIdeaTitle);
stringBuilder.append(".");
return stringBuilder.toString();
}
private void changeStatusAndQuit(AjaxRequestTarget target, Match.Status status, IModel<Match> matchModel, Component feedbackPanel) {
matchDao.changeStatus(SciProSession.get().getUser(), matchModel.getObject(), status);
Session.get().info(createInfoMessage(matchModel.getObject().getProjectIdea().getTitle(), status));
setResponsePage(AdminManageProjectIdeaPage.class);
target.addComponent(feedbackPanel);
}
}

@ -0,0 +1,51 @@
<!DOCTYPE html>
<html
xmlns:wicket="http://wicket.apache.org/dtds.data/wicket-xhtml1.4-strict.dtd">
<body>
<wicket:panel>
<div class="append-bottom prepend-top"><b><span wicket:id="supervisorInfo"></span></b></div>
<table wicket:id="areaTable" class="rounded-corner">
<thead>
<tr>
<th class="rounded-left-top">Research areas </th>
<th class="rounded-right-top"><span class="right" wicket:id="areaTableTotal"></span></th>
</tr>
</thead>
<tbody>
<tr wicket:id="areaTableList">
<td colspan="2" wicket:id="areaTableKeyword"></td>
</tr>
<tr><td colspan="2" wicket:id="areaTableLabel"></td></tr>
</tbody>
<tfoot>
<tr>
<td colspan="2" class="rounded-foot">&nbsp;</td>
</tr>
</tfoot>
</table>
<div class="append-bottom" wicket:id="areaTableNavigator"></div>
<table wicket:id="regularTable" class="rounded-corner">
<thead>
<tr>
<th class="rounded-left-top">Regular keywords </th>
<th class="rounded-right-top"><span class="right" wicket:id="regularTableTotal"></span></th>
</tr>
</thead>
<tbody>
<tr wicket:id="regularTableList">
<td colspan="2" wicket:id="regularTableKeyword"></td>
</tr>
<tr><td colspan="2" wicket:id="regularTableLabel"></td></tr>
</tbody>
<tfoot>
<tr>
<td colspan="2" class="rounded-foot">&nbsp;</td>
</tr>
</tfoot>
</table>
<div class="append-bottom" wicket:id="regularTableNavigator"></div>
<button wicket:id="closeButton">Close</button>
</wicket:panel>
</body>
</html>

@ -0,0 +1,74 @@
package se.su.dsv.scipro.admin.panels.match;
import java.util.ArrayList;
import java.util.List;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.ajax.markup.html.AjaxLink;
import org.apache.wicket.ajax.markup.html.navigation.paging.AjaxPagingNavigator;
import org.apache.wicket.markup.html.WebMarkupContainer;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.list.ListItem;
import org.apache.wicket.markup.html.list.PageableListView;
import org.apache.wicket.markup.html.panel.Panel;
import se.su.dsv.scipro.data.dataobjects.Employee;
import se.su.dsv.scipro.match.dao.interfaces.KeywordTypeDao;
import se.su.dsv.scipro.match.dataobject.Keyword;
public abstract class SupervisorKeywordDetailsPanel extends Panel {
private static final long serialVersionUID = 1L;
public SupervisorKeywordDetailsPanel(String str, Employee emp) {
super(str);
List<Keyword> areaKeywords = new ArrayList<Keyword>(emp.getKeywords().getFiltered(KeywordTypeDao.TYPE.RESEARCH_AREA.toDbName()));
List<Keyword> regularKeywords = new ArrayList<Keyword>(emp.getKeywords().getFiltered(KeywordTypeDao.TYPE.REGULAR.toDbName()));
add(new Label("supervisorInfo", "Supervisor: "+ emp.getNameAsString()));
setUpTable(areaKeywords, "areaTable", "research areas");
setUpTable(regularKeywords, "regularTable", "regular keywords");
add(new AjaxLink<Void>("closeButton") {
private static final long serialVersionUID = -8473625184915176333L;
@Override
public void onClick(AjaxRequestTarget target) {
onCloseButton(target);
}
});
}
private void setUpTable(List<Keyword> keywords, final String markupId, final String title) {
Label totalLabel = new Label(markupId + "Total", "Total: "+keywords.size());
Label emptyLabel = new Label(markupId + "Label","No "+title+" attached to selected supervisor");
emptyLabel.setVisible(keywords.isEmpty());
WebMarkupContainer container = new WebMarkupContainer(markupId);
container.setOutputMarkupId(true);
PageableListView<Keyword> listView = new PageableListView<Keyword>(markupId+"List", keywords, 10) {
private static final long serialVersionUID = 2191181676642843499L;
@Override
protected void populateItem(ListItem<Keyword> item) {
Keyword key = item.getModelObject();
item.add(new Label(markupId+"Keyword", key.getKeyword()));
}
};
AjaxPagingNavigator navigator = new AjaxPagingNavigator(markupId+"Navigator", listView);
navigator.setVisible(listView.getPageCount() > 1);
container.add(listView);
container.add(totalLabel);
container.add(emptyLabel);
add(navigator);
add(container);
}
public abstract void onCloseButton(AjaxRequestTarget target);
}

@ -1,55 +1,55 @@
package se.su.dsv.scipro.basepages;
import org.apache.wicket.PageParameters;
import org.apache.wicket.markup.html.image.Image;
import org.apache.wicket.resource.ContextRelativeResource;
import se.su.dsv.scipro.icons.ImageObject;
public class DemoPage extends PublicPage {
public DemoPage(final PageParameters pp){
super(pp);
add(new ImageObject("delete_24", ImageObject.TWENTYFOUR + ImageObject.DELETE));
add(new ImageObject("about", ImageObject.SIXTEEN + ImageObject.ABOUT));
add(new ImageObject("add", ImageObject.SIXTEEN + ImageObject.ADD));
add(new ImageObject("calendar", ImageObject.SIXTEEN + ImageObject.CALENDAR));
add(new ImageObject("check", ImageObject.SIXTEEN + ImageObject.CHECK));
add(new ImageObject("clipboard", ImageObject.SIXTEEN + ImageObject.CLIPBOARD));
add(new ImageObject("clock", ImageObject.SIXTEEN + ImageObject.CLOCK));
add(new ImageObject("copy", ImageObject.SIXTEEN + ImageObject.COPY));
add(new ImageObject("date_time", ImageObject.SIXTEEN + ImageObject.DATE_TIME));
add(new ImageObject("delete_16", ImageObject.SIXTEEN + ImageObject.DELETE));
add(new ImageObject("document", ImageObject.SIXTEEN + ImageObject.DOCUMENT));
add(new ImageObject("document_add", ImageObject.SIXTEEN + ImageObject.DOCUMENT_ADD));
add(new ImageObject("document_down", ImageObject.SIXTEEN + ImageObject.DOCUMENT_DOWN));
add(new ImageObject("document_view", ImageObject.SIXTEEN + ImageObject.DOCUMENT_VIEW));
add(new ImageObject("edit", ImageObject.SIXTEEN + ImageObject.EDIT));
add(new ImageObject("error", ImageObject.SIXTEEN + ImageObject.ERROR));
add(new ImageObject("extend", ImageObject.SIXTEEN + ImageObject.EXTEND));
add(new ImageObject("extend_reverse", ImageObject.SIXTEEN + ImageObject.EXTEND_REVERSE));
add(new ImageObject("flag_sweden", ImageObject.SIXTEEN + ImageObject.FLAG_SWEDEN));
add(new ImageObject("flag_gb", ImageObject.SIXTEEN + ImageObject.FLAG_GB));
add(new ImageObject("folder", ImageObject.SIXTEEN + ImageObject.FOLDER));
add(new ImageObject("folder_document", ImageObject.SIXTEEN + ImageObject.FOLDER_DOCUMENT));
add(new ImageObject("folder_up", ImageObject.SIXTEEN + ImageObject.FOLDER_UP));
add(new ImageObject("gear", ImageObject.SIXTEEN + ImageObject.GEAR));
add(new ImageObject("help", ImageObject.SIXTEEN + ImageObject.HELP));
add(new ImageObject("star_grey", ImageObject.SIXTEEN + ImageObject.STAR_GREY));
add(new ImageObject("star_red", ImageObject.SIXTEEN + ImageObject.STAR_RED));
add(new ImageObject("user", ImageObject.SIXTEEN + ImageObject.USER));
add(new ImageObject("click", ImageObject.PATH + ImageObject.LIGHT_CLICK));
add(new ImageObject("green_border", ImageObject.PATH + ImageObject.LIGHT_GREEN_BORDER));
add(new ImageObject("green", ImageObject.PATH + ImageObject.LIGHT_GREEN));
add(new ImageObject("yellow_border", ImageObject.PATH + ImageObject.LIGHT_YELLOW_BORDER));
add(new ImageObject("yellow", ImageObject.PATH + ImageObject.LIGHT_YELLOW));
add(new ImageObject("red_border", ImageObject.PATH + ImageObject.LIGHT_RED_BORDER));
add(new ImageObject("red", ImageObject.PATH + ImageObject.LIGHT_RED));
add(new ImageObject("grey_border", ImageObject.PATH + ImageObject.LIGHT_GREY_BORDER));
add(new ImageObject("grey", ImageObject.PATH + ImageObject.LIGHT_GREY));
}
}
package se.su.dsv.scipro.basepages;
import org.apache.wicket.PageParameters;
import org.apache.wicket.markup.html.image.Image;
import org.apache.wicket.resource.ContextRelativeResource;
import se.su.dsv.scipro.icons.ImageObject;
public class DemoPage extends PublicPage {
public DemoPage(final PageParameters pp){
super(pp);
add(new ImageObject("delete_24", ImageObject.SIXTEEN + ImageObject.DELETE));
add(new ImageObject("about", ImageObject.SIXTEEN + ImageObject.ABOUT));
add(new ImageObject("add", ImageObject.SIXTEEN + ImageObject.ADD));
add(new ImageObject("calendar", ImageObject.SIXTEEN + ImageObject.CALENDAR));
add(new ImageObject("check", ImageObject.SIXTEEN + ImageObject.CHECK));
add(new ImageObject("clipboard", ImageObject.SIXTEEN + ImageObject.CLIPBOARD));
add(new ImageObject("clock", ImageObject.SIXTEEN + ImageObject.CLOCK));
add(new ImageObject("copy", ImageObject.SIXTEEN + ImageObject.COPY));
add(new ImageObject("date_time", ImageObject.SIXTEEN + ImageObject.DATE_TIME));
add(new ImageObject("delete_16", ImageObject.SIXTEEN + ImageObject.DELETE));
add(new ImageObject("document", ImageObject.SIXTEEN + ImageObject.DOCUMENT));
add(new ImageObject("document_add", ImageObject.SIXTEEN + ImageObject.DOCUMENT_ADD));
add(new ImageObject("document_down", ImageObject.SIXTEEN + ImageObject.DOCUMENT_DOWN));
add(new ImageObject("document_view", ImageObject.SIXTEEN + ImageObject.DOCUMENT_VIEW));
add(new ImageObject("edit", ImageObject.SIXTEEN + ImageObject.EDIT));
add(new ImageObject("error", ImageObject.SIXTEEN + ImageObject.ERROR));
add(new ImageObject("extend", ImageObject.SIXTEEN + ImageObject.EXTEND));
add(new ImageObject("extend_reverse", ImageObject.SIXTEEN + ImageObject.EXTEND_REVERSE));
add(new ImageObject("flag_sweden", ImageObject.SIXTEEN + ImageObject.FLAG_SWEDEN));
add(new ImageObject("flag_gb", ImageObject.SIXTEEN + ImageObject.FLAG_GB));
add(new ImageObject("folder", ImageObject.SIXTEEN + ImageObject.FOLDER));
add(new ImageObject("folder_document", ImageObject.SIXTEEN + ImageObject.FOLDER_DOCUMENT));
add(new ImageObject("folder_up", ImageObject.SIXTEEN + ImageObject.FOLDER_UP));
add(new ImageObject("gear", ImageObject.SIXTEEN + ImageObject.GEAR));
add(new ImageObject("help", ImageObject.SIXTEEN + ImageObject.HELP));
add(new ImageObject("star_grey", ImageObject.SIXTEEN + ImageObject.STAR_GREY));
add(new ImageObject("star_red", ImageObject.SIXTEEN + ImageObject.STAR_RED));
add(new ImageObject("user", ImageObject.SIXTEEN + ImageObject.USER));
add(new ImageObject("click", ImageObject.PATH + ImageObject.LIGHT_CLICK));
add(new ImageObject("green_border", ImageObject.PATH + ImageObject.LIGHT_GREEN_BORDER));
add(new ImageObject("green", ImageObject.PATH + ImageObject.LIGHT_GREEN));
add(new ImageObject("yellow_border", ImageObject.PATH + ImageObject.LIGHT_YELLOW_BORDER));
add(new ImageObject("yellow", ImageObject.PATH + ImageObject.LIGHT_YELLOW));
add(new ImageObject("red_border", ImageObject.PATH + ImageObject.LIGHT_RED_BORDER));
add(new ImageObject("red", ImageObject.PATH + ImageObject.LIGHT_RED));
add(new ImageObject("grey_border", ImageObject.PATH + ImageObject.LIGHT_GREY_BORDER));
add(new ImageObject("grey", ImageObject.PATH + ImageObject.LIGHT_GREY));
}
}

@ -246,7 +246,7 @@ public class FunctionalListCheckListTemplatePanel extends Panel{
*/
};
item.add(deleteLink);
deleteLink.add(new ImageObject("deleteIcon", ImageObject.TWENTYFOUR + ImageObject.DELETE));
deleteLink.add(new ImageObject("deleteIcon", ImageObject.SIXTEEN + ImageObject.DELETE));
deleteLink.add(new JavascriptEventConfirmation("onclick", "Are you sure you want to remove this template?"));
item.setOutputMarkupId(true);
}

@ -198,13 +198,13 @@ public class ListCheckListPanel extends Panel {
if (!noanswer){
if (red){
item.replace(new ImageObject("image", ImageObject.TWENTYFOUR + ImageObject.LIGHT_RED));
item.replace(new ImageObject("image", ImageObject.SIXTEEN + ImageObject.LIGHT_RED));
}
else if (!red && yellow){
item.replace(new ImageObject("image", ImageObject.TWENTYFOUR + ImageObject.LIGHT_YELLOW));
item.replace(new ImageObject("image", ImageObject.SIXTEEN + ImageObject.LIGHT_YELLOW));
}
else if (!red && !yellow && green){
item.replace(new ImageObject("image", ImageObject.TWENTYFOUR + ImageObject.LIGHT_GREEN));
item.replace(new ImageObject("image", ImageObject.SIXTEEN + ImageObject.LIGHT_GREEN));
}
}

@ -154,8 +154,8 @@ public class CommentThreadPanel extends Panel {
item.add(commentDeleteLink);
// item.add(commentEditLink);
commentDeleteLink.add(new ImageObject("deleteIcon", ImageObject.TWENTYFOUR + ImageObject.DELETE));
commentEditLink.add(new ImageObject("editIcon", ImageObject.TWENTYFOUR + ImageObject.EDIT));
commentDeleteLink.add(new ImageObject("deleteIcon", ImageObject.SIXTEEN + ImageObject.DELETE));
commentEditLink.add(new ImageObject("editIcon", ImageObject.SIXTEEN + ImageObject.EDIT));
};
};

@ -0,0 +1,29 @@
package se.su.dsv.scipro.components;
import java.util.Arrays;
import java.util.List;
import org.apache.wicket.markup.html.form.DropDownChoice;
import org.apache.wicket.model.Model;
public class ItemsPerPageChoice extends DropDownChoice<Integer> {
private static final long serialVersionUID = -6679286933462794113L;
public ItemsPerPageChoice(String id) {
super(id);
initChoices();
setModel(Model.of(10));
}
private void initChoices() {
List<Integer> choices = Arrays.asList(new Integer[]{10, 25, 50, 100});
setChoices(choices);
setNullValid(false);
setRequired(true);
}
}

@ -1,172 +1,172 @@
package se.su.dsv.scipro.components.autocomplete;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.SortedSet;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.ajax.form.AjaxFormComponentUpdatingBehavior;
import org.apache.wicket.behavior.AttributeAppender;
import org.apache.wicket.extensions.ajax.markup.html.IndicatingAjaxLink;
import org.apache.wicket.markup.html.WebMarkupContainer;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.form.DropDownChoice;
import org.apache.wicket.markup.html.form.Form;
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.IModel;
import org.apache.wicket.model.Model;
import org.apache.wicket.model.PropertyModel;
import org.apache.wicket.spring.injection.annot.SpringBean;
import se.su.dsv.scipro.admin.pages.ProjectContainer;
import se.su.dsv.scipro.data.dao.interfaces.ProjectDao;
import se.su.dsv.scipro.data.dataobjects.Project;
import se.su.dsv.scipro.data.dataobjects.ProjectFollower;
import se.su.dsv.scipro.data.dataobjects.ProjectTeamMember;
import se.su.dsv.scipro.data.dataobjects.User;
import se.su.dsv.scipro.data.enums.ProjectTeamMemberRoles;
import se.su.dsv.scipro.icons.ImageObject;
import se.su.dsv.scipro.util.JavascriptEventConfirmation;
public class TeamMemberMultiObjectAutoCompleteField<O extends ProjectTeamMember/* object */,I /* its id */ extends Serializable> extends MultiObjectAutoCompleteField<O,I>{
private static final long serialVersionUID = 1L;
@SpringBean
ProjectDao projectDao;
private WebMarkupContainer noSelectionsContainer;
private IModel<ProjectContainer> projectModel;
TeamMemberMultiObjectAutoCompleteField(String pId, IModel<List<O>> pModel,
MultiObjectAutoCompleteBuilder<O,I> pBuilder, IModel<ProjectContainer> projectModel) {
super(pId, pModel, pBuilder);
this.projectModel = projectModel;
}
@Override
protected void addSelectedListView(){
selectedListView = new ListView<O>("listItem", new PropertyModel<List<O>>(this, "selectedObjects")){
private static final long serialVersionUID = 1L;
@Override
protected void populateItem(ListItem<O> item) {
final O object = item.getModelObject();
Label resultText = new Label("listItemText", autoCompleteRenderer.getTextValue(object));
for(String cssClass : resultListItemCssClasses){
AttributeAppender attrApp = new AttributeAppender("class", true, new Model<String>(cssClass), " ");
resultText.add(attrApp);
}
item.add(resultText);
ProjectFollower modelObject = null;
for(ProjectFollower tmp : projectModel.getObject().getProjectFollowers()){
if(item.getModelObject().equals( tmp.getFollower() )) {
modelObject = tmp;
}
}
if(modelObject == null){
modelObject = new ProjectFollower();
modelObject.setFollower(object);
modelObject.setProject(projectModel.getObject().getOriginalProject());
}
final CompoundPropertyModel<ProjectFollower> model = new CompoundPropertyModel<ProjectFollower>(modelObject);
ProjectRoleForm<ProjectFollower> form = new ProjectRoleForm<ProjectFollower>("projectRoleSelectionForm", model);
item.add(form);
IndicatingAjaxLink<Void> deleteLink = new IndicatingAjaxLink<Void>("deleteLink"){
private static final long serialVersionUID = 1L;
public void onClick(AjaxRequestTarget target) {
selectedObjects.remove(object);
target.addComponent(TeamMemberMultiObjectAutoCompleteField.this);
// Project x = projectModel.getObject().getOriginalProject();
// User u = object.getUser();
// Iterator<ProjectFollower> itr = x.getProjectFollowers().iterator();
// while (itr.hasNext()){
// if (itr.next().getFollower().getUser().equals(u)){
// x.getProjectFollowers().remove(itr.next());
// }
// }
// projectDao.save(x);
// for (ProjectFollower pf : x.getProjectFollowers()){
// if (pf.getFollower().getUser().equals(u)){
// x.getProjectFollowers().remove(pf);
// }
// }
// projectDao.save(x);
}
@Override
public boolean isVisible(){
return searchTextField.isEnabled();
}
};
item.add(deleteLink);
deleteLink.add(new ImageObject("deleteIcon", ImageObject.TWENTYFOUR + ImageObject.DELETE));
deleteLink.add(new JavascriptEventConfirmation("onclick", "Are you sure you want to remove this?"));
add(item);
}
};
add(selectedListView);
noSelectionsContainer = new WebMarkupContainer("noSelectionsContainer"){
private static final long serialVersionUID = 1L;
@Override
public boolean isVisible(){
return selectedListView.getModelObject().size() == 0;
}
};
noSelectionsContainer.setOutputMarkupId(true);
add(noSelectionsContainer);
noSelectionsContainer.removeAll();
noSelectionsContainer.add(new Label("noSelections", "No selections"));
}//addSelectedListView
private class ProjectRoleForm<P extends ProjectFollower> extends Form<P>{
private static final long serialVersionUID = 1L;
public ProjectRoleForm(final String id, final IModel<P> model) {
super(id, model);
List<ProjectTeamMemberRoles> choices = new ArrayList<ProjectTeamMemberRoles>();
for(ProjectTeamMemberRoles roleEnum : ProjectTeamMemberRoles.values()){
choices.add(roleEnum);
}
DropDownChoice<ProjectTeamMemberRoles> projectRoleSelection = new DropDownChoice<ProjectTeamMemberRoles>("projectRole", choices);
projectRoleSelection.setRequired(true);
projectRoleSelection.add(new AjaxFormComponentUpdatingBehavior("onchange") {
private static final long serialVersionUID = 1L;
protected void onUpdate(AjaxRequestTarget target) {
projectModel.getObject().getProjectFollowers().add( ProjectRoleForm.this.getModelObject() );
}
});
add(projectRoleSelection);
}
}
}
package se.su.dsv.scipro.components.autocomplete;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.SortedSet;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.ajax.form.AjaxFormComponentUpdatingBehavior;
import org.apache.wicket.behavior.AttributeAppender;
import org.apache.wicket.extensions.ajax.markup.html.IndicatingAjaxLink;
import org.apache.wicket.markup.html.WebMarkupContainer;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.form.DropDownChoice;
import org.apache.wicket.markup.html.form.Form;
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.IModel;
import org.apache.wicket.model.Model;
import org.apache.wicket.model.PropertyModel;
import org.apache.wicket.spring.injection.annot.SpringBean;
import se.su.dsv.scipro.admin.pages.ProjectContainer;
import se.su.dsv.scipro.data.dao.interfaces.ProjectDao;
import se.su.dsv.scipro.data.dataobjects.Project;
import se.su.dsv.scipro.data.dataobjects.ProjectFollower;
import se.su.dsv.scipro.data.dataobjects.ProjectTeamMember;
import se.su.dsv.scipro.data.dataobjects.User;
import se.su.dsv.scipro.data.enums.ProjectTeamMemberRoles;
import se.su.dsv.scipro.icons.ImageObject;
import se.su.dsv.scipro.util.JavascriptEventConfirmation;
public class TeamMemberMultiObjectAutoCompleteField<O extends ProjectTeamMember/* object */,I /* its id */ extends Serializable> extends MultiObjectAutoCompleteField<O,I>{
private static final long serialVersionUID = 1L;
@SpringBean
ProjectDao projectDao;
private WebMarkupContainer noSelectionsContainer;
private IModel<ProjectContainer> projectModel;
TeamMemberMultiObjectAutoCompleteField(String pId, IModel<List<O>> pModel,
MultiObjectAutoCompleteBuilder<O,I> pBuilder, IModel<ProjectContainer> projectModel) {
super(pId, pModel, pBuilder);
this.projectModel = projectModel;
}
@Override
protected void addSelectedListView(){
selectedListView = new ListView<O>("listItem", new PropertyModel<List<O>>(this, "selectedObjects")){
private static final long serialVersionUID = 1L;
@Override
protected void populateItem(ListItem<O> item) {
final O object = item.getModelObject();
Label resultText = new Label("listItemText", autoCompleteRenderer.getTextValue(object));
for(String cssClass : resultListItemCssClasses){
AttributeAppender attrApp = new AttributeAppender("class", true, new Model<String>(cssClass), " ");
resultText.add(attrApp);
}
item.add(resultText);
ProjectFollower modelObject = null;
for(ProjectFollower tmp : projectModel.getObject().getProjectFollowers()){
if(item.getModelObject().equals( tmp.getFollower() )) {
modelObject = tmp;
}
}
if(modelObject == null){
modelObject = new ProjectFollower();
modelObject.setFollower(object);
modelObject.setProject(projectModel.getObject().getOriginalProject());
}
final CompoundPropertyModel<ProjectFollower> model = new CompoundPropertyModel<ProjectFollower>(modelObject);
ProjectRoleForm<ProjectFollower> form = new ProjectRoleForm<ProjectFollower>("projectRoleSelectionForm", model);
item.add(form);
IndicatingAjaxLink<Void> deleteLink = new IndicatingAjaxLink<Void>("deleteLink"){
private static final long serialVersionUID = 1L;
public void onClick(AjaxRequestTarget target) {
selectedObjects.remove(object);
target.addComponent(TeamMemberMultiObjectAutoCompleteField.this);
// Project x = projectModel.getObject().getOriginalProject();
// User u = object.getUser();
// Iterator<ProjectFollower> itr = x.getProjectFollowers().iterator();
// while (itr.hasNext()){
// if (itr.next().getFollower().getUser().equals(u)){
// x.getProjectFollowers().remove(itr.next());
// }
// }
// projectDao.save(x);
// for (ProjectFollower pf : x.getProjectFollowers()){
// if (pf.getFollower().getUser().equals(u)){
// x.getProjectFollowers().remove(pf);
// }
// }
// projectDao.save(x);
}
@Override
public boolean isVisible(){
return searchTextField.isEnabled();
}
};
item.add(deleteLink);
deleteLink.add(new ImageObject("deleteIcon", ImageObject.SIXTEEN + ImageObject.DELETE));
deleteLink.add(new JavascriptEventConfirmation("onclick", "Are you sure you want to remove this?"));
add(item);
}
};
add(selectedListView);
noSelectionsContainer = new WebMarkupContainer("noSelectionsContainer"){
private static final long serialVersionUID = 1L;
@Override
public boolean isVisible(){
return selectedListView.getModelObject().size() == 0;
}
};
noSelectionsContainer.setOutputMarkupId(true);
add(noSelectionsContainer);
noSelectionsContainer.removeAll();
noSelectionsContainer.add(new Label("noSelections", "No selections"));
}//addSelectedListView
private class ProjectRoleForm<P extends ProjectFollower> extends Form<P>{
private static final long serialVersionUID = 1L;
public ProjectRoleForm(final String id, final IModel<P> model) {
super(id, model);
List<ProjectTeamMemberRoles> choices = new ArrayList<ProjectTeamMemberRoles>();
for(ProjectTeamMemberRoles roleEnum : ProjectTeamMemberRoles.values()){
choices.add(roleEnum);
}
DropDownChoice<ProjectTeamMemberRoles> projectRoleSelection = new DropDownChoice<ProjectTeamMemberRoles>("projectRole", choices);
projectRoleSelection.setRequired(true);
projectRoleSelection.add(new AjaxFormComponentUpdatingBehavior("onchange") {
private static final long serialVersionUID = 1L;
protected void onUpdate(AjaxRequestTarget target) {
projectModel.getObject().getProjectFollowers().add( ProjectRoleForm.this.getModelObject() );
}
});
add(projectRoleSelection);
}
}
}

@ -0,0 +1,7 @@
package se.su.dsv.scipro.data.dao.interfaces;
import se.su.dsv.scipro.match.Weights;
public interface WeightsDao extends Dao<Weights> {
public Weights getWeightsInstance();
}

@ -0,0 +1,37 @@
package se.su.dsv.scipro.data.dao.jpa;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;
import se.su.dsv.scipro.data.dao.interfaces.WeightsDao;
import se.su.dsv.scipro.match.Weights;
@Repository("weightsDao")
public class WeightsDaoJPAImp extends AbstractDaoJPAImp<Weights> implements WeightsDao{
private static final long INSTANCE_ID = 1L;
public WeightsDaoJPAImp() {
super(Weights.class);
}
@Override
@Transactional(readOnly = false)
public Weights getWeightsInstance() {
Weights weights = load(INSTANCE_ID);
if (weights == null) {
weights = new Weights(INSTANCE_ID);
save(weights);
}
return weights;
}
@Override
@Transactional(readOnly = false)
public Weights save(Weights object){
if(object.getId() == null)
throw new UnsupportedOperationException("You're not supposed to be creating new instances of this object manually!");
return super.save(object);
}
}

@ -71,8 +71,7 @@ public class Employee extends ProjectTeamMember {
@Override
public String toString() {
return "Supervisor [id=" + getId() + ", user=" + user + ", capabilities="
+ capabilities + ", keywords=" + keywords + "]";
return getNameAsString();
}
@Override

@ -49,7 +49,18 @@ public class GeneralSystemSettings extends DomainObject{
private String turnItInSurname = "Aschan";
@Basic(optional=true)
private int projectPartnerDaysToLive;
private int projectPartnerDaysToLive;
@Basic(optional=false)
private boolean supervisorsCanAcceptDeclinePIs = true;
public boolean getSupervisorsCanAcceptDeclinePIs(){
return supervisorsCanAcceptDeclinePIs;
}
public void setSupervisorsCanAcceptDeclinePIs(boolean supervisorsCanAcceptDeclinePIs){
this.supervisorsCanAcceptDeclinePIs = supervisorsCanAcceptDeclinePIs;
}
@Basic(optional=false)
private boolean finalSeminarThesisMustBeAPDF = false;

@ -1,125 +1,131 @@
package se.su.dsv.scipro.data.dataobjects;
import javax.persistence.DiscriminatorColumn;
import javax.persistence.DiscriminatorType;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Inheritance;
import javax.persistence.InheritanceType;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import javax.persistence.UniqueConstraint;
@Entity
@DiscriminatorColumn(name = "rolename", discriminatorType = DiscriminatorType.STRING, length = 8)
@Table(name="role", uniqueConstraints={@UniqueConstraint(columnNames={"user_id","rolename"}, name = "role_is_unique")})
@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
public abstract class Role extends LazyDeletableDomainObject implements Comparable<Role> {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue
private Long id;
@ManyToOne(optional=false)
protected User user;
/**
* @param id the id to set
*/
public void setId(Long id) {
this.id = id;
}
/**
* @return the id
*/
public Long getId() {
return id;
}
/**
* @param user the user to set
*/
public void setUser(User user) {
this.user = user;
}
/**
* @return the user
*/
public User getUser() {
return user;
}
public String getNameAsString(){
String str = "";
if(user.getFirstName() != null){
str += user.getFirstName();
}
str += " ";
if(user.getLastName() != null){
str += user.getLastName();
}
return str;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((id == null) ? 0 : id.hashCode());
result = prime * result + ((user == null) ? 0 : user.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;
Role other = (Role) obj;
if (id == null) {
if (other.id != null)
return false;
} else if (!id.equals(other.id))
return false;
if (user == null) {
if (other.user != null)
return false;
} else if (!user.equals(other.user))
return false;
return true;
}
@Override
public String toString() {
/*
String tmp = user.getFirstName() + " " + user.getLastName();
if(user.getEmailAddress() != null)
tmp = tmp + " (" + user.getEmailAddress() + ")";
return tmp;
*/
return this.getClass().toString();
}
/**
* Compares the owner (user) of the role (alphabetically on names)
*/
@Override
public int compareTo(Role other){
int comp = user.compareTo(other.user);
if(comp == 0)
comp = id.compareTo(other.id);
return comp;
}
}
package se.su.dsv.scipro.data.dataobjects;
import javax.persistence.DiscriminatorColumn;
import javax.persistence.DiscriminatorType;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Inheritance;
import javax.persistence.InheritanceType;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import javax.persistence.UniqueConstraint;
@Entity
@DiscriminatorColumn(name = "rolename", discriminatorType = DiscriminatorType.STRING, length = 8)
@Table(name="role", uniqueConstraints={@UniqueConstraint(columnNames={"user_id","rolename"}, name = "role_is_unique")})
@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
public abstract class Role extends LazyDeletableDomainObject implements Comparable<Role> {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue
private Long id;
@ManyToOne(optional=false)
protected User user;
/**
* @param id the id to set
*/
public void setId(Long id) {
this.id = id;
}
/**
* @return the id
*/
public Long getId() {
return id;
}
/**
* @param user the user to set
*/
public void setUser(User user) {
this.user = user;
}
/**
* @return the user
*/
public User getUser() {
return user;
}
public String getNameAsString(){
String str = "";
if(user.getFirstName() != null){
str += user.getFirstName();
}
str += " ";
if(user.getLastName() != null){
str += user.getLastName();
}
return str;
}
public String getEmailAsString(){
String str = "";
if(user.getEmailAddress()!=null)
str += user.getEmailAddress();
return str;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((id == null) ? 0 : id.hashCode());
result = prime * result + ((user == null) ? 0 : user.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;
Role other = (Role) obj;
if (id == null) {
if (other.id != null)
return false;
} else if (!id.equals(other.id))
return false;
if (user == null) {
if (other.user != null)
return false;
} else if (!user.equals(other.user))
return false;
return true;
}
@Override
public String toString() {
/*
String tmp = user.getFirstName() + " " + user.getLastName();
if(user.getEmailAddress() != null)
tmp = tmp + " (" + user.getEmailAddress() + ")";
return tmp;
*/
return this.getClass().toString();
}
/**
* Compares the owner (user) of the role (alphabetically on names)
*/
@Override
public int compareTo(Role other){
int comp = user.compareTo(other.user);
if(comp == 0)
comp = id.compareTo(other.id);
return comp;
}
}

@ -57,10 +57,14 @@ public class ProjectFacade {
public void deleteProject(Project project){
project = projectDao.reLoad(project);
for (Student s : project.getProjectParticipants()){
if (userSettingsDao.getUserSettings(s.getUser()).getActiveProject()!=null && userSettingsDao.getUserSettings(s.getUser()).getActiveProject().equals(project)){
// if (userSettingsDao.getUserSettings(s.getUser()).getActiveProject()!=null && userSettingsDao.getUserSettings(s.getUser()).getActiveProject().equals(project)){
// if (userSettingsDao.getUserSettings(s.getUser()).getActiveProject()!=null){
if (s.getUser()!=null && userSettingsDao.getUserSettings(s.getUser())!=null){
userSettingsDao.getUserSettings(s.getUser()).setActiveProject(null);
userSettingsDao.save(userSettingsDao.getUserSettings(s.getUser()));
}
// }
}
projectDao.delete(project);
}

@ -1,11 +1,9 @@
package se.su.dsv.scipro.data.facade;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import se.su.dsv.scipro.SciProSession;
import se.su.dsv.scipro.data.dataobjects.Employee;
import se.su.dsv.scipro.data.dataobjects.Student;
import se.su.dsv.scipro.data.dataobjects.User;
@ -15,8 +13,12 @@ import se.su.dsv.scipro.match.dao.interfaces.ProjectIdeaDao;
import se.su.dsv.scipro.match.dao.interfaces.ProjectIdeaDao.Params;
import se.su.dsv.scipro.match.dao.interfaces.SupervisorDao;
import se.su.dsv.scipro.match.dataobject.ApplicationPeriod;
import se.su.dsv.scipro.match.dataobject.Match;
import se.su.dsv.scipro.match.dataobject.ProjectIdea;
import java.util.HashSet;
import java.util.List;
@Service
public class ProjectIdeaFacade {
@ -39,7 +41,6 @@ public class ProjectIdeaFacade {
if(agreedSupervisorId != null) {
Employee agreedSupervisor = supervisorDao.load(agreedSupervisorId);
matchDao.addPreApprovedMatch(ideaCreator, idea, agreedSupervisor);
// } else if(idea.getMatch() == null) {
} else {
matchDao.addDefaultMatch(ideaCreator, idea);
}
@ -59,9 +60,49 @@ public class ProjectIdeaFacade {
pi.setAuthors(authorList);
pi = projectIdeaDao.save(pi);
}
@Transactional
public void setAllPublishedIdeasToConfirmed(){
HashSet<Match.Status> statusSet = new HashSet<Match.Status>();
statusSet.add(Match.Status.PUBLISHED);
Params params = new Params();
params.setStatuses(statusSet);
for (ProjectIdea pi : projectIdeaDao.findProjectIdeas(params)){
matchDao.changeStatus(SciProSession.get().getUser(), pi.getMatch(), Match.Status.CONFIRMED);
}
}
/**
*
* This method is used to return the latest decline message if a project idea is already rejected by a specific supervisor. The the latest decline message
* must be returned because the project idea might have been rejected several times by the same supervisor. The method takes a supervisor and
* a project idea as parameters. The method loops through the match history of the project idea to check if the supervisor has
* rejected one of the matches previously.
*
* @param supervisor the supervisor that should be checked
* @param projectIdea from which we get the match history
* @return String the decline message is returned if it exists
*/
public String declineMessageWhenRejectedMatch(final User supervisor, final ProjectIdea projectIdea){
if (supervisor == null)
throw new RenderingSafeException(new UnsupportedOperationException("Unable to recieve null supervisor."));
if (projectIdea == null)
throw new RenderingSafeException(new UnsupportedOperationException("Unable to recieve null project idea."));
else {
ProjectIdea reloadedProjectIdea = projectIdeaDao.load(projectIdea.getId());
if (reloadedProjectIdea.getMatchHistory().size()==0)
return null;
for (Match match : reloadedProjectIdea.getMatchHistory()){
if(match.getRejectedBy() != null && match.getRejectedBy().equals(supervisor)) {
return (match.getCommentForAdmin() != null && !match.getCommentForAdmin().isEmpty() ? match.getCommentForAdmin() : null);
}
}
return null;
}
}
/**
* @author fred
*
* Authors are not supposed to be able to submit multiple project ideas during the same period. This method takes a user and
* a list of (the current) application periods and loops through them to check if the user has already submitted or is already
@ -71,9 +112,9 @@ public class ProjectIdeaFacade {
* prevent a user ending up with more than one project idea, as two other users can still add the same user as partner into two
* different project ideas.
*
* @param u
* @param periodList
* @return
* @param u the user
* @param periodList the list
* @return boolean
*/
@Transactional
public boolean projectIdeaAlreadySubmittedThisPeriod(User u, List<ApplicationPeriod> periodList){

@ -30,7 +30,7 @@ public class HelpIconDialog extends Panel {
add(dialog);
//ImageIcon icon = new ImageIcon("helpIcon", ImageIcon.ICON_HELP, "Help");
ImageObject icon = new ImageObject("helpIcon", ImageObject.TWENTYFOUR + ImageObject.HELP);
ImageObject icon = new ImageObject("helpIcon", ImageObject.SIXTEEN + ImageObject.HELP);
icon.add(new AttributeAppender("onclick", new Model<String>(dialog.open().render(true).toString()), " "));
add(icon);

@ -29,7 +29,7 @@ public class HelpIconPanelDialog extends Panel {
add(dialog);
//ImageIcon icon = new ImageIcon("helpIcon", ImageIcon.ICON_HELP, "Help");
ImageObject icon = new ImageObject("helpIcon", ImageObject.TWENTYFOUR + ImageObject.HELP);
ImageObject icon = new ImageObject("helpIcon", ImageObject.SIXTEEN + ImageObject.HELP);
icon.add(new AttributeAppender("onclick", new Model<String>(dialog.open().render(true).toString()), " "));
add(icon);
}

@ -86,7 +86,7 @@ public class ImageObject extends ContextImage{
*
* Examples:
*
* wicketComponent.add(new ImageObject("deleteIcon", ImageObject.TWENTYFOUR + ImageObject.DELETE));
* wicketComponent.add(new ImageObject("deleteIcon", ImageObject.SIXTEEN + ImageObject.DELETE));
*
* wicketComponent.add(new ImageObject("greenLightIcon", ImageObject.PATH + ImageObject.LIGHT_GREEN));
*

@ -0,0 +1,34 @@
package se.su.dsv.scipro.keywords;
import java.io.Serializable;
import java.util.Set;
import se.su.dsv.scipro.match.dataobject.Keyword;
public class KeywordContainer implements Serializable {
private static final long serialVersionUID = 1L;
private Set<Keyword> keywordSet;
public KeywordContainer(Set<Keyword> keywordSet){
this.keywordSet = keywordSet;
}
public void add(Keyword k){
keywordSet.add(k);
}
public void remove(Keyword k){
keywordSet.remove(k);
}
public Set<Keyword> getKeywordSet() {
return keywordSet;
}
public void setKeywordSet(Set<Keyword> keywordSet) {
this.keywordSet = keywordSet;
}
}

@ -0,0 +1,27 @@
<!DOCTYPE html>
<html
xmlns:wicket="http://wicket.apache.org/dtds.data/wicket-xhtml1.4-strict.dtd">
<body>
<wicket:panel>
<form wicket:id="form">
<div class="span-16 last prepend-top" wicket:id="wmc">
<div><label wicket:id="instruction"></label></div>
<div class="span-8">
<label>Available</label>
<div wicket:id="availablelistview">
<input type="checkbox" wicket:id="checkbox" />
<span wicket:id="label"></span>
</div>
</div>
<div class="span-8 last">
<label>Selected</label>
<div wicket:id="selectedlistview">
<input type="checkbox" wicket:id="checkbox" />
<span wicket:id="label"></span>
</div>
</div>
</div>
</form>
</wicket:panel>
</body>
</html>

@ -0,0 +1,116 @@
package se.su.dsv.scipro.keywords;
import java.util.ArrayList;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.ajax.markup.html.form.AjaxCheckBox;
import org.apache.wicket.markup.html.WebMarkupContainer;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.form.Form;
import org.apache.wicket.markup.html.list.ListItem;
import org.apache.wicket.markup.html.list.ListView;
import org.apache.wicket.markup.html.panel.Panel;
import org.apache.wicket.model.Model;
import org.apache.wicket.spring.injection.annot.SpringBean;
import se.su.dsv.scipro.match.dao.interfaces.KeywordDao;
import se.su.dsv.scipro.match.dao.interfaces.KeywordTypeDao;
import se.su.dsv.scipro.match.dao.interfaces.KeywordTypeDao.TYPE;
import se.su.dsv.scipro.match.dataobject.Keyword;
import se.su.dsv.scipro.match.dataobject.KeywordType;
public abstract class SelectKeywordsPanel extends Panel {
private static final long serialVersionUID = 1L;
@SpringBean
private KeywordTypeDao keywordTypeDao;
@SpringBean
private KeywordDao keywordDao;
private Model<KeywordContainer> containerModel;
public Model<KeywordContainer> getContainerModel(){
return containerModel;
}
/**
* Override this method to do something.
*/
public abstract void onUpdateAdd(AjaxRequestTarget target, Keyword addedKeyword);
public abstract void onUpdateRemove(AjaxRequestTarget target, Keyword removedKeyword);
public SelectKeywordsPanel(String id, final Model<KeywordContainer> containerModel, final TYPE type, final String instruction) {
super(id);
this.containerModel = containerModel;
add(new SelectKeywordForm("form", containerModel, type, instruction));
}
private class SelectKeywordForm extends Form {
private static final long serialVersionUID = 1L;
private WebMarkupContainer wmc;
public SelectKeywordForm(String id, final Model<KeywordContainer> containerModel, final TYPE type, final String instruction) {
super(id);
wmc = new WebMarkupContainer("wmc");
wmc.setOutputMarkupId(true);
add(wmc);
wmc.add(new Label("instruction", instruction));
final KeywordType kwtype = keywordTypeDao.findByType(type);
ListView<Keyword> availableListView = new ListView<Keyword>("availablelistview", new ArrayList<Keyword>(keywordDao.findAllFromType(kwtype, false))){
private static final long serialVersionUID = 1L;
@Override
protected void populateItem(ListItem<Keyword> item) {
final Keyword kw = item.getModelObject();
if(containerModel.getObject().getKeywordSet().contains(kw)){
item.setVisible(false);
}
item.add(new Label("label", kw.getKeyword()));
item.add(new AjaxCheckBox("checkbox", new Model<Boolean>(containerModel.getObject().getKeywordSet().contains(kw))){
private static final long serialVersionUID = 1L;
@Override
protected void onUpdate(AjaxRequestTarget target) {
containerModel.getObject().add(kw);
target.addComponent(wmc);
onUpdateAdd(target, kw);
}
});
}
};
wmc.add(availableListView);
ListView<Keyword> selectedListView = new ListView<Keyword>("selectedlistview", new ArrayList<Keyword>(keywordDao.findAllFromType(kwtype, false))){
private static final long serialVersionUID = 1L;
@Override
protected void populateItem(ListItem<Keyword> item) {
final Keyword kw = item.getModelObject();
if(!containerModel.getObject().getKeywordSet().contains(kw)){
item.setVisible(false);
}
item.add(new Label("label", kw.getKeyword()));
item.add(new AjaxCheckBox("checkbox", new Model<Boolean>(containerModel.getObject().getKeywordSet().contains(kw))){
private static final long serialVersionUID = 1L;
@Override
protected void onUpdate(AjaxRequestTarget target) {
containerModel.getObject().remove(kw);
target.addComponent(wmc);
onUpdateRemove(target, kw);
}
});
}
};
wmc.add(selectedListView);
}
}
}

@ -82,9 +82,10 @@ public class GreedyMatchingAlgorithm implements MatchingAlgorithm {
continue;
}
if(availability.getProjectClass().toString().equalsIgnoreCase(ProjectClass.BACHELOR) &&
projectIdea.getProjectClass().toString().equalsIgnoreCase(ProjectClass.MASTER)) {
logger.info("A bachelor supervisor cannot handle master ideas.");
if(!availability.getProjectClass().toString().equals(
projectIdea.getProjectClass().toString()) ) {
//logger.info("A bachelor supervisor cannot handle master ideas.");
logger.info("Supervisor availability level and project idea level aren't equal.");
continue;
}

@ -2,6 +2,16 @@ package se.su.dsv.scipro.match;
import java.io.Serializable;
import javax.persistence.Basic;
import javax.persistence.Cacheable;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
import org.hibernate.annotations.Cache;
import org.hibernate.annotations.CacheConcurrencyStrategy;
import se.su.dsv.scipro.data.dataobjects.DomainObject;
import se.su.dsv.scipro.match.dao.interfaces.KeywordTypeDao;
import se.su.dsv.scipro.match.dataobject.KeywordType;
@ -10,16 +20,39 @@ import se.su.dsv.scipro.match.dataobject.KeywordType;
*
*/
public class Weights implements Serializable {
private static final long serialVersionUID = -3830919483369766778L;
@Entity
@Table(name="weights")
@Cacheable(true)
@Cache(usage= CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
public class Weights extends DomainObject implements Serializable {
private static final long serialVersionUID = 1L;
@Id
private Long id = null;
@Override
public Long getId() {
return id;
}
@Basic(optional=false)
private int keywordPoints = 3;
private int researchAreaPoints = 5;
private int preferredSupervisorPoints = 10;
@Basic(optional=false)
private int researchAreaPoints = 10;
@Basic(optional=false)
private int preferredSupervisorPoints = 1;
public Weights() {
}
/**
* Not part of the public API, do NOT USE
*/
public Weights(Long id){
this.id = id;
}
public void setKeywordPoints(int keywordPoints) {
this.keywordPoints = keywordPoints;
}
@ -53,4 +86,6 @@ public class Weights implements Serializable {
return 0;
}
}

@ -1,11 +1,15 @@
package se.su.dsv.scipro.match.dao.interfaces;
import se.su.dsv.scipro.data.dao.interfaces.Dao;
import se.su.dsv.scipro.data.dao.interfaces.QueryableDao;
import se.su.dsv.scipro.data.dataobjects.Student;
import se.su.dsv.scipro.data.dataobjects.User;
public interface AuthorDao extends Dao<Student>{
import java.util.List;
public interface AuthorDao extends QueryableDao<Student, AuthorDaoParams> {
Student getOrCreate(User user);
}
List<Student> getAutoCompleteAuthors(final String searchString, int limit);
}

@ -0,0 +1,22 @@
package se.su.dsv.scipro.match.dao.interfaces;
import se.su.dsv.scipro.data.dao.interfaces.Dao;
/**
* @author: fred-fri
* date: 2012 03 16
*/
public class AuthorDaoParams extends Dao.SortableParams {
private static final long serialVersionUID = 6742110347403190362L;
private String nameLike;
public String getNameLike() {
return nameLike;
}
public void setNameLike(String nameLike) {
this.nameLike = nameLike;
}
}

@ -13,10 +13,31 @@ public interface KeywordDao extends LazyDeleteDao<Keyword>{
Set<Keyword> getKeywords(KeywordType type, boolean includeDeleted);
List<Keyword> getKeywordList(Params params);
/**
* Returns the keyword if it is found
* @param keywordType the keyword can be of a specific type i.e. regular, research area or unit, is never NULL
* @param keywordName the search term, can only be a part of the keyword name, but must start with the same characters
* @return List<Keyword> the keyword list
*/
public List<Keyword> getAutoCompleteCapableSupervisors(final KeywordType keywordType, final String keywordName);
public List<Keyword> findAllFromType(KeywordType kt, boolean includeDeleted);
/**
* Returns the keyword if it is found
* @param externalIdentifier the identifier of the keyword, is often NULL in the table Keyword
* @param type the keyword can be of a specific type i.e. regular, research area or unit, is never NULL
* @return Keyword the keyword if it is found
*/
Keyword getKeywordByIdentifierAndType(final Long externalIdentifier, KeywordType type);
/**
* Returns the keyword if it is found
* @param keywordName the name of the keyword, is never NULL
* @param type the keyword can be of a specific type i.e. regular, research area or unit
* @return Keyword the keyword if it is found
*/
Keyword getKeywordByNameAndType(String keywordName, KeywordType type);

@ -9,6 +9,7 @@ import se.su.dsv.scipro.data.dao.interfaces.Dao;
import se.su.dsv.scipro.data.dataobjects.Employee;
import se.su.dsv.scipro.data.dataobjects.ProjectClass;
import se.su.dsv.scipro.data.dataobjects.Student;
import se.su.dsv.scipro.match.dataobject.Keyword;
import se.su.dsv.scipro.match.dataobject.Match;
import se.su.dsv.scipro.match.dataobject.ProjectIdea;
@ -48,7 +49,17 @@ public interface ProjectIdeaDao extends Dao<ProjectIdea> {
private Student author;
private Boolean projectCreated;
private Collection<Keyword> keywords;
public Collection<Keyword> getKeywords() {
return keywords;
}
public void setKeywords(Collection<Keyword> keywords) {
this.keywords = keywords;
}
public Collection<ProjectClass> getProjectClasses() {
return projectClasses;
}

@ -17,7 +17,7 @@ public class SupervisorDaoParams extends Dao.SortableParams {
private Collection<Keyword> keywords;
private String nameLike;
public Collection<Language> getLanguages() {
return languages;
}

@ -35,9 +35,11 @@ public class ApplicationPeriodDaoJPAImp extends
throws PersistenceException {
TypedQuery<ProjectIdea> query =
em.createQuery(
"select pi FROM ProjectIdea pi WHERE pi.dateCreated <= :endDate AND pi.projectClass IN (:projectClasses) AND pi.project = NULL",
"select pi FROM ProjectIdea pi WHERE pi.applicationPeriod = :period AND pi.projectClass IN (:projectClasses) AND pi.project = NULL",
ProjectIdea.class);
query.setParameter("endDate", applicationPeriod.getEndDate());
// query.setParameter("endDate", applicationPeriod.getEndDate());
//query.setParameter("startDate", applicationPeriod.getStartDate());
query.setParameter("period", applicationPeriod);
query.setParameter("projectClasses", applicationPeriod.getProjectClass());
query.setHint(QueryHints.HINT_CACHEABLE, "true");
try {

@ -1,23 +1,26 @@
package se.su.dsv.scipro.match.dao.jpa;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceException;
import javax.persistence.TypedQuery;
import org.hibernate.ejb.QueryHints;
import org.springframework.dao.EmptyResultDataAccessException;
import org.springframework.orm.jpa.JpaCallback;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;
import se.su.dsv.scipro.data.dao.jpa.AbstractDaoJPAImp;
import se.su.dsv.scipro.data.dao.jpa.AbstractQuerySet;
import se.su.dsv.scipro.data.dao.jpa.AbstractSortableQuerySet;
import se.su.dsv.scipro.data.dao.jpa.Query;
import se.su.dsv.scipro.data.dao.jpa.RoleDaoJPAImp;
import se.su.dsv.scipro.data.dataobjects.Student;
import se.su.dsv.scipro.data.dataobjects.User;
import se.su.dsv.scipro.match.dao.interfaces.AuthorDao;
import se.su.dsv.scipro.match.dao.interfaces.AuthorDaoParams;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceException;
import javax.persistence.TypedQuery;
import java.util.List;
@Repository("AuthorDao")
public class AuthorDaoJPAImp extends AbstractDaoJPAImp<Student> implements
AuthorDao {
public class AuthorDaoJPAImp extends QueryableDaoJPAImp<Student, AuthorDaoParams> implements AuthorDao {
public AuthorDaoJPAImp() {
super(Student.class);
@ -47,4 +50,42 @@ public class AuthorDaoJPAImp extends AbstractDaoJPAImp<Student> implements
}
}
@Override
public List<Student> getAutoCompleteAuthors(String searchString, int limit) {
return getJpaTemplate().execute(
new QuerySet()/*.projectClass(projectClass).languages(languages)*/
.nameLike(searchString).orderByUser().limit(limit)
.fetchCallback());
}
protected AbstractQuerySet<Student> createQuerySet(AuthorDaoParams params) {
return new QuerySet().nameLike(params.getNameLike())
.sort(params);
}
private static class QuerySet extends AbstractSortableQuerySet<Student> {
public QuerySet() {
super(Student.class);
}
public QuerySet orderByUser() {
getQuery().combine(RoleDaoJPAImp.orderByUserQuery());
return this;
}
public QuerySet nameLike(String name) {
if (name != null) {
getQuery().combine(
new Query().combine(RoleDaoJPAImp
.autoCompleteUserNameQuery(name)));
}
return this;
}
@Override
public Query initQuery() {
return new Query().select("s").from("Student s");
}
}
}

@ -23,8 +23,7 @@ import se.su.dsv.scipro.match.dataobject.Keyword;
import se.su.dsv.scipro.match.dataobject.KeywordType;
@Repository("keywordDao")
public class KeywordDaoJPAImp extends LazyDeleteAbstractDaoJPAImp<Keyword> implements
KeywordDao {
public class KeywordDaoJPAImp extends LazyDeleteAbstractDaoJPAImp<Keyword> implements KeywordDao {
public KeywordDaoJPAImp() {
super(Keyword.class);
@ -137,5 +136,21 @@ public class KeywordDaoJPAImp extends LazyDeleteAbstractDaoJPAImp<Keyword> imple
}
});
}
@Override
// TODO should be improved so that it is possible to search on "mining" and find "data mining"
public List<Keyword> getAutoCompleteCapableSupervisors(final KeywordType keywordType, final String keywordName) {
return getJpaTemplate().execute(new JpaCallback<List<Keyword>>() {
public List<Keyword> doInJpa(EntityManager em) throws PersistenceException {
TypedQuery<Keyword> query;
query = em.createQuery("SELECT x FROM "+domainClassString+" x WHERE x.type = :type AND x.keyword LIKE :keywordName ORDER BY keyword", domainClass);
query.setParameter("type", keywordType);
String keyWordNameString = keywordName + "%";
query.setParameter("keywordName", keyWordNameString);
query.setHint(QueryHints.HINT_CACHEABLE, "true");
return query.getResultList();
}
});
}
}

@ -22,18 +22,18 @@ import se.su.dsv.scipro.match.dataobject.ProjectIdea;
@Repository("matchDao")
public class MatchDaoJPAImp extends AbstractDaoJPAImp<Match> implements
MatchDao {
MatchDao {
@Autowired
private ProjectIdeaDao projectIdeaDao;
public MatchDaoJPAImp() {
super(Match.class);
}
@Override
public Match addPreApprovedMatch(User creator, ProjectIdea projectIdea,
Employee supervisor) {
Employee supervisor) {
Match match = new Match();
match.setSupervisor(supervisor);
match.setType(Match.Type.PRE_APPROVED);
@ -57,7 +57,7 @@ public class MatchDaoJPAImp extends AbstractDaoJPAImp<Match> implements
public Match changeStatus(User changer, Match match, Match.Status status) {
Match newMatch = new Match();
if (status != Match.Status.UNMATCHED){
newMatch.setSupervisor(match.getSupervisor());
newMatch.setSupervisor(match.getSupervisor());
}
newMatch.setType(match.getType());
if (status != null) {
@ -74,7 +74,7 @@ public class MatchDaoJPAImp extends AbstractDaoJPAImp<Match> implements
return save(newMatch);
}
public Match save(Match match) {
match = super.save(match);
ProjectIdea projectIdea = match.getProjectIdea();
@ -89,12 +89,12 @@ public class MatchDaoJPAImp extends AbstractDaoJPAImp<Match> implements
@Override
public List<Match> doInJpa(EntityManager em)
throws PersistenceException {
throws PersistenceException {
TypedQuery<Match> query =
em.createQuery(
"select m FROM Match m WHERE m.projectIdea = :projectIdea ORDER BY m.dateCreated DESC, m.id DESC",
Match.class);
em.createQuery(
"select m FROM Match m WHERE m.projectIdea = :projectIdea ORDER BY m.dateCreated DESC, m.id DESC",
Match.class);
query.setParameter("projectIdea", projectIdea);
query.setHint(QueryHints.HINT_CACHEABLE, "true");
try {

@ -35,9 +35,7 @@ import se.su.dsv.scipro.match.dataobject.Keyword;
import se.su.dsv.scipro.match.dataobject.Match;
@Repository("supervisorDao")
public class SupervisorDaoJPAImp extends
QueryableDaoJPAImp<Employee, SupervisorDaoParams> implements
SupervisorDao {
public class SupervisorDaoJPAImp extends QueryableDaoJPAImp<Employee, SupervisorDaoParams> implements SupervisorDao {
@Autowired
private ProjectIdeaDao projectIdeaDao;
@ -114,7 +112,8 @@ SupervisorDao {
return new QuerySet().languages(params.getLanguages())
.projectClass(params.getProjectClass())
.keywords(params.getKeywords())
.nameLike(params.getNameLike());
.nameLike(params.getNameLike())
.sort(params);
}
private static class QuerySet extends AbstractSortableQuerySet<Employee> {
@ -139,7 +138,7 @@ SupervisorDao {
}
return this;
}
public QuerySet orderByUser() {
getQuery().combine(RoleDaoJPAImp.orderByUserQuery());
return this;

@ -33,11 +33,9 @@ public class ApplicationPeriod extends DomainObject {
private String name;
@NotNull
@Temporal(TemporalType.DATE)
private Date startDate;
@NotNull
@Temporal(TemporalType.DATE)
private Date endDate;
public ApplicationPeriod() {

@ -17,7 +17,7 @@ public class Availability implements Serializable {
private Integer numCapable;
private final Employee supervisor;
public Availability(final Employee supervisor,final Long numMatched,final Integer numCapable,final ProjectClass projectClass) {
public Availability(final Employee supervisor, final Long numMatched, final Integer numCapable, final ProjectClass projectClass) {
this.supervisor = supervisor;
this.numMatched = numMatched;
this.numCapable = numCapable;

@ -68,8 +68,7 @@ public class Keyword extends LazyDeletableDomainObject {
@Override
public String toString() {
return "Keyword [id=" + id + ", keyword=" + keyword + ", type=" + type
+ "]";
return keyword;
}
@Override

@ -30,13 +30,42 @@ public class Match extends DomainObject implements Comparable<Match> {
}
public static enum Status {
PENDING,
PUBLISHED,
CONFIRMED,
REJECTED,
REFUSED,
INACTIVE,
UNMATCHED
PENDING
{
public String toString() {
return "Pending";
}
},
PUBLISHED{
public String toString() {
return "Suggested";
}
},
CONFIRMED{
public String toString() {
return "Accepted";
}
},
REJECTED{
public String toString() {
return "Rejected";
}
},
REFUSED{
public String toString() {
return "Refused";
}
},
INACTIVE{
public String toString() {
return "Inactive";
}
},
UNMATCHED{
public String toString() {
return "Unmatched";
}
}
}
public static final int NO_POINTS_ASSIGNED = -1;

@ -0,0 +1,45 @@
package se.su.dsv.scipro.match.dataprovider;
import java.util.Iterator;
import org.apache.wicket.injection.web.InjectorHolder;
import org.apache.wicket.markup.repeater.data.IDataProvider;
import org.apache.wicket.model.IModel;
import org.apache.wicket.spring.injection.annot.SpringBean;
import se.su.dsv.scipro.data.DomainObjectDetachableModel;
import se.su.dsv.scipro.match.dao.interfaces.ApplicationPeriodDao;
import se.su.dsv.scipro.match.dataobject.ApplicationPeriod;
public class ProjectIdeaStatisticDataProvider implements IDataProvider<ApplicationPeriod>{
private static final long serialVersionUID = 1L;
@SpringBean
private ApplicationPeriodDao applicationPeriodDao;
public ProjectIdeaStatisticDataProvider(){
InjectorHolder.getInjector().inject(this);
}
@Override
public Iterator<? extends ApplicationPeriod> iterator(int first, int count) {
return applicationPeriodDao.findAll(first, count).iterator();
}
@Override
public int size() {
return (int)applicationPeriodDao.countAll();
}
@Override
public IModel<ApplicationPeriod> model(ApplicationPeriod object) {
return new DomainObjectDetachableModel<ApplicationPeriod>(applicationPeriodDao,object);
}
@Override
public void detach() {
//Do nothing
}
}

@ -1,76 +1,89 @@
<!DOCTYPE html>
<html
xmlns:wicket="http://wicket.apache.org/dtds.data/wicket-xhtml1.4-strict.dtd">
xmlns:wicket="http://wicket.apache.org/dtds.data/wicket-xhtml1.4-strict.dtd">
<body>
<wicket:panel>
<div wicket:id="dialog">
<div wicket:id="dialogContent"></div>
</div>
<h5 class="peer-title">Search among all project ideas</h5>
<form wicket:id="form">
<label>Submitted between:</label><br>
<div wicket:id="container">
<div><span wicket:id="dateFrom">datePicker</span> and <span wicket:id="dateTo">datePicker</span></div>
</div>
<label for="titleField">Title:</label><br/>
<input style="width:300px;" wicket:id="titleField" type="text" /><br/>
<!-- these arent implemented yet, commenting out -->
<!-- <label for="supervisorField">Supervisor:</label><br/> -->
<!-- <input style="width:300px;" wicket:id="supervisorField" type="text" /><br/> -->
<!-- <label for="authorField">Author:</label><br/> -->
<!-- <input style="width:300px;" wicket:id="authorField" type="text" /> -->
<div class="span-16 append-bottom last">
<div class="span-6" wicket:id="projectClassPanel"></div>
<div class="span-10 last append-bottom" wicket:id="matchStatusPanel"></div>
<input wicket:id="filterButton" type="submit" />
</div>
</form>
<div wicket:id="allContainer">
<div>Number of found project ideas: <span wicket:id="totalProjectIdeas"></span></div>
<div class="span-15 last">
<table class="rounded-corner">
<thead>
<tr>
<th class="rounded-left-top">Level</th>
<th>Title</th>
<th>Author(s)</th>
<th>Matched to</th>
<th>Unit</th>
<th>Status</th>
<th class="rounded-right-top">Edit</th>
</tr>
</thead>
<tfoot>
<tr>
<td colspan="7" class="rounded-foot">&nbsp;</td>
</tr>
</tfoot>
<tbody>
<tr wicket:id="allDataView">
<td wicket:id="level"></td>
<td wicket:id="title"></td>
<td wicket:id="author"></td>
<td wicket:id="supervisor"></td>
<td wicket:id="supervisorUnit"></td>
<td wicket:id="status"></td>
<td><a href="#" wicket:id="editDialog"><img wicket:id="editIcon" /></a></td>
</tr>
<tr>
<td colspan="7" wicket:id="emptyLabel"></td>
</tr>
</tbody>
</table>
</div>
<div wicket:id="nav"></div>
</div>
<wicket:panel>
<div wicket:id="dialog">
<div wicket:id="dialogContent"></div>
</div>
<div class="prepend-top"></div>
<h5 class="peer-title">Search among all project ideas</h5>
</wicket:panel>
<form wicket:id="form">
<label>Submitted between:</label><br>
<div wicket:id="container">
<div><span wicket:id="dateFrom">datePicker</span> and <span wicket:id="dateTo">datePicker</span></div>
</div>
<label for="titleField">Title:</label><br/>
<input style="width:300px;" wicket:id="titleField" type="text"/><br/>
<!-- these arent implemented yet, commenting out -->
<!-- <label for="supervisorField">Supervisor:</label><br/> -->
<!-- <input style="width:300px;" wicket:id="supervisorField" type="text" /><br/> -->
<!-- <label for="authorField">Author:</label><br/> -->
<!-- <input style="width:300px;" wicket:id="authorField" type="text" /> -->
<div class="span-22 append-bottom last">
<div class="span-3" wicket:id="projectClassPanel"></div>
<div class="span-7 last append-bottom" wicket:id="matchStatusPanel"></div>
<div class="span-5">
<div><input wicket:id="filterButton" type="submit"/></div>
<div class="prepend-top"><label>DO NOT TOUCH unless you know what you're doing!</label></div>
<div>
<button wicket:id="acceptLink">Force accept all PUBLISHED ideas</button>
</div>
</div>
</div>
</form>
<div wicket:id="allContainer">
<div>Number of found project ideas: <span wicket:id="totalProjectIdeas"></span>
<span class="right">Ideas per page: <select wicket:id="itemsPerPage"></select></span>
</div>
<div class="span-22 last">
<table class="rounded-corner">
<thead>
<tr>
<th class="rounded-left-top"><a href="#" wicket:id="levelSortLink">Level</a></th>
<th><a href="#" wicket:id="titleSortLink">Title</a></th>
<th>Author(s)</th>
<th><a href="#" wicket:id="supervisorSortLink">Matched to</a></th>
<th>Unit</th>
<th><a href="#" wicket:id="statusSortLink">Status</a></th>
<th class="rounded-right-top">Edit</th>
</tr>
</thead>
<tfoot>
<tr>
<td colspan="7" class="rounded-foot">&nbsp;</td>
</tr>
</tfoot>
<tbody>
<tr wicket:id="allDataView">
<td wicket:id="level"></td>
<td wicket:id="title"></td>
<td wicket:id="author"></td>
<td wicket:id="supervisor"></td>
<td wicket:id="supervisorUnit"></td>
<td wicket:id="status"></td>
<td><a href="#" wicket:id="editDialog"><img wicket:id="editIcon"/></a></td>
</tr>
<tr>
<td colspan="7" wicket:id="emptyLabel"></td>
</tr>
</tbody>
</table>
</div>
<div class="span-15 last" wicket:id="nav"></div>
</div>
</wicket:panel>
</body>
</html>

@ -1,11 +1,8 @@
package se.su.dsv.scipro.match.panel;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import org.apache.wicket.Component;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.ajax.form.AjaxFormComponentUpdatingBehavior;
import org.apache.wicket.ajax.markup.html.AjaxLink;
import org.apache.wicket.ajax.markup.html.form.AjaxButton;
import org.apache.wicket.markup.html.WebMarkupContainer;
@ -18,66 +15,89 @@ import org.apache.wicket.markup.html.panel.Panel;
import org.apache.wicket.markup.repeater.Item;
import org.apache.wicket.markup.repeater.data.DataView;
import org.apache.wicket.model.Model;
import org.apache.wicket.spring.injection.annot.SpringBean;
import org.apache.wicket.util.string.Strings;
import org.odlabs.wiquery.ui.dialog.Dialog;
import se.su.dsv.scipro.admin.panels.match.AdminEditProjectIdeaPanel;
import se.su.dsv.scipro.components.CustomDateTimeField;
import se.su.dsv.scipro.components.ItemsPerPageChoice;
import se.su.dsv.scipro.data.dao.interfaces.Dao.SortableParams.Sort;
import se.su.dsv.scipro.data.dataobjects.ProjectClass;
import se.su.dsv.scipro.data.dataobjects.Student;
import se.su.dsv.scipro.data.facade.ProjectIdeaFacade;
import se.su.dsv.scipro.icons.ImageObject;
import se.su.dsv.scipro.match.dao.interfaces.ProjectIdeaDao;
import se.su.dsv.scipro.match.dao.interfaces.ProjectIdeaDao.Params;
import se.su.dsv.scipro.match.dataobject.Keyword;
import se.su.dsv.scipro.match.dataobject.Match;
import se.su.dsv.scipro.match.dataobject.ProjectIdea;
import se.su.dsv.scipro.match.dataprovider.ProjectIdeaDataProvider;
import se.su.dsv.scipro.util.JavascriptEventConfirmation;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
public class AdminManageProjectIdeaPanel extends Panel {
private static final long serialVersionUID = 1L;
private static final long serialVersionUID = 1L;
private WebMarkupContainer allContainer;
private ProjectIdeaDataProvider allProvider;
private Label emptyLabel;
private Dialog dialog;
private Label totalProjectIdeas;
private Date currentDate;
private Date pastDate;
public AdminManageProjectIdeaPanel(String id){
super(id);
allDataViewSetup();
FilterForm form = new FilterForm("form");
add(form);
}
private void allDataViewSetup(){
Calendar cal = Calendar.getInstance();
currentDate = cal.getTime();
cal.add(Calendar.MONTH, -6);
pastDate = cal.getTime();
dialog = new Dialog("dialog");
dialog.setModal(true);
dialog.setAutoOpen(false);
dialog.setWidth(800);
dialog.setHeight(800);
dialog.add(new EmptyPanel("dialogContent"));
add(dialog);
private ProjectIdeaDataProvider allProvider;
private Label emptyLabel;
private Dialog dialog;
private Label totalProjectIdeas;
allContainer = new WebMarkupContainer("allContainer");
//Add info for the user should there be no events to display.
emptyLabel = new Label("emptyLabel", "No project ideas to show.");
allContainer.add(emptyLabel);
emptyLabel.setOutputMarkupId(true); //Needs to be AJAX-enabled.
allProvider = new ProjectIdeaDataProvider();
ProjectIdeaDao.Params params = new ProjectIdeaDao.Params();
private Date currentDate;
private Date pastDate;
private Component feedBackPanel;
@SpringBean
private ProjectIdeaFacade projectIdeaFacade;
private Params params;
private ItemsPerPageChoice itemsPerPageChoice;
public AdminManageProjectIdeaPanel(String id, final Component feedBackPanel__) {
super(id);
feedBackPanel = feedBackPanel__;
allDataViewSetup();
FilterForm form = new FilterForm("form");
addSortingLinks();
add(form);
}
private void allDataViewSetup() {
Calendar cal = Calendar.getInstance();
currentDate = cal.getTime();
cal.add(Calendar.MONTH, -6);
pastDate = cal.getTime();
dialog = new Dialog("dialog");
dialog.setModal(true);
dialog.setAutoOpen(false);
dialog.setWidth(800);
dialog.setHeight(800);
dialog.add(new EmptyPanel("dialogContent"));
add(dialog);
allContainer = new WebMarkupContainer("allContainer");
//Add info for the user should there be no events to display.
emptyLabel = new Label("emptyLabel", "No project ideas to show.");
allContainer.add(emptyLabel);
emptyLabel.setOutputMarkupId(true); //Needs to be AJAX-enabled.
allProvider = new ProjectIdeaDataProvider();
params = new ProjectIdeaDao.Params();
params.setSortOn("title", Sort.ASCENDING);
//params.setStatuses(new ArrayList<Match.Status>(Arrays.asList(Match.Status.CONFIRMED, Match.Status.REFUSED, Match.Status.UNMATCHED)));
allProvider.setParams(params);
//Add data view
DataView<ProjectIdea> allDataView = new DataView<ProjectIdea>("allDataView", allProvider) {
//Add data view
final DataView<ProjectIdea> allDataView = new DataView<ProjectIdea>("allDataView", allProvider) {
private static final long serialVersionUID = 1L;
@Override
@ -96,14 +116,15 @@ public class AdminManageProjectIdeaPanel extends Panel {
@Override
public void onClick(AjaxRequestTarget target) {
if (target != null) {
dialog.replace(new AdminEditProjectIdeaPanel("dialogContent", new Model<ProjectIdea>(idea)) {
private static final long serialVersionUID = 1L;
});
target.addComponent(dialog);
dialog.setTitle("Edit project idea: " + idea.getTitle());
dialog.open(target);
}
// if (target != null) {
dialog.replace(new AdminEditProjectIdeaPanel("dialogContent", new Model<ProjectIdea>(idea), feedBackPanel) {
private static final long serialVersionUID = 1L;
});
dialog.setTitle("Edit project idea: " + Strings.escapeMarkup(idea.getTitle()).toString());
target.addComponent(dialog);
dialog.open(target);
// }
}
};
@ -134,94 +155,140 @@ public class AdminManageProjectIdeaPanel extends Panel {
}
};
emptyLabel.setVisible(allProvider.size()==0); //Rule for the empty label
allContainer.setOutputMarkupId(true);
allContainer.add(allDataView);
add(allContainer);
allDataView.setItemsPerPage(10);
allContainer.add(new PagingNavigator("nav", allDataView));
emptyLabel.setVisible(allProvider.size() == 0); //Rule for the empty label
allContainer.setOutputMarkupId(true);
allContainer.add(allDataView);
add(allContainer);
allDataView.setItemsPerPage(10);
allContainer.add(new PagingNavigator("nav", allDataView));
// totalProjectIdeas = new Label("totalProjectIdeas", new Model(Integer.toString(allProvider.size())));
totalProjectIdeas = new Label("totalProjectIdeas", Integer.toString(allProvider.size()));
totalProjectIdeas.setOutputMarkupId(true);
allContainer.add(totalProjectIdeas);
totalProjectIdeas = new Label("totalProjectIdeas", Integer.toString(allProvider.size()));
totalProjectIdeas.setOutputMarkupId(true);
allContainer.add(totalProjectIdeas);
}
private class FilterForm extends Form<Void>{
private static final long serialVersionUID = 1L;
private TextField<String> titleField, supervisorField, authorField;
private FilterFormProjectClassPanel projectClassPanel;
private FilterFormMatchStatusPanel matchStatusPanel;
private CustomDateTimeField dateFrom;
private CustomDateTimeField dateTo;
itemsPerPageChoice = new ItemsPerPageChoice("itemsPerPage");
itemsPerPageChoice.add(new AjaxFormComponentUpdatingBehavior("onchange") {
public FilterForm(String id) {
super(id);
titleField = new TextField<String>("titleField", new Model<String>());
supervisorField = new TextField<String>("supervisorField", new Model<String>());
authorField = new TextField<String>("authorField", new Model<String>());
dateFrom = new CustomDateTimeField("dateFrom",new Model<Date>(pastDate));
dateTo = new CustomDateTimeField("dateTo",new Model<Date>(currentDate));
add(titleField);
WebMarkupContainer container = new WebMarkupContainer("container");
add(container);
container.add(dateFrom);
container.add(dateTo);
private static final long serialVersionUID = 4143017524829639803L;
@Override
protected void onUpdate(AjaxRequestTarget target) {
allDataView.setItemsPerPage(itemsPerPageChoice.getModelObject());
target.addComponent(allContainer);
}
});
allContainer.add(itemsPerPageChoice);
}
private void addSortingLinks() {
addSortLink("level", "projectClass.name");
addSortLink("title", "title");
addSortLink("status", "match.status");
addSortLink("supervisor", "match.supervisor");
}
private void addSortLink(String markup, final String sortField) {
final AjaxLink<Void> sortLink = new AjaxLink<Void>(markup + "SortLink") {
private static final long serialVersionUID = -6459164267551936706L;
@Override
public void onClick(AjaxRequestTarget target) {
if (params.getDirection().equals(Sort.ASCENDING))
params.setSortOn(sortField, Sort.DESCENDING);
else
params.setSortOn(sortField, Sort.ASCENDING);
target.addComponent(allContainer);
}
};
allContainer.add(sortLink);
}
private class FilterForm extends Form<Void> {
private static final long serialVersionUID = 1L;
private TextField<String> titleField, supervisorField, authorField;
private FilterFormProjectClassPanel projectClassPanel;
private FilterFormMatchStatusPanel matchStatusPanel;
private CustomDateTimeField dateFrom;
private CustomDateTimeField dateTo;
public FilterForm(String id) {
super(id);
titleField = new TextField<String>("titleField", new Model<String>());
supervisorField = new TextField<String>("supervisorField", new Model<String>());
authorField = new TextField<String>("authorField", new Model<String>());
dateFrom = new CustomDateTimeField("dateFrom", new Model<Date>(pastDate));
dateTo = new CustomDateTimeField("dateTo", new Model<Date>(currentDate));
add(titleField);
WebMarkupContainer container = new WebMarkupContainer("container");
add(container);
container.add(dateFrom);
container.add(dateTo);
// these arent implemented yet, commenting out
// add(supervisorField);
// add(authorField);
AjaxButton filterButton = new AjaxButton("filterButton", new Model<String>("Filter")) {
private static final long serialVersionUID = 1L;
@Override
protected void onSubmit(AjaxRequestTarget target, Form<?> form) {
ProjectIdeaDao.Params params = new ProjectIdeaDao.Params();
params.setTitleContains(titleField.getModelObject());
List<ProjectClass> pclasses = projectClassPanel.getSelectedprojectClasses();
if(!pclasses.isEmpty()){
params.setProjectClasses(pclasses);
}
List<Match.Status> status = matchStatusPanel.getSelectedMatchStatus();
if(!status.isEmpty()){
params.setStatuses(status);
}
params.setSubmittedAfter(dateFrom.getModelObject());
params.setSubmittedBefore(dateTo.getModelObject());
allProvider.setParams(params);
emptyLabel.setVisible(allProvider.size()==0); //Rule for the empty label
allContainer.replace(new Label("totalProjectIdeas", Integer.toString(allProvider.size())));
target.addComponent(totalProjectIdeas);
target.addComponent(allContainer);
}
};
projectClassPanel = new FilterFormProjectClassPanel("projectClassPanel", new ArrayList<ProjectClass>());
matchStatusPanel = new FilterFormMatchStatusPanel("matchStatusPanel");
add(projectClassPanel);
add(matchStatusPanel);
add(filterButton);
}
}
AjaxButton filterButton = new AjaxButton("filterButton", new Model<String>("Filter")) {
private static final long serialVersionUID = 1L;
@Override
protected void onSubmit(AjaxRequestTarget target, Form<?> form) {
params.setTitleContains(titleField.getModelObject());
List<ProjectClass> pclasses = projectClassPanel.getSelectedprojectClasses();
if (!pclasses.isEmpty()) {
params.setProjectClasses(pclasses);
}
List<Match.Status> status = matchStatusPanel.getSelectedMatchStatus();
if (!status.isEmpty()) {
params.setStatuses(status);
}
params.setSubmittedAfter(dateFrom.getModelObject());
params.setSubmittedBefore(dateTo.getModelObject());
emptyLabel.setVisible(allProvider.size() == 0); //Rule for the empty label
allContainer.replace(new Label("totalProjectIdeas", Integer.toString(allProvider.size())));
target.addComponent(totalProjectIdeas);
target.addComponent(allContainer);
}
};
projectClassPanel = new FilterFormProjectClassPanel("projectClassPanel", new ArrayList<ProjectClass>());
matchStatusPanel = new FilterFormMatchStatusPanel("matchStatusPanel");
add(projectClassPanel);
add(matchStatusPanel);
add(new AjaxLink("acceptLink") {
private static final long serialVersionUID = 1L;
@Override
public void onClick(AjaxRequestTarget target) {
projectIdeaFacade.setAllPublishedIdeasToConfirmed();
target.addComponent(totalProjectIdeas);
target.addComponent(allContainer);
}
}.add(new JavascriptEventConfirmation("onclick", "Are you sure you want to force accept all suggested (PUBLISHED) project ideas?")));
add(filterButton);
}
}
}

@ -9,7 +9,7 @@
<input style="width:300px;" wicket:id="supervisorField" type="text" /><br />
<label for="keywordField">Search on keywords used by supervisor:</label><br />
<input style="width:300px;" wicket:id="keywordField" type="text" />
<div class="span-16 prepend-top append-bottom last">
<div class="span-22 prepend-top append-bottom last">
<div class="span-5">
<label for="unitPanel">Filter by unit:</label><br />
@ -30,7 +30,7 @@
</form>
<div wicket:id="container">
<div class="span-15 last">
<div class="span-22 last">
<table class="rounded-corner">
<thead>
<tr>

Some files were not shown because too many files have changed in this diff Show More