001    /**
002     * Copyright (c) 2000-2012 Liferay, Inc. All rights reserved.
003     *
004     * The contents of this file are subject to the terms of the Liferay Enterprise
005     * Subscription License ("License"). You may not use this file except in
006     * compliance with the License. You can obtain a copy of the License by
007     * contacting Liferay, Inc. See the License for the specific language governing
008     * permissions and limitations under the License, including but not limited to
009     * distribution rights of the Software.
010     *
011     *
012     *
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.portlet.LiferayWindowState;
020    import com.liferay.portal.kernel.servlet.SessionErrors;
021    import com.liferay.portal.kernel.upload.FileItem;
022    import com.liferay.portal.kernel.upload.UploadException;
023    import com.liferay.portal.kernel.upload.UploadPortletRequest;
024    import com.liferay.portal.kernel.util.Constants;
025    import com.liferay.portal.kernel.util.FileUtil;
026    import com.liferay.portal.kernel.util.GetterUtil;
027    import com.liferay.portal.kernel.util.LocaleUtil;
028    import com.liferay.portal.kernel.util.LocalizationUtil;
029    import com.liferay.portal.kernel.util.ParamUtil;
030    import com.liferay.portal.kernel.util.StringPool;
031    import com.liferay.portal.kernel.util.StringUtil;
032    import com.liferay.portal.kernel.util.Validator;
033    import com.liferay.portal.kernel.workflow.WorkflowConstants;
034    import com.liferay.portal.model.Layout;
035    import com.liferay.portal.security.auth.PrincipalException;
036    import com.liferay.portal.service.LayoutLocalServiceUtil;
037    import com.liferay.portal.service.ServiceContext;
038    import com.liferay.portal.service.ServiceContextFactory;
039    import com.liferay.portal.struts.PortletAction;
040    import com.liferay.portal.theme.ThemeDisplay;
041    import com.liferay.portal.util.PortalUtil;
042    import com.liferay.portal.util.WebKeys;
043    import com.liferay.portlet.PortletPreferencesFactoryUtil;
044    import com.liferay.portlet.PortletURLImpl;
045    import com.liferay.portlet.asset.AssetCategoryException;
046    import com.liferay.portlet.asset.AssetTagException;
047    import com.liferay.portlet.assetpublisher.util.AssetPublisherUtil;
048    import com.liferay.portlet.journal.ArticleContentException;
049    import com.liferay.portlet.journal.ArticleContentSizeException;
050    import com.liferay.portlet.journal.ArticleDisplayDateException;
051    import com.liferay.portlet.journal.ArticleExpirationDateException;
052    import com.liferay.portlet.journal.ArticleIdException;
053    import com.liferay.portlet.journal.ArticleSmallImageNameException;
054    import com.liferay.portlet.journal.ArticleSmallImageSizeException;
055    import com.liferay.portlet.journal.ArticleTitleException;
056    import com.liferay.portlet.journal.ArticleTypeException;
057    import com.liferay.portlet.journal.ArticleVersionException;
058    import com.liferay.portlet.journal.DuplicateArticleIdException;
059    import com.liferay.portlet.journal.NoSuchArticleException;
060    import com.liferay.portlet.journal.NoSuchStructureException;
061    import com.liferay.portlet.journal.NoSuchTemplateException;
062    import com.liferay.portlet.journal.model.JournalArticle;
063    import com.liferay.portlet.journal.model.JournalStructure;
064    import com.liferay.portlet.journal.service.JournalArticleLocalServiceUtil;
065    import com.liferay.portlet.journal.service.JournalArticleServiceUtil;
066    import com.liferay.portlet.journal.service.JournalContentSearchLocalServiceUtil;
067    import com.liferay.portlet.journal.service.JournalStructureLocalServiceUtil;
068    import com.liferay.portlet.journal.util.JournalUtil;
069    
070    import java.io.File;
071    
072    import java.util.Calendar;
073    import java.util.HashMap;
074    import java.util.Locale;
075    import java.util.Map;
076    
077    import javax.portlet.ActionRequest;
078    import javax.portlet.ActionResponse;
079    import javax.portlet.PortletConfig;
080    import javax.portlet.PortletContext;
081    import javax.portlet.PortletPreferences;
082    import javax.portlet.PortletRequest;
083    import javax.portlet.PortletRequestDispatcher;
084    import javax.portlet.RenderRequest;
085    import javax.portlet.RenderResponse;
086    import javax.portlet.ResourceRequest;
087    import javax.portlet.ResourceResponse;
088    import javax.portlet.WindowState;
089    
090    import org.apache.struts.action.ActionForm;
091    import org.apache.struts.action.ActionForward;
092    import org.apache.struts.action.ActionMapping;
093    
094    /**
095     * @author Brian Wing Shun Chan
096     * @author Raymond Augé
097     * @author Eduardo Lundgren
098     * @author Juan Fernández
099     */
100    public class EditArticleAction extends PortletAction {
101    
102            public static final String VERSION_SEPARATOR = "_version_";
103    
104            @Override
105            public void processAction(
106                            ActionMapping mapping, ActionForm form, PortletConfig portletConfig,
107                            ActionRequest actionRequest, ActionResponse actionResponse)
108                    throws Exception {
109    
110                    String cmd = ParamUtil.getString(actionRequest, Constants.CMD);
111    
112                    JournalArticle article = null;
113                    String oldUrlTitle = StringPool.BLANK;
114    
115                    try {
116                            if (Validator.isNull(cmd)) {
117                                    UploadException uploadException =
118                                            (UploadException)actionRequest.getAttribute(
119                                                    WebKeys.UPLOAD_EXCEPTION);
120    
121                                    if (uploadException != null) {
122                                            if (uploadException.isExceededSizeLimit()) {
123                                                    throw new ArticleContentSizeException();
124                                            }
125    
126                                            throw new PortalException(uploadException.getCause());
127                                    }
128    
129                                    return;
130                            }
131                            else if (cmd.equals(Constants.ADD) ||
132                                             cmd.equals(Constants.TRANSLATE) ||
133                                             cmd.equals(Constants.UPDATE)) {
134    
135                                    Object[] returnValue = updateArticle(actionRequest);
136    
137                                    article = (JournalArticle)returnValue[0];
138                                    oldUrlTitle = ((String)returnValue[1]);
139                            }
140                            else if (cmd.equals(Constants.DELETE) ||
141                                             cmd.equals(Constants.DELETE_VERSIONS)) {
142    
143                                    deleteArticles(actionRequest);
144                            }
145                            else if (cmd.equals(Constants.DELETE_TRANSLATION)) {
146                                    removeArticlesLocale(actionRequest);
147                            }
148                            else if (cmd.equals(Constants.EXPIRE)) {
149                                    expireArticles(actionRequest);
150                            }
151                            else if (cmd.equals(Constants.SUBSCRIBE)) {
152                                    subscribeArticles(actionRequest);
153                            }
154                            else if (cmd.equals(Constants.UNSUBSCRIBE)) {
155                                    unsubscribeArticles(actionRequest);
156                            }
157    
158                            String redirect = ParamUtil.getString(actionRequest, "redirect");
159    
160                            int workflowAction = ParamUtil.getInteger(
161                                    actionRequest, "workflowAction",
162                                    WorkflowConstants.ACTION_PUBLISH);
163    
164                            if ((article != null) &&
165                                    (workflowAction == WorkflowConstants.ACTION_SAVE_DRAFT)) {
166    
167                                    redirect = getSaveAndContinueRedirect(
168                                            portletConfig, actionRequest, article, redirect);
169                            }
170    
171                            if (redirect.contains("/content/" + oldUrlTitle + "?")) {
172                                    int pos = redirect.indexOf("?");
173    
174                                    if (pos == -1) {
175                                            pos = redirect.length();
176                                    }
177    
178                                    String newRedirect = redirect.substring(
179                                            0, pos - oldUrlTitle.length());
180    
181                                    newRedirect += article.getUrlTitle();
182    
183                                    if (oldUrlTitle.contains("/maximized")) {
184                                            newRedirect += "/maximized";
185                                    }
186    
187                                    if (pos < redirect.length()) {
188                                            newRedirect += "?" + redirect.substring(pos + 1);
189                                    }
190    
191                                    redirect = newRedirect;
192                            }
193    
194                            WindowState windowState = actionRequest.getWindowState();
195    
196                            ThemeDisplay themeDisplay =
197                                    (ThemeDisplay)actionRequest.getAttribute(WebKeys.THEME_DISPLAY);
198    
199                            Layout layout = themeDisplay.getLayout();
200    
201                            if (cmd.equals(Constants.DELETE_VERSIONS) &&
202                                    hasArticle(actionRequest)) {
203    
204                                    redirect = ParamUtil.getString(
205                                            actionRequest, "originalRedirect");
206                            }
207    
208                            if (cmd.equals(Constants.DELETE_TRANSLATION) ||
209                                    cmd.equals(Constants.TRANSLATE)) {
210    
211                                    setForward(
212                                            actionRequest,
213                                            "portlet.journal.update_translation_redirect");
214                            }
215                            else if (!windowState.equals(LiferayWindowState.POP_UP) &&
216                                             layout.isTypeControlPanel()) {
217    
218                                    sendRedirect(actionRequest, actionResponse, redirect);
219                            }
220                            else {
221                                    redirect = PortalUtil.escapeRedirect(redirect);
222    
223                                    if (Validator.isNotNull(redirect)) {
224                                            actionResponse.sendRedirect(redirect);
225                                    }
226                            }
227                    }
228                    catch (Exception e) {
229                            if (e instanceof NoSuchArticleException ||
230                                    e instanceof NoSuchStructureException ||
231                                    e instanceof NoSuchTemplateException ||
232                                    e instanceof PrincipalException) {
233    
234                                    SessionErrors.add(actionRequest, e.getClass());
235    
236                                    setForward(actionRequest, "portlet.journal.error");
237                            }
238                            else if (e instanceof ArticleContentException ||
239                                             e instanceof ArticleContentSizeException ||
240                                             e instanceof ArticleDisplayDateException ||
241                                             e instanceof ArticleExpirationDateException ||
242                                             e instanceof ArticleIdException ||
243                                             e instanceof ArticleSmallImageNameException ||
244                                             e instanceof ArticleSmallImageSizeException ||
245                                             e instanceof ArticleTitleException ||
246                                             e instanceof ArticleTypeException ||
247                                             e instanceof ArticleVersionException ||
248                                             e instanceof DuplicateArticleIdException) {
249    
250                                    SessionErrors.add(actionRequest, e.getClass());
251                            }
252                            else if (e instanceof AssetCategoryException ||
253                                             e instanceof AssetTagException ||
254                                             e instanceof LocaleException) {
255    
256                                    SessionErrors.add(actionRequest, e.getClass(), e);
257                            }
258                            else {
259                                    throw e;
260                            }
261                    }
262            }
263    
264            @Override
265            public ActionForward render(
266                            ActionMapping mapping, ActionForm form, PortletConfig portletConfig,
267                            RenderRequest renderRequest, RenderResponse renderResponse)
268                    throws Exception {
269    
270                    try {
271                            ActionUtil.getArticle(renderRequest);
272                    }
273                    catch (NoSuchArticleException nsae) {
274    
275                            // Let this slide because the user can manually input a article id
276                            // for a new article that does not yet exist.
277    
278                    }
279                    catch (Exception e) {
280                            if (//e instanceof NoSuchArticleException ||
281                                    e instanceof PrincipalException) {
282    
283                                    SessionErrors.add(renderRequest, e.getClass());
284    
285                                    return mapping.findForward("portlet.journal.error");
286                            }
287                            else {
288                                    throw e;
289                            }
290                    }
291    
292                    return mapping.findForward(
293                            getForward(renderRequest, "portlet.journal.edit_article"));
294            }
295    
296            @Override
297            public void serveResource(
298                            ActionMapping mapping, ActionForm form, PortletConfig portletConfig,
299                            ResourceRequest resourceRequest, ResourceResponse resourceResponse)
300                    throws Exception {
301    
302                    PortletContext portletContext = portletConfig.getPortletContext();
303    
304                    PortletRequestDispatcher portletRequestDispatcher =
305                            portletContext.getRequestDispatcher(
306                                    "/html/portlet/journal/editor.jsp");
307    
308                    portletRequestDispatcher.include(resourceRequest, resourceResponse);
309            }
310    
311            protected void deleteArticles(ActionRequest actionRequest)
312                    throws Exception {
313    
314                    long groupId = ParamUtil.getLong(actionRequest, "groupId");
315    
316                    String[] deleteArticleIds = StringUtil.split(
317                            ParamUtil.getString(actionRequest, "deleteArticleIds"));
318    
319                    ServiceContext serviceContext = ServiceContextFactory.getInstance(
320                            JournalArticle.class.getName(), actionRequest);
321    
322                    for (String deleteArticleId : deleteArticleIds) {
323                            int pos = deleteArticleId.lastIndexOf(VERSION_SEPARATOR);
324    
325                            String articleId = deleteArticleId;
326    
327                            String articleURL = ParamUtil.getString(
328                                    actionRequest, "articleURL");
329    
330                            double version = 0;
331    
332                            if (pos == -1) {
333                                    JournalArticleServiceUtil.deleteArticle(
334                                            groupId, articleId, articleURL, serviceContext);
335                            }
336                            else {
337                                    articleId = articleId.substring(0, pos);
338                                    version = GetterUtil.getDouble(
339                                            deleteArticleId.substring(
340                                                    pos + VERSION_SEPARATOR.length()));
341    
342                                    JournalArticleServiceUtil.deleteArticle(
343                                            groupId, articleId, version, articleURL, serviceContext);
344                            }
345    
346                            JournalUtil.removeRecentArticle(actionRequest, articleId, version);
347                    }
348            }
349    
350            protected void expireArticles(ActionRequest actionRequest)
351                    throws Exception {
352    
353                    long groupId = ParamUtil.getLong(actionRequest, "groupId");
354    
355                    String[] expireArticleIds = StringUtil.split(
356                            ParamUtil.getString(actionRequest, "expireArticleIds"));
357    
358                    ServiceContext serviceContext = ServiceContextFactory.getInstance(
359                            JournalArticle.class.getName(), actionRequest);
360    
361                    for (String expireArticleId : expireArticleIds) {
362                            int pos = expireArticleId.lastIndexOf(VERSION_SEPARATOR);
363    
364                            String articleId = expireArticleId;
365    
366                            String articleURL = ParamUtil.getString(
367                                    actionRequest, "articleURL");
368    
369                            double version = 0;
370    
371                            if (pos == -1) {
372                                    JournalArticleServiceUtil.expireArticle(
373                                            groupId, articleId, articleURL, serviceContext);
374                            }
375                            else {
376                                    articleId = articleId.substring(0, pos);
377                                    version = GetterUtil.getDouble(
378                                            expireArticleId.substring(
379                                                    pos + VERSION_SEPARATOR.length()));
380    
381                                    JournalArticleServiceUtil.expireArticle(
382                                            groupId, articleId, version, articleURL, serviceContext);
383                            }
384                    }
385            }
386    
387            protected Map<String, byte[]> getImages(
388                            UploadPortletRequest uploadPortletRequest)
389                    throws Exception {
390    
391                    Map<String, byte[]> images = new HashMap<String, byte[]>();
392    
393                    Map<String, FileItem[]> multipartParameterMap =
394                            uploadPortletRequest.getMultipartParameterMap();
395    
396                    String imagePrefix = "structure_image_";
397    
398                    for (String name : multipartParameterMap.keySet()) {
399                            if (name.startsWith(imagePrefix)) {
400                                    File file = uploadPortletRequest.getFile(name);
401                                    byte[] bytes = FileUtil.getBytes(file);
402    
403                                    if ((bytes != null) && (bytes.length > 0)) {
404                                            name = name.substring(imagePrefix.length());
405    
406                                            images.put(name, bytes);
407                                    }
408                            }
409                    }
410    
411                    return images;
412            }
413    
414            protected String getSaveAndContinueRedirect(
415                            PortletConfig portletConfig, ActionRequest actionRequest,
416                            JournalArticle article, String redirect)
417                    throws Exception {
418    
419                    ThemeDisplay themeDisplay = (ThemeDisplay)actionRequest.getAttribute(
420                            WebKeys.THEME_DISPLAY);
421    
422                    String originalRedirect = ParamUtil.getString(
423                            actionRequest, "originalRedirect");
424    
425                    String languageId = ParamUtil.getString(actionRequest, "languageId");
426    
427                    PortletURLImpl portletURL = new PortletURLImpl(
428                            actionRequest, portletConfig.getPortletName(),
429                            themeDisplay.getPlid(), PortletRequest.RENDER_PHASE);
430    
431                    portletURL.setWindowState(actionRequest.getWindowState());
432    
433                    portletURL.setParameter("struts_action", "/journal/edit_article");
434                    portletURL.setParameter(Constants.CMD, Constants.UPDATE, false);
435                    portletURL.setParameter("redirect", redirect, false);
436                    portletURL.setParameter("originalRedirect", originalRedirect, false);
437                    portletURL.setParameter(
438                            "groupId", String.valueOf(article.getGroupId()), false);
439                    portletURL.setParameter("articleId", article.getArticleId(), false);
440                    portletURL.setParameter(
441                            "version", String.valueOf(article.getVersion()), false);
442                    portletURL.setParameter("languageId", languageId, false);
443    
444                    return portletURL.toString();
445            }
446    
447            protected boolean hasArticle(ActionRequest actionRequest) throws Exception {
448                    long groupId = ParamUtil.getLong(actionRequest, "groupId");
449                    String articleId = ParamUtil.getString(actionRequest, "articleId");
450    
451                    try {
452                            JournalArticleLocalServiceUtil.getArticle(groupId, articleId);
453                    }
454                    catch (NoSuchArticleException nsae) {
455                            return true;
456                    }
457    
458                    return false;
459            }
460    
461            protected void removeArticlesLocale(ActionRequest actionRequest)
462                    throws Exception {
463    
464                    long groupId = ParamUtil.getLong(actionRequest, "groupId");
465    
466                    String[] removeArticleLocaleIds = StringUtil.split(
467                            ParamUtil.getString(actionRequest, "deleteArticleIds"));
468    
469                    for (String removeArticleLocaleId : removeArticleLocaleIds) {
470                            int pos = removeArticleLocaleId.lastIndexOf(VERSION_SEPARATOR);
471    
472                            String articleId = removeArticleLocaleId.substring(0, pos);
473                            double version = GetterUtil.getDouble(
474                                    removeArticleLocaleId.substring(
475                                            pos + VERSION_SEPARATOR.length()));
476                            String languageId = ParamUtil.getString(
477                                    actionRequest, "languageId");
478    
479                            JournalArticleServiceUtil.removeArticleLocale(
480                                    groupId, articleId, version, languageId);
481                    }
482            }
483    
484            protected void subscribeArticles(ActionRequest actionRequest)
485                    throws Exception {
486    
487                    ThemeDisplay themeDisplay = (ThemeDisplay)actionRequest.getAttribute(
488                            WebKeys.THEME_DISPLAY);
489    
490                    JournalArticleServiceUtil.subscribe(themeDisplay.getScopeGroupId());
491            }
492    
493            protected void unsubscribeArticles(ActionRequest actionRequest)
494                    throws Exception {
495    
496                    ThemeDisplay themeDisplay = (ThemeDisplay)actionRequest.getAttribute(
497                            WebKeys.THEME_DISPLAY);
498    
499                    JournalArticleServiceUtil.unsubscribe(themeDisplay.getScopeGroupId());
500            }
501    
502            protected Object[] updateArticle(ActionRequest actionRequest)
503                    throws Exception {
504    
505                    UploadPortletRequest uploadPortletRequest =
506                            PortalUtil.getUploadPortletRequest(actionRequest);
507    
508                    String cmd = ParamUtil.getString(uploadPortletRequest, Constants.CMD);
509    
510                    long groupId = ParamUtil.getLong(uploadPortletRequest, "groupId");
511    
512                    long classNameId = ParamUtil.getLong(
513                            uploadPortletRequest, "classNameId");
514                    long classPK = ParamUtil.getLong(uploadPortletRequest, "classPK");
515    
516                    String articleId = ParamUtil.getString(
517                            uploadPortletRequest, "articleId");
518                    boolean autoArticleId = ParamUtil.getBoolean(
519                            uploadPortletRequest, "autoArticleId");
520    
521                    double version = ParamUtil.getDouble(uploadPortletRequest, "version");
522    
523                    boolean localized = ParamUtil.getBoolean(
524                            uploadPortletRequest, "localized");
525    
526                    String defaultLanguageId = ParamUtil.getString(
527                            uploadPortletRequest, "defaultLanguageId");
528    
529                    Locale defaultLocale = LocaleUtil.fromLanguageId(defaultLanguageId);
530    
531                    String toLanguageId = ParamUtil.getString(
532                            uploadPortletRequest, "toLanguageId");
533    
534                    Locale toLocale = null;
535    
536                    String title = StringPool.BLANK;
537                    String description = StringPool.BLANK;
538    
539                    if (Validator.isNull(toLanguageId)) {
540                            title = ParamUtil.getString(
541                                    uploadPortletRequest, "title_" + defaultLanguageId);
542                            description = ParamUtil.getString(
543                                    uploadPortletRequest, "description_" + defaultLanguageId);
544                    }
545                    else {
546                            toLocale = LocaleUtil.fromLanguageId(toLanguageId);
547    
548                            title = ParamUtil.getString(
549                                    uploadPortletRequest, "title_" + toLanguageId);
550                            description = ParamUtil.getString(
551                                    uploadPortletRequest, "description_" + toLanguageId);
552                    }
553    
554                    String content = ParamUtil.getString(uploadPortletRequest, "content");
555    
556                    Boolean fileItemThresholdSizeExceeded =
557                                    (Boolean)uploadPortletRequest.getAttribute(
558                            WebKeys.FILE_ITEM_THRESHOLD_SIZE_EXCEEDED);
559    
560                    if ((fileItemThresholdSizeExceeded != null) &&
561                            fileItemThresholdSizeExceeded.booleanValue()) {
562    
563                            throw new ArticleContentSizeException();
564                    }
565    
566                    String type = ParamUtil.getString(uploadPortletRequest, "type");
567                    String structureId = ParamUtil.getString(
568                            uploadPortletRequest, "structureId");
569                    String templateId = ParamUtil.getString(
570                            uploadPortletRequest, "templateId");
571                    String layoutUuid = ParamUtil.getString(
572                            uploadPortletRequest, "layoutUuid");
573    
574                    // The target page and the article must belong to the same group
575    
576                    Layout targetLayout =
577                            LayoutLocalServiceUtil.fetchLayoutByUuidAndGroupId(
578                                    layoutUuid, groupId);
579    
580                    if (targetLayout == null) {
581                            layoutUuid = null;
582                    }
583    
584                    int displayDateMonth = ParamUtil.getInteger(
585                            uploadPortletRequest, "displayDateMonth");
586                    int displayDateDay = ParamUtil.getInteger(
587                            uploadPortletRequest, "displayDateDay");
588                    int displayDateYear = ParamUtil.getInteger(
589                            uploadPortletRequest, "displayDateYear");
590                    int displayDateHour = ParamUtil.getInteger(
591                            uploadPortletRequest, "displayDateHour");
592                    int displayDateMinute = ParamUtil.getInteger(
593                            uploadPortletRequest, "displayDateMinute");
594                    int displayDateAmPm = ParamUtil.getInteger(
595                            uploadPortletRequest, "displayDateAmPm");
596    
597                    if (displayDateAmPm == Calendar.PM) {
598                            displayDateHour += 12;
599                    }
600    
601                    int expirationDateMonth = ParamUtil.getInteger(
602                            uploadPortletRequest, "expirationDateMonth");
603                    int expirationDateDay = ParamUtil.getInteger(
604                            uploadPortletRequest, "expirationDateDay");
605                    int expirationDateYear = ParamUtil.getInteger(
606                            uploadPortletRequest, "expirationDateYear");
607                    int expirationDateHour = ParamUtil.getInteger(
608                            uploadPortletRequest, "expirationDateHour");
609                    int expirationDateMinute = ParamUtil.getInteger(
610                            uploadPortletRequest, "expirationDateMinute");
611                    int expirationDateAmPm = ParamUtil.getInteger(
612                            uploadPortletRequest, "expirationDateAmPm");
613                    boolean neverExpire = ParamUtil.getBoolean(
614                            uploadPortletRequest, "neverExpire");
615    
616                    if (expirationDateAmPm == Calendar.PM) {
617                            expirationDateHour += 12;
618                    }
619    
620                    int reviewDateMonth = ParamUtil.getInteger(
621                            uploadPortletRequest, "reviewDateMonth");
622                    int reviewDateDay = ParamUtil.getInteger(
623                            uploadPortletRequest, "reviewDateDay");
624                    int reviewDateYear = ParamUtil.getInteger(
625                            uploadPortletRequest, "reviewDateYear");
626                    int reviewDateHour = ParamUtil.getInteger(
627                            uploadPortletRequest, "reviewDateHour");
628                    int reviewDateMinute = ParamUtil.getInteger(
629                            uploadPortletRequest, "reviewDateMinute");
630                    int reviewDateAmPm = ParamUtil.getInteger(
631                            uploadPortletRequest, "reviewDateAmPm");
632                    boolean neverReview = ParamUtil.getBoolean(
633                            uploadPortletRequest, "neverReview");
634    
635                    if (reviewDateAmPm == Calendar.PM) {
636                            reviewDateHour += 12;
637                    }
638    
639                    boolean indexable = ParamUtil.getBoolean(
640                            uploadPortletRequest, "indexable");
641    
642                    boolean smallImage = ParamUtil.getBoolean(
643                            uploadPortletRequest, "smallImage");
644                    String smallImageURL = ParamUtil.getString(
645                            uploadPortletRequest, "smallImageURL");
646                    File smallFile = uploadPortletRequest.getFile("smallFile");
647    
648                    Map<String, byte[]> images = getImages(uploadPortletRequest);
649    
650                    String articleURL = ParamUtil.getString(
651                            uploadPortletRequest, "articleURL");
652    
653                    ServiceContext serviceContext = ServiceContextFactory.getInstance(
654                            JournalArticle.class.getName(), actionRequest);
655    
656                    serviceContext.setAttribute("defaultLanguageId", defaultLanguageId);
657    
658                    JournalArticle article = null;
659                    String oldUrlTitle = StringPool.BLANK;
660    
661                    if (cmd.equals(Constants.ADD)) {
662                            Map<Locale, String> titleMap = new HashMap<Locale, String>();
663    
664                            titleMap.put(defaultLocale, title);
665    
666                            Map<Locale, String> descriptionMap = new HashMap<Locale, String>();
667    
668                            descriptionMap.put(defaultLocale, description);
669    
670                            if (Validator.isNull(structureId)) {
671                                    content = LocalizationUtil.updateLocalization(
672                                            StringPool.BLANK, "static-content", content,
673                                            defaultLanguageId, defaultLanguageId, true, localized);
674                            }
675    
676                            // Add article
677    
678                            article = JournalArticleServiceUtil.addArticle(
679                                    groupId, classNameId, classPK, articleId, autoArticleId,
680                                    titleMap, descriptionMap, content, type, structureId,
681                                    templateId, layoutUuid, displayDateMonth, displayDateDay,
682                                    displayDateYear, displayDateHour, displayDateMinute,
683                                    expirationDateMonth, expirationDateDay, expirationDateYear,
684                                    expirationDateHour, expirationDateMinute, neverExpire,
685                                    reviewDateMonth, reviewDateDay, reviewDateYear, reviewDateHour,
686                                    reviewDateMinute, neverReview, indexable, smallImage,
687                                    smallImageURL, smallFile, images, articleURL, serviceContext);
688    
689                            AssetPublisherUtil.addAndStoreSelection(
690                                    actionRequest, JournalArticle.class.getName(),
691                                    article.getResourcePrimKey(), -1);
692                    }
693                    else {
694    
695                            // Merge current content with new content
696    
697                            JournalArticle curArticle = JournalArticleServiceUtil.getArticle(
698                                    groupId, articleId, version);
699    
700                            if (Validator.isNull(structureId)) {
701                                    if (!curArticle.isTemplateDriven()) {
702                                            String curContent = StringPool.BLANK;
703    
704                                            curContent = curArticle.getContent();
705    
706                                            if (cmd.equals(Constants.TRANSLATE)) {
707                                                    content = LocalizationUtil.updateLocalization(
708                                                            curContent, "static-content", content, toLanguageId,
709                                                            defaultLanguageId, true, true);
710                                            }
711                                            else {
712                                                    content = LocalizationUtil.updateLocalization(
713                                                            curContent, "static-content", content,
714                                                            defaultLanguageId, defaultLanguageId, true,
715                                                            localized);
716                                            }
717                                    }
718                            }
719                            else {
720                                    if (curArticle.isTemplateDriven()) {
721                                            JournalStructure structure =
722                                                    JournalStructureLocalServiceUtil.getStructure(
723                                                            groupId, structureId, true);
724    
725                                            boolean translate = cmd.equals(Constants.TRANSLATE);
726    
727                                            content = JournalUtil.mergeArticleContent(
728                                                    curArticle.getContent(), content, !translate);
729                                            content = JournalUtil.removeOldContent(
730                                                    content, structure.getMergedXsd());
731                                    }
732                            }
733    
734                            // Update article
735    
736                            article = JournalArticleServiceUtil.getArticle(
737                                    groupId, articleId, version);
738    
739                            Map<Locale, String> titleMap = article.getTitleMap();
740                            Map<Locale, String> descriptionMap = article.getDescriptionMap();
741    
742                            String tempOldUrlTitle = article.getUrlTitle();
743    
744                            if (cmd.equals(Constants.UPDATE)) {
745                                    titleMap.put(defaultLocale, title);
746                                    descriptionMap.put(defaultLocale, description);
747    
748                                    article = JournalArticleServiceUtil.updateArticle(
749                                            groupId, articleId, version, titleMap, descriptionMap,
750                                            content, type, structureId, templateId, layoutUuid,
751                                            displayDateMonth, displayDateDay, displayDateYear,
752                                            displayDateHour, displayDateMinute, expirationDateMonth,
753                                            expirationDateDay, expirationDateYear, expirationDateHour,
754                                            expirationDateMinute, neverExpire, reviewDateMonth,
755                                            reviewDateDay, reviewDateYear, reviewDateHour,
756                                            reviewDateMinute, neverReview, indexable, smallImage,
757                                            smallImageURL, smallFile, images, articleURL,
758                                            serviceContext);
759                            }
760                            else if (cmd.equals(Constants.TRANSLATE)) {
761                                    article = JournalArticleServiceUtil.updateArticleTranslation(
762                                            groupId, articleId, version, toLocale, title, description,
763                                            content, images, serviceContext);
764                            }
765    
766                            if (!tempOldUrlTitle.equals(article.getUrlTitle())) {
767                                    oldUrlTitle = tempOldUrlTitle;
768                            }
769                    }
770    
771                    // Recent articles
772    
773                    JournalUtil.addRecentArticle(actionRequest, article);
774    
775                    // Journal content
776    
777                    String portletResource = ParamUtil.getString(
778                            uploadPortletRequest, "portletResource");
779    
780                    if (Validator.isNotNull(portletResource)) {
781                            PortletPreferences preferences =
782                                    PortletPreferencesFactoryUtil.getPortletSetup(
783                                            uploadPortletRequest, portletResource);
784    
785                            preferences.setValue(
786                                    "groupId", String.valueOf(article.getGroupId()));
787                            preferences.setValue("articleId", article.getArticleId());
788    
789                            preferences.store();
790    
791                            updateContentSearch(
792                                    actionRequest, portletResource, article.getArticleId());
793                    }
794    
795                    return new Object[] {article, oldUrlTitle};
796            }
797    
798            protected void updateContentSearch(
799                            ActionRequest actionRequest, String portletResource,
800                            String articleId)
801                    throws Exception {
802    
803                    ThemeDisplay themeDisplay = (ThemeDisplay)actionRequest.getAttribute(
804                            WebKeys.THEME_DISPLAY);
805    
806                    Layout layout = themeDisplay.getLayout();
807    
808                    JournalContentSearchLocalServiceUtil.updateContentSearch(
809                            layout.getGroupId(), layout.isPrivateLayout(), layout.getLayoutId(),
810                            portletResource, articleId, true);
811            }
812    
813    }