1
14
15 package com.liferay.portlet.journal.action;
16
17 import com.liferay.portal.kernel.servlet.SessionErrors;
18 import com.liferay.portal.kernel.upload.UploadPortletRequest;
19 import com.liferay.portal.kernel.util.Constants;
20 import com.liferay.portal.kernel.util.FileUtil;
21 import com.liferay.portal.kernel.util.GetterUtil;
22 import com.liferay.portal.kernel.util.ParamUtil;
23 import com.liferay.portal.kernel.util.StringPool;
24 import com.liferay.portal.kernel.util.StringUtil;
25 import com.liferay.portal.kernel.util.Validator;
26 import com.liferay.portal.kernel.workflow.StatusConstants;
27 import com.liferay.portal.model.Layout;
28 import com.liferay.portal.security.auth.PrincipalException;
29 import com.liferay.portal.security.permission.ActionKeys;
30 import com.liferay.portal.security.permission.PermissionChecker;
31 import com.liferay.portal.service.ServiceContext;
32 import com.liferay.portal.service.ServiceContextFactory;
33 import com.liferay.portal.service.SubscriptionLocalServiceUtil;
34 import com.liferay.portal.struts.PortletAction;
35 import com.liferay.portal.theme.ThemeDisplay;
36 import com.liferay.portal.util.PortalUtil;
37 import com.liferay.portal.util.PortletKeys;
38 import com.liferay.portal.util.WebKeys;
39 import com.liferay.portlet.ActionRequestImpl;
40 import com.liferay.portlet.PortletPreferencesFactoryUtil;
41 import com.liferay.portlet.PortletURLImpl;
42 import com.liferay.portlet.asset.AssetTagException;
43 import com.liferay.portlet.assetpublisher.util.AssetPublisherUtil;
44 import com.liferay.portlet.journal.ArticleContentException;
45 import com.liferay.portlet.journal.ArticleDisplayDateException;
46 import com.liferay.portlet.journal.ArticleExpirationDateException;
47 import com.liferay.portlet.journal.ArticleIdException;
48 import com.liferay.portlet.journal.ArticleSmallImageNameException;
49 import com.liferay.portlet.journal.ArticleSmallImageSizeException;
50 import com.liferay.portlet.journal.ArticleTitleException;
51 import com.liferay.portlet.journal.ArticleTypeException;
52 import com.liferay.portlet.journal.DuplicateArticleIdException;
53 import com.liferay.portlet.journal.NoSuchArticleException;
54 import com.liferay.portlet.journal.NoSuchStructureException;
55 import com.liferay.portlet.journal.NoSuchTemplateException;
56 import com.liferay.portlet.journal.model.JournalArticle;
57 import com.liferay.portlet.journal.model.JournalStructure;
58 import com.liferay.portlet.journal.service.JournalArticleServiceUtil;
59 import com.liferay.portlet.journal.service.JournalContentSearchLocalServiceUtil;
60 import com.liferay.portlet.journal.service.JournalStructureLocalServiceUtil;
61 import com.liferay.portlet.journal.service.permission.JournalPermission;
62 import com.liferay.portlet.journal.util.JournalUtil;
63 import com.liferay.util.LocalizationUtil;
64
65 import java.io.File;
66
67 import java.util.Calendar;
68 import java.util.Enumeration;
69 import java.util.HashMap;
70 import java.util.Map;
71
72 import javax.portlet.ActionRequest;
73 import javax.portlet.ActionResponse;
74 import javax.portlet.PortletConfig;
75 import javax.portlet.PortletPreferences;
76 import javax.portlet.PortletRequest;
77 import javax.portlet.RenderRequest;
78 import javax.portlet.RenderResponse;
79 import javax.portlet.WindowState;
80
81 import org.apache.struts.action.ActionForm;
82 import org.apache.struts.action.ActionForward;
83 import org.apache.struts.action.ActionMapping;
84
85
91 public class EditArticleAction extends PortletAction {
92
93 public static final String VERSION_SEPARATOR = "_version_";
94
95 public void processAction(
96 ActionMapping mapping, ActionForm form, PortletConfig portletConfig,
97 ActionRequest actionRequest, ActionResponse actionResponse)
98 throws Exception {
99
100 String cmd = ParamUtil.getString(actionRequest, Constants.CMD);
101
102 JournalArticle article = null;
103
104 try {
105 if (cmd.equals(Constants.ADD) || cmd.equals(Constants.UPDATE)) {
106 article = updateArticle(actionRequest);
107 }
108 else if (cmd.equals(Constants.APPROVE)) {
109 approveArticle(actionRequest);
110 }
111 else if (cmd.equals(Constants.DELETE)) {
112 deleteArticles(actionRequest);
113 }
114 else if (cmd.equals(Constants.EXPIRE)) {
115 expireArticles(actionRequest);
116 }
117 else if (cmd.equals(Constants.SUBSCRIBE)) {
118 subscribeArticles(actionRequest);
119 }
120 else if (cmd.equals(Constants.UNSUBSCRIBE)) {
121 unsubscribeArticles(actionRequest);
122 }
123 else if (cmd.equals("removeArticlesLocale")) {
124 removeArticlesLocale(actionRequest);
125 }
126
127 if (Validator.isNotNull(cmd)) {
128 String redirect = ParamUtil.getString(
129 actionRequest, "redirect");
130
131 if (article != null) {
132 boolean saveAndContinue = ParamUtil.getBoolean(
133 actionRequest, "saveAndContinue");
134
135 if (saveAndContinue) {
136 redirect = getSaveAndContinueRedirect(
137 portletConfig, actionRequest, article, redirect);
138 }
139 }
140
141 String referringPortletResource = ParamUtil.getString(
142 actionRequest, "referringPortletResource");
143
144 if (referringPortletResource.equals(
145 PortletKeys.JOURNAL_CONTENT)) {
146
147 actionResponse.sendRedirect(redirect);
148 }
149 else {
150 sendRedirect(actionRequest, actionResponse, redirect);
151 }
152 }
153 }
154 catch (Exception e) {
155 if (e instanceof NoSuchArticleException ||
156 e instanceof NoSuchStructureException ||
157 e instanceof NoSuchTemplateException ||
158 e instanceof PrincipalException) {
159
160 SessionErrors.add(actionRequest, e.getClass().getName());
161
162 setForward(actionRequest, "portlet.journal.error");
163 }
164 else if (e instanceof ArticleContentException ||
165 e instanceof ArticleDisplayDateException ||
166 e instanceof ArticleExpirationDateException ||
167 e instanceof ArticleIdException ||
168 e instanceof ArticleSmallImageNameException ||
169 e instanceof ArticleSmallImageSizeException ||
170 e instanceof ArticleTitleException ||
171 e instanceof ArticleTypeException ||
172 e instanceof DuplicateArticleIdException) {
173
174 SessionErrors.add(actionRequest, e.getClass().getName());
175 }
176 else if (e instanceof AssetTagException) {
177 SessionErrors.add(actionRequest, e.getClass().getName(), e);
178 }
179 else {
180 throw e;
181 }
182 }
183 }
184
185 public ActionForward render(
186 ActionMapping mapping, ActionForm form, PortletConfig portletConfig,
187 RenderRequest renderRequest, RenderResponse renderResponse)
188 throws Exception {
189
190 try {
191 String cmd = ParamUtil.getString(renderRequest, Constants.CMD);
192
193 if (!cmd.equals(Constants.ADD)) {
194 ActionUtil.getArticle(renderRequest);
195 }
196 }
197 catch (NoSuchArticleException nsse) {
198
199
202 }
203 catch (Exception e) {
204 if ( e instanceof PrincipalException) {
206
207 SessionErrors.add(renderRequest, e.getClass().getName());
208
209 return mapping.findForward("portlet.journal.error");
210 }
211 else {
212 throw e;
213 }
214 }
215
216 return mapping.findForward(
217 getForward(renderRequest, "portlet.journal.edit_article"));
218 }
219
220 protected void approveArticle(ActionRequest actionRequest)
221 throws Exception {
222
223 long groupId = ParamUtil.getLong(actionRequest, "groupId");
224 String articleId = ParamUtil.getString(actionRequest, "articleId");
225 double version = ParamUtil.getDouble(actionRequest, "version");
226
227 String articleURL = ParamUtil.getString(actionRequest, "articleURL");
228
229 ServiceContext serviceContext = ServiceContextFactory.getInstance(
230 JournalArticle.class.getName(), actionRequest);
231
232 JournalArticleServiceUtil.updateStatus(
233 groupId, articleId, version, StatusConstants.APPROVED, articleURL,
234 serviceContext);
235 }
236
237 protected void deleteArticles(ActionRequest actionRequest)
238 throws Exception {
239
240 long groupId = ParamUtil.getLong(actionRequest, "groupId");
241
242 String[] deleteArticleIds = StringUtil.split(
243 ParamUtil.getString(actionRequest, "deleteArticleIds"));
244
245 ServiceContext serviceContext = ServiceContextFactory.getInstance(
246 JournalArticle.class.getName(), actionRequest);
247
248 for (int i = 0; i < deleteArticleIds.length; i++) {
249 int pos = deleteArticleIds[i].lastIndexOf(VERSION_SEPARATOR);
250
251 String articleId = deleteArticleIds[i].substring(0, pos);
252 double version = GetterUtil.getDouble(
253 deleteArticleIds[i].substring(
254 pos + VERSION_SEPARATOR.length()));
255
256 String articleURL = ParamUtil.getString(
257 actionRequest, "articleURL");
258
259 JournalArticleServiceUtil.deleteArticle(
260 groupId, articleId, version, articleURL, serviceContext);
261
262 JournalUtil.removeRecentArticle(actionRequest, deleteArticleIds[i]);
263 }
264 }
265
266 protected void expireArticles(ActionRequest actionRequest)
267 throws Exception {
268
269 long groupId = ParamUtil.getLong(actionRequest, "groupId");
270
271 String[] expireArticleIds = StringUtil.split(
272 ParamUtil.getString(actionRequest, "expireArticleIds"));
273
274 ServiceContext serviceContext = ServiceContextFactory.getInstance(
275 JournalArticle.class.getName(), actionRequest);
276
277 for (int i = 0; i < expireArticleIds.length; i++) {
278 int pos = expireArticleIds[i].lastIndexOf(VERSION_SEPARATOR);
279
280 String articleId = expireArticleIds[i].substring(0, pos);
281 double version = GetterUtil.getDouble(
282 expireArticleIds[i].substring(
283 pos + VERSION_SEPARATOR.length()));
284
285 String articleURL = ParamUtil.getString(
286 actionRequest, "articleURL");
287
288 JournalArticleServiceUtil.updateStatus(
289 groupId, articleId, version, StatusConstants.EXPIRED,
290 articleURL, serviceContext);
291 }
292 }
293
294 protected Map<String, byte[]> getImages(UploadPortletRequest uploadRequest)
295 throws Exception {
296
297 Map<String, byte[]> images = new HashMap<String, byte[]>();
298
299 String imagePrefix = "structure_image_";
300
301 Enumeration<String> enu = uploadRequest.getParameterNames();
302
303 while (enu.hasMoreElements()) {
304 String name = enu.nextElement();
305
306 if (name.startsWith(imagePrefix)) {
307 File file = uploadRequest.getFile(name);
308 byte[] bytes = FileUtil.getBytes(file);
309
310 if ((bytes != null) && (bytes.length > 0)) {
311 name = name.substring(imagePrefix.length(), name.length());
312
313 images.put(name, bytes);
314 }
315 }
316 }
317
318 return images;
319 }
320
321 protected String getSaveAndContinueRedirect(
322 PortletConfig portletConfig, ActionRequest actionRequest,
323 JournalArticle article, String redirect)
324 throws Exception {
325
326 ThemeDisplay themeDisplay = (ThemeDisplay)actionRequest.getAttribute(
327 WebKeys.THEME_DISPLAY);
328
329 String originalRedirect = ParamUtil.getString(
330 actionRequest, "originalRedirect");
331
332 PortletURLImpl portletURL = new PortletURLImpl(
333 (ActionRequestImpl)actionRequest, portletConfig.getPortletName(),
334 themeDisplay.getPlid(), PortletRequest.RENDER_PHASE);
335
336 portletURL.setWindowState(WindowState.MAXIMIZED);
337
338 portletURL.setParameter("struts_action", "/journal/edit_article");
339 portletURL.setParameter(Constants.CMD, Constants.UPDATE, false);
340 portletURL.setParameter("redirect", redirect, false);
341 portletURL.setParameter("originalRedirect", originalRedirect, false);
342 portletURL.setParameter(
343 "groupId", String.valueOf(article.getGroupId()), false);
344 portletURL.setParameter("articleId", article.getArticleId(), false);
345 portletURL.setParameter(
346 "version", String.valueOf(article.getVersion()), false);
347
348 return portletURL.toString();
349 }
350
351 protected void removeArticlesLocale(ActionRequest actionRequest)
352 throws Exception {
353
354 long groupId = ParamUtil.getLong(actionRequest, "groupId");
355
356 String[] removeArticleLocaleIds = StringUtil.split(
357 ParamUtil.getString(actionRequest, "deleteArticleIds"));
358
359 for (int i = 0; i < removeArticleLocaleIds.length; i++) {
360 int pos = removeArticleLocaleIds[i].lastIndexOf(VERSION_SEPARATOR);
361
362 String articleId = removeArticleLocaleIds[i].substring(0, pos);
363 double version = GetterUtil.getDouble(
364 removeArticleLocaleIds[i].substring(
365 pos + VERSION_SEPARATOR.length()));
366 String languageId = ParamUtil.getString(
367 actionRequest, "languageId");
368
369 JournalArticleServiceUtil.removeArticleLocale(
370 groupId, articleId, version, languageId);
371 }
372 }
373
374 protected void subscribeArticles(ActionRequest actionRequest)
375 throws Exception {
376
377 ThemeDisplay themeDisplay = (ThemeDisplay)actionRequest.getAttribute(
378 WebKeys.THEME_DISPLAY);
379
380 PermissionChecker permissionChecker =
381 themeDisplay.getPermissionChecker();
382
383 if (JournalPermission.contains(
384 permissionChecker, themeDisplay.getScopeGroupId(),
385 ActionKeys.SUBSCRIBE)) {
386
387 SubscriptionLocalServiceUtil.addSubscription(
388 themeDisplay.getUserId(), JournalArticle.class.getName(),
389 themeDisplay.getScopeGroupId());
390 }
391 }
392
393 protected void unsubscribeArticles(ActionRequest actionRequest)
394 throws Exception {
395
396 ThemeDisplay themeDisplay = (ThemeDisplay)actionRequest.getAttribute(
397 WebKeys.THEME_DISPLAY);
398
399 PermissionChecker permissionChecker =
400 themeDisplay.getPermissionChecker();
401
402 if (JournalPermission.contains(
403 permissionChecker, themeDisplay.getScopeGroupId(),
404 ActionKeys.SUBSCRIBE)) {
405
406 SubscriptionLocalServiceUtil.deleteSubscription(
407 themeDisplay.getUserId(), JournalArticle.class.getName(),
408 themeDisplay.getScopeGroupId());
409 }
410 }
411
412 protected JournalArticle updateArticle(ActionRequest actionRequest)
413 throws Exception {
414
415 UploadPortletRequest uploadRequest = PortalUtil.getUploadPortletRequest(
416 actionRequest);
417
418 String cmd = ParamUtil.getString(uploadRequest, Constants.CMD);
419
420 long groupId = ParamUtil.getLong(uploadRequest, "groupId");
421
422 String articleId = ParamUtil.getString(uploadRequest, "articleId");
423 boolean autoArticleId = ParamUtil.getBoolean(
424 uploadRequest, "autoArticleId");
425
426 double version = ParamUtil.getDouble(uploadRequest, "version");
427 boolean incrementVersion = ParamUtil.getBoolean(
428 uploadRequest, "incrementVersion");
429
430 String title = ParamUtil.getString(uploadRequest, "title");
431 String description = ParamUtil.getString(uploadRequest, "description");
432 String content = ParamUtil.getString(uploadRequest, "content");
433 String type = ParamUtil.getString(uploadRequest, "type");
434 String structureId = ParamUtil.getString(uploadRequest, "structureId");
435 String templateId = ParamUtil.getString(uploadRequest, "templateId");
436
437 String lastLanguageId = ParamUtil.getString(
438 uploadRequest, "lastLanguageId");
439 String defaultLanguageId = ParamUtil.getString(
440 uploadRequest, "defaultLanguageId");
441
442 int displayDateMonth = ParamUtil.getInteger(
443 uploadRequest, "displayDateMonth");
444 int displayDateDay = ParamUtil.getInteger(
445 uploadRequest, "displayDateDay");
446 int displayDateYear = ParamUtil.getInteger(
447 uploadRequest, "displayDateYear");
448 int displayDateHour = ParamUtil.getInteger(
449 uploadRequest, "displayDateHour");
450 int displayDateMinute = ParamUtil.getInteger(
451 uploadRequest, "displayDateMinute");
452 int displayDateAmPm = ParamUtil.getInteger(
453 uploadRequest, "displayDateAmPm");
454
455 if (displayDateAmPm == Calendar.PM) {
456 displayDateHour += 12;
457 }
458
459 int expirationDateMonth = ParamUtil.getInteger(
460 uploadRequest, "expirationDateMonth");
461 int expirationDateDay = ParamUtil.getInteger(
462 uploadRequest, "expirationDateDay");
463 int expirationDateYear = ParamUtil.getInteger(
464 uploadRequest, "expirationDateYear");
465 int expirationDateHour = ParamUtil.getInteger(
466 uploadRequest, "expirationDateHour");
467 int expirationDateMinute = ParamUtil.getInteger(
468 uploadRequest, "expirationDateMinute");
469 int expirationDateAmPm = ParamUtil.getInteger(
470 uploadRequest, "expirationDateAmPm");
471 boolean neverExpire = ParamUtil.getBoolean(
472 uploadRequest, "neverExpire");
473
474 if (expirationDateAmPm == Calendar.PM) {
475 expirationDateHour += 12;
476 }
477
478 int reviewDateMonth = ParamUtil.getInteger(
479 uploadRequest, "reviewDateMonth");
480 int reviewDateDay = ParamUtil.getInteger(
481 uploadRequest, "reviewDateDay");
482 int reviewDateYear = ParamUtil.getInteger(
483 uploadRequest, "reviewDateYear");
484 int reviewDateHour = ParamUtil.getInteger(
485 uploadRequest, "reviewDateHour");
486 int reviewDateMinute = ParamUtil.getInteger(
487 uploadRequest, "reviewDateMinute");
488 int reviewDateAmPm = ParamUtil.getInteger(
489 uploadRequest, "reviewDateAmPm");
490 boolean neverReview = ParamUtil.getBoolean(
491 uploadRequest, "neverReview");
492
493 if (reviewDateAmPm == Calendar.PM) {
494 reviewDateHour += 12;
495 }
496
497 boolean indexable = ParamUtil.getBoolean(uploadRequest, "indexable");
498
499 boolean smallImage = ParamUtil.getBoolean(uploadRequest, "smallImage");
500 String smallImageURL = ParamUtil.getString(
501 uploadRequest, "smallImageURL");
502 File smallFile = uploadRequest.getFile("smallFile");
503
504 Map<String, byte[]> images = getImages(uploadRequest);
505
506 String articleURL = ParamUtil.getString(uploadRequest, "articleURL");
507
508 ServiceContext serviceContext = ServiceContextFactory.getInstance(
509 JournalArticle.class.getName(), actionRequest);
510
511 JournalArticle article = null;
512
513 if (cmd.equals(Constants.ADD)) {
514 if (Validator.isNull(structureId)) {
515 content = LocalizationUtil.updateLocalization(
516 StringPool.BLANK, "static-content", content,
517 lastLanguageId, defaultLanguageId, true);
518 }
519
520
522 article = JournalArticleServiceUtil.addArticle(
523 groupId, articleId, autoArticleId, title, description,
524 content, type, structureId, templateId, displayDateMonth,
525 displayDateDay, displayDateYear, displayDateHour,
526 displayDateMinute, expirationDateMonth, expirationDateDay,
527 expirationDateYear, expirationDateHour, expirationDateMinute,
528 neverExpire, reviewDateMonth, reviewDateDay, reviewDateYear,
529 reviewDateHour, reviewDateMinute, neverReview, indexable,
530 smallImage, smallImageURL, smallFile, images, articleURL,
531 serviceContext);
532
533 AssetPublisherUtil.addAndStoreSelection(
534 actionRequest, JournalArticle.class.getName(),
535 article.getResourcePrimKey(), -1);
536 }
537 else {
538
539
541 JournalArticle curArticle = JournalArticleServiceUtil.getArticle(
542 groupId, articleId, version);
543
544 if (Validator.isNull(structureId)) {
545 if (!curArticle.isTemplateDriven()) {
546 content = LocalizationUtil.updateLocalization(
547 curArticle.getContent(), "static-content", content,
548 lastLanguageId, defaultLanguageId, true);
549 }
550 }
551 else {
552 if (curArticle.isTemplateDriven()) {
553 JournalStructure structure =
554 JournalStructureLocalServiceUtil.getStructure(
555 groupId, structureId);
556
557 content = JournalUtil.mergeArticleContent(
558 curArticle.getContent(), content);
559 content = JournalUtil.removeOldContent(
560 content, structure.getMergedXsd());
561 }
562 }
563
564
566 article = JournalArticleServiceUtil.updateArticle(
567 groupId, articleId, version, incrementVersion, title,
568 description, content, type, structureId, templateId,
569 displayDateMonth, displayDateDay, displayDateYear,
570 displayDateHour, displayDateMinute, expirationDateMonth,
571 expirationDateDay, expirationDateYear, expirationDateHour,
572 expirationDateMinute, neverExpire, reviewDateMonth,
573 reviewDateDay, reviewDateYear, reviewDateHour, reviewDateMinute,
574 neverReview, indexable, smallImage, smallImageURL, smallFile,
575 images, articleURL, serviceContext);
576 }
577
578 boolean approve = ParamUtil.getBoolean(uploadRequest, "approve");
579
580 if (approve) {
581 JournalArticleServiceUtil.updateStatus(
582 article.getGroupId(), article.getArticleId(),
583 article.getVersion(), StatusConstants.APPROVED, articleURL,
584 serviceContext);
585 }
586
587
589 JournalUtil.addRecentArticle(actionRequest, article);
590
591
593 String portletResource = ParamUtil.getString(
594 uploadRequest, "portletResource");
595
596 if (Validator.isNotNull(portletResource)) {
597 PortletPreferences preferences =
598 PortletPreferencesFactoryUtil.getPortletSetup(
599 uploadRequest, portletResource);
600
601 preferences.setValue(
602 "group-id", String.valueOf(article.getGroupId()));
603 preferences.setValue("article-id", article.getArticleId());
604
605 preferences.store();
606
607 updateContentSearch(
608 actionRequest, portletResource, article.getArticleId());
609 }
610
611 return article;
612 }
613
614 protected void updateContentSearch(
615 ActionRequest actionRequest, String portletResource,
616 String articleId)
617 throws Exception {
618
619 ThemeDisplay themeDisplay = (ThemeDisplay)actionRequest.getAttribute(
620 WebKeys.THEME_DISPLAY);
621
622 Layout layout = themeDisplay.getLayout();
623
624 JournalContentSearchLocalServiceUtil.updateContentSearch(
625 layout.getGroupId(), layout.isPrivateLayout(), layout.getLayoutId(),
626 portletResource, articleId);
627 }
628
629 }