001    /**
002     * Copyright (c) 2000-2013 Liferay, Inc. All rights reserved.
003     *
004     * The contents of this file are subject to the terms of the Liferay Enterprise
005     * Subscription License ("License"). You may not use this file except in
006     * compliance with the License. You can obtain a copy of the License by
007     * contacting Liferay, Inc. See the License for the specific language governing
008     * permissions and limitations under the License, including but not limited to
009     * distribution rights of the Software.
010     *
011     *
012     *
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.LiferayPortletURL;
022    import com.liferay.portal.kernel.portlet.LiferayWindowState;
023    import com.liferay.portal.kernel.servlet.SessionErrors;
024    import com.liferay.portal.kernel.servlet.SessionMessages;
025    import com.liferay.portal.kernel.upload.LiferayFileItemException;
026    import com.liferay.portal.kernel.upload.UploadException;
027    import com.liferay.portal.kernel.upload.UploadPortletRequest;
028    import com.liferay.portal.kernel.util.ArrayUtil;
029    import com.liferay.portal.kernel.util.Constants;
030    import com.liferay.portal.kernel.util.GetterUtil;
031    import com.liferay.portal.kernel.util.HtmlUtil;
032    import com.liferay.portal.kernel.util.HttpUtil;
033    import com.liferay.portal.kernel.util.LocaleUtil;
034    import com.liferay.portal.kernel.util.LocalizationUtil;
035    import com.liferay.portal.kernel.util.MapUtil;
036    import com.liferay.portal.kernel.util.ParamUtil;
037    import com.liferay.portal.kernel.util.StringPool;
038    import com.liferay.portal.kernel.util.StringUtil;
039    import com.liferay.portal.kernel.util.Validator;
040    import com.liferay.portal.kernel.workflow.WorkflowConstants;
041    import com.liferay.portal.model.Layout;
042    import com.liferay.portal.security.auth.PrincipalException;
043    import com.liferay.portal.service.LayoutLocalServiceUtil;
044    import com.liferay.portal.service.ServiceContext;
045    import com.liferay.portal.service.ServiceContextFactory;
046    import com.liferay.portal.struts.PortletAction;
047    import com.liferay.portal.theme.ThemeDisplay;
048    import com.liferay.portal.util.PortalUtil;
049    import com.liferay.portal.util.WebKeys;
050    import com.liferay.portlet.PortletURLFactoryUtil;
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                    LiferayPortletURL liferayPortletURL = PortletURLFactoryUtil.create(
453                            actionRequest, portletConfig.getPortletName(),
454                            themeDisplay.getPlid(), PortletRequest.RENDER_PHASE);
455    
456                    liferayPortletURL.setParameter(
457                            "struts_action", "/journal/edit_article");
458                    liferayPortletURL.setParameter("redirect", redirect, false);
459                    liferayPortletURL.setParameter(
460                            "referringPortletResource", referringPortletResource, false);
461                    liferayPortletURL.setParameter(
462                            "resourcePrimKey", String.valueOf(article.getResourcePrimKey()),
463                            false);
464                    liferayPortletURL.setParameter(
465                            "groupId", String.valueOf(article.getGroupId()), false);
466                    liferayPortletURL.setParameter(
467                            "folderId", String.valueOf(article.getFolderId()), false);
468                    liferayPortletURL.setParameter(
469                            "articleId", article.getArticleId(), false);
470                    liferayPortletURL.setParameter(
471                            "version", String.valueOf(article.getVersion()), false);
472                    liferayPortletURL.setParameter("languageId", languageId, false);
473                    liferayPortletURL.setWindowState(actionRequest.getWindowState());
474    
475                    return liferayPortletURL.toString();
476            }
477    
478            protected void moveArticles(ActionRequest actionRequest) throws Exception {
479                    ThemeDisplay themeDisplay = (ThemeDisplay)actionRequest.getAttribute(
480                            WebKeys.THEME_DISPLAY);
481    
482                    String articleId = ParamUtil.getString(actionRequest, "articleId");
483                    long newFolderId = ParamUtil.getLong(actionRequest, "newFolderId");
484    
485                    if (Validator.isNotNull(articleId)) {
486                            JournalArticleServiceUtil.moveArticle(
487                                    themeDisplay.getScopeGroupId(), articleId, newFolderId);
488                    }
489                    else {
490                            String[] articleIds = StringUtil.split(
491                                    ParamUtil.getString(actionRequest, "articleIds"));
492    
493                            for (int i = 0; i < articleIds.length; i++) {
494                                    JournalArticleServiceUtil.moveArticle(
495                                            themeDisplay.getScopeGroupId(), articleIds[i], newFolderId);
496                            }
497                    }
498            }
499    
500            protected void removeArticlesLocale(ActionRequest actionRequest)
501                    throws Exception {
502    
503                    long groupId = ParamUtil.getLong(actionRequest, "groupId");
504    
505                    String[] removeArticleLocaleIds = StringUtil.split(
506                            ParamUtil.getString(actionRequest, "articleIds"));
507    
508                    for (String removeArticleLocaleId : removeArticleLocaleIds) {
509                            int pos = removeArticleLocaleId.lastIndexOf(VERSION_SEPARATOR);
510    
511                            String articleId = removeArticleLocaleId.substring(0, pos);
512                            double version = GetterUtil.getDouble(
513                                    removeArticleLocaleId.substring(
514                                            pos + VERSION_SEPARATOR.length()));
515                            String languageId = ParamUtil.getString(
516                                    actionRequest, "languageId");
517    
518                            JournalArticleServiceUtil.removeArticleLocale(
519                                    groupId, articleId, version, languageId);
520                    }
521            }
522    
523            protected void restoreArticles(ActionRequest actionRequest)
524                    throws Exception {
525    
526                    ThemeDisplay themeDisplay = (ThemeDisplay)actionRequest.getAttribute(
527                            WebKeys.THEME_DISPLAY);
528    
529                    String[] restoreEntryIds = StringUtil.split(
530                            ParamUtil.getString(actionRequest, "restoreEntryIds"));
531    
532                    for (String restoreEntryId : restoreEntryIds) {
533                            JournalArticleServiceUtil.restoreArticleFromTrash(
534                                    themeDisplay.getScopeGroupId(), restoreEntryId);
535                    }
536            }
537    
538            protected void subscribeArticles(ActionRequest actionRequest)
539                    throws Exception {
540    
541                    ThemeDisplay themeDisplay = (ThemeDisplay)actionRequest.getAttribute(
542                            WebKeys.THEME_DISPLAY);
543    
544                    JournalArticleServiceUtil.subscribe(themeDisplay.getScopeGroupId());
545            }
546    
547            protected void unsubscribeArticles(ActionRequest actionRequest)
548                    throws Exception {
549    
550                    ThemeDisplay themeDisplay = (ThemeDisplay)actionRequest.getAttribute(
551                            WebKeys.THEME_DISPLAY);
552    
553                    JournalArticleServiceUtil.unsubscribe(themeDisplay.getScopeGroupId());
554            }
555    
556            protected Object[] updateArticle(ActionRequest actionRequest)
557                    throws Exception {
558    
559                    UploadPortletRequest uploadPortletRequest =
560                            PortalUtil.getUploadPortletRequest(actionRequest);
561    
562                    if (_log.isDebugEnabled()) {
563                            _log.debug(
564                                    "Updating article " +
565                                            MapUtil.toString(uploadPortletRequest.getParameterMap()));
566                    }
567    
568                    String cmd = ParamUtil.getString(uploadPortletRequest, Constants.CMD);
569    
570                    long groupId = ParamUtil.getLong(uploadPortletRequest, "groupId");
571                    long folderId = ParamUtil.getLong(uploadPortletRequest, "folderId");
572                    long classNameId = ParamUtil.getLong(
573                            uploadPortletRequest, "classNameId");
574                    long classPK = ParamUtil.getLong(uploadPortletRequest, "classPK");
575    
576                    String articleId = ParamUtil.getString(
577                            uploadPortletRequest, "articleId");
578    
579                    boolean autoArticleId = ParamUtil.getBoolean(
580                            uploadPortletRequest, "autoArticleId");
581                    double version = ParamUtil.getDouble(uploadPortletRequest, "version");
582                    boolean localized = ParamUtil.getBoolean(
583                            uploadPortletRequest, "localized");
584    
585                    String defaultLanguageId = ParamUtil.getString(
586                            uploadPortletRequest, "defaultLanguageId");
587    
588                    Locale defaultLocale = LocaleUtil.fromLanguageId(defaultLanguageId);
589    
590                    String toLanguageId = ParamUtil.getString(
591                            uploadPortletRequest, "toLanguageId");
592    
593                    Locale toLocale = null;
594    
595                    String title = StringPool.BLANK;
596                    String description = StringPool.BLANK;
597    
598                    if (Validator.isNull(toLanguageId)) {
599                            title = ParamUtil.getString(
600                                    uploadPortletRequest, "title_" + defaultLanguageId);
601                            description = ParamUtil.getString(
602                                    uploadPortletRequest, "description_" + defaultLanguageId);
603                    }
604                    else {
605                            toLocale = LocaleUtil.fromLanguageId(toLanguageId);
606    
607                            title = ParamUtil.getString(
608                                    uploadPortletRequest, "title_" + toLanguageId);
609                            description = ParamUtil.getString(
610                                    uploadPortletRequest, "description_" + toLanguageId);
611                    }
612    
613                    String content = ParamUtil.getString(
614                            uploadPortletRequest, "articleContent");
615    
616                    Map<String, byte[]> images = new HashMap<String, byte[]>();
617    
618                    ServiceContext serviceContext = ServiceContextFactory.getInstance(
619                            JournalArticle.class.getName(), uploadPortletRequest);
620    
621                    String structureId = ParamUtil.getString(
622                            uploadPortletRequest, "structureId");
623    
624                    DDMStructure ddmStructure = null;
625    
626                    if (Validator.isNotNull(structureId)) {
627                            ddmStructure = DDMStructureLocalServiceUtil.getStructure(
628                                    PortalUtil.getSiteGroupId(groupId),
629                                    PortalUtil.getClassNameId(JournalArticle.class), structureId,
630                                    true);
631    
632                            String languageId = toLanguageId;
633    
634                            if (Validator.isNull(languageId)) {
635                                    languageId = defaultLanguageId;
636                            }
637    
638                            Locale locale = LocaleUtil.fromLanguageId(languageId);
639    
640                            Object[] contentAndImages = ActionUtil.getContentAndImages(
641                                    ddmStructure, locale, serviceContext);
642    
643                            content = (String)contentAndImages[0];
644                            images = (HashMap<String, byte[]>)contentAndImages[1];
645                    }
646    
647                    Boolean fileItemThresholdSizeExceeded =
648                            (Boolean)uploadPortletRequest.getAttribute(
649                                    WebKeys.FILE_ITEM_THRESHOLD_SIZE_EXCEEDED);
650    
651                    if ((fileItemThresholdSizeExceeded != null) &&
652                            fileItemThresholdSizeExceeded.booleanValue()) {
653    
654                            throw new ArticleContentSizeException();
655                    }
656    
657                    String type = ParamUtil.getString(uploadPortletRequest, "type");
658                    String templateId = ParamUtil.getString(
659                            uploadPortletRequest, "templateId");
660                    String layoutUuid = ParamUtil.getString(
661                            uploadPortletRequest, "layoutUuid");
662    
663                    // The target page and the article must belong to the same group
664    
665                    Layout targetLayout =
666                            LayoutLocalServiceUtil.fetchLayoutByUuidAndGroupId(
667                                    layoutUuid, groupId, false);
668    
669                    if (targetLayout == null) {
670                            targetLayout = LayoutLocalServiceUtil.fetchLayoutByUuidAndGroupId(
671                                    layoutUuid, groupId, true);
672                    }
673    
674                    if (targetLayout == null) {
675                            layoutUuid = null;
676                    }
677    
678                    int displayDateMonth = ParamUtil.getInteger(
679                            uploadPortletRequest, "displayDateMonth");
680                    int displayDateDay = ParamUtil.getInteger(
681                            uploadPortletRequest, "displayDateDay");
682                    int displayDateYear = ParamUtil.getInteger(
683                            uploadPortletRequest, "displayDateYear");
684                    int displayDateHour = ParamUtil.getInteger(
685                            uploadPortletRequest, "displayDateHour");
686                    int displayDateMinute = ParamUtil.getInteger(
687                            uploadPortletRequest, "displayDateMinute");
688                    int displayDateAmPm = ParamUtil.getInteger(
689                            uploadPortletRequest, "displayDateAmPm");
690    
691                    if (displayDateAmPm == Calendar.PM) {
692                            displayDateHour += 12;
693                    }
694    
695                    int expirationDateMonth = ParamUtil.getInteger(
696                            uploadPortletRequest, "expirationDateMonth");
697                    int expirationDateDay = ParamUtil.getInteger(
698                            uploadPortletRequest, "expirationDateDay");
699                    int expirationDateYear = ParamUtil.getInteger(
700                            uploadPortletRequest, "expirationDateYear");
701                    int expirationDateHour = ParamUtil.getInteger(
702                            uploadPortletRequest, "expirationDateHour");
703                    int expirationDateMinute = ParamUtil.getInteger(
704                            uploadPortletRequest, "expirationDateMinute");
705                    int expirationDateAmPm = ParamUtil.getInteger(
706                            uploadPortletRequest, "expirationDateAmPm");
707                    boolean neverExpire = ParamUtil.getBoolean(
708                            uploadPortletRequest, "neverExpire");
709    
710                    if (expirationDateAmPm == Calendar.PM) {
711                            expirationDateHour += 12;
712                    }
713    
714                    int reviewDateMonth = ParamUtil.getInteger(
715                            uploadPortletRequest, "reviewDateMonth");
716                    int reviewDateDay = ParamUtil.getInteger(
717                            uploadPortletRequest, "reviewDateDay");
718                    int reviewDateYear = ParamUtil.getInteger(
719                            uploadPortletRequest, "reviewDateYear");
720                    int reviewDateHour = ParamUtil.getInteger(
721                            uploadPortletRequest, "reviewDateHour");
722                    int reviewDateMinute = ParamUtil.getInteger(
723                            uploadPortletRequest, "reviewDateMinute");
724                    int reviewDateAmPm = ParamUtil.getInteger(
725                            uploadPortletRequest, "reviewDateAmPm");
726                    boolean neverReview = ParamUtil.getBoolean(
727                            uploadPortletRequest, "neverReview");
728    
729                    if (reviewDateAmPm == Calendar.PM) {
730                            reviewDateHour += 12;
731                    }
732    
733                    boolean indexable = ParamUtil.getBoolean(
734                            uploadPortletRequest, "indexable");
735    
736                    boolean smallImage = ParamUtil.getBoolean(
737                            uploadPortletRequest, "smallImage");
738                    String smallImageURL = ParamUtil.getString(
739                            uploadPortletRequest, "smallImageURL");
740                    File smallFile = uploadPortletRequest.getFile("smallFile");
741    
742                    String articleURL = ParamUtil.getString(
743                            uploadPortletRequest, "articleURL");
744    
745                    serviceContext.setAttribute("defaultLanguageId", defaultLanguageId);
746    
747                    JournalArticle article = null;
748                    String oldUrlTitle = StringPool.BLANK;
749    
750                    if (cmd.equals(Constants.ADD)) {
751                            Map<Locale, String> titleMap = new HashMap<Locale, String>();
752    
753                            titleMap.put(defaultLocale, title);
754    
755                            Map<Locale, String> descriptionMap = new HashMap<Locale, String>();
756    
757                            descriptionMap.put(defaultLocale, description);
758    
759                            if (Validator.isNull(structureId)) {
760                                    content = LocalizationUtil.updateLocalization(
761                                            StringPool.BLANK, "static-content", content,
762                                            defaultLanguageId, defaultLanguageId, true, localized);
763                            }
764    
765                            // Add article
766    
767                            article = JournalArticleServiceUtil.addArticle(
768                                    groupId, folderId, classNameId, classPK, articleId,
769                                    autoArticleId, titleMap, descriptionMap, content, type,
770                                    structureId, templateId, layoutUuid, displayDateMonth,
771                                    displayDateDay, displayDateYear, displayDateHour,
772                                    displayDateMinute, expirationDateMonth, expirationDateDay,
773                                    expirationDateYear, expirationDateHour, expirationDateMinute,
774                                    neverExpire, reviewDateMonth, reviewDateDay, reviewDateYear,
775                                    reviewDateHour, reviewDateMinute, neverReview, indexable,
776                                    smallImage, smallImageURL, smallFile, images, articleURL,
777                                    serviceContext);
778    
779                            AssetPublisherUtil.addAndStoreSelection(
780                                    actionRequest, JournalArticle.class.getName(),
781                                    article.getResourcePrimKey(), -1);
782                    }
783                    else {
784    
785                            // Merge current content with new content
786    
787                            JournalArticle curArticle = JournalArticleServiceUtil.getArticle(
788                                    groupId, articleId, version);
789    
790                            if (Validator.isNull(structureId)) {
791                                    if (!curArticle.isTemplateDriven()) {
792                                            String curContent = StringPool.BLANK;
793    
794                                            curContent = curArticle.getContent();
795    
796                                            if (cmd.equals(Constants.TRANSLATE)) {
797                                                    content = LocalizationUtil.updateLocalization(
798                                                            curContent, "static-content", content, toLanguageId,
799                                                            defaultLanguageId, true, true);
800                                            }
801                                            else {
802                                                    content = LocalizationUtil.updateLocalization(
803                                                            curContent, "static-content", content,
804                                                            defaultLanguageId, defaultLanguageId, true,
805                                                            localized);
806                                            }
807                                    }
808                            }
809                            else {
810                                    if (curArticle.isTemplateDriven()) {
811                                            Fields newFields = DDMUtil.getFields(
812                                                    ddmStructure.getStructureId(), serviceContext);
813    
814                                            Fields existingFields = JournalConverterUtil.getDDMFields(
815                                                    ddmStructure, curArticle.getContent());
816    
817                                            Fields mergedFields = DDMUtil.mergeFields(
818                                                    newFields, existingFields);
819    
820                                            content = JournalConverterUtil.getContent(
821                                                    ddmStructure, mergedFields);
822                                    }
823                            }
824    
825                            // Update article
826    
827                            article = JournalArticleServiceUtil.getArticle(
828                                    groupId, articleId, version);
829    
830                            Map<Locale, String> titleMap = article.getTitleMap();
831                            Map<Locale, String> descriptionMap = article.getDescriptionMap();
832    
833                            String tempOldUrlTitle = article.getUrlTitle();
834    
835                            if (cmd.equals(Constants.PREVIEW) || cmd.equals(Constants.UPDATE)) {
836                                    titleMap.put(defaultLocale, title);
837                                    descriptionMap.put(defaultLocale, description);
838    
839                                    article = JournalArticleServiceUtil.updateArticle(
840                                            groupId, folderId, articleId, version, titleMap,
841                                            descriptionMap, content, type, structureId, templateId,
842                                            layoutUuid, displayDateMonth, displayDateDay,
843                                            displayDateYear, displayDateHour, displayDateMinute,
844                                            expirationDateMonth, expirationDateDay, expirationDateYear,
845                                            expirationDateHour, expirationDateMinute, neverExpire,
846                                            reviewDateMonth, reviewDateDay, reviewDateYear,
847                                            reviewDateHour, reviewDateMinute, neverReview, indexable,
848                                            smallImage, smallImageURL, smallFile, images, articleURL,
849                                            serviceContext);
850                            }
851                            else if (cmd.equals(Constants.TRANSLATE)) {
852                                    article = JournalArticleServiceUtil.updateArticleTranslation(
853                                            groupId, articleId, version, toLocale, title, description,
854                                            content, images, serviceContext);
855                            }
856    
857                            if (!tempOldUrlTitle.equals(article.getUrlTitle())) {
858                                    oldUrlTitle = tempOldUrlTitle;
859                            }
860                    }
861    
862                    // Recent articles
863    
864                    JournalUtil.addRecentArticle(actionRequest, article);
865    
866                    // Journal content
867    
868                    PortletPreferences portletPreferences = getStrictPortletSetup(
869                            actionRequest);
870    
871                    if (portletPreferences != null) {
872                            portletPreferences.setValue(
873                                    "groupId", String.valueOf(article.getGroupId()));
874                            portletPreferences.setValue("articleId", article.getArticleId());
875    
876                            portletPreferences.store();
877    
878                            String portletResource = ParamUtil.getString(
879                                    actionRequest, "portletResource");
880    
881                            updateContentSearch(
882                                    actionRequest, portletResource, article.getArticleId());
883                    }
884    
885                    return new Object[] {article, oldUrlTitle};
886            }
887    
888            protected void updateContentSearch(
889                            ActionRequest actionRequest, String portletResource,
890                            String articleId)
891                    throws Exception {
892    
893                    ThemeDisplay themeDisplay = (ThemeDisplay)actionRequest.getAttribute(
894                            WebKeys.THEME_DISPLAY);
895    
896                    Layout layout = themeDisplay.getLayout();
897    
898                    JournalContentSearchLocalServiceUtil.updateContentSearch(
899                            layout.getGroupId(), layout.isPrivateLayout(), layout.getLayoutId(),
900                            portletResource, articleId, true);
901            }
902    
903            private static Log _log = LogFactoryUtil.getLog(EditArticleAction.class);
904    
905    }