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