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