1   /**
2    * Copyright (c) 2000-2009 Liferay, Inc. All rights reserved.
3    *
4    * The contents of this file are subject to the terms of the Liferay Enterprise
5    * Subscription License ("License"). You may not use this file except in
6    * compliance with the License. You can obtain a copy of the License by
7    * contacting Liferay, Inc. See the License for the specific language governing
8    * permissions and limitations under the License, including but not limited to
9    * distribution rights of the Software.
10   *
11   * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
12   * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
13   * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
14   * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
15   * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
16   * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
17   * SOFTWARE.
18   */
19  
20  package com.liferay.portlet.documentlibrary.service.impl;
21  
22  import com.liferay.lock.ExpiredLockException;
23  import com.liferay.lock.InvalidLockException;
24  import com.liferay.lock.NoSuchLockException;
25  import com.liferay.lock.model.Lock;
26  import com.liferay.portal.PortalException;
27  import com.liferay.portal.SystemException;
28  import com.liferay.portal.kernel.log.Log;
29  import com.liferay.portal.kernel.log.LogFactoryUtil;
30  import com.liferay.portal.kernel.util.FileUtil;
31  import com.liferay.portal.kernel.util.ListUtil;
32  import com.liferay.portal.kernel.util.Validator;
33  import com.liferay.portal.security.auth.PrincipalException;
34  import com.liferay.portal.security.permission.ActionKeys;
35  import com.liferay.portal.service.ServiceContext;
36  import com.liferay.portlet.documentlibrary.model.DLFileEntry;
37  import com.liferay.portlet.documentlibrary.model.DLFolder;
38  import com.liferay.portlet.documentlibrary.model.impl.DLFolderImpl;
39  import com.liferay.portlet.documentlibrary.service.base.DLFolderServiceBaseImpl;
40  import com.liferay.portlet.documentlibrary.service.permission.DLFolderPermission;
41  
42  import java.io.File;
43  import java.io.InputStream;
44  
45  import java.rmi.RemoteException;
46  
47  import java.util.HashSet;
48  import java.util.Iterator;
49  import java.util.List;
50  import java.util.Set;
51  
52  /**
53   * <a href="DLFolderServiceImpl.java.html"><b><i>View Source</i></b></a>
54   *
55   * @author Brian Wing Shun Chan
56   *
57   */
58  public class DLFolderServiceImpl extends DLFolderServiceBaseImpl {
59  
60      public DLFolder addFolder(
61              long groupId, long parentFolderId, String name, String description,
62              ServiceContext serviceContext)
63          throws PortalException, SystemException {
64  
65          DLFolderPermission.check(
66              getPermissionChecker(), groupId, parentFolderId,
67              ActionKeys.ADD_FOLDER);
68  
69          return dlFolderLocalService.addFolder(
70              getUserId(), groupId, parentFolderId, name, description,
71              serviceContext);
72      }
73  
74      public DLFolder copyFolder(
75              long groupId, long sourceFolderId, long parentFolderId, String name,
76              String description, ServiceContext serviceContext)
77          throws PortalException, RemoteException, SystemException {
78  
79          DLFolder srcFolder = getFolder(sourceFolderId);
80  
81          DLFolder destFolder = addFolder(
82              groupId, parentFolderId, name, description, serviceContext);
83  
84          copyFolder(srcFolder, destFolder, serviceContext);
85  
86          return destFolder;
87      }
88  
89      public void deleteFolder(long folderId)
90          throws PortalException, RemoteException, SystemException {
91  
92          DLFolderPermission.check(
93              getPermissionChecker(), folderId, ActionKeys.DELETE);
94  
95          boolean hasLock = lockService.hasLock(
96              DLFolder.class.getName(), folderId, getUserId());
97  
98          Lock lock = null;
99  
100         if (!hasLock) {
101 
102             // Lock
103 
104             lock = lockFolder(folderId);
105         }
106 
107         try {
108             dlFolderLocalService.deleteFolder(folderId);
109         }
110         finally {
111             if (!hasLock) {
112 
113                 // Unlock
114 
115                 unlockFolder(folderId, lock.getUuid());
116             }
117         }
118     }
119 
120     public void deleteFolder(long groupId, long parentFolderId, String name)
121         throws PortalException, RemoteException, SystemException {
122 
123         long folderId = getFolderId(groupId, parentFolderId, name);
124 
125         deleteFolder(folderId);
126     }
127 
128     public DLFolder getFolder(long folderId)
129         throws PortalException, SystemException {
130 
131         DLFolderPermission.check(
132             getPermissionChecker(), folderId, ActionKeys.VIEW);
133 
134         return dlFolderLocalService.getFolder(folderId);
135     }
136 
137     public DLFolder getFolder(long groupId, long parentFolderId, String name)
138         throws PortalException, SystemException {
139 
140         DLFolder folder = dlFolderLocalService.getFolder(
141             groupId, parentFolderId, name);
142 
143         DLFolderPermission.check(
144             getPermissionChecker(), folder, ActionKeys.VIEW);
145 
146         return folder;
147     }
148 
149     public long getFolderId(long groupId, long parentFolderId, String name)
150         throws PortalException, SystemException {
151 
152         DLFolder folder = getFolder(groupId, parentFolderId, name);
153 
154         return folder.getFolderId();
155     }
156 
157     public List<DLFolder> getFolders(long groupId, long parentFolderId)
158         throws PortalException, SystemException {
159 
160         List<DLFolder> folders = dlFolderLocalService.getFolders(
161             groupId, parentFolderId);
162 
163         folders = ListUtil.copy(folders);
164 
165         Iterator<DLFolder> itr = folders.iterator();
166 
167         while (itr.hasNext()) {
168             DLFolder folder = itr.next();
169 
170             if (!DLFolderPermission.contains(
171                     getPermissionChecker(), folder.getFolderId(),
172                     ActionKeys.VIEW)) {
173 
174                 itr.remove();
175             }
176         }
177 
178         return folders;
179     }
180 
181     public boolean hasInheritableLock(long folderId) throws PortalException {
182         boolean inheritable = false;
183 
184         try {
185             Lock lock = lockService.getLock(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 = lockService.lock(
216             DLFolder.class.getName(), folderId, getUser().getUserId(), owner,
217             inheritable, expirationTime);
218 
219         Set<String> fileNames = new HashSet<String>();
220 
221         try {
222             List<DLFileEntry> fileEntries = dlFileEntryService.getFileEntries(
223                 folderId);
224 
225             for (DLFileEntry fileEntry : fileEntries) {
226                 dlFileEntryService.lockFileEntry(
227                     folderId, fileEntry.getName(), owner, expirationTime);
228 
229                 fileNames.add(fileEntry.getName());
230             }
231         }
232         catch (Exception e) {
233             for (String fileName : fileNames) {
234                 dlFileEntryService.unlockFileEntry(folderId, fileName);
235             }
236 
237             unlockFolder(folderId, lock.getUuid());
238 
239             if (e instanceof PortalException) {
240                 throw (PortalException)e;
241             }
242             else if (e instanceof RemoteException) {
243                 throw (RemoteException)e;
244             }
245             else if (e instanceof SystemException) {
246                 throw (SystemException)e;
247             }
248             else {
249                 throw new PortalException(e);
250             }
251         }
252 
253         return lock;
254     }
255 
256     public Lock refreshFolderLock(String lockUuid, long expirationTime)
257         throws PortalException {
258 
259         return lockService.refresh(lockUuid, expirationTime);
260     }
261 
262     public void reIndexSearch(long companyId)
263         throws PortalException, SystemException {
264 
265         if (!getPermissionChecker().isOmniadmin()) {
266             throw new PrincipalException();
267         }
268 
269         String[] ids = new String[] {String.valueOf(companyId)};
270 
271         dlFolderLocalService.reIndex(ids);
272     }
273 
274     public void unlockFolder(long folderId, String lockUuid)
275         throws PortalException {
276 
277         if (Validator.isNotNull(lockUuid)) {
278             try {
279                 Lock lock = lockService.getLock(
280                     DLFolder.class.getName(), folderId);
281 
282                 if (!lock.getUuid().equals(lockUuid)) {
283                     throw new InvalidLockException("UUIDs do not match");
284                 }
285             }
286             catch (PortalException pe) {
287                 if (pe instanceof ExpiredLockException ||
288                     pe instanceof NoSuchLockException) {
289                 }
290                 else {
291                     throw pe;
292                 }
293             }
294         }
295 
296         lockService.unlock(DLFolder.class.getName(), folderId);
297 
298         try {
299             List<DLFileEntry> fileEntries = dlFileEntryService.getFileEntries(
300                 folderId);
301 
302             for (DLFileEntry fileEntry : fileEntries) {
303                 dlFileEntryService.unlockFileEntry(
304                     folderId, fileEntry.getName());
305             }
306         }
307         catch (Exception e) {
308             _log.error(e, e);
309         }
310     }
311 
312     public void unlockFolder(
313             long groupId, long parentFolderId, String name, String lockUuid)
314         throws PortalException, SystemException {
315 
316         long folderId = getFolderId(groupId, parentFolderId, name);
317 
318         unlockFolder(folderId, lockUuid);
319     }
320 
321     public DLFolder updateFolder(
322             long folderId, long parentFolderId, String name, String description,
323             ServiceContext serviceContext)
324         throws PortalException, RemoteException, SystemException {
325 
326         DLFolderPermission.check(
327             getPermissionChecker(), folderId, ActionKeys.UPDATE);
328 
329         boolean hasLock = lockService.hasLock(
330             DLFolder.class.getName(), folderId, getUserId());
331 
332         Lock lock = null;
333 
334         if (!hasLock) {
335 
336             // Lock
337 
338             lock = lockFolder(folderId);
339         }
340 
341         try {
342             return dlFolderLocalService.updateFolder(
343                 folderId, parentFolderId, name, description, serviceContext);
344         }
345         finally {
346             if (!hasLock) {
347 
348                 // Unlock
349 
350                 unlockFolder(folderId, lock.getUuid());
351             }
352         }
353     }
354 
355     public boolean verifyInheritableLock(long folderId, String lockUuid)
356         throws PortalException {
357 
358         boolean verified = false;
359 
360         try {
361             Lock lock = lockService.getLock(DLFolder.class.getName(), folderId);
362 
363             if (!lock.isInheritable()) {
364                 throw new NoSuchLockException();
365             }
366 
367             if (lock.getUuid().equals(lockUuid)) {
368                 verified = true;
369             }
370         }
371         catch (ExpiredLockException ele) {
372             throw new NoSuchLockException(ele);
373         }
374 
375         return verified;
376     }
377 
378     protected void copyFolder(
379             DLFolder srcFolder, DLFolder destFolder,
380             ServiceContext serviceContext)
381         throws PortalException, RemoteException, SystemException {
382 
383         List<DLFileEntry> srcFileEntries = dlFileEntryService.getFileEntries(
384             srcFolder.getFolderId());
385 
386         for (DLFileEntry srcFileEntry : srcFileEntries) {
387             String name = srcFileEntry.getName();
388             String title = srcFileEntry.getTitleWithExtension();
389             String description = srcFileEntry.getDescription();
390             String extraSettings = srcFileEntry.getExtraSettings();
391 
392             File file = null;
393 
394             try {
395                 file = FileUtil.createTempFile(FileUtil.getExtension(name));
396 
397                 InputStream is = dlLocalService.getFileAsStream(
398                     srcFolder.getCompanyId(), srcFolder.getFolderId(), name);
399 
400                 FileUtil.write(file, is);
401             }
402             catch (Exception e) {
403                 _log.error(e, e);
404 
405                 continue;
406             }
407 
408             dlFileEntryService.addFileEntry(
409                 destFolder.getFolderId(), name, title, description,
410                 extraSettings, file, serviceContext);
411 
412             file.delete();
413         }
414 
415         List<DLFolder> srcSubfolders = getFolders(
416             srcFolder.getGroupId(), srcFolder.getFolderId());
417 
418         for (DLFolder srcSubfolder : srcSubfolders) {
419             String name = srcSubfolder.getName();
420             String description = srcSubfolder.getDescription();
421 
422             DLFolder destSubfolder = addFolder(
423                 destFolder.getGroupId(), destFolder.getFolderId(), name,
424                 description, serviceContext);
425 
426             copyFolder(srcSubfolder, destSubfolder, serviceContext);
427         }
428     }
429 
430     private static Log _log = LogFactoryUtil.getLog(DLFolderServiceImpl.class);
431 
432 }