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