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