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