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