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