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