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