summaryrefslogtreecommitdiff
path: root/src/com/p4square/grow/frontend
diff options
context:
space:
mode:
authorJesse Morgan <jesse@jesterpm.net>2016-04-09 14:22:20 -0700
committerJesse Morgan <jesse@jesterpm.net>2016-04-09 15:48:01 -0700
commit3102d8bce3426d9cf41aeaf201c360d342677770 (patch)
tree38c4f1e8828f9af9c4b77a173bee0d312b321698 /src/com/p4square/grow/frontend
parentbbf907e51dfcf157bdee24dead1d531122aa25db (diff)
Switching from Ivy+Ant to Maven.
Diffstat (limited to 'src/com/p4square/grow/frontend')
-rw-r--r--src/com/p4square/grow/frontend/AccountRedirectResource.java113
-rw-r--r--src/com/p4square/grow/frontend/AssessmentResetPage.java99
-rw-r--r--src/com/p4square/grow/frontend/AssessmentResultsPage.java145
-rw-r--r--src/com/p4square/grow/frontend/AuthenticatedResource.java18
-rw-r--r--src/com/p4square/grow/frontend/ChapterCompletePage.java209
-rw-r--r--src/com/p4square/grow/frontend/ErrorPage.java77
-rw-r--r--src/com/p4square/grow/frontend/FeedData.java105
-rw-r--r--src/com/p4square/grow/frontend/FeedResource.java101
-rw-r--r--src/com/p4square/grow/frontend/GroupLeaderTrainingPageResource.java26
-rw-r--r--src/com/p4square/grow/frontend/GrowFrontend.java230
-rw-r--r--src/com/p4square/grow/frontend/IntegrationDriver.java26
-rw-r--r--src/com/p4square/grow/frontend/JsonRequestProvider.java96
-rw-r--r--src/com/p4square/grow/frontend/LoginFormAuthenticator.java146
-rw-r--r--src/com/p4square/grow/frontend/LoginPageResource.java77
-rw-r--r--src/com/p4square/grow/frontend/LogoutResource.java40
-rw-r--r--src/com/p4square/grow/frontend/NewAccountResource.java135
-rw-r--r--src/com/p4square/grow/frontend/NewBelieverResource.java72
-rw-r--r--src/com/p4square/grow/frontend/NotFoundException.java13
-rw-r--r--src/com/p4square/grow/frontend/ProgressReporter.java30
-rw-r--r--src/com/p4square/grow/frontend/SurveyPageResource.java343
-rw-r--r--src/com/p4square/grow/frontend/TrainingPageResource.java268
-rw-r--r--src/com/p4square/grow/frontend/VideosResource.java133
22 files changed, 0 insertions, 2502 deletions
diff --git a/src/com/p4square/grow/frontend/AccountRedirectResource.java b/src/com/p4square/grow/frontend/AccountRedirectResource.java
deleted file mode 100644
index be2ae65..0000000
--- a/src/com/p4square/grow/frontend/AccountRedirectResource.java
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * Copyright 2013 Jesse Morgan
- */
-
-package com.p4square.grow.frontend;
-
-import java.io.IOException;
-import java.util.HashMap;
-import java.util.Map;
-
-import org.restlet.data.Status;
-import org.restlet.representation.Representation;
-import org.restlet.representation.StringRepresentation;
-import org.restlet.resource.ServerResource;
-
-import org.apache.log4j.Logger;
-
-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
- * or the training page.
- *
- * @author Jesse Morgan <jesse@jesterpm.net>
- */
-public class AccountRedirectResource extends ServerResource {
- private static final Logger LOG = Logger.getLogger(AccountRedirectResource.class);
-
- private Config mConfig;
- private Provider<String, UserRecord> mUserRecordProvider;
-
- // Fields pertaining to this request.
- private String mUserId;
-
- @Override
- public void doInit() {
- super.doInit();
-
- GrowFrontend growFrontend = (GrowFrontend) getApplication();
- mConfig = growFrontend.getConfig();
-
- 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();
- }
-
- /**
- * Redirect to the correct landing.
- */
- @Override
- protected Representation get() {
- if (mUserId == null || mUserId.length() == 0) {
- // This shouldn't happen, but I want to be safe because of the DB insert below.
- setStatus(Status.CLIENT_ERROR_FORBIDDEN);
- return new ErrorPage("Not Authenticated!");
- }
-
- try {
- // Fetch account Map.
- UserRecord user = null;
- try {
- user = mUserRecordProvider.get(mUserId);
- } catch (NotFoundException e) {
- // User record doesn't exist, so create a new one.
- user = new UserRecord(getRequest().getClientInfo().getUser());
- mUserRecordProvider.put(mUserId, user);
- }
-
- // Check for the new believers cookie
- String cookie = getRequest().getCookies().getFirstValue(NewBelieverResource.COOKIE_NAME);
- if (cookie != null && cookie.length() != 0) {
- user.setLanding("training");
- user.setNewBeliever(true);
- mUserRecordProvider.put(mUserId, user);
- }
-
- String landing = user.getLanding();
- if (landing == null) {
- landing = "assessment";
- }
-
- String nextPage = mConfig.getString("dynamicRoot", "");
- nextPage += "/account/" + landing;
- getResponse().redirectSeeOther(nextPage);
- return new StringRepresentation("Redirecting to " + nextPage);
-
- } catch (Exception e) {
- LOG.fatal("Could not render page: " + e.getMessage(), e);
- setStatus(Status.SERVER_ERROR_INTERNAL);
- return ErrorPage.RENDER_ERROR;
- }
- }
-
- /**
- * @return The backend endpoint URI
- */
- private String getBackendEndpoint() {
- return mConfig.getString("backendUri", "riap://component/backend");
- }
-}
diff --git a/src/com/p4square/grow/frontend/AssessmentResetPage.java b/src/com/p4square/grow/frontend/AssessmentResetPage.java
deleted file mode 100644
index 519b135..0000000
--- a/src/com/p4square/grow/frontend/AssessmentResetPage.java
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * Copyright 2013 Jesse Morgan
- */
-
-package com.p4square.grow.frontend;
-
-import java.util.Map;
-
-import freemarker.template.Template;
-
-import org.restlet.data.MediaType;
-import org.restlet.data.Status;
-import org.restlet.representation.Representation;
-import org.restlet.representation.StringRepresentation;
-import org.restlet.ext.freemarker.TemplateRepresentation;
-
-import org.apache.log4j.Logger;
-
-import com.p4square.fmfacade.FreeMarkerPageResource;
-
-import com.p4square.fmfacade.json.JsonRequestClient;
-import com.p4square.fmfacade.json.JsonResponse;
-import com.p4square.fmfacade.json.ClientException;
-
-import com.p4square.grow.config.Config;
-
-/**
- * This page delete's the current user's assessment.
- *
- * @author Jesse Morgan <jesse@jesterpm.net>
- */
-public class AssessmentResetPage extends FreeMarkerPageResource {
- private static final Logger LOG = Logger.getLogger(AssessmentResetPage.class);
-
- private GrowFrontend mGrowFrontend;
- private Config mConfig;
- private JsonRequestClient mJsonClient;
-
- private String mUserId;
-
- @Override
- public void doInit() {
- super.doInit();
-
- mGrowFrontend = (GrowFrontend) getApplication();
- mConfig = mGrowFrontend.getConfig();
-
- mJsonClient = new JsonRequestClient(getContext().getClientDispatcher());
-
- mUserId = getRequest().getClientInfo().getUser().getIdentifier();
- }
-
- /**
- * Return the login page.
- */
- @Override
- protected Representation get() {
- try {
- // Get the assessment results
- JsonResponse response = backendDelete("/accounts/" + mUserId + "/assessment");
- if (!response.getStatus().isSuccess()) {
- setStatus(Status.SERVER_ERROR_INTERNAL);
- return ErrorPage.BACKEND_ERROR;
- }
-
- String nextPage = mConfig.getString("dynamicRoot", "")
- + "/account/assessment/question/first";
- getResponse().redirectSeeOther(nextPage);
- return new StringRepresentation("Redirecting to " + nextPage);
-
- } catch (Exception e) {
- LOG.fatal("Could not render page: " + e.getMessage(), e);
- setStatus(Status.SERVER_ERROR_INTERNAL);
- return ErrorPage.RENDER_ERROR;
- }
- }
-
- /**
- * @return The backend endpoint URI
- */
- private String getBackendEndpoint() {
- return mConfig.getString("backendUri", "riap://component/backend");
- }
-
- /**
- * Helper method to send a GET to the backend.
- */
- private JsonResponse backendDelete(final String uri) {
- LOG.debug("Sending backend GET " + uri);
-
- final JsonResponse response = mJsonClient.delete(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;
- }
-}
diff --git a/src/com/p4square/grow/frontend/AssessmentResultsPage.java b/src/com/p4square/grow/frontend/AssessmentResultsPage.java
deleted file mode 100644
index f1c924b..0000000
--- a/src/com/p4square/grow/frontend/AssessmentResultsPage.java
+++ /dev/null
@@ -1,145 +0,0 @@
-/*
- * Copyright 2013 Jesse Morgan
- */
-
-package com.p4square.grow.frontend;
-
-import java.util.Date;
-import java.util.Map;
-
-import com.fasterxml.jackson.core.JsonProcessingException;
-import com.p4square.f1oauth.FellowshipOneIntegrationDriver;
-import freemarker.template.Template;
-
-import org.restlet.data.MediaType;
-import org.restlet.data.Status;
-import org.restlet.representation.Representation;
-import org.restlet.representation.StringRepresentation;
-import org.restlet.ext.freemarker.TemplateRepresentation;
-
-import org.apache.log4j.Logger;
-
-import com.p4square.fmfacade.FreeMarkerPageResource;
-
-import com.p4square.fmfacade.json.JsonRequestClient;
-import com.p4square.fmfacade.json.JsonResponse;
-import com.p4square.fmfacade.json.ClientException;
-
-import com.p4square.f1oauth.Attribute;
-import com.p4square.f1oauth.F1API;
-import com.p4square.f1oauth.F1User;
-
-import com.p4square.grow.config.Config;
-import com.p4square.grow.provider.JsonEncodedProvider;
-import org.restlet.security.User;
-
-/**
- * This page fetches the user's final score and displays the transitional page between
- * the assessment and the videos.
- *
- * @author Jesse Morgan <jesse@jesterpm.net>
- */
-public class AssessmentResultsPage extends FreeMarkerPageResource {
- private static final Logger LOG = Logger.getLogger(AssessmentResultsPage.class);
-
- private GrowFrontend mGrowFrontend;
- private Config mConfig;
- private JsonRequestClient mJsonClient;
-
- private String mUserId;
-
- @Override
- public void doInit() {
- super.doInit();
-
- mGrowFrontend = (GrowFrontend) getApplication();
- mConfig = mGrowFrontend.getConfig();
-
- mJsonClient = new JsonRequestClient(getContext().getClientDispatcher());
-
- mUserId = getRequest().getClientInfo().getUser().getIdentifier();
- }
-
- /**
- * Return the login page.
- */
- @Override
- protected Representation get() {
- Template t = mGrowFrontend.getTemplate("templates/assessment-results.ftl");
-
- try {
- if (t == null) {
- setStatus(Status.CLIENT_ERROR_NOT_FOUND);
- return ErrorPage.TEMPLATE_NOT_FOUND;
- }
-
- Map<String, Object> root = getRootObject();
-
- // Get the assessment results
- JsonResponse response = backendGet("/accounts/" + mUserId + "/assessment");
- if (!response.getStatus().isSuccess()) {
- setStatus(Status.SERVER_ERROR_INTERNAL);
- return ErrorPage.BACKEND_ERROR;
- }
-
- final String score = (String) response.getMap().get("result");
- if (score == null) {
- // Odd... send them to the first questions
- String nextPage = mConfig.getString("dynamicRoot", "")
- + "/account/assessment/question/first";
- getResponse().redirectSeeOther(nextPage);
- return new StringRepresentation("Redirecting to " + nextPage);
- }
-
- // Publish results in F1
- publishScoreInF1(response.getMap());
-
- root.put("stage", score);
- return new TemplateRepresentation(t, root, MediaType.TEXT_HTML);
-
- } catch (Exception e) {
- LOG.fatal("Could not render page: " + e.getMessage(), e);
- setStatus(Status.SERVER_ERROR_INTERNAL);
- return ErrorPage.RENDER_ERROR;
- }
- }
-
- private void publishScoreInF1(Map results) {
- final ProgressReporter reporter = mGrowFrontend.getThirdPartyIntegrationFactory().getProgressReporter();
-
- try {
- final User user = getRequest().getClientInfo().getUser();
- final String level = results.get("result").toString();
- final Date completionDate = new Date();
- final String data = JsonEncodedProvider.MAPPER.writeValueAsString(results);
-
- reporter.reportAssessmentComplete(user, level, completionDate, data);
-
- } catch (JsonProcessingException e) {
- LOG.error("Failed to generate json " + e.getMessage(), e);
- }
- }
-
- /**
- * @return The backend endpoint URI
- */
- 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;
- }
-}
diff --git a/src/com/p4square/grow/frontend/AuthenticatedResource.java b/src/com/p4square/grow/frontend/AuthenticatedResource.java
deleted file mode 100644
index 800eb83..0000000
--- a/src/com/p4square/grow/frontend/AuthenticatedResource.java
+++ /dev/null
@@ -1,18 +0,0 @@
-/*
- * Copyright 2013 Jesse Morgan
- */
-
-package com.p4square.grow.frontend;
-
-import org.restlet.resource.ServerResource;
-import org.restlet.representation.Representation;
-
-/**
- *
- * @author Jesse Morgan <jesse@jesterpm.net>
- */
-public class AuthenticatedResource extends ServerResource {
- protected Representation post() {
- return null;
- }
-}
diff --git a/src/com/p4square/grow/frontend/ChapterCompletePage.java b/src/com/p4square/grow/frontend/ChapterCompletePage.java
deleted file mode 100644
index 35abc43..0000000
--- a/src/com/p4square/grow/frontend/ChapterCompletePage.java
+++ /dev/null
@@ -1,209 +0,0 @@
-/*
- * Copyright 2013 Jesse Morgan
- */
-
-package com.p4square.grow.frontend;
-
-import java.util.Date;
-import java.util.Map;
-
-import com.p4square.f1oauth.FellowshipOneIntegrationDriver;
-import freemarker.template.Template;
-
-import org.restlet.data.MediaType;
-import org.restlet.data.Status;
-import org.restlet.representation.Representation;
-import org.restlet.representation.StringRepresentation;
-import org.restlet.ext.freemarker.TemplateRepresentation;
-
-import org.apache.log4j.Logger;
-
-import com.p4square.fmfacade.FreeMarkerPageResource;
-
-import com.p4square.fmfacade.json.JsonRequestClient;
-import com.p4square.fmfacade.json.JsonResponse;
-import com.p4square.fmfacade.json.ClientException;
-
-import com.p4square.f1oauth.Attribute;
-import com.p4square.f1oauth.F1API;
-import com.p4square.f1oauth.F1User;
-
-import com.p4square.grow.config.Config;
-import com.p4square.grow.model.TrainingRecord;
-import com.p4square.grow.provider.Provider;
-import com.p4square.grow.provider.TrainingRecordProvider;
-import org.restlet.security.User;
-
-/**
- * This resource displays the transitional page between chapters.
- *
- * @author Jesse Morgan <jesse@jesterpm.net>
- */
-public class ChapterCompletePage extends FreeMarkerPageResource {
- private static final Logger LOG = Logger.getLogger(ChapterCompletePage.class);
-
- private GrowFrontend mGrowFrontend;
- private Config mConfig;
- private JsonRequestClient mJsonClient;
- private Provider<String, TrainingRecord> mTrainingRecordProvider;
-
- private String mUserId;
- private String mChapter;
-
- @Override
- public void doInit() {
- super.doInit();
-
- mGrowFrontend = (GrowFrontend) getApplication();
- mConfig = mGrowFrontend.getConfig();
-
- mJsonClient = new JsonRequestClient(getContext().getClientDispatcher());
- mTrainingRecordProvider = new TrainingRecordProvider<String>(
- new JsonRequestProvider<TrainingRecord>(
- getContext().getClientDispatcher(),
- TrainingRecord.class)) {
- @Override
- public String makeKey(String userid) {
- return getBackendEndpoint() + "/accounts/" + userid + "/training";
- }
- };
-
- mUserId = getRequest().getClientInfo().getUser().getIdentifier();
-
- mChapter = getAttribute("chapter");
- }
-
- /**
- * Return the login page.
- */
- @Override
- protected Representation get() {
- try {
- Map<String, Object> root = getRootObject();
-
- // Get the training summary
- TrainingRecord trainingRecord = mTrainingRecordProvider.get(mUserId);
- if (trainingRecord == null) {
- // Wait. What? Everyone has a training record...
- setStatus(Status.SERVER_ERROR_INTERNAL);
- return new ErrorPage("Could not retrieve your training record.");
- }
-
- // Verify they completed the chapter.
- Map<String, Boolean> chapters = trainingRecord.getPlaylist().getChapterStatuses();
- Boolean completed = chapters.get(mChapter);
- if (completed == null || !completed) {
- // Redirect back to training page...
- String nextPage = mConfig.getString("dynamicRoot", "");
- nextPage += "/account/training/" + mChapter;
- getResponse().redirectSeeOther(nextPage);
- return new StringRepresentation("Redirecting to " + nextPage);
- }
-
- // Publish the training chapter complete attribute.
- assignAttribute();
-
- // Find the next chapter
- String nextChapter = null;
- {
- int min = Integer.MAX_VALUE;
- for (Map.Entry<String, Boolean> chapter : chapters.entrySet()) {
- int index = chapterIndex(chapter.getKey());
- if (!chapter.getValue() && index < min) {
- min = index;
- nextChapter = chapter.getKey();
- }
- }
- }
-
- String nextOverride = getQueryValue("next");
- if (nextOverride != null) {
- nextChapter = nextOverride;
- }
-
- root.put("stage", mChapter);
- root.put("nextstage", nextChapter);
-
- /*
- * We will display one of two transitional pages:
- *
- * If the next chapter has a forward page, display the forward page.
- * Else, if this chapter is not "Introduction", display the chapter
- * complete message.
- */
- Template t = mGrowFrontend.getTemplate("templates/stage-"
- + nextChapter + "-forward.ftl");
-
- if (t == null) {
- // Skip the chapter complete message for "Introduction"
- if ("introduction".equals(mChapter)) {
- String nextPage = mConfig.getString("dynamicRoot", "");
- nextPage += "/account/training/" + nextChapter;
- getResponse().redirectSeeOther(nextPage);
- return new StringRepresentation("Redirecting to " + nextPage);
- }
-
- t = mGrowFrontend.getTemplate("templates/stage-complete.ftl");
- if (t == null) {
- setStatus(Status.CLIENT_ERROR_NOT_FOUND);
- return ErrorPage.TEMPLATE_NOT_FOUND;
- }
- }
-
- return new TemplateRepresentation(t, root, MediaType.TEXT_HTML);
-
- } catch (Exception e) {
- LOG.fatal("Could not render page: " + e.getMessage(), e);
- setStatus(Status.SERVER_ERROR_INTERNAL);
- return ErrorPage.RENDER_ERROR;
- }
- }
-
- private void assignAttribute() {
- final ProgressReporter reporter = mGrowFrontend.getThirdPartyIntegrationFactory().getProgressReporter();
-
- final User user = getRequest().getClientInfo().getUser();
- final Date completionDate = new Date();
-
- reporter.reportChapterComplete(user, mChapter, completionDate);
- }
-
- /**
- * @return The backend endpoint URI
- */
- 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;
- }
-
- int chapterIndex(String chapter) {
- if ("leader".equals(chapter)) {
- return 5;
- } else if ("teacher".equals(chapter)) {
- return 4;
- } else if ("disciple".equals(chapter)) {
- return 3;
- } else if ("believer".equals(chapter)) {
- return 2;
- } else if ("seeker".equals(chapter)) {
- return 1;
- } else {
- return Integer.MAX_VALUE;
- }
- }
-}
diff --git a/src/com/p4square/grow/frontend/ErrorPage.java b/src/com/p4square/grow/frontend/ErrorPage.java
deleted file mode 100644
index 81abe74..0000000
--- a/src/com/p4square/grow/frontend/ErrorPage.java
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * Copyright 2013 Jesse Morgan
- */
-
-package com.p4square.grow.frontend;
-
-import java.util.HashMap;
-import java.util.Map;
-
-import java.io.IOException;
-import java.io.Writer;
-
-import freemarker.template.Template;
-
-import org.restlet.data.MediaType;
-import org.restlet.ext.freemarker.TemplateRepresentation;
-import org.restlet.representation.Representation;
-import org.restlet.representation.StringRepresentation;
-import org.restlet.representation.WriterRepresentation;
-
-import com.p4square.fmfacade.FreeMarkerPageResource;
-
-/**
- * ErrorPage wraps a String or Template Representation and displays the given
- * error message.
- *
- * @author Jesse Morgan <jesse@jesterpm.net>
- */
-public class ErrorPage extends WriterRepresentation {
- public static final ErrorPage TEMPLATE_NOT_FOUND =
- new ErrorPage("Could not find the requested page template.");
-
- public static final ErrorPage RENDER_ERROR =
- new ErrorPage("Error rendering page.");
-
- public static final ErrorPage BACKEND_ERROR =
- new ErrorPage("Error communicating with backend.");
-
- public static final ErrorPage NOT_FOUND =
- new ErrorPage("The requested URL could not be found.");
-
- private static Template cTemplate = null;
- private static Map<String, Object> cRoot = null;
-
- private final String mMessage;
-
- public ErrorPage(String msg) {
- this(msg, MediaType.TEXT_HTML);
- }
-
- public ErrorPage(String msg, MediaType mediaType) {
- super(mediaType);
-
- mMessage = msg;
- }
-
- public static synchronized void setTemplate(Template template, Map<String, Object> root) {
- cTemplate = template;
- cRoot = root;
- }
-
- protected Representation getRepresentation() {
- if (cTemplate == null) {
- return new StringRepresentation(mMessage);
-
- } else {
- Map<String, Object> root = new HashMap<String, Object>(cRoot);
- root.put("errorMessage", mMessage);
- return new TemplateRepresentation(cTemplate, root, MediaType.TEXT_HTML);
- }
- }
-
- @Override
- public void write(Writer writer) throws IOException {
- getRepresentation().write(writer);
- }
-}
diff --git a/src/com/p4square/grow/frontend/FeedData.java b/src/com/p4square/grow/frontend/FeedData.java
deleted file mode 100644
index feb03a1..0000000
--- a/src/com/p4square/grow/frontend/FeedData.java
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * Copyright 2014 Jesse Morgan
- */
-
-package com.p4square.grow.frontend;
-
-import java.io.IOException;
-
-import java.util.Arrays;
-import java.util.HashSet;
-import java.util.List;
-
-import org.restlet.Context;
-import org.restlet.Restlet;
-
-import com.fasterxml.jackson.databind.JavaType;
-import com.fasterxml.jackson.databind.type.TypeFactory;
-
-import com.p4square.grow.config.Config;
-import com.p4square.grow.frontend.JsonRequestProvider;
-import com.p4square.grow.model.Message;
-import com.p4square.grow.model.MessageThread;
-import com.p4square.grow.provider.JsonEncodedProvider;
-import com.p4square.grow.provider.Provider;
-
-/**
- * Fetch feed data for a topic.
- */
-public class FeedData {
-
- /**
- * Allowed Topics.
- */
- public static final HashSet<String> TOPICS = new HashSet(Arrays.asList("seeker", "believer",
- "disciple", "teacher", "leader"));
-
-
- private final Config mConfig;
- private final String mBackendURI;
-
- // TODO: Elegantly merge the List and individual providers.
- private final JsonRequestProvider<List<MessageThread>> mThreadsProvider;
- private final JsonRequestProvider<MessageThread> mThreadProvider;
-
- private final JsonRequestProvider<List<Message>> mMessagesProvider;
- private final JsonRequestProvider<Message> mMessageProvider;
-
- public FeedData(final Context context, final Config config) {
- mConfig = config;
- mBackendURI = mConfig.getString("backendUri", "riap://component/backend") + "/feed";
-
- Restlet clientDispatcher = context.getClientDispatcher();
-
- TypeFactory factory = JsonEncodedProvider.MAPPER.getTypeFactory();
-
- JavaType threadType = factory.constructCollectionType(List.class, MessageThread.class);
- mThreadsProvider = new JsonRequestProvider<List<MessageThread>>(clientDispatcher, threadType);
- mThreadProvider = new JsonRequestProvider<MessageThread>(clientDispatcher, MessageThread.class);
-
- JavaType messageType = factory.constructCollectionType(List.class, Message.class);
- mMessagesProvider = new JsonRequestProvider<List<Message>>(clientDispatcher, messageType);
- mMessageProvider = new JsonRequestProvider<Message>(clientDispatcher, Message.class);
- }
-
- /**
- * 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 {
- return mMessagesProvider.get(makeUrl(topic, threadId));
- }
-
- public void createThread(final String topic, final Message message) throws IOException {
- MessageThread thread = new MessageThread();
- thread.setMessage(message);
-
- mThreadProvider.post(makeUrl(topic), thread);
- }
-
- public void createResponse(final String topic, final String thread, final Message message)
- throws IOException {
-
- mMessageProvider.post(makeUrl(topic, thread), message);
- }
-
- private String makeUrl(String... parts) {
- String url = mBackendURI;
- for (String part : parts) {
- url += "/" + part;
- }
-
- return url;
- }
-
- private String makeUrl(int limit, String... parts) {
- return makeUrl(parts) + "?limit=" + limit;
- }
-}
diff --git a/src/com/p4square/grow/frontend/FeedResource.java b/src/com/p4square/grow/frontend/FeedResource.java
deleted file mode 100644
index 13d0fa0..0000000
--- a/src/com/p4square/grow/frontend/FeedResource.java
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * Copyright 2014 Jesse Morgan
- */
-
-package com.p4square.grow.frontend;
-
-import java.io.IOException;
-
-import org.restlet.data.Form;
-import org.restlet.data.Status;
-import org.restlet.representation.Representation;
-import org.restlet.resource.ServerResource;
-
-import org.apache.log4j.Logger;
-
-import com.p4square.grow.config.Config;
-import com.p4square.grow.model.Message;
-import com.p4square.grow.model.UserRecord;
-
-/**
- * This resource handles user interactions with the feed.
- */
-public class FeedResource extends ServerResource {
- private static final Logger LOG = Logger.getLogger(FeedResource.class);
-
- private Config mConfig;
-
- private FeedData mFeedData;
-
- // Fields pertaining to this request.
- protected String mTopic;
- protected String mThread;
-
- @Override
- public void doInit() {
- super.doInit();
-
- GrowFrontend growFrontend = (GrowFrontend) getApplication();
- mConfig = growFrontend.getConfig();
-
- mFeedData = new FeedData(getContext(), mConfig);
-
- mTopic = getAttribute("topic");
- if (mTopic != null) {
- mTopic = mTopic.trim();
- }
-
- mThread = getAttribute("thread");
- if (mThread != null) {
- mThread = mThread.trim();
- }
- }
-
- /**
- * Create a new MessageThread.
- */
- @Override
- protected Representation post(Representation entity) {
- try {
- if (mTopic == null || mTopic.length() == 0 || !FeedData.TOPICS.contains(mTopic)) {
- setStatus(Status.CLIENT_ERROR_NOT_FOUND);
- return ErrorPage.NOT_FOUND;
- }
-
- Form form = new Form(entity);
-
- String question = form.getFirstValue("question");
-
- Message message = new Message();
- message.setMessage(question);
-
- UserRecord user = new UserRecord(getRequest().getClientInfo().getUser());
- message.setAuthor(user);
-
- if (mThread != null && mThread.length() != 0) {
- // Post a response
- mFeedData.createResponse(mTopic, mThread, message);
-
- } else {
- // Post a new thread
- mFeedData.createThread(mTopic, message);
- }
-
- /*
- * Can't trust the referrer, so we'll send them to the
- * appropriate part of the training page
- * TODO: This could be better done.
- */
- String nextPage = mConfig.getString("dynamicRoot", "");
- nextPage += "/account/training/" + mTopic;
- getResponse().redirectSeeOther(nextPage);
- return null;
-
- } catch (IOException e) {
- LOG.fatal("Could not save message: " + e.getMessage(), e);
- setStatus(Status.SERVER_ERROR_INTERNAL);
- return ErrorPage.BACKEND_ERROR;
-
- }
- }
-}
diff --git a/src/com/p4square/grow/frontend/GroupLeaderTrainingPageResource.java b/src/com/p4square/grow/frontend/GroupLeaderTrainingPageResource.java
deleted file mode 100644
index 3ab140e..0000000
--- a/src/com/p4square/grow/frontend/GroupLeaderTrainingPageResource.java
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright 2013 Jesse Morgan
- */
-
-package com.p4square.grow.frontend;
-
-/**
- * Display the Group Leader training videos.
- *
- * @author Jesse Morgan <jesse@jesterpm.net>
- */
-public class GroupLeaderTrainingPageResource extends TrainingPageResource {
- private static final String[] CHAPTERS = { "leader" };
-
- @Override
- public void doInit() {
- super.doInit();
-
- mChapter = "leader";
- }
-
- @Override
- public String[] getChaptersInOrder() {
- return CHAPTERS;
- }
-}
diff --git a/src/com/p4square/grow/frontend/GrowFrontend.java b/src/com/p4square/grow/frontend/GrowFrontend.java
deleted file mode 100644
index b5f62fb..0000000
--- a/src/com/p4square/grow/frontend/GrowFrontend.java
+++ /dev/null
@@ -1,230 +0,0 @@
-/*
- * Copyright 2013 Jesse Morgan <jesse@jesterpm.net>
- */
-
-package com.p4square.grow.frontend;
-
-import java.io.File;
-import java.io.IOException;
-import java.lang.reflect.Constructor;
-
-import freemarker.template.Template;
-
-import org.restlet.Application;
-import org.restlet.Component;
-import org.restlet.Context;
-import org.restlet.Restlet;
-import org.restlet.data.Protocol;
-import org.restlet.resource.Directory;
-import org.restlet.routing.Redirector;
-import org.restlet.routing.Router;
-import org.restlet.security.Authenticator;
-
-import com.codahale.metrics.MetricRegistry;
-
-import org.apache.log4j.Logger;
-
-import com.p4square.fmfacade.FMFacade;
-import com.p4square.fmfacade.FreeMarkerPageResource;
-
-import com.p4square.grow.config.Config;
-
-import com.p4square.restlet.metrics.MetricRouter;
-
-import com.p4square.session.SessionCheckingAuthenticator;
-import com.p4square.session.SessionCreatingAuthenticator;
-import org.restlet.security.Verifier;
-
-/**
- * This is the Restlet Application implementing the Grow project front-end.
- * It's implemented as an extension of FMFacade that connects interactive pages
- * with various ServerResources. This class provides a main method to start a
- * Jetty instance for testing.
- *
- * @author Jesse Morgan <jesse@jesterpm.net>
- */
-public class GrowFrontend extends FMFacade {
- private static Logger LOG = Logger.getLogger(GrowFrontend.class);
-
- private final Config mConfig;
- private final MetricRegistry mMetricRegistry;
-
- private IntegrationDriver mIntegrationFactory;
-
- public GrowFrontend() {
- this(new Config(), new MetricRegistry());
- }
-
- public GrowFrontend(Config config, MetricRegistry metricRegistry) {
- mConfig = config;
- mMetricRegistry = metricRegistry;
- }
-
- public Config getConfig() {
- return mConfig;
- }
-
- public MetricRegistry getMetrics() {
- return mMetricRegistry;
- }
-
- @Override
- public synchronized void start() throws Exception {
- Template errorTemplate = getTemplate("templates/error.ftl");
- if (errorTemplate != null) {
- ErrorPage.setTemplate(errorTemplate,
- FreeMarkerPageResource.baseRootObject(getContext(), this));
- }
-
- getContext().getAttributes().put("com.p4square.grow.config", mConfig);
- getContext().getAttributes().put("com.p4square.grow.metrics", mMetricRegistry);
-
- super.start();
- }
-
- public synchronized IntegrationDriver getThirdPartyIntegrationFactory() {
- if (mIntegrationFactory == null) {
- final String driverClassName = getConfig().getString("integrationDriver",
- "com.p4square.f1oauth.FellowshipOneIntegrationDriver");
- try {
- Class<?> clazz = Class.forName(driverClassName);
- Constructor<?> constructor = clazz.getConstructor(Context.class);
- mIntegrationFactory = (IntegrationDriver) constructor.newInstance(getContext());
- } catch (Exception e) {
- LOG.error("Failed to instantiate IntegrationDriver " + driverClassName);
- }
- }
-
- return mIntegrationFactory;
- }
-
- @Override
- protected Router createRouter() {
- Router router = new MetricRouter(getContext(), mMetricRegistry);
-
- final Authenticator defaultGuard = new SessionCheckingAuthenticator(getContext(), true);
- defaultGuard.setNext(FreeMarkerPageResource.class);
- router.attachDefault(defaultGuard);
- router.attach("/", new Redirector(getContext(), "index.html", Redirector.MODE_CLIENT_PERMANENT));
- router.attach("/login.html", LoginPageResource.class);
- router.attach("/newaccount.html", NewAccountResource.class);
- router.attach("/newbeliever", NewBelieverResource.class);
-
- final Router accountRouter = new MetricRouter(getContext(), mMetricRegistry);
- accountRouter.attach("/authenticate", AuthenticatedResource.class);
- accountRouter.attach("/logout", LogoutResource.class);
-
- accountRouter.attach("", AccountRedirectResource.class);
- accountRouter.attach("/assessment/question/{questionId}", SurveyPageResource.class);
- accountRouter.attach("/assessment/results", AssessmentResultsPage.class);
- accountRouter.attach("/assessment/reset", AssessmentResetPage.class);
- accountRouter.attach("/assessment", SurveyPageResource.class);
- accountRouter.attach("/training/{chapter}/completed", ChapterCompletePage.class);
- accountRouter.attach("/training/{chapter}/videos/{videoId}.json", VideosResource.class);
- accountRouter.attach("/training/{chapter}", TrainingPageResource.class);
- accountRouter.attach("/training", TrainingPageResource.class);
- accountRouter.attach("/feed/{topic}", FeedResource.class);
- accountRouter.attach("/feed/{topic}/{thread}", FeedResource.class);
-
- final Authenticator accountGuard = createAuthenticatorChain(accountRouter);
- router.attach("/account", accountGuard);
-
- return router;
- }
-
- private Authenticator createAuthenticatorChain(Restlet last) {
- final Context context = getContext();
- final String loginPage = getConfig().getString("dynamicRoot", "") + "/login.html";
- final String loginPost = getConfig().getString("dynamicRoot", "") + "/account/authenticate";
- final String defaultPage = getConfig().getString("dynamicRoot", "") + "/account";
-
- // This is used to check for an existing session
- SessionCheckingAuthenticator sessionChk = new SessionCheckingAuthenticator(context, true);
-
- // This is used to authenticate the user
- Verifier verifier = getThirdPartyIntegrationFactory().newUserAuthenticationVerifier();
- LoginFormAuthenticator loginAuth = new LoginFormAuthenticator(context, false, verifier);
- loginAuth.setLoginFormUrl(loginPage);
- loginAuth.setLoginPostUrl(loginPost);
- loginAuth.setDefaultPage(defaultPage);
-
- // This is used to create a new session for a newly authenticated user.
- SessionCreatingAuthenticator sessionCreate = new SessionCreatingAuthenticator(context);
-
- sessionChk.setNext(loginAuth);
- loginAuth.setNext(sessionCreate);
-
- sessionCreate.setNext(last);
-
- return sessionChk;
- }
-
- /**
- * Stand-alone main for testing.
- */
- public static void main(String[] args) {
- // Start the HTTP Server
- final Component component = new Component();
- component.getServers().add(Protocol.HTTP, 8085);
- component.getClients().add(Protocol.HTTP);
- component.getClients().add(Protocol.HTTPS);
- component.getClients().add(Protocol.FILE);
- //component.getClients().add(new Client(null, Arrays.asList(Protocol.HTTPS), "org.restlet.ext.httpclient.HttpClientHelper"));
-
- // Static content
- try {
- component.getDefaultHost().attach("/images/", new FileServingApp("./build/root/images/"));
- component.getDefaultHost().attach("/scripts", new FileServingApp("./build/root/scripts"));
- component.getDefaultHost().attach("/style.css", new FileServingApp("./build/root/style.css"));
- component.getDefaultHost().attach("/favicon.ico", new FileServingApp("./build/root/favicon.ico"));
- component.getDefaultHost().attach("/notfound.html", new FileServingApp("./build/root/notfound.html"));
- component.getDefaultHost().attach("/error.html", new FileServingApp("./build/root/error.html"));
- } catch (IOException e) {
- LOG.error("Could not create directory for static resources: "
- + e.getMessage(), e);
- }
-
- // Setup App
- GrowFrontend app = new GrowFrontend();
-
- // Load an optional config file from the first argument.
- app.getConfig().setDomain("dev");
- if (args.length == 1) {
- app.getConfig().updateConfig(args[0]);
- }
-
- component.getDefaultHost().attach(app);
-
- // Setup shutdown hook
- Runtime.getRuntime().addShutdownHook(new Thread() {
- public void run() {
- try {
- component.stop();
- } catch (Exception e) {
- LOG.error("Exception during cleanup", e);
- }
- }
- });
-
- LOG.info("Starting server...");
-
- try {
- component.start();
- } catch (Exception e) {
- LOG.fatal("Could not start: " + e.getMessage(), e);
- }
- }
-
- private static class FileServingApp extends Application {
- private final String mPath;
-
- public FileServingApp(String path) throws IOException {
- mPath = new File(path).getAbsolutePath();
- }
-
- @Override
- public Restlet createInboundRoot() {
- return new Directory(getContext(), "file://" + mPath);
- }
- }
-}
diff --git a/src/com/p4square/grow/frontend/IntegrationDriver.java b/src/com/p4square/grow/frontend/IntegrationDriver.java
deleted file mode 100644
index b9c3508..0000000
--- a/src/com/p4square/grow/frontend/IntegrationDriver.java
+++ /dev/null
@@ -1,26 +0,0 @@
-package com.p4square.grow.frontend;
-
-import org.restlet.security.Verifier;
-
-/**
- * An IntegrationDriver is used to create implementations of various objects
- * used to integration Grow with a particular Church Management System.
- */
-public interface IntegrationDriver {
-
- /**
- * Create a new Restlet Verifier to authenticate users when they login to the site.
- *
- * @return A Verifier.
- */
- Verifier newUserAuthenticationVerifier();
-
- /**
- * Return a ProgressReporter for this Church Management System.
- *
- * The ProgressReporter should be thread-safe.
- *
- * @return The ProgressReporter.
- */
- ProgressReporter getProgressReporter();
-}
diff --git a/src/com/p4square/grow/frontend/JsonRequestProvider.java b/src/com/p4square/grow/frontend/JsonRequestProvider.java
deleted file mode 100644
index bf3b2b3..0000000
--- a/src/com/p4square/grow/frontend/JsonRequestProvider.java
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * Copyright 2013 Jesse Morgan
- */
-
-package com.p4square.grow.frontend;
-
-import java.io.IOException;
-
-import com.fasterxml.jackson.databind.JavaType;
-
-import org.restlet.Request;
-import org.restlet.Response;
-import org.restlet.Restlet;
-import org.restlet.data.Method;
-import org.restlet.data.Status;
-import org.restlet.representation.Representation;
-import org.restlet.representation.StringRepresentation;
-
-import com.p4square.grow.provider.Provider;
-import com.p4square.grow.provider.JsonEncodedProvider;
-
-/**
- * Fetch a JSON object via a Request.
- *
- * @author Jesse Morgan <jesse@jesterpm.net>
- */
-public class JsonRequestProvider<V> extends JsonEncodedProvider<V> implements Provider<String, V> {
-
- private final Restlet mDispatcher;
-
- public JsonRequestProvider(Restlet dispatcher, Class<V> clazz) {
- super(clazz);
-
- mDispatcher = dispatcher;
- }
-
- public JsonRequestProvider(Restlet dispatcher, JavaType type) {
- super(type);
-
- mDispatcher = dispatcher;
- }
-
- @Override
- public V get(String url) throws IOException {
- Request request = new Request(Method.GET, url);
- Response response = mDispatcher.handle(request);
- Representation representation = response.getEntity();
-
- if (!response.getStatus().isSuccess()) {
- if (representation != null) {
- representation.release();
- }
-
- if (Status.CLIENT_ERROR_NOT_FOUND.equals(response.getStatus())) {
- throw new NotFoundException("Could not get object. " + response.getStatus());
- } else {
- throw new IOException("Could not get object. " + response.getStatus());
- }
- }
-
- return decode(representation.getText());
- }
-
- @Override
- public void put(String url, V obj) throws IOException {
- final Request request = new Request(Method.PUT, url);
- request.setEntity(new StringRepresentation(encode(obj)));
-
- final Response response = mDispatcher.handle(request);
-
- if (!response.getStatus().isSuccess()) {
- throw new IOException("Could not put object. " + response.getStatus());
- }
- }
-
- /**
- * Variant of put() which makes a POST request to the url.
- *
- * This method may eventually be incorporated into Provider for
- * creating new objects with auto-generated IDs.
- *
- * @param url The url to make the request to.
- * @param obj The post to post.
- * @throws IOException on failure.
- */
- public void post(String url, V obj) throws IOException {
- final Request request = new Request(Method.POST, url);
- request.setEntity(new StringRepresentation(encode(obj)));
-
- final Response response = mDispatcher.handle(request);
-
- if (!response.getStatus().isSuccess()) {
- throw new IOException("Could not put object. " + response.getStatus());
- }
- }
-}
diff --git a/src/com/p4square/grow/frontend/LoginFormAuthenticator.java b/src/com/p4square/grow/frontend/LoginFormAuthenticator.java
deleted file mode 100644
index 21c9097..0000000
--- a/src/com/p4square/grow/frontend/LoginFormAuthenticator.java
+++ /dev/null
@@ -1,146 +0,0 @@
-/*
- * Copyright 2013 Jesse Morgan
- */
-
-package com.p4square.grow.frontend;
-
-import org.apache.log4j.Logger;
-
-import org.restlet.Context;
-import org.restlet.Request;
-import org.restlet.Response;
-import org.restlet.data.ChallengeResponse;
-import org.restlet.data.ChallengeScheme;
-import org.restlet.data.Form;
-import org.restlet.data.Method;
-import org.restlet.data.Reference;
-import org.restlet.security.Authenticator;
-import org.restlet.security.Verifier;
-
-/**
- * LoginFormAuthenticator changes
- *
- *
- * @author Jesse Morgan <jesse@jesterpm.net>
- */
-public class LoginFormAuthenticator extends Authenticator {
- private static final Logger LOG = Logger.getLogger(LoginFormAuthenticator.class);
-
- private final Verifier mVerifier;
-
- private String mLoginPage = "/login.html";
- private String mLoginPostUrl = "/authenticate";
- private String mDefaultRedirect = "/index.html";
-
- public LoginFormAuthenticator(Context context, boolean optional, Verifier verifier) {
- super(context, false, optional, null);
-
- mVerifier = verifier;
- }
-
- public void setLoginFormUrl(String url) {
- mLoginPage = url;
- }
-
- public void setLoginPostUrl(String url) {
- mLoginPostUrl = url;
- }
-
- public void setDefaultPage(String url) {
- mDefaultRedirect = url;
- }
-
- @Override
- protected int beforeHandle(Request request, Response response) {
- if (!isLoginAttempt(request) && request.getClientInfo().isAuthenticated()) {
- // TODO: Logout
- LOG.debug("Already authenticated. Skipping");
- return CONTINUE;
-
- } else {
- return super.beforeHandle(request, response);
- }
- }
-
-
- @Override
- protected boolean authenticate(Request request, Response response) {
- boolean isLoginAttempt = isLoginAttempt(request);
-
- Form query = request.getOriginalRef().getQueryAsForm();
- String redirect = query.getFirstValue("redirect");
- if (redirect == null || redirect.length() == 0) {
- if (isLoginAttempt) {
- redirect = mDefaultRedirect;
- } else {
- redirect = request.getResourceRef().getPath();
- }
- }
-
- boolean authenticationFailed = false;
-
- if (isLoginAttempt) {
- LOG.debug("Attempting authentication");
-
- // Process login form
- final Form form = new Form(request.getEntity());
- final String email = form.getFirstValue("email");
- final String password = form.getFirstValue("password");
-
- boolean authenticated = false;
-
- if (email != null && !"".equals(email) &&
- password != null && !"".equals(password)) {
-
- LOG.debug("Got login request from " + email);
-
- request.setChallengeResponse(
- new ChallengeResponse(ChallengeScheme.HTTP_BASIC, email, password.toCharArray()));
-
- // We expect the verifier to setup the User object.
- int result = mVerifier.verify(request, response);
- if (result == Verifier.RESULT_VALID) {
- return true;
- }
- }
-
- authenticationFailed = true;
- }
-
- if (!isOptional() || authenticationFailed) {
- Reference ref = new Reference(mLoginPage);
- ref.addQueryParameter("redirect", redirect);
-
- if (authenticationFailed) {
- ref.addQueryParameter("retry", "t");
- }
-
- LOG.debug("Redirecting to " + ref);
- response.redirectSeeOther(ref.toString());
- }
- LOG.debug("Failing authentication.");
- return false;
- }
-
- @Override
- protected int authenticated(Request request, Response response) {
- super.authenticated(request, response);
-
- Form query = request.getOriginalRef().getQueryAsForm();
- String redirect = query.getFirstValue("redirect");
- if (redirect == null || redirect.length() == 0) {
- redirect = mDefaultRedirect;
- }
-
- // TODO: Ensure redirect is a relative url.
- LOG.debug("Redirecting to " + redirect);
- response.redirectSeeOther(redirect);
-
- return CONTINUE;
- }
-
- private boolean isLoginAttempt(Request request) {
- String requestPath = request.getResourceRef().getPath();
- return request.getMethod() == Method.POST && mLoginPostUrl.equals(requestPath);
- }
-}
diff --git a/src/com/p4square/grow/frontend/LoginPageResource.java b/src/com/p4square/grow/frontend/LoginPageResource.java
deleted file mode 100644
index 38eba07..0000000
--- a/src/com/p4square/grow/frontend/LoginPageResource.java
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * Copyright 2013 Jesse Morgan
- */
-
-package com.p4square.grow.frontend;
-
-import java.util.Map;
-
-import freemarker.template.Template;
-
-import org.restlet.data.Form;
-import org.restlet.data.MediaType;
-import org.restlet.data.Status;
-import org.restlet.resource.ServerResource;
-import org.restlet.representation.Representation;
-import org.restlet.ext.freemarker.TemplateRepresentation;
-
-import org.apache.log4j.Logger;
-
-import com.p4square.fmfacade.FreeMarkerPageResource;
-
-/**
- * LoginPageResource presents a login page template and processes the response.
- * Upon successful authentication, the user is redirected to another page and
- * a cookie is set.
- *
- * @author Jesse Morgan <jesse@jesterpm.net>
- */
-public class LoginPageResource extends FreeMarkerPageResource {
- private static Logger cLog = Logger.getLogger(LoginPageResource.class);
-
- private GrowFrontend mGrowFrontend;
-
- private String mErrorMessage;
-
- @Override
- public void doInit() {
- super.doInit();
-
- mGrowFrontend = (GrowFrontend) getApplication();
-
- mErrorMessage = null;
- }
-
- /**
- * Return the login page.
- */
- @Override
- protected Representation get() {
- Template t = mGrowFrontend.getTemplate("pages/login.html.ftl");
-
- try {
- if (t == null) {
- setStatus(Status.CLIENT_ERROR_NOT_FOUND);
- return null;
- }
-
- Map<String, Object> root = getRootObject();
-
- Form query = getRequest().getOriginalRef().getQueryAsForm();
- String redirect = query.getFirstValue("redirect");
- root.put("redirect", redirect);
- String retry = query.getFirstValue("retry");
- if ("t".equals(retry)) {
- root.put("errorMessage", "Invalid email or password.");
- }
-
- return new TemplateRepresentation(t, root, MediaType.TEXT_HTML);
-
- } catch (Exception e) {
- cLog.fatal("Could not render page: " + e.getMessage(), e);
- setStatus(Status.SERVER_ERROR_INTERNAL);
- return null;
- }
- }
-
-}
diff --git a/src/com/p4square/grow/frontend/LogoutResource.java b/src/com/p4square/grow/frontend/LogoutResource.java
deleted file mode 100644
index e26dcb7..0000000
--- a/src/com/p4square/grow/frontend/LogoutResource.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright 2013 Jesse Morgan
- */
-
-package com.p4square.grow.frontend;
-
-import org.restlet.representation.Representation;
-import org.restlet.representation.StringRepresentation;
-import org.restlet.resource.ServerResource;
-
-import com.p4square.session.Sessions;
-
-import com.p4square.grow.config.Config;
-
-/**
- * This Resource removes a user's session and session cookies.
- *
- * @author Jesse Morgan <jesse@jesterpm.net>
- */
-public class LogoutResource extends ServerResource {
- private Config mConfig;
-
- @Override
- protected void doInit() {
- super.doInit();
-
- GrowFrontend growFrontend = (GrowFrontend) getApplication();
- mConfig = growFrontend.getConfig();
- }
-
- @Override
- protected Representation get() {
- Sessions.getInstance().delete(getRequest(), getResponse());
-
- String nextPage = mConfig.getString("dynamicRoot", "");
- nextPage += "/index.html";
- getResponse().redirectSeeOther(nextPage);
- return new StringRepresentation("Redirecting to " + nextPage);
- }
-}
diff --git a/src/com/p4square/grow/frontend/NewAccountResource.java b/src/com/p4square/grow/frontend/NewAccountResource.java
deleted file mode 100644
index 5c13017..0000000
--- a/src/com/p4square/grow/frontend/NewAccountResource.java
+++ /dev/null
@@ -1,135 +0,0 @@
-/*
- * Copyright 2013 Jesse Morgan
- */
-
-package com.p4square.grow.frontend;
-
-import java.util.Map;
-
-import com.p4square.f1oauth.FellowshipOneIntegrationDriver;
-import freemarker.template.Template;
-
-import org.restlet.data.Form;
-import org.restlet.data.MediaType;
-import org.restlet.data.Status;
-import org.restlet.representation.Representation;
-import org.restlet.representation.StringRepresentation;
-import org.restlet.ext.freemarker.TemplateRepresentation;
-
-import org.apache.log4j.Logger;
-
-import com.p4square.f1oauth.F1Access;
-import com.p4square.restlet.oauth.OAuthException;
-
-import com.p4square.fmfacade.FreeMarkerPageResource;
-
-/**
- * This resource creates a new InFellowship account.
- *
- * @author Jesse Morgan <jesse@jesterpm.net>
- */
-public class NewAccountResource extends FreeMarkerPageResource {
- private static Logger LOG = Logger.getLogger(NewAccountResource.class);
-
- private GrowFrontend mGrowFrontend;
- private F1Access mHelper;
-
- private String mErrorMessage;
-
- private String mLoginPageUrl;
- private String mVerificationPage;
-
- @Override
- public void doInit() {
- super.doInit();
-
- mGrowFrontend = (GrowFrontend) getApplication();
-
- final IntegrationDriver driver = mGrowFrontend.getThirdPartyIntegrationFactory();
- if (driver instanceof FellowshipOneIntegrationDriver) {
- mHelper = ((FellowshipOneIntegrationDriver) driver).getF1Access();
- } else {
- LOG.error("NewAccountResource only works with F1!");
- mHelper = null;
- }
-
- mErrorMessage = "";
-
- mLoginPageUrl = mGrowFrontend.getConfig().getString("postAccountCreationPage",
- getRequest().getRootRef().toString());
- mVerificationPage = mGrowFrontend.getConfig().getString("dynamicRoot", "")
- + "/verification.html";
- }
-
- /**
- * Return the login page.
- */
- @Override
- protected Representation get() {
- Template t = mGrowFrontend.getTemplate("pages/newaccount.html.ftl");
-
- try {
- if (t == null) {
- setStatus(Status.CLIENT_ERROR_NOT_FOUND);
- return ErrorPage.TEMPLATE_NOT_FOUND;
- }
-
- Map<String, Object> root = getRootObject();
- if (mErrorMessage.length() > 0) {
- root.put("errorMessage", mErrorMessage);
- }
-
- return new TemplateRepresentation(t, root, MediaType.TEXT_HTML);
-
- } catch (Exception e) {
- LOG.fatal("Could not render page: " + e.getMessage(), e);
- setStatus(Status.SERVER_ERROR_INTERNAL);
- return ErrorPage.RENDER_ERROR;
- }
- }
-
- @Override
- protected Representation post(Representation rep) {
- if (mHelper == null) {
- mErrorMessage += "F1 support is not enabled! ";
- return get();
- }
-
- Form form = new Form(rep);
-
- String firstname = form.getFirstValue("firstname");
- String lastname = form.getFirstValue("lastname");
- String email = form.getFirstValue("email");
-
- if (isEmpty(firstname)) {
- mErrorMessage += "First Name is a required field. ";
- }
- if (isEmpty(lastname)) {
- mErrorMessage += "Last Name is a required field. ";
- }
- if (isEmpty(email)) {
- mErrorMessage += "Email is a required field. ";
- }
-
- if (mErrorMessage.length() > 0) {
- return get();
- }
-
- try {
- if (!mHelper.createAccount(firstname, lastname, email, mLoginPageUrl)) {
- mErrorMessage = "An account with that address already exists.";
- return get();
- }
-
- getResponse().redirectSeeOther(mVerificationPage);
- return new StringRepresentation("Redirecting to " + mVerificationPage);
-
- } catch (OAuthException e) {
- return new ErrorPage(e.getStatus().getDescription());
- }
- }
-
- private boolean isEmpty(String s) {
- return s == null || s.trim().length() == 0;
- }
-}
diff --git a/src/com/p4square/grow/frontend/NewBelieverResource.java b/src/com/p4square/grow/frontend/NewBelieverResource.java
deleted file mode 100644
index 8fe078a..0000000
--- a/src/com/p4square/grow/frontend/NewBelieverResource.java
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Copyright 2014 Jesse Morgan
- */
-
-package com.p4square.grow.frontend;
-
-import freemarker.template.Template;
-
-import org.restlet.data.CookieSetting;
-import org.restlet.data.MediaType;
-import org.restlet.data.Status;
-import org.restlet.representation.Representation;
-import org.restlet.ext.freemarker.TemplateRepresentation;
-
-import org.apache.log4j.Logger;
-
-import com.p4square.fmfacade.FreeMarkerPageResource;
-
-/**
- * This resource displays the transitional page between chapters.
- *
- * @author Jesse Morgan <jesse@jesterpm.net>
- */
-public class NewBelieverResource extends FreeMarkerPageResource {
- private static final Logger LOG = Logger.getLogger(NewBelieverResource.class);
-
- public static final String COOKIE_NAME = "seeker";
-
- private GrowFrontend mGrowFrontend;
-
- @Override
- public void doInit() {
- super.doInit();
-
- mGrowFrontend = (GrowFrontend) getApplication();
- }
-
- /**
- * Display the New Believer page.
- *
- * The New Believer page creates a cookie to remember the user,
- * explains what's going on, and then asks the user to go to the login
- * page.
- *
- * When the user hits the {@link AccountRedirectResource} the cookie
- * is read and the user is moved ahead to the training section.
- */
- @Override
- protected Representation get() {
- Template t = mGrowFrontend.getTemplate("templates/newbeliever.ftl");
-
- try {
- if (t == null) {
- setStatus(Status.CLIENT_ERROR_NOT_FOUND);
- return ErrorPage.TEMPLATE_NOT_FOUND;
- }
-
- // Set the new believer cookie
- CookieSetting cookie = new CookieSetting(COOKIE_NAME, "true");
- cookie.setPath("/");
- getRequest().getCookies().add(cookie);
- getResponse().getCookieSettings().add(cookie);
-
- return new TemplateRepresentation(t, getRootObject(), MediaType.TEXT_HTML);
-
- } catch (Exception e) {
- LOG.fatal("Could not render page: " + e.getMessage(), e);
- setStatus(Status.SERVER_ERROR_INTERNAL);
- return ErrorPage.RENDER_ERROR;
- }
- }
-}
diff --git a/src/com/p4square/grow/frontend/NotFoundException.java b/src/com/p4square/grow/frontend/NotFoundException.java
deleted file mode 100644
index dfa2a4c..0000000
--- a/src/com/p4square/grow/frontend/NotFoundException.java
+++ /dev/null
@@ -1,13 +0,0 @@
-/*
- * Copyright 2014 Jesse Morgan
- */
-
-package com.p4square.grow.frontend;
-
-import java.io.IOException;
-
-public class NotFoundException extends IOException {
- public NotFoundException(final String message) {
- super(message);
- }
-}
diff --git a/src/com/p4square/grow/frontend/ProgressReporter.java b/src/com/p4square/grow/frontend/ProgressReporter.java
deleted file mode 100644
index 2f36832..0000000
--- a/src/com/p4square/grow/frontend/ProgressReporter.java
+++ /dev/null
@@ -1,30 +0,0 @@
-package com.p4square.grow.frontend;
-
-import org.restlet.security.User;
-
-import java.util.Date;
-
-/**
- * A ProgressReporter is used to record a User's progress in a Church Management System.
- */
-public interface ProgressReporter {
-
- /**
- * Report that the User completed the assessment.
- *
- * @param user The user who completed the assessment.
- * @param level The assessment level.
- * @param date The completion date.
- * @param results Result information (e.g. json of the results).
- */
- void reportAssessmentComplete(User user, String level, Date date, String results);
-
- /**
- * Report that the User completed the chapter.
- *
- * @param user The user who completed the chapter.
- * @param chapter The chapter completed.
- * @param date The completion date.
- */
- void reportChapterComplete(User user, String chapter, Date date);
-}
diff --git a/src/com/p4square/grow/frontend/SurveyPageResource.java b/src/com/p4square/grow/frontend/SurveyPageResource.java
deleted file mode 100644
index 3575fe3..0000000
--- a/src/com/p4square/grow/frontend/SurveyPageResource.java
+++ /dev/null
@@ -1,343 +0,0 @@
-/*
- * Copyright 2013 Jesse Morgan
- */
-
-package com.p4square.grow.frontend;
-
-import java.io.IOException;
-
-import java.util.Map;
-import java.util.HashMap;
-
-import freemarker.template.Template;
-
-import org.restlet.data.Form;
-import org.restlet.data.MediaType;
-import org.restlet.data.Status;
-import org.restlet.ext.freemarker.TemplateRepresentation;
-import org.restlet.representation.Representation;
-import org.restlet.representation.StringRepresentation;
-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.Question;
-import com.p4square.grow.model.UserRecord;
-import com.p4square.grow.provider.DelegateProvider;
-import com.p4square.grow.provider.JsonEncodedProvider;
-import com.p4square.grow.provider.Provider;
-
-/**
- * SurveyPageResource handles rendering the survey and processing user's answers.
- *
- * This resource expects the user to be authenticated and the ClientInfo User object
- * to be populated. Each question is requested from the backend along with the
- * user's previous answer. Each answer is sent to the backend and the user is redirected
- * to the next question. After the last question the user is sent to his results.
- *
- * @author Jesse Morgan <jesse@jesterpm.net>
- */
-public class SurveyPageResource extends FreeMarkerPageResource {
- private static final Logger LOG = Logger.getLogger(SurveyPageResource.class);
-
- private Config mConfig;
- private Template mSurveyTemplate;
- private JsonRequestClient mJsonClient;
- private Provider<String, Question> mQuestionProvider;
- private Provider<String, UserRecord> mUserRecordProvider;
-
- // Fields pertaining to this request.
- private String mQuestionId;
- private String mUserId;
-
- @Override
- public void doInit() {
- super.doInit();
-
- GrowFrontend growFrontend = (GrowFrontend) getApplication();
- mConfig = growFrontend.getConfig();
- mSurveyTemplate = growFrontend.getTemplate("templates/survey.ftl");
- if (mSurveyTemplate == null) {
- LOG.fatal("Could not find survey template.");
- setStatus(Status.SERVER_ERROR_INTERNAL);
- }
-
- mJsonClient = new JsonRequestClient(getContext().getClientDispatcher());
- mQuestionProvider = new DelegateProvider<String, String, Question>(
- new JsonRequestProvider<Question>(getContext().getClientDispatcher(),
- Question.class)) {
- @Override
- public String makeKey(String questionId) {
- return getBackendEndpoint() + "/assessment/question/" + questionId;
- }
- };
-
- 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();
- }
-
- /**
- * Return a page with a survey question.
- */
- @Override
- protected Representation get() {
- try {
- // Get the current question.
- if (mQuestionId == null) {
- // Get user's current question
- mQuestionId = getCurrentQuestionId();
-
- if (mQuestionId != null) {
- Question lastQuestion = getQuestion(mQuestionId);
- return redirectToNextQuestion(lastQuestion, getAnswer(mQuestionId));
- }
- }
-
- // If we don't have a current question, get the first one.
- if (mQuestionId == null) {
- mQuestionId = "first";
- }
-
- Question question = getQuestion(mQuestionId);
- if (question == null) {
- setStatus(Status.CLIENT_ERROR_NOT_FOUND);
- return new ErrorPage("Could not find the question.");
- }
-
- // Set the real question id if a meta-id was used (i.e. first)
- mQuestionId = question.getId();
-
- // Get any previous answer to the question
- String selectedAnswer = getAnswer(mQuestionId);
-
- Map root = getRootObject();
- root.put("question", question);
- root.put("selectedAnswerId", selectedAnswer);
-
- // Get the question count and compute progress
- {
- JsonResponse response = backendGet("/assessment/question/count");
- if (response.getStatus().isSuccess()) {
- Map countData = response.getMap();
- if (countData != null) {
- response = backendGet("/accounts/" + mUserId + "/assessment");
- if (response.getStatus().isSuccess()) {
- Integer completed = (Integer) response.getMap().get("totalAnswers");
- Integer total = (Integer) countData.get("count");
-
- if (completed != null && total != null && total != 0) {
- root.put("percentComplete", String.valueOf((int) (100.0 * completed) / total));
- }
- }
- }
- }
- }
-
- return new TemplateRepresentation(mSurveyTemplate, root, MediaType.TEXT_HTML);
-
- } catch (Exception e) {
- LOG.fatal("Could not render page: " + e.getMessage(), e);
- setStatus(Status.SERVER_ERROR_INTERNAL);
- return ErrorPage.RENDER_ERROR;
- }
- }
-
- /**
- * Record a survey answer and redirect to the next question.
- */
- @Override
- protected Representation post(Representation entity) {
- final Form form = new Form(entity);
- final String answerId = form.getFirstValue("answer");
- final String direction = form.getFirstValue("direction");
- boolean justGoBack = false; // FIXME: Ugly hack
-
- if (mQuestionId == null || answerId == null || answerId.length() == 0) {
- if ("previous".equals(direction)) {
- // Just go back
- justGoBack = true;
-
- } else {
- // Something is wrong.
- setStatus(Status.CLIENT_ERROR_BAD_REQUEST);
- return new ErrorPage("Question or answer messing.");
- }
- }
-
- try {
- // Find the question
- Question question = getQuestion(mQuestionId);
- if (question == null) {
- // User is answering a question which doesn't exist
- setStatus(Status.CLIENT_ERROR_NOT_FOUND);
- return new ErrorPage("Question not found.");
- }
-
- // Store answer
- if (!justGoBack) {
- Map<String, String> answer = new HashMap<String, String>();
- answer.put("answerId", answerId);
- JsonResponse response = backendPut("/accounts/" + mUserId +
- "/assessment/answers/" + mQuestionId, answer);
-
- if (!response.getStatus().isSuccess()) {
- // Something went wrong talking to the backend, error out.
- LOG.fatal("Error recording survey answer " + response.getStatus());
- setStatus(Status.SERVER_ERROR_INTERNAL);
- return ErrorPage.BACKEND_ERROR;
- }
- }
-
- // Find the next question or finish the assessment.
- if ("previous".equals(direction)) {
- return redirectToPreviousQuestion(question);
-
- } else {
- return redirectToNextQuestion(question, answerId);
- }
-
- } catch (Exception e) {
- LOG.fatal("Could not render page: " + e.getMessage(), e);
- setStatus(Status.SERVER_ERROR_INTERNAL);
- return ErrorPage.RENDER_ERROR;
- }
- }
-
- private Question getQuestion(String id) {
- try {
- return mQuestionProvider.get(id);
-
- } catch (IOException e) {
- LOG.warn("Error fetching question.", e);
- return null;
- }
- }
-
- private String getAnswer(String questionId) {
- try {
- JsonResponse response = backendGet("/accounts/" + mUserId + "/assessment/answers/" + questionId);
- if (response.getStatus().isSuccess()) {
- return (String) response.getMap().get("answerId");
- }
-
- } catch (ClientException e) {
- LOG.warn("Error fetching answer to question " + questionId, e);
- }
-
- return null;
- }
-
- private Representation redirectToNextQuestion(Question question, String answerid) {
- String nextQuestionId = question.getNextQuestion(answerid);
-
- if (nextQuestionId == null) {
- // Just finished the last question. Update the user's account
- try {
- UserRecord account = null;
- try {
- account = mUserRecordProvider.get(mUserId);
- } catch (NotFoundException e) {
- // User record doesn't exist, so create a new one.
- account = new UserRecord(getRequest().getClientInfo().getUser());
- }
- account.setLanding("training");
- mUserRecordProvider.put(mUserId, account);
- } catch (IOException e) {
- LOG.warn("IOException updating landing for " + mUserId, e);
- }
-
- String nextPage = mConfig.getString("dynamicRoot", "");
- nextPage += "/account/assessment/results";
- getResponse().redirectSeeOther(nextPage);
- return new StringRepresentation("Redirecting to " + nextPage);
- }
-
- return redirectToQuestion(nextQuestionId);
- }
-
- private Representation redirectToPreviousQuestion(Question question) {
- String nextQuestionId = question.getPreviousQuestion();
-
- if (nextQuestionId == null) {
- nextQuestionId = (String) question.getId();
- }
-
- return redirectToQuestion(nextQuestionId);
- }
-
- private Representation redirectToQuestion(String id) {
- String nextPage = mConfig.getString("dynamicRoot", "");
- nextPage += "/account/assessment/question/" + id;
- getResponse().redirectSeeOther(nextPage);
- return new StringRepresentation("Redirecting to " + nextPage);
- }
-
- private String getCurrentQuestionId() {
- String id = null;
- try {
- JsonResponse response = backendGet("/accounts/" + mUserId + "/assessment");
-
- if (response.getStatus().isSuccess()) {
- return (String) response.getMap().get("lastAnswered");
-
- } else {
- LOG.warn("Failed to get assessment results: " + response.getStatus());
- }
-
- } catch (ClientException e) {
- LOG.error("Exception getting assessment results.", e);
- }
-
- return null;
- }
-
- /**
- * @return The backend endpoint URI
- */
- 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/TrainingPageResource.java b/src/com/p4square/grow/frontend/TrainingPageResource.java
deleted file mode 100644
index a1e7789..0000000
--- a/src/com/p4square/grow/frontend/TrainingPageResource.java
+++ /dev/null
@@ -1,268 +0,0 @@
-/*
- * Copyright 2013 Jesse Morgan
- */
-
-package com.p4square.grow.frontend;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.HashMap;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
-
-import freemarker.template.Template;
-
-import org.restlet.data.CookieSetting;
-import org.restlet.data.Form;
-import org.restlet.data.MediaType;
-import org.restlet.data.Status;
-import org.restlet.ext.freemarker.TemplateRepresentation;
-import org.restlet.representation.Representation;
-import org.restlet.representation.StringRepresentation;
-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.FreeMarkerPageResource;
-
-import com.p4square.grow.config.Config;
-import com.p4square.grow.model.TrainingRecord;
-import com.p4square.grow.model.VideoRecord;
-import com.p4square.grow.model.Playlist;
-import com.p4square.grow.provider.TrainingRecordProvider;
-import com.p4square.grow.provider.Provider;
-
-/**
- * TrainingPageResource handles rendering the training page.
- *
- * This resource expects the user to be authenticated and the ClientInfo User object
- * to be populated.
- *
- * @author Jesse Morgan <jesse@jesterpm.net>
- */
-public class TrainingPageResource extends FreeMarkerPageResource {
- private static final Logger LOG = Logger.getLogger(TrainingPageResource.class);
-
- private static final String[] CHAPTERS = { "introduction", "seeker", "believer", "disciple", "teacher", "leader" };
- private static final Comparator<Map<String, Object>> VIDEO_COMPARATOR = new Comparator<Map<String, Object>>() {
- @Override
- public int compare(Map<String, Object> left, Map<String, Object> right) {
- String leftNumberStr = (String) left.get("number");
- String rightNumberStr = (String) right.get("number");
-
- if (leftNumberStr == null || rightNumberStr == null) {
- return -1;
- }
-
- double leftNumber = Double.valueOf(leftNumberStr);
- double rightNumber = Double.valueOf(rightNumberStr);
-
- return Double.compare(leftNumber, rightNumber);
- }
- };
-
- private Config mConfig;
- private Template mTrainingTemplate;
- private JsonRequestClient mJsonClient;
-
- private Provider<String, TrainingRecord> mTrainingRecordProvider;
- private FeedData mFeedData;
-
- // Fields pertaining to this request.
- protected String mChapter;
- protected String mUserId;
-
- @Override
- public void doInit() {
- super.doInit();
-
- GrowFrontend growFrontend = (GrowFrontend) getApplication();
- mConfig = growFrontend.getConfig();
- mTrainingTemplate = growFrontend.getTemplate("templates/training.ftl");
- if (mTrainingTemplate == null) {
- LOG.fatal("Could not find training template.");
- setStatus(Status.SERVER_ERROR_INTERNAL);
- }
-
- mJsonClient = new JsonRequestClient(getContext().getClientDispatcher());
- mTrainingRecordProvider = new TrainingRecordProvider<String>(new JsonRequestProvider<TrainingRecord>(getContext().getClientDispatcher(), TrainingRecord.class)) {
- @Override
- public String makeKey(String userid) {
- return getBackendEndpoint() + "/accounts/" + userid + "/training";
- }
- };
-
- mFeedData = new FeedData(getContext(), mConfig);
-
- mChapter = getAttribute("chapter");
- mUserId = getRequest().getClientInfo().getUser().getIdentifier();
- }
-
- /**
- * Return a page of videos.
- */
- @Override
- protected Representation get() {
- try {
- // Get the training summary
- TrainingRecord trainingRecord = mTrainingRecordProvider.get(mUserId);
- if (trainingRecord == null) {
- setStatus(Status.SERVER_ERROR_INTERNAL);
- return new ErrorPage("Could not retrieve TrainingRecord.");
- }
-
- Playlist playlist = trainingRecord.getPlaylist();
- Map<String, Boolean> chapters = playlist.getChapterStatuses();
- Map<String, Boolean> allowedChapters = new LinkedHashMap<String, Boolean>();
-
- // The user is not allowed to view chapters after his highest completed chapter.
- // In this loop we find which chapters are allowed and check if the user tried
- // to skip ahead.
- boolean allowUserToSkip = mConfig.getBoolean("allowUserToSkip", false) || getQueryValue("magicskip") != null;
- String defaultChapter = null;
- boolean userTriedToSkip = false;
- int overallProgress = 0;
-
- boolean foundRequired = false;
- for (String chapterId : getChaptersInOrder()) {
- boolean allowed = true;
-
- Boolean completed = chapters.get(chapterId);
- if (completed != null) {
- if (!foundRequired) {
- if (!completed) {
- // The first incomplete chapter is the highest allowed chapter.
- foundRequired = true;
- defaultChapter = chapterId;
- }
-
- } else {
- allowed = allowUserToSkip;
-
- if (!allowUserToSkip && chapterId.equals(mChapter)) {
- userTriedToSkip = true;
- }
- }
-
- allowedChapters.put(chapterId, allowed);
-
- if (completed) {
- overallProgress++;
- }
- }
- }
-
- // Overall progress is the percentage of chapters complete
- overallProgress = (int) ((double) overallProgress / getChaptersInOrder().length * 100);
-
- if (defaultChapter == null) {
- // Everything is completed... send them back to introduction.
- defaultChapter = "introduction";
- }
-
- if (mChapter == null || userTriedToSkip) {
- // No chapter was specified or the user tried to skip ahead.
- // Either case, redirect.
- String nextPage = mConfig.getString("dynamicRoot", "");
- nextPage += "/account/training/" + defaultChapter;
- getResponse().redirectSeeOther(nextPage);
- return new StringRepresentation("Redirecting to " + nextPage);
- }
-
-
- // Get videos for the chapter.
- List<Map<String, Object>> videos = null;
- {
- JsonResponse response = backendGet("/training/" + mChapter);
- if (!response.getStatus().isSuccess()) {
- setStatus(Status.CLIENT_ERROR_NOT_FOUND);
- return null;
- }
- videos = (List<Map<String, Object>>) response.getMap().get("videos");
- Collections.sort(videos, VIDEO_COMPARATOR);
- }
-
- // Mark the completed videos as completed
- int chapterProgress = 0;
- for (Map<String, Object> video : videos) {
- boolean completed = false;
- VideoRecord record = playlist.find((String) video.get("id"));
- LOG.info("VideoId: " + video.get("id"));
- if (record != null) {
- LOG.info("VideoRecord: " + record.getComplete());
- completed = record.getComplete();
- }
- video.put("completed", completed);
-
- if (completed) {
- chapterProgress++;
- }
- }
- chapterProgress = chapterProgress * 100 / videos.size();
-
- Map root = getRootObject();
- root.put("chapter", mChapter);
- root.put("chapters", allowedChapters.keySet());
- root.put("isChapterAllowed", allowedChapters);
- root.put("chapterProgress", chapterProgress);
- root.put("overallProgress", overallProgress);
- root.put("videos", videos);
- root.put("allowUserToSkip", allowUserToSkip);
-
- // 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)) {
- showfeed = false;
- }
-
- root.put("showfeed", showfeed);
- if (showfeed) {
- root.put("feeddata", mFeedData);
- }
-
- return new TemplateRepresentation(mTrainingTemplate, root, MediaType.TEXT_HTML);
-
- } catch (Exception e) {
- LOG.fatal("Could not render page: " + e.getMessage(), e);
- setStatus(Status.SERVER_ERROR_INTERNAL);
- return ErrorPage.RENDER_ERROR;
- }
- }
-
- /**
- * This method returns a list of chapters in the correct order.
- */
- protected String[] getChaptersInOrder() {
- return CHAPTERS;
- }
-
- /**
- * @return The backend endpoint URI
- */
- 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;
- }
-
-}
diff --git a/src/com/p4square/grow/frontend/VideosResource.java b/src/com/p4square/grow/frontend/VideosResource.java
deleted file mode 100644
index 2099a77..0000000
--- a/src/com/p4square/grow/frontend/VideosResource.java
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
- * Copyright 2013 Jesse Morgan
- */
-
-package com.p4square.grow.frontend;
-
-import java.util.HashMap;
-import java.util.Map;
-
-import freemarker.template.Template;
-
-import org.restlet.data.Form;
-import org.restlet.data.MediaType;
-import org.restlet.data.Status;
-import org.restlet.ext.jackson.JacksonRepresentation;
-import org.restlet.representation.Representation;
-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.grow.config.Config;
-
-/**
- * VideosResource returns JSON blobs with video information and records watched
- * videos.
- *
- * @author Jesse Morgan <jesse@jesterpm.net>
- */
-public class VideosResource extends ServerResource {
- private static Logger cLog = Logger.getLogger(VideosResource.class);
-
- private Config mConfig;
- private JsonRequestClient mJsonClient;
-
- // Fields pertaining to this request.
- private String mChapter;
- private String mVideoId;
- private String mUserId;
-
- @Override
- public void doInit() {
- super.doInit();
-
- GrowFrontend growFrontend = (GrowFrontend) getApplication();
- mConfig = growFrontend.getConfig();
-
- mJsonClient = new JsonRequestClient(getContext().getClientDispatcher());
-
- mChapter = getAttribute("chapter");
- mVideoId = getAttribute("videoId");
- mUserId = getRequest().getClientInfo().getUser().getIdentifier();
- }
-
- /**
- * Fetch a video record from the backend.
- */
- @Override
- protected Representation get() {
- try {
- JsonResponse response = backendGet("/training/" + mChapter + "/videos/" + mVideoId);
-
- if (response.getStatus().isSuccess()) {
- return new JacksonRepresentation<Map>(response.getMap());
-
- } else {
- setStatus(response.getStatus());
- return null;
- }
-
- } catch (Exception e) {
- cLog.fatal("Could not render page: " + e.getMessage(), e);
- setStatus(Status.SERVER_ERROR_INTERNAL);
- return null;
- }
- }
-
- /**
- * Mark a video as completed.
- */
- @Override
- protected Representation post(Representation entity) {
- Map<String, Object> data = new HashMap<String, Object>();
- data.put("complete", "true");
- JsonResponse response = backendPut("/accounts/" + mUserId + "/training/videos/" + mVideoId, data);
-
- if (!response.getStatus().isSuccess()) {
- // Something went wrong talking to the backend, error out.
- cLog.fatal("Error recording completed video " + response.getStatus());
- setStatus(Status.SERVER_ERROR_INTERNAL);
- return ErrorPage.BACKEND_ERROR;
- }
-
- setStatus(Status.SUCCESS_NO_CONTENT);
- return null;
- }
-
- /**
- * @return The backend endpoint URI
- */
- 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) {
- cLog.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)) {
- cLog.warn("Error making backend request for '" + uri + "'. status = " + response.getStatus().toString());
- }
-
- return response;
- }
-
- private JsonResponse backendPut(final String uri, final Map data) {
- cLog.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)) {
- cLog.warn("Error making backend request for '" + uri + "'. status = " + response.getStatus().toString());
- }
-
- return response;
- }
-}