1   /**
2    * Copyright (c) 2000-2007 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.documentlibrary.webdav;
24  
25  import com.liferay.portal.PortalException;
26  import com.liferay.portal.kernel.security.permission.ActionKeys;
27  import com.liferay.portal.kernel.util.GetterUtil;
28  import com.liferay.portal.kernel.util.StringPool;
29  import com.liferay.portal.kernel.util.StringUtil;
30  import com.liferay.portal.security.auth.PrincipalException;
31  import com.liferay.portal.webdav.BaseResourceImpl;
32  import com.liferay.portal.webdav.BaseWebDAVStorageImpl;
33  import com.liferay.portal.webdav.Resource;
34  import com.liferay.portal.webdav.Status;
35  import com.liferay.portal.webdav.WebDAVException;
36  import com.liferay.portal.webdav.WebDAVRequest;
37  import com.liferay.portal.webdav.WebDAVUtil;
38  import com.liferay.portlet.documentlibrary.NoSuchFileEntryException;
39  import com.liferay.portlet.documentlibrary.NoSuchFolderException;
40  import com.liferay.portlet.documentlibrary.model.DLFileEntry;
41  import com.liferay.portlet.documentlibrary.model.DLFolder;
42  import com.liferay.portlet.documentlibrary.model.impl.DLFolderImpl;
43  import com.liferay.portlet.documentlibrary.service.DLFileEntryLocalServiceUtil;
44  import com.liferay.portlet.documentlibrary.service.DLFileEntryServiceUtil;
45  import com.liferay.portlet.documentlibrary.service.DLFolderLocalServiceUtil;
46  import com.liferay.portlet.documentlibrary.service.DLFolderServiceUtil;
47  import com.liferay.portlet.documentlibrary.service.permission.DLFolderPermission;
48  import com.liferay.util.FileUtil;
49  import com.liferay.util.PwdGenerator;
50  import com.liferay.util.SystemProperties;
51  import com.liferay.util.Time;
52  
53  import java.io.File;
54  import java.io.InputStream;
55  
56  import java.util.ArrayList;
57  import java.util.Iterator;
58  import java.util.List;
59  
60  import javax.servlet.http.HttpServletRequest;
61  import javax.servlet.http.HttpServletResponse;
62  
63  import org.apache.commons.logging.Log;
64  import org.apache.commons.logging.LogFactory;
65  
66  /**
67   * <a href="DLWebDAVStorageImpl.java.html"><b><i>View Source</i></b></a>
68   *
69   * @author Brian Wing Shun Chan
70   *
71   */
72  public class DLWebDAVStorageImpl extends BaseWebDAVStorageImpl {
73  
74      public Status addFolder(WebDAVRequest webDavReq)
75          throws WebDAVException {
76  
77          try {
78              String[] pathArray = webDavReq.getPathArray();
79  
80              long plid = getPlid(webDavReq.getGroupId());
81              long parentFolderId = getParentFolderId(webDavReq, true);
82              String name = pathArray[pathArray.length - 1];
83              String description = StringPool.BLANK;
84              boolean addCommunityPermissions = true;
85              boolean addGuestPermissions = true;
86  
87              DLFolder folder = DLFolderServiceUtil.addFolder(
88                  plid, parentFolderId, name, description,
89                  addCommunityPermissions, addGuestPermissions);
90  
91              pathArray[pathArray.length - 1] = String.valueOf(
92                  folder.getFolderId());
93  
94              String location = StringUtil.merge(pathArray, StringPool.SLASH);
95  
96              return new Status(location, HttpServletResponse.SC_CREATED);
97          }
98          catch (PrincipalException pe) {
99              return new Status(HttpServletResponse.SC_FORBIDDEN);
100         }
101         catch (Exception e) {
102             throw new WebDAVException(e);
103         }
104     }
105 
106     public int copyResource(WebDAVRequest webDavReq, String destination)
107         throws WebDAVException {
108 
109         File file = null;
110 
111         try {
112             Resource resource = getResource(webDavReq);
113 
114             if (resource == null) {
115                 return HttpServletResponse.SC_NOT_FOUND;
116             }
117 
118             Object model = resource.getModel();
119 
120             String[] destinationArray = WebDAVUtil.getPathArray(destination);
121 
122             if (model instanceof DLFolder) {
123                 DLFolder folder = (DLFolder)model;
124 
125                 long plid = getPlid(webDavReq.getGroupId());
126                 long parentFolderId = GetterUtil.getLong(
127                     destinationArray[destinationArray.length - 2]);
128                 String name = "Copy of " + folder.getName();
129                 String description = folder.getDescription();
130                 boolean addCommunityPermissions = true;
131                 boolean addGuestPermissions = true;
132 
133                 DLFolderServiceUtil.addFolder(
134                     plid, parentFolderId, name, description,
135                     addCommunityPermissions, addGuestPermissions);
136             }
137             else {
138                 DLFileEntry fileEntry = (DLFileEntry)model;
139 
140                 String[] pathArray = webDavReq.getPathArray();
141                 long userId = webDavReq.getUserId();
142 
143                 long folderId = GetterUtil.getLong(
144                     destinationArray[destinationArray.length - 2]);
145                 String name = pathArray[pathArray.length - 1];
146                 String title = "Copy of " + fileEntry.getTitle();
147                 String description = fileEntry.getDescription();
148                 String[] tagsEntries = new String[0];
149                 String extraSettings = fileEntry.getExtraSettings();
150 
151                 String fileName =
152                     SystemProperties.get(SystemProperties.TMP_DIR) +
153                         StringPool.SLASH + Time.getTimestamp() +
154                             PwdGenerator.getPassword(PwdGenerator.KEY2, 8);
155 
156                 file = new File(fileName);
157 
158                 InputStream is = DLFileEntryLocalServiceUtil.getFileAsStream(
159                     fileEntry.getCompanyId(), userId, fileEntry.getFolderId(),
160                     fileEntry.getName());
161 
162                 FileUtil.write(file, is);
163 
164                 if (_log.isDebugEnabled()) {
165                     _log.debug("Writing request to file " + fileName);
166                 }
167 
168                 boolean addCommunityPermissions = true;
169                 boolean addGuestPermissions = true;
170 
171                 DLFolderPermission.check(
172                     webDavReq.getPermissionChecker(), folderId,
173                     ActionKeys.ADD_DOCUMENT);
174 
175                 DLFileEntryLocalServiceUtil.addFileEntry(
176                     userId, folderId, name, title, description, tagsEntries,
177                     extraSettings, file, addCommunityPermissions,
178                     addGuestPermissions);
179             }
180 
181             return HttpServletResponse.SC_CREATED;
182         }
183         catch (PrincipalException pe) {
184             return HttpServletResponse.SC_FORBIDDEN;
185         }
186         catch (Exception e) {
187             throw new WebDAVException(e);
188         }
189         finally {
190             if (file != null) {
191                 file.delete();
192             }
193         }
194     }
195 
196     public int deleteResource(WebDAVRequest webDavReq) throws WebDAVException {
197         try {
198             Resource resource = getResource(webDavReq);
199 
200             if (resource == null) {
201                 return HttpServletResponse.SC_NOT_FOUND;
202             }
203 
204             Object model = resource.getModel();
205 
206             if (model instanceof DLFolder) {
207                 DLFolder folder = (DLFolder)model;
208 
209                 DLFolderServiceUtil.deleteFolder(folder.getFolderId());
210             }
211             else {
212                 DLFileEntry fileEntry = (DLFileEntry)model;
213 
214                 DLFileEntryServiceUtil.deleteFileEntry(
215                     fileEntry.getFolderId(), fileEntry.getName());
216             }
217 
218             return HttpServletResponse.SC_NO_CONTENT;
219         }
220         catch (PrincipalException pe) {
221             return HttpServletResponse.SC_FORBIDDEN;
222         }
223         catch (Exception e) {
224             throw new WebDAVException(e);
225         }
226     }
227 
228     public Resource getResource(WebDAVRequest webDavReq)
229         throws WebDAVException {
230 
231         try {
232             String[] pathArray = webDavReq.getPathArray();
233 
234             DLFolder parentFolder = null;
235 
236             long parentFolderId = DLFolderImpl.DEFAULT_PARENT_FOLDER_ID;
237 
238             for (int i = 2; i < (pathArray.length - 1); i++) {
239                 long folderId = GetterUtil.getLong(pathArray[i]);
240 
241                 parentFolder = DLFolderLocalServiceUtil.getFolder(folderId);
242 
243                 if (webDavReq.getGroupId() == parentFolder.getGroupId()) {
244                     parentFolderId = folderId;
245                 }
246             }
247 
248             String name = pathArray[pathArray.length - 1];
249 
250             try {
251                 long folderId = GetterUtil.getLong(name);
252 
253                 DLFolder folder = DLFolderLocalServiceUtil.getFolder(folderId);
254 
255                 if ((folder.getParentFolderId() != parentFolderId) ||
256                     (webDavReq.getGroupId() != folder.getGroupId())) {
257 
258                     throw new NoSuchFolderException();
259                 }
260 
261                 return toResource(webDavReq, folder, false);
262             }
263             catch (NoSuchFolderException nsfe) {
264                 try {
265                     DLFileEntry fileEntry =
266                         DLFileEntryLocalServiceUtil.getFileEntry(
267                             parentFolderId, name);
268 
269                     return toResource(webDavReq, fileEntry, false);
270                 }
271                 catch (NoSuchFileEntryException nsfee) {
272                     return null;
273                 }
274             }
275         }
276         catch (Exception e) {
277             throw new WebDAVException(e);
278         }
279     }
280 
281     public List getResources(WebDAVRequest webDavReq)
282         throws WebDAVException {
283 
284         try {
285             long parentFolderId = getParentFolderId(webDavReq, false);
286 
287             List folders = getFolders(webDavReq, parentFolderId);
288             List fileEntries = getFileEntries(webDavReq, parentFolderId);
289 
290             List resources = new ArrayList(folders.size() + fileEntries.size());
291 
292             resources.addAll(folders);
293             resources.addAll(fileEntries);
294 
295             return resources;
296         }
297         catch (Exception e) {
298             throw new WebDAVException(e);
299         }
300     }
301 
302     public int moveResource(WebDAVRequest webDavReq, String destination)
303         throws WebDAVException {
304 
305         try {
306             Resource resource = getResource(webDavReq);
307 
308             if (resource == null) {
309                 return HttpServletResponse.SC_NOT_FOUND;
310             }
311 
312             Object model = resource.getModel();
313 
314             String[] destinationArray = WebDAVUtil.getPathArray(destination);
315 
316             if (model instanceof DLFolder) {
317                 DLFolder folder = (DLFolder)model;
318 
319                 long folderId = folder.getFolderId();
320                 long parentFolderId = GetterUtil.getLong(
321                     destinationArray[destinationArray.length - 2]);
322                 String name = destinationArray[destinationArray.length - 1];
323                 String description = folder.getDescription();
324 
325                 if (parentFolderId != folder.getParentFolderId()) {
326                     name = folder.getName();
327                 }
328 
329                 DLFolderServiceUtil.updateFolder(
330                     folderId, parentFolderId, name, description);
331             }
332             else {
333                 DLFileEntry fileEntry = (DLFileEntry)model;
334 
335                 long folderId = fileEntry.getFolderId();
336                 long newFolderId = GetterUtil.getLong(
337                     destinationArray[destinationArray.length - 2]);
338                 String name = fileEntry.getName();
339                 String sourceFileName = null;
340                 String title = destinationArray[destinationArray.length - 1];
341                 String description = fileEntry.getDescription();
342                 String[] tagsEntries = new String[0];
343                 String extraSettings = fileEntry.getExtraSettings();
344                 byte[] byteArray = null;
345 
346                 if (newFolderId != folderId) {
347                     title = fileEntry.getTitle();
348                 }
349 
350                 DLFileEntryServiceUtil.updateFileEntry(
351                     folderId, newFolderId, name, sourceFileName, title,
352                     description, tagsEntries, extraSettings, byteArray);
353             }
354 
355             return HttpServletResponse.SC_CREATED;
356         }
357         catch (PrincipalException pe) {
358             return HttpServletResponse.SC_FORBIDDEN;
359         }
360         catch (Exception e) {
361             throw new WebDAVException(e);
362         }
363     }
364 
365     public int putResource(WebDAVRequest webDavReq, String destination)
366         throws WebDAVException {
367 
368         File file = null;
369 
370         try {
371             HttpServletRequest req = webDavReq.getHttpServletRequest();
372             String[] pathArray = webDavReq.getPathArray();
373             long userId = webDavReq.getUserId();
374 
375             long folderId = getParentFolderId(webDavReq, true);
376             String name = pathArray[pathArray.length - 1];
377             String title = StringPool.BLANK;
378             String description = StringPool.BLANK;
379             String[] tagsEntries = new String[0];
380             String extraSettings = StringPool.BLANK;
381 
382             String fileName =
383                 SystemProperties.get(SystemProperties.TMP_DIR) +
384                     StringPool.SLASH + Time.getTimestamp() +
385                         PwdGenerator.getPassword(PwdGenerator.KEY2, 8);
386 
387             file = new File(fileName);
388 
389             FileUtil.write(file, req.getInputStream());
390 
391             if (_log.isDebugEnabled()) {
392                 _log.debug("Writing request to file " + fileName);
393             }
394 
395             boolean addCommunityPermissions = true;
396             boolean addGuestPermissions = true;
397 
398             DLFolderPermission.check(
399                 webDavReq.getPermissionChecker(), folderId,
400                 ActionKeys.ADD_DOCUMENT);
401 
402             DLFileEntryLocalServiceUtil.addFileEntry(
403                 userId, folderId, name, title, description, tagsEntries,
404                 extraSettings, file, addCommunityPermissions,
405                 addGuestPermissions);
406 
407             return HttpServletResponse.SC_CREATED;
408         }
409         catch (PrincipalException pe) {
410             return HttpServletResponse.SC_FORBIDDEN;
411         }
412         catch (PortalException pe) {
413             if (_log.isWarnEnabled()) {
414                 _log.warn(pe.getMessage());
415             }
416 
417             return HttpServletResponse.SC_CONFLICT;
418         }
419         catch (Exception e) {
420             throw new WebDAVException(e);
421         }
422         finally {
423             if (file != null) {
424                 file.delete();
425             }
426         }
427     }
428 
429     protected List getFileEntries(WebDAVRequest webDavReq, long parentFolderId)
430         throws Exception {
431 
432         List fileEntries = new ArrayList();
433 
434         Iterator itr = DLFileEntryLocalServiceUtil.getFileEntries(
435             parentFolderId).iterator();
436 
437         while (itr.hasNext()) {
438             DLFileEntry fileEntry = (DLFileEntry)itr.next();
439 
440             Resource resource = toResource(webDavReq, fileEntry, true);
441 
442             fileEntries.add(resource);
443         }
444 
445         return fileEntries;
446     }
447 
448     protected List getFolders(WebDAVRequest webDavReq, long parentFolderId)
449         throws Exception {
450 
451         List folders = new ArrayList();
452 
453         Iterator itr = DLFolderLocalServiceUtil.getFolders(
454             webDavReq.getGroupId(), parentFolderId).iterator();
455 
456         while (itr.hasNext()) {
457             DLFolder folder = (DLFolder)itr.next();
458 
459             Resource resource = toResource(webDavReq, folder, true);
460 
461             folders.add(resource);
462         }
463 
464         return folders;
465     }
466 
467     protected long getParentFolderId(
468             WebDAVRequest webDavReq, boolean newResource)
469         throws Exception {
470 
471         long parentFolderId = DLFolderImpl.DEFAULT_PARENT_FOLDER_ID;
472 
473         String[] pathArray = webDavReq.getPathArray();
474 
475         if (pathArray.length <= 2) {
476             return parentFolderId;
477         }
478         else {
479             int x = pathArray.length;
480 
481             if (newResource) {
482                 x--;
483             }
484 
485             for (int i = 2; i < x; i++) {
486                 try {
487                     long folderId = GetterUtil.getLong(pathArray[i]);
488 
489                     DLFolder folder = DLFolderLocalServiceUtil.getFolder(
490                         folderId);
491 
492                     if (webDavReq.getGroupId() == folder.getGroupId()) {
493                         parentFolderId = folderId;
494                     }
495                 }
496                 catch (NoSuchFolderException nsfe) {
497                     break;
498                 }
499             }
500         }
501 
502         return parentFolderId;
503     }
504 
505     protected Resource toResource(
506         WebDAVRequest webDavReq, DLFileEntry fileEntry, boolean appendPath) {
507 
508         String href = getRootPath() + webDavReq.getPath();
509 
510         if (appendPath) {
511             href += StringPool.SLASH + fileEntry.getName();
512         }
513 
514         return new DLFileEntryResourceImpl(webDavReq, fileEntry, href);
515     }
516 
517     protected Resource toResource(
518         WebDAVRequest webDavReq, DLFolder folder, boolean appendPath) {
519 
520         String href = getRootPath() + webDavReq.getPath();
521 
522         if (appendPath) {
523             href += StringPool.SLASH + folder.getFolderId();
524         }
525 
526         Resource resource = new BaseResourceImpl(
527             href, folder.getName(), true, folder.getCreateDate(),
528             //href, folder.getFolderId(), true, folder.getCreateDate(),
529             folder.getModifiedDate());
530 
531         resource.setModel(folder);
532 
533         return resource;
534     }
535 
536     private static Log _log = LogFactory.getLog(DLWebDAVStorageImpl.class);
537 
538 }