Merge branch 'release-0.4.2'
[Sone.git] / src / main / java / net / pterodactylus / sone / web / ajax / GetStatusAjaxPage.java
1 /*
2  * Sone - GetStatusAjaxPage.java - Copyright © 2010 David Roden
3  *
4  * This program is free software: you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation, either version 3 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
16  */
17
18 package net.pterodactylus.sone.web.ajax;
19
20 import java.io.IOException;
21 import java.io.StringWriter;
22 import java.text.DateFormat;
23 import java.text.SimpleDateFormat;
24 import java.util.ArrayList;
25 import java.util.Collections;
26 import java.util.Date;
27 import java.util.HashSet;
28 import java.util.List;
29 import java.util.Set;
30
31 import net.pterodactylus.sone.data.Post;
32 import net.pterodactylus.sone.data.Reply;
33 import net.pterodactylus.sone.data.Sone;
34 import net.pterodactylus.sone.template.SoneAccessor;
35 import net.pterodactylus.sone.web.WebInterface;
36 import net.pterodactylus.util.json.JsonArray;
37 import net.pterodactylus.util.json.JsonObject;
38 import net.pterodactylus.util.notify.Notification;
39 import net.pterodactylus.util.notify.TemplateNotification;
40 import net.pterodactylus.util.template.TemplateContext;
41
42 /**
43  * The “get status” AJAX handler returns all information that is necessary to
44  * update the web interface in real-time.
45  *
46  * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
47  */
48 public class GetStatusAjaxPage extends JsonPage {
49
50         /** Date formatter. */
51         private static final DateFormat dateFormat = new SimpleDateFormat("MMM d, yyyy, HH:mm:ss");
52
53         /**
54          * Creates a new “get status” AJAX handler.
55          *
56          * @param webInterface
57          *            The Sone web interface
58          */
59         public GetStatusAjaxPage(WebInterface webInterface) {
60                 super("getStatus.ajax", webInterface);
61         }
62
63         /**
64          * {@inheritDoc}
65          */
66         @Override
67         protected JsonObject createJsonObject(Request request) {
68                 /* load Sones. */
69                 boolean loadAllSones = Boolean.parseBoolean(request.getHttpRequest().getParam("loadAllSones", "true"));
70                 Set<Sone> sones = new HashSet<Sone>(Collections.singleton(getCurrentSone(request.getToadletContext(), false)));
71                 if (loadAllSones) {
72                         sones.addAll(webInterface.getCore().getSones());
73                 }
74                 JsonArray jsonSones = new JsonArray();
75                 for (Sone sone : sones) {
76                         if (sone == null) {
77                                 continue;
78                         }
79                         JsonObject jsonSone = createJsonSone(sone);
80                         jsonSones.add(jsonSone);
81                 }
82                 /* load notifications. */
83                 List<Notification> notifications = new ArrayList<Notification>(webInterface.getNotifications().getChangedNotifications());
84                 Set<Notification> removedNotifications = webInterface.getNotifications().getRemovedNotifications();
85                 Collections.sort(notifications, Notification.LAST_UPDATED_TIME_SORTER);
86                 JsonArray jsonNotifications = new JsonArray();
87                 for (Notification notification : notifications) {
88                         jsonNotifications.add(createJsonNotification(notification));
89                 }
90                 JsonArray jsonRemovedNotifications = new JsonArray();
91                 for (Notification notification : removedNotifications) {
92                         jsonRemovedNotifications.add(createJsonNotification(notification));
93                 }
94                 /* load new posts. */
95                 Set<Post> newPosts = webInterface.getNewPosts();
96                 JsonArray jsonPosts = new JsonArray();
97                 for (Post post : newPosts) {
98                         JsonObject jsonPost = new JsonObject();
99                         jsonPost.put("id", post.getId());
100                         jsonPost.put("sone", post.getSone().getId());
101                         jsonPost.put("recipient", (post.getRecipient() != null) ? post.getRecipient().getId() : null);
102                         jsonPost.put("time", post.getTime());
103                         jsonPosts.add(jsonPost);
104                 }
105                 /* load new replies. */
106                 Set<Reply> newReplies = webInterface.getNewReplies();
107                 JsonArray jsonReplies = new JsonArray();
108                 for (Reply reply : newReplies) {
109                         JsonObject jsonReply = new JsonObject();
110                         jsonReply.put("id", reply.getId());
111                         jsonReply.put("sone", reply.getSone().getId());
112                         jsonReply.put("post", reply.getPost().getId());
113                         jsonReply.put("postSone", reply.getPost().getSone().getId());
114                         jsonReplies.add(jsonReply);
115                 }
116                 return createSuccessJsonObject().put("sones", jsonSones).put("notifications", jsonNotifications).put("removedNotifications", jsonRemovedNotifications).put("newPosts", jsonPosts).put("newReplies", jsonReplies);
117         }
118
119         /**
120          * {@inheritDoc}
121          */
122         @Override
123         protected boolean needsFormPassword() {
124                 return false;
125         }
126
127         /**
128          * {@inheritDoc}
129          */
130         @Override
131         protected boolean requiresLogin() {
132                 return false;
133         }
134
135         //
136         // PRIVATE METHODS
137         //
138
139         /**
140          * Creates a JSON object from the given Sone.
141          *
142          * @param sone
143          *            The Sone to convert to a JSON object
144          * @return The JSON representation of the given Sone
145          */
146         private JsonObject createJsonSone(Sone sone) {
147                 JsonObject jsonSone = new JsonObject();
148                 jsonSone.put("id", sone.getId());
149                 jsonSone.put("name", SoneAccessor.getNiceName(sone));
150                 jsonSone.put("local", sone.getInsertUri() != null);
151                 jsonSone.put("status", webInterface.getCore().getSoneStatus(sone).name());
152                 jsonSone.put("modified", webInterface.getCore().isModifiedSone(sone));
153                 jsonSone.put("locked", webInterface.getCore().isLocked(sone));
154                 jsonSone.put("lastUpdatedUnknown", sone.getTime() == 0);
155                 synchronized (dateFormat) {
156                         jsonSone.put("lastUpdated", dateFormat.format(new Date(sone.getTime())));
157                 }
158                 jsonSone.put("age", (System.currentTimeMillis() - sone.getTime()) / 1000);
159                 return jsonSone;
160         }
161
162         /**
163          * Creates a JSON object from the given notification.
164          *
165          * @param notification
166          *            The notification to create a JSON object
167          * @return The JSON object
168          */
169         private JsonObject createJsonNotification(Notification notification) {
170                 JsonObject jsonNotification = new JsonObject();
171                 jsonNotification.put("id", notification.getId());
172                 StringWriter notificationWriter = new StringWriter();
173                 try {
174                         if (notification instanceof TemplateNotification) {
175                                 TemplateContext templateContext = webInterface.getTemplateContextFactory().createTemplateContext().mergeContext(((TemplateNotification) notification).getTemplateContext());
176                                 templateContext.set("notification", notification);
177                                 ((TemplateNotification) notification).render(templateContext, notificationWriter);
178                         } else {
179                                 notification.render(notificationWriter);
180                         }
181                 } catch (IOException ioe1) {
182                         /* StringWriter never throws, ignore. */
183                 }
184                 jsonNotification.put("text", notificationWriter.toString());
185                 jsonNotification.put("createdTime", notification.getCreatedTime());
186                 jsonNotification.put("lastUpdatedTime", notification.getLastUpdatedTime());
187                 jsonNotification.put("dismissable", notification.isDismissable());
188                 return jsonNotification;
189         }
190
191 }