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