1   /**
2    * Copyright (c) 2000-2010 Liferay, Inc. All rights reserved.
3    *
4    * This library is free software; you can redistribute it and/or modify it under
5    * the terms of the GNU Lesser General Public License as published by the Free
6    * Software Foundation; either version 2.1 of the License, or (at your option)
7    * any later version.
8    *
9    * This library is distributed in the hope that it will be useful, but WITHOUT
10   * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11   * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
12   * details.
13   */
14  
15  package com.liferay.portlet.documentlibrary.service.impl;
16  
17  import com.liferay.portal.ExpiredLockException;
18  import com.liferay.portal.InvalidLockException;
19  import com.liferay.portal.NoSuchLockException;
20  import com.liferay.portal.kernel.exception.PortalException;
21  import com.liferay.portal.kernel.exception.SystemException;
22  import com.liferay.portal.kernel.log.Log;
23  import com.liferay.portal.kernel.log.LogFactoryUtil;
24  import com.liferay.portal.kernel.util.FileUtil;
25  import com.liferay.portal.kernel.util.ListUtil;
26  import com.liferay.portal.kernel.util.Validator;
27  import com.liferay.portal.model.Lock;
28  import com.liferay.portal.security.permission.ActionKeys;
29  import com.liferay.portal.service.ServiceContext;
30  import com.liferay.portlet.documentlibrary.model.DLFileEntry;
31  import com.liferay.portlet.documentlibrary.model.DLFolder;
32  import com.liferay.portlet.documentlibrary.model.impl.DLFolderImpl;
33  import com.liferay.portlet.documentlibrary.service.base.DLFolderServiceBaseImpl;
34  import com.liferay.portlet.documentlibrary.service.permission.DLFolderPermission;
35  
36  import java.io.File;
37  import java.io.InputStream;
38  
39  import java.rmi.RemoteException;
40  
41  import java.util.HashSet;
42  import java.util.Iterator;
43  import java.util.List;
44  import java.util.Set;
45  
46  /**
47   * <a href="DLFolderServiceImpl.java.html"><b><i>View Source</i></b></a>
48   *
49   * @author Brian Wing Shun Chan
50   */
51  public class DLFolderServiceImpl extends DLFolderServiceBaseImpl {
52  
53      public DLFolder addFolder(
54              long groupId, long parentFolderId, String name, String description,
55              ServiceContext serviceContext)
56          throws PortalException, SystemException {
57  
58          DLFolderPermission.check(
59              getPermissionChecker(), groupId, parentFolderId,
60              ActionKeys.ADD_FOLDER);
61  
62          return dlFolderLocalService.addFolder(
63              null, getUserId(), groupId, parentFolderId, name, description,
64              serviceContext);
65      }
66  
67      public DLFolder copyFolder(
68              long groupId, long sourceFolderId, long parentFolderId, String name,
69              String description, ServiceContext serviceContext)
70          throws PortalException, RemoteException, SystemException {
71  
72          DLFolder srcFolder = getFolder(sourceFolderId);
73  
74          DLFolder destFolder = addFolder(
75              groupId, parentFolderId, name, description, serviceContext);
76  
77          copyFolder(srcFolder, destFolder, serviceContext);
78  
79          return destFolder;
80      }
81  
82      public void deleteFolder(long folderId)
83          throws PortalException, RemoteException, SystemException {
84  
85          DLFolder folder = dlFolderLocalService.getFolder(folderId);
86  
87          DLFolderPermission.check(
88              getPermissionChecker(), folder, ActionKeys.DELETE);
89  
90          boolean hasLock = lockLocalService.hasLock(
91              getUserId(), DLFolder.class.getName(), folderId);
92  
93          Lock lock = null;
94  
95          if (!hasLock) {
96  
97              // Lock
98  
99              lock = lockFolder(folderId);
100         }
101 
102         try {
103             dlFolderLocalService.deleteFolder(folderId);
104         }
105         finally {
106             if (!hasLock) {
107 
108                 // Unlock
109 
110                 unlockFolder(folder.getGroupId(), folderId, lock.getUuid());
111             }
112         }
113     }
114 
115     public void deleteFolder(long groupId, long parentFolderId, String name)
116         throws PortalException, RemoteException, SystemException {
117 
118         long folderId = getFolderId(groupId, parentFolderId, name);
119 
120         deleteFolder(folderId);
121     }
122 
123     public DLFolder getFolder(long folderId)
124         throws PortalException, SystemException {
125 
126         DLFolder folder = dlFolderLocalService.getFolder(folderId);
127 
128         DLFolderPermission.check(
129             getPermissionChecker(), folder, ActionKeys.VIEW);
130 
131         return folder;
132     }
133 
134     public DLFolder getFolder(long groupId, long parentFolderId, String name)
135         throws PortalException, SystemException {
136 
137         DLFolder folder = dlFolderLocalService.getFolder(
138             groupId, parentFolderId, name);
139 
140         DLFolderPermission.check(
141             getPermissionChecker(), folder, ActionKeys.VIEW);
142 
143         return folder;
144     }
145 
146     public long getFolderId(long groupId, long parentFolderId, String name)
147         throws PortalException, SystemException {
148 
149         DLFolder folder = getFolder(groupId, parentFolderId, name);
150 
151         return folder.getFolderId();
152     }
153 
154     public List<DLFolder> getFolders(long groupId, long parentFolderId)
155         throws PortalException, SystemException {
156 
157         List<DLFolder> folders = dlFolderLocalService.getFolders(
158             groupId, parentFolderId);
159 
160         folders = ListUtil.copy(folders);
161 
162         Iterator<DLFolder> itr = folders.iterator();
163 
164         while (itr.hasNext()) {
165             DLFolder folder = itr.next();
166 
167             if (!DLFolderPermission.contains(
168                     getPermissionChecker(), groupId, folder.getFolderId(),
169                     ActionKeys.VIEW)) {
170 
171                 itr.remove();
172             }
173         }
174 
175         return folders;
176     }
177 
178     public boolean hasInheritableLock(long folderId)
179         throws PortalException, SystemException {
180 
181         boolean inheritable = false;
182 
183         try {
184             Lock lock = lockLocalService.getLock(
185                 DLFolder.class.getName(), folderId);
186 
187             inheritable = lock.isInheritable();
188         }
189         catch (ExpiredLockException ele) {
190         }
191         catch (NoSuchLockException nsle) {
192         }
193 
194         return inheritable;
195     }
196 
197     public Lock lockFolder(long folderId)
198         throws PortalException, RemoteException, SystemException {
199 
200         return lockFolder(
201             folderId, null, false, DLFolderImpl.LOCK_EXPIRATION_TIME);
202     }
203 
204     public Lock lockFolder(
205             long folderId, String owner, boolean inheritable,
206             long expirationTime)
207         throws PortalException, RemoteException, SystemException {
208 
209         if ((expirationTime <= 0) ||
210             (expirationTime > DLFolderImpl.LOCK_EXPIRATION_TIME)) {
211 
212             expirationTime = DLFolderImpl.LOCK_EXPIRATION_TIME;
213         }
214 
215         Lock lock = lockLocalService.lock(
216             getUser().getUserId(), DLFolder.class.getName(), folderId, owner,
217             inheritable, expirationTime);
218 
219         Set<String> fileNames = new HashSet<String>();
220 
221         DLFolder folder = dlFolderPersistence.findByPrimaryKey(folderId);
222 
223         long groupId = folder.getGroupId();
224 
225         try {
226 
227             List<DLFileEntry> fileEntries = dlFileEntryService.getFileEntries(
228                 groupId, folderId);
229 
230             for (DLFileEntry fileEntry : fileEntries) {
231                 dlFileEntryService.lockFileEntry(
232                     groupId, folderId, fileEntry.getName(), owner,
233                     expirationTime);
234 
235                 fileNames.add(fileEntry.getName());
236             }
237         }
238         catch (Exception e) {
239             for (String fileName : fileNames) {
240                 dlFileEntryService.unlockFileEntry(groupId, folderId, fileName);
241             }
242 
243             unlockFolder(groupId, folderId, lock.getUuid());
244 
245             if (e instanceof PortalException) {
246                 throw (PortalException)e;
247             }
248             else if (e instanceof RemoteException) {
249                 throw (RemoteException)e;
250             }
251             else if (e instanceof SystemException) {
252                 throw (SystemException)e;
253             }
254             else {
255                 throw new PortalException(e);
256             }
257         }
258 
259         return lock;
260     }
261 
262     public Lock refreshFolderLock(String lockUuid, long expirationTime)
263         throws PortalException, SystemException {
264 
265         return lockLocalService.refresh(lockUuid, expirationTime);
266     }
267 
268     public void unlockFolder(long groupId, long folderId, String lockUuid)
269         throws PortalException, SystemException {
270 
271         if (Validator.isNotNull(lockUuid)) {
272             try {
273                 Lock lock = lockLocalService.getLock(
274                     DLFolder.class.getName(), folderId);
275 
276                 if (!lock.getUuid().equals(lockUuid)) {
277                     throw new InvalidLockException("UUIDs do not match");
278                 }
279             }
280             catch (PortalException pe) {
281                 if (pe instanceof ExpiredLockException ||
282                     pe instanceof NoSuchLockException) {
283                 }
284                 else {
285                     throw pe;
286                 }
287             }
288         }
289 
290         lockLocalService.unlock(DLFolder.class.getName(), folderId);
291 
292         try {
293             List<DLFileEntry> fileEntries = dlFileEntryService.getFileEntries(
294                 groupId, folderId);
295 
296             for (DLFileEntry fileEntry : fileEntries) {
297                 dlFileEntryService.unlockFileEntry(
298                     groupId, folderId, fileEntry.getName());
299             }
300         }
301         catch (Exception e) {
302             _log.error(e, e);
303         }
304     }
305 
306     public void unlockFolder(
307             long groupId, long parentFolderId, String name, String lockUuid)
308         throws PortalException, SystemException {
309 
310         long folderId = getFolderId(groupId, parentFolderId, name);
311 
312         unlockFolder(groupId, folderId, lockUuid);
313     }
314 
315     public DLFolder updateFolder(
316             long folderId, long parentFolderId, String name, String description,
317             ServiceContext serviceContext)
318         throws PortalException, RemoteException, SystemException {
319 
320         DLFolder folder = dlFolderLocalService.getFolder(folderId);
321 
322         DLFolderPermission.check(
323             getPermissionChecker(), folder, ActionKeys.UPDATE);
324 
325         boolean hasLock = lockLocalService.hasLock(
326             getUserId(), DLFolder.class.getName(), folderId);
327 
328         Lock lock = null;
329 
330         if (!hasLock) {
331 
332             // Lock
333 
334             lock = lockFolder(folderId);
335         }
336 
337         try {
338             return dlFolderLocalService.updateFolder(
339                 folderId, parentFolderId, name, description, serviceContext);
340         }
341         finally {
342             if (!hasLock) {
343 
344                 // Unlock
345 
346                 unlockFolder(folder.getGroupId(), folderId, lock.getUuid());
347             }
348         }
349     }
350 
351     public boolean verifyInheritableLock(long folderId, String lockUuid)
352         throws PortalException, SystemException {
353 
354         boolean verified = false;
355 
356         try {
357             Lock lock = lockLocalService.getLock(
358                 DLFolder.class.getName(), folderId);
359 
360             if (!lock.isInheritable()) {
361                 throw new NoSuchLockException();
362             }
363 
364             if (lock.getUuid().equals(lockUuid)) {
365                 verified = true;
366             }
367         }
368         catch (ExpiredLockException ele) {
369             throw new NoSuchLockException(ele);
370         }
371 
372         return verified;
373     }
374 
375     protected void copyFolder(
376             DLFolder srcFolder, DLFolder destFolder,
377             ServiceContext serviceContext)
378         throws PortalException, RemoteException, SystemException {
379 
380         List<DLFileEntry> srcFileEntries = dlFileEntryService.getFileEntries(
381             srcFolder.getGroupId(), srcFolder.getFolderId());
382 
383         for (DLFileEntry srcFileEntry : srcFileEntries) {
384             String name = srcFileEntry.getName();
385             String title = srcFileEntry.getTitle();
386             String description = srcFileEntry.getDescription();
387             String extraSettings = srcFileEntry.getExtraSettings();
388 
389             File file = null;
390 
391             try {
392                 file = FileUtil.createTempFile(FileUtil.getExtension(title));
393 
394                 InputStream is = dlLocalService.getFileAsStream(
395                     srcFolder.getCompanyId(), srcFolder.getFolderId(), name);
396 
397                 FileUtil.write(file, is);
398             }
399             catch (Exception e) {
400                 _log.error(e, e);
401 
402                 continue;
403             }
404 
405             dlFileEntryService.addFileEntry(
406                 destFolder.getGroupId(), destFolder.getFolderId(), name, title,
407                 description, null, extraSettings, file, serviceContext);
408 
409             file.delete();
410         }
411 
412         List<DLFolder> srcSubfolders = getFolders(
413             srcFolder.getGroupId(), srcFolder.getFolderId());
414 
415         for (DLFolder srcSubfolder : srcSubfolders) {
416             String name = srcSubfolder.getName();
417             String description = srcSubfolder.getDescription();
418 
419             DLFolder destSubfolder = addFolder(
420                 destFolder.getGroupId(), destFolder.getFolderId(), name,
421                 description, serviceContext);
422 
423             copyFolder(srcSubfolder, destSubfolder, serviceContext);
424         }
425     }
426 
427     private static Log _log = LogFactoryUtil.getLog(DLFolderServiceImpl.class);
428 
429 }