diff options
| author | Jesse Morgan <jesse@jesterpm.net> | 2016-04-09 15:53:24 -0700 | 
|---|---|---|
| committer | Jesse Morgan <jesse@jesterpm.net> | 2016-04-09 15:53:24 -0700 | 
| commit | 371ccae3d1f31ec38f4af77fb7fcd175d49b3cd5 (patch) | |
| tree | 38c4f1e8828f9af9c4b77a173bee0d312b321698 /src/com/p4square/grow/frontend | |
| parent | bbf907e51dfcf157bdee24dead1d531122aa25db (diff) | |
| parent | 3102d8bce3426d9cf41aeaf201c360d342677770 (diff) | |
Merge pull request #10 from PuyallupFoursquare/maven
Switching from Ivy+Ant to Maven.
Diffstat (limited to 'src/com/p4square/grow/frontend')
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; -    } -} | 
