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 if (pos == -1) {
239 JournalArticleServiceUtil.deleteArticle(
240 groupId, articleId, articleURL, serviceContext);
241 }
242 else {
243 articleId = articleId.substring(0, pos);
244 double version = GetterUtil.getDouble(
245 deleteArticleIds[i].substring(
246 pos + VERSION_SEPARATOR.length()));
247
248 JournalArticleServiceUtil.deleteArticle(
249 groupId, articleId, version, articleURL, serviceContext);
250 }
251
252 JournalUtil.removeRecentArticle(actionRequest, deleteArticleIds[i]);
253 }
254 }
255
256 protected void expireArticles(ActionRequest actionRequest)
257 throws Exception {
258
259 long groupId = ParamUtil.getLong(actionRequest, "groupId");
260
261 String[] expireArticleIds = StringUtil.split(
262 ParamUtil.getString(actionRequest, "expireArticleIds"));
263
264 ServiceContext serviceContext = ServiceContextFactory.getInstance(
265 JournalArticle.class.getName(), actionRequest);
266
267 for (int i = 0; i < expireArticleIds.length; i++) {
268 int pos = expireArticleIds[i].lastIndexOf(VERSION_SEPARATOR);
269
270 String articleId = expireArticleIds[i].substring(0, pos);
271 double version = GetterUtil.getDouble(
272 expireArticleIds[i].substring(
273 pos + VERSION_SEPARATOR.length()));
274
275 String articleURL = ParamUtil.getString(
276 actionRequest, "articleURL");
277
278 JournalArticleServiceUtil.expireArticle(
279 groupId, articleId, version, articleURL, serviceContext);
280 }
281 }
282
283 protected Map<String, byte[]> getImages(UploadPortletRequest uploadRequest)
284 throws Exception {
285
286 Map<String, byte[]> images = new HashMap<String, byte[]>();
287
288 String imagePrefix = "structure_image_";
289
290 Enumeration<String> enu = uploadRequest.getParameterNames();
291
292 while (enu.hasMoreElements()) {
293 String name = enu.nextElement();
294
295 if (name.startsWith(imagePrefix)) {
296 File file = uploadRequest.getFile(name);
297 byte[] bytes = FileUtil.getBytes(file);
298
299 if ((bytes != null) && (bytes.length > 0)) {
300 name = name.substring(imagePrefix.length(), name.length());
301
302 images.put(name, bytes);
303 }
304 }
305 }
306
307 return images;
308 }
309
310 protected String getSaveAndContinueRedirect(
311 PortletConfig portletConfig, ActionRequest actionRequest,
312 JournalArticle article, String redirect)
313 throws Exception {
314
315 ThemeDisplay themeDisplay = (ThemeDisplay)actionRequest.getAttribute(
316 WebKeys.THEME_DISPLAY);
317
318 String originalRedirect = ParamUtil.getString(
319 actionRequest, "originalRedirect");
320
321 String languageId = ParamUtil.getString(actionRequest, "languageId");
322
323 PortletURLImpl portletURL = new PortletURLImpl(
324 (ActionRequestImpl)actionRequest, portletConfig.getPortletName(),
325 themeDisplay.getPlid(), PortletRequest.RENDER_PHASE);
326
327 portletURL.setWindowState(WindowState.MAXIMIZED);
328
329 portletURL.setParameter("struts_action", "/journal/edit_article");
330 portletURL.setParameter(Constants.CMD, Constants.UPDATE, false);
331 portletURL.setParameter("redirect", redirect, false);
332 portletURL.setParameter("originalRedirect", originalRedirect, false);
333 portletURL.setParameter(
334 "groupId", String.valueOf(article.getGroupId()), false);
335 portletURL.setParameter("articleId", article.getArticleId(), false);
336 portletURL.setParameter(
337 "version", String.valueOf(article.getVersion()), false);
338 portletURL.setParameter("languageId", languageId, false);
339
340 return portletURL.toString();
341 }
342
343 protected void removeArticlesLocale(ActionRequest actionRequest)
344 throws Exception {
345
346 long groupId = ParamUtil.getLong(actionRequest, "groupId");
347
348 String[] removeArticleLocaleIds = StringUtil.split(
349 ParamUtil.getString(actionRequest, "deleteArticleIds"));
350
351 for (int i = 0; i < removeArticleLocaleIds.length; i++) {
352 int pos = removeArticleLocaleIds[i].lastIndexOf(VERSION_SEPARATOR);
353
354 String articleId = removeArticleLocaleIds[i].substring(0, pos);
355 double version = GetterUtil.getDouble(
356 removeArticleLocaleIds[i].substring(
357 pos + VERSION_SEPARATOR.length()));
358 String languageId = ParamUtil.getString(
359 actionRequest, "languageId");
360
361 JournalArticleServiceUtil.removeArticleLocale(
362 groupId, articleId, version, languageId);
363 }
364 }
365
366 protected void subscribeArticles(ActionRequest actionRequest)
367 throws Exception {
368
369 ThemeDisplay themeDisplay = (ThemeDisplay)actionRequest.getAttribute(
370 WebKeys.THEME_DISPLAY);
371
372 PermissionChecker permissionChecker =
373 themeDisplay.getPermissionChecker();
374
375 if (JournalPermission.contains(
376 permissionChecker, themeDisplay.getScopeGroupId(),
377 ActionKeys.SUBSCRIBE)) {
378
379 SubscriptionLocalServiceUtil.addSubscription(
380 themeDisplay.getUserId(), JournalArticle.class.getName(),
381 themeDisplay.getScopeGroupId());
382 }
383 }
384
385 protected void unsubscribeArticles(ActionRequest actionRequest)
386 throws Exception {
387
388 ThemeDisplay themeDisplay = (ThemeDisplay)actionRequest.getAttribute(
389 WebKeys.THEME_DISPLAY);
390
391 PermissionChecker permissionChecker =
392 themeDisplay.getPermissionChecker();
393
394 if (JournalPermission.contains(
395 permissionChecker, themeDisplay.getScopeGroupId(),
396 ActionKeys.SUBSCRIBE)) {
397
398 SubscriptionLocalServiceUtil.deleteSubscription(
399 themeDisplay.getUserId(), JournalArticle.class.getName(),
400 themeDisplay.getScopeGroupId());
401 }
402 }
403
404 protected JournalArticle updateArticle(ActionRequest actionRequest)
405 throws Exception {
406
407 UploadPortletRequest uploadRequest = PortalUtil.getUploadPortletRequest(
408 actionRequest);
409
410 String cmd = ParamUtil.getString(uploadRequest, Constants.CMD);
411
412 long groupId = ParamUtil.getLong(uploadRequest, "groupId");
413
414 String articleId = ParamUtil.getString(uploadRequest, "articleId");
415 boolean autoArticleId = ParamUtil.getBoolean(
416 uploadRequest, "autoArticleId");
417
418 double version = ParamUtil.getDouble(uploadRequest, "version");
419
420 String title = ParamUtil.getString(uploadRequest, "title");
421 String description = ParamUtil.getString(uploadRequest, "description");
422 String content = ParamUtil.getString(uploadRequest, "content");
423 String type = ParamUtil.getString(uploadRequest, "type");
424 String structureId = ParamUtil.getString(uploadRequest, "structureId");
425 String templateId = ParamUtil.getString(uploadRequest, "templateId");
426
427 String lastLanguageId = ParamUtil.getString(
428 uploadRequest, "lastLanguageId");
429 String defaultLanguageId = ParamUtil.getString(
430 uploadRequest, "defaultLanguageId");
431
432 int displayDateMonth = ParamUtil.getInteger(
433 uploadRequest, "displayDateMonth");
434 int displayDateDay = ParamUtil.getInteger(
435 uploadRequest, "displayDateDay");
436 int displayDateYear = ParamUtil.getInteger(
437 uploadRequest, "displayDateYear");
438 int displayDateHour = ParamUtil.getInteger(
439 uploadRequest, "displayDateHour");
440 int displayDateMinute = ParamUtil.getInteger(
441 uploadRequest, "displayDateMinute");
442 int displayDateAmPm = ParamUtil.getInteger(
443 uploadRequest, "displayDateAmPm");
444
445 if (displayDateAmPm == Calendar.PM) {
446 displayDateHour += 12;
447 }
448
449 int expirationDateMonth = ParamUtil.getInteger(
450 uploadRequest, "expirationDateMonth");
451 int expirationDateDay = ParamUtil.getInteger(
452 uploadRequest, "expirationDateDay");
453 int expirationDateYear = ParamUtil.getInteger(
454 uploadRequest, "expirationDateYear");
455 int expirationDateHour = ParamUtil.getInteger(
456 uploadRequest, "expirationDateHour");
457 int expirationDateMinute = ParamUtil.getInteger(
458 uploadRequest, "expirationDateMinute");
459 int expirationDateAmPm = ParamUtil.getInteger(
460 uploadRequest, "expirationDateAmPm");
461 boolean neverExpire = ParamUtil.getBoolean(
462 uploadRequest, "neverExpire");
463
464 if (expirationDateAmPm == Calendar.PM) {
465 expirationDateHour += 12;
466 }
467
468 int reviewDateMonth = ParamUtil.getInteger(
469 uploadRequest, "reviewDateMonth");
470 int reviewDateDay = ParamUtil.getInteger(
471 uploadRequest, "reviewDateDay");
472 int reviewDateYear = ParamUtil.getInteger(
473 uploadRequest, "reviewDateYear");
474 int reviewDateHour = ParamUtil.getInteger(
475 uploadRequest, "reviewDateHour");
476 int reviewDateMinute = ParamUtil.getInteger(
477 uploadRequest, "reviewDateMinute");
478 int reviewDateAmPm = ParamUtil.getInteger(
479 uploadRequest, "reviewDateAmPm");
480 boolean neverReview = ParamUtil.getBoolean(
481 uploadRequest, "neverReview");
482
483 if (reviewDateAmPm == Calendar.PM) {
484 reviewDateHour += 12;
485 }
486
487 boolean indexable = ParamUtil.getBoolean(uploadRequest, "indexable");
488
489 boolean smallImage = ParamUtil.getBoolean(uploadRequest, "smallImage");
490 String smallImageURL = ParamUtil.getString(
491 uploadRequest, "smallImageURL");
492 File smallFile = uploadRequest.getFile("smallFile");
493
494 Map<String, byte[]> images = getImages(uploadRequest);
495
496 String articleURL = ParamUtil.getString(uploadRequest, "articleURL");
497
498 ServiceContext serviceContext = ServiceContextFactory.getInstance(
499 JournalArticle.class.getName(), actionRequest);
500
501 JournalArticle article = null;
502
503 if (cmd.equals(Constants.ADD)) {
504 if (Validator.isNull(structureId)) {
505 content = LocalizationUtil.updateLocalization(
506 StringPool.BLANK, "static-content", content,
507 lastLanguageId, defaultLanguageId, true);
508 }
509
510
511
512 article = JournalArticleServiceUtil.addArticle(
513 groupId, articleId, autoArticleId, title, description,
514 content, type, structureId, templateId, displayDateMonth,
515 displayDateDay, displayDateYear, displayDateHour,
516 displayDateMinute, expirationDateMonth, expirationDateDay,
517 expirationDateYear, expirationDateHour, expirationDateMinute,
518 neverExpire, reviewDateMonth, reviewDateDay, reviewDateYear,
519 reviewDateHour, reviewDateMinute, neverReview, indexable,
520 smallImage, smallImageURL, smallFile, images, articleURL,
521 serviceContext);
522
523 AssetPublisherUtil.addAndStoreSelection(
524 actionRequest, JournalArticle.class.getName(),
525 article.getResourcePrimKey(), -1);
526 }
527 else {
528
529
530
531 JournalArticle curArticle = JournalArticleServiceUtil.getArticle(
532 groupId, articleId, version);
533
534 if (Validator.isNull(structureId)) {
535 if (!curArticle.isTemplateDriven()) {
536 content = LocalizationUtil.updateLocalization(
537 curArticle.getContent(), "static-content", content,
538 lastLanguageId, defaultLanguageId, true);
539 }
540 }
541 else {
542 if (curArticle.isTemplateDriven()) {
543 JournalStructure structure =
544 JournalStructureLocalServiceUtil.getStructure(
545 groupId, structureId);
546
547 content = JournalUtil.mergeArticleContent(
548 curArticle.getContent(), content);
549 content = JournalUtil.removeOldContent(
550 content, structure.getMergedXsd());
551 }
552 }
553
554
555
556 article = JournalArticleServiceUtil.updateArticle(
557 groupId, articleId, version, title, description, content, type,
558 structureId, templateId, displayDateMonth, displayDateDay,
559 displayDateYear, displayDateHour, displayDateMinute,
560 expirationDateMonth, expirationDateDay, expirationDateYear,
561 expirationDateHour, expirationDateMinute, neverExpire,
562 reviewDateMonth, reviewDateDay, reviewDateYear, reviewDateHour,
563 reviewDateMinute, neverReview, indexable, smallImage,
564 smallImageURL, smallFile, images, articleURL, serviceContext);
565 }
566
567
568
569 JournalUtil.addRecentArticle(actionRequest, article);
570
571
572
573 String portletResource = ParamUtil.getString(
574 uploadRequest, "portletResource");
575
576 if (Validator.isNotNull(portletResource)) {
577 PortletPreferences preferences =
578 PortletPreferencesFactoryUtil.getPortletSetup(
579 uploadRequest, portletResource);
580
581 preferences.setValue(
582 "group-id", String.valueOf(article.getGroupId()));
583 preferences.setValue("article-id", article.getArticleId());
584
585 preferences.store();
586
587 updateContentSearch(
588 actionRequest, portletResource, article.getArticleId());
589 }
590
591 return article;
592 }
593
594 protected void updateContentSearch(
595 ActionRequest actionRequest, String portletResource,
596 String articleId)
597 throws Exception {
598
599 ThemeDisplay themeDisplay = (ThemeDisplay)actionRequest.getAttribute(
600 WebKeys.THEME_DISPLAY);
601
602 Layout layout = themeDisplay.getLayout();
603
604 JournalContentSearchLocalServiceUtil.updateContentSearch(
605 layout.getGroupId(), layout.isPrivateLayout(), layout.getLayoutId(),
606 portletResource, articleId);
607 }
608
609 }