summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJesse Morgan <jesse@jesterpm.net>2014-03-24 21:38:02 -0700
committerJesse Morgan <jesse@jesterpm.net>2014-03-31 19:39:30 -0700
commitcfb2c5ef6582e51ae9cfdfff35e12b5b7fdc24fb (patch)
tree88df0d7004d73e113f6f9c95c599bd27ff91110f /src
parent44de44ac6a3879c78b7e31d7e460bb0125275237 (diff)
Enabling the Feed and various bug fixes.
* Fixing thread ordering. * Adding a limit of 5 threads per topic. * Changing frontend /account references to UserRecord.
Diffstat (limited to 'src')
-rw-r--r--src/com/p4square/grow/backend/db/CassandraCollectionProvider.java12
-rw-r--r--src/com/p4square/grow/backend/feed/ThreadResource.java5
-rw-r--r--src/com/p4square/grow/backend/feed/TopicResource.java17
-rw-r--r--src/com/p4square/grow/frontend/AccountRedirectResource.java64
-rw-r--r--src/com/p4square/grow/frontend/FeedData.java15
-rw-r--r--src/com/p4square/grow/frontend/SurveyPageResource.java47
-rw-r--r--src/com/p4square/grow/frontend/TrainingPageResource.java17
-rw-r--r--src/com/p4square/grow/model/Message.java8
-rw-r--r--src/com/p4square/grow/model/MessageThread.java4
-rw-r--r--src/com/p4square/grow/model/UserRecord.java16
-rw-r--r--src/templates/templates/communityfeed.ftl3
11 files changed, 106 insertions, 102 deletions
diff --git a/src/com/p4square/grow/backend/db/CassandraCollectionProvider.java b/src/com/p4square/grow/backend/db/CassandraCollectionProvider.java
index cc11828..5e83247 100644
--- a/src/com/p4square/grow/backend/db/CassandraCollectionProvider.java
+++ b/src/com/p4square/grow/backend/db/CassandraCollectionProvider.java
@@ -7,7 +7,7 @@ package com.p4square.grow.backend.db;
import java.io.IOException;
import java.util.Collections;
-import java.util.HashMap;
+import java.util.LinkedHashMap;
import java.util.Map;
import com.netflix.astyanax.model.Column;
@@ -45,21 +45,21 @@ public class CassandraCollectionProvider<V> implements CollectionProvider<String
@Override
public Map<String, V> query(String collection, int limit) throws IOException {
- Map<String, V> result = new HashMap<>();
+ Map<String, V> result = new LinkedHashMap<>();
ColumnList<String> row = mDb.getRow(mCF, collection);
if (!row.isEmpty()) {
int count = 0;
for (Column<String> c : row) {
+ if (limit >= 0 && ++count > limit) {
+ break; // Limit reached.
+ }
+
String key = c.getName();
String blob = c.getStringValue();
V obj = decode(blob);
result.put(key, obj);
-
- if (limit >= 0 && ++count > limit) {
- break; // Limit reached.
- }
}
}
diff --git a/src/com/p4square/grow/backend/feed/ThreadResource.java b/src/com/p4square/grow/backend/feed/ThreadResource.java
index c0604a8..e8f46c2 100644
--- a/src/com/p4square/grow/backend/feed/ThreadResource.java
+++ b/src/com/p4square/grow/backend/feed/ThreadResource.java
@@ -8,7 +8,6 @@ import java.io.IOException;
import java.util.Date;
import java.util.Map;
-import java.util.UUID;
import org.restlet.data.Status;
import org.restlet.resource.ServerResource;
@@ -68,7 +67,7 @@ public class ThreadResource extends ServerResource {
}
/**
- * POST a new thread to the topic.
+ * POST a new message to the thread.
*/
@Override
protected Representation post(Representation entity) {
@@ -86,7 +85,7 @@ public class ThreadResource extends ServerResource {
// Force the thread id and message to be what we expect.
message.setThreadId(mThreadId);
- message.setId(String.format("%x-%s", System.currentTimeMillis(), UUID.randomUUID().toString()));
+ message.setId(Message.generateId());
if (message.getCreated() == null) {
message.setCreated(new Date());
diff --git a/src/com/p4square/grow/backend/feed/TopicResource.java b/src/com/p4square/grow/backend/feed/TopicResource.java
index 5826355..24b6a92 100644
--- a/src/com/p4square/grow/backend/feed/TopicResource.java
+++ b/src/com/p4square/grow/backend/feed/TopicResource.java
@@ -8,7 +8,6 @@ import java.io.IOException;
import java.util.Date;
import java.util.Map;
-import java.util.UUID;
import org.restlet.data.Status;
import org.restlet.resource.ServerResource;
@@ -50,10 +49,20 @@ public class TopicResource extends ServerResource {
return new JacksonRepresentation(FeedDataProvider.TOPICS);
}
- // TODO: Support limit query parameter.
+ // Parse limit query parameter.
+ int limit = -1;
+ String limitString = getQueryValue("limit");
+ if (limitString != null) {
+ try {
+ limit = Integer.parseInt(limitString);
+ } catch (NumberFormatException e) {
+ setStatus(Status.CLIENT_ERROR_BAD_REQUEST);
+ return null;
+ }
+ }
try {
- Map<String, MessageThread> threads = mBackend.getThreadProvider().query(mTopic);
+ Map<String, MessageThread> threads = mBackend.getThreadProvider().query(mTopic, limit);
return new JacksonRepresentation(threads.values());
} catch (IOException e) {
@@ -90,7 +99,7 @@ public class TopicResource extends ServerResource {
MessageThread newThread = MessageThread.createNew();
// Force the thread id and message to be what we expect.
- message.setId(String.format("%x-%s", System.currentTimeMillis(), UUID.randomUUID().toString()));
+ message.setId(Message.generateId());
message.setThreadId(newThread.getId());
newThread.setMessage(message);
diff --git a/src/com/p4square/grow/frontend/AccountRedirectResource.java b/src/com/p4square/grow/frontend/AccountRedirectResource.java
index 25467cd..b363c89 100644
--- a/src/com/p4square/grow/frontend/AccountRedirectResource.java
+++ b/src/com/p4square/grow/frontend/AccountRedirectResource.java
@@ -14,13 +14,13 @@ import org.restlet.resource.ServerResource;
import org.apache.log4j.Logger;
-import com.p4square.fmfacade.json.JsonRequestClient;
-import com.p4square.fmfacade.json.JsonResponse;
-import com.p4square.fmfacade.json.ClientException;
-
import com.p4square.fmfacade.FreeMarkerPageResource;
import com.p4square.grow.config.Config;
+import com.p4square.grow.model.UserRecord;
+import com.p4square.grow.provider.Provider;
+import com.p4square.grow.provider.DelegateProvider;
+import com.p4square.grow.provider.JsonEncodedProvider;
/**
* This resource simply redirects the user to either the assessment
@@ -32,7 +32,7 @@ public class AccountRedirectResource extends ServerResource {
private static final Logger LOG = Logger.getLogger(AccountRedirectResource.class);
private Config mConfig;
- private JsonRequestClient mJsonClient;
+ private Provider<String, UserRecord> mUserRecordProvider;
// Fields pertaining to this request.
private String mUserId;
@@ -44,7 +44,14 @@ public class AccountRedirectResource extends ServerResource {
GrowFrontend growFrontend = (GrowFrontend) getApplication();
mConfig = growFrontend.getConfig();
- mJsonClient = new JsonRequestClient(getContext().getClientDispatcher());
+ mUserRecordProvider = new DelegateProvider<String, String, UserRecord>(
+ new JsonRequestProvider<UserRecord>(getContext().getClientDispatcher(),
+ UserRecord.class)) {
+ @Override
+ public String makeKey(String userid) {
+ return getBackendEndpoint() + "/accounts/" + userid;
+ }
+ };
mUserId = getRequest().getClientInfo().getUser().getIdentifier();
}
@@ -56,25 +63,17 @@ public class AccountRedirectResource extends ServerResource {
protected Representation get() {
try {
// Fetch account Map.
- Map account = new HashMap();
- try {
- JsonResponse response = backendGet("/accounts/" + mUserId);
- if (response.getStatus().isSuccess()) {
- account = response.getMap();
- }
- } catch (ClientException e) {
-
- }
+ UserRecord user = mUserRecordProvider.get(mUserId);
// Check for the new believers cookie
String cookie = getRequest().getCookies().getFirstValue(NewBelieverResource.COOKIE_NAME);
if (cookie != null && cookie.length() != 0) {
- account.put("landing", "training");
- account.put("newbeliever", "true");
- backendPut("/accounts/" + mUserId, account);
+ user.setLanding("training");
+ user.setNewBeliever(true);
+ mUserRecordProvider.put(mUserId, user);
}
- String landing = (String) account.get("landing");
+ String landing = user.getLanding();
if (landing == null) {
landing = "assessment";
}
@@ -97,31 +96,4 @@ public class AccountRedirectResource extends ServerResource {
private String getBackendEndpoint() {
return mConfig.getString("backendUri", "riap://component/backend");
}
-
- /**
- * Helper method to send a GET to the backend.
- */
- private JsonResponse backendGet(final String uri) {
- LOG.debug("Sending backend GET " + uri);
-
- final JsonResponse response = mJsonClient.get(getBackendEndpoint() + uri);
- final Status status = response.getStatus();
- if (!status.isSuccess() && !Status.CLIENT_ERROR_NOT_FOUND.equals(status)) {
- LOG.warn("Error making backend request for '" + uri + "'. status = " + response.getStatus().toString());
- }
-
- return response;
- }
-
- protected JsonResponse backendPut(final String uri, final Map data) {
- LOG.debug("Sending backend PUT " + uri);
-
- final JsonResponse response = mJsonClient.put(getBackendEndpoint() + uri, data);
- final Status status = response.getStatus();
- if (!status.isSuccess() && !Status.CLIENT_ERROR_NOT_FOUND.equals(status)) {
- LOG.warn("Error making backend request for '" + uri + "'. status = " + response.getStatus().toString());
- }
-
- return response;
- }
}
diff --git a/src/com/p4square/grow/frontend/FeedData.java b/src/com/p4square/grow/frontend/FeedData.java
index 55e845c..feb03a1 100644
--- a/src/com/p4square/grow/frontend/FeedData.java
+++ b/src/com/p4square/grow/frontend/FeedData.java
@@ -62,8 +62,15 @@ public class FeedData {
mMessageProvider = new JsonRequestProvider<Message>(clientDispatcher, Message.class);
}
- public List<MessageThread> getThreads(final String topic) throws IOException {
- return mThreadsProvider.get(makeUrl(topic));
+ /**
+ * Get the threads for a topic.
+ *
+ * @param topic The topic to request threads for.
+ * @param limit The maximum number of threads.
+ * @return A list of MessageThread objects.
+ */
+ public List<MessageThread> getThreads(final String topic, final int limit) throws IOException {
+ return mThreadsProvider.get(makeUrl(limit, topic));
}
public List<Message> getMessages(final String topic, final String threadId) throws IOException {
@@ -91,4 +98,8 @@ public class FeedData {
return url;
}
+
+ private String makeUrl(int limit, String... parts) {
+ return makeUrl(parts) + "?limit=" + limit;
+ }
}
diff --git a/src/com/p4square/grow/frontend/SurveyPageResource.java b/src/com/p4square/grow/frontend/SurveyPageResource.java
index f864014..1f9c56c 100644
--- a/src/com/p4square/grow/frontend/SurveyPageResource.java
+++ b/src/com/p4square/grow/frontend/SurveyPageResource.java
@@ -29,8 +29,11 @@ import com.p4square.fmfacade.FreeMarkerPageResource;
import com.p4square.grow.config.Config;
import com.p4square.grow.model.Question;
-import com.p4square.grow.provider.QuestionProvider;
+import com.p4square.grow.model.UserRecord;
+import com.p4square.grow.provider.DelegateProvider;
+import com.p4square.grow.provider.JsonEncodedProvider;
import com.p4square.grow.provider.Provider;
+import com.p4square.grow.provider.QuestionProvider;
/**
* SurveyPageResource handles rendering the survey and processing user's answers.
@@ -49,6 +52,7 @@ public class SurveyPageResource extends FreeMarkerPageResource {
private Template mSurveyTemplate;
private JsonRequestClient mJsonClient;
private Provider<String, Question> mQuestionProvider;
+ private Provider<String, UserRecord> mUserRecordProvider;
// Fields pertaining to this request.
private String mQuestionId;
@@ -74,6 +78,15 @@ public class SurveyPageResource extends FreeMarkerPageResource {
}
};
+ mUserRecordProvider = new DelegateProvider<String, String, UserRecord>(
+ new JsonRequestProvider<UserRecord>(getContext().getClientDispatcher(),
+ UserRecord.class)) {
+ @Override
+ public String makeKey(String userid) {
+ return getBackendEndpoint() + "/accounts/" + userid;
+ }
+ };
+
mQuestionId = getAttribute("questionId");
mUserId = getRequest().getClientInfo().getUser().getIdentifier();
}
@@ -205,24 +218,6 @@ public class SurveyPageResource extends FreeMarkerPageResource {
}
}
- private Map<?, ?> getAccount(String id) {
- try {
- Map<?, ?> account = null;
-
- JsonResponse response = backendGet("/accounts/" + id);
- if (!response.getStatus().isSuccess()) {
- return null;
- }
- account = response.getMap();
-
- return account;
-
- } catch (ClientException e) {
- LOG.warn("Error fetching account.", e);
- return null;
- }
- }
-
private Question getQuestion(String id) {
try {
return mQuestionProvider.get(id);
@@ -252,12 +247,16 @@ public class SurveyPageResource extends FreeMarkerPageResource {
if (nextQuestionId == null) {
// Just finished the last question. Update the user's account
- Map account = getAccount(mUserId);
- if (account == null) {
- account = new HashMap();
+ try {
+ UserRecord account = mUserRecordProvider.get(mUserId);
+ if (account == null) {
+ account = new UserRecord();
+ }
+ account.setLanding("training");
+ mUserRecordProvider.put(mUserId, account);
+ } catch (IOException e) {
+ LOG.warn("IOException updating landing for " + mUserId, e);
}
- account.put("landing", "training");
- backendPut("/accounts/" + mUserId, account);
String nextPage = mConfig.getString("dynamicRoot", "");
nextPage += "/account/assessment/results";
diff --git a/src/com/p4square/grow/frontend/TrainingPageResource.java b/src/com/p4square/grow/frontend/TrainingPageResource.java
index 0c8f656..ae2f3a7 100644
--- a/src/com/p4square/grow/frontend/TrainingPageResource.java
+++ b/src/com/p4square/grow/frontend/TrainingPageResource.java
@@ -214,21 +214,8 @@ public class TrainingPageResource extends FreeMarkerPageResource {
root.put("videos", videos);
root.put("allowUserToSkip", allowUserToSkip);
- // Optionally show the feed.
- boolean showfeed = "true".equals(getRequest().getCookies().getFirstValue("showfeed"));
- if (getQueryValue("showfeed") != null) {
- CookieSetting cookie = new CookieSetting("showfeed", "true");
- cookie.setPath("/");
- if ("true".equals(getQueryValue("showfeed"))) {
- showfeed = true;
- getResponse().getCookieSettings().add(cookie);
- } else {
- showfeed = false;
- cookie.setValue("false");
- cookie.setMaxAge(0);
- getResponse().getCookieSettings().add(cookie);
- }
- }
+ // Determine if we should show the feed.
+ boolean showfeed = true;
// Don't show the feed if the topic isn't allowed.
if (!FeedData.TOPICS.contains(mChapter)) {
diff --git a/src/com/p4square/grow/model/Message.java b/src/com/p4square/grow/model/Message.java
index ad02af9..9d33320 100644
--- a/src/com/p4square/grow/model/Message.java
+++ b/src/com/p4square/grow/model/Message.java
@@ -5,6 +5,7 @@
package com.p4square.grow.model;
import java.util.Date;
+import java.util.UUID;
/**
* A feed message.
@@ -19,6 +20,13 @@ public class Message {
private String mMessage;
/**
+ * @return a new message id.
+ */
+ public static String generateId() {
+ return String.format("%x-%s", System.currentTimeMillis(), UUID.randomUUID().toString());
+ }
+
+ /**
* @return The id of the thread that the message belongs to.
*/
public String getThreadId() {
diff --git a/src/com/p4square/grow/model/MessageThread.java b/src/com/p4square/grow/model/MessageThread.java
index 25a46b7..9542a18 100644
--- a/src/com/p4square/grow/model/MessageThread.java
+++ b/src/com/p4square/grow/model/MessageThread.java
@@ -21,7 +21,9 @@ public class MessageThread {
*/
public static MessageThread createNew() {
MessageThread t = new MessageThread();
- t.setId(String.format("%x-%s", System.currentTimeMillis(), UUID.randomUUID().toString()));
+ // IDs are keyed to sort lexicographically from latest to oldest.
+ t.setId(String.format("%016x-%s", Long.MAX_VALUE - System.currentTimeMillis(),
+ UUID.randomUUID().toString()));
return t;
}
diff --git a/src/com/p4square/grow/model/UserRecord.java b/src/com/p4square/grow/model/UserRecord.java
index b5aaa4e..4399282 100644
--- a/src/com/p4square/grow/model/UserRecord.java
+++ b/src/com/p4square/grow/model/UserRecord.java
@@ -21,6 +21,7 @@ public class UserRecord {
private String mLastName;
private String mEmail;
private String mLanding;
+ private boolean mNewBeliever;
// Backend Access
private String mBackendPasswordHash;
@@ -117,6 +118,21 @@ public class UserRecord {
}
/**
+ * @return true if the user came from the New Believer's landing.
+ */
+ public boolean getNewBeliever() {
+ return mNewBeliever;
+ }
+
+ /**
+ * Set the user's new believer flag.
+ * @param value The new flag.
+ */
+ public void setNewBeliever(final boolean value) {
+ mNewBeliever = value;
+ }
+
+ /**
* @return The user's backend password hash, null if he doesn't have
* access.
*/
diff --git a/src/templates/templates/communityfeed.ftl b/src/templates/templates/communityfeed.ftl
index 7c68771..71b33bc 100644
--- a/src/templates/templates/communityfeed.ftl
+++ b/src/templates/templates/communityfeed.ftl
@@ -2,7 +2,8 @@
<div id="thefeed">
<h2>Discussion Forum</h2>
- <#assign threads = feeddata.getThreads(chapter)>
+ <#assign max_threads = 5>
+ <#assign threads = feeddata.getThreads(chapter, max_threads)>
<#list threads as thread>
<#assign messages = feeddata.getMessages(chapter, thread.id)>
<article>