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