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