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