[Tynstep-svn] r225 - in trunk/step: step-build/src/main/resources/checkstyle step-build/src/main/resources/eclipse step-core 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/guice step-core/src/main/java/com/tyndalehouse/step/core/guice/providers 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/utils step-core/src/main/java/com/tyndalehouse/step/core/xsl/impl step-core/src/main/resources step-core/src/test/java 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/impl step-core/src/test/java/com/tyndalehouse/step/core/xsl/impl step-core/src/test/resources step-parent 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/webapp/js step-web/src/test step-web/src/test/java/com/tyndalehouse/step/rest/controllers
ChrisBurrell at crosswire.org
ChrisBurrell at crosswire.org
Sat Mar 26 10:01:59 MST 2011
Author: ChrisBurrell
Date: 2011-03-26 10:01:58 -0700 (Sat, 26 Mar 2011)
New Revision: 225
Added:
trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/data/entities/History.java
trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/service/FavouritesService.java
trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/service/impl/FavouritesServiceImpl.java
trunk/step/step-core/src/test/java/com/tyndalehouse/step/core/data/DataDrivenTestExtension.java
trunk/step/step-core/src/test/java/com/tyndalehouse/step/core/service/impl/FavouritesServiceImplTest.java
trunk/step/step-core/src/test/resources/ebean.properties
trunk/step/step-web/src/main/java/com/tyndalehouse/step/rest/controllers/FavouritesController.java
trunk/step/step-web/src/main/java/com/tyndalehouse/step/rest/framework/StepJsonValueAdapter.java
trunk/step/step-web/src/test/resources/
Removed:
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/impl/BookmarkServiceImpl.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/service/impl/BookmarkServiceImplTest.java
trunk/step/step-core/src/test/java/log4j.properties
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/framework/Cached.java
Modified:
trunk/step/step-build/src/main/resources/checkstyle/checkstyle.test.xml
trunk/step/step-build/src/main/resources/eclipse/org.eclipse.jdt.core.prefs
trunk/step/step-build/src/main/resources/eclipse/pmd.xml
trunk/step/step-core/pom.xml
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/entities/Bookmark.java
trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/data/entities/HotSpot.java
trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/data/entities/ScriptureReference.java
trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/data/entities/ScriptureTarget.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/Timeband.java
trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/data/entities/TimelineEvent.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/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/guice/providers/DefaultLexiconRefsProvider.java
trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/guice/providers/DefaultVersionsProvider.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/service/UserDataService.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/UserDataServiceImpl.java
trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/utils/JSwordUtils.java
trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/xsl/impl/InterlinearProviderImpl.java
trunk/step/step-core/src/main/resources/ebean.properties
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/data/entities/UserTest.java
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/xsl/impl/InterlinearProviderImplTest.java
trunk/step/step-core/src/test/resources/log4j.properties
trunk/step/step-parent/pom.xml
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/BibleController.java
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/UserController.java
trunk/step/step-web/src/main/webapp/js/bookmark.js
trunk/step/step-web/src/main/webapp/js/login.js
trunk/step/step-web/src/main/webapp/js/ui_hooks.js
trunk/step/step-web/src/test/java/com/tyndalehouse/step/rest/controllers/FrontControllerTest.java
Log:
updating with history merging functionality
Modified: trunk/step/step-build/src/main/resources/checkstyle/checkstyle.test.xml
===================================================================
--- trunk/step/step-build/src/main/resources/checkstyle/checkstyle.test.xml 2011-03-22 10:29:42 UTC (rev 224)
+++ trunk/step/step-build/src/main/resources/checkstyle/checkstyle.test.xml 2011-03-26 17:01:58 UTC (rev 225)
@@ -169,7 +169,9 @@
<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/org.eclipse.jdt.core.prefs
===================================================================
--- trunk/step/step-build/src/main/resources/eclipse/org.eclipse.jdt.core.prefs 2011-03-22 10:29:42 UTC (rev 224)
+++ trunk/step/step-build/src/main/resources/eclipse/org.eclipse.jdt.core.prefs 2011-03-26 17:01:58 UTC (rev 225)
@@ -276,3 +276,7 @@
org.eclipse.jdt.core.formatter.tabulation.size=4
org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations=false
org.eclipse.jdt.core.formatter.wrap_before_binary_operator=true
+org.eclipse.jdt.core.compiler.problem.suppressOptionalErrors=disabled
+org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled
+org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=ignore
+org.eclipse.jdt.core.compiler.problem.unusedWarningToken=ignore
Modified: trunk/step/step-build/src/main/resources/eclipse/pmd.xml
===================================================================
--- trunk/step/step-build/src/main/resources/eclipse/pmd.xml 2011-03-22 10:29:42 UTC (rev 224)
+++ trunk/step/step-build/src/main/resources/eclipse/pmd.xml 2011-03-26 17:01:58 UTC (rev 225)
@@ -244,10 +244,6 @@
<ruleset>Controversial Rules</ruleset>
</rule>
<rule>
- <name>AvoidUsingVolatile</name>
- <ruleset>Controversial Rules</ruleset>
- </rule>
- <rule>
<name>AvoidAccessibilityAlteration</name>
<ruleset>Controversial Rules</ruleset>
</rule>
Modified: trunk/step/step-core/pom.xml
===================================================================
--- trunk/step/step-core/pom.xml 2011-03-22 10:29:42 UTC (rev 224)
+++ trunk/step/step-core/pom.xml 2011-03-26 17:01:58 UTC (rev 225)
@@ -100,6 +100,11 @@
<artifactId>commons-collections</artifactId>
</dependency>
+ <dependency>
+ <groupId>commons-codec</groupId>
+ <artifactId>commons-codec</artifactId>
+ </dependency>
+
<!-- we don't always need this - depends on what version -->
<dependency>
<groupId>commons-dbcp</groupId>
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-22 10:29:42 UTC (rev 224)
+++ trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/data/create/TimelineModuleLoader.java 2011-03-26 17:01:58 UTC (rev 225)
@@ -95,6 +95,7 @@
private Map<String, HotSpot> loadHotSpots(final Map<String, Timeband> bands) {
LOG.debug("Loading hot spot data");
final Map<String, HotSpot> hotSpots = load(HOTSPOTS_CSV_DATA_FILE, new CsvDataMapper<HotSpot>() {
+ @Override
public HotSpot mapRow(final int rowNum, final CsvData data) {
final HotSpot hs = new HotSpot();
hs.setCode(data.getData(rowNum, HOTSPOT_CODE_COLUMN));
@@ -116,6 +117,7 @@
private Map<String, Timeband> loadTimebands() {
LOG.debug("Loading timeband data");
final Map<String, Timeband> timebands = load(TIMEBAND_CSV_DATA_FILE, new CsvDataMapper<Timeband>() {
+ @Override
public Timeband mapRow(final int rowNum, final CsvData data) {
final Timeband timeband = new Timeband();
timeband.setCode(data.getData(rowNum, TIMEBAND_CODE_COLUMN));
Modified: 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 2011-03-22 10:29:42 UTC (rev 224)
+++ trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/data/entities/Bookmark.java 2011-03-26 17:01:58 UTC (rev 225)
@@ -1,5 +1,7 @@
package com.tyndalehouse.step.core.data.entities;
+import java.io.Serializable;
+
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
@@ -14,16 +16,18 @@
*
*/
@Entity
-public class Bookmark {
+public class Bookmark implements Serializable {
+ private static final long serialVersionUID = 537098392958960964L;
+
@Id
@GeneratedValue
private Integer id;
- @Column
+ @Column(nullable = false)
private String bookmarkReference;
@ManyToOne(cascade = CascadeType.PERSIST)
- @Column
+ @Column(nullable = false)
private User user;
/**
Added: trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/data/entities/History.java
===================================================================
--- trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/data/entities/History.java (rev 0)
+++ trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/data/entities/History.java 2011-03-26 17:01:58 UTC (rev 225)
@@ -0,0 +1,95 @@
+package com.tyndalehouse.step.core.data.entities;
+
+import java.io.Serializable;
+import java.sql.Timestamp;
+
+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;
+
+/**
+ * A user may have multiple history items, these are always ordered by the last inserted data however
+ *
+ * @author Chris
+ *
+ */
+ at Entity
+public class History implements Serializable {
+ private static final long serialVersionUID = 2983314321961626288L;
+
+ @Id
+ @GeneratedValue
+ private Integer id;
+
+ @Column(nullable = false)
+ private String historyReference;
+
+ @ManyToOne(cascade = CascadeType.PERSIST)
+ @Column(nullable = false)
+ private User user;
+
+ @Temporal(TemporalType.TIMESTAMP)
+ @Column(nullable = false)
+ private Timestamp lastUpdated;
+
+ /**
+ * @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 user
+ */
+ public User getUser() {
+ return this.user;
+ }
+
+ /**
+ * @param user the user to set
+ */
+ public void setUser(final User user) {
+ this.user = user;
+ }
+
+ /**
+ * @return the historyReference
+ */
+ public String getHistoryReference() {
+ return this.historyReference;
+ }
+
+ /**
+ * @param historyReference the historyReference to set
+ */
+ public void setHistoryReference(final String historyReference) {
+ this.historyReference = historyReference;
+ }
+
+ /**
+ * @return the lastUpdated
+ */
+ public Timestamp getLastUpdated() {
+ return this.lastUpdated;
+ }
+
+ /**
+ * @param lastUpdated the lastUpdated to set
+ */
+ public void setLastUpdated(final Timestamp lastUpdated) {
+ this.lastUpdated = lastUpdated;
+ }
+}
Property changes on: trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/data/entities/History.java
___________________________________________________________________
Added: svn:mime-type
+ text/plain
Modified: trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/data/entities/HotSpot.java
===================================================================
--- trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/data/entities/HotSpot.java 2011-03-22 10:29:42 UTC (rev 224)
+++ trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/data/entities/HotSpot.java 2011-03-26 17:01:58 UTC (rev 225)
@@ -1,5 +1,6 @@
package com.tyndalehouse.step.core.data.entities;
+import java.io.Serializable;
import java.util.List;
import javax.persistence.CascadeType;
@@ -21,7 +22,9 @@
*/
@CacheStrategy(readOnly = true)
@Entity
-public class HotSpot implements KeyedEntity {
+public class HotSpot implements KeyedEntity, Serializable {
+ private static final long serialVersionUID = -7904172771680747618L;
+
@Id
@GeneratedValue
private Integer id;
@@ -72,6 +75,7 @@
/**
* @return the code
*/
+ @Override
public String getCode() {
return this.code;
}
Modified: trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/data/entities/ScriptureReference.java
===================================================================
--- trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/data/entities/ScriptureReference.java 2011-03-22 10:29:42 UTC (rev 224)
+++ trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/data/entities/ScriptureReference.java 2011-03-26 17:01:58 UTC (rev 225)
@@ -1,5 +1,7 @@
package com.tyndalehouse.step.core.data.entities;
+import java.io.Serializable;
+
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
@@ -14,7 +16,9 @@
* @author Chris
*/
@Entity
-public class ScriptureReference {
+public class ScriptureReference implements Serializable {
+ private static final long serialVersionUID = -3854523992102175988L;
+
@Id
@GeneratedValue
private Integer scriptureReferenceId;
Modified: trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/data/entities/ScriptureTarget.java
===================================================================
--- trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/data/entities/ScriptureTarget.java 2011-03-22 10:29:42 UTC (rev 224)
+++ trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/data/entities/ScriptureTarget.java 2011-03-26 17:01:58 UTC (rev 225)
@@ -1,5 +1,7 @@
package com.tyndalehouse.step.core.data.entities;
+import java.io.Serializable;
+
import javax.persistence.DiscriminatorColumn;
import javax.persistence.DiscriminatorType;
import javax.persistence.Entity;
@@ -20,7 +22,8 @@
@Entity
@Inheritance(strategy = InheritanceType.JOINED)
@DiscriminatorColumn(discriminatorType = DiscriminatorType.INTEGER, name = "targetTypeId")
-public class ScriptureTarget {
+public class ScriptureTarget implements Serializable {
+ private static final long serialVersionUID = -3343458338757180529L;
@Id
@GeneratedValue
private Integer id;
Modified: 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 2011-03-22 10:29:42 UTC (rev 224)
+++ trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/data/entities/Session.java 2011-03-26 17:01:58 UTC (rev 225)
@@ -1,5 +1,6 @@
package com.tyndalehouse.step.core.data.entities;
+import java.io.Serializable;
import java.util.Date;
import javax.persistence.CascadeType;
@@ -19,7 +20,9 @@
*
*/
@Entity
-public class Session {
+public class Session implements Serializable {
+ private static final long serialVersionUID = 6232919302889735151L;
+
@Id
@GeneratedValue
private Integer id;
Modified: trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/data/entities/Timeband.java
===================================================================
--- trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/data/entities/Timeband.java 2011-03-22 10:29:42 UTC (rev 224)
+++ trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/data/entities/Timeband.java 2011-03-26 17:01:58 UTC (rev 225)
@@ -1,5 +1,6 @@
package com.tyndalehouse.step.core.data.entities;
+import java.io.Serializable;
import java.util.List;
import javax.persistence.CascadeType;
@@ -19,7 +20,9 @@
*/
@CacheStrategy(readOnly = true)
@Entity
-public class Timeband implements KeyedEntity {
+public class Timeband implements KeyedEntity, Serializable {
+ private static final long serialVersionUID = 8217910739779785032L;
+
@Id
@GeneratedValue
private Integer id;
@@ -50,6 +53,7 @@
/**
* @return the code
*/
+ @Override
public String getCode() {
return this.code;
}
Modified: trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/data/entities/TimelineEvent.java
===================================================================
--- trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/data/entities/TimelineEvent.java 2011-03-22 10:29:42 UTC (rev 224)
+++ trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/data/entities/TimelineEvent.java 2011-03-26 17:01:58 UTC (rev 225)
@@ -1,5 +1,7 @@
package com.tyndalehouse.step.core.data.entities;
+import java.io.Serializable;
+
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.DiscriminatorValue;
@@ -17,7 +19,9 @@
@CacheStrategy(readOnly = true)
@Entity
@DiscriminatorValue("1")
-public class TimelineEvent extends ScriptureTarget {
+public class TimelineEvent extends ScriptureTarget implements Serializable {
+ private static final long serialVersionUID = -4642904574412249515L;
+
@Column
private String summary;
@@ -120,4 +124,26 @@
this.hotSpot = hotSpot;
}
+ /**
+ * to get rid of a findbugs bug, we override to make clear we are using the parent's equal method
+ *
+ * @param obj the object that we are comparing
+ * @return true if objects are equals
+ */
+ @SuppressWarnings("PMD.UselessOverridingMethod")
+ @Override
+ public boolean equals(final Object obj) {
+ return super.equals(obj);
+ }
+
+ /**
+ * overriding the hashcode because we've override the equals
+ *
+ * @return the parent's hashcode
+ */
+ @SuppressWarnings("PMD.UselessOverridingMethod")
+ @Override
+ public int hashCode() {
+ return super.hashCode();
+ }
}
Modified: 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 2011-03-22 10:29:42 UTC (rev 224)
+++ trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/data/entities/User.java 2011-03-26 17:01:58 UTC (rev 225)
@@ -1,5 +1,7 @@
package com.tyndalehouse.step.core.data.entities;
+import java.io.Serializable;
+
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
@@ -14,7 +16,9 @@
*/
@Entity
@Table(name = "users")
-public class User {
+public class User implements Serializable {
+ private static final long serialVersionUID = 6221804892435479330L;
+
@Id
@GeneratedValue
private Integer id;
Modified: 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 2011-03-22 10:29:42 UTC (rev 224)
+++ trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/data/entities/readme.txt 2011-03-26 17:01:58 UTC (rev 225)
@@ -1,2 +1,3 @@
Entities currently need to be added to
-com.tyndalehouse.step.core.guice.providers.DatabaseConfigProvider.addEntities(ServerConfig)
\ No newline at end of file
+com.tyndalehouse.step.core.guice.providers.DatabaseConfigProvider
+>addEntities(ServerConfig)
\ No newline at end of file
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-22 10:29:42 UTC (rev 224)
+++ trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/guice/StepCoreModule.java 2011-03-26 17:01:58 UTC (rev 225)
@@ -21,13 +21,13 @@
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.FavouritesService;
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.FavouritesServiceImpl;
import com.tyndalehouse.step.core.service.impl.JSwordServiceImpl;
import com.tyndalehouse.step.core.service.impl.ModuleServiceImpl;
import com.tyndalehouse.step.core.service.impl.TimelineServiceImpl;
@@ -39,6 +39,7 @@
* @author Chris
*
*/
+ at SuppressWarnings("PMD.CouplingBetweenObjects")
public class StepCoreModule extends AbstractModule {
private static final String CORE_GUICE_PROPERTIES = "/step.core.properties";
@@ -51,7 +52,7 @@
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(FavouritesService.class).to(FavouritesServiceImpl.class);
bind(UserDataService.class).to(UserDataServiceImpl.class);
bind(Loader.class);
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-22 10:29:42 UTC (rev 224)
+++ trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/guice/providers/DatabaseConfigProvider.java 2011-03-26 17:01:58 UTC (rev 225)
@@ -9,6 +9,7 @@
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.History;
import com.tyndalehouse.step.core.data.entities.HotSpot;
import com.tyndalehouse.step.core.data.entities.ScriptureReference;
import com.tyndalehouse.step.core.data.entities.ScriptureTarget;
@@ -119,6 +120,7 @@
config.addClass(User.class);
config.addClass(Session.class);
config.addClass(Bookmark.class);
+ config.addClass(History.class);
}
}
Modified: trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/guice/providers/DefaultLexiconRefsProvider.java
===================================================================
--- trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/guice/providers/DefaultLexiconRefsProvider.java 2011-03-22 10:29:42 UTC (rev 224)
+++ trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/guice/providers/DefaultLexiconRefsProvider.java 2011-03-26 17:01:58 UTC (rev 225)
@@ -21,6 +21,7 @@
*
*/
@Provides
+ @Override
public Map<String, String> get() {
final Map<String, String> moduleRefs = new HashMap<String, String>();
moduleRefs.put("strong:H", "StrongsHebrew");
Modified: trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/guice/providers/DefaultVersionsProvider.java
===================================================================
--- trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/guice/providers/DefaultVersionsProvider.java 2011-03-22 10:29:42 UTC (rev 224)
+++ trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/guice/providers/DefaultVersionsProvider.java 2011-03-26 17:01:58 UTC (rev 225)
@@ -21,6 +21,7 @@
*
*/
@Provides
+ @Override
public List<String> get() {
final List<String> versions = new ArrayList<String>();
versions.add("ESV");
Modified: 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 2011-03-22 10:29:42 UTC (rev 224)
+++ trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/guice/providers/ServerSessionProvider.java 2011-03-26 17:01:58 UTC (rev 225)
@@ -9,7 +9,8 @@
import com.tyndalehouse.step.core.service.UserDataService;
/**
- * A server session provider
+ * A server session provider TODO should use CACHE here since we query almost everytime there is a request for
+ * bookmarks, etc.
*
* @author Chris
*
@@ -40,7 +41,7 @@
@Override
public Session get() {
final String clientSessionId = this.clientSessionProvider.get().getSessionId();
- final Session serverSession = this.ebean.find(Session.class).where()
+ final Session serverSession = this.ebean.find(Session.class).fetch("user", "id, name").where()
.eq("jSessionId", clientSessionId).findUnique();
if (serverSession == null) {
Modified: 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 2011-03-22 10:29:42 UTC (rev 224)
+++ trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/guice/providers/TestData.java 2011-03-26 17:01:58 UTC (rev 225)
@@ -1,13 +1,17 @@
package com.tyndalehouse.step.core.guice.providers;
+import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.List;
+import org.apache.commons.codec.digest.DigestUtils;
+
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.History;
import com.tyndalehouse.step.core.data.entities.User;
/**
@@ -26,17 +30,30 @@
@Inject
public TestData(final EbeanServer ebean) {
this.ebean = ebean;
- createBookmarks();
+ final User u = getUser();
+ createBookmarks(u);
+ createHistory(u);
}
/**
+ * creates a history item for the test user
+ *
+ * @param u the user
+ */
+ private void createHistory(final User u) {
+ final History h = new History();
+ h.setHistoryReference("Rev 1");
+ h.setUser(u);
+ h.setLastUpdated(new Timestamp(System.currentTimeMillis()));
+ this.ebean.save(h);
+ }
+
+ /**
* creates the bookmarks
+ *
+ * @param u the user
*/
- private void createBookmarks() {
- final User u = new User();
- u.setEmailAddress("t at t.c");
- u.setName("Mr Test");
- u.setPassword("password");
+ private void createBookmarks(final User u) {
final List<Bookmark> bookmarks = new ArrayList<Bookmark>();
final Bookmark b1 = new Bookmark();
@@ -56,4 +73,17 @@
tx.commit();
this.ebean.endTransaction();
}
+
+ /**
+ * creates a user
+ *
+ * @return the user to be created
+ */
+ private User getUser() {
+ final User u = new User();
+ u.setEmailAddress("t at t.c");
+ u.setName("Mr Test");
+ u.setPassword(new String(DigestUtils.sha512("password")));
+ return u;
+ }
}
Deleted: 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 2011-03-22 10:29:42 UTC (rev 224)
+++ trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/service/BookmarkService.java 2011-03-26 17:01:58 UTC (rev 225)
@@ -1,36 +0,0 @@
-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);
-
-}
Copied: trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/service/FavouritesService.java (from rev 222, 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/FavouritesService.java (rev 0)
+++ trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/service/FavouritesService.java 2011-03-26 17:01:58 UTC (rev 225)
@@ -0,0 +1,56 @@
+package com.tyndalehouse.step.core.service;
+
+import java.sql.Timestamp;
+import java.util.List;
+
+import com.tyndalehouse.step.core.data.entities.Bookmark;
+import com.tyndalehouse.step.core.data.entities.History;
+
+/**
+ * A service to add, remove bookmarks, history, etc.
+ *
+ * @author Chris
+ *
+ */
+public interface FavouritesService {
+ /**
+ * 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);
+
+ /**
+ * gets a set of bookmarks associated with the current session
+ *
+ * @param clientHistory the client history that we will merge in
+ *
+ * @return a list of bookmarks
+ */
+ List<History> getHistory(List<History> clientHistory);
+
+ /**
+ * Adds a bookmark if not already there
+ *
+ * @param reference the reference to add to the history item
+ * @param date the date at which it was last updated
+ * @return the id of the history item that was added
+ */
+ int addHistory(String reference, Timestamp date);
+
+}
Property changes on: trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/service/FavouritesService.java
___________________________________________________________________
Added: svn:mime-type
+ text/plain
Modified: 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 2011-03-22 10:29:42 UTC (rev 224)
+++ trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/service/UserDataService.java 2011-03-26 17:01:58 UTC (rev 225)
@@ -29,8 +29,9 @@
* @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
+ * @return the user that has been created
*/
- void register(String emailAddress, String name, String country, String password);
+ User 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
@@ -53,4 +54,9 @@
* logs the current user out
*/
void logout();
+
+ /**
+ * @return the logged in user if the user is logged in
+ */
+ User getLoggedInUser();
}
Deleted: 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 2011-03-22 10:29:42 UTC (rev 224)
+++ trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/service/impl/BookmarkServiceImpl.java 2011-03-26 17:01:58 UTC (rev 225)
@@ -1,86 +0,0 @@
-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();
- }
-}
Copied: trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/service/impl/FavouritesServiceImpl.java (from rev 222, 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/FavouritesServiceImpl.java (rev 0)
+++ trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/service/impl/FavouritesServiceImpl.java 2011-03-26 17:01:58 UTC (rev 225)
@@ -0,0 +1,223 @@
+package com.tyndalehouse.step.core.service.impl;
+
+import static com.avaje.ebean.Expr.eq;
+
+import java.sql.Timestamp;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.avaje.ebean.BeanState;
+import com.avaje.ebean.EbeanServer;
+import com.avaje.ebean.ExpressionList;
+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.History;
+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.FavouritesService;
+
+/**
+ * An implementation of the bookmark
+ *
+ * @author Chris
+ *
+ */
+ at Singleton
+public class FavouritesServiceImpl implements FavouritesService {
+ private static final String HISTORY_ORDER_BY = "lastUpdated";
+ private static final String HISTORY_FETCH_FIELDS = "id, historyReference, lastUpdated";
+ private static final int MAX_HISTORY_ITEMS = 10;
+ private static final String USER_FIELD = "user";
+ private static final Logger LOG = LoggerFactory.getLogger(FavouritesServiceImpl.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 FavouritesServiceImpl(final EbeanServer ebean, final Provider<Session> serverSession) {
+ this.ebean = ebean;
+ this.serverSession = serverSession;
+
+ }
+
+ @Override
+ public List<Bookmark> getBookmarks() {
+ return getFavourites("id, bookmarkReference", Bookmark.class, "id", true);
+ }
+
+ @Override
+ public List<History> getHistory(final List<History> clientHistory) {
+ final List<History> combinedHistories = combineHistories(clientHistory,
+ getFavourites(HISTORY_FETCH_FIELDS, History.class, HISTORY_ORDER_BY, false));
+
+ // now we have de-duplicated lists, we can sort by dates!
+ Collections.sort(combinedHistories, new Comparator<History>() {
+ @Override
+ public int compare(final History o1, final History o2) {
+ // we want the most recent elements at the beginning of the set
+ return o2.getLastUpdated().compareTo(o1.getLastUpdated());
+ }
+ });
+
+ if (LOG.isTraceEnabled()) {
+ LOG.trace("After sorting & de-duping:");
+ for (final History h : combinedHistories) {
+ LOG.trace("Item ref: [{}]", h.getHistoryReference());
+ }
+ }
+
+ // now we prune to a maximum number of items
+ pruneCombinedHistory(combinedHistories);
+
+ // finally, we can unfortunately not return these beans as they contain the "User" object
+ // so want to return just the history...
+ return getFavourites(HISTORY_FETCH_FIELDS, History.class, HISTORY_ORDER_BY, false);
+ }
+
+ /**
+ * Ensures the top of the list is saved to the database, and the bottom part is chopped off and removed
+ *
+ * @param combinedHistories the history that contains too many elements
+ */
+ private void pruneCombinedHistory(final List<History> combinedHistories) {
+ History lastItem = null;
+ for (int ii = 0; ii < MAX_HISTORY_ITEMS && ii < combinedHistories.size(); ii++) {
+ lastItem = combinedHistories.get(ii);
+ // if we ve not persisted this yet, then set user and save
+ if (lastItem.getUser() == null) {
+ lastItem.setUser(this.serverSession.get().getUser());
+ this.ebean.save(lastItem);
+ }
+ }
+
+ // we remove the remaining ones at the end of the list
+ while (combinedHistories.size() > MAX_HISTORY_ITEMS) {
+ final History overflowHistoryItem = combinedHistories.get(combinedHistories.size() - 1);
+ final BeanState beanState = this.ebean.getBeanState(overflowHistoryItem);
+ if (!beanState.isNew()) {
+ this.ebean.delete(overflowHistoryItem);
+ }
+ combinedHistories.remove(combinedHistories.size() - 1);
+ }
+ }
+
+ /**
+ * combines the client and server history by de-duplication and checking the latest dates
+ *
+ * @param clientHistory the client history
+ * @param serverHistory the server history
+ * @return the histories, combined
+ */
+ List<History> combineHistories(final List<History> clientHistory, final List<History> serverHistory) {
+ final Map<String, History> combinedHistory = new HashMap<String, History>();
+
+ // first put all the items from the server history
+ for (final History h : serverHistory) {
+ combinedHistory.put(h.getHistoryReference(), h);
+ }
+
+ // then put all the items from the client history, being careful to overwrite
+ // only if date is more recent
+ for (final History h : clientHistory) {
+ final History existingItem = combinedHistory.get(h.getHistoryReference());
+
+ // if no item exists already OR if the item ante-dates the one we have
+ if (existingItem == null || existingItem.getLastUpdated().before(h.getLastUpdated())) {
+ combinedHistory.put(h.getHistoryReference(), h);
+ }
+ }
+ return new ArrayList<History>(combinedHistory.values());
+ }
+
+ /**
+ * a simple helper method for retrieving favourite items, for a particular user
+ *
+ * @param <T> the type of favourite (history, bookmark)
+ * @param fetchProperties the fields to select out
+ * @param favouriteClass the class that matches T
+ * @param orderByClause the order specified to retrieve the data
+ * @param ascending true to mark ascending order
+ * @return a list of Ts (bookmarks or favourites, ordered correctly, by user logged on)
+ */
+ private <T> List<T> getFavourites(final String fetchProperties, final Class<T> favouriteClass,
+ final String orderByClause, final boolean ascending) {
+ 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");
+ }
+
+ final ExpressionList<T> query = this.ebean.find(favouriteClass).select(fetchProperties).where()
+ .eq(USER_FIELD, user);
+ if (ascending) {
+ return query.order().asc(orderByClause).findList();
+ } else {
+ return query.order().desc(orderByClause).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.isEmpty()) {
+ LOG.debug("Creating bookmark [{}]", reference);
+ 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 [{}]", reference);
+ return bookmarks.get(0).getId();
+ }
+
+ @Override
+ public int addHistory(final String reference, final Timestamp lastUpdated) {
+ // we first check if the history item is already there
+ final History persistedHistoryItem = this.ebean.find(History.class).select("*").where()
+ .eq("historyReference", reference).findUnique();
+
+ final Timestamp lastUpdatedTime = lastUpdated != null ? lastUpdated : new Timestamp(
+ System.currentTimeMillis());
+ if (persistedHistoryItem == null) {
+ final History h = new History();
+ h.setHistoryReference(reference);
+ h.setLastUpdated(lastUpdatedTime);
+ h.setUser(this.serverSession.get().getUser());
+ this.ebean.save(h);
+ return h.getId();
+ }
+
+ // else just update the timestamp
+ persistedHistoryItem.setLastUpdated(lastUpdatedTime);
+ this.ebean.save(persistedHistoryItem);
+ return persistedHistoryItem.getId();
+ }
+}
Property changes on: trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/service/impl/FavouritesServiceImpl.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-22 10:29:42 UTC (rev 224)
+++ trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/service/impl/JSwordServiceImpl.java 2011-03-26 17:01:58 UTC (rev 225)
@@ -66,6 +66,7 @@
* @param bibleCategory the categories of books that should be considered
* @return returns a list of installed modules
*/
+ @Override
public List<Book> getInstalledModules(final BookCategory... bibleCategory) {
if (bibleCategory == null || bibleCategory.length == 0) {
return new ArrayList<Book>();
@@ -79,6 +80,8 @@
// we set up a filter to retrieve just certain types of books
final BookFilter bf = new BookFilter() {
+ @Override
+ @SuppressWarnings("PMD.JUnit4TestShouldUseTestAnnotation")
public boolean test(final Book b) {
return categories.contains(b.getBookCategory());
}
@@ -90,6 +93,7 @@
* @param bibleCategory the list of books that should be considered
* @return a list of all modules
*/
+ @Override
public List<Book> getAllModules(final BookCategory... bibleCategory) {
final List<Book> books = new ArrayList<Book>();
for (final Installer installer : this.bookInstallers) {
@@ -134,6 +138,7 @@
final SAXEventProvider osissep = bookData.getSAXEventProvider();
TransformingSAXEventProvider htmlsep = null;
htmlsep = (TransformingSAXEventProvider) new Converter() {
+ @Override
public SAXEventProvider convert(final SAXEventProvider provider) throws TransformerException {
try {
final String file = requiredTransformation.getFile();
Modified: 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 2011-03-22 10:29:42 UTC (rev 224)
+++ trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/service/impl/UserDataServiceImpl.java 2011-03-26 17:01:58 UTC (rev 225)
@@ -50,7 +50,7 @@
}
@Override
- public void register(final String emailAddress, final String name, final String country,
+ public User 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();
@@ -77,13 +77,11 @@
this.ebean.save(u);
// next, we just associate the current session with the user by logging in
- this.login(emailAddress, password);
+ return 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 Session session = new Session();
final ClientSession clientSession = this.clientSessionProvider.get();
@@ -106,6 +104,16 @@
}
@Override
+ public User getLoggedInUser() {
+ final Session session = this.sessionProvider.get();
+ if (session == null) {
+ return null;
+ }
+
+ return session.getUser();
+ }
+
+ @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();
Modified: trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/utils/JSwordUtils.java
===================================================================
--- trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/utils/JSwordUtils.java 2011-03-22 10:29:42 UTC (rev 224)
+++ trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/utils/JSwordUtils.java 2011-03-26 17:01:58 UTC (rev 225)
@@ -53,6 +53,7 @@
// finally sort by initials
sort(versions, new Comparator<BibleVersion>() {
+ @Override
public int compare(final BibleVersion o1, final BibleVersion o2) {
return o1.getInitials().compareTo(o2.getInitials());
}
Modified: trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/xsl/impl/InterlinearProviderImpl.java
===================================================================
--- trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/xsl/impl/InterlinearProviderImpl.java 2011-03-22 10:29:42 UTC (rev 224)
+++ trunk/step/step-core/src/main/java/com/tyndalehouse/step/core/xsl/impl/InterlinearProviderImpl.java 2011-03-26 17:01:58 UTC (rev 225)
@@ -281,7 +281,7 @@
* @param morph the morphology (identifies how the used is word in the sentence - i.e. grammar)
* @param word the word to be stored
*/
- void addTextualInfo(final String verseReference, final String strong, final String morph,
+ private void addTextualInfo(final String verseReference, final String strong, final String morph,
final String word) {
final String strongKey = getAnyKey(strong);
Modified: trunk/step/step-core/src/main/resources/ebean.properties
===================================================================
--- trunk/step/step-core/src/main/resources/ebean.properties 2011-03-22 10:29:42 UTC (rev 224)
+++ trunk/step/step-core/src/main/resources/ebean.properties 2011-03-26 17:01:58 UTC (rev 225)
@@ -1,17 +1,10 @@
-# -------------------------------------------------------------
-# Load (Dev/Test/Prod) properties external to your war/jar
-# -------------------------------------------------------------
-# You can use load.properties to load the properties from a
-# file external to your war/jar.
-#load.properties.override=${CATALINA_HOME}/conf/myapp.ebean.properties
-
-
ebean.ddl.generate=false
ebean.ddl.run=false
ebean.debug.sql=true
#ebean.debug.lazyload=false
+
+ebean.json.jsonValueAdapter=com.tyndalehouse.step.rest.framework.StepJsonValueAdapter
-
# -------------------------------------------------------------
# Transaction Logging
# -------------------------------------------------------------
Modified: trunk/step/step-core/src/main/resources/step.core.properties
===================================================================
--- trunk/step/step-core/src/main/resources/step.core.properties 2011-03-22 10:29:42 UTC (rev 224)
+++ trunk/step/step-core/src/main/resources/step.core.properties 2011-03-26 17:01:58 UTC (rev 225)
@@ -1,5 +1,5 @@
# Front controller properties
-cache.enabled=true
+cache.enabled=false
#list of installers in the format: host,package,catalog
installer.1=www.crosswire.org,/ftpmirror/pub/sword/packages/rawzip,/ftpmirror/pub/sword/raw
Deleted: 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 2011-03-22 10:29:42 UTC (rev 224)
+++ trunk/step/step-core/src/test/java/com/tyndalehouse/step/core/data/AbstractDataTest.java 2011-03-26 17:01:58 UTC (rev 225)
@@ -1,72 +0,0 @@
-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;
- }
-}
Copied: trunk/step/step-core/src/test/java/com/tyndalehouse/step/core/data/DataDrivenTestExtension.java (from rev 222, 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/DataDrivenTestExtension.java (rev 0)
+++ trunk/step/step-core/src/test/java/com/tyndalehouse/step/core/data/DataDrivenTestExtension.java 2011-03-26 17:01:58 UTC (rev 225)
@@ -0,0 +1,77 @@
+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.
+ *
+ * @author Chris
+ *
+ */
+public class DataDrivenTestExtension {
+ private static volatile EbeanServer ebean;
+ private static volatile Injector injector;
+ private boolean runInTransaction = true;
+
+ /**
+ * prevent initialisation, from anything but extending classes
+ */
+ protected DataDrivenTestExtension() {
+ // do nothing
+ }
+
+ /**
+ * 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/DataDrivenTestExtension.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-22 10:29:42 UTC (rev 224)
+++ trunk/step/step-core/src/test/java/com/tyndalehouse/step/core/data/create/DataTest.java 2011-03-26 17:01:58 UTC (rev 225)
@@ -8,7 +8,7 @@
import org.slf4j.LoggerFactory;
import com.avaje.ebean.SqlRow;
-import com.tyndalehouse.step.core.data.AbstractDataTest;
+import com.tyndalehouse.step.core.data.DataDrivenTestExtension;
import com.tyndalehouse.step.core.data.entities.Timeband;
/**
@@ -17,7 +17,7 @@
* @author Chris
*
*/
-public class DataTest extends AbstractDataTest {
+public class DataTest extends DataDrivenTestExtension {
private static final Logger LOG = LoggerFactory.getLogger(DataTest.class);
/**
Modified: 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 2011-03-22 10:29:42 UTC (rev 224)
+++ trunk/step/step-core/src/test/java/com/tyndalehouse/step/core/data/entities/UserTest.java 2011-03-26 17:01:58 UTC (rev 225)
@@ -5,7 +5,7 @@
import org.junit.Test;
import com.avaje.ebean.Ebean;
-import com.tyndalehouse.step.core.data.AbstractDataTest;
+import com.tyndalehouse.step.core.data.DataDrivenTestExtension;
/**
* tests that i can create a user - probably not going to do this for all entities
@@ -13,18 +13,18 @@
* @author Chris
*
*/
-public class UserTest extends AbstractDataTest {
+public class UserTest extends DataDrivenTestExtension {
/**
* tests we can create a user
*/
@Test
- public void createUser() {
+ public void testCreateUser() {
final User u = new User();
u.setEmailAddress("chrisburrell at test.com");
u.setName("Chris");
u.setPassword("password");
- Ebean.save(u);
+ getEbean().save(u);
final User r = Ebean.find(User.class, u.getId());
assertEquals(u.getEmailAddress(), r.getEmailAddress());
}
Deleted: 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 2011-03-22 10:29:42 UTC (rev 224)
+++ trunk/step/step-core/src/test/java/com/tyndalehouse/step/core/service/impl/BookmarkServiceImplTest.java 2011-03-26 17:01:58 UTC (rev 225)
@@ -1,120 +0,0 @@
-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;
- }
-
-}
Copied: trunk/step/step-core/src/test/java/com/tyndalehouse/step/core/service/impl/FavouritesServiceImplTest.java (from rev 222, 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/FavouritesServiceImplTest.java (rev 0)
+++ trunk/step/step-core/src/test/java/com/tyndalehouse/step/core/service/impl/FavouritesServiceImplTest.java 2011-03-26 17:01:58 UTC (rev 225)
@@ -0,0 +1,258 @@
+package com.tyndalehouse.step.core.service.impl;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Mockito.when;
+
+import java.sql.Timestamp;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.runners.MockitoJUnitRunner;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.inject.Provider;
+import com.tyndalehouse.step.core.data.DataDrivenTestExtension;
+import com.tyndalehouse.step.core.data.entities.Bookmark;
+import com.tyndalehouse.step.core.data.entities.History;
+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)
+ at SuppressWarnings("PMD.TooManyMethods")
+public class FavouritesServiceImplTest extends DataDrivenTestExtension {
+ private static final Logger LOG = LoggerFactory.getLogger(FavouritesServiceImplTest.class);
+
+ @Mock
+ private Provider<Session> serverSession;
+ private FavouritesServiceImpl favouritesService;
+ private User u;
+
+ /**
+ * sets up the service under test
+ */
+ @Before
+ public void setUp() {
+ this.favouritesService = new FavouritesServiceImpl(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.favouritesService.getBookmarks().size());
+ }
+
+ /**
+ * ensures that with no bookmarks, this still works
+ */
+ @Test
+ public void testReadOneBookmarks() {
+ final String testReference = "Genesis 1:1";
+ saveNewBookmarkDirectly(testReference);
+ assertEquals(this.favouritesService.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.favouritesService.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.favouritesService.addBookmark(testReference);
+ final int duplicateBookmarkId = this.favouritesService.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.favouritesService.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;
+ }
+
+ /**
+ * tests that merging history work alright
+ */
+ @Test
+ public void testGetHistoryMerge() {
+ final long currentDate = System.currentTimeMillis();
+ final List<History> client = new ArrayList<History>();
+
+ // add client history
+ addHistoryToList(client, "A", currentDate + 10000);
+ addHistoryToList(client, "C", currentDate + 30000);
+
+ // save server history
+ final History s1 = new History();
+ s1.setHistoryReference("B");
+ s1.setLastUpdated(new Timestamp(currentDate + 20000));
+ s1.setUser(this.serverSession.get().getUser());
+ getEbean().save(s1);
+
+ final History s2 = new History();
+ s2.setHistoryReference("D");
+ s2.setLastUpdated(new Timestamp(currentDate + 40000));
+ s2.setUser(this.serverSession.get().getUser());
+ getEbean().save(s2);
+
+ final List<History> history = this.favouritesService.getHistory(client);
+ assertEquals(4, history.size());
+ assertEquals(s2.getHistoryReference(), history.get(0).getHistoryReference());
+ assertEquals(client.get(1).getHistoryReference(), history.get(1).getHistoryReference());
+ assertEquals(s1.getHistoryReference(), history.get(2).getHistoryReference());
+ assertEquals(client.get(0).getHistoryReference(), history.get(3).getHistoryReference());
+ }
+
+ /**
+ * tests pruning
+ */
+ @Test
+ public void testPruning() {
+ final long currentDate = System.currentTimeMillis();
+ final List<History> client = new ArrayList<History>();
+
+ // create 7 items in client history - naming A,B,C ... G, latest is G
+ for (int ii = 0; ii < 7; ii++) {
+ addHistoryToList(client, new String(new char[] { (char) (65 + ii) }), currentDate + (1 + ii)
+ * 10000);
+ }
+
+ // create server items too, 7 of them, Z ... T, latest is Z
+ for (int ii = 0; ii < 7; ii++) {
+ // save server history
+ final History s1 = new History();
+ s1.setHistoryReference(new String(new char[] { (char) (90 - ii) }));
+ s1.setLastUpdated(new Timestamp(currentDate - (1 + ii) * 10000));
+ s1.setUser(this.serverSession.get().getUser());
+ getEbean().save(s1);
+ LOG.debug("Created item [{}], [{}]", s1.getHistoryReference(), s1.getLastUpdated().getTime());
+ }
+
+ final List<History> history = this.favouritesService.getHistory(client);
+
+ for (final History h : history) {
+ LOG.debug("Item ref: [{}]", h.getHistoryReference());
+ }
+
+ assertEquals(10, history.size());
+ assertEquals("G", history.get(0).getHistoryReference());
+ assertEquals("F", history.get(1).getHistoryReference());
+ assertEquals("E", history.get(2).getHistoryReference());
+ assertEquals("D", history.get(3).getHistoryReference());
+ assertEquals("C", history.get(4).getHistoryReference());
+ assertEquals("B", history.get(5).getHistoryReference());
+ assertEquals("A", history.get(6).getHistoryReference());
+ assertEquals("Z", history.get(7).getHistoryReference());
+ assertEquals("Y", history.get(8).getHistoryReference());
+ assertEquals("X", history.get(9).getHistoryReference());
+ }
+
+ /**
+ * Test that the de-duplication works
+ */
+ @Test
+ public void testCombineHistories() {
+ final List<History> clientHistory = new ArrayList<History>();
+ final List<History> serverHistory = new ArrayList<History>();
+
+ // make some client history
+ addHistoryToList(clientHistory, "A", 1);
+ addHistoryToList(clientHistory, "B", 1);
+ addHistoryToList(clientHistory, "C", 2);
+
+ // make some server history
+ addHistoryToList(serverHistory, "B", 2);
+ addHistoryToList(serverHistory, "C", 1);
+
+ final List<History> history = this.favouritesService.combineHistories(clientHistory, serverHistory);
+ Collections.sort(history, new Comparator<History>() {
+ @Override
+ public int compare(final History o1, final History o2) {
+ return o1.getHistoryReference().compareTo(o2.getHistoryReference());
+ }
+ });
+
+ assertEquals(3, history.size());
+ assertEquals("A", history.get(0).getHistoryReference());
+ assertEquals(1, history.get(0).getLastUpdated().getTime());
+ assertEquals("B", history.get(1).getHistoryReference());
+ assertEquals(2, history.get(1).getLastUpdated().getTime());
+ assertEquals("C", history.get(2).getHistoryReference());
+ assertEquals(2, history.get(2).getLastUpdated().getTime());
+ }
+
+ /**
+ * helper method that adds a history item to a list
+ *
+ * @param historyList the list to which to add the item
+ * @param historyReference the reference
+ * @param lastUpdated the date last updated
+ */
+ private void addHistoryToList(final List<History> historyList, final String historyReference,
+ final long lastUpdated) {
+ final History c1 = new History();
+ c1.setHistoryReference(historyReference);
+ c1.setLastUpdated(new Timestamp(lastUpdated));
+ LOG.debug("Created item [{}], [{}]", c1.getHistoryReference(), c1.getLastUpdated().getTime());
+ historyList.add(c1);
+ }
+}
Property changes on: trunk/step/step-core/src/test/java/com/tyndalehouse/step/core/service/impl/FavouritesServiceImplTest.java
___________________________________________________________________
Added: svn:mime-type
+ text/plain
Modified: 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 2011-03-22 10:29:42 UTC (rev 224)
+++ trunk/step/step-core/src/test/java/com/tyndalehouse/step/core/service/impl/UserDataServiceImplTest.java 2011-03-26 17:01:58 UTC (rev 225)
@@ -14,7 +14,7 @@
import org.mockito.runners.MockitoJUnitRunner;
import com.google.inject.Provider;
-import com.tyndalehouse.step.core.data.AbstractDataTest;
+import com.tyndalehouse.step.core.data.DataDrivenTestExtension;
import com.tyndalehouse.step.core.data.entities.Session;
import com.tyndalehouse.step.core.data.entities.User;
import com.tyndalehouse.step.core.exceptions.StepInternalException;
@@ -27,7 +27,7 @@
*
*/
@RunWith(MockitoJUnitRunner.class)
-public class UserDataServiceImplTest extends AbstractDataTest {
+public class UserDataServiceImplTest extends DataDrivenTestExtension {
@Mock
private Provider<Session> serverSessionProvider;
@Mock
Modified: trunk/step/step-core/src/test/java/com/tyndalehouse/step/core/xsl/impl/InterlinearProviderImplTest.java
===================================================================
--- trunk/step/step-core/src/test/java/com/tyndalehouse/step/core/xsl/impl/InterlinearProviderImplTest.java 2011-03-22 10:29:42 UTC (rev 224)
+++ trunk/step/step-core/src/test/java/com/tyndalehouse/step/core/xsl/impl/InterlinearProviderImplTest.java 2011-03-26 17:01:58 UTC (rev 225)
@@ -2,6 +2,9 @@
import static org.junit.Assert.assertEquals;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+
import org.junit.Test;
/**
@@ -12,16 +15,28 @@
*/
public class InterlinearProviderImplTest {
/**
- * this checks that when keyed with strong, morph and verse number, we can retrieve the word. We should be able to
- * retrieve by (strong,morph), regardless of verse number. We should also be able to retrieve by (strong,verse
- * number)
+ * this checks that when keyed with strong, morph and verse number, we can retrieve the word. We should be
+ * able to retrieve by (strong,morph), regardless of verse number. We should also be able to retrieve by
+ * (strong,verse number)
+ *
+ * @throws InvocationTargetException reflection exception which should fail the test
+ * @throws IllegalAccessException reflection exception which should fail the test
+ * @throws NoSuchMethodException reflect exception which should fail the test
*/
@Test
- public void testInterlinearStrongMorphBased() {
+ public void testInterlinearStrongMorphBased() throws IllegalAccessException, InvocationTargetException,
+ NoSuchMethodException {
final InterlinearProviderImpl interlinear = new InterlinearProviderImpl();
+ // NOTE: because we don't want to expose a method called during initialisation as non-private (could
+ // break
+ // the initialisation, of the provider, we use reflection to open up its access for testing purposes!
+ final Method method = interlinear.getClass().getDeclaredMethod("addTextualInfo", String.class,
+ String.class, String.class, String.class);
+ method.setAccessible(true);
+
// add a word based on a strong,morph
- interlinear.addTextualInfo("v1", "strong", "morph", "word");
+ method.invoke(interlinear, "v1", "strong", "morph", "word");
assertEquals(interlinear.getWord("v1", "strong", "morph"), "word");
assertEquals(interlinear.getWord("x", "strong", "morph"), "word");
Deleted: trunk/step/step-core/src/test/java/log4j.properties
===================================================================
--- trunk/step/step-core/src/test/java/log4j.properties 2011-03-22 10:29:42 UTC (rev 224)
+++ trunk/step/step-core/src/test/java/log4j.properties 2011-03-26 17:01:58 UTC (rev 225)
@@ -1,13 +0,0 @@
-# Set root logger level to DEBUG and its only appender to A1.
-log4j.rootLogger=WARN, A1
-
-# A1 is set to be a ConsoleAppender.
-log4j.appender.A1=org.apache.log4j.ConsoleAppender
-log4j.appender.A1.layout=org.apache.log4j.PatternLayout
-log4j.appender.A1.layout.ConversionPattern=%-15.15c(%-5p) %m%n
-
-
-# Categories
-org.crosswire.jsword.book.sword.ConfigEntry=WARN
-log4j.category.com.tyndalehouse.step=DEBUG
-
Added: trunk/step/step-core/src/test/resources/ebean.properties
===================================================================
--- trunk/step/step-core/src/test/resources/ebean.properties (rev 0)
+++ trunk/step/step-core/src/test/resources/ebean.properties 2011-03-26 17:01:58 UTC (rev 225)
@@ -0,0 +1,73 @@
+ebean.ddl.generate=false
+ebean.ddl.run=false
+ebean.debug.sql=true
+#ebean.debug.lazyload=false
+
+
+# ebean.json.jsonValueAdapter=com.tyndalehouse.step.rest.framework.StepJsonValueAdapter
+
+# -------------------------------------------------------------
+# Transaction Logging
+# -------------------------------------------------------------
+
+# Use java util logging to log transaction details
+#ebean.loggingToJavaLogger=true
+
+# General logging level: (none, explicit, all)
+ebean.logging=all
+
+# Sharing log files: (none, explicit, all)
+ebean.logging.logfilesharing=all
+
+# location of transaction logs
+ebean.logging.directory=logs
+#ebean.logging.directory=${catalina.base}/logs/trans
+
+# Specific Log levels (none, summary, binding, sql)
+ebean.logging.iud=sql
+ebean.logging.query=sql
+ebean.logging.sqlquery=sql
+
+ebean.logging.txnCommit=none
+
+# -------------------------------------------------------------
+# DataSources (If using default Ebean DataSourceFactory)
+# -------------------------------------------------------------
+# You can specify many DataSources (one per EbeanServer) and
+# one of them is defined as the default/primary DataSource
+
+# specify the default/primary DataSource
+#datasource.default=h2
+
+#datasource.h2.username=sa
+#datasource.h2.password=
+#datasource.h2.databaseUrl=jdbc:h2:mem:tests;DB_CLOSE_DELAY=-1
+#datasource.h2.databaseDriver=org.h2.Driver
+#datasource.h2.minConnections=1
+#datasource.h2.maxConnections=25
+#datasource.h2.heartbeatsql=select 1
+#datasource.h2.isolationlevel=read_committed
+
+#datasource.mysql.username=test
+#datasource.mysql.password=test
+#datasource.mysql.databaseUrl=jdbc:mysql://127.0.0.1:3306/test
+#datasource.mysql.databaseDriver=com.mysql.jdbc.Driver
+#datasource.mysql.minConnections=1
+#datasource.mysql.maxConnections=25
+#datasource.mysql.heartbeatsql=select 1
+#datasource.mysql.isolationlevel=read_committed
+
+#datasource.ora.username=test
+#datasource.ora.password=test
+#datasource.ora.databaseUrl=jdbc:oracle:thin:@127.0.0.1:1521:XE
+#datasource.ora.databaseDriver=oracle.jdbc.driver.OracleDriver
+#datasource.ora.minConnections=1
+#datasource.ora.maxConnections=25
+#datasource.ora.heartbeatsql=select count(*) from dual
+#datasource.ora.isolationlevel=read_committed
+
+#datasource.pg.username=test
+#datasource.pg.password=test
+#datasource.pg.databaseUrl=jdbc:postgresql://127.0.0.1:5433/test
+#datasource.pg.databaseDriver=org.postgresql.Driver
+#datasource.pg.heartbeatsql=select 1
Property changes on: trunk/step/step-core/src/test/resources/ebean.properties
___________________________________________________________________
Added: svn:mime-type
+ text/plain
Modified: trunk/step/step-core/src/test/resources/log4j.properties
===================================================================
--- trunk/step/step-core/src/test/resources/log4j.properties 2011-03-22 10:29:42 UTC (rev 224)
+++ trunk/step/step-core/src/test/resources/log4j.properties 2011-03-26 17:01:58 UTC (rev 225)
@@ -8,5 +8,5 @@
log4j.appender.A1.layout.ConversionPattern=%d %-5p %C{1}:%L - %m%n
log4j.category.org.crosswire.jsword.book.sword.ConfigEntry=WARN
-log4j.category.com.tyndalehouse.step=INFO
+log4j.category.com.tyndalehouse.step=DEBUG
Modified: trunk/step/step-parent/pom.xml
===================================================================
--- trunk/step/step-parent/pom.xml 2011-03-22 10:29:42 UTC (rev 224)
+++ trunk/step/step-parent/pom.xml 2011-03-26 17:01:58 UTC (rev 225)
@@ -46,6 +46,7 @@
<commons-configuration.version>1.6</commons-configuration.version>
<commons-dbcp.version>1.3</commons-dbcp.version>
<commons-io.version>1.4</commons-io.version>
+ <commons-codec.version>1.4</commons-codec.version>
<commons-dbutils.version>1.3</commons-dbutils.version>
<commons-httpclient.version>3.1</commons-httpclient.version>
@@ -205,6 +206,11 @@
<artifactId>commons-lang</artifactId>
<version>${commons-lang.version}</version>
</dependency>
+ <dependency>
+ <groupId>commons-codec</groupId>
+ <artifactId>commons-codec</artifactId>
+ <version>${commons-codec.version}</version>
+ </dependency>
<dependency>
<groupId>commons-collections</groupId>
Modified: 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 2011-03-22 10:29:42 UTC (rev 224)
+++ trunk/step/step-web/src/main/java/com/tyndalehouse/step/models/WebSessionImpl.java 2011-03-26 17:01:58 UTC (rev 225)
@@ -24,6 +24,7 @@
/**
* @return the session
*/
+ @Override
public String getSessionId() {
return this.sessionId;
}
@@ -38,6 +39,7 @@
/**
* @return the ipAddress
*/
+ @Override
public String getIpAddress() {
return this.ipAddress;
}
Modified: trunk/step/step-web/src/main/java/com/tyndalehouse/step/rest/controllers/BibleController.java
===================================================================
--- trunk/step/step-web/src/main/java/com/tyndalehouse/step/rest/controllers/BibleController.java 2011-03-22 10:29:42 UTC (rev 224)
+++ trunk/step/step-web/src/main/java/com/tyndalehouse/step/rest/controllers/BibleController.java 2011-03-26 17:01:58 UTC (rev 225)
@@ -4,6 +4,7 @@
import java.util.ArrayList;
import java.util.List;
+import java.util.Locale;
import org.apache.commons.lang.Validate;
import org.slf4j.Logger;
@@ -94,7 +95,7 @@
final List<LookupOption> lookupOptions = new ArrayList<LookupOption>();
if (userOptions != null) {
for (final String o : userOptions) {
- lookupOptions.add(LookupOption.valueOf(o.toUpperCase()));
+ lookupOptions.add(LookupOption.valueOf(o.toUpperCase(Locale.ENGLISH)));
}
}
Deleted: 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 2011-03-22 10:29:42 UTC (rev 224)
+++ trunk/step/step-web/src/main/java/com/tyndalehouse/step/rest/controllers/BookmarkController.java 2011-03-26 17:01:58 UTC (rev 225)
@@ -1,60 +0,0 @@
-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);
- }
-}
Copied: trunk/step/step-web/src/main/java/com/tyndalehouse/step/rest/controllers/FavouritesController.java (from rev 222, 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/FavouritesController.java (rev 0)
+++ trunk/step/step-web/src/main/java/com/tyndalehouse/step/rest/controllers/FavouritesController.java 2011-03-26 17:01:58 UTC (rev 225)
@@ -0,0 +1,113 @@
+package com.tyndalehouse.step.rest.controllers;
+
+import java.sql.Timestamp;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.commons.lang.StringUtils;
+
+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.History;
+import com.tyndalehouse.step.core.exceptions.StepInternalException;
+import com.tyndalehouse.step.core.service.FavouritesService;
+
+/**
+ * This helps manage bookmarks and history items. This implementation simply wraps around the Favourites
+ * 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 FavouritesController {
+ private final FavouritesService favouritesService;
+
+ /**
+ * We simply inject the bookmark service and proxy requests through
+ *
+ * @param bookmarkService the bookmark service used to get our data
+ */
+ @Inject
+ public FavouritesController(final FavouritesService bookmarkService) {
+ this.favouritesService = bookmarkService;
+ }
+
+ /**
+ * gets a set of bookmarks associated with the current session
+ *
+ * @return a list of bookmarks
+ */
+ public List<Bookmark> getBookmarks() {
+ return this.favouritesService.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.favouritesService.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.favouritesService.addBookmark(reference);
+ }
+
+ /**
+ * The encoding might be client specific, so we first decode the information sent, and then pass it
+ * through into a list of objects
+ *
+ * @param clientHistoryString the string as passed by the UI of the current cookie contents
+ * @return all the history items to the UI, merged with the client history as appropriate
+ */
+ public List<History> getHistory(final String clientHistoryString) {
+ final List<History> clientHistory = new ArrayList<History>();
+
+ // check for no history - currently a bit of a hack
+ if (StringUtils.isNotEmpty(clientHistoryString) && !"null".equals(clientHistoryString)) {
+
+ // first we split by '#' to get individual portions of the history list
+ // then by @ sign to get the date at which they were last updated
+ // we will do a fairly gross approximation here and refactor if this causes issues
+ try {
+ final String[] tokens = StringUtils.split(clientHistoryString, "~@");
+ for (int ii = 0; ii < tokens.length; ii = ii + 2) {
+ final History item = new History();
+ item.setHistoryReference(tokens[ii]);
+ item.setLastUpdated(new Timestamp(Long.parseLong(tokens[ii + 1])));
+ clientHistory.add(item);
+ }
+ } catch (final NumberFormatException e) {
+ throw new StepInternalException("Unable to parse stored history", e);
+ }
+ }
+ return this.favouritesService.getHistory(clientHistory);
+ }
+
+ /**
+ * adds or updates the history item
+ *
+ * @param reference the reference to be checked and added/updated
+ * @return the id of the reference
+ */
+ public int addHistory(final String reference) {
+ final String[] split = StringUtils.split(reference, '@');
+ if (split.length != 2) {
+ throw new StepInternalException("Unable to add history item to user profile.");
+ }
+
+ return this.favouritesService.addHistory(split[0], new Timestamp(Long.valueOf(split[1])));
+ }
+}
Property changes on: trunk/step/step-web/src/main/java/com/tyndalehouse/step/rest/controllers/FavouritesController.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-22 10:29:42 UTC (rev 224)
+++ trunk/step/step-web/src/main/java/com/tyndalehouse/step/rest/controllers/FrontController.java 2011-03-26 17:01:58 UTC (rev 225)
@@ -41,6 +41,9 @@
*/
@Singleton
public class FrontController extends HttpServlet {
+ private static final String ENTITIES_PACKAGE = "com.tyndalehouse.step.core.data.entities";
+ private static final String AVAJE_PACKAGE = "com.avaje";
+
private static final String UTF_8_ENCODING = "UTF-8";
private static final Logger LOGGER = LoggerFactory.getLogger(FrontController.class);
private static final char PACKAGE_SEPARATOR = '.';
@@ -52,12 +55,13 @@
private final transient Injector guiceInjector;
// TODO but also check thread safety and whether we should share this object
private final transient ObjectMapper jsonMapper = new ObjectMapper();
+ // TODO check if this is thread safe, and if so, then make private field
+ private final transient JsonContext ebeanJson;
// 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;
/**
@@ -67,13 +71,15 @@
* @param isCacheEnabled indicates whether responses should be cached for fast retrieval TODO rename all
* ebeans to DB
* @param ebean the db access/persisitence object
+ * @param errorResolver the error resolver is the object that helps us translate errors for the client
*/
@Inject
public FrontController(final Injector guiceInjector,
@Named("cache.enabled") final Boolean isCacheEnabled, final EbeanServer ebean,
final ClientErrorResolver errorResolver) {
this.guiceInjector = guiceInjector;
- this.ebean = ebean;
+ this.ebeanJson = ebean.createJsonContext();
+
this.errorResolver = errorResolver;
this.isCacheEnabled = Boolean.TRUE.equals(isCacheEnabled);
}
@@ -155,7 +161,7 @@
return new ClientHandledIssue(cause.getMessage(), this.errorResolver.resolve(cause.getClass()));
} else if (cause instanceof IllegalArgumentException) {
// a validation exception occurred
- LOGGER.trace(e.getMessage(), e);
+ LOGGER.warn(e.getMessage(), e);
return new ClientHandledIssue(cause.getMessage());
}
@@ -176,13 +182,16 @@
// therefore we can't just use simple jackson mapper
if (responseValue == null) {
return new byte[0];
- } else if (responseValue.getClass().getPackage().getName().startsWith("com.avaje")) {
- final JsonContext json = this.ebean.createJsonContext();
+ } else {
+ final String responsePackage = responseValue.getClass().getPackage().getName();
+ if (responsePackage.startsWith(ENTITIES_PACKAGE)
+ || responseValue.getClass().getPackage().getName().startsWith(AVAJE_PACKAGE)) {
- // convert list of beans into JSON
- response = json.toJsonString(responseValue);
- } else {
- response = this.jsonMapper.writeValueAsString(responseValue);
+ // convert list of beans into JSON
+ response = this.ebeanJson.toJsonString(responseValue);
+ } else {
+ response = this.jsonMapper.writeValueAsString(responseValue);
+ }
}
return response.getBytes(UTF_8_ENCODING);
Modified: 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 2011-03-22 10:29:42 UTC (rev 224)
+++ trunk/step/step-web/src/main/java/com/tyndalehouse/step/rest/controllers/UserController.java 2011-03-26 17:01:58 UTC (rev 225)
@@ -1,5 +1,7 @@
package com.tyndalehouse.step.rest.controllers;
+import org.apache.commons.codec.digest.DigestUtils;
+
import com.google.inject.Inject;
import com.tyndalehouse.step.core.data.entities.User;
import com.tyndalehouse.step.core.service.UserDataService;
@@ -30,25 +32,37 @@
* @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
+ * @return the registered user TODO salt
*/
- public void register(final String emailAddress, final String name, final String country,
+ public User 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...
+ return this.userDataService.register(emailAddress, name, country,
+ new String(DigestUtils.sha512(password)));
}
/**
- * TODO sha-1 encoding Associates the current session with the username assuming password and username
- * authenticates
+ * 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);
+ return this.userDataService.login(emailAddress, new String(DigestUtils.sha512(password)));
}
+ /**
+ * Logs a user out
+ */
public void logout() {
this.userDataService.logout();
}
+
+ /**
+ * @return true if logged in
+ */
+ public User getLoggedInUser() {
+ return this.userDataService.getLoggedInUser();
+ }
}
Deleted: trunk/step/step-web/src/main/java/com/tyndalehouse/step/rest/framework/Cached.java
===================================================================
--- trunk/step/step-web/src/main/java/com/tyndalehouse/step/rest/framework/Cached.java 2011-03-22 10:29:42 UTC (rev 224)
+++ trunk/step/step-web/src/main/java/com/tyndalehouse/step/rest/framework/Cached.java 2011-03-26 17:01:58 UTC (rev 225)
@@ -1,22 +0,0 @@
-package com.tyndalehouse.step.rest.framework;
-
-import static java.lang.annotation.ElementType.METHOD;
-import static java.lang.annotation.RetentionPolicy.RUNTIME;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
-
-/**
- * This indicates that the REST-like call can be cached by the server
- *
- * @author Chris
- *
- */
- at Target(METHOD)
- at Retention(RUNTIME)
-public @interface Cached {
- /** true to indicate that the results from the method can be cached */
- // CHECKSTYLE:OFF
- boolean value = false;
- // CHECKSTYLE:ON
-}
Added: trunk/step/step-web/src/main/java/com/tyndalehouse/step/rest/framework/StepJsonValueAdapter.java
===================================================================
--- trunk/step/step-web/src/main/java/com/tyndalehouse/step/rest/framework/StepJsonValueAdapter.java (rev 0)
+++ trunk/step/step-web/src/main/java/com/tyndalehouse/step/rest/framework/StepJsonValueAdapter.java 2011-03-26 17:01:58 UTC (rev 225)
@@ -0,0 +1,22 @@
+package com.tyndalehouse.step.rest.framework;
+
+import java.sql.Timestamp;
+import java.text.SimpleDateFormat;
+import java.util.Locale;
+
+import com.avaje.ebeaninternal.server.text.json.DefaultJsonValueAdapter;
+
+/**
+ * we override the default JSON value adapter to provide custom serialisation for dates
+ *
+ * @author Chris
+ *
+ */
+public class StepJsonValueAdapter extends DefaultJsonValueAdapter {
+ @Override
+ public String jsonFromTimestamp(final Timestamp date) {
+ final SimpleDateFormat sdf = new SimpleDateFormat("\"EEE, d MMM yyyy HH:mm:ss Z\"",
+ Locale.getDefault());
+ return sdf.format(date);
+ }
+}
Property changes on: trunk/step/step-web/src/main/java/com/tyndalehouse/step/rest/framework/StepJsonValueAdapter.java
___________________________________________________________________
Added: svn:mime-type
+ text/plain
Modified: trunk/step/step-web/src/main/webapp/js/bookmark.js
===================================================================
--- trunk/step/step-web/src/main/webapp/js/bookmark.js 2011-03-22 10:29:42 UTC (rev 224)
+++ trunk/step/step-web/src/main/webapp/js/bookmark.js 2011-03-26 17:01:58 UTC (rev 225)
@@ -1,7 +1,8 @@
-
/**
* The bookmarks components record events that are happening across the application,
* for e.g. passage changes, but will also show related information to the passage.
+ *
+ * This could probably now be simplified by doing all the logic server side for the history
*/
function Bookmark(bookmarkContainer) {
this.historyContainer = $("#historyDisplayPane");
@@ -17,7 +18,12 @@
this.bookmarkContainer.hear("bookmark-addition-requested", function(selfElement, data) {
self.addBookmark(data.reference);
});
+
+ this.bookmarkContainer.hear("user-logged-in", function(selfElement, data) {
+ self.mergeHistory(data);
+ });
+
this.initialiseHistory();
//add accordion handlers
@@ -43,14 +49,15 @@
self.loadBookmarks();
}).hear("user-logged-out", function(selfElement, data) {
//we clear the bookmarks
-
self.loadedBookmarks = false;
self.bookmarkContainer.html("");
});
}
+//TODO make server setting
Bookmark.maxBookmarks = 10;
-Bookmark.historyDelimiter = '#';
+//TODO make server setting
+Bookmark.historyDelimiter = '~';
//we need to ignore the first two passage changes since we have those in the history
//the history giving us the order of things
@@ -70,9 +77,18 @@
//if we have the bookmark already, then we stop here
var history = this.getHistory();
- var indexInHistory = $.inArray(passageReference, history);
+ //check if we have the reference in the array (starts for example: '1 John@' where @ denotes the time at which it happened
+ var indexInHistory = 0;
+ for(var indexInHistory = 0; indexInHistory < history.length; indexInHistory++) {
+ if(history[indexInHistory].match("^" + passageReference + "@")) {
+ break;
+ }
+ }
+
+ //if we didn't find the item
+ var fullHistoryStorageText = passageReference + "@" + new Date().getTime();
- if(indexInHistory == -1) {
+ if(indexInHistory == history.length) {
if(history.length > Bookmark.maxBookmarks) {
//we remove the first element in the array (i.e. the last child).
history.pop();
@@ -81,13 +97,15 @@
//then add
this.createHistoryItem(passageReference);
- history.unshift(passageReference);
+ history.unshift(fullHistoryStorageText);
+ $.get(HISTORY_ADD + fullHistoryStorageText);
} else {
//reposition item...
var item = $("div.bookmarkItem", this.historyContainer).eq(indexInHistory).detach();
history.splice(indexInHistory, 1);
this.historyContainer.prepend(item);
- history.unshift(passageReference);
+ history.unshift(fullHistoryStorageText);
+ $.get(HISTORY_ADD + fullHistoryStorageText);
}
this.setHistory(history);
@@ -103,13 +121,47 @@
Bookmark.prototype.initialiseHistory = function() {
+ //create the history from the cookie, or - logged-in event will override
+ var self = this;
+ self.createHistoryItemsFromCookies();
+}
+
+/**
+ * we need to work out what our current history is like, and then reset it to be appropriate
+ */
+Bookmark.prototype.mergeHistory = function() {
+ //we call this when we're logged on, so we get can send the history to the server, merge and set it back
+ var self = this;
+ $.getSafe(HISTORY_GET + $.cookie("history"), function(data) {
+ //we now have the merged history
+ self.clearHistory();
+
+ var historyText = "";
+ if(data) {
+ $.each(data, function(index, item) {
+ //for each item, it has a lastUpdated and a historyReference
+ historyText += item.historyReference + '@' + new Date(item.lastUpdated).getTime() + Bookmark.historyDelimiter;
+ });
+
+ $.cookie("history", historyText);
+ self.createHistoryItemsFromCookies();
+ }
+ });
+};
+
+/**
+ * creates the history from the items stored in the cookie,
+ * this is called either after setting the persisted history
+ * into the cookie, or when the user is not logged in!
+ */
+Bookmark.prototype.createHistoryItemsFromCookies = function() {
var history = this.getHistory();
if(history != null) {
for(var ii = history.length -1; ii >= 0; ii--) {
this.createHistoryItem(history[ii]);
}
}
-}
+};
/**
* loads the bookmarks from the server
@@ -128,7 +180,7 @@
}
});
}
-}
+};
/**
* creates a history item
@@ -144,8 +196,18 @@
this.createItem(passageReference, this.bookmarkContainer, false);
};
+/**
+ * clears the history
+ */
+Bookmark.prototype.clearHistory = function() {
+ this.historyContainer.empty();
+};
-Bookmark.prototype.createItem = function(passageReference, container, ascending) {
+
+Bookmark.prototype.createItem = function(passageCookieReference, container, ascending) {
+ var passageRefParts = passageCookieReference.split('@');
+ var passageReference = passageRefParts[0];
+
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>";
Modified: trunk/step/step-web/src/main/webapp/js/login.js
===================================================================
--- trunk/step/step-web/src/main/webapp/js/login.js 2011-03-22 10:29:42 UTC (rev 224)
+++ trunk/step/step-web/src/main/webapp/js/login.js 2011-03-26 17:01:58 UTC (rev 225)
@@ -20,6 +20,15 @@
this.root.hear("show-register-popup", function(selfElement, data) {
self.showLoginPopup();
});
+
+ //we check whether we are logged on already...
+ $.getSafe(USER_GET_LOGGED_IN_USER, function(data) {
+ //if we have data, we use it to show it
+ if(data && data.name) {
+ //set the name of the user
+ self.setLoggedInUser(data.name);
+ }
+ });
}
/**
@@ -46,23 +55,12 @@
$.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();
- }
+ self.performSuccessfulLogin(data, popup, callback);
});
},
"Create an account" : function() {
//show register popup
- self.showRegisterPopup();
+ self.showRegisterPopup(callback);
},
"Cancel" : function() {
$(this).dialog("close");
@@ -73,13 +71,43 @@
});
};
-Login.prototype.showRegisterPopup = function() {
+/**
+ * performs a succesful login by changing the name at the top right of the screen
+ */
+Login.prototype.performSuccessfulLogin = function(data, popup, callback) {
+ this.setLoggedInUser(data.name);
+ $(popup).dialog("close");
+
+ if(callback) {
+ callback();
+ }
+};
+
+/**
+ * shows the register popup
+ */
+Login.prototype.showRegisterPopup = function(callback) {
this.registerMode = true;
var self = this;
this.root.dialog({
buttons : {
"Register" : function() {
// send information to server
+ var email = $("#emailAddress", self.root).val();
+ var name = $("#name", self.root).val();
+ var country = $("#country", self.root).val();
+ var password = $("#password", self.root).val();
+ var popup = this;
+
+ $.getSafe(USER_REGISTER +
+ email + "/" +
+ name + "/" +
+ country + "/" +
+ password,
+ function(data) {
+ self.performSuccessfulLogin(data, popup, callback);
+ }
+ );
},
"Cancel" : function() {
self.showLoginPopup();
@@ -121,3 +149,19 @@
}
});
};
+
+/**
+ * sets the user's name up and rebinds the click to
+ * be a logout operation instead.
+ */
+Login.prototype.setLoggedInUser = function(name) {
+ var loginLink = $("#loginLink");
+ var self = this;
+
+ loginLink.text(name);
+ loginLink.unbind('click');
+ $.shout("user-logged-in");
+ loginLink.click(function() {
+ self.showLogout();
+ });
+}
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-22 10:29:42 UTC (rev 224)
+++ trunk/step/step-web/src/main/webapp/js/ui_hooks.js 2011-03-26 17:01:58 UTC (rev 225)
@@ -9,9 +9,12 @@
// The following section defines method names and controller names
// These are used as part of the rest-like calls
/////////////////////////////////////////////////////////////////////////
-BOOKMARKS_GET = "rest/bookmark/getBookmarks";
-BOOKMARKS_ADD = "rest/bookmark/addBookmark/";
+BOOKMARKS_GET = "rest/favourites/getBookmarks";
+BOOKMARKS_ADD = "rest/favourites/addBookmark/";
+HISTORY_GET = "rest/favourites/getHistory/";
+HISTORY_ADD = "rest/favourites/addHistory/";
+
BIBLE_GET_BIBLE_VERSIONS = "rest/bible/getBibleVersions/";
BIBLE_GET_BIBLE_TEXT = "rest/bible/getBibleText/";
BIBLE_GET_FEATURES = "rest/bible/getFeatures/";
@@ -31,7 +34,8 @@
USER_LOGIN = "rest/user/login/";
USER_LOGOUT = "rest/user/logout/";
USER_REGISTER = "rest/user/register/"
-
+USER_GET_LOGGED_IN_USER = "rest/user/getLoggedInUser";
+
//////////////////////////
// SOME DEFAULTS
//////////////////////////
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-22 10:29:42 UTC (rev 224)
+++ trunk/step/step-web/src/test/java/com/tyndalehouse/step/rest/controllers/FrontControllerTest.java 2011-03-26 17:01:58 UTC (rev 225)
@@ -16,7 +16,6 @@
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
-import java.util.ArrayList;
import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
@@ -27,6 +26,7 @@
import org.junit.Test;
+import com.avaje.ebean.EbeanServer;
import com.google.inject.Injector;
import com.tyndalehouse.step.core.exceptions.StepInternalException;
import com.tyndalehouse.step.core.service.BibleInformationService;
@@ -38,6 +38,7 @@
* @author Chris
*
*/
+ at SuppressWarnings("PMD.TooManyMethods")
public class FrontControllerTest {
/**
@@ -50,7 +51,7 @@
final HttpServletRequest request = mock(HttpServletRequest.class);
final HttpServletResponse response = mock(HttpServletResponse.class);
- final FrontController fc = spy(new FrontController(null, false, null, null));
+ final FrontController fc = spy(new FrontController(null, false, mock(EbeanServer.class), null));
final StepRequest parsedRequest = new StepRequest("SomeController", "someMethod", new String[] {
"arg1", "arg2" });
final ServletOutputStream mockOutputStream = mock(ServletOutputStream.class);
@@ -74,7 +75,7 @@
final HttpServletResponse response = mock(HttpServletResponse.class);
final StepInternalException testException = new StepInternalException("A test exception");
- final FrontController fc = spy(new FrontController(null, false, null, null));
+ final FrontController fc = spy(new FrontController(null, false, mock(EbeanServer.class), null));
final StepRequest parsedRequest = new StepRequest("SomeController", "someMethod", new String[] {
"arg1", "arg2" });
@@ -94,7 +95,8 @@
// 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, null, null);
+ final FrontController fc = new FrontController(mock(Injector.class), Boolean.FALSE,
+ mock(EbeanServer.class), null);
// when
final Object[] args = fc.getArgs(sampleRequest, 24);
@@ -113,7 +115,8 @@
// 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, null, null);
+ final FrontController fc = new FrontController(mock(Injector.class), Boolean.FALSE,
+ mock(EbeanServer.class), null);
// when
final Object[] args = fc.getArgs(sampleRequest, 24);
@@ -131,7 +134,7 @@
*/
@Test
public void testGetPath() throws ServletException {
- final FrontController fc = new FrontController(null, null, null, null);
+ final FrontController fc = new FrontController(null, null, mock(EbeanServer.class), null);
final FrontController spy = spy(fc);
final ServletContext mockServletContext = mock(ServletContext.class);
@@ -158,7 +161,8 @@
final HttpServletResponse response = mock(HttpServletResponse.class);
final int sampleRequestLength = 10;
- new FrontController(null, null, null, null).setupHeaders(response, sampleRequestLength);
+ new FrontController(null, null, mock(EbeanServer.class), null).setupHeaders(response,
+ sampleRequestLength);
verify(response).addDateHeader(eq("Date"), anyLong());
verify(response).setCharacterEncoding("UTF-8");
@@ -176,7 +180,7 @@
@Test
public void testGetControllerMethod() throws IllegalAccessException, InvocationTargetException {
final FrontController frontController = new FrontController(mock(Injector.class), Boolean.FALSE,
- null, null);
+ mock(EbeanServer.class), null);
final BibleInformationService bibleInfo = mock(BibleInformationService.class);
final BibleController controllerInstance = new BibleController(bibleInfo);
@@ -196,7 +200,8 @@
public void testGetController() {
final String controllerName = "Bible";
final Injector mockInjector = mock(Injector.class);
- final FrontController frontController = new FrontController(mockInjector, Boolean.FALSE, null, null);
+ final FrontController frontController = new FrontController(mockInjector, Boolean.FALSE,
+ mock(EbeanServer.class), null);
final BibleController mockController = mock(BibleController.class);
when(mockInjector.getInstance(BibleController.class)).thenReturn(mockController);
@@ -213,12 +218,12 @@
*/
@Test
public void testGetClasses() {
- final FrontController fc = new FrontController(null, Boolean.FALSE, null, null);
+ final FrontController fc = new FrontController(null, Boolean.FALSE, mock(EbeanServer.class), null);
assertEquals(0, fc.getClasses(null).length);
assertEquals(0, fc.getClasses(new Object[0]).length);
- assertArrayEquals(new Class<?>[] { String.class, ArrayList.class },
- fc.getClasses(new Object[] { "hello", new ArrayList<String>() }));
+ assertArrayEquals(new Class<?>[] { String.class, Integer.class },
+ fc.getClasses(new Object[] { "hello", Integer.valueOf(1) }));
}
@@ -227,7 +232,7 @@
*/
@Test
public void testJsonEncoding() {
- final byte[] encodedJsonResponse = new FrontController(null, null, null, null)
+ final byte[] encodedJsonResponse = new FrontController(null, null, mock(EbeanServer.class), null)
.getEncodedJsonResponse("abc");
// this reprensents the string "{abc}"
@@ -243,7 +248,7 @@
*/
@Test
public void testDoErrorHandlesCorrectly() throws IOException {
- final FrontController fc = new FrontController(null, null, null, null);
+ final FrontController fc = new FrontController(null, null, mock(EbeanServer.class), null);
final HttpServletResponse response = mock(HttpServletResponse.class);
final StepRequest stepRequest = new StepRequest("controller", "method", null);
final ServletOutputStream outputStream = mock(ServletOutputStream.class);
@@ -278,7 +283,7 @@
contextName + requestSeparator + servletName + requestSeparator + controllerName
+ requestSeparator + methodName + requestSeparator + arg1 + requestSeparator + arg2);
- final FrontController frontController = new FrontController(null, null, null, null);
+ final FrontController frontController = new FrontController(null, null, mock(EbeanServer.class), null);
frontController.init(mock(ServletConfig.class));
final FrontController spy = spy(frontController);
@@ -303,7 +308,7 @@
final StepRequest sr = new StepRequest("bible", "getAllFeatures", new String[] {});
final BibleController testController = mock(BibleController.class);
- final FrontController fc = spy(new FrontController(null, null, null, null));
+ final FrontController fc = spy(new FrontController(null, null, mock(EbeanServer.class), null));
doReturn(testController).when(fc).getController("bible");
// do test
More information about the Tynstep-svn
mailing list