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