001
014
015 package com.liferay.portlet.messageboards.action;
016
017 import com.liferay.portal.kernel.captcha.CaptchaConfigurationException;
018 import com.liferay.portal.kernel.captcha.CaptchaMaxChallengesException;
019 import com.liferay.portal.kernel.captcha.CaptchaTextException;
020 import com.liferay.portal.kernel.captcha.CaptchaUtil;
021 import com.liferay.portal.kernel.exception.PortalException;
022 import com.liferay.portal.kernel.portlet.LiferayWindowState;
023 import com.liferay.portal.kernel.sanitizer.SanitizerException;
024 import com.liferay.portal.kernel.servlet.SessionErrors;
025 import com.liferay.portal.kernel.upload.LiferayFileItemException;
026 import com.liferay.portal.kernel.upload.UploadException;
027 import com.liferay.portal.kernel.upload.UploadPortletRequest;
028 import com.liferay.portal.kernel.util.Constants;
029 import com.liferay.portal.kernel.util.ObjectValuePair;
030 import com.liferay.portal.kernel.util.ParamUtil;
031 import com.liferay.portal.kernel.util.StreamUtil;
032 import com.liferay.portal.kernel.util.StringUtil;
033 import com.liferay.portal.kernel.util.Validator;
034 import com.liferay.portal.kernel.workflow.WorkflowConstants;
035 import com.liferay.portal.security.auth.PrincipalException;
036 import com.liferay.portal.security.permission.ActionKeys;
037 import com.liferay.portal.security.permission.PermissionChecker;
038 import com.liferay.portal.service.ServiceContext;
039 import com.liferay.portal.service.ServiceContextFactory;
040 import com.liferay.portal.struts.PortletAction;
041 import com.liferay.portal.theme.ThemeDisplay;
042 import com.liferay.portal.util.PortalUtil;
043 import com.liferay.portal.util.PropsValues;
044 import com.liferay.portal.util.WebKeys;
045 import com.liferay.portlet.ActionResponseImpl;
046 import com.liferay.portlet.asset.AssetCategoryException;
047 import com.liferay.portlet.asset.AssetTagException;
048 import com.liferay.portlet.documentlibrary.DuplicateFileException;
049 import com.liferay.portlet.documentlibrary.FileExtensionException;
050 import com.liferay.portlet.documentlibrary.FileNameException;
051 import com.liferay.portlet.documentlibrary.FileSizeException;
052 import com.liferay.portlet.documentlibrary.antivirus.AntivirusScannerException;
053 import com.liferay.portlet.messageboards.LockedThreadException;
054 import com.liferay.portlet.messageboards.MBGroupServiceSettings;
055 import com.liferay.portlet.messageboards.MessageBodyException;
056 import com.liferay.portlet.messageboards.MessageSubjectException;
057 import com.liferay.portlet.messageboards.NoSuchMessageException;
058 import com.liferay.portlet.messageboards.RequiredMessageException;
059 import com.liferay.portlet.messageboards.model.MBMessage;
060 import com.liferay.portlet.messageboards.service.MBMessageServiceUtil;
061 import com.liferay.portlet.messageboards.service.MBThreadLocalServiceUtil;
062 import com.liferay.portlet.messageboards.service.MBThreadServiceUtil;
063 import com.liferay.portlet.messageboards.service.permission.MBMessagePermission;
064
065 import java.io.InputStream;
066
067 import java.util.ArrayList;
068 import java.util.List;
069
070 import javax.portlet.ActionRequest;
071 import javax.portlet.ActionResponse;
072 import javax.portlet.PortletConfig;
073 import javax.portlet.PortletURL;
074 import javax.portlet.RenderRequest;
075 import javax.portlet.RenderResponse;
076 import javax.portlet.WindowState;
077
078 import org.apache.struts.action.ActionForm;
079 import org.apache.struts.action.ActionForward;
080 import org.apache.struts.action.ActionMapping;
081
082
087 public class EditMessageAction extends PortletAction {
088
089 @Override
090 public void processAction(
091 ActionMapping actionMapping, ActionForm actionForm,
092 PortletConfig portletConfig, ActionRequest actionRequest,
093 ActionResponse actionResponse)
094 throws Exception {
095
096 String cmd = ParamUtil.getString(actionRequest, Constants.CMD);
097
098 MBMessage message = null;
099
100 try {
101 UploadException uploadException =
102 (UploadException)actionRequest.getAttribute(
103 WebKeys.UPLOAD_EXCEPTION);
104
105 if (uploadException != null) {
106 if (uploadException.isExceededLiferayFileItemSizeLimit()) {
107 throw new LiferayFileItemException();
108 }
109 else if (uploadException.isExceededSizeLimit()) {
110 throw new FileSizeException(uploadException.getCause());
111 }
112
113 throw new PortalException(uploadException.getCause());
114 }
115 else if (cmd.equals(Constants.ADD) ||
116 cmd.equals(Constants.UPDATE)) {
117
118 message = updateMessage(actionRequest, actionResponse);
119 }
120 else if (cmd.equals(Constants.DELETE)) {
121 deleteMessage(actionRequest);
122 }
123 else if (cmd.equals(Constants.LOCK)) {
124 lockThreads(actionRequest);
125 }
126 else if (cmd.equals(Constants.SUBSCRIBE)) {
127 subscribeMessage(actionRequest);
128 }
129 else if (cmd.equals(Constants.UNLOCK)) {
130 unlockThreads(actionRequest);
131 }
132 else if (cmd.equals(Constants.UNSUBSCRIBE)) {
133 unsubscribeMessage(actionRequest);
134 }
135
136 if (Validator.isNotNull(cmd)) {
137 WindowState windowState = actionRequest.getWindowState();
138
139 if (!windowState.equals(LiferayWindowState.POP_UP)) {
140 String redirect = getRedirect(
141 actionRequest, actionResponse, message);
142
143 sendRedirect(actionRequest, actionResponse, redirect);
144 }
145 else {
146 String redirect = PortalUtil.escapeRedirect(
147 ParamUtil.getString(actionRequest, "redirect"));
148
149 if (Validator.isNotNull(redirect)) {
150 actionResponse.sendRedirect(redirect);
151 }
152 }
153 }
154 }
155 catch (Exception e) {
156 if (e instanceof NoSuchMessageException ||
157 e instanceof PrincipalException ||
158 e instanceof RequiredMessageException) {
159
160 SessionErrors.add(actionRequest, e.getClass());
161
162 setForward(actionRequest, "portlet.message_boards.error");
163 }
164 else if (e instanceof AntivirusScannerException ||
165 e instanceof CaptchaConfigurationException ||
166 e instanceof CaptchaMaxChallengesException ||
167 e instanceof CaptchaTextException ||
168 e instanceof DuplicateFileException ||
169 e instanceof FileExtensionException ||
170 e instanceof FileNameException ||
171 e instanceof FileSizeException ||
172 e instanceof LiferayFileItemException ||
173 e instanceof LockedThreadException ||
174 e instanceof MessageBodyException ||
175 e instanceof MessageSubjectException ||
176 e instanceof SanitizerException) {
177
178 UploadException uploadException =
179 (UploadException)actionRequest.getAttribute(
180 WebKeys.UPLOAD_EXCEPTION);
181
182 if (uploadException != null) {
183 String uploadExceptionRedirect = ParamUtil.getString(
184 actionRequest, "uploadExceptionRedirect");
185
186 actionResponse.sendRedirect(uploadExceptionRedirect);
187 }
188
189 if (e instanceof AntivirusScannerException) {
190 SessionErrors.add(actionRequest, e.getClass(), e);
191 }
192 else {
193 SessionErrors.add(actionRequest, e.getClass());
194 }
195 }
196 else if (e instanceof AssetCategoryException ||
197 e instanceof AssetTagException) {
198
199 SessionErrors.add(actionRequest, e.getClass(), e);
200 }
201 else {
202 Throwable cause = e.getCause();
203
204 if (cause instanceof SanitizerException) {
205 SessionErrors.add(actionRequest, SanitizerException.class);
206 }
207 else {
208 throw e;
209 }
210 }
211 }
212 }
213
214 @Override
215 public ActionForward render(
216 ActionMapping actionMapping, ActionForm actionForm,
217 PortletConfig portletConfig, RenderRequest renderRequest,
218 RenderResponse renderResponse)
219 throws Exception {
220
221 try {
222 ActionUtil.getMessage(renderRequest);
223 }
224 catch (Exception e) {
225 if (e instanceof NoSuchMessageException ||
226 e instanceof PrincipalException) {
227
228 SessionErrors.add(renderRequest, e.getClass());
229
230 return actionMapping.findForward(
231 "portlet.message_boards.error");
232 }
233 else {
234 throw e;
235 }
236 }
237
238 return actionMapping.findForward(
239 getForward(renderRequest, "portlet.message_boards.edit_message"));
240 }
241
242 protected void deleteMessage(ActionRequest actionRequest) throws Exception {
243 long messageId = ParamUtil.getLong(actionRequest, "messageId");
244
245 MBMessageServiceUtil.deleteMessage(messageId);
246 }
247
248 protected String getRedirect(
249 ActionRequest actionRequest, ActionResponse actionResponse,
250 MBMessage message) {
251
252 if (message == null) {
253 String redirect = ParamUtil.getString(actionRequest, "redirect");
254
255 return redirect;
256 }
257
258 int workflowAction = ParamUtil.getInteger(
259 actionRequest, "workflowAction", WorkflowConstants.ACTION_PUBLISH);
260
261 if (workflowAction == WorkflowConstants.ACTION_SAVE_DRAFT) {
262 return getSaveAndContinueRedirect(
263 actionRequest, actionResponse, message);
264 }
265 else if (message == null) {
266 return ParamUtil.getString(actionRequest, "redirect");
267 }
268
269 ActionResponseImpl actionResponseImpl =
270 (ActionResponseImpl)actionResponse;
271
272 PortletURL portletURL = actionResponseImpl.createRenderURL();
273
274 portletURL.setParameter(
275 "struts_action", "/message_boards/view_message");
276 portletURL.setParameter(
277 "messageId", String.valueOf(message.getMessageId()));
278
279 return portletURL.toString();
280 }
281
282 protected String getSaveAndContinueRedirect(
283 ActionRequest actionRequest, ActionResponse actionResponse,
284 MBMessage message) {
285
286 String redirect = ParamUtil.getString(actionRequest, "redirect");
287
288 boolean preview = ParamUtil.getBoolean(actionRequest, "preview");
289
290 PortletURL portletURL =
291 ((ActionResponseImpl)actionResponse).createRenderURL();
292
293 portletURL.setParameter(
294 "struts_action", "/message_boards/edit_message");
295 portletURL.setParameter("redirect", redirect);
296 portletURL.setParameter(
297 "messageId", String.valueOf(message.getMessageId()));
298 portletURL.setParameter("preview", String.valueOf(preview));
299
300 return portletURL.toString();
301 }
302
303 protected void lockThreads(ActionRequest actionRequest) throws Exception {
304 long threadId = ParamUtil.getLong(actionRequest, "threadId");
305
306 if (threadId > 0) {
307 MBThreadServiceUtil.lockThread(threadId);
308 }
309 else {
310 long[] threadIds = StringUtil.split(
311 ParamUtil.getString(actionRequest, "threadIds"), 0L);
312
313 for (int i = 0; i < threadIds.length; i++) {
314 MBThreadServiceUtil.lockThread(threadIds[i]);
315 }
316 }
317 }
318
319 protected void subscribeMessage(ActionRequest actionRequest)
320 throws Exception {
321
322 long messageId = ParamUtil.getLong(actionRequest, "messageId");
323
324 MBMessageServiceUtil.subscribeMessage(messageId);
325 }
326
327 protected void unlockThreads(ActionRequest actionRequest) throws Exception {
328 long threadId = ParamUtil.getLong(actionRequest, "threadId");
329
330 if (threadId > 0) {
331 MBThreadServiceUtil.unlockThread(threadId);
332 }
333 else {
334 long[] threadIds = StringUtil.split(
335 ParamUtil.getString(actionRequest, "threadIds"), 0L);
336
337 for (int i = 0; i < threadIds.length; i++) {
338 MBThreadServiceUtil.unlockThread(threadIds[i]);
339 }
340 }
341 }
342
343 protected void unsubscribeMessage(ActionRequest actionRequest)
344 throws Exception {
345
346 long messageId = ParamUtil.getLong(actionRequest, "messageId");
347
348 MBMessageServiceUtil.unsubscribeMessage(messageId);
349 }
350
351 protected MBMessage updateMessage(
352 ActionRequest actionRequest, ActionResponse actionResponse)
353 throws Exception {
354
355 ThemeDisplay themeDisplay = (ThemeDisplay)actionRequest.getAttribute(
356 WebKeys.THEME_DISPLAY);
357
358 long messageId = ParamUtil.getLong(actionRequest, "messageId");
359
360 long groupId = themeDisplay.getScopeGroupId();
361 long categoryId = ParamUtil.getLong(actionRequest, "mbCategoryId");
362 long threadId = ParamUtil.getLong(actionRequest, "threadId");
363 long parentMessageId = ParamUtil.getLong(
364 actionRequest, "parentMessageId");
365 String subject = ParamUtil.getString(actionRequest, "subject");
366 String body = ParamUtil.getString(actionRequest, "body");
367
368 MBGroupServiceSettings mbGroupServiceSettings =
369 MBGroupServiceSettings.getInstance(groupId);
370
371 List<ObjectValuePair<String, InputStream>> inputStreamOVPs =
372 new ArrayList<>(5);
373
374 try {
375 UploadPortletRequest uploadPortletRequest =
376 PortalUtil.getUploadPortletRequest(actionRequest);
377
378 for (int i = 1; i <= 5; i++) {
379 String fileName = uploadPortletRequest.getFileName(
380 "msgFile" + i);
381 InputStream inputStream = uploadPortletRequest.getFileAsStream(
382 "msgFile" + i);
383
384 if ((inputStream == null) || Validator.isNull(fileName)) {
385 continue;
386 }
387
388 ObjectValuePair<String, InputStream> inputStreamOVP =
389 new ObjectValuePair<>(fileName, inputStream);
390
391 inputStreamOVPs.add(inputStreamOVP);
392 }
393
394 boolean question = ParamUtil.getBoolean(actionRequest, "question");
395 boolean anonymous = ParamUtil.getBoolean(
396 actionRequest, "anonymous");
397 double priority = ParamUtil.getDouble(actionRequest, "priority");
398 boolean allowPingbacks = ParamUtil.getBoolean(
399 actionRequest, "allowPingbacks");
400
401 ServiceContext serviceContext = ServiceContextFactory.getInstance(
402 MBMessage.class.getName(), actionRequest);
403
404 boolean preview = ParamUtil.getBoolean(actionRequest, "preview");
405
406 serviceContext.setAttribute("preview", preview);
407
408 MBMessage message = null;
409
410 if (messageId <= 0) {
411 if (PropsValues.
412 CAPTCHA_CHECK_PORTLET_MESSAGE_BOARDS_EDIT_MESSAGE) {
413
414 CaptchaUtil.check(actionRequest);
415 }
416
417 if (threadId <= 0) {
418
419
420
421 message = MBMessageServiceUtil.addMessage(
422 groupId, categoryId, subject, body,
423 mbGroupServiceSettings.getMessageFormat(),
424 inputStreamOVPs, anonymous, priority, allowPingbacks,
425 serviceContext);
426
427 if (question) {
428 MBThreadLocalServiceUtil.updateQuestion(
429 message.getThreadId(), true);
430 }
431 }
432 else {
433
434
435
436 message = MBMessageServiceUtil.addMessage(
437 parentMessageId, subject, body,
438 mbGroupServiceSettings.getMessageFormat(),
439 inputStreamOVPs, anonymous, priority, allowPingbacks,
440 serviceContext);
441 }
442 }
443 else {
444 List<String> existingFiles = new ArrayList<>();
445
446 for (int i = 1; i <= 5; i++) {
447 String path = ParamUtil.getString(
448 actionRequest, "existingPath" + i);
449
450 if (Validator.isNotNull(path)) {
451 existingFiles.add(path);
452 }
453 }
454
455
456
457 message = MBMessageServiceUtil.updateMessage(
458 messageId, subject, body, inputStreamOVPs, existingFiles,
459 priority, allowPingbacks, serviceContext);
460
461 if (message.isRoot()) {
462 MBThreadLocalServiceUtil.updateQuestion(
463 message.getThreadId(), question);
464 }
465 }
466
467 PermissionChecker permissionChecker =
468 themeDisplay.getPermissionChecker();
469
470 boolean subscribe = ParamUtil.getBoolean(
471 actionRequest, "subscribe");
472
473 if (!preview && subscribe &&
474 MBMessagePermission.contains(
475 permissionChecker, message, ActionKeys.SUBSCRIBE)) {
476
477 MBMessageServiceUtil.subscribeMessage(message.getMessageId());
478 }
479
480 return message;
481 }
482 finally {
483 for (ObjectValuePair<String, InputStream> inputStreamOVP :
484 inputStreamOVPs) {
485
486 InputStream inputStream = inputStreamOVP.getValue();
487
488 StreamUtil.cleanUp(inputStream);
489 }
490 }
491 }
492
493 }