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