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