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