1   /**
2    * Copyright (c) 2000-2010 Liferay, Inc. All rights reserved.
3    *
4    * This library is free software; you can redistribute it and/or modify it under
5    * the terms of the GNU Lesser General Public License as published by the Free
6    * Software Foundation; either version 2.1 of the License, or (at your option)
7    * any later version.
8    *
9    * This library is distributed in the hope that it will be useful, but WITHOUT
10   * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11   * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
12   * details.
13   */
14  
15  package com.liferay.portlet.messageboards.action;
16  
17  import com.liferay.documentlibrary.FileNameException;
18  import com.liferay.documentlibrary.FileSizeException;
19  import com.liferay.portal.kernel.captcha.CaptchaTextException;
20  import com.liferay.portal.kernel.captcha.CaptchaUtil;
21  import com.liferay.portal.kernel.servlet.SessionErrors;
22  import com.liferay.portal.kernel.upload.UploadPortletRequest;
23  import com.liferay.portal.kernel.util.Constants;
24  import com.liferay.portal.kernel.util.FileUtil;
25  import com.liferay.portal.kernel.util.ObjectValuePair;
26  import com.liferay.portal.kernel.util.ParamUtil;
27  import com.liferay.portal.kernel.util.Validator;
28  import com.liferay.portal.kernel.workflow.WorkflowConstants;
29  import com.liferay.portal.security.auth.PrincipalException;
30  import com.liferay.portal.service.ServiceContext;
31  import com.liferay.portal.service.ServiceContextFactory;
32  import com.liferay.portal.struts.PortletAction;
33  import com.liferay.portal.theme.ThemeDisplay;
34  import com.liferay.portal.util.PortalUtil;
35  import com.liferay.portal.util.PropsValues;
36  import com.liferay.portal.util.WebKeys;
37  import com.liferay.portlet.ActionResponseImpl;
38  import com.liferay.portlet.asset.AssetTagException;
39  import com.liferay.portlet.messageboards.LockedThreadException;
40  import com.liferay.portlet.messageboards.MessageBodyException;
41  import com.liferay.portlet.messageboards.MessageSubjectException;
42  import com.liferay.portlet.messageboards.NoSuchMessageException;
43  import com.liferay.portlet.messageboards.RequiredMessageException;
44  import com.liferay.portlet.messageboards.model.MBMessage;
45  import com.liferay.portlet.messageboards.service.MBMessageFlagLocalServiceUtil;
46  import com.liferay.portlet.messageboards.service.MBMessageServiceUtil;
47  import com.liferay.portlet.messageboards.service.MBThreadServiceUtil;
48  
49  import java.io.File;
50  
51  import java.util.ArrayList;
52  import java.util.List;
53  
54  import javax.portlet.ActionRequest;
55  import javax.portlet.ActionResponse;
56  import javax.portlet.PortletConfig;
57  import javax.portlet.PortletURL;
58  import javax.portlet.RenderRequest;
59  import javax.portlet.RenderResponse;
60  
61  import org.apache.struts.action.ActionForm;
62  import org.apache.struts.action.ActionForward;
63  import org.apache.struts.action.ActionMapping;
64  
65  /**
66   * <a href="EditMessageAction.java.html"><b><i>View Source</i></b></a>
67   *
68   * @author Brian Wing Shun Chan
69   */
70  public class EditMessageAction extends PortletAction {
71  
72      public void processAction(
73              ActionMapping mapping, ActionForm form, PortletConfig portletConfig,
74              ActionRequest actionRequest, ActionResponse actionResponse)
75          throws Exception {
76  
77          String cmd = ParamUtil.getString(actionRequest, Constants.CMD);
78  
79          try {
80              MBMessage message = null;
81  
82              if (cmd.equals(Constants.ADD) || cmd.equals(Constants.UPDATE)) {
83                  message = updateMessage(actionRequest, actionResponse);
84              }
85              else if (cmd.equals(Constants.DELETE)) {
86                  deleteMessage(actionRequest);
87              }
88              else if (cmd.equals(Constants.LOCK)) {
89                  lockThread(actionRequest);
90              }
91              else if (cmd.equals(Constants.SUBSCRIBE)) {
92                  subscribeMessage(actionRequest);
93              }
94              else if (cmd.equals(Constants.UNLOCK)) {
95                  unlockThread(actionRequest);
96              }
97              else if (cmd.equals(Constants.UNSUBSCRIBE)) {
98                  unsubscribeMessage(actionRequest);
99              }
100 
101             if (Validator.isNotNull(cmd)) {
102                 String redirect = ParamUtil.getString(
103                     actionRequest, "redirect");
104 
105                 int workflowAction = ParamUtil.getInteger(
106                     actionRequest, "workflowAction",
107                     WorkflowConstants.ACTION_PUBLISH);
108 
109                 if ((message != null) &&
110                     (workflowAction == WorkflowConstants.ACTION_SAVE_DRAFT)) {
111 
112                     redirect = getSaveAndContinueRedirect(
113                         actionRequest, actionResponse, message);
114                 }
115 
116                 sendRedirect(actionRequest, actionResponse, redirect);
117             }
118         }
119         catch (Exception e) {
120             if (e instanceof NoSuchMessageException ||
121                 e instanceof PrincipalException ||
122                 e instanceof RequiredMessageException) {
123 
124                 SessionErrors.add(actionRequest, e.getClass().getName());
125 
126                 setForward(actionRequest, "portlet.message_boards.error");
127             }
128             else if (e instanceof CaptchaTextException ||
129                      e instanceof FileNameException ||
130                      e instanceof FileSizeException ||
131                      e instanceof LockedThreadException ||
132                      e instanceof MessageBodyException ||
133                      e instanceof MessageSubjectException) {
134 
135                 SessionErrors.add(actionRequest, e.getClass().getName());
136             }
137             else if (e instanceof AssetTagException) {
138                 SessionErrors.add(actionRequest, e.getClass().getName(), e);
139             }
140             else {
141                 throw e;
142             }
143         }
144     }
145 
146     public ActionForward render(
147             ActionMapping mapping, ActionForm form, PortletConfig portletConfig,
148             RenderRequest renderRequest, RenderResponse renderResponse)
149         throws Exception {
150 
151         try {
152             ActionUtil.getMessage(renderRequest);
153         }
154         catch (Exception e) {
155             if (e instanceof NoSuchMessageException ||
156                 e instanceof PrincipalException) {
157 
158                 SessionErrors.add(renderRequest, e.getClass().getName());
159 
160                 return mapping.findForward("portlet.message_boards.error");
161             }
162             else {
163                 throw e;
164             }
165         }
166 
167         return mapping.findForward(
168             getForward(renderRequest, "portlet.message_boards.edit_message"));
169     }
170 
171     protected void deleteMessage(ActionRequest actionRequest) throws Exception {
172         long messageId = ParamUtil.getLong(actionRequest, "messageId");
173 
174         MBMessageServiceUtil.deleteMessage(messageId);
175     }
176 
177     protected String getSaveAndContinueRedirect(
178         ActionRequest actionRequest, ActionResponse actionResponse,
179         MBMessage message) {
180 
181         boolean preview = ParamUtil.getBoolean(actionRequest, "preview");
182 
183         PortletURL portletURL =
184             ((ActionResponseImpl)actionResponse).createRenderURL();
185 
186         portletURL.setParameter(
187             "struts_action", "/message_boards/edit_message");
188         portletURL.setParameter(
189             "messageId", String.valueOf(message.getMessageId()));
190         portletURL.setParameter("preview", String.valueOf(preview));
191 
192         return portletURL.toString();
193     }
194 
195     protected void lockThread(ActionRequest actionRequest) throws Exception {
196         long threadId = ParamUtil.getLong(actionRequest, "threadId");
197 
198         MBThreadServiceUtil.lockThread(threadId);
199     }
200 
201     protected void subscribeMessage(ActionRequest actionRequest)
202         throws Exception {
203 
204         long messageId = ParamUtil.getLong(actionRequest, "messageId");
205 
206         MBMessageServiceUtil.subscribeMessage(messageId);
207     }
208 
209     protected void unlockThread(ActionRequest actionRequest) throws Exception {
210         long threadId = ParamUtil.getLong(actionRequest, "threadId");
211 
212         MBThreadServiceUtil.unlockThread(threadId);
213     }
214 
215     protected void unsubscribeMessage(ActionRequest actionRequest)
216         throws Exception {
217 
218         long messageId = ParamUtil.getLong(actionRequest, "messageId");
219 
220         MBMessageServiceUtil.unsubscribeMessage(messageId);
221     }
222 
223     protected MBMessage updateMessage(
224             ActionRequest actionRequest, ActionResponse actionResponse)
225         throws Exception {
226 
227         ThemeDisplay themeDisplay = (ThemeDisplay)actionRequest.getAttribute(
228             WebKeys.THEME_DISPLAY);
229 
230         long messageId = ParamUtil.getLong(actionRequest, "messageId");
231 
232         long groupId = themeDisplay.getScopeGroupId();
233         long categoryId = ParamUtil.getLong(actionRequest, "mbCategoryId");
234         long threadId = ParamUtil.getLong(actionRequest, "threadId");
235         long parentMessageId = ParamUtil.getLong(
236             actionRequest, "parentMessageId");
237         String subject = ParamUtil.getString(actionRequest, "subject");
238         String body = ParamUtil.getString(actionRequest, "body");
239         boolean attachments = ParamUtil.getBoolean(
240             actionRequest, "attachments");
241 
242         List<ObjectValuePair<String, byte[]>> files =
243             new ArrayList<ObjectValuePair<String, byte[]>>();
244 
245         if (attachments) {
246             UploadPortletRequest uploadRequest =
247                 PortalUtil.getUploadPortletRequest(actionRequest);
248 
249             for (int i = 1; i <= 5; i++) {
250                 File file = uploadRequest.getFile("msgFile" + i);
251                 String fileName = uploadRequest.getFileName("msgFile" + i);
252                 byte[] bytes = FileUtil.getBytes(file);
253 
254                 if ((bytes != null) && (bytes.length > 0)) {
255                     ObjectValuePair<String, byte[]> ovp =
256                         new ObjectValuePair<String, byte[]>(fileName, bytes);
257 
258                     files.add(ovp);
259                 }
260             }
261         }
262 
263         boolean question = ParamUtil.getBoolean(actionRequest, "question");
264         boolean anonymous = ParamUtil.getBoolean(actionRequest, "anonymous");
265         double priority = ParamUtil.getDouble(actionRequest, "priority");
266         boolean allowPingbacks = ParamUtil.getBoolean(
267             actionRequest, "allowPingbacks");
268 
269         ServiceContext serviceContext = ServiceContextFactory.getInstance(
270             MBMessage.class.getName(), actionRequest);
271 
272         MBMessage message = null;
273 
274         if (messageId <= 0) {
275             if (PropsValues.CAPTCHA_CHECK_PORTLET_MESSAGE_BOARDS_EDIT_MESSAGE) {
276                 CaptchaUtil.check(actionRequest);
277             }
278 
279             if (threadId <= 0) {
280 
281                 // Post new thread
282 
283                 message = MBMessageServiceUtil.addMessage(
284                     groupId, categoryId, subject, body, files, anonymous,
285                     priority, allowPingbacks, serviceContext);
286 
287                 if (question) {
288                     MBMessageFlagLocalServiceUtil.addQuestionFlag(
289                         message.getMessageId());
290                 }
291             }
292             else {
293 
294                 // Post reply
295 
296                 message = MBMessageServiceUtil.addMessage(
297                     groupId, categoryId, threadId, parentMessageId, subject,
298                     body, files, anonymous, priority, allowPingbacks,
299                     serviceContext);
300             }
301         }
302         else {
303             List<String> existingFiles = new ArrayList<String>();
304 
305             for (int i = 1; i <= 5; i++) {
306                 String path = ParamUtil.getString(
307                     actionRequest, "existingPath" + i);
308 
309                 if (Validator.isNotNull(path)) {
310                     existingFiles.add(path);
311                 }
312             }
313 
314             // Update message
315 
316             message = MBMessageServiceUtil.updateMessage(
317                 messageId, subject, body, files, existingFiles, priority,
318                 allowPingbacks, serviceContext);
319 
320             if (message.isRoot()) {
321                 if (question) {
322                     MBMessageFlagLocalServiceUtil.addQuestionFlag(messageId);
323                 }
324                 else {
325                     MBMessageFlagLocalServiceUtil.deleteQuestionAndAnswerFlags(
326                         message.getThreadId());
327                 }
328             }
329         }
330 
331         return message;
332     }
333 
334 }