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