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.documentlibrary.action;
016    
017    import com.liferay.portal.DuplicateLockException;
018    import com.liferay.portal.NoSuchRepositoryEntryException;
019    import com.liferay.portal.kernel.exception.PortalException;
020    import com.liferay.portal.kernel.exception.SystemException;
021    import com.liferay.portal.kernel.json.JSONArray;
022    import com.liferay.portal.kernel.json.JSONFactoryUtil;
023    import com.liferay.portal.kernel.json.JSONObject;
024    import com.liferay.portal.kernel.portlet.LiferayWindowState;
025    import com.liferay.portal.kernel.repository.model.FileEntry;
026    import com.liferay.portal.kernel.repository.model.Folder;
027    import com.liferay.portal.kernel.servlet.ServletResponseConstants;
028    import com.liferay.portal.kernel.servlet.SessionErrors;
029    import com.liferay.portal.kernel.servlet.SessionMessages;
030    import com.liferay.portal.kernel.upload.UploadException;
031    import com.liferay.portal.kernel.upload.UploadPortletRequest;
032    import com.liferay.portal.kernel.util.Constants;
033    import com.liferay.portal.kernel.util.ContentTypes;
034    import com.liferay.portal.kernel.util.FileUtil;
035    import com.liferay.portal.kernel.util.HttpUtil;
036    import com.liferay.portal.kernel.util.KeyValuePair;
037    import com.liferay.portal.kernel.util.MimeTypesUtil;
038    import com.liferay.portal.kernel.util.ParamUtil;
039    import com.liferay.portal.kernel.util.PropsKeys;
040    import com.liferay.portal.kernel.util.StreamUtil;
041    import com.liferay.portal.kernel.util.StringBundler;
042    import com.liferay.portal.kernel.util.StringPool;
043    import com.liferay.portal.kernel.util.StringUtil;
044    import com.liferay.portal.kernel.util.TempFileUtil;
045    import com.liferay.portal.kernel.util.Validator;
046    import com.liferay.portal.kernel.workflow.WorkflowConstants;
047    import com.liferay.portal.security.auth.PrincipalException;
048    import com.liferay.portal.service.ServiceContext;
049    import com.liferay.portal.service.ServiceContextFactory;
050    import com.liferay.portal.struts.ActionConstants;
051    import com.liferay.portal.struts.PortletAction;
052    import com.liferay.portal.theme.ThemeDisplay;
053    import com.liferay.portal.util.PortalUtil;
054    import com.liferay.portal.util.PortletKeys;
055    import com.liferay.portal.util.PrefsPropsUtil;
056    import com.liferay.portal.util.WebKeys;
057    import com.liferay.portlet.PortletURLImpl;
058    import com.liferay.portlet.asset.AssetCategoryException;
059    import com.liferay.portlet.asset.AssetTagException;
060    import com.liferay.portlet.asset.model.AssetVocabulary;
061    import com.liferay.portlet.assetpublisher.util.AssetPublisherUtil;
062    import com.liferay.portlet.documentlibrary.DuplicateFileException;
063    import com.liferay.portlet.documentlibrary.DuplicateFolderNameException;
064    import com.liferay.portlet.documentlibrary.FileExtensionException;
065    import com.liferay.portlet.documentlibrary.FileMimeTypeException;
066    import com.liferay.portlet.documentlibrary.FileNameException;
067    import com.liferay.portlet.documentlibrary.FileSizeException;
068    import com.liferay.portlet.documentlibrary.InvalidFileEntryTypeException;
069    import com.liferay.portlet.documentlibrary.InvalidFileVersionException;
070    import com.liferay.portlet.documentlibrary.NoSuchFileEntryException;
071    import com.liferay.portlet.documentlibrary.NoSuchFileVersionException;
072    import com.liferay.portlet.documentlibrary.NoSuchFolderException;
073    import com.liferay.portlet.documentlibrary.SourceFileNameException;
074    import com.liferay.portlet.documentlibrary.model.DLFileEntry;
075    import com.liferay.portlet.documentlibrary.service.DLAppLocalServiceUtil;
076    import com.liferay.portlet.documentlibrary.service.DLAppServiceUtil;
077    import com.liferay.portlet.documentlibrary.util.DLUtil;
078    import com.liferay.portlet.dynamicdatamapping.StorageFieldRequiredException;
079    import com.liferay.portlet.trash.util.TrashUtil;
080    
081    import java.io.InputStream;
082    
083    import java.util.ArrayList;
084    import java.util.Arrays;
085    import java.util.HashMap;
086    import java.util.HashSet;
087    import java.util.List;
088    import java.util.Map;
089    import java.util.Set;
090    
091    import javax.portlet.ActionRequest;
092    import javax.portlet.ActionResponse;
093    import javax.portlet.PortletConfig;
094    import javax.portlet.PortletContext;
095    import javax.portlet.PortletPreferences;
096    import javax.portlet.PortletRequest;
097    import javax.portlet.PortletRequestDispatcher;
098    import javax.portlet.PortletResponse;
099    import javax.portlet.RenderRequest;
100    import javax.portlet.RenderResponse;
101    import javax.portlet.ResourceRequest;
102    import javax.portlet.ResourceResponse;
103    import javax.portlet.WindowState;
104    
105    import javax.servlet.http.HttpServletResponse;
106    
107    import org.apache.commons.fileupload.FileUploadBase.IOFileUploadException;
108    import org.apache.struts.action.ActionForm;
109    import org.apache.struts.action.ActionForward;
110    import org.apache.struts.action.ActionMapping;
111    
112    /**
113     * @author Brian Wing Shun Chan
114     * @author Alexander Chow
115     * @author Sergio Gonz??lez
116     * @author Manuel de la Pe??a
117     * @author Levente Hud??k
118     * @author Kenneth Chang
119     */
120    public class EditFileEntryAction extends PortletAction {
121    
122            public static final String TEMP_RANDOM_SUFFIX = "--tempRandomSuffix--";
123    
124            @Override
125            public void processAction(
126                            ActionMapping actionMapping, ActionForm actionForm,
127                            PortletConfig portletConfig, ActionRequest actionRequest,
128                            ActionResponse actionResponse)
129                    throws Exception {
130    
131                    String cmd = ParamUtil.getString(actionRequest, Constants.CMD);
132    
133                    FileEntry fileEntry = null;
134    
135                    try {
136                            if (Validator.isNull(cmd)) {
137                                    UploadException uploadException =
138                                            (UploadException)actionRequest.getAttribute(
139                                                    WebKeys.UPLOAD_EXCEPTION);
140    
141                                    if (uploadException != null) {
142                                            if (uploadException.isExceededSizeLimit()) {
143                                                    throw new FileSizeException(uploadException.getCause());
144                                            }
145    
146                                            throw new PortalException(uploadException.getCause());
147                                    }
148                            }
149                            else if (cmd.equals(Constants.ADD) ||
150                                             cmd.equals(Constants.ADD_DYNAMIC) ||
151                                             cmd.equals(Constants.UPDATE) ||
152                                             cmd.equals(Constants.UPDATE_AND_CHECKIN)) {
153    
154                                    fileEntry = updateFileEntry(
155                                            portletConfig, actionRequest, actionResponse);
156                            }
157                            else if (cmd.equals(Constants.ADD_MULTIPLE)) {
158                                    addMultipleFileEntries(
159                                            portletConfig, actionRequest, actionResponse);
160                            }
161                            else if (cmd.equals(Constants.ADD_TEMP)) {
162                                    addTempFileEntry(actionRequest, actionResponse);
163                            }
164                            else if (cmd.equals(Constants.DELETE)) {
165                                    deleteFileEntry(actionRequest, false);
166                            }
167                            else if (cmd.equals(Constants.DELETE_TEMP)) {
168                                    deleteTempFileEntry(actionRequest, actionResponse);
169                            }
170                            else if (cmd.equals(Constants.CANCEL_CHECKOUT)) {
171                                    cancelFileEntriesCheckOut(actionRequest);
172                            }
173                            else if (cmd.equals(Constants.CHECKIN)) {
174                                    checkInFileEntries(actionRequest);
175                            }
176                            else if (cmd.equals(Constants.CHECKOUT)) {
177                                    checkOutFileEntries(actionRequest);
178                            }
179                            else if (cmd.equals(Constants.MOVE)) {
180                                    moveFileEntries(actionRequest, false);
181                            }
182                            else if (cmd.equals(Constants.MOVE_FROM_TRASH)) {
183                                    moveFileEntries(actionRequest, true);
184                            }
185                            else if (cmd.equals(Constants.MOVE_TO_TRASH)) {
186                                    deleteFileEntry(actionRequest, true);
187                            }
188                            else if (cmd.equals(Constants.REVERT)) {
189                                    revertFileEntry(actionRequest);
190                            }
191    
192                            WindowState windowState = actionRequest.getWindowState();
193    
194                            if (cmd.equals(Constants.ADD_TEMP) ||
195                                    cmd.equals(Constants.DELETE_TEMP)) {
196    
197                                    setForward(actionRequest, ActionConstants.COMMON_NULL);
198                            }
199                            else if (cmd.equals(Constants.PREVIEW)) {
200                            }
201                            else if (!cmd.equals(Constants.MOVE_FROM_TRASH) &&
202                                             !windowState.equals(LiferayWindowState.POP_UP)) {
203    
204                                    sendRedirect(actionRequest, actionResponse);
205                            }
206                            else {
207                                    String redirect = ParamUtil.getString(
208                                            actionRequest, "redirect");
209                                    int workflowAction = ParamUtil.getInteger(
210                                            actionRequest, "workflowAction",
211                                            WorkflowConstants.ACTION_SAVE_DRAFT);
212    
213                                    if ((fileEntry != null) &&
214                                            (workflowAction == WorkflowConstants.ACTION_SAVE_DRAFT)) {
215    
216                                            redirect = getSaveAndContinueRedirect(
217                                                    portletConfig, actionRequest, fileEntry, redirect);
218    
219                                            sendRedirect(actionRequest, actionResponse, redirect);
220                                    }
221                                    else {
222                                            if (!windowState.equals(LiferayWindowState.POP_UP)) {
223                                                    sendRedirect(actionRequest, actionResponse);
224                                            }
225                                            else {
226                                                    redirect = PortalUtil.escapeRedirect(
227                                                            ParamUtil.getString(actionRequest, "redirect"));
228    
229                                                    if (Validator.isNotNull(redirect)) {
230                                                            if (cmd.equals(Constants.ADD) &&
231                                                                    (fileEntry != null)) {
232    
233                                                                    String portletId = HttpUtil.getParameter(
234                                                                            redirect, "p_p_id", false);
235    
236                                                                    String namespace =
237                                                                            PortalUtil.getPortletNamespace(portletId);
238    
239                                                                    redirect = HttpUtil.addParameter(
240                                                                            redirect, namespace + "className",
241                                                                            DLFileEntry.class.getName());
242                                                                    redirect = HttpUtil.addParameter(
243                                                                            redirect, namespace + "classPK",
244                                                                            fileEntry.getFileEntryId());
245                                                            }
246    
247                                                            actionResponse.sendRedirect(redirect);
248                                                    }
249                                            }
250                                    }
251                            }
252                    }
253                    catch (Exception e) {
254                            handleUploadException(
255                                    portletConfig, actionRequest, actionResponse, cmd, e);
256                    }
257            }
258    
259            @Override
260            public ActionForward render(
261                            ActionMapping actionMapping, ActionForm actionForm,
262                            PortletConfig portletConfig, RenderRequest renderRequest,
263                            RenderResponse renderResponse)
264                    throws Exception {
265    
266                    try {
267                            ActionUtil.getFileEntry(renderRequest);
268                    }
269                    catch (Exception e) {
270                            if (e instanceof NoSuchFileEntryException ||
271                                    e instanceof NoSuchFileVersionException ||
272                                    e instanceof NoSuchRepositoryEntryException ||
273                                    e instanceof PrincipalException) {
274    
275                                    SessionErrors.add(renderRequest, e.getClass());
276    
277                                    return actionMapping.findForward(
278                                            "portlet.document_library.error");
279                            }
280                            else {
281                                    throw e;
282                            }
283                    }
284    
285                    String forward = "portlet.document_library.edit_file_entry";
286    
287                    return actionMapping.findForward(getForward(renderRequest, forward));
288            }
289    
290            @Override
291            public void serveResource(
292                            ActionMapping actionMapping, ActionForm actionForm,
293                            PortletConfig portletConfig, ResourceRequest resourceRequest,
294                            ResourceResponse resourceResponse)
295                    throws Exception {
296    
297                    PortletContext portletContext = portletConfig.getPortletContext();
298    
299                    PortletRequestDispatcher portletRequestDispatcher =
300                            portletContext.getRequestDispatcher(
301                                    "/html/portlet/document_library/" +
302                                            "upload_multiple_file_entries_resources.jsp");
303    
304                    portletRequestDispatcher.include(resourceRequest, resourceResponse);
305            }
306    
307            protected void addMultipleFileEntries(
308                            PortletConfig portletConfig, ActionRequest actionRequest,
309                            ActionResponse actionResponse)
310                    throws Exception {
311    
312                    List<KeyValuePair> validFileNameKVPs = new ArrayList<KeyValuePair>();
313                    List<KeyValuePair> invalidFileNameKVPs = new ArrayList<KeyValuePair>();
314    
315                    String[] selectedFileNames = ParamUtil.getParameterValues(
316                            actionRequest, "selectedFileName");
317    
318                    for (String selectedFileName : selectedFileNames) {
319                            addMultipleFileEntries(
320                                    portletConfig, actionRequest, actionResponse, selectedFileName,
321                                    validFileNameKVPs, invalidFileNameKVPs);
322                    }
323    
324                    JSONArray jsonArray = JSONFactoryUtil.createJSONArray();
325    
326                    for (KeyValuePair validFileNameKVP : validFileNameKVPs) {
327                            String fileName = validFileNameKVP.getKey();
328                            String originalFileName = validFileNameKVP.getValue();
329    
330                            JSONObject jsonObject = JSONFactoryUtil.createJSONObject();
331    
332                            jsonObject.put("added", Boolean.TRUE);
333                            jsonObject.put("fileName", fileName);
334                            jsonObject.put("originalFileName", originalFileName);
335    
336                            jsonArray.put(jsonObject);
337                    }
338    
339                    for (KeyValuePair invalidFileNameKVP : invalidFileNameKVPs) {
340                            String fileName = invalidFileNameKVP.getKey();
341                            String errorMessage = invalidFileNameKVP.getValue();
342    
343                            JSONObject jsonObject = JSONFactoryUtil.createJSONObject();
344    
345                            jsonObject.put("added", Boolean.FALSE);
346                            jsonObject.put("errorMessage", errorMessage);
347                            jsonObject.put("fileName", fileName);
348                            jsonObject.put("originalFileName", fileName);
349    
350                            jsonArray.put(jsonObject);
351                    }
352    
353                    writeJSON(actionRequest, actionResponse, jsonArray);
354            }
355    
356            protected void addMultipleFileEntries(
357                            PortletConfig portletConfig, ActionRequest actionRequest,
358                            ActionResponse actionResponse, String selectedFileName,
359                            List<KeyValuePair> validFileNameKVPs,
360                            List<KeyValuePair> invalidFileNameKVPs)
361                    throws Exception {
362    
363                    String originalSelectedFileName = selectedFileName;
364    
365                    ThemeDisplay themeDisplay = (ThemeDisplay)actionRequest.getAttribute(
366                            WebKeys.THEME_DISPLAY);
367    
368                    long repositoryId = ParamUtil.getLong(actionRequest, "repositoryId");
369                    long folderId = ParamUtil.getLong(actionRequest, "folderId");
370                    String description = ParamUtil.getString(actionRequest, "description");
371                    String changeLog = ParamUtil.getString(actionRequest, "changeLog");
372    
373                    FileEntry tempFileEntry = null;
374    
375                    try {
376                            tempFileEntry = TempFileUtil.getTempFile(
377                                    themeDisplay.getScopeGroupId(), themeDisplay.getUserId(),
378                                    selectedFileName, _TEMP_FOLDER_NAME);
379    
380                            String mimeType = tempFileEntry.getMimeType();
381                            InputStream inputStream = tempFileEntry.getContentStream();
382                            long size = tempFileEntry.getSize();
383    
384                            ServiceContext serviceContext = ServiceContextFactory.getInstance(
385                                    DLFileEntry.class.getName(), actionRequest);
386    
387                            int pos = selectedFileName.indexOf(TEMP_RANDOM_SUFFIX);
388    
389                            if (pos != -1) {
390                                    selectedFileName = selectedFileName.substring(0, pos);
391                            }
392    
393                            while (true) {
394                                    try {
395                                            DLAppLocalServiceUtil.getFileEntry(
396                                                    themeDisplay.getScopeGroupId(), folderId,
397                                                    selectedFileName);
398    
399                                            StringBundler sb = new StringBundler(5);
400    
401                                            sb.append(FileUtil.stripExtension(selectedFileName));
402                                            sb.append(StringPool.DASH);
403                                            sb.append(StringUtil.randomString());
404                                            sb.append(StringPool.PERIOD);
405                                            sb.append(FileUtil.getExtension(selectedFileName));
406    
407                                            selectedFileName = sb.toString();
408                                    }
409                                    catch (Exception e) {
410                                            break;
411                                    }
412                            }
413    
414                            FileEntry fileEntry = DLAppServiceUtil.addFileEntry(
415                                    repositoryId, folderId, selectedFileName, mimeType,
416                                    selectedFileName, description, changeLog, inputStream, size,
417                                    serviceContext);
418    
419                            AssetPublisherUtil.addAndStoreSelection(
420                                    actionRequest, DLFileEntry.class.getName(),
421                                    fileEntry.getFileEntryId(), -1);
422    
423                            AssetPublisherUtil.addRecentFolderId(
424                                    actionRequest, DLFileEntry.class.getName(), folderId);
425    
426                            validFileNameKVPs.add(
427                                    new KeyValuePair(selectedFileName, originalSelectedFileName));
428    
429                            return;
430                    }
431                    catch (Exception e) {
432                            String errorMessage = getAddMultipleFileEntriesErrorMessage(
433                                    portletConfig, actionRequest, actionResponse, e);
434    
435                            invalidFileNameKVPs.add(
436                                    new KeyValuePair(originalSelectedFileName, errorMessage));
437                    }
438                    finally {
439                            if (tempFileEntry != null) {
440                                    TempFileUtil.deleteTempFile(tempFileEntry.getFileEntryId());
441                            }
442                    }
443            }
444    
445            protected void addTempFileEntry(
446                            ActionRequest actionRequest, ActionResponse actionResponse)
447                    throws Exception {
448    
449                    UploadPortletRequest uploadPortletRequest =
450                            PortalUtil.getUploadPortletRequest(actionRequest);
451    
452                    ThemeDisplay themeDisplay = (ThemeDisplay)actionRequest.getAttribute(
453                            WebKeys.THEME_DISPLAY);
454    
455                    long folderId = ParamUtil.getLong(uploadPortletRequest, "folderId");
456                    String sourceFileName = uploadPortletRequest.getFileName("file");
457    
458                    String title = sourceFileName;
459    
460                    sourceFileName = sourceFileName.concat(
461                            TEMP_RANDOM_SUFFIX).concat(StringUtil.randomString());
462    
463                    InputStream inputStream = null;
464    
465                    try {
466                            inputStream = uploadPortletRequest.getFileAsStream("file");
467    
468                            String contentType = uploadPortletRequest.getContentType("file");
469    
470                            DLAppServiceUtil.addTempFileEntry(
471                                    themeDisplay.getScopeGroupId(), folderId, sourceFileName,
472                                    _TEMP_FOLDER_NAME, inputStream, contentType);
473    
474                            JSONObject jsonObject = JSONFactoryUtil.createJSONObject();
475    
476                            jsonObject.put("name", sourceFileName);
477                            jsonObject.put("title", title);
478    
479                            writeJSON(actionRequest, actionResponse, jsonObject);
480                    }
481                    catch (Exception e) {
482                            UploadException uploadException =
483                                    (UploadException)actionRequest.getAttribute(
484                                            WebKeys.UPLOAD_EXCEPTION);
485    
486                            if ((uploadException != null) &&
487                                    (uploadException.getCause() instanceof IOFileUploadException)) {
488    
489                                    // Cancelled a temporary upload
490    
491                            }
492                            else if ((uploadException != null) &&
493                                             uploadException.isExceededSizeLimit()) {
494    
495                                    throw new FileSizeException(uploadException.getCause());
496                            }
497                            else {
498                                    throw e;
499                            }
500                    }
501                    finally {
502                            StreamUtil.cleanUp(inputStream);
503                    }
504            }
505    
506            protected void cancelFileEntriesCheckOut(ActionRequest actionRequest)
507                    throws Exception {
508    
509                    long fileEntryId = ParamUtil.getLong(actionRequest, "fileEntryId");
510    
511                    if (fileEntryId > 0) {
512                            DLAppServiceUtil.cancelCheckOut(fileEntryId);
513                    }
514                    else {
515                            long[] fileEntryIds = StringUtil.split(
516                                    ParamUtil.getString(actionRequest, "fileEntryIds"), 0L);
517    
518                            for (int i = 0; i < fileEntryIds.length; i++) {
519                                    DLAppServiceUtil.cancelCheckOut(fileEntryIds[i]);
520                            }
521                    }
522            }
523    
524            protected void checkInFileEntries(ActionRequest actionRequest)
525                    throws Exception {
526    
527                    long fileEntryId = ParamUtil.getLong(actionRequest, "fileEntryId");
528    
529                    ServiceContext serviceContext = ServiceContextFactory.getInstance(
530                            actionRequest);
531    
532                    if (fileEntryId > 0) {
533                            DLAppServiceUtil.checkInFileEntry(
534                                    fileEntryId, false, StringPool.BLANK, serviceContext);
535                    }
536                    else {
537                            long[] fileEntryIds = StringUtil.split(
538                                    ParamUtil.getString(actionRequest, "fileEntryIds"), 0L);
539    
540                            for (int i = 0; i < fileEntryIds.length; i++) {
541                                    DLAppServiceUtil.checkInFileEntry(
542                                            fileEntryIds[i], false, StringPool.BLANK, serviceContext);
543                            }
544                    }
545            }
546    
547            protected void checkOutFileEntries(ActionRequest actionRequest)
548                    throws Exception {
549    
550                    long fileEntryId = ParamUtil.getLong(actionRequest, "fileEntryId");
551    
552                    ServiceContext serviceContext = ServiceContextFactory.getInstance(
553                            actionRequest);
554    
555                    if (fileEntryId > 0) {
556                            DLAppServiceUtil.checkOutFileEntry(fileEntryId, serviceContext);
557                    }
558                    else {
559                            long[] fileEntryIds = StringUtil.split(
560                                    ParamUtil.getString(actionRequest, "fileEntryIds"), 0L);
561    
562                            for (int i = 0; i < fileEntryIds.length; i++) {
563                                    DLAppServiceUtil.checkOutFileEntry(
564                                            fileEntryIds[i], serviceContext);
565                            }
566                    }
567            }
568    
569            protected void deleteFileEntry(
570                            ActionRequest actionRequest, boolean moveToTrash)
571                    throws Exception {
572    
573                    long fileEntryId = ParamUtil.getLong(actionRequest, "fileEntryId");
574    
575                    if (fileEntryId == 0) {
576                            return;
577                    }
578    
579                    String version = ParamUtil.getString(actionRequest, "version");
580    
581                    if (Validator.isNotNull(version)) {
582                            DLAppServiceUtil.deleteFileVersion(fileEntryId, version);
583    
584                            return;
585                    }
586    
587                    if (!moveToTrash) {
588                            DLAppServiceUtil.deleteFileEntry(fileEntryId);
589    
590                            return;
591                    }
592    
593                    FileEntry fileEntry = DLAppServiceUtil.moveFileEntryToTrash(
594                            fileEntryId);
595    
596                    Map<String, String[]> data = new HashMap<String, String[]>();
597    
598                    data.put(
599                            "deleteEntryClassName", new String[] {DLFileEntry.class.getName()});
600    
601                    if (fileEntry != null) {
602                            data.put(
603                                    "deleteEntryTitle",
604                                    new String[] {
605                                            TrashUtil.getOriginalTitle(fileEntry.getTitle())});
606                    }
607    
608                    data.put(
609                            "restoreFileEntryIds", new String[] {String.valueOf(fileEntryId)});
610    
611                    SessionMessages.add(
612                            actionRequest,
613                            PortalUtil.getPortletId(actionRequest) +
614                                    SessionMessages.KEY_SUFFIX_DELETE_SUCCESS_DATA,
615                            data);
616    
617                    hideDefaultSuccessMessage(actionRequest);
618            }
619    
620            protected void deleteTempFileEntry(
621                            ActionRequest actionRequest, ActionResponse actionResponse)
622                    throws Exception {
623    
624                    ThemeDisplay themeDisplay = (ThemeDisplay)actionRequest.getAttribute(
625                            WebKeys.THEME_DISPLAY);
626    
627                    long folderId = ParamUtil.getLong(actionRequest, "folderId");
628                    String fileName = ParamUtil.getString(actionRequest, "fileName");
629    
630                    JSONObject jsonObject = JSONFactoryUtil.createJSONObject();
631    
632                    try {
633                            DLAppServiceUtil.deleteTempFileEntry(
634                                    themeDisplay.getScopeGroupId(), folderId, fileName,
635                                    _TEMP_FOLDER_NAME);
636    
637                            jsonObject.put("deleted", Boolean.TRUE);
638                    }
639                    catch (Exception e) {
640                            String errorMessage = themeDisplay.translate(
641                                    "an-unexpected-error-occurred-while-deleting-the-file");
642    
643                            jsonObject.put("deleted", Boolean.FALSE);
644                            jsonObject.put("errorMessage", errorMessage);
645                    }
646    
647                    writeJSON(actionRequest, actionResponse, jsonObject);
648            }
649    
650            protected String getAddMultipleFileEntriesErrorMessage(
651                            PortletConfig portletConfig, ActionRequest actionRequest,
652                            ActionResponse actionResponse, Exception e)
653                    throws Exception {
654    
655                    String errorMessage = null;
656    
657                    ThemeDisplay themeDisplay = (ThemeDisplay)actionRequest.getAttribute(
658                            WebKeys.THEME_DISPLAY);
659    
660                    if (e instanceof AssetCategoryException) {
661                            AssetCategoryException ace = (AssetCategoryException)e;
662    
663                            AssetVocabulary assetVocabulary = ace.getVocabulary();
664    
665                            String vocabularyTitle = StringPool.BLANK;
666    
667                            if (assetVocabulary != null) {
668                                    vocabularyTitle = assetVocabulary.getTitle(
669                                            themeDisplay.getLocale());
670                            }
671    
672                            if (ace.getType() == AssetCategoryException.AT_LEAST_ONE_CATEGORY) {
673                                    errorMessage = themeDisplay.translate(
674                                            "please-select-at-least-one-category-for-x",
675                                            vocabularyTitle);
676                            }
677                            else if (ace.getType() ==
678                                                    AssetCategoryException.TOO_MANY_CATEGORIES) {
679    
680                                    errorMessage = themeDisplay.translate(
681                                            "you-cannot-select-more-than-one-category-for-x",
682                                            vocabularyTitle);
683                            }
684                    }
685                    else if (e instanceof DuplicateFileException) {
686                            errorMessage = themeDisplay.translate(
687                                    "the-folder-you-selected-already-has-an-entry-with-this-name." +
688                                            "-please-select-a-different-folder");
689                    }
690                    else if (e instanceof FileExtensionException) {
691                            errorMessage = themeDisplay.translate(
692                                    "please-enter-a-file-with-a-valid-extension-x",
693                                            StringUtil.merge(
694                                                    getAllowedFileExtensions(
695                                                            portletConfig, actionRequest, actionResponse)));
696                    }
697                    else if (e instanceof FileNameException) {
698                            errorMessage = themeDisplay.translate(
699                                    "please-enter-a-file-with-a-valid-file-name");
700                    }
701                    else if (e instanceof FileSizeException) {
702                            long maxSizeMB = PrefsPropsUtil.getLong(
703                                    PropsKeys.DL_FILE_MAX_SIZE) / 1024 / 1024;
704    
705                            errorMessage = themeDisplay.translate(
706                                    "file-size-is-larger-than-x-megabytes", maxSizeMB);
707                    }
708                    else if (e instanceof InvalidFileEntryTypeException) {
709                            errorMessage = themeDisplay.translate(
710                                    "the-document-type-you-selected-is-not-valid-for-this-folder");
711                    }
712                    else {
713                            errorMessage = themeDisplay.translate(
714                                    "an-unexpected-error-occurred-while-saving-your-document");
715                    }
716    
717                    return errorMessage;
718            }
719    
720            protected String[] getAllowedFileExtensions(
721                            PortletConfig portletConfig, PortletRequest portletRequest,
722                            PortletResponse portletResponse)
723                    throws PortalException, SystemException {
724    
725                    String portletName = portletConfig.getPortletName();
726    
727                    if (!portletName.equals(PortletKeys.MEDIA_GALLERY_DISPLAY)) {
728                            return PrefsPropsUtil.getStringArray(
729                                    PropsKeys.DL_FILE_EXTENSIONS, StringPool.COMMA);
730                    }
731                    else {
732                            PortletPreferences portletPreferences = getStrictPortletSetup(
733                                    portletRequest);
734    
735                            if (portletPreferences == null) {
736                                    portletPreferences = portletRequest.getPreferences();
737                            }
738    
739                            Set<String> extensions = new HashSet<String>();
740    
741                            String[] mimeTypes = DLUtil.getMediaGalleryMimeTypes(
742                                    portletPreferences, portletRequest);
743    
744                            for (String mimeType : mimeTypes) {
745                                    extensions.addAll(MimeTypesUtil.getExtensions(mimeType));
746                            }
747    
748                            return extensions.toArray(new String[extensions.size()]);
749                    }
750            }
751    
752            protected String getSaveAndContinueRedirect(
753                            PortletConfig portletConfig, ActionRequest actionRequest,
754                            FileEntry fileEntry, String redirect)
755                    throws Exception {
756    
757                    ThemeDisplay themeDisplay = (ThemeDisplay)actionRequest.getAttribute(
758                            WebKeys.THEME_DISPLAY);
759    
760                    PortletURLImpl portletURL = new PortletURLImpl(
761                            actionRequest, portletConfig.getPortletName(),
762                            themeDisplay.getPlid(), PortletRequest.RENDER_PHASE);
763    
764                    portletURL.setParameter(
765                            "struts_action", "/document_library/edit_file_entry");
766                    portletURL.setParameter(Constants.CMD, Constants.UPDATE, false);
767                    portletURL.setParameter("redirect", redirect, false);
768    
769                    String referringPortletResource = ParamUtil.getString(
770                            actionRequest, "referringPortletResource");
771    
772                    portletURL.setParameter(
773                            "referringPortletResource", referringPortletResource, false);
774    
775                    portletURL.setParameter(
776                            "groupId", String.valueOf(fileEntry.getGroupId()), false);
777                    portletURL.setParameter(
778                            "fileEntryId", String.valueOf(fileEntry.getFileEntryId()), false);
779                    portletURL.setParameter(
780                            "version", String.valueOf(fileEntry.getVersion()), false);
781                    portletURL.setWindowState(actionRequest.getWindowState());
782    
783                    return portletURL.toString();
784            }
785    
786            protected void handleUploadException(
787                            PortletConfig portletConfig, ActionRequest actionRequest,
788                            ActionResponse actionResponse, String cmd, Exception e)
789                    throws Exception {
790    
791                    if (e instanceof AssetCategoryException ||
792                            e instanceof AssetTagException) {
793    
794                            SessionErrors.add(actionRequest, e.getClass(), e);
795                    }
796                    else if (e instanceof DuplicateFileException ||
797                                     e instanceof DuplicateFolderNameException ||
798                                     e instanceof FileExtensionException ||
799                                     e instanceof FileMimeTypeException ||
800                                     e instanceof FileNameException ||
801                                     e instanceof FileSizeException ||
802                                     e instanceof NoSuchFolderException ||
803                                     e instanceof SourceFileNameException ||
804                                     e instanceof StorageFieldRequiredException) {
805    
806                            if (!cmd.equals(Constants.ADD_DYNAMIC) &&
807                                    !cmd.equals(Constants.ADD_MULTIPLE) &&
808                                    !cmd.equals(Constants.ADD_TEMP)) {
809    
810                                    SessionErrors.add(actionRequest, e.getClass());
811    
812                                    return;
813                            }
814    
815                            if (e instanceof DuplicateFileException ||
816                                    e instanceof FileExtensionException ||
817                                    e instanceof FileNameException ||
818                                    e instanceof FileSizeException) {
819    
820                                    HttpServletResponse response =
821                                            PortalUtil.getHttpServletResponse(actionResponse);
822    
823                                    response.setContentType(ContentTypes.TEXT_HTML);
824                                    response.setStatus(HttpServletResponse.SC_OK);
825    
826                                    String errorMessage = StringPool.BLANK;
827                                    int errorType = 0;
828    
829                                    ThemeDisplay themeDisplay =
830                                            (ThemeDisplay)actionRequest.getAttribute(
831                                                    WebKeys.THEME_DISPLAY);
832    
833                                    if (e instanceof DuplicateFileException) {
834                                            errorMessage = themeDisplay.translate(
835                                                    "please-enter-a-unique-document-name");
836                                            errorType =
837                                                    ServletResponseConstants.SC_DUPLICATE_FILE_EXCEPTION;
838                                    }
839                                    else if (e instanceof FileExtensionException) {
840                                            errorMessage = themeDisplay.translate(
841                                                    "please-enter-a-file-with-a-valid-extension-x",
842                                                    StringUtil.merge(
843                                                            getAllowedFileExtensions(
844                                                                    portletConfig, actionRequest, actionResponse)));
845                                            errorType =
846                                                    ServletResponseConstants.SC_FILE_EXTENSION_EXCEPTION;
847                                    }
848                                    else if (e instanceof FileNameException) {
849                                            errorMessage = themeDisplay.translate(
850                                                    "please-enter-a-file-with-a-valid-file-name");
851                                            errorType = ServletResponseConstants.SC_FILE_NAME_EXCEPTION;
852                                    }
853                                    else if (e instanceof FileSizeException) {
854                                            long fileMaxSize = PrefsPropsUtil.getLong(
855                                                    PropsKeys.DL_FILE_MAX_SIZE);
856    
857                                            if (fileMaxSize == 0) {
858                                                    fileMaxSize = PrefsPropsUtil.getLong(
859                                                            PropsKeys.UPLOAD_SERVLET_REQUEST_IMPL_MAX_SIZE);
860                                            }
861    
862                                            fileMaxSize /= 1024;
863    
864                                            errorMessage = themeDisplay.translate(
865                                                    "please-enter-a-file-with-a-valid-file-size-no-larger" +
866                                                            "-than-x",
867                                                    fileMaxSize);
868    
869                                            errorType = ServletResponseConstants.SC_FILE_SIZE_EXCEPTION;
870                                    }
871    
872                                    JSONObject jsonObject = JSONFactoryUtil.createJSONObject();
873    
874                                    jsonObject.put("message", errorMessage);
875                                    jsonObject.put("status", errorType);
876    
877                                    writeJSON(actionRequest, actionResponse, jsonObject);
878                            }
879    
880                            SessionErrors.add(actionRequest, e.getClass());
881                    }
882                    else if (e instanceof DuplicateLockException ||
883                                     e instanceof InvalidFileVersionException ||
884                                     e instanceof NoSuchFileEntryException ||
885                                     e instanceof PrincipalException) {
886    
887                            if (e instanceof DuplicateLockException) {
888                                    DuplicateLockException dle = (DuplicateLockException)e;
889    
890                                    SessionErrors.add(actionRequest, dle.getClass(), dle.getLock());
891                            }
892                            else {
893                                    SessionErrors.add(actionRequest, e.getClass());
894                            }
895    
896                            setForward(actionRequest, "portlet.document_library.error");
897                    }
898                    else {
899                            throw e;
900                    }
901            }
902    
903            protected void moveFileEntries(
904                            ActionRequest actionRequest, boolean moveFromTrash)
905                    throws Exception {
906    
907                    long[] fileEntryIds = null;
908    
909                    long fileEntryId = ParamUtil.getLong(actionRequest, "fileEntryId");
910    
911                    if (fileEntryId > 0) {
912                            fileEntryIds = new long[] {fileEntryId};
913                    }
914                    else {
915                            fileEntryIds = StringUtil.split(
916                                    ParamUtil.getString(actionRequest, "fileEntryIds"), 0L);
917                    }
918    
919                    long newFolderId = ParamUtil.getLong(actionRequest, "newFolderId");
920    
921                    ServiceContext serviceContext = ServiceContextFactory.getInstance(
922                            DLFileEntry.class.getName(), actionRequest);
923    
924                    for (long moveFileEntryId : fileEntryIds) {
925                            if (moveFromTrash) {
926                                    DLAppServiceUtil.moveFileEntryFromTrash(
927                                            moveFileEntryId, newFolderId, serviceContext);
928                            }
929    
930                            else {
931                                    DLAppServiceUtil.moveFileEntry(
932                                            moveFileEntryId, newFolderId, serviceContext);
933                            }
934                    }
935            }
936    
937            protected void revertFileEntry(ActionRequest actionRequest)
938                    throws Exception {
939    
940                    long fileEntryId = ParamUtil.getLong(actionRequest, "fileEntryId");
941                    String version = ParamUtil.getString(actionRequest, "version");
942    
943                    ServiceContext serviceContext = ServiceContextFactory.getInstance(
944                            DLFileEntry.class.getName(), actionRequest);
945    
946                    DLAppServiceUtil.revertFileEntry(fileEntryId, version, serviceContext);
947            }
948    
949            protected FileEntry updateFileEntry(
950                            PortletConfig portletConfig, ActionRequest actionRequest,
951                            ActionResponse actionResponse)
952                    throws Exception {
953    
954                    UploadPortletRequest uploadPortletRequest =
955                            PortalUtil.getUploadPortletRequest(actionRequest);
956    
957                    ThemeDisplay themeDisplay = (ThemeDisplay)actionRequest.getAttribute(
958                            WebKeys.THEME_DISPLAY);
959    
960                    String cmd = ParamUtil.getString(uploadPortletRequest, Constants.CMD);
961    
962                    long fileEntryId = ParamUtil.getLong(
963                            uploadPortletRequest, "fileEntryId");
964    
965                    long repositoryId = ParamUtil.getLong(
966                            uploadPortletRequest, "repositoryId");
967                    long folderId = ParamUtil.getLong(uploadPortletRequest, "folderId");
968                    String sourceFileName = uploadPortletRequest.getFileName("file");
969                    String title = ParamUtil.getString(uploadPortletRequest, "title");
970                    String description = ParamUtil.getString(
971                            uploadPortletRequest, "description");
972                    String changeLog = ParamUtil.getString(
973                            uploadPortletRequest, "changeLog");
974                    boolean majorVersion = ParamUtil.getBoolean(
975                            uploadPortletRequest, "majorVersion");
976    
977                    if (folderId > 0) {
978                            Folder folder = DLAppServiceUtil.getFolder(folderId);
979    
980                            if (folder.getGroupId() != themeDisplay.getScopeGroupId()) {
981                                    throw new NoSuchFolderException();
982                            }
983                    }
984    
985                    InputStream inputStream = null;
986    
987                    try {
988                            String contentType = uploadPortletRequest.getContentType("file");
989    
990                            long size = uploadPortletRequest.getSize("file");
991    
992                            if ((cmd.equals(Constants.ADD) ||
993                                     cmd.equals(Constants.ADD_DYNAMIC)) &&
994                                    (size == 0)) {
995    
996                                    contentType = MimeTypesUtil.getContentType(title);
997                            }
998    
999                            if (cmd.equals(Constants.ADD) ||
1000                                    cmd.equals(Constants.ADD_DYNAMIC) || (size > 0)) {
1001    
1002                                    String portletName = portletConfig.getPortletName();
1003    
1004                                    if (portletName.equals(PortletKeys.MEDIA_GALLERY_DISPLAY)) {
1005                                            PortletPreferences portletPreferences =
1006                                                    getStrictPortletSetup(actionRequest);
1007    
1008                                            if (portletPreferences == null) {
1009                                                    portletPreferences = actionRequest.getPreferences();
1010                                            }
1011    
1012                                            String[] mimeTypes = DLUtil.getMediaGalleryMimeTypes(
1013                                                    portletPreferences, actionRequest);
1014    
1015                                            if (Arrays.binarySearch(mimeTypes, contentType) < 0) {
1016                                                    throw new FileMimeTypeException(contentType);
1017                                            }
1018                                    }
1019                            }
1020    
1021                            inputStream = uploadPortletRequest.getFileAsStream("file");
1022    
1023                            ServiceContext serviceContext = ServiceContextFactory.getInstance(
1024                                    DLFileEntry.class.getName(), uploadPortletRequest);
1025    
1026                            FileEntry fileEntry = null;
1027    
1028                            if (cmd.equals(Constants.ADD) ||
1029                                    cmd.equals(Constants.ADD_DYNAMIC)) {
1030    
1031                                    // Add file entry
1032    
1033                                    fileEntry = DLAppServiceUtil.addFileEntry(
1034                                            repositoryId, folderId, sourceFileName, contentType, title,
1035                                            description, changeLog, inputStream, size, serviceContext);
1036    
1037                                    AssetPublisherUtil.addAndStoreSelection(
1038                                            actionRequest, DLFileEntry.class.getName(),
1039                                            fileEntry.getFileEntryId(), -1);
1040    
1041                                    if (cmd.equals(Constants.ADD_DYNAMIC)) {
1042                                            JSONObject jsonObject = JSONFactoryUtil.createJSONObject();
1043    
1044                                            jsonObject.put("fileEntryId", fileEntry.getFileEntryId());
1045    
1046                                            writeJSON(actionRequest, actionResponse, jsonObject);
1047                                    }
1048                            }
1049                            else if (cmd.equals(Constants.UPDATE_AND_CHECKIN)) {
1050    
1051                                    // Update file entry and checkin
1052    
1053                                    fileEntry = DLAppServiceUtil.updateFileEntryAndCheckIn(
1054                                            fileEntryId, sourceFileName, contentType, title,
1055                                            description, changeLog, majorVersion, inputStream, size,
1056                                            serviceContext);
1057                            }
1058                            else {
1059    
1060                                    // Update file entry
1061    
1062                                    fileEntry = DLAppServiceUtil.updateFileEntry(
1063                                            fileEntryId, sourceFileName, contentType, title,
1064                                            description, changeLog, majorVersion, inputStream, size,
1065                                            serviceContext);
1066                            }
1067    
1068                            AssetPublisherUtil.addRecentFolderId(
1069                                    actionRequest, DLFileEntry.class.getName(), folderId);
1070    
1071                            return fileEntry;
1072                    }
1073                    catch (Exception e) {
1074                            UploadException uploadException =
1075                                    (UploadException)actionRequest.getAttribute(
1076                                            WebKeys.UPLOAD_EXCEPTION);
1077    
1078                            if ((uploadException != null) &&
1079                                    uploadException.isExceededSizeLimit()) {
1080    
1081                                    throw new FileSizeException(uploadException.getCause());
1082                            }
1083    
1084                            throw e;
1085                    }
1086                    finally {
1087                            StreamUtil.cleanUp(inputStream);
1088                    }
1089            }
1090    
1091            private static final String _TEMP_FOLDER_NAME =
1092                    EditFileEntryAction.class.getName();
1093    
1094    }