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