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