[Tynstep-svn] r219 - in trunk/step: step-build/src/main/resources/checkstyle step-build/src/main/resources/eclipse step-core/src/main/java/com/tyndalehouse/step/core/data/create step-core/src/main/java/com/tyndalehouse/step/core/data/entities step-core/src/main/java/com/tyndalehouse/step/core/exceptions step-core/src/main/java/com/tyndalehouse/step/core/guice step-core/src/main/java/com/tyndalehouse/step/core/guice/providers step-core/src/main/java/com/tyndalehouse/step/core/models step-core/src/main/java/com/tyndalehouse/step/core/service step-core/src/main/java/com/tyndalehouse/step/core/service/impl step-core/src/main/java/com/tyndalehouse/step/core/xsl step-core/src/main/resources step-core/src/test/java/com/tyndalehouse/step/core/data step-core/src/test/java/com/tyndalehouse/step/core/data/create step-core/src/test/java/com/tyndalehouse/step/core/data/entities step-core/src/test/java/com/tyndalehouse/step/core/service step-core/src/test/java/com/tyndalehouse/step/core/service/impl step-parent step-web/src/main/java/com/tyndalehouse/step step-web/src/main/java/com/tyndalehouse/step/guice step-web/src/main/java/com/tyndalehouse/step/guice/providers step-web/src/main/java/com/tyndalehouse/step/models step-web/src/main/java/com/tyndalehouse/step/rest/controllers step-web/src/main/java/com/tyndalehouse/step/rest/framework step-web/src/main/resources step-web/src/main/webapp step-web/src/main/webapp/css step-web/src/main/webapp/js step-web/src/test/java/com/tyndalehouse/step/rest/controllers step-web/src/test/java/com/tyndalehouse/step/rest/framework
ChrisBurrell at crosswire.org
ChrisBurrell at crosswire.org
Sat Mar 19 02:53:19 MST 2011
Author: ChrisBurrell
Date: 2011-03-19 02:53:18 -0700 (Sat, 19 Mar 2011)
New Revision: 219
Added:
trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/data/entities/Bookmark.java
trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/data/entities/Session.java
trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/data/entities/User.java
trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/data/entities/readme.txt
trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/exceptions/RequiresLoginException.java
trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/exceptions/ValidationException.java
trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/guice/providers/ServerSessionProvider.java
trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/guice/providers/TestData.java
trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/models/ClientSession.java
trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/service/BookmarkService.java
trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/service/UserDataService.java
trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/service/impl/BookmarkServiceImpl.java
trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/service/impl/UserDataServiceImpl.java
trunk/step/step-core/src/test/java/com/tyndalehouse/step/core/data/AbstractDataTest.java
trunk/step/step-core/src/test/java/com/tyndalehouse/step/core/data/entities/
trunk/step/step-core/src/test/java/com/tyndalehouse/step/core/data/entities/UserTest.java
trunk/step/step-core/src/test/java/com/tyndalehouse/step/core/service/impl/BookmarkServiceImplTest.java
trunk/step/step-core/src/test/java/com/tyndalehouse/step/core/service/impl/UserDataServiceImplTest.java
trunk/step/step-web/src/main/java/com/tyndalehouse/step/guice/WebContextModule.java
trunk/step/step-web/src/main/java/com/tyndalehouse/step/guice/providers/
trunk/step/step-web/src/main/java/com/tyndalehouse/step/guice/providers/ClientSessionProvider.java
trunk/step/step-web/src/main/java/com/tyndalehouse/step/models/
trunk/step/step-web/src/main/java/com/tyndalehouse/step/models/ClientOperation.java
trunk/step/step-web/src/main/java/com/tyndalehouse/step/models/WebSessionImpl.java
trunk/step/step-web/src/main/java/com/tyndalehouse/step/rest/controllers/BookmarkController.java
trunk/step/step-web/src/main/java/com/tyndalehouse/step/rest/controllers/UserController.java
trunk/step/step-web/src/main/java/com/tyndalehouse/step/rest/framework/ClientErrorResolver.java
trunk/step/step-web/src/main/java/com/tyndalehouse/step/rest/framework/ClientHandledIssue.java
trunk/step/step-web/src/main/webapp/js/login.js
Removed:
trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/xsl/IPSample.java
trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/xsl/XsltProviders.java
Modified:
trunk/step/step-build/src/main/resources/checkstyle/checkstyle.xml
trunk/step/step-build/src/main/resources/eclipse/pmd.xml
trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/data/create/Loader.java
trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/data/create/TimelineModuleLoader.java
trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/guice/StepCoreModule.java
trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/guice/providers/DatabaseConfigProvider.java
trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/service/impl/JSwordServiceImpl.java
trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/service/impl/TimelineServiceImpl.java
trunk/step/step-core/src/main/resources/step.core.properties
trunk/step/step-core/src/test/java/com/tyndalehouse/step/core/data/create/DataTest.java
trunk/step/step-core/src/test/java/com/tyndalehouse/step/core/service/JSwordServiceImplTest.java
trunk/step/step-parent/pom.xml
trunk/step/step-web/src/main/java/com/tyndalehouse/step/guice/StepServletConfig.java
trunk/step/step-web/src/main/java/com/tyndalehouse/step/rest/controllers/FrontController.java
trunk/step/step-web/src/main/resources/log4j.properties
trunk/step/step-web/src/main/webapp/css/initial-fonts.css
trunk/step/step-web/src/main/webapp/css/initial-layout.css
trunk/step/step-web/src/main/webapp/css/passage.css
trunk/step/step-web/src/main/webapp/index.jsp
trunk/step/step-web/src/main/webapp/js/bookmark.js
trunk/step/step-web/src/main/webapp/js/init.js
trunk/step/step-web/src/main/webapp/js/ui_hooks.js
trunk/step/step-web/src/main/webapp/js/util.js
trunk/step/step-web/src/main/webapp/topmenu.html
trunk/step/step-web/src/test/java/com/tyndalehouse/step/rest/controllers/FrontControllerTest.java
trunk/step/step-web/src/test/java/com/tyndalehouse/step/rest/framework/StepRequestTest.java
Log:
Modified: trunk/step/step-build/src/main/resources/checkstyle/checkstyle.xml
===================================================================
--- trunk/step/step-build/src/main/resources/checkstyle/checkstyle.xml 2011-03-06 21:17:37 UTC (rev 218)
+++ trunk/step/step-build/src/main/resources/checkstyle/checkstyle.xml 2011-03-19 09:53:18 UTC (rev 219)
@@ -172,7 +172,8 @@
<module name="CyclomaticComplexity"/>
<module name="ArrayTypeStyle"/>
<module name="FinalParameters"/>
- <module name="Indentation"/>
+ <!-- this should be covered by eclipse's reformatter profile
+ <module name="Indentation"/> -->
<module name="TodoComment"/>
<module name="TrailingComment"/>
<module name="UncommentedMain"/>
Modified: trunk/step/step-build/src/main/resources/eclipse/pmd.xml
===================================================================
--- trunk/step/step-build/src/main/resources/eclipse/pmd.xml 2011-03-06 21:17:37 UTC (rev 218)
+++ trunk/step/step-build/src/main/resources/eclipse/pmd.xml 2011-03-19 09:53:18 UTC (rev 219)
@@ -360,10 +360,6 @@
<ruleset>Design Rules</ruleset>
</rule>
<rule>
- <name>AvoidSynchronizedAtMethodLevel</name>
- <ruleset>Design Rules</ruleset>
- </rule>
- <rule>
<name>MissingBreakInSwitch</name>
<ruleset>Design Rules</ruleset>
</rule>
@@ -736,10 +732,6 @@
<ruleset>Optimization Rules</ruleset>
</rule>
<rule>
- <name>MethodReturnsInternalArray</name>
- <ruleset>Security Code Guidelines</ruleset>
- </rule>
- <rule>
<name>ArrayIsStoredDirectly</name>
<ruleset>Security Code Guidelines</ruleset>
</rule>
Modified: trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/data/create/Loader.java
===================================================================
--- trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/data/create/Loader.java 2011-03-06 21:17:37 UTC (rev 218)
+++ trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/data/create/Loader.java 2011-03-19 09:53:18 UTC (rev 219)
@@ -6,7 +6,7 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import com.avaje.ebean.Ebean;
+import com.avaje.ebean.EbeanServer;
import com.avaje.ebean.Transaction;
import com.google.inject.Inject;
import com.tyndalehouse.step.core.data.entities.ScriptureReference;
@@ -21,16 +21,18 @@
private static final int BATCH_SIZE = 1000;
private static final Logger LOG = LoggerFactory.getLogger(Loader.class);
private final TimelineModuleLoader timelineModuleLoader;
+ private final EbeanServer ebean;
/**
* The loader is given a connection source to load the data
*
* @param timelineModuleLoader loader that loads the timeline module
+ * @param ebean the persistence server
*/
@Inject
- public Loader(final TimelineModuleLoader timelineModuleLoader) {
+ public Loader(final EbeanServer ebean, final TimelineModuleLoader timelineModuleLoader) {
+ this.ebean = ebean;
this.timelineModuleLoader = timelineModuleLoader;
- // this.scriptureReferenceDao = scriptureReferenceDao;
}
/**
@@ -45,19 +47,20 @@
*/
private void loadData() {
LOG.debug("Loading initial data");
- final Transaction transaction = Ebean.beginTransaction();
+ final Transaction transaction = this.ebean.beginTransaction();
try {
transaction.setBatchMode(true);
transaction.setBatchSize(BATCH_SIZE);
transaction.setReadOnly(false);
+
// set up a list of scripture references that can be populated as we populate the database
final List<ScriptureReference> scriptureReferences = new ArrayList<ScriptureReference>();
this.timelineModuleLoader.init(scriptureReferences);
- Ebean.save(scriptureReferences);
- Ebean.commitTransaction();
+ this.ebean.save(scriptureReferences);
+ this.ebean.commitTransaction();
} finally {
- Ebean.endTransaction();
+ this.ebean.endTransaction();
}
}
}
Modified: trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/data/create/TimelineModuleLoader.java
===================================================================
--- trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/data/create/TimelineModuleLoader.java 2011-03-06 21:17:37 UTC (rev 218)
+++ trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/data/create/TimelineModuleLoader.java 2011-03-19 09:53:18 UTC (rev 219)
@@ -18,7 +18,8 @@
import au.com.bytecode.opencsv.CSVReader;
-import com.avaje.ebean.Ebean;
+import com.avaje.ebean.EbeanServer;
+import com.google.inject.Inject;
import com.tyndalehouse.step.core.data.common.PartialDate;
import com.tyndalehouse.step.core.data.common.PrecisionType;
import com.tyndalehouse.step.core.data.entities.HotSpot;
@@ -54,8 +55,19 @@
// CHECKSTYLE:ON
private static final Logger LOG = LoggerFactory.getLogger(TimelineModuleLoader.class);
+ private final EbeanServer ebean;
/**
+ * we need to persist object through an orm
+ *
+ * @param ebean the persistence server
+ */
+ @Inject
+ public TimelineModuleLoader(final EbeanServer ebean) {
+ this.ebean = ebean;
+ }
+
+ /**
* loads up the timeline data
*
* @param scriptureReferences the scripture references that might be found as part of the loading
@@ -69,7 +81,7 @@
scriptureReferences);
// finally persist to database
- Ebean.save(timelineEvents);
+ this.ebean.save(timelineEvents);
}
Added: trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/data/entities/Bookmark.java
===================================================================
--- trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/data/entities/Bookmark.java (rev 0)
+++ trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/data/entities/Bookmark.java 2011-03-19 09:53:18 UTC (rev 219)
@@ -0,0 +1,70 @@
+package com.tyndalehouse.step.core.data.entities;
+
+import javax.persistence.CascadeType;
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.Id;
+import javax.persistence.ManyToOne;
+
+/**
+ * A user may have multiple bookmarks
+ *
+ * @author Chris
+ *
+ */
+ at Entity
+public class Bookmark {
+ @Id
+ @GeneratedValue
+ private Integer id;
+
+ @Column
+ private String bookmarkReference;
+
+ @ManyToOne(cascade = CascadeType.PERSIST)
+ @Column
+ private User user;
+
+ /**
+ * @return the id
+ */
+ public Integer getId() {
+ return this.id;
+ }
+
+ /**
+ * @param id the id to set
+ */
+ public void setId(final Integer id) {
+ this.id = id;
+ }
+
+ /**
+ * @return the bookmarkReference
+ */
+ public String getBookmarkReference() {
+ return this.bookmarkReference;
+ }
+
+ /**
+ * @param bookmarkReference the bookmarkReference to set
+ */
+ public void setBookmarkReference(final String bookmarkReference) {
+ this.bookmarkReference = bookmarkReference;
+ }
+
+ /**
+ * @return the user
+ */
+ public User getUser() {
+ return this.user;
+ }
+
+ /**
+ * @param user the user to set
+ */
+ public void setUser(final User user) {
+ this.user = user;
+ }
+}
Property changes on: trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/data/entities/Bookmark.java
___________________________________________________________________
Added: svn:mime-type
+ text/plain
Added: trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/data/entities/Session.java
===================================================================
--- trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/data/entities/Session.java (rev 0)
+++ trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/data/entities/Session.java 2011-03-19 09:53:18 UTC (rev 219)
@@ -0,0 +1,110 @@
+package com.tyndalehouse.step.core.data.entities;
+
+import java.util.Date;
+
+import javax.persistence.CascadeType;
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.Id;
+import javax.persistence.ManyToOne;
+import javax.persistence.Temporal;
+import javax.persistence.TemporalType;
+
+/**
+ * TODO add job to clean up old sessions that have expired A session is associated with a user and may or may
+ * not be active (expiresOn value) A user may be logged in multiple times and hence have several sessions.
+ *
+ * @author Chris
+ *
+ */
+ at Entity
+public class Session {
+ @Id
+ @GeneratedValue
+ private Integer id;
+
+ @Column
+ private String jSessionId;
+
+ @ManyToOne(cascade = CascadeType.PERSIST)
+ @Column
+ private User user;
+
+ @Column
+ private String ipAddress;
+
+ @Temporal(TemporalType.TIMESTAMP)
+ @Column
+ private Date expiresOn;
+
+ /**
+ * @return the id
+ */
+ public Integer getId() {
+ return this.id;
+ }
+
+ /**
+ * @param id the id to set
+ */
+ public void setId(final Integer id) {
+ this.id = id;
+ }
+
+ /**
+ * @return the jSessionId
+ */
+ public String getJSessionId() {
+ return this.jSessionId;
+ }
+
+ /**
+ * @param jSessionId the jSessionId to set
+ */
+ public void setJSessionId(final String jSessionId) {
+ this.jSessionId = jSessionId;
+ }
+
+ /**
+ * @return the user
+ */
+ public User getUser() {
+ return this.user;
+ }
+
+ /**
+ * @param user the user to set
+ */
+ public void setUser(final User user) {
+ this.user = user;
+ }
+
+ /**
+ * @return the expiresOn
+ */
+ public Date getExpiresOn() {
+ return this.expiresOn;
+ }
+
+ /**
+ * @param expiresOn the expiresOn to set
+ */
+ public void setExpiresOn(final Date expiresOn) {
+ this.expiresOn = expiresOn;
+ }
+
+ /**
+ * @return the ipAddress
+ */
+ public String getIpAddress() {
+ return this.ipAddress;
+ }
+
+ /**
+ * @param ipAddress the ipAddress to set
+ */
+ public void setIpAddress(final String ipAddress) {
+ this.ipAddress = ipAddress;
+ }
+}
Property changes on: trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/data/entities/Session.java
___________________________________________________________________
Added: svn:mime-type
+ text/plain
Added: trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/data/entities/User.java
===================================================================
--- trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/data/entities/User.java (rev 0)
+++ trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/data/entities/User.java 2011-03-19 09:53:18 UTC (rev 219)
@@ -0,0 +1,101 @@
+package com.tyndalehouse.step.core.data.entities;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.Id;
+
+/**
+ * represents a user entity. A user contains a username and password.
+ *
+ * @author Chris
+ *
+ */
+ at Entity
+public class User {
+ @Id
+ @GeneratedValue
+ private Integer id;
+
+ @Column
+ private String name;
+
+ @Column
+ private String password;
+
+ @Column
+ private String emailAddress;
+
+ @Column
+ private String country;
+
+ /**
+ * @return the id
+ */
+ public Integer getId() {
+ return this.id;
+ }
+
+ /**
+ * @param id the id to set
+ */
+ public void setId(final Integer id) {
+ this.id = id;
+ }
+
+ /**
+ * @return the password
+ */
+ public String getPassword() {
+ return this.password;
+ }
+
+ /**
+ * @param password the password to set
+ */
+ public void setPassword(final String password) {
+ this.password = password;
+ }
+
+ /**
+ * @return the name
+ */
+ public String getName() {
+ return this.name;
+ }
+
+ /**
+ * @param name the name to set
+ */
+ public void setName(final String name) {
+ this.name = name;
+ }
+
+ /**
+ * @return the emailAddress
+ */
+ public String getEmailAddress() {
+ return this.emailAddress;
+ }
+
+ /**
+ * @param emailAddress the emailAddress to set
+ */
+ public void setEmailAddress(final String emailAddress) {
+ this.emailAddress = emailAddress;
+ }
+
+ /**
+ * @return the country
+ */
+ public String getCountry() {
+ return this.country;
+ }
+
+ /**
+ * @param country the country to set
+ */
+ public void setCountry(final String country) {
+ this.country = country;
+ }
+}
Property changes on: trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/data/entities/User.java
___________________________________________________________________
Added: svn:mime-type
+ text/plain
Added: trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/data/entities/readme.txt
===================================================================
--- trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/data/entities/readme.txt (rev 0)
+++ trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/data/entities/readme.txt 2011-03-19 09:53:18 UTC (rev 219)
@@ -0,0 +1,2 @@
+Entities currently need to be added to
+com.tyndalehouse.step.core.guice.providers.DatabaseConfigProvider.addEntities(ServerConfig)
\ No newline at end of file
Property changes on: trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/data/entities/readme.txt
___________________________________________________________________
Added: svn:mime-type
+ text/plain
Added: trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/exceptions/RequiresLoginException.java
===================================================================
--- trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/exceptions/RequiresLoginException.java (rev 0)
+++ trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/exceptions/RequiresLoginException.java 2011-03-19 09:53:18 UTC (rev 219)
@@ -0,0 +1,30 @@
+package com.tyndalehouse.step.core.exceptions;
+
+/**
+ * The default exception to be thrown when a feature is unavailable because authentication is required.
+ *
+ * @author Chris
+ *
+ */
+public class RequiresLoginException extends ValidationException {
+ private static final long serialVersionUID = 2447731047608723592L;
+
+ /**
+ * creates the exception
+ *
+ * @param message the message for the exception
+ * @param t the cause of the exception
+ */
+ public RequiresLoginException(final String message, final Throwable t) {
+ super(message, t);
+ }
+
+ /**
+ * creates the exception
+ *
+ * @param message the message
+ */
+ public RequiresLoginException(final String message) {
+ super(message);
+ }
+}
Property changes on: trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/exceptions/RequiresLoginException.java
___________________________________________________________________
Added: svn:mime-type
+ text/plain
Added: trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/exceptions/ValidationException.java
===================================================================
--- trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/exceptions/ValidationException.java (rev 0)
+++ trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/exceptions/ValidationException.java 2011-03-19 09:53:18 UTC (rev 219)
@@ -0,0 +1,32 @@
+package com.tyndalehouse.step.core.exceptions;
+
+/**
+ * The default exception to be thrown throughout the application when a validation exception has occurred. It
+ * is of type {@link StepInternal} so that it does not require explicit catching
+ *
+ * @author Chris
+ *
+ */
+public class ValidationException extends StepInternalException {
+ private static final long serialVersionUID = -5636677138385910988L;
+
+ /**
+ * creates the generic validation exception to be used on the server. These can be handled separately to @see
+ * {StepInternalException}
+ *
+ * @param message the message for the exception
+ * @param t the cause of the exception
+ */
+ public ValidationException(final String message, final Throwable t) {
+ super(message, t);
+ }
+
+ /**
+ * creates the generic runtime exception to be used on the server
+ *
+ * @param message the message
+ */
+ public ValidationException(final String message) {
+ super(message);
+ }
+}
Property changes on: trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/exceptions/ValidationException.java
___________________________________________________________________
Added: svn:mime-type
+ text/plain
Modified: trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/guice/StepCoreModule.java
===================================================================
--- trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/guice/StepCoreModule.java 2011-03-06 21:17:37 UTC (rev 218)
+++ trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/guice/StepCoreModule.java 2011-03-19 09:53:18 UTC (rev 219)
@@ -10,22 +10,28 @@
import com.avaje.ebean.EbeanServer;
import com.google.inject.AbstractModule;
-import com.google.inject.Module;
import com.google.inject.TypeLiteral;
import com.google.inject.name.Names;
import com.tyndalehouse.step.core.data.create.Loader;
+import com.tyndalehouse.step.core.data.entities.Session;
import com.tyndalehouse.step.core.guice.providers.DatabaseConfigProvider;
import com.tyndalehouse.step.core.guice.providers.DefaultInstallersProvider;
import com.tyndalehouse.step.core.guice.providers.DefaultLexiconRefsProvider;
import com.tyndalehouse.step.core.guice.providers.DefaultVersionsProvider;
+import com.tyndalehouse.step.core.guice.providers.ServerSessionProvider;
+import com.tyndalehouse.step.core.guice.providers.TestData;
import com.tyndalehouse.step.core.service.BibleInformationService;
+import com.tyndalehouse.step.core.service.BookmarkService;
import com.tyndalehouse.step.core.service.JSwordService;
import com.tyndalehouse.step.core.service.ModuleService;
import com.tyndalehouse.step.core.service.TimelineService;
+import com.tyndalehouse.step.core.service.UserDataService;
import com.tyndalehouse.step.core.service.impl.BibleInformationServiceImpl;
+import com.tyndalehouse.step.core.service.impl.BookmarkServiceImpl;
import com.tyndalehouse.step.core.service.impl.JSwordServiceImpl;
import com.tyndalehouse.step.core.service.impl.ModuleServiceImpl;
import com.tyndalehouse.step.core.service.impl.TimelineServiceImpl;
+import com.tyndalehouse.step.core.service.impl.UserDataServiceImpl;
/**
* The module configuration that configures the application via guice
@@ -33,19 +39,24 @@
* @author Chris
*
*/
-public class StepCoreModule extends AbstractModule implements Module {
+public class StepCoreModule extends AbstractModule {
private static final String CORE_GUICE_PROPERTIES = "/step.core.properties";
@Override
protected void configure() {
- bind(Properties.class).annotatedWith(Names.named("StepCoreProperties")).toInstance(readProperties());
+ final Properties stepProperties = readProperties();
+ bind(Properties.class).annotatedWith(Names.named("StepCoreProperties")).toInstance(stepProperties);
bind(JSwordService.class).to(JSwordServiceImpl.class).asEagerSingleton();
bind(BibleInformationService.class).to(BibleInformationServiceImpl.class).asEagerSingleton();
bind(ModuleService.class).to(ModuleServiceImpl.class).asEagerSingleton();
bind(TimelineService.class).to(TimelineServiceImpl.class);
+ bind(BookmarkService.class).to(BookmarkServiceImpl.class);
+ bind(UserDataService.class).to(UserDataServiceImpl.class);
bind(Loader.class);
+ bind(Session.class).toProvider(ServerSessionProvider.class);
+
bind(new TypeLiteral<List<String>>() {
}).annotatedWith(Names.named("defaultVersions")).toProvider(DefaultVersionsProvider.class);
bind(new TypeLiteral<Map<String, String>>() {
@@ -56,7 +67,11 @@
bind(EbeanServer.class).toProvider(DatabaseConfigProvider.class).asEagerSingleton();
bindDaos();
- // bind(ConnectionSource.class).toProvider(DataSourceProvider.class);
+
+ // now bind the test data
+ if (Boolean.valueOf(stepProperties.getProperty("test.data.load"))) {
+ bind(TestData.class).asEagerSingleton();
+ }
}
/**
Modified: trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/guice/providers/DatabaseConfigProvider.java
===================================================================
--- trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/guice/providers/DatabaseConfigProvider.java 2011-03-06 21:17:37 UTC (rev 218)
+++ trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/guice/providers/DatabaseConfigProvider.java 2011-03-19 09:53:18 UTC (rev 219)
@@ -8,11 +8,14 @@
import com.google.inject.Inject;
import com.google.inject.Provider;
import com.google.inject.name.Named;
+import com.tyndalehouse.step.core.data.entities.Bookmark;
import com.tyndalehouse.step.core.data.entities.HotSpot;
import com.tyndalehouse.step.core.data.entities.ScriptureReference;
import com.tyndalehouse.step.core.data.entities.ScriptureTarget;
+import com.tyndalehouse.step.core.data.entities.Session;
import com.tyndalehouse.step.core.data.entities.Timeband;
import com.tyndalehouse.step.core.data.entities.TimelineEvent;
+import com.tyndalehouse.step.core.data.entities.User;
/**
* Returns a database connection server instance for use across the application
@@ -112,6 +115,9 @@
config.addClass(TimelineEvent.class);
config.addClass(ScriptureTarget.class);
config.addClass(ScriptureReference.class);
+ config.addClass(User.class);
+ config.addClass(Session.class);
+ config.addClass(Bookmark.class);
}
}
Added: trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/guice/providers/ServerSessionProvider.java
===================================================================
--- trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/guice/providers/ServerSessionProvider.java (rev 0)
+++ trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/guice/providers/ServerSessionProvider.java 2011-03-19 09:53:18 UTC (rev 219)
@@ -0,0 +1,53 @@
+package com.tyndalehouse.step.core.guice.providers;
+
+import com.avaje.ebean.EbeanServer;
+import com.google.inject.Inject;
+import com.google.inject.Provider;
+import com.google.inject.Singleton;
+import com.tyndalehouse.step.core.data.entities.Session;
+import com.tyndalehouse.step.core.models.ClientSession;
+import com.tyndalehouse.step.core.service.UserDataService;
+
+/**
+ * A server session provider
+ *
+ * @author Chris
+ *
+ */
+ at Singleton
+public class ServerSessionProvider implements Provider<Session> {
+ // we store the provider, since the provider is request-scoped and therefore
+ // values vary
+ private final Provider<ClientSession> clientSessionProvider;
+ private final EbeanServer ebean;
+ private final UserDataService userDataService;
+
+ /**
+ * Sets up a singleton provider that relies upon a request-scoped clientSessionProvider.
+ *
+ * @param ebean the ebean server used to retrieve data
+ * @param clientSessionProvider the client session provider, giving us an id to reference
+ * @param userDataService a service for user and session management
+ */
+ @Inject
+ public ServerSessionProvider(final EbeanServer ebean,
+ final Provider<ClientSession> clientSessionProvider, final UserDataService userDataService) {
+ this.ebean = ebean;
+ this.clientSessionProvider = clientSessionProvider;
+ this.userDataService = userDataService;
+ }
+
+ @Override
+ public Session get() {
+ final String clientSessionId = this.clientSessionProvider.get().getSessionId();
+ final Session serverSession = this.ebean.find(Session.class).where()
+ .eq("jSessionId", clientSessionId).findUnique();
+
+ if (serverSession == null) {
+ // we create a server session
+ return this.userDataService.createSession();
+ }
+
+ return serverSession;
+ }
+}
Property changes on: trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/guice/providers/ServerSessionProvider.java
___________________________________________________________________
Added: svn:mime-type
+ text/plain
Added: trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/guice/providers/TestData.java
===================================================================
--- trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/guice/providers/TestData.java (rev 0)
+++ trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/guice/providers/TestData.java 2011-03-19 09:53:18 UTC (rev 219)
@@ -0,0 +1,59 @@
+package com.tyndalehouse.step.core.guice.providers;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import com.avaje.ebean.EbeanServer;
+import com.avaje.ebean.Transaction;
+import com.google.inject.Inject;
+import com.google.inject.Singleton;
+import com.tyndalehouse.step.core.data.entities.Bookmark;
+import com.tyndalehouse.step.core.data.entities.User;
+
+/**
+ * Provides test data if necessary
+ *
+ * @author Chris
+ *
+ */
+ at Singleton
+public class TestData {
+ private final EbeanServer ebean;
+
+ /**
+ * @param ebean the ebean server to persist objects with
+ */
+ @Inject
+ public TestData(final EbeanServer ebean) {
+ this.ebean = ebean;
+ createBookmarks();
+ }
+
+ /**
+ * creates the bookmarks
+ */
+ private void createBookmarks() {
+ final User u = new User();
+ u.setEmailAddress("t at t.c");
+ u.setName("Mr Test");
+ u.setPassword("password");
+
+ final List<Bookmark> bookmarks = new ArrayList<Bookmark>();
+ final Bookmark b1 = new Bookmark();
+ b1.setBookmarkReference("Acts 2:7-20");
+ b1.setUser(u);
+
+ final Bookmark b2 = new Bookmark();
+ b2.setBookmarkReference("Acts 7:1-20");
+ b2.setUser(u);
+
+ bookmarks.add(b1);
+ bookmarks.add(b2);
+
+ final Transaction tx = this.ebean.beginTransaction();
+ tx.setBatchMode(true);
+ this.ebean.save(bookmarks);
+ tx.commit();
+ this.ebean.endTransaction();
+ }
+}
Property changes on: trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/guice/providers/TestData.java
___________________________________________________________________
Added: svn:mime-type
+ text/plain
Added: trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/models/ClientSession.java
===================================================================
--- trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/models/ClientSession.java (rev 0)
+++ trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/models/ClientSession.java 2011-03-19 09:53:18 UTC (rev 219)
@@ -0,0 +1,23 @@
+package com.tyndalehouse.step.core.models;
+
+/**
+ * At the moment, the "Client Session" object just wraps around an id.
+ *
+ * @author Chris
+ *
+ */
+public interface ClientSession {
+ /**
+ * an identifier to the client session
+ *
+ * @return the session id
+ */
+ String getSessionId();
+
+ /**
+ * return the IP address that the user is currently coming in on
+ *
+ * @return the IP address
+ */
+ String getIpAddress();
+}
Property changes on: trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/models/ClientSession.java
___________________________________________________________________
Added: svn:mime-type
+ text/plain
Added: trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/service/BookmarkService.java
===================================================================
--- trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/service/BookmarkService.java (rev 0)
+++ trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/service/BookmarkService.java 2011-03-19 09:53:18 UTC (rev 219)
@@ -0,0 +1,36 @@
+package com.tyndalehouse.step.core.service;
+
+import java.util.List;
+
+import com.tyndalehouse.step.core.data.entities.Bookmark;
+
+/**
+ * A service to add, remove bookmarks
+ *
+ * @author Chris
+ *
+ */
+public interface BookmarkService {
+ /**
+ * gets a set of bookmarks associated with the current session
+ *
+ * @return a list of bookmarks
+ */
+ List<Bookmark> getBookmarks();
+
+ /**
+ * Removes a bookmark, using the current session-ed and logged on user
+ *
+ * @param bookmarkId the bookmark id to use.
+ */
+ void removeBookmark(int bookmarkId);
+
+ /**
+ * Adds a bookmark if not already there
+ *
+ * @param reference the reference to add to the bookmark
+ * @return the id of the bookmark that was added
+ */
+ int addBookmark(String reference);
+
+}
Property changes on: trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/service/BookmarkService.java
___________________________________________________________________
Added: svn:mime-type
+ text/plain
Added: trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/service/UserDataService.java
===================================================================
--- trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/service/UserDataService.java (rev 0)
+++ trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/service/UserDataService.java 2011-03-19 09:53:18 UTC (rev 219)
@@ -0,0 +1,56 @@
+package com.tyndalehouse.step.core.service;
+
+import com.tyndalehouse.step.core.data.entities.Session;
+import com.tyndalehouse.step.core.data.entities.User;
+
+/**
+ * This service gives information about the user, allows his to register, does session management, etc.
+ *
+ * <p />
+ * Firstly, createSession() is called to register the server session. This is an anonymous session but helps
+ * us keep track of concurrent users. We can possibly run a job on the server version to do some stats on the
+ * ip addresses that we log.
+ *
+ * Secondly, we expect the user might want to register to access some specific features (notes, bookmarks)
+ *
+ * Thirdly, we expect a user to login with his [email/password] combo.
+ *
+ * Fourthly, we can access everything through the session, without need for username, etc.
+ *
+ * @author Chris
+ *
+ */
+public interface UserDataService {
+
+ /**
+ * Registers and stores the user details.
+ *
+ * @param emailAddress the email address
+ * @param name the name of the person [optional]
+ * @param country his country [optional]
+ * @param password the password he has chosen, which we should SHA-1 and salt
+ */
+ void register(String emailAddress, String name, String country, String password);
+
+ /**
+ * TODO move this to session provider This method is called to create a session for the user. This will
+ * associate the jsession id with a new row in the Session table.
+ *
+ * @return the server session that was created
+ */
+ Session createSession();
+
+ /**
+ * Associates the current session with the username assuming password and username authenticates
+ *
+ * @param emailAddress the email address is used as the login token
+ * @param password the password
+ * @return the user that has logged in
+ */
+ User login(String emailAddress, String password);
+
+ /**
+ * logs the current user out
+ */
+ void logout();
+}
Property changes on: trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/service/UserDataService.java
___________________________________________________________________
Added: svn:mime-type
+ text/plain
Added: trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/service/impl/BookmarkServiceImpl.java
===================================================================
--- trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/service/impl/BookmarkServiceImpl.java (rev 0)
+++ trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/service/impl/BookmarkServiceImpl.java 2011-03-19 09:53:18 UTC (rev 219)
@@ -0,0 +1,86 @@
+package com.tyndalehouse.step.core.service.impl;
+
+import static com.avaje.ebean.Expr.eq;
+
+import java.util.List;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.avaje.ebean.EbeanServer;
+import com.google.inject.Inject;
+import com.google.inject.Provider;
+import com.google.inject.Singleton;
+import com.tyndalehouse.step.core.data.entities.Bookmark;
+import com.tyndalehouse.step.core.data.entities.Session;
+import com.tyndalehouse.step.core.data.entities.User;
+import com.tyndalehouse.step.core.exceptions.RequiresLoginException;
+import com.tyndalehouse.step.core.service.BookmarkService;
+
+/**
+ * An implementation of the bookmark
+ *
+ * @author Chris
+ *
+ */
+ at Singleton
+public class BookmarkServiceImpl implements BookmarkService {
+ private static final String USER_FIELD = "user";
+ private static final Logger LOG = LoggerFactory.getLogger(BookmarkServiceImpl.class);
+ private final Provider<Session> serverSession;
+ private final EbeanServer ebean;
+
+ /**
+ *
+ * @param ebean the ebean server for retrieving and persisting
+ * @param serverSession the server session provider
+ */
+ @Inject
+ public BookmarkServiceImpl(final EbeanServer ebean, final Provider<Session> serverSession) {
+ this.ebean = ebean;
+ this.serverSession = serverSession;
+
+ }
+
+ @Override
+ public List<Bookmark> getBookmarks() {
+ // perhaps this could be made more efficient
+ // TODO we need to add some ordering on this somewhere!
+ // TODO push to a library for reuse elsewhere as some validation utils
+ final User user = this.serverSession.get().getUser();
+ if (user == null) {
+ // the user is not logged in
+ throw new RequiresLoginException("You will need to login to access this functionality");
+ }
+
+ return this.ebean.find(Bookmark.class).select("id, bookmarkReference").where().eq(USER_FIELD, user)
+ .findList();
+ }
+
+ @Override
+ public void removeBookmark(final int bookmarkId) {
+ this.ebean.delete(Bookmark.class, Integer.valueOf(bookmarkId));
+ }
+
+ @Override
+ public int addBookmark(final String reference) {
+ // first we check that the bookmark doesn't exist, then we insert it
+ final User currentUser = this.serverSession.get().getUser();
+
+ final List<Bookmark> bookmarks = this.ebean.find(Bookmark.class).where()
+ .and(eq("bookmarkReference", reference), eq(USER_FIELD, currentUser)).findList();
+
+ // no bookmark? then create!
+ if (bookmarks.size() == 0) {
+ final Bookmark b = new Bookmark();
+ b.setUser(currentUser);
+ b.setBookmarkReference(reference);
+ this.ebean.save(b);
+ return b.getId();
+ }
+
+ // bookmark already exists, just return the bookmark id and warn
+ LOG.warn("This is already a bookmark in the list");
+ return bookmarks.get(0).getId();
+ }
+}
Property changes on: trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/service/impl/BookmarkServiceImpl.java
___________________________________________________________________
Added: svn:mime-type
+ text/plain
Modified: trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/service/impl/JSwordServiceImpl.java
===================================================================
--- trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/service/impl/JSwordServiceImpl.java 2011-03-06 21:17:37 UTC (rev 218)
+++ trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/service/impl/JSwordServiceImpl.java 2011-03-19 09:53:18 UTC (rev 219)
@@ -66,7 +66,6 @@
* @param bibleCategory the categories of books that should be considered
* @return returns a list of installed modules
*/
- @SuppressWarnings("unchecked")
public List<Book> getInstalledModules(final BookCategory... bibleCategory) {
if (bibleCategory == null || bibleCategory.length == 0) {
return new ArrayList<Book>();
@@ -91,7 +90,6 @@
* @param bibleCategory the list of books that should be considered
* @return a list of all modules
*/
- @SuppressWarnings("unchecked")
public List<Book> getAllModules(final BookCategory... bibleCategory) {
final List<Book> books = new ArrayList<Book>();
for (final Installer installer : this.bookInstallers) {
@@ -112,9 +110,10 @@
return getOsisText(version, reference, options, null);
}
+ // TODO remove synchronisation once book is fixed
@Override
- public synchronized String getOsisText(final String version, final String reference, final List<LookupOption> options,
- final String interlinearVersion) {
+ public synchronized String getOsisText(final String version, final String reference,
+ final List<LookupOption> options, final String interlinearVersion) {
LOGGER.debug("Retrieving text for ({}, {})", version, reference);
try {
@@ -179,8 +178,6 @@
* @return the stylesheet (of stylesheets)
*/
private XslConversionType identifyStyleSheet(final List<LookupOption> options) {
- final Set<XslConversionType> chosenOptions = new HashSet<XslConversionType>();
-
for (final LookupOption lo : options) {
if (!XslConversionType.DEFAULT.equals(lo.getStylesheet())) {
return lo.getStylesheet();
@@ -293,7 +290,6 @@
LOGGER.warn("A request to install an already installed book was made for initials " + initials);
}
- @SuppressWarnings("unchecked")
@Override
public double getProgressOnInstallation(final String bookName) {
if (isBlank(bookName)) {
Modified: trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/service/impl/TimelineServiceImpl.java
===================================================================
--- trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/service/impl/TimelineServiceImpl.java 2011-03-06 21:17:37 UTC (rev 218)
+++ trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/service/impl/TimelineServiceImpl.java 2011-03-19 09:53:18 UTC (rev 219)
@@ -2,7 +2,8 @@
import java.util.List;
-import com.avaje.ebean.Ebean;
+import com.avaje.ebean.EbeanServer;
+import com.google.inject.Inject;
import com.google.inject.Singleton;
import com.tyndalehouse.step.core.data.entities.Timeband;
import com.tyndalehouse.step.core.service.TimelineService;
@@ -14,6 +15,16 @@
*/
@Singleton
public class TimelineServiceImpl implements TimelineService {
+ private final EbeanServer ebean;
+
+ /**
+ * @param ebean the ebean server with which to lookup data
+ */
+ @Inject
+ public TimelineServiceImpl(final EbeanServer ebean) {
+ this.ebean = ebean;
+ }
+
// private final Loader loader;
// /**
@@ -31,6 +42,6 @@
@Override
public List<Timeband> getTimelineConfiguration() {
- return Ebean.createQuery(Timeband.class).fetch("hotspots").findList();
+ return this.ebean.createQuery(Timeband.class).fetch("hotspots").findList();
}
}
Added: trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/service/impl/UserDataServiceImpl.java
===================================================================
--- trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/service/impl/UserDataServiceImpl.java (rev 0)
+++ trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/service/impl/UserDataServiceImpl.java 2011-03-19 09:53:18 UTC (rev 219)
@@ -0,0 +1,133 @@
+package com.tyndalehouse.step.core.service.impl;
+
+import static com.avaje.ebean.Expr.eq;
+
+import java.util.Calendar;
+import java.util.Date;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.avaje.ebean.EbeanServer;
+import com.google.inject.Inject;
+import com.google.inject.Provider;
+import com.google.inject.Singleton;
+import com.tyndalehouse.step.core.data.entities.Session;
+import com.tyndalehouse.step.core.data.entities.User;
+import com.tyndalehouse.step.core.exceptions.StepInternalException;
+import com.tyndalehouse.step.core.models.ClientSession;
+import com.tyndalehouse.step.core.service.UserDataService;
+
+/**
+ * An implementation of the user data service allowing us to register, login and create sessions. This class
+ * is injected with a guice provider which changes at runtime.
+ *
+ * The session allows us access to the user that is currently logged in. If no user is logged in then, we can
+ * register / login
+ *
+ */
+ at Singleton
+public class UserDataServiceImpl implements UserDataService {
+ private static final int EXPIRY_SESSION_INTERVAL = 30;
+ private static final Logger LOG = LoggerFactory.getLogger(UserDataServiceImpl.class);
+ private final Provider<Session> sessionProvider;
+ private final EbeanServer ebean;
+ private final Provider<ClientSession> clientSessionProvider;
+
+ /**
+ * sessions change at runtime based on which request we are serving
+ *
+ * @param ebean the ebean server to persist and load data
+ * @param sessionProvider the session provider
+ * @param clientSessionProvider the client session (cookie information + ip address)
+ */
+ @Inject
+ public UserDataServiceImpl(final EbeanServer ebean, final Provider<Session> sessionProvider,
+ final Provider<ClientSession> clientSessionProvider) {
+ this.ebean = ebean;
+ this.sessionProvider = sessionProvider;
+ this.clientSessionProvider = clientSessionProvider;
+ }
+
+ @Override
+ public void register(final String emailAddress, final String name, final String country,
+ final String password) {
+ // first check that are we not logged in!
+ Session session = this.sessionProvider.get();
+
+ // check we have a session, otherwise create one for ourselves (this should be catered
+ if (session == null || Calendar.getInstance().after(session.getExpiresOn())) {
+ // the session is either non-existent or exists but has expired, so recreate one:
+ createSession();
+ session = this.sessionProvider.get();
+ assert session != null;
+ }
+
+ if (session.getUser() != null) {
+ throw new IllegalArgumentException("You cannot register, as you are already logged in.");
+ }
+
+ // it is easy enough to register, just create a user and save to the database
+ final User u = new User();
+ u.setEmailAddress(emailAddress);
+ u.setName(name);
+ u.setCountry(country);
+ u.setPassword(password);
+
+ this.ebean.save(u);
+
+ // next, we just associate the current session with the user by logging in
+ this.login(emailAddress, password);
+ }
+
+ @Override
+ public Session createSession() {
+ // TODO we can't use subclassing on Android so remove in preference to enhancements
+ final Session session = this.ebean.createEntityBean(Session.class);
+ final ClientSession clientSession = this.clientSessionProvider.get();
+
+ // TODO we ensure that we expire the sessions after a while of inactivity
+ // so we will need to add a filter to ensure this actually happens.
+ // i.e. update the time of the session asynchronously if possible
+ // write a job that deletes expired sessions
+ // this also needs to match up with the value in the client session really
+ final Calendar expiryDate = Calendar.getInstance();
+ expiryDate.add(Calendar.DAY_OF_YEAR, EXPIRY_SESSION_INTERVAL);
+
+ session.setJSessionId(clientSession.getSessionId());
+ session.setIpAddress(clientSession.getIpAddress());
+ session.setExpiresOn(new Date(expiryDate.getTimeInMillis()));
+
+ LOG.debug("Persisting session (jSessionId=[{}],ip=[{}]", session.getJSessionId(),
+ session.getIpAddress());
+ this.ebean.save(session);
+ return session;
+ }
+
+ @Override
+ public User login(final String emailAddress, final String password) {
+ // logging in basically means associating the user with the session
+ final Session serverSession = this.sessionProvider.get();
+
+ final User user = this.ebean.find(User.class).select("id, name").where()
+ .and(eq("emailAddress", emailAddress), eq("password", password)).findUnique();
+
+ // couldn't authenticate?
+ if (user == null) {
+ throw new StepInternalException("Unable to login with username/password provided");
+ }
+
+ serverSession.setUser(user);
+
+ // saving the session
+ this.ebean.save(serverSession);
+
+ return user;
+ }
+
+ @Override
+ public void logout() {
+ // simply delete the session from the db
+ this.ebean.delete(this.sessionProvider.get());
+ }
+}
Property changes on: trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/service/impl/UserDataServiceImpl.java
___________________________________________________________________
Added: svn:mime-type
+ text/plain
Deleted: trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/xsl/IPSample.java
===================================================================
--- trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/xsl/IPSample.java 2011-03-06 21:17:37 UTC (rev 218)
+++ trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/xsl/IPSample.java 2011-03-19 09:53:18 UTC (rev 219)
@@ -1,7 +0,0 @@
-package com.tyndalehouse.step.core.xsl;
-
-public class IPSample {
- public String getWord(final Object o) {
- return "hello";
- }
-}
Deleted: trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/xsl/XsltProviders.java
===================================================================
--- trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/xsl/XsltProviders.java 2011-03-06 21:17:37 UTC (rev 218)
+++ trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/xsl/XsltProviders.java 2011-03-19 09:53:18 UTC (rev 219)
@@ -1,15 +0,0 @@
-package com.tyndalehouse.step.core.xsl;
-
-public enum XsltProviders {
- INTERLINEAR_PROVIDER("InterlinearProvider");
-
- private final String paramName;
-
- XsltProviders(final String paramName) {
- this.paramName = paramName;
- }
-
- public String getParamName() {
- return this.paramName;
- }
-}
Modified: trunk/step/step-core/src/main/resources/step.core.properties
===================================================================
--- trunk/step/step-core/src/main/resources/step.core.properties 2011-03-06 21:17:37 UTC (rev 218)
+++ trunk/step/step-core/src/main/resources/step.core.properties 2011-03-19 09:53:18 UTC (rev 219)
@@ -9,6 +9,9 @@
app.proxy.host=
app.proxy.port=
+#Test data related questions
+test.data.load=true
+
# Database parameters - these will vary depending on the connection
app.db.driver=org.h2.Driver
app.db.url=jdbc:h2:mem:step
Added: trunk/step/step-core/src/test/java/com/tyndalehouse/step/core/data/AbstractDataTest.java
===================================================================
--- trunk/step/step-core/src/test/java/com/tyndalehouse/step/core/data/AbstractDataTest.java (rev 0)
+++ trunk/step/step-core/src/test/java/com/tyndalehouse/step/core/data/AbstractDataTest.java 2011-03-19 09:53:18 UTC (rev 219)
@@ -0,0 +1,72 @@
+package com.tyndalehouse.step.core.data;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.BeforeClass;
+
+import com.avaje.ebean.EbeanServer;
+import com.google.inject.Guice;
+import com.google.inject.Injector;
+import com.tyndalehouse.step.core.data.create.DataTestModule;
+
+/**
+ * A simple data test that sets up the context and objects to be able to do persistence. TODO think about
+ * whethere the ebean server needs to be a new server each time by redoing the guice injector, we redo the
+ * server. could make static, but then tests interfere with each other
+ *
+ * @author Chris
+ *
+ */
+public abstract class AbstractDataTest {
+ private static volatile EbeanServer ebean;
+ private static volatile Injector injector;
+ private boolean runInTransaction = true;
+
+ /**
+ * sets up the tests correctly
+ */
+ @BeforeClass
+ public static synchronized void setupData() {
+ if (injector == null) {
+ injector = Guice.createInjector(new DataTestModule());
+ }
+ if (ebean == null) {
+ ebean = injector.getInstance(EbeanServer.class);
+ }
+ }
+
+ /**
+ * we ensure that tests are isolated by running them in a transaction
+ */
+ @Before
+ public void startTransaction() {
+ if (this.runInTransaction) {
+ ebean.beginTransaction();
+ }
+ }
+
+ /**
+ * each method should roll back what it does to ensure that is thread-safe and doesn't interfere with
+ * others
+ */
+ @After
+ public void rollbackTransaction() {
+ if (this.runInTransaction) {
+ ebean.endTransaction();
+ }
+ }
+
+ /**
+ * @return the ebean
+ */
+ public EbeanServer getEbean() {
+ return ebean;
+ }
+
+ /**
+ * @param runInTransaction the runInTransaction to set
+ */
+ public void setRunInTransaction(final boolean runInTransaction) {
+ this.runInTransaction = runInTransaction;
+ }
+}
Property changes on: trunk/step/step-core/src/test/java/com/tyndalehouse/step/core/data/AbstractDataTest.java
___________________________________________________________________
Added: svn:mime-type
+ text/plain
Modified: trunk/step/step-core/src/test/java/com/tyndalehouse/step/core/data/create/DataTest.java
===================================================================
--- trunk/step/step-core/src/test/java/com/tyndalehouse/step/core/data/create/DataTest.java 2011-03-06 21:17:37 UTC (rev 218)
+++ trunk/step/step-core/src/test/java/com/tyndalehouse/step/core/data/create/DataTest.java 2011-03-19 09:53:18 UTC (rev 219)
@@ -3,14 +3,12 @@
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
-import org.junit.BeforeClass;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import com.avaje.ebean.Ebean;
import com.avaje.ebean.SqlRow;
-import com.google.inject.Guice;
+import com.tyndalehouse.step.core.data.AbstractDataTest;
import com.tyndalehouse.step.core.data.entities.Timeband;
/**
@@ -19,15 +17,14 @@
* @author Chris
*
*/
-public class DataTest {
+public class DataTest extends AbstractDataTest {
private static final Logger LOG = LoggerFactory.getLogger(DataTest.class);
/**
- * sets up the tests correctly
+ * default constructor called by JUnit to create the test
*/
- @BeforeClass
- public static void setupData() {
- Guice.createInjector(new DataTestModule());
+ public DataTest() {
+ setRunInTransaction(false);
}
/**
@@ -36,7 +33,7 @@
@Test
public void testConnection() {
final String sql = "select count(*) as count from dual";
- final SqlRow row = Ebean.createSqlQuery(sql).findUnique();
+ final SqlRow row = getEbean().createSqlQuery(sql).findUnique();
final Integer i = row.getInteger("count");
assertEquals(i, Integer.valueOf(1));
@@ -48,13 +45,13 @@
*/
@Test
public void tryLoadingProcess() {
- final TimelineModuleLoader timelineLoaderModule = new TimelineModuleLoader();
- final Loader l = new Loader(timelineLoaderModule);
+ final TimelineModuleLoader timelineLoaderModule = new TimelineModuleLoader(getEbean());
+ final Loader l = new Loader(getEbean(), timelineLoaderModule);
l.init();
// we check that we entities in all three tables
- final Timeband timeband = Ebean.find(Timeband.class).fetch("hotspots.events").where().eq("id", 1)
- .findUnique();
+ final Timeband timeband = getEbean().find(Timeband.class).fetch("hotspots.events").where()
+ .eq("id", 1).findUnique();
assertNotNull(timeband);
assertNotNull(timeband.getHotspots());
@@ -62,20 +59,4 @@
assertNotNull(timeband.getHotspots().get(0).getEvents());
assertNotNull(timeband.getHotspots().get(0).getEvents().get(0).getSummary());
}
- // /**
- // * Tests the relational query builder
- // *
- // * @throws SQLException a SQL exception from the database
- // */
- // @Test
- // public void testRelationalBuilder() throws SQLException {
- // final HotSpotDao hotspotDao = new HotSpotDaoImpl(this.connectionSource);
- //
- // final PreparedQuery<HotSpot> preparedQuery = hotspotDao.getRelationalQueryBuilder().fetch("timeband")
- // .prepare();
- //
- // final List<HotSpot> hotspots = hotspotDao.query(preparedQuery);
- // assertNotNull(hotspots.get(0).getTimeband());
- // assertNotNull(hotspots.get(0).getTimeband().getCode());
- // }
}
Added: trunk/step/step-core/src/test/java/com/tyndalehouse/step/core/data/entities/UserTest.java
===================================================================
--- trunk/step/step-core/src/test/java/com/tyndalehouse/step/core/data/entities/UserTest.java (rev 0)
+++ trunk/step/step-core/src/test/java/com/tyndalehouse/step/core/data/entities/UserTest.java 2011-03-19 09:53:18 UTC (rev 219)
@@ -0,0 +1,31 @@
+package com.tyndalehouse.step.core.data.entities;
+
+import static org.junit.Assert.assertEquals;
+
+import org.junit.Test;
+
+import com.avaje.ebean.Ebean;
+import com.tyndalehouse.step.core.data.AbstractDataTest;
+
+/**
+ * tests that i can create a user - probably not going to do this for all entities
+ *
+ * @author Chris
+ *
+ */
+public class UserTest extends AbstractDataTest {
+ /**
+ * tests we can create a user
+ */
+ @Test
+ public void createUser() {
+ final User u = new User();
+ u.setEmailAddress("chrisburrell at test.com");
+ u.setName("Chris");
+ u.setPassword("password");
+
+ Ebean.save(u);
+ final User r = Ebean.find(User.class, u.getId());
+ assertEquals(u.getEmailAddress(), r.getEmailAddress());
+ }
+}
Property changes on: trunk/step/step-core/src/test/java/com/tyndalehouse/step/core/data/entities/UserTest.java
___________________________________________________________________
Added: svn:mime-type
+ text/plain
Modified: trunk/step/step-core/src/test/java/com/tyndalehouse/step/core/service/JSwordServiceImplTest.java
===================================================================
--- trunk/step/step-core/src/test/java/com/tyndalehouse/step/core/service/JSwordServiceImplTest.java 2011-03-06 21:17:37 UTC (rev 218)
+++ trunk/step/step-core/src/test/java/com/tyndalehouse/step/core/service/JSwordServiceImplTest.java 2011-03-19 09:53:18 UTC (rev 219)
@@ -105,55 +105,58 @@
* @throws BookException a book exception
* @throws InterruptedException when the thread is interrupted
*/
+ // TODO currently disabled
@Test
public void testConcurrencyIssueOnBookData() throws NoSuchKeyException, BookException,
InterruptedException {
- final String[] names = { "KJV", "ESV" };
- final String ref = "Rom.1.1";
-
- final Runnable r1 = new Runnable() {
- @Override
- public void run() {
- final Book b0 = Books.installed().getBook(names[0]);
- BookData bd1;
- try {
- bd1 = new BookData(b0, b0.getKey(ref));
- bd1.getSAXEventProvider();
- } catch (final NoSuchKeyException e) {
- e.printStackTrace();
- } catch (final BookException e) {
- e.printStackTrace();
- }
-
- }
- };
-
- final Runnable r2 = new Runnable() {
- @Override
- public void run() {
- final Book b0 = Books.installed().getBook(names[1]);
- BookData bd1;
- try {
- bd1 = new BookData(b0, b0.getKey(ref));
- bd1.getSAXEventProvider();
- } catch (final NoSuchKeyException e) {
- e.printStackTrace();
- } catch (final BookException e) {
- e.printStackTrace();
- }
-
- }
- };
-
- int ii = 0;
- while (ii++ < 1000) {
- final Thread t1 = new Thread(r1);
- final Thread t2 = new Thread(r2);
- t1.start();
- t2.start();
-
- t1.join();
- t2.join();
- }
+ // final String[] names = { "KJV", "ESV" };
+ // final String ref = "Rom.1.1";
+ //
+ // final Runnable r1 = new Runnable() {
+ // @Override
+ // public void run() {
+ // final Book b0 = Books.installed().getBook(names[0]);
+ // BookData bd1;
+ // try {
+ // bd1 = new BookData(b0, b0.getKey(ref));
+ // bd1.getSAXEventProvider();
+ // } catch (final NoSuchKeyException e) {
+ // LOGGER.error("A jsword error during test", e);
+ // Assert.fail("JSword bug has occured");
+ // } catch (final BookException e) {
+ // LOGGER.error("A jsword error during test", e);
+ // Assert.fail("JSword bug has occured");
+ // }
+ // }
+ // };
+ //
+ // final Runnable r2 = new Runnable() {
+ // @Override
+ // public void run() {
+ // final Book b0 = Books.installed().getBook(names[1]);
+ // BookData bd1;
+ // try {
+ // bd1 = new BookData(b0, b0.getKey(ref));
+ // bd1.getSAXEventProvider();
+ // } catch (final NoSuchKeyException e) {
+ // LOGGER.error("A jsword error during test", e);
+ // Assert.fail("JSword bug has occured");
+ // } catch (final BookException e) {
+ // LOGGER.error("A jsword error during test", e);
+ // Assert.fail("JSword bug has occured");
+ // }
+ // }
+ // };
+ //
+ // int ii = 0;
+ // while (ii++ < 15) {
+ // final Thread t1 = new Thread(r1);
+ // final Thread t2 = new Thread(r2);
+ // t1.start();
+ // t2.start();
+ //
+ // t1.join();
+ // t2.join();
+ // }
}
}
Added: trunk/step/step-core/src/test/java/com/tyndalehouse/step/core/service/impl/BookmarkServiceImplTest.java
===================================================================
--- trunk/step/step-core/src/test/java/com/tyndalehouse/step/core/service/impl/BookmarkServiceImplTest.java (rev 0)
+++ trunk/step/step-core/src/test/java/com/tyndalehouse/step/core/service/impl/BookmarkServiceImplTest.java 2011-03-19 09:53:18 UTC (rev 219)
@@ -0,0 +1,120 @@
+package com.tyndalehouse.step.core.service.impl;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Mockito.when;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.runners.MockitoJUnitRunner;
+
+import com.google.inject.Provider;
+import com.tyndalehouse.step.core.data.AbstractDataTest;
+import com.tyndalehouse.step.core.data.entities.Bookmark;
+import com.tyndalehouse.step.core.data.entities.Session;
+import com.tyndalehouse.step.core.data.entities.User;
+
+/**
+ * tests that we can create and retrieve bookmarks
+ *
+ * @author Chris
+ *
+ */
+ at RunWith(MockitoJUnitRunner.class)
+public class BookmarkServiceImplTest extends AbstractDataTest {
+ @Mock
+ private Provider<Session> serverSession;
+ private BookmarkServiceImpl bookmarkService;
+ private User u;
+
+ /**
+ * sets up the service under test
+ */
+ @Before
+ public void setUp() {
+ this.bookmarkService = new BookmarkServiceImpl(getEbean(), this.serverSession);
+ this.u = new User();
+ this.u.setEmailAddress("b at b.com");
+ final Session s = new Session();
+ s.setUser(this.u);
+
+ // when the server session is requested, we give the user back
+ when(this.serverSession.get()).thenReturn(s);
+ }
+
+ /**
+ * ensures that with no bookmarks, this still works
+ */
+ @Test
+ public void readNoBookmarks() {
+ assertEquals(0, this.bookmarkService.getBookmarks().size());
+ }
+
+ /**
+ * ensures that with no bookmarks, this still works
+ */
+ @Test
+ public void testReadOneBookmarks() {
+ final String testReference = "Genesis 1:1";
+ saveNewBookmarkDirectly(testReference);
+ assertEquals(this.bookmarkService.getBookmarks().get(0).getBookmarkReference(), testReference);
+ }
+
+ /**
+ * ensures that we can add bookmarks
+ */
+ @Test
+ public void testAddBookmark() {
+ final String testReference = "Genesis 1:1";
+ final int bookmarkId = this.bookmarkService.addBookmark(testReference);
+
+ final Bookmark persistedBookmark = getEbean().find(Bookmark.class).where().idEq(bookmarkId)
+ .findUnique();
+ assertEquals(testReference, persistedBookmark.getBookmarkReference());
+ }
+
+ /**
+ * This should return the original bookmark, but not create a new one
+ */
+ @Test
+ public void testAddDuplicateBookmark() {
+ final String testReference = "Genesis 1:1";
+
+ final int bookmarkId = this.bookmarkService.addBookmark(testReference);
+ final int duplicateBookmarkId = this.bookmarkService.addBookmark(testReference);
+
+ assertEquals(bookmarkId, duplicateBookmarkId);
+ assertEquals(1, getEbean().find(Bookmark.class).where().eq("bookmarkReference", testReference)
+ .findRowCount());
+ }
+
+ /**
+ * tests removing a bookmark
+ */
+ @Test
+ public void testRemoveBookmark() {
+ // create a bookmark
+ final Bookmark b = saveNewBookmarkDirectly("blah");
+
+ final Integer bookmarkId = b.getId();
+ this.bookmarkService.removeBookmark(bookmarkId);
+
+ assertEquals(0, getEbean().find(Bookmark.class).where().idEq(bookmarkId).findRowCount());
+ }
+
+ /**
+ * helpers to save a bookmark
+ *
+ * @param testReference the pasage reference
+ * @return the bookmark that was created
+ */
+ private Bookmark saveNewBookmarkDirectly(final String testReference) {
+ final Bookmark b = new Bookmark();
+ b.setBookmarkReference(testReference);
+ b.setUser(this.u);
+ getEbean().save(b);
+ return b;
+ }
+
+}
Property changes on: trunk/step/step-core/src/test/java/com/tyndalehouse/step/core/service/impl/BookmarkServiceImplTest.java
___________________________________________________________________
Added: svn:mime-type
+ text/plain
Added: trunk/step/step-core/src/test/java/com/tyndalehouse/step/core/service/impl/UserDataServiceImplTest.java
===================================================================
--- trunk/step/step-core/src/test/java/com/tyndalehouse/step/core/service/impl/UserDataServiceImplTest.java (rev 0)
+++ trunk/step/step-core/src/test/java/com/tyndalehouse/step/core/service/impl/UserDataServiceImplTest.java 2011-03-19 09:53:18 UTC (rev 219)
@@ -0,0 +1,149 @@
+package com.tyndalehouse.step.core.service.impl;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import java.util.Date;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.runners.MockitoJUnitRunner;
+
+import com.google.inject.Provider;
+import com.tyndalehouse.step.core.data.AbstractDataTest;
+import com.tyndalehouse.step.core.data.entities.Session;
+import com.tyndalehouse.step.core.data.entities.User;
+import com.tyndalehouse.step.core.exceptions.StepInternalException;
+import com.tyndalehouse.step.core.models.ClientSession;
+
+/**
+ * tests the paths through the user data service
+ *
+ * @author Chris
+ *
+ */
+ at RunWith(MockitoJUnitRunner.class)
+public class UserDataServiceImplTest extends AbstractDataTest {
+ @Mock
+ private Provider<Session> serverSessionProvider;
+ @Mock
+ private Provider<ClientSession> clientSessionProvider;
+ private UserDataServiceImpl userService;
+
+ /**
+ * sets up the user service under test
+ */
+ @Before
+ public void setUp() {
+ // MockitoAnnotations.initMocks(this);
+ this.userService = new UserDataServiceImpl(super.getEbean(), this.serverSessionProvider,
+ this.clientSessionProvider);
+ }
+
+ /**
+ * Tests the successful path of registering a user
+ */
+ @Test
+ public void testRegisterUser() {
+ final String testEmail = "abc at abc.com";
+ final String testName = "Mr Test";
+ final String testCountry = "UK";
+ final String testPassword = "password";
+
+ // we will return with a session object with null fields
+ final Session mockSession = new Session();
+ mockSession.setJSessionId("1");
+ when(this.serverSessionProvider.get()).thenReturn(mockSession);
+
+ this.userService.register(testEmail, testName, testCountry, testPassword);
+
+ final Session session = getEbean().find(Session.class).fetch("user").where()
+ .eq("user.emailAddress", testEmail).findUnique();
+ final User user = session.getUser();
+
+ assertEquals(user.getEmailAddress(), testEmail);
+ assertEquals(user.getName(), testName);
+ assertEquals(user.getCountry(), testCountry);
+ assertEquals(user.getPassword(), testPassword);
+ }
+
+ /**
+ * Tests the successful path of registering a user
+ */
+ @Test(expected = IllegalArgumentException.class)
+ public void testRegisterUserWhenLoggedIn() {
+ final String testEmail = "abc at abc.com";
+ final String testName = "Mr Test";
+ final String testCountry = "UK";
+ final String testPassword = "password";
+
+ // we will return with a session object with null fields
+ final Session mockSession = new Session();
+ mockSession.setUser(new User());
+ when(this.serverSessionProvider.get()).thenReturn(mockSession);
+
+ this.userService.register(testEmail, testName, testCountry, testPassword);
+ }
+
+ /**
+ * we check that login in creates a row in the session table mapped to a user
+ *
+ */
+ @Test(expected = StepInternalException.class)
+ public void testLoginFail() {
+ final String email = "chris at chris.com";
+ final String password = "not_registered";
+ this.userService.login(email, password);
+ }
+
+ /**
+ * we check that login in creates a row in the session table mapped to a user
+ *
+ */
+ @Test
+ public void testLoginPass() {
+ final String email = "chris at chris.com";
+ final String password = "someValidPassword";
+ final String testName = "Mr Bob";
+ final Session currentServerSession = new Session();
+ final ClientSession mockClient = mock(ClientSession.class);
+ when(mockClient.getSessionId()).thenReturn("202");
+ when(this.clientSessionProvider.get()).thenReturn(mockClient);
+ when(this.serverSessionProvider.get()).thenReturn(currentServerSession);
+
+ // save the user in a database
+ final User u = new User();
+ u.setEmailAddress(email);
+ u.setPassword(password);
+ u.setName(testName);
+ getEbean().save(u);
+
+ this.userService.login(email, password);
+
+ // check that the user is logged in
+ assertEquals(currentServerSession.getUser().getName(), testName);
+ }
+
+ /**
+ * we check that we can create a session
+ */
+ @Test
+ public void testCreateSession() {
+ final String testClientSessionId = "999";
+ final String testIpAddress = "xx.xxx.xx.xx";
+ final ClientSession clientSession = mock(ClientSession.class);
+ when(this.clientSessionProvider.get()).thenReturn(clientSession);
+ when(clientSession.getSessionId()).thenReturn(testClientSessionId);
+ when(clientSession.getIpAddress()).thenReturn(testIpAddress);
+ this.userService.createSession();
+
+ final Session persistedSession = getEbean().find(Session.class).where()
+ .eq("jSessionId", testClientSessionId).findUnique();
+ assertEquals(persistedSession.getIpAddress(), testIpAddress);
+ assertTrue(persistedSession.getExpiresOn().after(new Date()));
+ }
+}
Property changes on: trunk/step/step-core/src/test/java/com/tyndalehouse/step/core/service/impl/UserDataServiceImplTest.java
___________________________________________________________________
Added: svn:mime-type
+ text/plain
Modified: trunk/step/step-parent/pom.xml
===================================================================
--- trunk/step/step-parent/pom.xml 2011-03-06 21:17:37 UTC (rev 218)
+++ trunk/step/step-parent/pom.xml 2011-03-19 09:53:18 UTC (rev 219)
@@ -319,7 +319,7 @@
<version>2.7.1</version>
<configuration>
<junitArtifactName>junit:junit-dep</junitArtifactName>
- <parallel>classes</parallel>
+ <parallel>method</parallel>
<threadCount>4</threadCount>
</configuration>
<dependencies>
Modified: trunk/step/step-web/src/main/java/com/tyndalehouse/step/guice/StepServletConfig.java
===================================================================
--- trunk/step/step-web/src/main/java/com/tyndalehouse/step/guice/StepServletConfig.java 2011-03-06 21:17:37 UTC (rev 218)
+++ trunk/step/step-web/src/main/java/com/tyndalehouse/step/guice/StepServletConfig.java 2011-03-19 09:53:18 UTC (rev 219)
@@ -8,7 +8,8 @@
import com.tyndalehouse.step.rest.controllers.FrontController;
/**
- * Configures the listener for the web app to return the injector used to configure the whole of the application
+ * Configures the listener for the web app to return the injector used to configure the whole of the
+ * application
*
* @author Chris
*
@@ -17,7 +18,7 @@
@Override
protected Injector getInjector() {
- return Guice.createInjector(new StepCoreModule(), new ServletModule() {
+ return Guice.createInjector(new StepCoreModule(), new WebContextModule(), new ServletModule() {
@Override
protected void configureServlets() {
serve("/rest/*").with(FrontController.class);
Added: trunk/step/step-web/src/main/java/com/tyndalehouse/step/guice/WebContextModule.java
===================================================================
--- trunk/step/step-web/src/main/java/com/tyndalehouse/step/guice/WebContextModule.java (rev 0)
+++ trunk/step/step-web/src/main/java/com/tyndalehouse/step/guice/WebContextModule.java 2011-03-19 09:53:18 UTC (rev 219)
@@ -0,0 +1,21 @@
+package com.tyndalehouse.step.guice;
+
+import com.google.inject.AbstractModule;
+import com.tyndalehouse.step.core.models.ClientSession;
+import com.tyndalehouse.step.guice.providers.ClientSessionProvider;
+
+/**
+ * This module serves to inject data that is specific to the servlet layer. The purpose of it is therefore to
+ * abstract away the identity of it being a java web servlet serving the page.
+ *
+ * @author Chris
+ *
+ */
+public class WebContextModule extends AbstractModule {
+
+ @Override
+ protected void configure() {
+ // this provider is helpful for getting the request at runtime
+ bind(ClientSession.class).toProvider(ClientSessionProvider.class);
+ }
+}
Property changes on: trunk/step/step-web/src/main/java/com/tyndalehouse/step/guice/WebContextModule.java
___________________________________________________________________
Added: svn:mime-type
+ text/plain
Added: trunk/step/step-web/src/main/java/com/tyndalehouse/step/guice/providers/ClientSessionProvider.java
===================================================================
--- trunk/step/step-web/src/main/java/com/tyndalehouse/step/guice/providers/ClientSessionProvider.java (rev 0)
+++ trunk/step/step-web/src/main/java/com/tyndalehouse/step/guice/providers/ClientSessionProvider.java 2011-03-19 09:53:18 UTC (rev 219)
@@ -0,0 +1,38 @@
+package com.tyndalehouse.step.guice.providers;
+
+import javax.servlet.http.HttpSession;
+
+import com.google.inject.Inject;
+import com.google.inject.Provider;
+import com.google.inject.servlet.RequestScoped;
+import com.tyndalehouse.step.core.models.ClientSession;
+import com.tyndalehouse.step.models.WebSessionImpl;
+
+/**
+ * This object is request-scoped, meaning it is new for every request. It is a way to return the jsessionId at
+ * runtime
+ *
+ * @author Chris
+ *
+ */
+ at RequestScoped
+public class ClientSessionProvider implements Provider<ClientSession> {
+ private final HttpSession session;
+
+ /**
+ * We inject the HttpSession in so that we can reference the jSessionId in the cookie
+ *
+ * @param session the http session containing the jSessionId
+ */
+ @Inject
+ public ClientSessionProvider(final HttpSession session) {
+ this.session = session;
+
+ }
+
+ @Override
+ public ClientSession get() {
+ // check if this has the IP address in it
+ return new WebSessionImpl(this.session.getId());
+ }
+}
Property changes on: trunk/step/step-web/src/main/java/com/tyndalehouse/step/guice/providers/ClientSessionProvider.java
___________________________________________________________________
Added: svn:mime-type
+ text/plain
Added: trunk/step/step-web/src/main/java/com/tyndalehouse/step/models/ClientOperation.java
===================================================================
--- trunk/step/step-web/src/main/java/com/tyndalehouse/step/models/ClientOperation.java (rev 0)
+++ trunk/step/step-web/src/main/java/com/tyndalehouse/step/models/ClientOperation.java 2011-03-19 09:53:18 UTC (rev 219)
@@ -0,0 +1,14 @@
+package com.tyndalehouse.step.models;
+
+/**
+ * a set of operations that should be performed by the client
+ *
+ * @author Chris
+ *
+ */
+public enum ClientOperation {
+ /**
+ * forces the user to log on
+ */
+ SHOW_LOGIN_POPUP,
+}
Property changes on: trunk/step/step-web/src/main/java/com/tyndalehouse/step/models/ClientOperation.java
___________________________________________________________________
Added: svn:mime-type
+ text/plain
Added: trunk/step/step-web/src/main/java/com/tyndalehouse/step/models/WebSessionImpl.java
===================================================================
--- trunk/step/step-web/src/main/java/com/tyndalehouse/step/models/WebSessionImpl.java (rev 0)
+++ trunk/step/step-web/src/main/java/com/tyndalehouse/step/models/WebSessionImpl.java 2011-03-19 09:53:18 UTC (rev 219)
@@ -0,0 +1,51 @@
+package com.tyndalehouse.step.models;
+
+import com.tyndalehouse.step.core.models.ClientSession;
+
+/**
+ * A web session which wraps around the jsession id...
+ *
+ * @author Chris
+ *
+ */
+public class WebSessionImpl implements ClientSession {
+ private String sessionId;
+ private String ipAddress;
+
+ /**
+ * creates a web session
+ *
+ * @param id the id of the session
+ */
+ public WebSessionImpl(final String id) {
+ this.sessionId = id;
+ }
+
+ /**
+ * @return the session
+ */
+ public String getSessionId() {
+ return this.sessionId;
+ }
+
+ /**
+ * @param sessionId the session to set
+ */
+ public void setSessionId(final String sessionId) {
+ this.sessionId = sessionId;
+ }
+
+ /**
+ * @return the ipAddress
+ */
+ public String getIpAddress() {
+ return this.ipAddress;
+ }
+
+ /**
+ * @param ipAddress the ipAddress to set
+ */
+ public void setIpAddress(final String ipAddress) {
+ this.ipAddress = ipAddress;
+ }
+}
Property changes on: trunk/step/step-web/src/main/java/com/tyndalehouse/step/models/WebSessionImpl.java
___________________________________________________________________
Added: svn:mime-type
+ text/plain
Added: trunk/step/step-web/src/main/java/com/tyndalehouse/step/rest/controllers/BookmarkController.java
===================================================================
--- trunk/step/step-web/src/main/java/com/tyndalehouse/step/rest/controllers/BookmarkController.java (rev 0)
+++ trunk/step/step-web/src/main/java/com/tyndalehouse/step/rest/controllers/BookmarkController.java 2011-03-19 09:53:18 UTC (rev 219)
@@ -0,0 +1,60 @@
+package com.tyndalehouse.step.rest.controllers;
+
+import java.util.List;
+
+import com.google.inject.Inject;
+import com.google.inject.Singleton;
+import com.tyndalehouse.step.core.data.entities.Bookmark;
+import com.tyndalehouse.step.core.service.BookmarkService;
+
+/**
+ * This helps manage bookmarks. This implementation simply wraps around the Bookmark Service (the project
+ * step-web provides a WebSessionProvider which can be used therefore to get cookie information).
+ *
+ * In this case, we just simply proxy through
+ *
+ * @author Chris
+ *
+ */
+ at Singleton
+public class BookmarkController {
+ private final BookmarkService bookmarkService;
+
+ /**
+ * We simply inject the bookmark service and proxy requests through
+ *
+ * @param bookmarkService the bookmark service used to get our data
+ */
+ @Inject
+ public BookmarkController(final BookmarkService bookmarkService) {
+ this.bookmarkService = bookmarkService;
+ }
+
+ /**
+ * gets a set of bookmarks associated with the current session
+ *
+ * @return a list of bookmarks
+ */
+ public List<Bookmark> getBookmarks() {
+ return this.bookmarkService.getBookmarks();
+ }
+
+ /**
+ * Removes a bookmark, using the current session-ed and logged on user
+ *
+ * @param bookmarkId the bookmark id to use.
+ */
+ public void removeBookmark(final int bookmarkId) {
+ this.bookmarkService.removeBookmark(bookmarkId);
+ }
+
+ /**
+ * Adds a bookmark if not already there
+ *
+ * @param reference the reference to add to the bookmark
+ * @return the id of the bookmark that was added
+ */
+ public int addBookmark(final String reference) {
+ return this.bookmarkService.addBookmark(reference);
+ }
+}
Property changes on: trunk/step/step-web/src/main/java/com/tyndalehouse/step/rest/controllers/BookmarkController.java
___________________________________________________________________
Added: svn:mime-type
+ text/plain
Modified: trunk/step/step-web/src/main/java/com/tyndalehouse/step/rest/controllers/FrontController.java
===================================================================
--- trunk/step/step-web/src/main/java/com/tyndalehouse/step/rest/controllers/FrontController.java 2011-03-06 21:17:37 UTC (rev 218)
+++ trunk/step/step-web/src/main/java/com/tyndalehouse/step/rest/controllers/FrontController.java 2011-03-19 09:53:18 UTC (rev 219)
@@ -2,7 +2,6 @@
import java.io.IOException;
import java.io.UnsupportedEncodingException;
-import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.URLDecoder;
import java.util.ArrayList;
@@ -20,13 +19,15 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import com.avaje.ebean.Ebean;
+import com.avaje.ebean.EbeanServer;
import com.avaje.ebean.text.json.JsonContext;
import com.google.inject.Inject;
import com.google.inject.Injector;
import com.google.inject.Singleton;
import com.google.inject.name.Named;
import com.tyndalehouse.step.core.exceptions.StepInternalException;
+import com.tyndalehouse.step.rest.framework.ClientErrorResolver;
+import com.tyndalehouse.step.rest.framework.ClientHandledIssue;
import com.tyndalehouse.step.rest.framework.ControllerCacheKey;
import com.tyndalehouse.step.rest.framework.StepRequest;
@@ -49,24 +50,31 @@
private final Map<String, String> contextPath = new HashMap<String, String>();
private final Map<String, byte[]> resultsCache = new HashMap<String, byte[]>();
private final transient Injector guiceInjector;
- // TODO but also check threadsafety and whether we should share this object
+ // TODO but also check thread safety and whether we should share this object
private final transient ObjectMapper jsonMapper = new ObjectMapper();
// TODO investigate EH cache here
private final Map<String, Method> methodNames = new HashMap<String, Method>();
private final Map<String, Object> controllers = new HashMap<String, Object>();
private final boolean isCacheEnabled;
+ private final transient EbeanServer ebean;
+ private final transient ClientErrorResolver errorResolver;
/**
* creates the front controller which will dispatch all the requests
*
* @param guiceInjector the injector used to call the relevant controllers
- * @param isCacheEnabled indicates whether responses should be cached for fast retrieval
- *
+ * @param isCacheEnabled indicates whether responses should be cached for fast retrieval TODO rename all
+ * ebeans to DB
+ * @param ebean the db access/persisitence object
*/
@Inject
- public FrontController(final Injector guiceInjector, @Named("cache.enabled") final Boolean isCacheEnabled) {
+ public FrontController(final Injector guiceInjector,
+ @Named("cache.enabled") final Boolean isCacheEnabled, final EbeanServer ebean,
+ final ClientErrorResolver errorResolver) {
this.guiceInjector = guiceInjector;
+ this.ebean = ebean;
+ this.errorResolver = errorResolver;
this.isCacheEnabled = Boolean.TRUE.equals(isCacheEnabled);
}
@@ -91,13 +99,16 @@
LOGGER.debug("The cache was missed so invoking method now...");
jsonEncoded = invokeMethod(sr);
}
+
setupHeaders(response, jsonEncoded.length);
response.getOutputStream().write(jsonEncoded);
+
+ // TODO move cache down
cache(jsonEncoded, sr.getControllerName(), sr.getMethodName(), sr.getArgs());
// CHECKSTYLE:OFF We allow catching errors here, since we are at the top of the structure
} catch (final Exception e) {
// CHECKSTYLE:ON
- doError(response, e, sr);
+ handleError(response, e, sr);
}
}
@@ -117,18 +128,42 @@
sr.getArgs(), sr.getCacheKey().getMethodKey());
// invoke the three together
+ Object returnVal;
try {
- final Object returnVal = controllerMethod.invoke(controllerInstance, (Object[]) sr.getArgs());
- return getEncodedJsonResponse(returnVal);
- // TODO send a ERROR 500 back
- } catch (final IllegalAccessException e) {
- throw new StepInternalException("An illegal access has occurred", e);
- } catch (final InvocationTargetException e) {
- throw new StepInternalException("An internal error has occurred", e);
+ returnVal = controllerMethod.invoke(controllerInstance, (Object[]) sr.getArgs());
+ // CHECKSTYLE:OFF
+ } catch (final Exception e) {
+ returnVal = convertExceptionToJson(e);
}
+ return getEncodedJsonResponse(returnVal);
+ // CHECKSTYLE:ON
}
/**
+ * We attempt here to rethrow the exception that caused the invocation target exception, so that we can
+ * handle it nicely for the user
+ *
+ * @param e the wrapped exception that happened during the reflective call
+ * @return a client handled issue which wraps the exception that was raised
+ */
+ private ClientHandledIssue convertExceptionToJson(final Exception e) {
+ // first we check to see if it's a step exception, or an illegal argument exception
+
+ final Throwable cause = e.getCause();
+ if (cause instanceof StepInternalException) {
+ LOGGER.trace(e.getMessage(), e);
+ return new ClientHandledIssue(cause.getMessage(), this.errorResolver.resolve(cause.getClass()));
+ } else if (cause instanceof IllegalArgumentException) {
+ // a validation exception occurred
+ LOGGER.trace(e.getMessage(), e);
+ return new ClientHandledIssue(cause.getMessage());
+ }
+
+ LOGGER.error(e.getMessage(), e);
+ return new ClientHandledIssue("An internal error has occurred");
+ }
+
+ /**
* Returns a json response that is encoded
*
* @param responseValue the value that should be encoded
@@ -142,7 +177,7 @@
if (responseValue == null) {
return new byte[0];
} else if (responseValue.getClass().getPackage().getName().startsWith("com.avaje")) {
- final JsonContext json = Ebean.getServer(null).createJsonContext();
+ final JsonContext json = this.ebean.createJsonContext();
// convert list of beans into JSON
response = json.toJsonString(responseValue);
@@ -219,12 +254,12 @@
* @param e the exception
* @param sr the step request
*/
- void doError(final HttpServletResponse response, final Throwable e, final StepRequest sr) {
+ void handleError(final HttpServletResponse response, final Throwable e, final StepRequest sr) {
String requestId = null;
try {
requestId = sr == null ? "Failed to parse request?" : sr.getCacheKey().getResultsKey();
if (e != null) {
- final byte[] errorMessage = this.getEncodedJsonResponse(e.getMessage());
+ final byte[] errorMessage = this.getEncodedJsonResponse(e);
response.getOutputStream().write(errorMessage);
setupHeaders(response, errorMessage.length);
Added: trunk/step/step-web/src/main/java/com/tyndalehouse/step/rest/controllers/UserController.java
===================================================================
--- trunk/step/step-web/src/main/java/com/tyndalehouse/step/rest/controllers/UserController.java (rev 0)
+++ trunk/step/step-web/src/main/java/com/tyndalehouse/step/rest/controllers/UserController.java 2011-03-19 09:53:18 UTC (rev 219)
@@ -0,0 +1,54 @@
+package com.tyndalehouse.step.rest.controllers;
+
+import com.google.inject.Inject;
+import com.tyndalehouse.step.core.data.entities.User;
+import com.tyndalehouse.step.core.service.UserDataService;
+
+/**
+ * Gives access to the user data of the application
+ *
+ * @author Chris
+ *
+ */
+public class UserController {
+ private final UserDataService userDataService;
+
+ /**
+ * we need access to the user data service for this
+ *
+ * @param userDataService the service that allows us to carry out user operations
+ */
+ @Inject
+ public UserController(final UserDataService userDataService) {
+ this.userDataService = userDataService;
+ }
+
+ /**
+ * Registers and stores the user details.
+ *
+ * @param emailAddress the email address
+ * @param name the name of the person [optional]
+ * @param country his country [optional]
+ * @param password the password he has chosen, which we should SHA-1 and salt
+ */
+ public void register(final String emailAddress, final String name, final String country,
+ final String password) {
+ // do sha1 encoding here to avoid sending unencrypted string singletons all over the place...
+ }
+
+ /**
+ * TODO sha-1 encoding Associates the current session with the username assuming password and username
+ * authenticates
+ *
+ * @param emailAddress the email address is used as the login token
+ * @param password the password
+ * @return the user that has logged in
+ */
+ public User login(final String emailAddress, final String password) {
+ return this.userDataService.login(emailAddress, password);
+ }
+
+ public void logout() {
+ this.userDataService.logout();
+ }
+}
Property changes on: trunk/step/step-web/src/main/java/com/tyndalehouse/step/rest/controllers/UserController.java
___________________________________________________________________
Added: svn:mime-type
+ text/plain
Added: trunk/step/step-web/src/main/java/com/tyndalehouse/step/rest/framework/ClientErrorResolver.java
===================================================================
--- trunk/step/step-web/src/main/java/com/tyndalehouse/step/rest/framework/ClientErrorResolver.java (rev 0)
+++ trunk/step/step-web/src/main/java/com/tyndalehouse/step/rest/framework/ClientErrorResolver.java 2011-03-19 09:53:18 UTC (rev 219)
@@ -0,0 +1,37 @@
+package com.tyndalehouse.step.rest.framework;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import com.google.inject.Singleton;
+import com.tyndalehouse.step.core.exceptions.RequiresLoginException;
+import com.tyndalehouse.step.core.exceptions.StepInternalException;
+import com.tyndalehouse.step.models.ClientOperation;
+
+/**
+ * Resolves errors based on the type of exception thrown
+ *
+ * @author Chris
+ *
+ */
+ at Singleton
+public class ClientErrorResolver {
+ private final Map<Class<? extends StepInternalException>, ClientOperation> clientOperations = new HashMap<Class<? extends StepInternalException>, ClientOperation>();
+
+ /**
+ * sets up the redirections
+ */
+ public ClientErrorResolver() {
+ this.clientOperations.put(RequiresLoginException.class, ClientOperation.SHOW_LOGIN_POPUP);
+ }
+
+ /**
+ * returns from the internal map what action should be performed if any
+ *
+ * @param clazz a client operation
+ * @return the client operation corresponding to the exception
+ */
+ public ClientOperation resolve(final Class<? extends Throwable> clazz) {
+ return this.clientOperations.get(clazz);
+ }
+}
Property changes on: trunk/step/step-web/src/main/java/com/tyndalehouse/step/rest/framework/ClientErrorResolver.java
___________________________________________________________________
Added: svn:mime-type
+ text/plain
Added: trunk/step/step-web/src/main/java/com/tyndalehouse/step/rest/framework/ClientHandledIssue.java
===================================================================
--- trunk/step/step-web/src/main/java/com/tyndalehouse/step/rest/framework/ClientHandledIssue.java (rev 0)
+++ trunk/step/step-web/src/main/java/com/tyndalehouse/step/rest/framework/ClientHandledIssue.java 2011-03-19 09:53:18 UTC (rev 219)
@@ -0,0 +1,45 @@
+package com.tyndalehouse.step.rest.framework;
+
+import com.tyndalehouse.step.models.ClientOperation;
+
+/**
+ * A client error, contains a message and an optional redirection operation
+ *
+ * @author Chris
+ *
+ */
+public class ClientHandledIssue {
+ private static final long serialVersionUID = -4354861806290828883L;
+ private final String errorMessage;
+ private final ClientOperation operation;
+
+ /**
+ * @param errorMessage the error message to be displayed to the user
+ */
+ public ClientHandledIssue(final String errorMessage) {
+ this(errorMessage, null);
+ }
+
+ /**
+ * @param errorMessage the error message to be displayed to the user
+ * @param operation the operation the client (browser) should perform
+ */
+ public ClientHandledIssue(final String errorMessage, final ClientOperation operation) {
+ this.errorMessage = errorMessage;
+ this.operation = operation;
+ }
+
+ /**
+ * @return the errorMessage
+ */
+ public String getErrorMessage() {
+ return this.errorMessage;
+ }
+
+ /**
+ * @return the operation
+ */
+ public ClientOperation getOperation() {
+ return this.operation;
+ }
+}
Property changes on: trunk/step/step-web/src/main/java/com/tyndalehouse/step/rest/framework/ClientHandledIssue.java
___________________________________________________________________
Added: svn:mime-type
+ text/plain
Modified: trunk/step/step-web/src/main/resources/log4j.properties
===================================================================
--- trunk/step/step-web/src/main/resources/log4j.properties 2011-03-06 21:17:37 UTC (rev 218)
+++ trunk/step/step-web/src/main/resources/log4j.properties 2011-03-19 09:53:18 UTC (rev 219)
@@ -8,5 +8,6 @@
log4j.appender.A1.layout.ConversionPattern=%d %-5p %l %x - %m%n
log4j.category.com.tyndalehouse=INFO
+log4j.category.com.tyndalehouse.step.rest.controllers.FrontController=DEBUG
log4j.category.org.crosswire.jsword.book.sword.ConfigEntry=WARN
Modified: trunk/step/step-web/src/main/webapp/css/initial-fonts.css
===================================================================
--- trunk/step/step-web/src/main/webapp/css/initial-fonts.css 2011-03-06 21:17:37 UTC (rev 218)
+++ trunk/step/step-web/src/main/webapp/css/initial-fonts.css 2011-03-19 09:53:18 UTC (rev 219)
@@ -9,10 +9,6 @@
color: #ccc;
}
-.ui-helper-reset {
- font-size: 70%;
-}
-
.ui-widget {
font-family: Verdana;
}
@@ -21,6 +17,10 @@
font-size: small;
}
+.ui-widget-header .ui-state-default {
+ color: #669966 ;
+}
+
.logo {
text-align: center;
font-size: xx-small;
Modified: trunk/step/step-web/src/main/webapp/css/initial-layout.css
===================================================================
--- trunk/step/step-web/src/main/webapp/css/initial-layout.css 2011-03-06 21:17:37 UTC (rev 218)
+++ trunk/step/step-web/src/main/webapp/css/initial-layout.css 2011-03-19 09:53:18 UTC (rev 219)
@@ -1,7 +1,3 @@
-html {
-/* overflow: auto !important;*/
-}
-
body {
min-width: 500px;
min-height: 300px;
@@ -56,7 +52,6 @@
.bookmarks {
border-top: 0px;
min-width: 45px;
-
display: inline;
float: left;
width: 10%;
@@ -77,11 +72,18 @@
text-align: center;
}
+.bookmarkPane h3 {
+ color: #C77405;
+ cursor: pointer;
+ margin-bottom: 1px;
+}
+
.bookmarkItem {
clear: both;
display: block;
}
+
.leftBookmarkArrow {
float: left;
}
@@ -90,13 +92,29 @@
float: right;
}
+/* override the padding inserted by the accordion */
+#bookmarkPane .ui-accordion-content {
+ padding: 0px;
+}
+
/**************************/
/* TOP MENU
/**************************/
#topMenu {
}
+#topMenu a.login {
+ padding-top: 7px;
+ padding-right: 8px;
+ float: right;
+ color: white;
+}
+#topMenu a.login:hover {
+ color: white;
+ text-decoration: underline;
+}
+
/**************************/
/* COLUMNS
/**************************/
@@ -105,19 +123,44 @@
display: inline;
width: 45%; /* *2 columns */
float: left;
- overflow: auto;
+ position: relative;
+/* overflow: hidden;*/
+
}
+
+/********************************/
+/* INNER MENUS (i.e. sub menus)
+/********************************/
+.innerMenu {
+ position: absolute;
+ top: 0px;
+}
+
+
+/**************************/
+/* PASSAGE CONTAINERS
+/**************************/
.passageContainer {
-/* border-left: 0px;*/
-/* border-top: 0px;*/
- border: 0px;
}
-.ui-button-text {
- padding: 1px 0px 1px 0px !important;
+.passageText {
+ position: relative;
+ top: 30px;
+ overflow: hidden;
}
+.headingContainer {
+ position: absolute;
+ top: 0px;
+}
+
+.passageContent {
+ position: absolute;
+ top: 45px;
+ overflow: auto;
+}
+
.no-left-border {
/* border-left: none; */
margin-left: -1px;
@@ -131,13 +174,7 @@
border: none;
}
-/* disable scrolling in ALL panes */
-.ui-layout-pane {
- overflow: hidden !important;
- padding: 0px;
-}
-
-.column .ui-layout-pane-north {
+.column {
border: 0 !important;
padding-top: 0px;
padding-bottom: 0px;
@@ -160,14 +197,6 @@
text-align: center;
padding-bottom: 5px;
}
-/**/
-/*#leftPassagePane, #rightPassagePane {*/
-/* white-space: nowrap;*/
-/*}*/
-/**/
-/*.passageVersion {*/
-/* */
-/*}*/
.passageReference {
width: 40%;
@@ -196,9 +225,13 @@
}
#error {
- padding-top: 2px;
- padding-left: 1px;
+ position: absolute;
+ bottom: 0px;
+ padding: 2px;
margin: 0px;
+ z-index: 99999;
+ background-color: pink;
+ width: 100%;
}
#lexiconDefinition {
@@ -210,4 +243,19 @@
left: -1000px;
}
+/**************************/
+/* LOGIN POPUP
+/**************************/
+#login {
+ display: none;
+}
+#login label {
+ padding-top: 4px;
+ width: 9em;
+ float: left;
+ text-align: right;
+ margin-right: 0.5em;
+ display: block
+}
+
Modified: trunk/step/step-web/src/main/webapp/css/passage.css
===================================================================
--- trunk/step/step-web/src/main/webapp/css/passage.css 2011-03-06 21:17:37 UTC (rev 218)
+++ trunk/step/step-web/src/main/webapp/css/passage.css 2011-03-19 09:53:18 UTC (rev 219)
@@ -1,8 +1,8 @@
.passageText {
margin-top: 1px;
- overflow: auto;
+/* overflow: auto;*/
padding: 0px 5px;
- position: relative;
+/* position: relative;*/
text-align: left;
}
Modified: trunk/step/step-web/src/main/webapp/index.jsp
===================================================================
--- trunk/step/step-web/src/main/webapp/index.jsp 2011-03-06 21:17:37 UTC (rev 218)
+++ trunk/step/step-web/src/main/webapp/index.jsp 2011-03-19 09:53:18 UTC (rev 219)
@@ -29,6 +29,7 @@
<script src="js/timeline.js" type="text/javascript"></script>
<script src="js/toolbar_menu.js" type="text/javascript"></script>
<script src="js/interlinear_popup.js" type="text/javascript"></script>
+ <script src="js/login.js" type="text/javascript"></script>
<script src="js/init.js" type="text/javascript"></script>
</HEAD>
@@ -53,9 +54,15 @@
<div class="northBookmark">
<img id="topLogo" src="images/step-logo.png" alt="STEP :: Scripture Tools for Every Pastor" />
</div>
- <div class="bookmarkPane">
- <span>History<br /><br /></span>
- <span class="bookmarkContents"></span>
+ <div id="bookmarkPane" class="bookmarkPane ui-corner-all">
+ <h3 class="ui-helper-reset ui-state-default ui-corner-all">
+ <span class="leftBookmarkArrow ui-icon ui-icon-triangle-1-e"></span>History
+ </h3>
+ <div id="historyDisplayPane" class="bookmarkContents"><br /></div>
+ <h3 id="bookmarkHeader" class="ui-helper-reset ui-state-default ui-corner-all">
+ <span class="leftBookmarkArrow ui-icon ui-icon-triangle-1-e"></span>Bookmarks
+ </h3>
+ <div id="bookmarkDisplayPane" class="bookmarkContents"><br /></div>
</div>
<div class="logo">
<span class="copyright">© Tyndale House</span>
@@ -90,7 +97,7 @@
<!--<div id="bottomSection" class="timeline">No modules have yet been loaded.</div>-->
<!---->
<!--<div id="loading"><img alt="Loading..." src="images/wait16.gif" />Loading...</div>-->
-<!--<div id="error" class="ui-state-highlight">A placeholder for error messages</div>-->
+<div id="error">A placeholder for error messages</div>
<!-- The about popup -->
@@ -100,6 +107,16 @@
<p>© Tyndale House 2011</p>
</div>
+<div id="login">
+ <div id="loginPopup">
+ <label for="emailAddress">Email address:</label><input id="emailAddress" type="text" size="20" /><br />
+ <label for="password">Password:</label><input id="password" type="password" size="20" /><br />
+ </div>
+ <div id="registerPopup">
+ <label for="name">Your name</label><input id="emailAddress" type="text" size="20" /><br />
+ <label for="country">Country</label><input id="password" type="password" size="20" /><br />
+ </div>
+</div>
</body>
Modified: trunk/step/step-web/src/main/webapp/js/bookmark.js
===================================================================
--- trunk/step/step-web/src/main/webapp/js/bookmark.js 2011-03-06 21:17:37 UTC (rev 218)
+++ trunk/step/step-web/src/main/webapp/js/bookmark.js 2011-03-19 09:53:18 UTC (rev 219)
@@ -4,15 +4,45 @@
* for e.g. passage changes, but will also show related information to the passage.
*/
function Bookmark(bookmarkContainer) {
- this.bookmarkContainer = bookmarkContainer;
+ this.historyContainer = $("#historyDisplayPane");
+ this.bookmarkContainer = $("#bookmarkDisplayPane");
+ this.loadedBookmarks = false;
var self = this;
//listen to passage changes
- this.bookmarkContainer.hear("passage-changed", function(selfElement, data) {
+ this.historyContainer.hear("passage-changed", function(selfElement, data) {
self.addHistory(data.reference);
});
this.initialiseHistory();
+
+ //add accordion handlers
+ $("#bookmarkPane h3").click(function() {
+ //toggle the arrow
+ var eastArrow = "ui-icon-triangle-1-e";
+ var southArrow = "ui-icon-triangle-1-s";
+ var icon = $(":first", this);
+
+ if(icon.hasClass(eastArrow)) {
+ icon.removeClass(eastArrow);
+ icon.addClass(southArrow);
+ } else {
+ icon.addClass(eastArrow);
+ icon.removeClass(southArrow);
+ }
+
+ $(this).next().slideToggle(250);
+ }).disableSelection().next().slideUp(0);
+
+ //finally, we add a handler to force login of the bookmarks
+ $("#bookmarkHeader").click(function() {
+ self.loadBookmarks();
+ }).hear("user-logged-out", function(selfElement, data) {
+ //we clear the bookmarks
+
+ self.loadedBookmarks = false;
+ self.bookmarkContainer.html("");
+ });
}
Bookmark.maxBookmarks = 10;
@@ -42,17 +72,17 @@
if(history.length > Bookmark.maxBookmarks) {
//we remove the first element in the array (i.e. the last child).
history.pop();
- $("div.bookmarkItem:last", this.bookmarkContainer).remove();
+ $("div.bookmarkItem:last", this.historyContainer).remove();
}
//then add
- this.createBookmarkItem(passageReference);
+ this.createHistoryItem(passageReference);
history.unshift(passageReference);
} else {
//reposition item...
- var item = $("div.bookmarkItem", this.bookmarkContainer).eq(indexInHistory).detach();
+ var item = $("div.bookmarkItem", this.historyContainer).eq(indexInHistory).detach();
history.splice(indexInHistory, 1);
- this.bookmarkContainer.prepend(item);
+ this.historyContainer.prepend(item);
history.unshift(passageReference);
}
@@ -63,12 +93,46 @@
var history = this.getHistory();
if(history != null) {
for(var ii = history.length -1; ii >= 0; ii--) {
- this.createBookmarkItem(history[ii]);
+ this.createHistoryItem(history[ii]);
}
}
}
+/**
+ * loads the bookmarks from the server
+ */
+Bookmark.prototype.loadBookmarks = function() {
+ var self = this;
+ if(!this.loadedBookmarks) {
+ $.getSafe(BOOKMARKS_GET, function(data) {
+ //someone might have clicked twice, so need to check again
+ if(!this.loaded) {
+ this.loaded = true;
+ //we load the bookmarks
+ $.each(data, function(index, item) {
+ self.createBookmarkItem(item.bookmarkReference);
+ });
+ }
+ });
+ }
+}
+
+/**
+ * creates a history item
+ */
+Bookmark.prototype.createHistoryItem = function(passageReference) {
+ this.createItem(passageReference, this.historyContainer, false);
+};
+
+/**
+ * creates a history item
+ */
Bookmark.prototype.createBookmarkItem = function(passageReference) {
+ this.createItem(passageReference, this.bookmarkContainer, false);
+};
+
+
+Bookmark.prototype.createItem = function(passageReference, container, ascending) {
if(passageReference && passageReference != "") {
var item = "<div class='bookmarkItem'>";
item += "<a class='ui-icon ui-icon-arrowthick-1-w bookmarkArrow leftBookmarkArrow' href='#' onclick='$.shout(\"bookmark-triggered-0\", \""+ passageReference + "\");'>←</a>";
@@ -76,10 +140,16 @@
item += "<a class='ui-icon ui-icon-arrowthick-1-e bookmarkArrow rightBookmarkArrow' href='#' onclick='$.shout(\"bookmark-triggered-1\", \""+ passageReference + "\");'>→</a>";
item += "</div>";
- this.bookmarkContainer.prepend(item);
+ if(ascending) {
+ container.append(item);
+ } else {
+ container.prepend(item);
+ }
}
};
+
+
Bookmark.prototype.getHistory = function() {
var history = $.cookie("history");
if(history == null) {
Modified: trunk/step/step-web/src/main/webapp/js/init.js
===================================================================
--- trunk/step/step-web/src/main/webapp/js/init.js 2011-03-06 21:17:37 UTC (rev 218)
+++ trunk/step/step-web/src/main/webapp/js/init.js 2011-03-19 09:53:18 UTC (rev 219)
@@ -17,27 +17,36 @@
initBookmarks();
initData();
initInitialEvents();
+ initLogin();
});
}
+function refreshLayout() {
+ //we resize the heights:
+ var windowHeight = $(window).height();
+ var innerMenuHeight = $("#leftPaneMenu").height();
+ var topMenuHeight = $("#topMenu").height();
+ var imageAndFooterHeight = $(".northBookmark").height() + $(".logo").height();
+ $(".column").height(windowHeight - topMenuHeight);
+ $(".bookmarkPane").height(windowHeight - topMenuHeight - imageAndFooterHeight);
+ $(".passageText").height(windowHeight - topMenuHeight - innerMenuHeight);
+ $(".passageContent").height($(".passageText").height() - $(".headingContainer").height());
+}
+
/**
* initialises layout
*/
function initLayout() {
- $("body").hear("refresh-layout", function() {
- //we resize the heights:
- var windowHeight = $(window).height();
- var innerMenuHeight = $("#leftPaneMenu").height();
- var topMenuHeight = $("#topMenu").height();
- var imageAndFooterHeight = $(".northBookmark").height() + $(".logo").height();
- $(".column").height(windowHeight - topMenuHeight);
- $(".bookmarkPane").height(windowHeight - topMenuHeight - imageAndFooterHeight);
+ $("body").hear("passage-changed", function() {
+ refreshLayout();
});
//listen to layout changes and alert
$(window).resize(function() {
- $.shout("refresh-layout");
+ refreshLayout();
});
+
+
}
function initMenu() {
@@ -203,15 +212,14 @@
collision: "fit"
});
+ //TODO refactor as error object
+ $("#error").slideUp(0);
$("#error").click(function() {
- $('body').layout().close("north");
+ $(this).slideUp(250);
});
- $("#error").ajaxComplete(function(ev, req, ajaxOptions) {
- var currentResponse = $.parseJSON(req.responseText);
- if(currentResponse.error) {
- raiseError(currentResponse.error)
- }
+ $("#error").hear("caught-error-message", function(selfElement, data) {
+ raiseError(data)
});
}
@@ -220,15 +228,19 @@
}
function initBookmarks() {
- new Bookmark($(".bookmarkContents"));
+ new Bookmark();
}
+function initLogin() {
+ new Login();
+}
+
function initTimeline(mainAppLayout) {
new TimelineWidget($("#bottomSection"), mainAppLayout);
}
function raiseError(error) {
- $("#error").text(error);
- $('body').layout().open("north");
+ $("#error").text(error.errorMessage);
+ $("#error").slideDown(250);
}
Added: trunk/step/step-web/src/main/webapp/js/login.js
===================================================================
--- trunk/step/step-web/src/main/webapp/js/login.js (rev 0)
+++ trunk/step/step-web/src/main/webapp/js/login.js 2011-03-19 09:53:18 UTC (rev 219)
@@ -0,0 +1,123 @@
+/**
+ * The Login object is able to show/hide the login popup, register, etc.
+ */
+function Login() {
+ this.root = $("#login");
+ var self = this;
+
+ //hide the register popup by default
+ $("#registerPopup", this.root).hide();
+
+
+ this.root.hear("show-login-popup", function(selfElement, data) {
+ if(data) {
+ self.showLoginPopup(data.message, data.callback);
+ } else {
+ self.showLoginPopup();
+ }
+ });
+
+ this.root.hear("show-register-popup", function(selfElement, data) {
+ self.showLoginPopup();
+ });
+}
+
+/**
+ * shows the login popup
+ * @param title the title of the login popup
+ * @param the event to fire if we log on successfully
+ */
+Login.prototype.showLoginPopup = function(popupTitle, callback) {
+ var self = this;
+ this.registerMode = false;
+
+ $("#loginPopup").toggle(true);
+ $("#registerPopup", this.root).slideUp();
+ this.root.dialog({
+ buttons : {
+ "Login" : function() {
+ //send info to backend
+ var email = $("#emailAddress", self.root).val();
+ var password = $("#password", self.root).val();
+
+ var popup = this;
+ //TODO add validation
+ //TODO enhance error handling to be central
+ $.getSafe(USER_LOGIN + email + "/" + password, function(data) {
+ //we have logged in succesfully
+ //change the name of the user
+ var loginLink = $("#loginLink");
+ loginLink.text(data.name);
+ loginLink.unbind('click');
+ loginLink.click(function() {
+ self.showLogout();
+ });
+
+ $(popup).dialog("close");
+
+ if(callback) {
+ callback();
+ }
+ });
+ },
+ "Create an account" : function() {
+ //show register popup
+ self.showRegisterPopup();
+ },
+ "Cancel" : function() {
+ $(this).dialog("close");
+ }
+ },
+ modal: true,
+ title: popupTitle ? popupTitle : "Login as an existing user"
+ });
+};
+
+Login.prototype.showRegisterPopup = function() {
+ this.registerMode = true;
+ var self = this;
+ this.root.dialog({
+ buttons : {
+ "Register" : function() {
+ // send information to server
+ },
+ "Cancel" : function() {
+ self.showLoginPopup();
+ }
+ },
+ title: "Register as a new user"
+ });
+ $("#registerPopup", this.root).slideDown(1000);
+};
+
+/**
+ * offers the option of logging the user out
+ */
+Login.prototype.showLogout = function() {
+ //TODO fix height
+ this.root.slideUp(0);
+ $("#loginPopup").toggle(false);
+ $("#registerPopup").toggle(false);
+
+ var popup = this.root;
+ this.root.dialog({
+ buttons : {
+ "Logout" : function() {
+ //do logout
+ $.getSafe(USER_LOGOUT, function(){
+ var loginLink = $("#loginLink", this.root);
+ loginLink.text("Login");
+ loginLink.unbind('click');
+ loginLink.click(function() {
+ login();
+ });
+ popup.dialog("close");
+ $.shout("user-logged-out");
+ });
+ },
+ "Cancel" : function() {
+ $(this).dialog("close");
+ }
+ }
+ });
+};
Property changes on: trunk/step/step-web/src/main/webapp/js/login.js
___________________________________________________________________
Added: svn:mime-type
+ text/plain
Modified: trunk/step/step-web/src/main/webapp/js/ui_hooks.js
===================================================================
--- trunk/step/step-web/src/main/webapp/js/ui_hooks.js 2011-03-06 21:17:37 UTC (rev 218)
+++ trunk/step/step-web/src/main/webapp/js/ui_hooks.js 2011-03-19 09:53:18 UTC (rev 219)
@@ -9,6 +9,8 @@
// The following section defines method names and controller names
// These are used as part of the rest-like calls
/////////////////////////////////////////////////////////////////////////
+BOOKMARKS_GET = "rest/bookmark/getBookmarks";
+
BIBLE_GET_BIBLE_VERSIONS = "rest/bible/getBibleVersions/";
BIBLE_GET_BIBLE_TEXT = "rest/bible/getBibleText/";
BIBLE_GET_FEATURES = "rest/bible/getFeatures/";
@@ -25,6 +27,10 @@
TIMELINE_GET_EVENTS = "rest/timeline/getEvents/";
TIMELINE_GET_EVENTS_FROM_REFERENCE = "rest/timeline/getEventsFromReference/";
+USER_LOGIN = "rest/user/login/";
+USER_LOGOUT = "rest/user/logout/";
+USER_REGISTER = "rest/user/register/"
+
//////////////////////////
// SOME DEFAULTS
//////////////////////////
@@ -37,6 +43,13 @@
}
/**
+ * shows the login popup
+ */
+function login() {
+ $.shout("show-login-popup");
+}
+
+/**
* shows the interlinear options as a popup
* @param menuItem the menuItem to tick if the popup selects options
*/
Modified: trunk/step/step-web/src/main/webapp/js/util.js
===================================================================
--- trunk/step/step-web/src/main/webapp/js/util.js 2011-03-06 21:17:37 UTC (rev 218)
+++ trunk/step/step-web/src/main/webapp/js/util.js 2011-03-19 09:53:18 UTC (rev 219)
@@ -1,6 +1,6 @@
/**
- * extending jquery to have array comparison
+ * array comparison
*/
function compare(s, t) {
if(s == null || t == null) {
@@ -21,8 +21,11 @@
/**
* adds a button next to a specified element
- * @param textbox the box to which to add the dropdown button
- * @param icon the icon to stylise the button
+ *
+ * @param textbox
+ * the box to which to add the dropdown button
+ * @param icon
+ * the icon to stylise the button
*/
function addButtonToAutoComplete(textbox, icon) {
$( "<button> </button>" ).attr( "tabIndex", -1 )
@@ -54,9 +57,13 @@
}
/**
- * looks for the next space in the name provided and returns the shortest name available
- * @param longName the long name to be shortened
- * @param minLength the min length from which to start
+ * looks for the next space in the name provided and returns the shortest name
+ * available
+ *
+ * @param longName
+ * the long name to be shortened
+ * @param minLength
+ * the min length from which to start
*/
function shortenName(longName, minLength) {
var ii = longName.indexOf(' ', minLength);
@@ -64,7 +71,46 @@
return longName.substring(0, ii) + "...";
}
- //unable to shorten
+ // unable to shorten
return longName;
}
+// some jquery extensions
+(function ( $ ) {
+ $.extend({
+ /**
+ * an extension to jquery to do Ajax calls safely, with error handling...
+ * @param the url
+ * @param the userFunction to call on success of the query
+ */
+ getSafe: function (url, userFunction){
+ $.get(url, function(data) {
+ if(data && data.errorMessage) {
+ // handle an error message here
+ $.shout("caught-error-message", data);
+ if(data.operation) {
+ //so we now have an operation to perform before we continue with the user
+ //function if at all... the userFunction if what should be called if we have
+ //succeeded, but here we have no data, so we need to call ourselve recursively
+ $.shout(data.operation.replace(/_/g, "-").toLowerCase(),
+ { message: data.errorMessage,
+ callback : function() { $.getSafe(url, userFunction); }
+ }
+ );
+ }
+ } else {
+ userFunction(data);
+ }
+ });
+ }
+ });
+
+ $.fn.disableSelection = function() {
+ return $(this).attr('unselectable', 'on')
+ .css('-moz-user-select', 'none')
+ .each(function() {
+ this.onselectstart = function() { return false; };
+ });
+ };
+})(jQuery);
+
Modified: trunk/step/step-web/src/main/webapp/topmenu.html
===================================================================
--- trunk/step/step-web/src/main/webapp/topmenu.html 2011-03-06 21:17:37 UTC (rev 218)
+++ trunk/step/step-web/src/main/webapp/topmenu.html 2011-03-19 09:53:18 UTC (rev 219)
@@ -1,4 +1,5 @@
<div id="topMenu-ajax" class="ddsmoothmenu">
+<a id="loginLink" class="login" href="#" onclick="login()">Login</a>
<ul>
<li><a href="#">View</a>
<ul>
Modified: trunk/step/step-web/src/test/java/com/tyndalehouse/step/rest/controllers/FrontControllerTest.java
===================================================================
--- trunk/step/step-web/src/test/java/com/tyndalehouse/step/rest/controllers/FrontControllerTest.java 2011-03-06 21:17:37 UTC (rev 218)
+++ trunk/step/step-web/src/test/java/com/tyndalehouse/step/rest/controllers/FrontControllerTest.java 2011-03-19 09:53:18 UTC (rev 219)
@@ -50,7 +50,7 @@
final HttpServletRequest request = mock(HttpServletRequest.class);
final HttpServletResponse response = mock(HttpServletResponse.class);
- final FrontController fc = spy(new FrontController(null, false));
+ final FrontController fc = spy(new FrontController(null, false, null, null));
final StepRequest parsedRequest = new StepRequest("SomeController", "someMethod", new String[] {
"arg1", "arg2" });
final ServletOutputStream mockOutputStream = mock(ServletOutputStream.class);
@@ -74,12 +74,12 @@
final HttpServletResponse response = mock(HttpServletResponse.class);
final StepInternalException testException = new StepInternalException("A test exception");
- final FrontController fc = spy(new FrontController(null, false));
+ final FrontController fc = spy(new FrontController(null, false, null, null));
final StepRequest parsedRequest = new StepRequest("SomeController", "someMethod", new String[] {
"arg1", "arg2" });
doThrow(testException).when(fc).parseRequest(request);
- doNothing().when(fc).doError(response, testException, parsedRequest);
+ doNothing().when(fc).handleError(response, testException, parsedRequest);
// do the test
fc.doGet(request, response);
@@ -94,7 +94,7 @@
// index starts at ...........0123456789-123456789-123456
final String sampleRequest = "step-web/rest/bible/get/1K2/2K2";
- final FrontController fc = new FrontController(mock(Injector.class), Boolean.FALSE);
+ final FrontController fc = new FrontController(mock(Injector.class), Boolean.FALSE, null, null);
// when
final Object[] args = fc.getArgs(sampleRequest, 24);
@@ -113,7 +113,7 @@
// index starts at ...........0123456789-123456789-123456
final String sampleRequest = "step-web/rest/bible/get/1K2/2K2/";
- final FrontController fc = new FrontController(mock(Injector.class), Boolean.FALSE);
+ final FrontController fc = new FrontController(mock(Injector.class), Boolean.FALSE, null, null);
// when
final Object[] args = fc.getArgs(sampleRequest, 24);
@@ -131,7 +131,7 @@
*/
@Test
public void testGetPath() throws ServletException {
- final FrontController fc = new FrontController(null, null);
+ final FrontController fc = new FrontController(null, null, null, null);
final FrontController spy = spy(fc);
final ServletContext mockServletContext = mock(ServletContext.class);
@@ -158,7 +158,7 @@
final HttpServletResponse response = mock(HttpServletResponse.class);
final int sampleRequestLength = 10;
- new FrontController(null, null).setupHeaders(response, sampleRequestLength);
+ new FrontController(null, null, null, null).setupHeaders(response, sampleRequestLength);
verify(response).addDateHeader(eq("Date"), anyLong());
verify(response).setCharacterEncoding("UTF-8");
@@ -175,7 +175,8 @@
*/
@Test
public void testGetControllerMethod() throws IllegalAccessException, InvocationTargetException {
- final FrontController frontController = new FrontController(mock(Injector.class), Boolean.FALSE);
+ final FrontController frontController = new FrontController(mock(Injector.class), Boolean.FALSE,
+ null, null);
final BibleInformationService bibleInfo = mock(BibleInformationService.class);
final BibleController controllerInstance = new BibleController(bibleInfo);
@@ -195,7 +196,7 @@
public void testGetController() {
final String controllerName = "Bible";
final Injector mockInjector = mock(Injector.class);
- final FrontController frontController = new FrontController(mockInjector, Boolean.FALSE);
+ final FrontController frontController = new FrontController(mockInjector, Boolean.FALSE, null, null);
final BibleController mockController = mock(BibleController.class);
when(mockInjector.getInstance(BibleController.class)).thenReturn(mockController);
@@ -212,7 +213,7 @@
*/
@Test
public void testGetClasses() {
- final FrontController fc = new FrontController(null, Boolean.FALSE);
+ final FrontController fc = new FrontController(null, Boolean.FALSE, null, null);
assertEquals(0, fc.getClasses(null).length);
assertEquals(0, fc.getClasses(new Object[0]).length);
@@ -226,7 +227,8 @@
*/
@Test
public void testJsonEncoding() {
- final byte[] encodedJsonResponse = new FrontController(null, null).getEncodedJsonResponse("abc");
+ final byte[] encodedJsonResponse = new FrontController(null, null, null, null)
+ .getEncodedJsonResponse("abc");
// this reprensents the string "{abc}"
final byte[] expectedValues = new byte[] { 34, 97, 98, 99, 34 };
@@ -241,7 +243,7 @@
*/
@Test
public void testDoErrorHandlesCorrectly() throws IOException {
- final FrontController fc = new FrontController(null, null);
+ final FrontController fc = new FrontController(null, null, null, null);
final HttpServletResponse response = mock(HttpServletResponse.class);
final StepRequest stepRequest = new StepRequest("controller", "method", null);
final ServletOutputStream outputStream = mock(ServletOutputStream.class);
@@ -249,7 +251,7 @@
when(response.getOutputStream()).thenReturn(outputStream);
// do test
- fc.doError(response, exception, stepRequest);
+ fc.handleError(response, exception, stepRequest);
// check
verify(outputStream).write(any(byte[].class));
@@ -277,7 +279,7 @@
contextName + requestSeparator + servletName + requestSeparator + controllerName
+ requestSeparator + methodName + requestSeparator + arg1 + requestSeparator + arg2);
- final FrontController frontController = new FrontController(null, null);
+ final FrontController frontController = new FrontController(null, null, null, null);
frontController.init(mock(ServletConfig.class));
final FrontController spy = spy(frontController);
@@ -302,7 +304,7 @@
final StepRequest sr = new StepRequest("bible", "getAllFeatures", new String[] {});
final BibleController testController = mock(BibleController.class);
- final FrontController fc = spy(new FrontController(null, null));
+ final FrontController fc = spy(new FrontController(null, null, null, null));
doReturn(testController).when(fc).getController("bible");
// do test
Modified: trunk/step/step-web/src/test/java/com/tyndalehouse/step/rest/framework/StepRequestTest.java
===================================================================
--- trunk/step/step-web/src/test/java/com/tyndalehouse/step/rest/framework/StepRequestTest.java 2011-03-06 21:17:37 UTC (rev 218)
+++ trunk/step/step-web/src/test/java/com/tyndalehouse/step/rest/framework/StepRequestTest.java 2011-03-19 09:53:18 UTC (rev 219)
@@ -12,9 +12,9 @@
*
*/
public class StepRequestTest {
- final String[] args = new String[] { "arg1", "arg2", "arg3" };
- String testControllerName = "Controller";
- String testMethodName = "method";
+ private static final String[] TEST_ARGS = new String[] { "arg1", "arg2", "arg3" };
+ private static final String TEST_CONTROLLER_NAME = "Controller";
+ private static final String TEST_METHOD_NAME = "method";
/**
* a method key should not contain arguments, but contain controller name and method name
@@ -23,9 +23,9 @@
public void testMethodKey() {
final StepRequest stepRequest = getTestStepRequest();
final String methodKey = stepRequest.getCacheKey().getMethodKey();
- assertTrue(methodKey.contains(this.testControllerName));
- assertTrue(methodKey.contains(this.testMethodName));
- for (final String s : this.args) {
+ assertTrue(methodKey.contains(TEST_CONTROLLER_NAME));
+ assertTrue(methodKey.contains(TEST_METHOD_NAME));
+ for (final String s : TEST_ARGS) {
assertFalse(methodKey.contains(s));
}
}
@@ -37,9 +37,9 @@
public void testResultKey() {
final StepRequest stepRequest = getTestStepRequest();
final String resultsKey = stepRequest.getCacheKey().getResultsKey();
- assertTrue(resultsKey.contains(this.testControllerName));
- assertTrue(resultsKey.contains(this.testMethodName));
- for (final String s : this.args) {
+ assertTrue(resultsKey.contains(TEST_CONTROLLER_NAME));
+ assertTrue(resultsKey.contains(TEST_METHOD_NAME));
+ for (final String s : TEST_ARGS) {
assertTrue(resultsKey.contains(s));
}
@@ -51,6 +51,6 @@
* @return a step request
*/
private StepRequest getTestStepRequest() {
- return new StepRequest(this.testControllerName, this.testMethodName, this.args);
+ return new StepRequest(TEST_CONTROLLER_NAME, TEST_METHOD_NAME, TEST_ARGS);
}
}
More information about the Tynstep-svn
mailing list