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