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