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