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.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.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 parentFolderId = IGFolderConstants.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 = IGFolderConstants.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                 groupId, 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                     long groupId = webDavRequest.getGroupId();
260 
261                     IGImage image =
262                         IGImageServiceUtil.
263                             getImageByFolderIdAndNameWithExtension(
264                                 groupId, parentFolderId, name);
265 
266                     return toResource(webDavRequest, image, false);
267                 }
268                 catch (NoSuchImageException nsie) {
269                     return null;
270                 }
271             }
272         }
273         catch (Exception e) {
274             throw new WebDAVException(e);
275         }
276     }
277 
278     public List<Resource> getResources(WebDAVRequest webDavRequest)
279         throws WebDAVException {
280 
281         try {
282             long folderId = getFolderId(webDavRequest.getPathArray());
283 
284             List<Resource> folders = getFolders(webDavRequest, folderId);
285             List<Resource> images = getImages(webDavRequest, folderId);
286 
287             List<Resource> resources = new ArrayList<Resource>(
288                 folders.size() + images.size());
289 
290             resources.addAll(folders);
291             resources.addAll(images);
292 
293             return resources;
294         }
295         catch (Exception e) {
296             throw new WebDAVException(e);
297         }
298     }
299 
300     public Status makeCollection(WebDAVRequest webDavRequest)
301         throws WebDAVException {
302 
303         try {
304             HttpServletRequest request = webDavRequest.getHttpServletRequest();
305 
306             if (request.getContentLength() > 0) {
307                 return new Status(
308                     HttpServletResponse.SC_UNSUPPORTED_MEDIA_TYPE);
309             }
310 
311             String[] pathArray = webDavRequest.getPathArray();
312 
313             long groupId = webDavRequest.getGroupId();
314             long parentFolderId = getParentFolderId(pathArray);
315             String name = WebDAVUtil.getResourceName(pathArray);
316             String description = StringPool.BLANK;
317 
318             ServiceContext serviceContext = new ServiceContext();
319 
320             serviceContext.setAddCommunityPermissions(
321                 isAddCommunityPermissions(groupId));
322             serviceContext.setAddGuestPermissions(true);
323             serviceContext.setPlid(getPlid(webDavRequest.getGroupId()));
324             serviceContext.setScopeGroupId(webDavRequest.getGroupId());
325 
326             IGFolderServiceUtil.addFolder(
327                 parentFolderId, name, description, serviceContext);
328 
329             String location = StringUtil.merge(pathArray, StringPool.SLASH);
330 
331             return new Status(location, HttpServletResponse.SC_CREATED);
332         }
333         catch (DuplicateFolderNameException dfne) {
334             return new Status(HttpServletResponse.SC_METHOD_NOT_ALLOWED);
335         }
336         catch (NoSuchFolderException nsfe) {
337             return new Status(HttpServletResponse.SC_CONFLICT);
338         }
339         catch (PrincipalException pe) {
340             return new Status(HttpServletResponse.SC_FORBIDDEN);
341         }
342         catch (Exception e) {
343             throw new WebDAVException(e);
344         }
345     }
346 
347     public int moveCollectionResource(
348             WebDAVRequest webDavRequest, Resource resource, String destination,
349             boolean overwrite)
350         throws WebDAVException {
351 
352         try {
353             String[] destinationArray = WebDAVUtil.getPathArray(
354                 destination, true);
355 
356             IGFolder folder = (IGFolder)resource.getModel();
357 
358             long groupId = WebDAVUtil.getGroupId(destinationArray);
359             long folderId = folder.getFolderId();
360             long parentFolderId = getParentFolderId(destinationArray);
361             String name = WebDAVUtil.getResourceName(destinationArray);
362             String description = folder.getDescription();
363 
364             ServiceContext serviceContext = new ServiceContext();
365 
366             int status = HttpServletResponse.SC_CREATED;
367 
368             if (overwrite) {
369                 if (deleteResource(groupId, parentFolderId, name)) {
370                     status = HttpServletResponse.SC_NO_CONTENT;
371                 }
372             }
373 
374             IGFolderServiceUtil.updateFolder(
375                 folderId, parentFolderId, name, description, false,
376                 serviceContext);
377 
378             return status;
379         }
380         catch (PrincipalException pe) {
381             return HttpServletResponse.SC_FORBIDDEN;
382         }
383         catch (DuplicateFolderNameException dfne) {
384             return HttpServletResponse.SC_PRECONDITION_FAILED;
385         }
386         catch (Exception e) {
387             throw new WebDAVException(e);
388         }
389     }
390 
391     public int moveSimpleResource(
392             WebDAVRequest webDavRequest, Resource resource, String destination,
393             boolean overwrite)
394         throws WebDAVException {
395 
396         try {
397             String[] destinationArray = WebDAVUtil.getPathArray(
398                 destination, true);
399 
400             IGImage image = (IGImage)resource.getModel();
401 
402             long groupId = WebDAVUtil.getGroupId(destinationArray);
403             long parentFolderId = getParentFolderId(destinationArray);
404             String name = WebDAVUtil.getResourceName(destinationArray);
405             String description = image.getDescription();
406             File file = null;
407             String contentType = null;
408 
409             ServiceContext serviceContext = new ServiceContext();
410 
411             int status = HttpServletResponse.SC_CREATED;
412 
413             if (overwrite) {
414                 if (deleteResource(groupId, parentFolderId, name)) {
415                     status = HttpServletResponse.SC_NO_CONTENT;
416                 }
417             }
418 
419             IGImageServiceUtil.updateImage(
420                 image.getImageId(), groupId, parentFolderId, name, description,
421                 file, contentType, serviceContext);
422 
423             return status;
424         }
425         catch (PrincipalException pe) {
426             return HttpServletResponse.SC_FORBIDDEN;
427         }
428         catch (DuplicateFileException dfe) {
429             return HttpServletResponse.SC_PRECONDITION_FAILED;
430         }
431         catch (DuplicateFolderNameException dfne) {
432             return HttpServletResponse.SC_PRECONDITION_FAILED;
433         }
434         catch (Exception e) {
435             throw new WebDAVException(e);
436         }
437     }
438 
439     public int putResource(WebDAVRequest webDavRequest) throws WebDAVException {
440         File file = null;
441 
442         try {
443             HttpServletRequest request = webDavRequest.getHttpServletRequest();
444 
445             String[] pathArray = webDavRequest.getPathArray();
446 
447             long groupId = webDavRequest.getGroupId();
448             long parentFolderId = getParentFolderId(pathArray);
449             String name = WebDAVUtil.getResourceName(pathArray);
450             String description = StringPool.BLANK;
451 
452             file = FileUtil.createTempFile(FileUtil.getExtension(name));
453 
454             FileUtil.write(file, request.getInputStream());
455 
456             String contentType = MimeTypesUtil.getContentType(name);
457 
458             ServiceContext serviceContext = new ServiceContext();
459 
460             serviceContext.setAddCommunityPermissions(
461                 isAddCommunityPermissions(groupId));
462             serviceContext.setAddGuestPermissions(true);
463 
464             try {
465                 IGImage image =
466                     IGImageServiceUtil.getImageByFolderIdAndNameWithExtension(
467                         groupId, parentFolderId, name);
468 
469                 long imageId = image.getImageId();
470 
471                 description = image.getDescription();
472 
473                 String[] assetTagNames = AssetTagLocalServiceUtil.getTagNames(
474                     IGImage.class.getName(), imageId);
475 
476                 serviceContext.setAssetTagNames(assetTagNames);
477 
478                 IGImageServiceUtil.updateImage(
479                     imageId, groupId, parentFolderId, name, description, file,
480                     contentType, serviceContext);
481             }
482             catch (NoSuchImageException nsie) {
483                 IGImageServiceUtil.addImage(
484                     groupId, parentFolderId, name, description, file,
485                     contentType, serviceContext);
486             }
487 
488             return HttpServletResponse.SC_CREATED;
489         }
490         catch (PrincipalException pe) {
491             return HttpServletResponse.SC_FORBIDDEN;
492         }
493         catch (PortalException pe) {
494             if (_log.isWarnEnabled()) {
495                 _log.warn(pe, pe);
496             }
497 
498             return HttpServletResponse.SC_CONFLICT;
499         }
500         catch (Exception e) {
501             throw new WebDAVException(e);
502         }
503         finally {
504             if (file != null) {
505                 file.delete();
506             }
507         }
508     }
509 
510     protected boolean deleteResource(
511             long groupId, long parentFolderId, String name)
512         throws PortalException, SystemException {
513 
514         try {
515             IGFolder folder = IGFolderServiceUtil.getFolder(
516                 groupId, parentFolderId, name);
517 
518             IGFolderServiceUtil.deleteFolder(folder.getFolderId());
519 
520             return true;
521         }
522         catch (NoSuchFolderException nsfe) {
523             if (name.indexOf(StringPool.PERIOD) == -1) {
524                 return false;
525             }
526 
527             try {
528                 IGImageServiceUtil.deleteImageByFolderIdAndNameWithExtension(
529                     groupId, parentFolderId, name);
530 
531                 return true;
532             }
533             catch (NoSuchImageException nsie) {
534             }
535         }
536 
537         return false;
538     }
539 
540     protected List<Resource> getFolders(
541             WebDAVRequest webDavRequest, long parentFolderId)
542         throws Exception {
543 
544         List<Resource> resources = new ArrayList<Resource>();
545 
546         long groupId = webDavRequest.getGroupId();
547 
548         List<IGFolder> folders = IGFolderServiceUtil.getFolders(
549             groupId, parentFolderId);
550 
551         for (IGFolder folder : folders) {
552             Resource resource = toResource(webDavRequest, folder, true);
553 
554             resources.add(resource);
555         }
556 
557         return resources;
558     }
559 
560     protected List<Resource> getImages(
561             WebDAVRequest webDavRequest, long parentFolderId)
562         throws Exception {
563 
564         long groupId = webDavRequest.getGroupId();
565 
566         List<Resource> resources = new ArrayList<Resource>();
567 
568         List<IGImage> images = IGImageServiceUtil.getImages(
569             groupId, parentFolderId);
570 
571         for (IGImage image : images) {
572             Resource resource = toResource(webDavRequest, image, true);
573 
574             resources.add(resource);
575         }
576 
577         return resources;
578     }
579 
580     protected long getFolderId(String[] pathArray) throws Exception {
581         return getFolderId(pathArray, false);
582     }
583 
584     protected long getFolderId(String[] pathArray, boolean parent)
585         throws Exception {
586 
587         long folderId = IGFolderConstants.DEFAULT_PARENT_FOLDER_ID;
588 
589         if (pathArray.length <= 2) {
590             return folderId;
591         }
592         else {
593             long groupId = WebDAVUtil.getGroupId(pathArray);
594 
595             int x = pathArray.length;
596 
597             if (parent) {
598                 x--;
599             }
600 
601             for (int i = 3; i < x; i++) {
602                 String name = pathArray[i];
603 
604                 IGFolder folder = IGFolderServiceUtil.getFolder(
605                     groupId, folderId, name);
606 
607                 if (groupId == folder.getGroupId()) {
608                     folderId = folder.getFolderId();
609                 }
610             }
611         }
612 
613         return folderId;
614     }
615 
616     protected long getParentFolderId(String[] pathArray) throws Exception {
617         return getFolderId(pathArray, true);
618     }
619 
620     protected Resource toResource(
621         WebDAVRequest webDavRequest, IGImage image, boolean appendPath) {
622 
623         String parentPath = getRootPath() + webDavRequest.getPath();
624         String name = StringPool.BLANK;
625 
626         if (appendPath) {
627             name = image.getNameWithExtension();
628         }
629 
630         return new IGImageResourceImpl(image, parentPath, name);
631     }
632 
633     protected Resource toResource(
634         WebDAVRequest webDavRequest, IGFolder folder, boolean appendPath) {
635 
636         String parentPath = getRootPath() + webDavRequest.getPath();
637         String name = StringPool.BLANK;
638 
639         if (appendPath) {
640             name = folder.getName();
641         }
642 
643         Resource resource = new BaseResourceImpl(
644             parentPath, name, folder.getName(), folder.getCreateDate(),
645             folder.getModifiedDate());
646 
647         resource.setModel(folder);
648         resource.setClassName(IGFolder.class.getName());
649         resource.setPrimaryKey(folder.getPrimaryKey());
650 
651         return resource;
652     }
653 
654     private static Log _log = LogFactoryUtil.getLog(IGWebDAVStorageImpl.class);
655 
656 }