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