001    /**
002     * Copyright (c) 2000-present Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
013     */
014    
015    package com.liferay.portlet.journal.action;
016    
017    import com.liferay.portal.LocaleException;
018    import com.liferay.portal.kernel.exception.PortalException;
019    import com.liferay.portal.kernel.log.Log;
020    import com.liferay.portal.kernel.log.LogFactoryUtil;
021    import com.liferay.portal.kernel.portlet.LiferayWindowState;
022    import com.liferay.portal.kernel.servlet.SessionErrors;
023    import com.liferay.portal.kernel.servlet.SessionMessages;
024    import com.liferay.portal.kernel.upload.LiferayFileItemException;
025    import com.liferay.portal.kernel.upload.UploadException;
026    import com.liferay.portal.kernel.upload.UploadPortletRequest;
027    import com.liferay.portal.kernel.util.Constants;
028    import com.liferay.portal.kernel.util.HtmlUtil;
029    import com.liferay.portal.kernel.util.HttpUtil;
030    import com.liferay.portal.kernel.util.LocalizationUtil;
031    import com.liferay.portal.kernel.util.MapUtil;
032    import com.liferay.portal.kernel.util.ParamUtil;
033    import com.liferay.portal.kernel.util.StringPool;
034    import com.liferay.portal.kernel.util.StringUtil;
035    import com.liferay.portal.kernel.util.Validator;
036    import com.liferay.portal.kernel.workflow.WorkflowConstants;
037    import com.liferay.portal.model.Layout;
038    import com.liferay.portal.model.TrashedModel;
039    import com.liferay.portal.security.auth.PrincipalException;
040    import com.liferay.portal.service.ServiceContext;
041    import com.liferay.portal.service.ServiceContextFactory;
042    import com.liferay.portal.struts.PortletAction;
043    import com.liferay.portal.theme.ThemeDisplay;
044    import com.liferay.portal.util.PortalUtil;
045    import com.liferay.portal.util.WebKeys;
046    import com.liferay.portlet.PortletURLFactoryUtil;
047    import com.liferay.portlet.PortletURLImpl;
048    import com.liferay.portlet.asset.AssetCategoryException;
049    import com.liferay.portlet.asset.AssetTagException;
050    import com.liferay.portlet.assetpublisher.util.AssetPublisherUtil;
051    import com.liferay.portlet.documentlibrary.DuplicateFileException;
052    import com.liferay.portlet.documentlibrary.FileSizeException;
053    import com.liferay.portlet.dynamicdatamapping.NoSuchStructureException;
054    import com.liferay.portlet.dynamicdatamapping.NoSuchTemplateException;
055    import com.liferay.portlet.dynamicdatamapping.StorageFieldRequiredException;
056    import com.liferay.portlet.dynamicdatamapping.model.DDMStructure;
057    import com.liferay.portlet.dynamicdatamapping.service.DDMStructureLocalServiceUtil;
058    import com.liferay.portlet.journal.ArticleContentException;
059    import com.liferay.portlet.journal.ArticleContentSizeException;
060    import com.liferay.portlet.journal.ArticleDisplayDateException;
061    import com.liferay.portlet.journal.ArticleExpirationDateException;
062    import com.liferay.portlet.journal.ArticleIdException;
063    import com.liferay.portlet.journal.ArticleSmallImageNameException;
064    import com.liferay.portlet.journal.ArticleSmallImageSizeException;
065    import com.liferay.portlet.journal.ArticleTitleException;
066    import com.liferay.portlet.journal.ArticleVersionException;
067    import com.liferay.portlet.journal.DuplicateArticleIdException;
068    import com.liferay.portlet.journal.NoSuchArticleException;
069    import com.liferay.portlet.journal.asset.JournalArticleAssetRenderer;
070    import com.liferay.portlet.journal.model.JournalArticle;
071    import com.liferay.portlet.journal.service.JournalArticleServiceUtil;
072    import com.liferay.portlet.journal.service.JournalContentSearchLocalServiceUtil;
073    import com.liferay.portlet.journal.util.JournalUtil;
074    import com.liferay.portlet.trash.util.TrashUtil;
075    
076    import java.io.File;
077    
078    import java.util.ArrayList;
079    import java.util.Calendar;
080    import java.util.HashMap;
081    import java.util.List;
082    import java.util.Locale;
083    import java.util.Map;
084    
085    import javax.portlet.ActionRequest;
086    import javax.portlet.ActionResponse;
087    import javax.portlet.PortletConfig;
088    import javax.portlet.PortletPreferences;
089    import javax.portlet.PortletRequest;
090    import javax.portlet.PortletURL;
091    import javax.portlet.RenderRequest;
092    import javax.portlet.RenderResponse;
093    import javax.portlet.WindowState;
094    
095    import org.apache.struts.action.ActionForm;
096    import org.apache.struts.action.ActionForward;
097    import org.apache.struts.action.ActionMapping;
098    
099    /**
100     * @author Brian Wing Shun Chan
101     * @author Raymond Aug??
102     * @author Eduardo Lundgren
103     * @author Juan Fern??ndez
104     * @author Levente Hud??k
105     */
106    public class EditArticleAction extends PortletAction {
107    
108            public static final String VERSION_SEPARATOR = "_version_";
109    
110            @Override
111            public void processAction(
112                            ActionMapping actionMapping, ActionForm actionForm,
113                            PortletConfig portletConfig, ActionRequest actionRequest,
114                            ActionResponse actionResponse)
115                    throws Exception {
116    
117                    String cmd = ParamUtil.getString(actionRequest, Constants.CMD);
118    
119                    JournalArticle article = null;
120                    String oldUrlTitle = StringPool.BLANK;
121    
122                    try {
123                            UploadException uploadException =
124                                    (UploadException)actionRequest.getAttribute(
125                                            WebKeys.UPLOAD_EXCEPTION);
126    
127                            if (uploadException != null) {
128                                    if (uploadException.isExceededLiferayFileItemSizeLimit()) {
129                                            throw new LiferayFileItemException();
130                                    }
131                                    else if (uploadException.isExceededSizeLimit()) {
132                                            throw new ArticleContentSizeException();
133                                    }
134    
135                                    throw new PortalException(uploadException.getCause());
136                            }
137                            else if (Validator.isNull(cmd)) {
138                                    return;
139                            }
140                            else if (cmd.equals(Constants.ADD) ||
141                                             cmd.equals(Constants.PREVIEW) ||
142                                             cmd.equals(Constants.UPDATE)) {
143    
144                                    Object[] contentAndImages = updateArticle(actionRequest);
145    
146                                    article = (JournalArticle)contentAndImages[0];
147                                    oldUrlTitle = ((String)contentAndImages[1]);
148                            }
149                            else if (cmd.equals(Constants.DELETE)) {
150                                    deleteArticles(actionRequest, false);
151                            }
152                            else if (cmd.equals(Constants.EXPIRE)) {
153                                    expireArticles(actionRequest);
154                            }
155                            else if (cmd.equals(Constants.MOVE_TO_TRASH)) {
156                                    deleteArticles(actionRequest, true);
157                            }
158                            else if (cmd.equals(Constants.SUBSCRIBE)) {
159                                    subscribeStructure(actionRequest);
160                            }
161                            else if (cmd.equals(Constants.UNSUBSCRIBE)) {
162                                    unsubscribeStructure(actionRequest);
163                            }
164    
165                            String redirect = ParamUtil.getString(actionRequest, "redirect");
166    
167                            int workflowAction = ParamUtil.getInteger(
168                                    actionRequest, "workflowAction",
169                                    WorkflowConstants.ACTION_PUBLISH);
170    
171                            String portletId = HttpUtil.getParameter(redirect, "p_p_id", false);
172    
173                            String namespace = PortalUtil.getPortletNamespace(portletId);
174    
175                            if (Validator.isNotNull(oldUrlTitle)) {
176                                    String oldRedirectParam = namespace + "redirect";
177    
178                                    String oldRedirect = HttpUtil.getParameter(
179                                            redirect, oldRedirectParam, false);
180    
181                                    if (Validator.isNotNull(oldRedirect)) {
182                                            String newRedirect = HttpUtil.decodeURL(oldRedirect);
183    
184                                            newRedirect = StringUtil.replace(
185                                                    newRedirect, oldUrlTitle, article.getUrlTitle());
186                                            newRedirect = StringUtil.replace(
187                                                    newRedirect, oldRedirectParam, "redirect");
188    
189                                            redirect = StringUtil.replace(
190                                                    redirect, oldRedirect, newRedirect);
191                                    }
192                            }
193    
194                            if (cmd.equals(Constants.DELETE) &&
195                                    !ActionUtil.hasArticle(actionRequest)) {
196    
197                                    ThemeDisplay themeDisplay =
198                                            (ThemeDisplay)actionRequest.getAttribute(
199                                                    WebKeys.THEME_DISPLAY);
200    
201                                    PortletURL portletURL = PortletURLFactoryUtil.create(
202                                            actionRequest, portletConfig.getPortletName(),
203                                            themeDisplay.getPlid(), PortletRequest.RENDER_PHASE);
204    
205                                    redirect = portletURL.toString();
206                            }
207    
208                            if ((article != null) &&
209                                    (workflowAction == WorkflowConstants.ACTION_SAVE_DRAFT)) {
210    
211                                    redirect = getSaveAndContinueRedirect(
212                                            portletConfig, actionRequest, article, redirect);
213    
214                                    if (cmd.equals(Constants.PREVIEW)) {
215                                            SessionMessages.add(actionRequest, "previewRequested");
216    
217                                            hideDefaultSuccessMessage(actionRequest);
218                                    }
219    
220                                    sendRedirect(actionRequest, actionResponse, redirect);
221                            }
222                            else {
223                                    WindowState windowState = actionRequest.getWindowState();
224    
225                                    if (!windowState.equals(LiferayWindowState.POP_UP)) {
226                                            sendRedirect(actionRequest, actionResponse, redirect);
227                                    }
228                                    else {
229                                            redirect = PortalUtil.escapeRedirect(redirect);
230    
231                                            if (Validator.isNotNull(redirect)) {
232                                                    if (cmd.equals(Constants.ADD) && (article != null)) {
233                                                            redirect = HttpUtil.addParameter(
234                                                                    redirect, namespace + "className",
235                                                                    JournalArticle.class.getName());
236                                                            redirect = HttpUtil.addParameter(
237                                                                    redirect, namespace + "classPK",
238                                                                    JournalArticleAssetRenderer.getClassPK(
239                                                                            article));
240                                                    }
241    
242                                                    actionResponse.sendRedirect(redirect);
243                                            }
244                                    }
245                            }
246                    }
247                    catch (Exception e) {
248                            if (e instanceof NoSuchArticleException ||
249                                    e instanceof NoSuchStructureException ||
250                                    e instanceof NoSuchTemplateException ||
251                                    e instanceof PrincipalException) {
252    
253                                    SessionErrors.add(actionRequest, e.getClass());
254    
255                                    setForward(actionRequest, "portlet.journal.error");
256                            }
257                            else if (e instanceof ArticleContentException ||
258                                             e instanceof ArticleContentSizeException ||
259                                             e instanceof ArticleDisplayDateException ||
260                                             e instanceof ArticleExpirationDateException ||
261                                             e instanceof ArticleIdException ||
262                                             e instanceof ArticleSmallImageNameException ||
263                                             e instanceof ArticleSmallImageSizeException ||
264                                             e instanceof ArticleTitleException ||
265                                             e instanceof ArticleVersionException ||
266                                             e instanceof DuplicateArticleIdException ||
267                                             e instanceof DuplicateFileException ||
268                                             e instanceof FileSizeException ||
269                                             e instanceof LiferayFileItemException ||
270                                             e instanceof StorageFieldRequiredException) {
271    
272                                    SessionErrors.add(actionRequest, e.getClass());
273                            }
274                            else if (e instanceof AssetCategoryException ||
275                                             e instanceof AssetTagException ||
276                                             e instanceof LocaleException) {
277    
278                                    SessionErrors.add(actionRequest, e.getClass(), e);
279                            }
280                            else {
281                                    throw e;
282                            }
283                    }
284            }
285    
286            @Override
287            public ActionForward render(
288                            ActionMapping actionMapping, ActionForm actionForm,
289                            PortletConfig portletConfig, RenderRequest renderRequest,
290                            RenderResponse renderResponse)
291                    throws Exception {
292    
293                    try {
294                            ActionUtil.getArticle(renderRequest);
295                    }
296                    catch (NoSuchArticleException nsae) {
297    
298                            // Let this slide because the user can manually input a article id
299                            // for a new article that does not yet exist.
300    
301                    }
302                    catch (Exception e) {
303                            if (//e instanceof NoSuchArticleException ||
304                                    e instanceof PrincipalException) {
305    
306                                    SessionErrors.add(renderRequest, e.getClass());
307    
308                                    return actionMapping.findForward("portlet.journal.error");
309                            }
310                            else {
311                                    throw e;
312                            }
313                    }
314    
315                    return actionMapping.findForward(
316                            getForward(renderRequest, "portlet.journal.edit_article"));
317            }
318    
319            protected void deleteArticles(
320                            ActionRequest actionRequest, boolean moveToTrash)
321                    throws Exception {
322    
323                    ThemeDisplay themeDisplay = (ThemeDisplay)actionRequest.getAttribute(
324                            WebKeys.THEME_DISPLAY);
325    
326                    String[] deleteArticleIds = null;
327    
328                    String articleId = ParamUtil.getString(actionRequest, "articleId");
329    
330                    if (Validator.isNotNull(articleId)) {
331                            deleteArticleIds = new String[] {articleId};
332                    }
333                    else {
334                            deleteArticleIds = StringUtil.split(
335                                    ParamUtil.getString(actionRequest, "articleIds"));
336                    }
337    
338                    List<TrashedModel> trashedModels = new ArrayList<TrashedModel>();
339    
340                    for (String deleteArticleId : deleteArticleIds) {
341                            if (moveToTrash) {
342                                    JournalArticle article =
343                                            JournalArticleServiceUtil.moveArticleToTrash(
344                                                    themeDisplay.getScopeGroupId(),
345                                                    HtmlUtil.unescape(deleteArticleId));
346    
347                                    trashedModels.add(article);
348                            }
349                            else {
350                                    ActionUtil.deleteArticle(
351                                            actionRequest, HtmlUtil.unescape(deleteArticleId));
352                            }
353                    }
354    
355                    if (moveToTrash && !trashedModels.isEmpty()) {
356                            TrashUtil.addTrashSessionMessages(actionRequest, trashedModels);
357    
358                            hideDefaultSuccessMessage(actionRequest);
359                    }
360            }
361    
362            protected void expireArticles(ActionRequest actionRequest)
363                    throws Exception {
364    
365                    String articleId = ParamUtil.getString(actionRequest, "articleId");
366    
367                    if (Validator.isNotNull(articleId)) {
368                            ActionUtil.expireArticle(actionRequest, articleId);
369                    }
370                    else {
371                            String[] expireArticleIds = StringUtil.split(
372                                    ParamUtil.getString(actionRequest, "expireArticleIds"));
373    
374                            for (String expireArticleId : expireArticleIds) {
375                                    ActionUtil.expireArticle(
376                                            actionRequest, HtmlUtil.unescape(expireArticleId));
377                            }
378                    }
379            }
380    
381            protected String getSaveAndContinueRedirect(
382                            PortletConfig portletConfig, ActionRequest actionRequest,
383                            JournalArticle article, String redirect)
384                    throws Exception {
385    
386                    ThemeDisplay themeDisplay = (ThemeDisplay)actionRequest.getAttribute(
387                            WebKeys.THEME_DISPLAY);
388    
389                    String referringPortletResource = ParamUtil.getString(
390                            actionRequest, "referringPortletResource");
391    
392                    PortletURLImpl portletURL = new PortletURLImpl(
393                            actionRequest, portletConfig.getPortletName(),
394                            themeDisplay.getPlid(), PortletRequest.RENDER_PHASE);
395    
396                    portletURL.setParameter("struts_action", "/journal/edit_article");
397                    portletURL.setParameter("redirect", redirect, false);
398                    portletURL.setParameter(
399                            "referringPortletResource", referringPortletResource, false);
400                    portletURL.setParameter(
401                            "resourcePrimKey", String.valueOf(article.getResourcePrimKey()),
402                            false);
403                    portletURL.setParameter(
404                            "groupId", String.valueOf(article.getGroupId()), false);
405                    portletURL.setParameter(
406                            "folderId", String.valueOf(article.getFolderId()), false);
407                    portletURL.setParameter("articleId", article.getArticleId(), false);
408                    portletURL.setParameter(
409                            "version", String.valueOf(article.getVersion()), false);
410                    portletURL.setWindowState(actionRequest.getWindowState());
411    
412                    return portletURL.toString();
413            }
414    
415            protected void subscribeStructure(ActionRequest actionRequest)
416                    throws Exception {
417    
418                    ThemeDisplay themeDisplay = (ThemeDisplay)actionRequest.getAttribute(
419                            WebKeys.THEME_DISPLAY);
420    
421                    long ddmStructureId = ParamUtil.getLong(
422                            actionRequest, "ddmStructureId");
423    
424                    JournalArticleServiceUtil.subscribeStructure(
425                            themeDisplay.getScopeGroupId(), themeDisplay.getUserId(),
426                            ddmStructureId);
427            }
428    
429            protected void unsubscribeStructure(ActionRequest actionRequest)
430                    throws Exception {
431    
432                    ThemeDisplay themeDisplay = (ThemeDisplay)actionRequest.getAttribute(
433                            WebKeys.THEME_DISPLAY);
434    
435                    long ddmStructureId = ParamUtil.getLong(
436                            actionRequest, "ddmStructureId");
437    
438                    JournalArticleServiceUtil.unsubscribeStructure(
439                            themeDisplay.getScopeGroupId(), themeDisplay.getUserId(),
440                            ddmStructureId);
441            }
442    
443            protected Object[] updateArticle(ActionRequest actionRequest)
444                    throws Exception {
445    
446                    UploadPortletRequest uploadPortletRequest =
447                            PortalUtil.getUploadPortletRequest(actionRequest);
448    
449                    if (_log.isDebugEnabled()) {
450                            _log.debug(
451                                    "Updating article " +
452                                            MapUtil.toString(uploadPortletRequest.getParameterMap()));
453                    }
454    
455                    String cmd = ParamUtil.getString(uploadPortletRequest, Constants.CMD);
456    
457                    long groupId = ParamUtil.getLong(uploadPortletRequest, "groupId");
458                    long folderId = ParamUtil.getLong(uploadPortletRequest, "folderId");
459                    long classNameId = ParamUtil.getLong(
460                            uploadPortletRequest, "classNameId");
461                    long classPK = ParamUtil.getLong(uploadPortletRequest, "classPK");
462    
463                    String articleId = ParamUtil.getString(
464                            uploadPortletRequest, "articleId");
465    
466                    boolean autoArticleId = ParamUtil.getBoolean(
467                            uploadPortletRequest, "autoArticleId");
468                    double version = ParamUtil.getDouble(uploadPortletRequest, "version");
469    
470                    Map<Locale, String> titleMap = LocalizationUtil.getLocalizationMap(
471                            actionRequest, "title");
472                    Map<Locale, String> descriptionMap =
473                            LocalizationUtil.getLocalizationMap(actionRequest, "description");
474    
475                    ServiceContext serviceContext = ServiceContextFactory.getInstance(
476                            JournalArticle.class.getName(), uploadPortletRequest);
477    
478                    String ddmStructureKey = ParamUtil.getString(
479                            uploadPortletRequest, "ddmStructureKey");
480    
481                    DDMStructure ddmStructure = DDMStructureLocalServiceUtil.getStructure(
482                            PortalUtil.getSiteGroupId(groupId),
483                            PortalUtil.getClassNameId(JournalArticle.class), ddmStructureKey,
484                            true);
485    
486                    Object[] contentAndImages = ActionUtil.getContentAndImages(
487                            ddmStructure, serviceContext);
488    
489                    String content = (String)contentAndImages[0];
490                    Map<String, byte[]> images =
491                            (HashMap<String, byte[]>)contentAndImages[1];
492    
493                    Boolean fileItemThresholdSizeExceeded =
494                            (Boolean)uploadPortletRequest.getAttribute(
495                                    WebKeys.FILE_ITEM_THRESHOLD_SIZE_EXCEEDED);
496    
497                    if ((fileItemThresholdSizeExceeded != null) &&
498                            fileItemThresholdSizeExceeded.booleanValue()) {
499    
500                            throw new ArticleContentSizeException();
501                    }
502    
503                    String ddmTemplateKey = ParamUtil.getString(
504                            uploadPortletRequest, "ddmTemplateKey");
505                    String layoutUuid = ParamUtil.getString(
506                            uploadPortletRequest, "layoutUuid");
507    
508                    Layout targetLayout = JournalUtil.getArticleLayout(layoutUuid, groupId);
509    
510                    if (targetLayout == null) {
511                            layoutUuid = null;
512                    }
513    
514                    int displayDateMonth = ParamUtil.getInteger(
515                            uploadPortletRequest, "displayDateMonth");
516                    int displayDateDay = ParamUtil.getInteger(
517                            uploadPortletRequest, "displayDateDay");
518                    int displayDateYear = ParamUtil.getInteger(
519                            uploadPortletRequest, "displayDateYear");
520                    int displayDateHour = ParamUtil.getInteger(
521                            uploadPortletRequest, "displayDateHour");
522                    int displayDateMinute = ParamUtil.getInteger(
523                            uploadPortletRequest, "displayDateMinute");
524                    int displayDateAmPm = ParamUtil.getInteger(
525                            uploadPortletRequest, "displayDateAmPm");
526    
527                    if (displayDateAmPm == Calendar.PM) {
528                            displayDateHour += 12;
529                    }
530    
531                    int expirationDateMonth = ParamUtil.getInteger(
532                            uploadPortletRequest, "expirationDateMonth");
533                    int expirationDateDay = ParamUtil.getInteger(
534                            uploadPortletRequest, "expirationDateDay");
535                    int expirationDateYear = ParamUtil.getInteger(
536                            uploadPortletRequest, "expirationDateYear");
537                    int expirationDateHour = ParamUtil.getInteger(
538                            uploadPortletRequest, "expirationDateHour");
539                    int expirationDateMinute = ParamUtil.getInteger(
540                            uploadPortletRequest, "expirationDateMinute");
541                    int expirationDateAmPm = ParamUtil.getInteger(
542                            uploadPortletRequest, "expirationDateAmPm");
543                    boolean neverExpire = ParamUtil.getBoolean(
544                            uploadPortletRequest, "neverExpire");
545    
546                    if (expirationDateAmPm == Calendar.PM) {
547                            expirationDateHour += 12;
548                    }
549    
550                    int reviewDateMonth = ParamUtil.getInteger(
551                            uploadPortletRequest, "reviewDateMonth");
552                    int reviewDateDay = ParamUtil.getInteger(
553                            uploadPortletRequest, "reviewDateDay");
554                    int reviewDateYear = ParamUtil.getInteger(
555                            uploadPortletRequest, "reviewDateYear");
556                    int reviewDateHour = ParamUtil.getInteger(
557                            uploadPortletRequest, "reviewDateHour");
558                    int reviewDateMinute = ParamUtil.getInteger(
559                            uploadPortletRequest, "reviewDateMinute");
560                    int reviewDateAmPm = ParamUtil.getInteger(
561                            uploadPortletRequest, "reviewDateAmPm");
562                    boolean neverReview = ParamUtil.getBoolean(
563                            uploadPortletRequest, "neverReview");
564    
565                    if (reviewDateAmPm == Calendar.PM) {
566                            reviewDateHour += 12;
567                    }
568    
569                    boolean indexable = ParamUtil.getBoolean(
570                            uploadPortletRequest, "indexable");
571    
572                    boolean smallImage = ParamUtil.getBoolean(
573                            uploadPortletRequest, "smallImage");
574                    String smallImageURL = ParamUtil.getString(
575                            uploadPortletRequest, "smallImageURL");
576                    File smallFile = uploadPortletRequest.getFile("smallFile");
577    
578                    String articleURL = ParamUtil.getString(
579                            uploadPortletRequest, "articleURL");
580    
581                    JournalArticle article = null;
582                    String oldUrlTitle = StringPool.BLANK;
583    
584                    if (cmd.equals(Constants.ADD)) {
585    
586                            // Add article
587    
588                            article = JournalArticleServiceUtil.addArticle(
589                                    groupId, folderId, classNameId, classPK, articleId,
590                                    autoArticleId, titleMap, descriptionMap, content,
591                                    ddmStructureKey, ddmTemplateKey, layoutUuid, displayDateMonth,
592                                    displayDateDay, displayDateYear, displayDateHour,
593                                    displayDateMinute, expirationDateMonth, expirationDateDay,
594                                    expirationDateYear, expirationDateHour, expirationDateMinute,
595                                    neverExpire, reviewDateMonth, reviewDateDay, reviewDateYear,
596                                    reviewDateHour, reviewDateMinute, neverReview, indexable,
597                                    smallImage, smallImageURL, smallFile, images, articleURL,
598                                    serviceContext);
599    
600                            AssetPublisherUtil.addAndStoreSelection(
601                                    actionRequest, JournalArticle.class.getName(),
602                                    article.getResourcePrimKey(), -1);
603                    }
604                    else {
605    
606                            // Update article
607    
608                            article = JournalArticleServiceUtil.getArticle(
609                                    groupId, articleId, version);
610    
611                            String tempOldUrlTitle = article.getUrlTitle();
612    
613                            if (cmd.equals(Constants.PREVIEW) || cmd.equals(Constants.UPDATE)) {
614                                    article = JournalArticleServiceUtil.updateArticle(
615                                            groupId, folderId, articleId, version, titleMap,
616                                            descriptionMap, content, ddmStructureKey, ddmTemplateKey,
617                                            layoutUuid, displayDateMonth, displayDateDay,
618                                            displayDateYear, displayDateHour, displayDateMinute,
619                                            expirationDateMonth, expirationDateDay, expirationDateYear,
620                                            expirationDateHour, expirationDateMinute, neverExpire,
621                                            reviewDateMonth, reviewDateDay, reviewDateYear,
622                                            reviewDateHour, reviewDateMinute, neverReview, indexable,
623                                            smallImage, smallImageURL, smallFile, images, articleURL,
624                                            serviceContext);
625                            }
626    
627                            if (!tempOldUrlTitle.equals(article.getUrlTitle())) {
628                                    oldUrlTitle = tempOldUrlTitle;
629                            }
630                    }
631    
632                    // Recent articles
633    
634                    JournalUtil.addRecentArticle(actionRequest, article);
635    
636                    // Journal content
637    
638                    PortletPreferences portletPreferences = getStrictPortletSetup(
639                            actionRequest);
640    
641                    if (portletPreferences != null) {
642                            portletPreferences.setValue(
643                                    "groupId", String.valueOf(article.getGroupId()));
644                            portletPreferences.setValue("articleId", article.getArticleId());
645    
646                            portletPreferences.store();
647    
648                            String portletResource = ParamUtil.getString(
649                                    actionRequest, "portletResource");
650    
651                            updateContentSearch(
652                                    actionRequest, portletResource, article.getArticleId());
653                    }
654    
655                    return new Object[] {article, oldUrlTitle};
656            }
657    
658            protected void updateContentSearch(
659                            ActionRequest actionRequest, String portletResource,
660                            String articleId)
661                    throws Exception {
662    
663                    ThemeDisplay themeDisplay = (ThemeDisplay)actionRequest.getAttribute(
664                            WebKeys.THEME_DISPLAY);
665    
666                    Layout layout = themeDisplay.getLayout();
667    
668                    JournalContentSearchLocalServiceUtil.updateContentSearch(
669                            layout.getGroupId(), layout.isPrivateLayout(), layout.getLayoutId(),
670                            portletResource, articleId, true);
671            }
672    
673            private static Log _log = LogFactoryUtil.getLog(EditArticleAction.class);
674    
675    }