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.StringPool;
29  import com.liferay.portal.kernel.util.StringUtil;
30  import com.liferay.portal.kernel.util.Validator;
31  import com.liferay.portal.security.auth.PrincipalException;
32  import com.liferay.portal.util.ContentTypeUtil;
33  import com.liferay.portal.webdav.BaseResourceImpl;
34  import com.liferay.portal.webdav.BaseWebDAVStorageImpl;
35  import com.liferay.portal.webdav.Resource;
36  import com.liferay.portal.webdav.Status;
37  import com.liferay.portal.webdav.WebDAVException;
38  import com.liferay.portal.webdav.WebDAVRequest;
39  import com.liferay.portal.webdav.WebDAVUtil;
40  import com.liferay.portlet.imagegallery.DuplicateFolderNameException;
41  import com.liferay.portlet.imagegallery.NoSuchFolderException;
42  import com.liferay.portlet.imagegallery.NoSuchImageException;
43  import com.liferay.portlet.imagegallery.model.IGFolder;
44  import com.liferay.portlet.imagegallery.model.IGImage;
45  import com.liferay.portlet.imagegallery.model.impl.IGFolderImpl;
46  import com.liferay.portlet.imagegallery.service.IGFolderServiceUtil;
47  import com.liferay.portlet.imagegallery.service.IGImageServiceUtil;
48  import com.liferay.util.FileUtil;
49  
50  import java.io.File;
51  import java.io.InputStream;
52  
53  import java.rmi.RemoteException;
54  
55  import java.util.ArrayList;
56  import java.util.List;
57  
58  import javax.servlet.http.HttpServletRequest;
59  import javax.servlet.http.HttpServletResponse;
60  
61  import org.apache.commons.logging.Log;
62  import org.apache.commons.logging.LogFactory;
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 webDavReq, 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 webDavReq, 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 webDavReq) throws WebDAVException {
203         try {
204             Resource resource = getResource(webDavReq);
205 
206             if (resource == null) {
207                 return HttpServletResponse.SC_NOT_FOUND;
208             }
209 
210             Object model = resource.getModel();
211 
212             if (model instanceof IGFolder) {
213                 IGFolder folder = (IGFolder)model;
214 
215                 IGFolderServiceUtil.deleteFolder(folder.getFolderId());
216             }
217             else {
218                 IGImage image = (IGImage)model;
219 
220                 IGImageServiceUtil.deleteImage(image.getImageId());
221             }
222 
223             return HttpServletResponse.SC_NO_CONTENT;
224         }
225         catch (PrincipalException pe) {
226             return HttpServletResponse.SC_FORBIDDEN;
227         }
228         catch (Exception e) {
229             throw new WebDAVException(e);
230         }
231     }
232 
233     public Resource getResource(WebDAVRequest webDavReq)
234         throws WebDAVException {
235 
236         try {
237             String[] pathArray = webDavReq.getPathArray();
238 
239             long parentFolderId = getParentFolderId(pathArray);
240             String name = WebDAVUtil.getResourceName(pathArray);
241 
242             if (Validator.isNull(name)) {
243                 String path = getRootPath() + webDavReq.getPath();
244 
245                 return new BaseResourceImpl(path, StringPool.BLANK, getToken());
246             }
247 
248             try {
249                 IGFolder folder = IGFolderServiceUtil.getFolder(
250                     webDavReq.getGroupId(), parentFolderId, name);
251 
252                 if ((folder.getParentFolderId() != parentFolderId) ||
253                     (webDavReq.getGroupId() != folder.getGroupId())) {
254 
255                     throw new NoSuchFolderException();
256                 }
257 
258                 return toResource(webDavReq, folder, false);
259             }
260             catch (NoSuchFolderException nsfe) {
261                 try {
262                     IGImage image =
263                         IGImageServiceUtil.
264                             getImageByFolderIdAndNameWithExtension(
265                                 parentFolderId, name);
266 
267                     return toResource(webDavReq, image, false);
268                 }
269                 catch (NoSuchImageException nsie) {
270                     return null;
271                 }
272             }
273         }
274         catch (Exception e) {
275             throw new WebDAVException(e);
276         }
277     }
278 
279     public List<Resource> getResources(WebDAVRequest webDavReq)
280         throws WebDAVException {
281 
282         try {
283             long folderId = getFolderId(webDavReq.getPathArray());
284 
285             List<Resource> folders = getFolders(webDavReq, folderId);
286             List<Resource> images = getImages(webDavReq, folderId);
287 
288             List<Resource> resources = new ArrayList<Resource>(
289                 folders.size() + images.size());
290 
291             resources.addAll(folders);
292             resources.addAll(images);
293 
294             return resources;
295         }
296         catch (Exception e) {
297             throw new WebDAVException(e);
298         }
299     }
300 
301     public Status makeCollection(WebDAVRequest webDavReq)
302         throws WebDAVException {
303 
304         try {
305             HttpServletRequest req = webDavReq.getHttpServletRequest();
306 
307             if (req.getContentLength() > 0) {
308                 return new Status(
309                     HttpServletResponse.SC_UNSUPPORTED_MEDIA_TYPE);
310             }
311 
312             String[] pathArray = webDavReq.getPathArray();
313 
314             long plid = getPlid(webDavReq.getGroupId());
315             long parentFolderId = getParentFolderId(pathArray);
316             String name = WebDAVUtil.getResourceName(pathArray);
317             String description = StringPool.BLANK;
318             boolean addCommunityPermissions = true;
319             boolean addGuestPermissions = true;
320 
321             IGFolderServiceUtil.addFolder(
322                 plid, parentFolderId, name, description,
323                 addCommunityPermissions, addGuestPermissions);
324 
325             String location = StringUtil.merge(pathArray, StringPool.SLASH);
326 
327             return new Status(location, HttpServletResponse.SC_CREATED);
328         }
329         catch (DuplicateFolderNameException dfne) {
330             return new Status(HttpServletResponse.SC_METHOD_NOT_ALLOWED);
331         }
332         catch (NoSuchFolderException nsfe) {
333             return new Status(HttpServletResponse.SC_CONFLICT);
334         }
335         catch (PrincipalException pe) {
336             return new Status(HttpServletResponse.SC_FORBIDDEN);
337         }
338         catch (Exception e) {
339             throw new WebDAVException(e);
340         }
341     }
342 
343     public int moveCollectionResource(
344             WebDAVRequest webDavReq, Resource resource, String destination,
345             boolean overwrite)
346         throws WebDAVException {
347 
348         try {
349             String[] destinationArray = WebDAVUtil.getPathArray(
350                 destination, true);
351 
352             IGFolder folder = (IGFolder)resource.getModel();
353 
354             long groupId = WebDAVUtil.getGroupId(destinationArray);
355             long folderId = folder.getFolderId();
356             long parentFolderId = getParentFolderId(destinationArray);
357             String name = WebDAVUtil.getResourceName(destinationArray);
358             String description = folder.getDescription();
359 
360             int status = HttpServletResponse.SC_CREATED;
361 
362             if (overwrite) {
363                 if (deleteResource(groupId, parentFolderId, name)) {
364                     status = HttpServletResponse.SC_NO_CONTENT;
365                 }
366             }
367 
368             IGFolderServiceUtil.updateFolder(
369                 folderId, parentFolderId, name, description, false);
370 
371             return status;
372         }
373         catch (PrincipalException pe) {
374             return HttpServletResponse.SC_FORBIDDEN;
375         }
376         catch (DuplicateFolderNameException dfne) {
377             return HttpServletResponse.SC_PRECONDITION_FAILED;
378         }
379         catch (Exception e) {
380             throw new WebDAVException(e);
381         }
382     }
383 
384     public int moveSimpleResource(
385             WebDAVRequest webDavReq, Resource resource, String destination,
386             boolean overwrite)
387         throws WebDAVException {
388 
389         try {
390             String[] destinationArray = WebDAVUtil.getPathArray(
391                 destination, true);
392 
393             IGImage image = (IGImage)resource.getModel();
394 
395             long groupId = WebDAVUtil.getGroupId(destinationArray);
396             long parentFolderId = getParentFolderId(destinationArray);
397             String name = WebDAVUtil.getResourceName(destinationArray);
398             String description = image.getDescription();
399             File file = null;
400             String contentType = null;
401             String[] tagsEntries = null;
402 
403             int status = HttpServletResponse.SC_CREATED;
404 
405             if (overwrite) {
406                 if (deleteResource(groupId, parentFolderId, name)) {
407                     status = HttpServletResponse.SC_NO_CONTENT;
408                 }
409             }
410 
411             IGImageServiceUtil.updateImage(
412                 image.getImageId(), parentFolderId, name, description, file,
413                 contentType, tagsEntries);
414 
415             return status;
416         }
417         catch (PrincipalException pe) {
418             return HttpServletResponse.SC_FORBIDDEN;
419         }
420         catch (DuplicateFileException dfe) {
421             return HttpServletResponse.SC_PRECONDITION_FAILED;
422         }
423         catch (DuplicateFolderNameException dfne) {
424             return HttpServletResponse.SC_PRECONDITION_FAILED;
425         }
426         catch (Exception e) {
427             throw new WebDAVException(e);
428         }
429     }
430 
431     public int putResource(WebDAVRequest webDavReq) throws WebDAVException {
432         File file = null;
433 
434         try {
435             HttpServletRequest req = webDavReq.getHttpServletRequest();
436 
437             String[] pathArray = webDavReq.getPathArray();
438 
439             long parentFolderId = getParentFolderId(pathArray);
440             String name = WebDAVUtil.getResourceName(pathArray);
441             String description = StringPool.BLANK;
442 
443             file = FileUtil.createTempFile(FileUtil.getExtension(name));
444 
445             FileUtil.write(file, req.getInputStream());
446 
447             String contentType = ContentTypeUtil.getContentType(name);
448             String[] tagsEntries = null;
449             boolean addCommunityPermissions = true;
450             boolean addGuestPermissions = true;
451 
452             IGImageServiceUtil.addImage(
453                 parentFolderId, name, description, file, contentType,
454                 tagsEntries, addCommunityPermissions, addGuestPermissions);
455 
456             return HttpServletResponse.SC_CREATED;
457         }
458         catch (PrincipalException pe) {
459             return HttpServletResponse.SC_FORBIDDEN;
460         }
461         catch (PortalException pe) {
462             if (_log.isWarnEnabled()) {
463                 _log.warn(pe, pe);
464             }
465 
466             return HttpServletResponse.SC_CONFLICT;
467         }
468         catch (Exception e) {
469             throw new WebDAVException(e);
470         }
471         finally {
472             if (file != null) {
473                 file.delete();
474             }
475         }
476     }
477 
478     protected boolean deleteResource(
479             long groupId, long parentFolderId, String name)
480         throws PortalException, SystemException, RemoteException {
481 
482         try {
483             IGFolder folder = IGFolderServiceUtil.getFolder(
484                 groupId, parentFolderId, name);
485 
486             IGFolderServiceUtil.deleteFolder(folder.getFolderId());
487 
488             return true;
489         }
490         catch (NoSuchFolderException nsfe) {
491             if (name.indexOf(StringPool.PERIOD) == -1) {
492                 return false;
493             }
494 
495             try {
496                 IGImageServiceUtil.deleteImageByFolderIdAndNameWithExtension(
497                     parentFolderId, name);
498 
499                 return true;
500             }
501             catch (NoSuchImageException nsie) {
502             }
503         }
504 
505         return false;
506     }
507 
508     protected List<Resource> getFolders(
509             WebDAVRequest webDavReq, long parentFolderId)
510         throws Exception {
511 
512         List<Resource> resources = new ArrayList<Resource>();
513 
514         long groupId = webDavReq.getGroupId();
515 
516         List<IGFolder> folders = IGFolderServiceUtil.getFolders(
517             groupId, parentFolderId);
518 
519         for (IGFolder folder : folders) {
520             Resource resource = toResource(webDavReq, folder, true);
521 
522             resources.add(resource);
523         }
524 
525         return resources;
526     }
527 
528     protected List<Resource> getImages(
529             WebDAVRequest webDavReq, long parentFolderId)
530         throws Exception {
531 
532         List<Resource> resources = new ArrayList<Resource>();
533 
534         List<IGImage> images = IGImageServiceUtil.getImages(parentFolderId);
535 
536         for (IGImage image : images) {
537             Resource resource = toResource(webDavReq, image, true);
538 
539             resources.add(resource);
540         }
541 
542         return resources;
543     }
544 
545     protected long getFolderId(String[] pathArray) throws Exception {
546         return getFolderId(pathArray, false);
547     }
548 
549     protected long getFolderId(String[] pathArray, boolean parent)
550         throws Exception {
551 
552         long folderId = IGFolderImpl.DEFAULT_PARENT_FOLDER_ID;
553 
554         if (pathArray.length <= 2) {
555             return folderId;
556         }
557         else {
558             long groupId = WebDAVUtil.getGroupId(pathArray);
559 
560             int x = pathArray.length;
561 
562             if (parent) {
563                 x--;
564             }
565 
566             for (int i = 3; i < x; i++) {
567                 String name = pathArray[i];
568 
569                 IGFolder folder = IGFolderServiceUtil.getFolder(
570                     groupId, folderId, name);
571 
572                 if (groupId == folder.getGroupId()) {
573                     folderId = folder.getFolderId();
574                 }
575             }
576         }
577 
578         return folderId;
579     }
580 
581     protected long getParentFolderId(String[] pathArray) throws Exception {
582         return getFolderId(pathArray, true);
583     }
584 
585     protected Resource toResource(
586         WebDAVRequest webDavReq, IGImage image, boolean appendPath) {
587 
588         String parentPath = getRootPath() + webDavReq.getPath();
589         String name = StringPool.BLANK;
590 
591         if (appendPath) {
592             name = image.getNameWithExtension();
593         }
594 
595         return new IGImageResourceImpl(image, parentPath, name);
596     }
597 
598     protected Resource toResource(
599         WebDAVRequest webDavReq, IGFolder folder, boolean appendPath) {
600 
601         String parentPath = getRootPath() + webDavReq.getPath();
602         String name = StringPool.BLANK;
603 
604         if (appendPath) {
605             name = folder.getName();
606         }
607 
608         Resource resource = new BaseResourceImpl(
609             parentPath, name, folder.getName(), folder.getCreateDate(),
610             folder.getModifiedDate());
611 
612         resource.setModel(folder);
613         resource.setClassName(IGFolder.class.getName());
614         resource.setPrimaryKey(folder.getPrimaryKey());
615 
616         return resource;
617     }
618 
619     private static Log _log = LogFactory.getLog(IGWebDAVStorageImpl.class);
620 
621 }