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