001    /**
002     * Copyright (c) 2000-2010 Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
013     */
014    
015    package com.liferay.portlet.documentlibrary.service.impl;
016    
017    import com.liferay.portal.ExpiredLockException;
018    import com.liferay.portal.InvalidLockException;
019    import com.liferay.portal.NoSuchLockException;
020    import com.liferay.portal.kernel.exception.PortalException;
021    import com.liferay.portal.kernel.exception.SystemException;
022    import com.liferay.portal.kernel.log.Log;
023    import com.liferay.portal.kernel.log.LogFactoryUtil;
024    import com.liferay.portal.kernel.util.ArrayUtil;
025    import com.liferay.portal.kernel.util.FileUtil;
026    import com.liferay.portal.kernel.util.Validator;
027    import com.liferay.portal.model.Lock;
028    import com.liferay.portal.security.permission.ActionKeys;
029    import com.liferay.portal.service.ServiceContext;
030    import com.liferay.portlet.documentlibrary.model.DLFileEntry;
031    import com.liferay.portlet.documentlibrary.model.DLFolder;
032    import com.liferay.portlet.documentlibrary.model.impl.DLFolderImpl;
033    import com.liferay.portlet.documentlibrary.service.base.DLFolderServiceBaseImpl;
034    import com.liferay.portlet.documentlibrary.service.permission.DLFolderPermission;
035    
036    import java.io.File;
037    import java.io.InputStream;
038    
039    import java.rmi.RemoteException;
040    
041    import java.util.ArrayList;
042    import java.util.HashSet;
043    import java.util.List;
044    import java.util.Set;
045    
046    /**
047     * @author Brian Wing Shun Chan
048     */
049    public class DLFolderServiceImpl extends DLFolderServiceBaseImpl {
050    
051            public DLFolder addFolder(
052                            long groupId, long parentFolderId, String name, String description,
053                            ServiceContext serviceContext)
054                    throws PortalException, SystemException {
055    
056                    DLFolderPermission.check(
057                            getPermissionChecker(), groupId, parentFolderId,
058                            ActionKeys.ADD_FOLDER);
059    
060                    return dlFolderLocalService.addFolder(
061                            getUserId(), groupId, parentFolderId, name, description,
062                            serviceContext);
063            }
064    
065            public DLFolder copyFolder(
066                            long groupId, long sourceFolderId, long parentFolderId, String name,
067                            String description, ServiceContext serviceContext)
068                    throws PortalException, RemoteException, SystemException {
069    
070                    DLFolder srcFolder = getFolder(sourceFolderId);
071    
072                    DLFolder destFolder = addFolder(
073                            groupId, parentFolderId, name, description, serviceContext);
074    
075                    copyFolder(srcFolder, destFolder, serviceContext);
076    
077                    return destFolder;
078            }
079    
080            public void deleteFolder(long folderId)
081                    throws PortalException, RemoteException, SystemException {
082    
083                    DLFolder folder = dlFolderLocalService.getFolder(folderId);
084    
085                    DLFolderPermission.check(
086                            getPermissionChecker(), folder, ActionKeys.DELETE);
087    
088                    boolean hasLock = lockLocalService.hasLock(
089                            getUserId(), DLFolder.class.getName(), folderId);
090    
091                    Lock lock = null;
092    
093                    if (!hasLock) {
094    
095                            // Lock
096    
097                            lock = lockFolder(folderId);
098                    }
099    
100                    try {
101                            dlFolderLocalService.deleteFolder(folderId);
102                    }
103                    finally {
104                            if (!hasLock) {
105    
106                                    // Unlock
107    
108                                    unlockFolder(folder.getGroupId(), folderId, lock.getUuid());
109                            }
110                    }
111            }
112    
113            public void deleteFolder(long groupId, long parentFolderId, String name)
114                    throws PortalException, RemoteException, SystemException {
115    
116                    long folderId = getFolderId(groupId, parentFolderId, name);
117    
118                    deleteFolder(folderId);
119            }
120    
121            public List<Object> getFileEntriesAndFileShortcuts(
122                            long groupId, List<Long> folderIds, int status, int start, int end)
123                    throws SystemException {
124    
125                    return dlFolderFinder.filterFindFE_FS_ByG_F_S(
126                            groupId, folderIds, status, start, end);
127            }
128    
129            public List<Object> getFileEntriesAndFileShortcuts(
130                            long groupId, long folderId, int status, int start, int end)
131                    throws SystemException {
132    
133                    List<Long> folderIds = new ArrayList<Long>();
134    
135                    folderIds.add(folderId);
136    
137                    return dlFolderFinder.filterFindFE_FS_ByG_F_S(
138                            groupId, folderIds, status, start, end);
139            }
140    
141            public int getFileEntriesAndFileShortcutsCount(
142                            long groupId, List<Long> folderIds, int status)
143                    throws SystemException {
144    
145                    return dlFolderFinder.filterCountFE_FS_ByG_F_S(
146                            groupId, folderIds, status);
147            }
148    
149            public int getFileEntriesAndFileShortcutsCount(
150                            long groupId, long folderId, int status)
151                    throws SystemException {
152    
153                    List<Long> folderIds = new ArrayList<Long>();
154    
155                    folderIds.add(folderId);
156    
157                    return dlFolderFinder.filterCountFE_FS_ByG_F_S(
158                            groupId, folderIds, status);
159            }
160    
161            public DLFolder getFolder(long folderId)
162                    throws PortalException, SystemException {
163    
164                    DLFolder folder = dlFolderLocalService.getFolder(folderId);
165    
166                    DLFolderPermission.check(
167                            getPermissionChecker(), folder, ActionKeys.VIEW);
168    
169                    return folder;
170            }
171    
172            public DLFolder getFolder(long groupId, long parentFolderId, String name)
173                    throws PortalException, SystemException {
174    
175                    DLFolder folder = dlFolderLocalService.getFolder(
176                            groupId, parentFolderId, name);
177    
178                    DLFolderPermission.check(
179                            getPermissionChecker(), folder, ActionKeys.VIEW);
180    
181                    return folder;
182            }
183    
184            public long getFolderId(long groupId, long parentFolderId, String name)
185                    throws PortalException, SystemException {
186    
187                    DLFolder folder = getFolder(groupId, parentFolderId, name);
188    
189                    return folder.getFolderId();
190            }
191    
192            public long[] getFolderIds(long groupId, long folderId)
193                    throws SystemException {
194    
195                    List<Long> folderIds = new ArrayList<Long>();
196    
197                    folderIds.add(folderId);
198    
199                    getSubfolderIds(folderIds, groupId, folderId);
200    
201                    return ArrayUtil.toArray(
202                            folderIds.toArray(new Long[folderIds.size()]));
203            }
204    
205            public List<DLFolder> getFolders(long groupId, long parentFolderId)
206                    throws SystemException {
207    
208                    return dlFolderPersistence.filterFindByG_P(groupId, parentFolderId);
209            }
210    
211            public List<DLFolder> getFolders(
212                            long groupId, long parentFolderId, int start, int end)
213                    throws SystemException {
214    
215                    return dlFolderPersistence.filterFindByG_P(
216                            groupId, parentFolderId, start, end);
217            }
218    
219            public List<Object> getFoldersAndFileEntriesAndFileShortcuts(
220                            long groupId, List<Long> folderIds, int status, int start, int end)
221                    throws SystemException {
222    
223                    return dlFolderFinder.filterFindF_FE_FS_ByG_F_S(
224                            groupId, folderIds, status, start, end);
225            }
226    
227            public List<Object> getFoldersAndFileEntriesAndFileShortcuts(
228                            long groupId, long folderId, int status, int start, int end)
229                    throws PortalException, SystemException {
230    
231                    DLFolderPermission.check(
232                            getPermissionChecker(), groupId, folderId, ActionKeys.VIEW);
233    
234                    List<Long> folderIds = new ArrayList<Long>();
235    
236                    folderIds.add(folderId);
237    
238                    return getFoldersAndFileEntriesAndFileShortcuts(
239                            groupId, folderIds, status, start, end);
240            }
241    
242            public int getFoldersAndFileEntriesAndFileShortcutsCount(
243                            long groupId, List<Long> folderIds, int status)
244                    throws SystemException {
245    
246                    return dlFolderFinder.filterCountF_FE_FS_ByG_F_S(
247                            groupId, folderIds, status);
248            }
249    
250            public int getFoldersAndFileEntriesAndFileShortcutsCount(
251                            long groupId, long folderId, int status)
252                    throws PortalException, SystemException {
253    
254                    DLFolderPermission.check(
255                            getPermissionChecker(), groupId, folderId, ActionKeys.VIEW);
256    
257                    List<Long> folderIds = new ArrayList<Long>();
258    
259                    folderIds.add(folderId);
260    
261                    return getFoldersAndFileEntriesAndFileShortcutsCount(
262                            groupId, folderIds, status);
263            }
264    
265            public int getFoldersCount(long groupId, long parentFolderId)
266                    throws SystemException {
267    
268                    return dlFolderPersistence.filterCountByG_P(groupId, parentFolderId);
269            }
270    
271            public void getSubfolderIds(
272                            List<Long> folderIds, long groupId, long folderId)
273                    throws SystemException {
274    
275                    List<DLFolder> folders = dlFolderPersistence.filterFindByG_P(
276                            groupId, folderId);
277    
278                    for (DLFolder folder : folders) {
279                            folderIds.add(folder.getFolderId());
280    
281                            getSubfolderIds(
282                                    folderIds, folder.getGroupId(), folder.getFolderId());
283                    }
284            }
285    
286            public boolean hasInheritableLock(long folderId)
287                    throws PortalException, SystemException {
288    
289                    boolean inheritable = false;
290    
291                    try {
292                            Lock lock = lockLocalService.getLock(
293                                    DLFolder.class.getName(), folderId);
294    
295                            inheritable = lock.isInheritable();
296                    }
297                    catch (ExpiredLockException ele) {
298                    }
299                    catch (NoSuchLockException nsle) {
300                    }
301    
302                    return inheritable;
303            }
304    
305            public Lock lockFolder(long folderId)
306                    throws PortalException, RemoteException, SystemException {
307    
308                    return lockFolder(
309                            folderId, null, false, DLFolderImpl.LOCK_EXPIRATION_TIME);
310            }
311    
312            public Lock lockFolder(
313                            long folderId, String owner, boolean inheritable,
314                            long expirationTime)
315                    throws PortalException, RemoteException, SystemException {
316    
317                    if ((expirationTime <= 0) ||
318                            (expirationTime > DLFolderImpl.LOCK_EXPIRATION_TIME)) {
319    
320                            expirationTime = DLFolderImpl.LOCK_EXPIRATION_TIME;
321                    }
322    
323                    Lock lock = lockLocalService.lock(
324                            getUser().getUserId(), DLFolder.class.getName(), folderId, owner,
325                            inheritable, expirationTime);
326    
327                    Set<String> fileNames = new HashSet<String>();
328    
329                    DLFolder folder = dlFolderPersistence.findByPrimaryKey(folderId);
330    
331                    long groupId = folder.getGroupId();
332    
333                    try {
334    
335                            List<DLFileEntry> fileEntries = dlFileEntryService.getFileEntries(
336                                    groupId, folderId);
337    
338                            for (DLFileEntry fileEntry : fileEntries) {
339                                    dlFileEntryService.lockFileEntry(
340                                            groupId, folderId, fileEntry.getName(), owner,
341                                            expirationTime);
342    
343                                    fileNames.add(fileEntry.getName());
344                            }
345                    }
346                    catch (Exception e) {
347                            for (String fileName : fileNames) {
348                                    dlFileEntryService.unlockFileEntry(groupId, folderId, fileName);
349                            }
350    
351                            unlockFolder(groupId, folderId, lock.getUuid());
352    
353                            if (e instanceof PortalException) {
354                                    throw (PortalException)e;
355                            }
356                            else if (e instanceof RemoteException) {
357                                    throw (RemoteException)e;
358                            }
359                            else if (e instanceof SystemException) {
360                                    throw (SystemException)e;
361                            }
362                            else {
363                                    throw new PortalException(e);
364                            }
365                    }
366    
367                    return lock;
368            }
369    
370            public Lock refreshFolderLock(String lockUuid, long expirationTime)
371                    throws PortalException, SystemException {
372    
373                    return lockLocalService.refresh(lockUuid, expirationTime);
374            }
375    
376            public void unlockFolder(long groupId, long folderId, String lockUuid)
377                    throws PortalException, SystemException {
378    
379                    if (Validator.isNotNull(lockUuid)) {
380                            try {
381                                    Lock lock = lockLocalService.getLock(
382                                            DLFolder.class.getName(), folderId);
383    
384                                    if (!lock.getUuid().equals(lockUuid)) {
385                                            throw new InvalidLockException("UUIDs do not match");
386                                    }
387                            }
388                            catch (PortalException pe) {
389                                    if (pe instanceof ExpiredLockException ||
390                                            pe instanceof NoSuchLockException) {
391                                    }
392                                    else {
393                                            throw pe;
394                                    }
395                            }
396                    }
397    
398                    lockLocalService.unlock(DLFolder.class.getName(), folderId);
399    
400                    try {
401                            List<DLFileEntry> fileEntries =
402                                    dlFileEntryLocalService.getFileEntries(groupId, folderId);
403    
404                            for (DLFileEntry fileEntry : fileEntries) {
405                                    dlFileEntryService.unlockFileEntry(
406                                            groupId, folderId, fileEntry.getName());
407                            }
408                    }
409                    catch (Exception e) {
410                            _log.error(e, e);
411                    }
412            }
413    
414            public void unlockFolder(
415                            long groupId, long parentFolderId, String name, String lockUuid)
416                    throws PortalException, SystemException {
417    
418                    long folderId = getFolderId(groupId, parentFolderId, name);
419    
420                    unlockFolder(groupId, folderId, lockUuid);
421            }
422    
423            public DLFolder updateFolder(
424                            long folderId, long parentFolderId, String name, String description,
425                            ServiceContext serviceContext)
426                    throws PortalException, RemoteException, SystemException {
427    
428                    DLFolder folder = dlFolderLocalService.getFolder(folderId);
429    
430                    DLFolderPermission.check(
431                            getPermissionChecker(), folder, ActionKeys.UPDATE);
432    
433                    boolean hasLock = lockLocalService.hasLock(
434                            getUserId(), DLFolder.class.getName(), folderId);
435    
436                    Lock lock = null;
437    
438                    if (!hasLock) {
439    
440                            // Lock
441    
442                            lock = lockFolder(folderId);
443                    }
444    
445                    try {
446                            return dlFolderLocalService.updateFolder(
447                                    folderId, parentFolderId, name, description, serviceContext);
448                    }
449                    finally {
450                            if (!hasLock) {
451    
452                                    // Unlock
453    
454                                    unlockFolder(folder.getGroupId(), folderId, lock.getUuid());
455                            }
456                    }
457            }
458    
459            public boolean verifyInheritableLock(long folderId, String lockUuid)
460                    throws PortalException, SystemException {
461    
462                    boolean verified = false;
463    
464                    try {
465                            Lock lock = lockLocalService.getLock(
466                                    DLFolder.class.getName(), folderId);
467    
468                            if (!lock.isInheritable()) {
469                                    throw new NoSuchLockException();
470                            }
471    
472                            if (lock.getUuid().equals(lockUuid)) {
473                                    verified = true;
474                            }
475                    }
476                    catch (ExpiredLockException ele) {
477                            throw new NoSuchLockException(ele);
478                    }
479    
480                    return verified;
481            }
482    
483            protected void copyFolder(
484                            DLFolder srcFolder, DLFolder destFolder,
485                            ServiceContext serviceContext)
486                    throws PortalException, RemoteException, SystemException {
487    
488                    List<DLFileEntry> srcFileEntries = dlFileEntryService.getFileEntries(
489                            srcFolder.getGroupId(), srcFolder.getFolderId());
490    
491                    for (DLFileEntry srcFileEntry : srcFileEntries) {
492                            String name = srcFileEntry.getName();
493                            String title = srcFileEntry.getTitle();
494                            String description = srcFileEntry.getDescription();
495                            String extraSettings = srcFileEntry.getExtraSettings();
496    
497                            File file = null;
498    
499                            try {
500                                    file = FileUtil.createTempFile(FileUtil.getExtension(title));
501    
502                                    InputStream is = dlLocalService.getFileAsStream(
503                                            srcFolder.getCompanyId(), srcFolder.getFolderId(), name);
504    
505                                    FileUtil.write(file, is);
506                            }
507                            catch (Exception e) {
508                                    _log.error(e, e);
509    
510                                    continue;
511                            }
512    
513                            dlFileEntryService.addFileEntry(
514                                    destFolder.getGroupId(), destFolder.getFolderId(), name, title,
515                                    description, null, extraSettings, file, serviceContext);
516    
517                            file.delete();
518                    }
519    
520                    List<DLFolder> srcSubfolders = getFolders(
521                            srcFolder.getGroupId(), srcFolder.getFolderId());
522    
523                    for (DLFolder srcSubfolder : srcSubfolders) {
524                            String name = srcSubfolder.getName();
525                            String description = srcSubfolder.getDescription();
526    
527                            DLFolder destSubfolder = addFolder(
528                                    destFolder.getGroupId(), destFolder.getFolderId(), name,
529                                    description, serviceContext);
530    
531                            copyFolder(srcSubfolder, destSubfolder, serviceContext);
532                    }
533            }
534    
535            private static Log _log = LogFactoryUtil.getLog(DLFolderServiceImpl.class);
536    
537    }