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