1
22
23 package com.liferay.portlet.documentlibrary.webdav;
24
25 import com.liferay.documentlibrary.DuplicateFileException;
26 import com.liferay.lock.DuplicateLockException;
27 import com.liferay.lock.ExpiredLockException;
28 import com.liferay.lock.InvalidLockException;
29 import com.liferay.lock.NoSuchLockException;
30 import com.liferay.lock.model.Lock;
31 import com.liferay.portal.PortalException;
32 import com.liferay.portal.kernel.util.FileUtil;
33 import com.liferay.portal.kernel.util.StringPool;
34 import com.liferay.portal.kernel.util.StringUtil;
35 import com.liferay.portal.kernel.util.Validator;
36 import com.liferay.portal.security.auth.PrincipalException;
37 import com.liferay.portal.webdav.BaseResourceImpl;
38 import com.liferay.portal.webdav.BaseWebDAVStorageImpl;
39 import com.liferay.portal.webdav.LockException;
40 import com.liferay.portal.webdav.Resource;
41 import com.liferay.portal.webdav.Status;
42 import com.liferay.portal.webdav.WebDAVException;
43 import com.liferay.portal.webdav.WebDAVRequest;
44 import com.liferay.portal.webdav.WebDAVUtil;
45 import com.liferay.portlet.documentlibrary.DuplicateFolderNameException;
46 import com.liferay.portlet.documentlibrary.NoSuchFileEntryException;
47 import com.liferay.portlet.documentlibrary.NoSuchFolderException;
48 import com.liferay.portlet.documentlibrary.model.DLFileEntry;
49 import com.liferay.portlet.documentlibrary.model.DLFolder;
50 import com.liferay.portlet.documentlibrary.model.impl.DLFolderImpl;
51 import com.liferay.portlet.documentlibrary.service.DLFileEntryLocalServiceUtil;
52 import com.liferay.portlet.documentlibrary.service.DLFileEntryServiceUtil;
53 import com.liferay.portlet.documentlibrary.service.DLFolderServiceUtil;
54 import com.liferay.portlet.tags.service.TagsEntryLocalServiceUtil;
55
56 import java.io.File;
57 import java.io.InputStream;
58
59 import java.util.ArrayList;
60 import java.util.List;
61
62 import javax.servlet.http.HttpServletRequest;
63 import javax.servlet.http.HttpServletResponse;
64
65 import org.apache.commons.logging.Log;
66 import org.apache.commons.logging.LogFactory;
67
68
75 public class DLWebDAVStorageImpl extends BaseWebDAVStorageImpl {
76
77 public int copyCollectionResource(
78 WebDAVRequest webDavRequest, Resource resource, String destination,
79 boolean overwrite, long depth)
80 throws WebDAVException {
81
82 try {
83 String[] destinationArray = WebDAVUtil.getPathArray(
84 destination, true);
85
86 long parentFolderId = DLFolderImpl.DEFAULT_PARENT_FOLDER_ID;
87
88 try {
89 parentFolderId = getParentFolderId(destinationArray);
90 }
91 catch (NoSuchFolderException nsfe) {
92 return HttpServletResponse.SC_CONFLICT;
93 }
94
95 DLFolder folder = (DLFolder)resource.getModel();
96
97 long groupId = WebDAVUtil.getGroupId(destination);
98 long plid = getPlid(groupId);
99 String name = WebDAVUtil.getResourceName(destinationArray);
100 String description = folder.getDescription();
101 boolean addCommunityPermissions = true;
102 boolean addGuestPermissions = true;
103
104 int status = HttpServletResponse.SC_CREATED;
105
106 if (overwrite) {
107 if (deleteResource(
108 groupId, parentFolderId, name,
109 webDavRequest.getLockUuid())) {
110
111 status = HttpServletResponse.SC_NO_CONTENT;
112 }
113 }
114
115 if (depth == 0) {
116 DLFolderServiceUtil.addFolder(
117 plid, parentFolderId, name, description,
118 addCommunityPermissions, addGuestPermissions);
119 }
120 else {
121 DLFolderServiceUtil.copyFolder(
122 plid, folder.getFolderId(), parentFolderId, name,
123 description, addCommunityPermissions, addGuestPermissions);
124 }
125
126 return status;
127 }
128 catch (DuplicateFolderNameException dfne) {
129 return HttpServletResponse.SC_PRECONDITION_FAILED;
130 }
131 catch (PrincipalException pe) {
132 return HttpServletResponse.SC_FORBIDDEN;
133 }
134 catch (Exception e) {
135 throw new WebDAVException(e);
136 }
137 }
138
139 public int copySimpleResource(
140 WebDAVRequest webDavRequest, Resource resource, String destination,
141 boolean overwrite)
142 throws WebDAVException {
143
144 File file = null;
145
146 try {
147 String[] destinationArray = WebDAVUtil.getPathArray(
148 destination, true);
149
150 long parentFolderId = DLFolderImpl.DEFAULT_PARENT_FOLDER_ID;
151
152 try {
153 parentFolderId = getParentFolderId(destinationArray);
154 }
155 catch (NoSuchFolderException nsfe) {
156 return HttpServletResponse.SC_CONFLICT;
157 }
158
159 DLFileEntry fileEntry = (DLFileEntry)resource.getModel();
160
161 long groupId = WebDAVUtil.getGroupId(destination);
162 long userId = webDavRequest.getUserId();
163 String name = WebDAVUtil.getResourceName(destinationArray);
164 String title = WebDAVUtil.getResourceName(destinationArray);
165 String description = fileEntry.getDescription();
166 String[] tagsEntries = null;
167 String extraSettings = fileEntry.getExtraSettings();
168
169 file = FileUtil.createTempFile(
170 FileUtil.getExtension(fileEntry.getName()));
171
172 InputStream is = DLFileEntryLocalServiceUtil.getFileAsStream(
173 fileEntry.getCompanyId(), userId, fileEntry.getFolderId(),
174 fileEntry.getName());
175
176 FileUtil.write(file, is);
177
178 boolean addCommunityPermissions = true;
179 boolean addGuestPermissions = true;
180
181 int status = HttpServletResponse.SC_CREATED;
182
183 if (overwrite) {
184 if (deleteResource(
185 groupId, parentFolderId, title,
186 webDavRequest.getLockUuid())) {
187
188 status = HttpServletResponse.SC_NO_CONTENT;
189 }
190 }
191
192 DLFileEntryServiceUtil.addFileEntry(
193 parentFolderId, name, title, description, tagsEntries,
194 extraSettings, file, addCommunityPermissions,
195 addGuestPermissions);
196
197 return status;
198 }
199 catch (DuplicateFolderNameException dfne) {
200 return HttpServletResponse.SC_PRECONDITION_FAILED;
201 }
202 catch (DuplicateFileException dfe) {
203 return HttpServletResponse.SC_PRECONDITION_FAILED;
204 }
205 catch (LockException le) {
206 return WebDAVUtil.SC_LOCKED;
207 }
208 catch (PrincipalException pe) {
209 return HttpServletResponse.SC_FORBIDDEN;
210 }
211 catch (Exception e) {
212 throw new WebDAVException(e);
213 }
214 finally {
215 if (file != null) {
216 file.delete();
217 }
218 }
219 }
220
221 public int deleteResource(WebDAVRequest webDavRequest)
222 throws WebDAVException {
223
224 try {
225 Resource resource = getResource(webDavRequest);
226
227 if (resource == null) {
228 return HttpServletResponse.SC_NOT_FOUND;
229 }
230
231 Object model = resource.getModel();
232
233 if (model instanceof DLFolder) {
234 DLFolder folder = (DLFolder)model;
235
236 DLFolderServiceUtil.deleteFolder(folder.getFolderId());
237 }
238 else {
239 DLFileEntry fileEntry = (DLFileEntry)model;
240
241 if (isLocked(fileEntry, webDavRequest.getLockUuid())) {
242 return WebDAVUtil.SC_LOCKED;
243 }
244
245 DLFileEntryServiceUtil.deleteFileEntry(
246 fileEntry.getFolderId(), fileEntry.getName());
247 }
248
249 return HttpServletResponse.SC_NO_CONTENT;
250 }
251 catch (PrincipalException pe) {
252 return HttpServletResponse.SC_FORBIDDEN;
253 }
254 catch (Exception e) {
255 throw new WebDAVException(e);
256 }
257 }
258
259 public Resource getResource(WebDAVRequest webDavRequest)
260 throws WebDAVException {
261
262 try {
263 String[] pathArray = webDavRequest.getPathArray();
264
265 long parentFolderId = getParentFolderId(pathArray);
266 String name = WebDAVUtil.getResourceName(pathArray);
267
268 if (Validator.isNull(name)) {
269 String path = getRootPath() + webDavRequest.getPath();
270
271 return new BaseResourceImpl(path, StringPool.BLANK, getToken());
272 }
273
274 try {
275 DLFolder folder = DLFolderServiceUtil.getFolder(
276 webDavRequest.getGroupId(), parentFolderId, name);
277
278 if ((folder.getParentFolderId() != parentFolderId) ||
279 (webDavRequest.getGroupId() != folder.getGroupId())) {
280
281 throw new NoSuchFolderException();
282 }
283
284 return toResource(webDavRequest, folder, false);
285 }
286 catch (NoSuchFolderException nsfe) {
287 try {
288 String titleWithExtension = name;
289
290 DLFileEntry fileEntry =
291 DLFileEntryServiceUtil.getFileEntryByTitle(
292 parentFolderId, titleWithExtension);
293
294 return toResource(webDavRequest, fileEntry, false);
295 }
296 catch (NoSuchFileEntryException nsfee) {
297 return null;
298 }
299 }
300 }
301 catch (Exception e) {
302 throw new WebDAVException(e);
303 }
304 }
305
306 public List<Resource> getResources(WebDAVRequest webDavRequest)
307 throws WebDAVException {
308
309 try {
310 long folderId = getFolderId(webDavRequest.getPathArray());
311
312 List<Resource> folders = getFolders(webDavRequest, folderId);
313 List<Resource> fileEntries = getFileEntries(
314 webDavRequest, folderId);
315
316 List<Resource> resources = new ArrayList<Resource>(
317 folders.size() + fileEntries.size());
318
319 resources.addAll(folders);
320 resources.addAll(fileEntries);
321
322 return resources;
323 }
324 catch (Exception e) {
325 throw new WebDAVException(e);
326 }
327 }
328
329 public boolean isSupportsClassTwo() {
330 return true;
331 }
332
333 public Lock lockResource(
334 WebDAVRequest webDavRequest, String owner, long timeout)
335 throws WebDAVException {
336
337 Resource resource = getResource(webDavRequest);
338
339 Lock lock = null;
340
341 if (resource instanceof DLFileEntryResourceImpl) {
342 DLFileEntry fileEntry = (DLFileEntry)resource.getModel();
343
344 try {
345 lock = DLFileEntryServiceUtil.lockFileEntry(
346 fileEntry.getFolderId(), fileEntry.getName(), owner,
347 timeout);
348 }
349 catch (Exception e) {
350
351
353 if (!(e instanceof DuplicateLockException)) {
354 throw new WebDAVException(e);
355 }
356 }
357 }
358
359 return lock;
360 }
361
362 public Status makeCollection(WebDAVRequest webDavRequest)
363 throws WebDAVException {
364
365 try {
366 HttpServletRequest request = webDavRequest.getHttpServletRequest();
367
368 if (request.getContentLength() > 0) {
369 return new Status(
370 HttpServletResponse.SC_UNSUPPORTED_MEDIA_TYPE);
371 }
372
373 String[] pathArray = webDavRequest.getPathArray();
374
375 long plid = getPlid(webDavRequest.getGroupId());
376 long parentFolderId = getParentFolderId(pathArray);
377 String name = WebDAVUtil.getResourceName(pathArray);
378 String description = StringPool.BLANK;
379 boolean addCommunityPermissions = true;
380 boolean addGuestPermissions = true;
381
382 DLFolderServiceUtil.addFolder(
383 plid, parentFolderId, name, description,
384 addCommunityPermissions, addGuestPermissions);
385
386 String location = StringUtil.merge(pathArray, StringPool.SLASH);
387
388 return new Status(location, HttpServletResponse.SC_CREATED);
389 }
390 catch (DuplicateFolderNameException dfne) {
391 return new Status(HttpServletResponse.SC_METHOD_NOT_ALLOWED);
392 }
393 catch (NoSuchFolderException nsfe) {
394 return new Status(HttpServletResponse.SC_CONFLICT);
395 }
396 catch (PrincipalException pe) {
397 return new Status(HttpServletResponse.SC_FORBIDDEN);
398 }
399 catch (Exception e) {
400 throw new WebDAVException(e);
401 }
402 }
403
404 public int moveCollectionResource(
405 WebDAVRequest webDavRequest, Resource resource, String destination,
406 boolean overwrite)
407 throws WebDAVException {
408
409 try {
410 String[] destinationArray = WebDAVUtil.getPathArray(
411 destination, true);
412
413 DLFolder folder = (DLFolder)resource.getModel();
414
415 long groupId = WebDAVUtil.getGroupId(destinationArray);
416 long folderId = folder.getFolderId();
417 long parentFolderId = getParentFolderId(destinationArray);
418 String name = WebDAVUtil.getResourceName(destinationArray);
419 String description = folder.getDescription();
420
421 int status = HttpServletResponse.SC_CREATED;
422
423 if (overwrite) {
424 if (deleteResource(
425 groupId, parentFolderId, name,
426 webDavRequest.getLockUuid())) {
427
428 status = HttpServletResponse.SC_NO_CONTENT;
429 }
430 }
431
432 DLFolderServiceUtil.updateFolder(
433 folderId, parentFolderId, name, description);
434
435 return status;
436 }
437 catch (PrincipalException pe) {
438 return HttpServletResponse.SC_FORBIDDEN;
439 }
440 catch (DuplicateFolderNameException dfne) {
441 return HttpServletResponse.SC_PRECONDITION_FAILED;
442 }
443 catch (Exception e) {
444 throw new WebDAVException(e);
445 }
446 }
447
448 public int moveSimpleResource(
449 WebDAVRequest webDavRequest, Resource resource, String destination,
450 boolean overwrite)
451 throws WebDAVException {
452
453 try {
454 String[] destinationArray = WebDAVUtil.getPathArray(
455 destination, true);
456
457 DLFileEntry fileEntry = (DLFileEntry)resource.getModel();
458
459 if (isLocked(fileEntry, webDavRequest.getLockUuid())) {
460 return WebDAVUtil.SC_LOCKED;
461 }
462
463 long groupId = WebDAVUtil.getGroupId(destinationArray);
464 long parentFolderId = getParentFolderId(destinationArray);
465 String name = fileEntry.getName();
466 String sourceFileName = null;
467 String title = WebDAVUtil.getResourceName(destinationArray);
468 String description = fileEntry.getDescription();
469 String[] tagsEntries = null;
470 String extraSettings = fileEntry.getExtraSettings();
471 byte[] bytes = null;
472
473 int status = HttpServletResponse.SC_CREATED;
474
475 if (overwrite) {
476 if (deleteResource(
477 groupId, parentFolderId, title,
478 webDavRequest.getLockUuid())) {
479
480 status = HttpServletResponse.SC_NO_CONTENT;
481 }
482 }
483
484 DLFileEntryServiceUtil.updateFileEntry(
485 fileEntry.getFolderId(), parentFolderId, name, sourceFileName,
486 title, description, tagsEntries, extraSettings, bytes);
487
488 return status;
489 }
490 catch (PrincipalException pe) {
491 return HttpServletResponse.SC_FORBIDDEN;
492 }
493 catch (DuplicateFileException dfe) {
494 return HttpServletResponse.SC_PRECONDITION_FAILED;
495 }
496 catch (DuplicateFolderNameException dfne) {
497 return HttpServletResponse.SC_PRECONDITION_FAILED;
498 }
499 catch (LockException le) {
500 return WebDAVUtil.SC_LOCKED;
501 }
502 catch (Exception e) {
503 throw new WebDAVException(e);
504 }
505 }
506
507 public int putResource(WebDAVRequest webDavRequest) throws WebDAVException {
508 File file = null;
509
510 try {
511 HttpServletRequest request = webDavRequest.getHttpServletRequest();
512
513 String[] pathArray = webDavRequest.getPathArray();
514
515 long parentFolderId = getParentFolderId(pathArray);
516 String name = WebDAVUtil.getResourceName(pathArray);
517 String title = name;
518 String description = StringPool.BLANK;
519 String[] tagsEntries = null;
520 String extraSettings = StringPool.BLANK;
521 boolean addCommunityPermissions = true;
522 boolean addGuestPermissions = true;
523
524 try {
525 DLFileEntry entry = DLFileEntryServiceUtil.getFileEntryByTitle(
526 parentFolderId, name);
527
528 if (isLocked(entry, webDavRequest.getLockUuid())) {
529 return WebDAVUtil.SC_LOCKED;
530 }
531
532 name = entry.getName();
533 description = entry.getDescription();
534 tagsEntries = TagsEntryLocalServiceUtil.getEntryNames(
535 DLFileEntry.class.getName(), entry.getFileEntryId());
536 extraSettings = entry.getExtraSettings();
537
538 DLFileEntryServiceUtil.updateFileEntry(
539 parentFolderId, parentFolderId, name, title, title,
540 description, tagsEntries, extraSettings,
541 FileUtil.getBytes(request.getInputStream()));
542 }
543 catch (NoSuchFileEntryException nsfee) {
544 file = FileUtil.createTempFile(FileUtil.getExtension(name));
545
546 FileUtil.write(file, request.getInputStream());
547
548 DLFileEntryServiceUtil.addFileEntry(
549 parentFolderId, name, title, description, tagsEntries,
550 extraSettings, file, addCommunityPermissions,
551 addGuestPermissions);
552 }
553
554 return HttpServletResponse.SC_CREATED;
555 }
556 catch (PrincipalException pe) {
557 return HttpServletResponse.SC_FORBIDDEN;
558 }
559 catch (PortalException pe) {
560 if (_log.isWarnEnabled()) {
561 _log.warn(pe, pe);
562 }
563
564 return HttpServletResponse.SC_CONFLICT;
565 }
566 catch (Exception e) {
567 throw new WebDAVException(e);
568 }
569 finally {
570 if (file != null) {
571 file.delete();
572 }
573 }
574 }
575
576 public Lock refreshResourceLock(
577 WebDAVRequest webDavRequest, String uuid, long timeout)
578 throws WebDAVException {
579
580 Resource resource = getResource(webDavRequest);
581
582 Lock lock = null;
583
584 if (resource instanceof DLFileEntryResourceImpl) {
585 try {
586 lock = DLFileEntryServiceUtil.refreshFileEntryLock(
587 uuid, timeout);
588 }
589 catch (Exception e) {
590 throw new WebDAVException(e);
591 }
592 }
593
594 return lock;
595 }
596
597 public boolean unlockResource(WebDAVRequest webDavRequest, String token)
598 throws WebDAVException {
599
600 Resource resource = getResource(webDavRequest);
601
602 try {
603 if (resource instanceof DLFileEntryResourceImpl) {
604 DLFileEntry fileEntry = (DLFileEntry)resource.getModel();
605
606 DLFileEntryServiceUtil.unlockFileEntry(
607 fileEntry.getFolderId(), fileEntry.getName(), token);
608
609 return true;
610 }
611 }
612 catch (Exception e) {
613 if (e instanceof InvalidLockException) {
614 if (_log.isWarnEnabled()) {
615 _log.warn(e.getMessage());
616 }
617 }
618 else {
619 if (_log.isWarnEnabled()) {
620 _log.warn("Unable to unlock file entry", e);
621 }
622 }
623 }
624
625 return false;
626 }
627
628 protected boolean deleteResource(
629 long groupId, long parentFolderId, String name, String lockUuid)
630 throws Exception {
631
632 try {
633 DLFolder folder = DLFolderServiceUtil.getFolder(
634 groupId, parentFolderId, name);
635
636 DLFolderServiceUtil.deleteFolder(folder.getFolderId());
637
638 return true;
639 }
640 catch (NoSuchFolderException nsfe) {
641 try {
642 DLFileEntry fileEntry =
643 DLFileEntryServiceUtil.getFileEntryByTitle(
644 parentFolderId, name);
645
646 if (isLocked(fileEntry, lockUuid)) {
647 throw new LockException();
648 }
649
650 DLFileEntryServiceUtil.deleteFileEntryByTitle(
651 parentFolderId, name);
652
653 return true;
654 }
655 catch (NoSuchFileEntryException nsfee) {
656 }
657 }
658
659 return false;
660 }
661
662 protected List<Resource> getFileEntries(
663 WebDAVRequest webDavRequest, long parentFolderId)
664 throws Exception {
665
666 List<Resource> resources = new ArrayList<Resource>();
667
668 List<DLFileEntry> fileEntries = DLFileEntryServiceUtil.getFileEntries(
669 parentFolderId);
670
671 for (DLFileEntry fileEntry : fileEntries) {
672 Resource resource = toResource(webDavRequest, fileEntry, true);
673
674 resources.add(resource);
675 }
676
677 return resources;
678 }
679
680 protected long getFolderId(String[] pathArray) throws Exception {
681 return getFolderId(pathArray, false);
682 }
683
684 protected long getFolderId(String[] pathArray, boolean parent)
685 throws Exception {
686
687 long folderId = DLFolderImpl.DEFAULT_PARENT_FOLDER_ID;
688
689 if (pathArray.length <= 2) {
690 return folderId;
691 }
692 else {
693 long groupId = WebDAVUtil.getGroupId(pathArray);
694
695 int x = pathArray.length;
696
697 if (parent) {
698 x--;
699 }
700
701 for (int i = 3; i < x; i++) {
702 String name = pathArray[i];
703
704 DLFolder folder = DLFolderServiceUtil.getFolder(
705 groupId, folderId, name);
706
707 if (groupId == folder.getGroupId()) {
708 folderId = folder.getFolderId();
709 }
710 }
711 }
712
713 return folderId;
714 }
715
716 protected List<Resource> getFolders(
717 WebDAVRequest webDavRequest, long parentFolderId)
718 throws Exception {
719
720 List<Resource> resources = new ArrayList<Resource>();
721
722 long groupId = webDavRequest.getGroupId();
723
724 List<DLFolder> folders = DLFolderServiceUtil.getFolders(
725 groupId, parentFolderId);
726
727 for (DLFolder folder : folders) {
728 Resource resource = toResource(webDavRequest, folder, true);
729
730 resources.add(resource);
731 }
732
733 return resources;
734 }
735
736 protected long getParentFolderId(String[] pathArray) throws Exception {
737 return getFolderId(pathArray, true);
738 }
739
740 protected boolean isLocked(DLFileEntry fileEntry, String lockUuid)
741 throws Exception {
742
743 long parentFolderId = fileEntry.getFolderId();
744 String fileName = fileEntry.getName();
745
746 return isLocked(parentFolderId, fileName, lockUuid);
747 }
748
749 protected boolean isLocked(
750 long parentFolderId, String fileName, String lockUuid)
751 throws Exception {
752
753 boolean locked = false;
754
755 try {
756 Lock lock = DLFileEntryServiceUtil.getFileEntryLock(
757 parentFolderId, fileName);
758
759 if (!lock.getUuid().equals(lockUuid)) {
760 locked = true;
761 }
762 }
763 catch (PortalException pe) {
764 if (pe instanceof ExpiredLockException ||
765 pe instanceof NoSuchLockException) {
766 }
767 else {
768 throw pe;
769 }
770 }
771
772 return locked;
773 }
774
775 protected Resource toResource(
776 WebDAVRequest webDavRequest, DLFileEntry fileEntry,
777 boolean appendPath) {
778
779 String parentPath = getRootPath() + webDavRequest.getPath();
780 String name = StringPool.BLANK;
781
782 if (appendPath) {
783 name = fileEntry.getTitleWithExtension();
784 }
785
786 return new DLFileEntryResourceImpl(
787 webDavRequest, fileEntry, parentPath, name);
788 }
789
790 protected Resource toResource(
791 WebDAVRequest webDavRequest, DLFolder folder, boolean appendPath) {
792
793 String parentPath = getRootPath() + webDavRequest.getPath();
794 String name = StringPool.BLANK;
795
796 if (appendPath) {
797 name = folder.getName();
798 }
799
800 Resource resource = new BaseResourceImpl(
801 parentPath, name, folder.getName(), folder.getCreateDate(),
802 folder.getModifiedDate());
803
804 resource.setModel(folder);
805 resource.setClassName(DLFolder.class.getName());
806 resource.setPrimaryKey(folder.getPrimaryKey());
807
808 return resource;
809 }
810
811 private static Log _log = LogFactory.getLog(DLWebDAVStorageImpl.class);
812
813 }