1   /**
2    * Copyright (c) 2000-2009 Liferay, Inc. All rights reserved.
3    *
4    * Permission is hereby granted, free of charge, to any person obtaining a copy
5    * of this software and associated documentation files (the "Software"), to deal
6    * in the Software without restriction, including without limitation the rights
7    * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8    * copies of the Software, and to permit persons to whom the Software is
9    * furnished to do so, subject to the following conditions:
10   *
11   * The above copyright notice and this permission notice shall be included in
12   * all copies or substantial portions of the Software.
13   *
14   * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15   * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16   * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17   * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18   * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19   * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20   * SOFTWARE.
21   */
22  
23  package com.liferay.portlet.imagegallery.webdav;
24  
25  import com.liferay.documentlibrary.DuplicateFileException;
26  import com.liferay.portal.PortalException;
27  import com.liferay.portal.SystemException;
28  import com.liferay.portal.kernel.log.Log;
29  import com.liferay.portal.kernel.log.LogFactoryUtil;
30  import com.liferay.portal.kernel.util.FileUtil;
31  import com.liferay.portal.kernel.util.StringPool;
32  import com.liferay.portal.kernel.util.StringUtil;
33  import com.liferay.portal.kernel.util.Validator;
34  import com.liferay.portal.security.auth.PrincipalException;
35  import com.liferay.portal.service.ServiceContext;
36  import com.liferay.portal.util.ContentTypeUtil;
37  import com.liferay.portal.webdav.BaseResourceImpl;
38  import com.liferay.portal.webdav.BaseWebDAVStorageImpl;
39  import com.liferay.portal.webdav.Resource;
40  import com.liferay.portal.webdav.Status;
41  import com.liferay.portal.webdav.WebDAVException;
42  import com.liferay.portal.webdav.WebDAVRequest;
43  import com.liferay.portal.webdav.WebDAVUtil;
44  import com.liferay.portlet.imagegallery.DuplicateFolderNameException;
45  import com.liferay.portlet.imagegallery.NoSuchFolderException;
46  import com.liferay.portlet.imagegallery.NoSuchImageException;
47  import com.liferay.portlet.imagegallery.model.IGFolder;
48  import com.liferay.portlet.imagegallery.model.IGImage;
49  import com.liferay.portlet.imagegallery.model.impl.IGFolderImpl;
50  import com.liferay.portlet.imagegallery.service.IGFolderServiceUtil;
51  import com.liferay.portlet.imagegallery.service.IGImageServiceUtil;
52  import com.liferay.portlet.tags.service.TagsEntryLocalServiceUtil;
53  
54  import java.io.File;
55  import java.io.InputStream;
56  
57  import java.util.ArrayList;
58  import java.util.List;
59  
60  import javax.servlet.http.HttpServletRequest;
61  import javax.servlet.http.HttpServletResponse;
62  
63  /**
64   * <a href="IGWebDAVStorageImpl.java.html"><b><i>View Source</i></b></a>
65   *
66   * @author Alexander Chow
67   *
68   */
69  public class IGWebDAVStorageImpl extends BaseWebDAVStorageImpl {
70  
71      public int copyCollectionResource(
72              WebDAVRequest webDavRequest, Resource resource, String destination,
73              boolean overwrite, long depth)
74          throws WebDAVException {
75  
76          try {
77              String[] destinationArray = WebDAVUtil.getPathArray(
78                  destination, true);
79  
80              long parentFolderId = IGFolderImpl.DEFAULT_PARENT_FOLDER_ID;
81  
82              try {
83                  parentFolderId = getParentFolderId(destinationArray);
84              }
85              catch (NoSuchFolderException nsfe) {
86                  return HttpServletResponse.SC_CONFLICT;
87              }
88  
89              IGFolder folder = (IGFolder)resource.getModel();
90  
91              long groupId = WebDAVUtil.getGroupId(destination);
92              String name = WebDAVUtil.getResourceName(destinationArray);
93              String description = folder.getDescription();
94              boolean addCommunityPermissions = true;
95              boolean addGuestPermissions = true;
96  
97              int status = HttpServletResponse.SC_CREATED;
98  
99              if (overwrite) {
100                 if (deleteResource(groupId, parentFolderId, name)) {
101                     status = HttpServletResponse.SC_NO_CONTENT;
102                 }
103             }
104 
105             ServiceContext serviceContext = new ServiceContext();
106 
107             serviceContext.setAddCommunityPermissions(addCommunityPermissions);
108             serviceContext.setAddGuestPermissions(addGuestPermissions);
109             serviceContext.setScopeGroupId(groupId);
110 
111             if (depth == 0) {
112                 IGFolderServiceUtil.addFolder(
113                     parentFolderId, name, description, serviceContext);
114             }
115             else {
116                 IGFolderServiceUtil.copyFolder(
117                     folder.getFolderId(), parentFolderId, name, description,
118                     serviceContext);
119             }
120 
121             return status;
122         }
123         catch (DuplicateFolderNameException dfne) {
124             return HttpServletResponse.SC_PRECONDITION_FAILED;
125         }
126         catch (PrincipalException pe) {
127             return HttpServletResponse.SC_FORBIDDEN;
128         }
129         catch (Exception e) {
130             throw new WebDAVException(e);
131         }
132     }
133 
134     public int copySimpleResource(
135             WebDAVRequest webDavRequest, Resource resource, String destination,
136             boolean overwrite)
137         throws WebDAVException {
138 
139         File file = null;
140 
141         try {
142             String[] destinationArray = WebDAVUtil.getPathArray(
143                 destination, true);
144 
145             long parentFolderId = IGFolderImpl.DEFAULT_PARENT_FOLDER_ID;
146 
147             try {
148                 parentFolderId = getParentFolderId(destinationArray);
149             }
150             catch (NoSuchFolderException nsfe) {
151                 return HttpServletResponse.SC_CONFLICT;
152             }
153 
154             IGImage image = (IGImage)resource.getModel();
155 
156             long groupId = WebDAVUtil.getGroupId(destination);
157             String name = WebDAVUtil.getResourceName(destinationArray);
158             String description = image.getDescription();
159             String contentType = ContentTypeUtil.getContentType(
160                 image.getNameWithExtension());
161 
162             file = FileUtil.createTempFile(image.getImageType());
163 
164             InputStream is = resource.getContentAsStream();
165 
166             FileUtil.write(file, is);
167 
168             ServiceContext serviceContext = new ServiceContext();
169 
170             serviceContext.setAddCommunityPermissions(true);
171             serviceContext.setAddGuestPermissions(true);
172 
173             int status = HttpServletResponse.SC_CREATED;
174 
175             if (overwrite) {
176                 if (deleteResource(groupId, parentFolderId, name)) {
177                     status = HttpServletResponse.SC_NO_CONTENT;
178                 }
179             }
180 
181             IGImageServiceUtil.addImage(
182                 parentFolderId, name, description, file, contentType,
183                 serviceContext);
184 
185             return status;
186         }
187         catch (DuplicateFolderNameException dfne) {
188             return HttpServletResponse.SC_PRECONDITION_FAILED;
189         }
190         catch (DuplicateFileException dfe) {
191             return HttpServletResponse.SC_PRECONDITION_FAILED;
192         }
193         catch (PrincipalException pe) {
194             return HttpServletResponse.SC_FORBIDDEN;
195         }
196         catch (Exception e) {
197             throw new WebDAVException(e);
198         }
199         finally {
200             if (file != null) {
201                 file.delete();
202             }
203         }
204     }
205 
206     public int deleteResource(WebDAVRequest webDavRequest)
207         throws WebDAVException {
208 
209         try {
210             Resource resource = getResource(webDavRequest);
211 
212             if (resource == null) {
213                 return HttpServletResponse.SC_NOT_FOUND;
214             }
215 
216             Object model = resource.getModel();
217 
218             if (model instanceof IGFolder) {
219                 IGFolder folder = (IGFolder)model;
220 
221                 IGFolderServiceUtil.deleteFolder(folder.getFolderId());
222             }
223             else {
224                 IGImage image = (IGImage)model;
225 
226                 IGImageServiceUtil.deleteImage(image.getImageId());
227             }
228 
229             return HttpServletResponse.SC_NO_CONTENT;
230         }
231         catch (PrincipalException pe) {
232             return HttpServletResponse.SC_FORBIDDEN;
233         }
234         catch (Exception e) {
235             throw new WebDAVException(e);
236         }
237     }
238 
239     public Resource getResource(WebDAVRequest webDavRequest)
240         throws WebDAVException {
241 
242         try {
243             String[] pathArray = webDavRequest.getPathArray();
244 
245             long parentFolderId = getParentFolderId(pathArray);
246             String name = WebDAVUtil.getResourceName(pathArray);
247 
248             if (Validator.isNull(name)) {
249                 String path = getRootPath() + webDavRequest.getPath();
250 
251                 return new BaseResourceImpl(path, StringPool.BLANK, getToken());
252             }
253 
254             try {
255                 IGFolder folder = IGFolderServiceUtil.getFolder(
256                     webDavRequest.getGroupId(), parentFolderId, name);
257 
258                 if ((folder.getParentFolderId() != parentFolderId) ||
259                     (webDavRequest.getGroupId() != folder.getGroupId())) {
260 
261                     throw new NoSuchFolderException();
262                 }
263 
264                 return toResource(webDavRequest, folder, false);
265             }
266             catch (NoSuchFolderException nsfe) {
267                 try {
268                     IGImage image =
269                         IGImageServiceUtil.
270                             getImageByFolderIdAndNameWithExtension(
271                                 parentFolderId, name);
272 
273                     return toResource(webDavRequest, image, false);
274                 }
275                 catch (NoSuchImageException nsie) {
276                     return null;
277                 }
278             }
279         }
280         catch (Exception e) {
281             throw new WebDAVException(e);
282         }
283     }
284 
285     public List<Resource> getResources(WebDAVRequest webDavRequest)
286         throws WebDAVException {
287 
288         try {
289             long folderId = getFolderId(webDavRequest.getPathArray());
290 
291             List<Resource> folders = getFolders(webDavRequest, folderId);
292             List<Resource> images = getImages(webDavRequest, folderId);
293 
294             List<Resource> resources = new ArrayList<Resource>(
295                 folders.size() + images.size());
296 
297             resources.addAll(folders);
298             resources.addAll(images);
299 
300             return resources;
301         }
302         catch (Exception e) {
303             throw new WebDAVException(e);
304         }
305     }
306 
307     public Status makeCollection(WebDAVRequest webDavRequest)
308         throws WebDAVException {
309 
310         try {
311             HttpServletRequest request = webDavRequest.getHttpServletRequest();
312 
313             if (request.getContentLength() > 0) {
314                 return new Status(
315                     HttpServletResponse.SC_UNSUPPORTED_MEDIA_TYPE);
316             }
317 
318             String[] pathArray = webDavRequest.getPathArray();
319 
320             long parentFolderId = getParentFolderId(pathArray);
321             String name = WebDAVUtil.getResourceName(pathArray);
322             String description = StringPool.BLANK;
323 
324             ServiceContext serviceContext = new ServiceContext();
325 
326             serviceContext.setAddCommunityPermissions(true);
327             serviceContext.setAddGuestPermissions(true);
328             serviceContext.setPlid(getPlid(webDavRequest.getGroupId()));
329             serviceContext.setScopeGroupId(webDavRequest.getGroupId());
330 
331             IGFolderServiceUtil.addFolder(
332                 parentFolderId, name, description, serviceContext);
333 
334             String location = StringUtil.merge(pathArray, StringPool.SLASH);
335 
336             return new Status(location, HttpServletResponse.SC_CREATED);
337         }
338         catch (DuplicateFolderNameException dfne) {
339             return new Status(HttpServletResponse.SC_METHOD_NOT_ALLOWED);
340         }
341         catch (NoSuchFolderException nsfe) {
342             return new Status(HttpServletResponse.SC_CONFLICT);
343         }
344         catch (PrincipalException pe) {
345             return new Status(HttpServletResponse.SC_FORBIDDEN);
346         }
347         catch (Exception e) {
348             throw new WebDAVException(e);
349         }
350     }
351 
352     public int moveCollectionResource(
353             WebDAVRequest webDavRequest, Resource resource, String destination,
354             boolean overwrite)
355         throws WebDAVException {
356 
357         try {
358             String[] destinationArray = WebDAVUtil.getPathArray(
359                 destination, true);
360 
361             IGFolder folder = (IGFolder)resource.getModel();
362 
363             long groupId = WebDAVUtil.getGroupId(destinationArray);
364             long folderId = folder.getFolderId();
365             long parentFolderId = getParentFolderId(destinationArray);
366             String name = WebDAVUtil.getResourceName(destinationArray);
367             String description = folder.getDescription();
368 
369             int status = HttpServletResponse.SC_CREATED;
370 
371             if (overwrite) {
372                 if (deleteResource(groupId, parentFolderId, name)) {
373                     status = HttpServletResponse.SC_NO_CONTENT;
374                 }
375             }
376 
377             IGFolderServiceUtil.updateFolder(
378                 folderId, parentFolderId, name, description, false);
379 
380             return status;
381         }
382         catch (PrincipalException pe) {
383             return HttpServletResponse.SC_FORBIDDEN;
384         }
385         catch (DuplicateFolderNameException dfne) {
386             return HttpServletResponse.SC_PRECONDITION_FAILED;
387         }
388         catch (Exception e) {
389             throw new WebDAVException(e);
390         }
391     }
392 
393     public int moveSimpleResource(
394             WebDAVRequest webDavRequest, Resource resource, String destination,
395             boolean overwrite)
396         throws WebDAVException {
397 
398         try {
399             String[] destinationArray = WebDAVUtil.getPathArray(
400                 destination, true);
401 
402             IGImage image = (IGImage)resource.getModel();
403 
404             long groupId = WebDAVUtil.getGroupId(destinationArray);
405             long parentFolderId = getParentFolderId(destinationArray);
406             String name = WebDAVUtil.getResourceName(destinationArray);
407             String description = image.getDescription();
408             File file = null;
409             String contentType = null;
410 
411             ServiceContext serviceContext = new ServiceContext();
412 
413             int status = HttpServletResponse.SC_CREATED;
414 
415             if (overwrite) {
416                 if (deleteResource(groupId, parentFolderId, name)) {
417                     status = HttpServletResponse.SC_NO_CONTENT;
418                 }
419             }
420 
421             IGImageServiceUtil.updateImage(
422                 image.getImageId(), parentFolderId, name, description, file,
423                 contentType, serviceContext);
424 
425             return status;
426         }
427         catch (PrincipalException pe) {
428             return HttpServletResponse.SC_FORBIDDEN;
429         }
430         catch (DuplicateFileException dfe) {
431             return HttpServletResponse.SC_PRECONDITION_FAILED;
432         }
433         catch (DuplicateFolderNameException dfne) {
434             return HttpServletResponse.SC_PRECONDITION_FAILED;
435         }
436         catch (Exception e) {
437             throw new WebDAVException(e);
438         }
439     }
440 
441     public int putResource(WebDAVRequest webDavRequest) throws WebDAVException {
442         File file = null;
443 
444         try {
445             HttpServletRequest request = webDavRequest.getHttpServletRequest();
446 
447             String[] pathArray = webDavRequest.getPathArray();
448 
449             long parentFolderId = getParentFolderId(pathArray);
450             String name = WebDAVUtil.getResourceName(pathArray);
451             String description = StringPool.BLANK;
452 
453             file = FileUtil.createTempFile(FileUtil.getExtension(name));
454 
455             FileUtil.write(file, request.getInputStream());
456 
457             String contentType = ContentTypeUtil.getContentType(name);
458 
459             ServiceContext serviceContext = new ServiceContext();
460 
461             serviceContext.setAddCommunityPermissions(true);
462             serviceContext.setAddGuestPermissions(true);
463 
464             try {
465                 IGImage image =
466                     IGImageServiceUtil.getImageByFolderIdAndNameWithExtension(
467                         parentFolderId, name);
468 
469                 long imageId = image.getImageId();
470 
471                 description = image.getDescription();
472                 String[] tagsEntries = TagsEntryLocalServiceUtil.getEntryNames(
473                     IGImage.class.getName(), imageId);
474 
475                 serviceContext.setTagsEntries(tagsEntries);
476 
477                 IGImageServiceUtil.updateImage(
478                     imageId, parentFolderId, name, description, file,
479                     contentType, serviceContext);
480             }
481             catch (NoSuchImageException nsie) {
482                 IGImageServiceUtil.addImage(
483                     parentFolderId, name, description, file, contentType,
484                     serviceContext);
485             }
486 
487             return HttpServletResponse.SC_CREATED;
488         }
489         catch (PrincipalException pe) {
490             return HttpServletResponse.SC_FORBIDDEN;
491         }
492         catch (PortalException pe) {
493             if (_log.isWarnEnabled()) {
494                 _log.warn(pe, pe);
495             }
496 
497             return HttpServletResponse.SC_CONFLICT;
498         }
499         catch (Exception e) {
500             throw new WebDAVException(e);
501         }
502         finally {
503             if (file != null) {
504                 file.delete();
505             }
506         }
507     }
508 
509     protected boolean deleteResource(
510             long groupId, long parentFolderId, String name)
511         throws PortalException, SystemException {
512 
513         try {
514             IGFolder folder = IGFolderServiceUtil.getFolder(
515                 groupId, parentFolderId, name);
516 
517             IGFolderServiceUtil.deleteFolder(folder.getFolderId());
518 
519             return true;
520         }
521         catch (NoSuchFolderException nsfe) {
522             if (name.indexOf(StringPool.PERIOD) == -1) {
523                 return false;
524             }
525 
526             try {
527                 IGImageServiceUtil.deleteImageByFolderIdAndNameWithExtension(
528                     parentFolderId, name);
529 
530                 return true;
531             }
532             catch (NoSuchImageException nsie) {
533             }
534         }
535 
536         return false;
537     }
538 
539     protected List<Resource> getFolders(
540             WebDAVRequest webDavRequest, long parentFolderId)
541         throws Exception {
542 
543         List<Resource> resources = new ArrayList<Resource>();
544 
545         long groupId = webDavRequest.getGroupId();
546 
547         List<IGFolder> folders = IGFolderServiceUtil.getFolders(
548             groupId, parentFolderId);
549 
550         for (IGFolder folder : folders) {
551             Resource resource = toResource(webDavRequest, folder, true);
552 
553             resources.add(resource);
554         }
555 
556         return resources;
557     }
558 
559     protected List<Resource> getImages(
560             WebDAVRequest webDavRequest, long parentFolderId)
561         throws Exception {
562 
563         List<Resource> resources = new ArrayList<Resource>();
564 
565         List<IGImage> images = IGImageServiceUtil.getImages(parentFolderId);
566 
567         for (IGImage image : images) {
568             Resource resource = toResource(webDavRequest, image, true);
569 
570             resources.add(resource);
571         }
572 
573         return resources;
574     }
575 
576     protected long getFolderId(String[] pathArray) throws Exception {
577         return getFolderId(pathArray, false);
578     }
579 
580     protected long getFolderId(String[] pathArray, boolean parent)
581         throws Exception {
582 
583         long folderId = IGFolderImpl.DEFAULT_PARENT_FOLDER_ID;
584 
585         if (pathArray.length <= 2) {
586             return folderId;
587         }
588         else {
589             long groupId = WebDAVUtil.getGroupId(pathArray);
590 
591             int x = pathArray.length;
592 
593             if (parent) {
594                 x--;
595             }
596 
597             for (int i = 3; i < x; i++) {
598                 String name = pathArray[i];
599 
600                 IGFolder folder = IGFolderServiceUtil.getFolder(
601                     groupId, folderId, name);
602 
603                 if (groupId == folder.getGroupId()) {
604                     folderId = folder.getFolderId();
605                 }
606             }
607         }
608 
609         return folderId;
610     }
611 
612     protected long getParentFolderId(String[] pathArray) throws Exception {
613         return getFolderId(pathArray, true);
614     }
615 
616     protected Resource toResource(
617         WebDAVRequest webDavRequest, IGImage image, boolean appendPath) {
618 
619         String parentPath = getRootPath() + webDavRequest.getPath();
620         String name = StringPool.BLANK;
621 
622         if (appendPath) {
623             name = image.getNameWithExtension();
624         }
625 
626         return new IGImageResourceImpl(image, parentPath, name);
627     }
628 
629     protected Resource toResource(
630         WebDAVRequest webDavRequest, IGFolder folder, boolean appendPath) {
631 
632         String parentPath = getRootPath() + webDavRequest.getPath();
633         String name = StringPool.BLANK;
634 
635         if (appendPath) {
636             name = folder.getName();
637         }
638 
639         Resource resource = new BaseResourceImpl(
640             parentPath, name, folder.getName(), folder.getCreateDate(),
641             folder.getModifiedDate());
642 
643         resource.setModel(folder);
644         resource.setClassName(IGFolder.class.getName());
645         resource.setPrimaryKey(folder.getPrimaryKey());
646 
647         return resource;
648     }
649 
650     private static Log _log = LogFactoryUtil.getLog(IGWebDAVStorageImpl.class);
651 
652 }