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