diff options
Diffstat (limited to 'src/com/p4square/grow/frontend')
-rw-r--r-- | src/com/p4square/grow/frontend/ErrorPage.java | 3 | ||||
-rw-r--r-- | src/com/p4square/grow/frontend/FeedData.java | 31 | ||||
-rw-r--r-- | src/com/p4square/grow/frontend/FeedResource.java | 107 | ||||
-rw-r--r-- | src/com/p4square/grow/frontend/GrowFrontend.java | 2 | ||||
-rw-r--r-- | src/com/p4square/grow/frontend/JsonRequestProvider.java | 24 |
5 files changed, 159 insertions, 8 deletions
diff --git a/src/com/p4square/grow/frontend/ErrorPage.java b/src/com/p4square/grow/frontend/ErrorPage.java index 5ae64d9..81abe74 100644 --- a/src/com/p4square/grow/frontend/ErrorPage.java +++ b/src/com/p4square/grow/frontend/ErrorPage.java @@ -36,6 +36,9 @@ public class ErrorPage extends WriterRepresentation { 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; diff --git a/src/com/p4square/grow/frontend/FeedData.java b/src/com/p4square/grow/frontend/FeedData.java index acff8d9..eddc6a4 100644 --- a/src/com/p4square/grow/frontend/FeedData.java +++ b/src/com/p4square/grow/frontend/FeedData.java @@ -28,8 +28,12 @@ public class FeedData { private final Config mConfig; private final String mBackendURI; - private final Provider<String, List<MessageThread>> mThreadProvider; - private final Provider<String, List<Message>> mMessageProvider; + // 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; @@ -40,18 +44,33 @@ public class FeedData { TypeFactory factory = JsonEncodedProvider.MAPPER.getTypeFactory(); JavaType threadType = factory.constructCollectionType(List.class, MessageThread.class); - mThreadProvider = new JsonRequestProvider<List<MessageThread>>(clientDispatcher, threadType); + mThreadsProvider = new JsonRequestProvider<List<MessageThread>>(clientDispatcher, threadType); + mThreadProvider = new JsonRequestProvider<MessageThread>(clientDispatcher, MessageThread.class); JavaType messageType = factory.constructCollectionType(List.class, Message.class); - mMessageProvider = new JsonRequestProvider<List<Message>>(clientDispatcher, messageType); + mMessagesProvider = new JsonRequestProvider<List<Message>>(clientDispatcher, messageType); + mMessageProvider = new JsonRequestProvider<Message>(clientDispatcher, Message.class); } public List<MessageThread> getThreads(final String topic) throws IOException { - return mThreadProvider.get(makeUrl(topic)); + return mThreadsProvider.get(makeUrl(topic)); } public List<Message> getMessages(final String topic, final String threadId) throws IOException { - return mMessageProvider.get(makeUrl(topic, threadId)); + 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) { diff --git a/src/com/p4square/grow/frontend/FeedResource.java b/src/com/p4square/grow/frontend/FeedResource.java new file mode 100644 index 0000000..eea89b1 --- /dev/null +++ b/src/com/p4square/grow/frontend/FeedResource.java @@ -0,0 +1,107 @@ +/* + * Copyright 2014 Jesse Morgan + */ + +package com.p4square.grow.frontend; + +import java.io.IOException; + +import java.util.Arrays; +import java.util.HashSet; + +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 static final HashSet<String> TOPICS = new HashSet(Arrays.asList("introduction", "seeker", "believer", + "disciple", "teacher")); + + 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 || !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/GrowFrontend.java b/src/com/p4square/grow/frontend/GrowFrontend.java index 540d5a7..2ad3ed6 100644 --- a/src/com/p4square/grow/frontend/GrowFrontend.java +++ b/src/com/p4square/grow/frontend/GrowFrontend.java @@ -111,6 +111,8 @@ public class GrowFrontend extends FMFacade { accountRouter.attach("/training/leader", GroupLeaderTrainingPageResource.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); diff --git a/src/com/p4square/grow/frontend/JsonRequestProvider.java b/src/com/p4square/grow/frontend/JsonRequestProvider.java index 8eee6d3..a04294d 100644 --- a/src/com/p4square/grow/frontend/JsonRequestProvider.java +++ b/src/com/p4square/grow/frontend/JsonRequestProvider.java @@ -16,6 +16,7 @@ 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; /** @@ -23,7 +24,7 @@ import com.p4square.grow.provider.JsonEncodedProvider; * * @author Jesse Morgan <jesse@jesterpm.net> */ -public class JsonRequestProvider<V> extends JsonEncodedProvider<String, V> { +public class JsonRequestProvider<V> extends JsonEncodedProvider<V> implements Provider<String, V> { private final Restlet mDispatcher; @@ -66,7 +67,26 @@ public class JsonRequestProvider<V> extends JsonEncodedProvider<String, V> { 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()); + } + } } |