1   /**
2    * Copyright (c) 2000-2010 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   *
12   *
13   */
14  
15  package com.liferay.portlet.documentlibrary.service.impl;
16  
17  import com.liferay.documentlibrary.DuplicateFileException;
18  import com.liferay.documentlibrary.FileSizeException;
19  import com.liferay.documentlibrary.NoSuchFileException;
20  import com.liferay.documentlibrary.util.DLIndexerUtil;
21  import com.liferay.documentlibrary.util.JCRHook;
22  import com.liferay.portal.PortalException;
23  import com.liferay.portal.SystemException;
24  import com.liferay.portal.kernel.io.unsync.UnsyncBufferedInputStream;
25  import com.liferay.portal.kernel.io.unsync.UnsyncByteArrayInputStream;
26  import com.liferay.portal.kernel.log.Log;
27  import com.liferay.portal.kernel.log.LogFactoryUtil;
28  import com.liferay.portal.kernel.search.SearchEngineUtil;
29  import com.liferay.portal.kernel.search.SearchException;
30  import com.liferay.portal.kernel.util.FileUtil;
31  import com.liferay.portal.kernel.util.GetterUtil;
32  import com.liferay.portal.kernel.util.MathUtil;
33  import com.liferay.portal.kernel.util.MimeTypesUtil;
34  import com.liferay.portal.kernel.util.OrderByComparator;
35  import com.liferay.portal.kernel.util.StringPool;
36  import com.liferay.portal.kernel.util.Validator;
37  import com.liferay.portal.model.Resource;
38  import com.liferay.portal.model.ResourceConstants;
39  import com.liferay.portal.model.User;
40  import com.liferay.portal.service.ServiceContext;
41  import com.liferay.portal.util.PortalUtil;
42  import com.liferay.portal.util.PortletKeys;
43  import com.liferay.portal.util.PropsValues;
44  import com.liferay.portlet.documentlibrary.DuplicateFolderNameException;
45  import com.liferay.portlet.documentlibrary.NoSuchFileEntryException;
46  import com.liferay.portlet.documentlibrary.NoSuchFileVersionException;
47  import com.liferay.portlet.documentlibrary.NoSuchFolderException;
48  import com.liferay.portlet.documentlibrary.model.DLFileEntry;
49  import com.liferay.portlet.documentlibrary.model.DLFileEntryConstants;
50  import com.liferay.portlet.documentlibrary.model.DLFileShortcut;
51  import com.liferay.portlet.documentlibrary.model.DLFileVersion;
52  import com.liferay.portlet.documentlibrary.model.DLFolder;
53  import com.liferay.portlet.documentlibrary.model.DLFolderConstants;
54  import com.liferay.portlet.documentlibrary.model.impl.DLFileEntryImpl;
55  import com.liferay.portlet.documentlibrary.service.base.DLFileEntryLocalServiceBaseImpl;
56  import com.liferay.portlet.documentlibrary.social.DLActivityKeys;
57  import com.liferay.portlet.documentlibrary.util.DLUtil;
58  import com.liferay.portlet.documentlibrary.util.comparator.FileEntryModifiedDateComparator;
59  import com.liferay.portlet.messageboards.model.MBDiscussion;
60  import com.liferay.portlet.ratings.model.RatingsEntry;
61  import com.liferay.portlet.ratings.model.RatingsStats;
62  import com.liferay.portlet.tags.model.TagsEntryConstants;
63  
64  import java.io.File;
65  import java.io.FileInputStream;
66  import java.io.FileNotFoundException;
67  import java.io.InputStream;
68  
69  import java.util.Date;
70  import java.util.List;
71  
72  /**
73   * <a href="DLFileEntryLocalServiceImpl.java.html"><b><i>View Source</i></b></a>
74   *
75   * <p>
76   * For DLFileEntries, the naming convention for some of the variables is not
77   * very informative, due to legacy code. Each DLFileEntry has a corresponding
78   * name and title. The "name" is a unique identifier for a given file and
79   * usually follows the format "DLFE-1234.xls" whereas the "title" is the actual
80   * name specified by the user (e.g., "Budget.xls").
81   * </p>
82   *
83   * @author Brian Wing Shun Chan
84   * @author Harry Mark
85   */
86  public class DLFileEntryLocalServiceImpl
87      extends DLFileEntryLocalServiceBaseImpl {
88  
89      /**
90       * @deprecated
91       */
92      public DLFileEntry addFileEntry(
93              long userId, long folderId, String name, String title,
94              String description, String extraSettings, byte[] bytes,
95              ServiceContext serviceContext)
96          throws PortalException, SystemException {
97  
98          return addFileEntry(
99              null, userId, folderId, name, title, description, null,
100             extraSettings, bytes, serviceContext);
101     }
102 
103     /**
104      * @deprecated
105      */
106     public DLFileEntry addFileEntry(
107             long userId, long folderId, String name, String title,
108             String description, String extraSettings, File file,
109             ServiceContext serviceContext)
110         throws PortalException, SystemException {
111 
112         return addFileEntry(
113             null, userId, folderId, name, title, description, null,
114             extraSettings, file, serviceContext);
115     }
116 
117     /**
118      * @deprecated
119      */
120     public DLFileEntry addFileEntry(
121             long userId, long folderId, String name, String title,
122             String description, String extraSettings, InputStream is, int size,
123             ServiceContext serviceContext)
124         throws PortalException, SystemException {
125 
126         return addFileEntry(
127             null, userId, folderId, name, title, description, null,
128             extraSettings, is, size, serviceContext);
129     }
130 
131     /**
132      * @deprecated
133      */
134     public DLFileEntry addFileEntry(
135             String uuid, long userId, long folderId, String name, String title,
136             String description, String extraSettings, byte[] bytes,
137             ServiceContext serviceContext)
138         throws PortalException, SystemException {
139 
140         return addFileEntry(
141             uuid, userId, folderId, name, title, description, null,
142             extraSettings, bytes, serviceContext);
143     }
144 
145     /**
146      * @deprecated
147      */
148     public DLFileEntry addFileEntry(
149             String uuid, long userId, long folderId, String name, String title,
150             String description, String extraSettings, File file,
151             ServiceContext serviceContext)
152         throws PortalException, SystemException {
153 
154         return addFileEntry(
155             uuid, userId, folderId, name, title, description, null,
156             extraSettings, file, serviceContext);
157     }
158 
159     public DLFileEntry addFileEntry(
160             String uuid, long userId, long folderId, String name, String title,
161             String description, String versionDescription, String extraSettings,
162             byte[] bytes, ServiceContext serviceContext)
163         throws PortalException, SystemException {
164 
165         if (!PropsValues.WEBDAV_LITMUS) {
166             if (bytes == null) {
167                 throw new FileSizeException();
168             }
169         }
170 
171         InputStream is = new UnsyncByteArrayInputStream(bytes);
172 
173         return addFileEntry(
174             uuid, userId, folderId, name, title, description,
175             versionDescription, extraSettings, is, bytes.length,
176             serviceContext);
177     }
178 
179     public DLFileEntry addFileEntry(
180             String uuid, long userId, long folderId, String name, String title,
181             String description, String versionDescription, String extraSettings,
182             File file, ServiceContext serviceContext)
183         throws PortalException, SystemException {
184 
185         if (!PropsValues.WEBDAV_LITMUS) {
186             if (file == null) {
187                 throw new FileSizeException();
188             }
189         }
190 
191         try {
192             InputStream is = new UnsyncBufferedInputStream(
193                 new FileInputStream(file));
194 
195             return addFileEntry(
196                 uuid, userId, folderId, name, title, description,
197                 versionDescription, extraSettings, is, file.length(),
198                 serviceContext);
199         }
200         catch (FileNotFoundException fnfe) {
201             throw new FileSizeException();
202         }
203     }
204 
205     public DLFileEntry addFileEntry(
206             String uuid, long userId, long folderId, String name, String title,
207             String description, String versionDescription, String extraSettings,
208             InputStream is, long size, ServiceContext serviceContext)
209         throws PortalException, SystemException {
210 
211         // File entry
212 
213         User user = userPersistence.findByPrimaryKey(userId);
214         folderId = getFolderId(user.getCompanyId(), folderId);
215         DLFolder folder = dlFolderPersistence.findByPrimaryKey(folderId);
216 
217         if (Validator.isNull(title)) {
218             title = name;
219         }
220 
221         name = getName(name);
222         title = DLFileEntryImpl.stripExtension(name, title);
223 
224         Date now = new Date();
225 
226         validate(folder.getGroupId(), folderId, name, title, is);
227 
228         long fileEntryId = counterLocalService.increment();
229 
230         DLFileEntry fileEntry = dlFileEntryPersistence.create(fileEntryId);
231 
232         fileEntry.setUuid(uuid);
233         fileEntry.setGroupId(folder.getGroupId());
234         fileEntry.setCompanyId(user.getCompanyId());
235         fileEntry.setUserId(user.getUserId());
236         fileEntry.setUserName(user.getFullName());
237         fileEntry.setVersionUserId(user.getUserId());
238         fileEntry.setVersionUserName(user.getFullName());
239         fileEntry.setCreateDate(serviceContext.getCreateDate(now));
240         fileEntry.setModifiedDate(serviceContext.getModifiedDate(now));
241         fileEntry.setFolderId(folderId);
242         fileEntry.setName(name);
243         fileEntry.setTitle(title);
244         fileEntry.setDescription(description);
245         fileEntry.setVersion(DLFileEntryConstants.DEFAULT_VERSION);
246         fileEntry.setSize((int)size);
247         fileEntry.setReadCount(DLFileEntryConstants.DEFAULT_READ_COUNT);
248         fileEntry.setExtraSettings(extraSettings);
249         fileEntry.setExpandoBridgeAttributes(serviceContext);
250 
251         dlFileEntryPersistence.update(fileEntry, false);
252 
253         // Resources
254 
255         if (serviceContext.getAddCommunityPermissions() ||
256                 serviceContext.getAddGuestPermissions()) {
257 
258             addFileEntryResources(
259                 fileEntry, serviceContext.getAddCommunityPermissions(),
260                 serviceContext.getAddGuestPermissions());
261         }
262         else {
263             addFileEntryResources(
264                 fileEntry, serviceContext.getCommunityPermissions(),
265                 serviceContext.getGuestPermissions());
266         }
267 
268         // File version
269 
270         addFileVersion(
271             user, fileEntry, serviceContext.getModifiedDate(now),
272             fileEntry.getVersion(), null);
273 
274         // Folder
275 
276         folder.setLastPostDate(fileEntry.getModifiedDate());
277 
278         dlFolderPersistence.update(folder, false);
279 
280         // Message boards
281 
282         if (PropsValues.DL_FILE_ENTRY_COMMENTS_ENABLED) {
283             mbMessageLocalService.addDiscussionMessage(
284                 userId, fileEntry.getUserName(), DLFileEntry.class.getName(),
285                 fileEntryId);
286         }
287 
288         // Social
289 
290         socialActivityLocalService.addActivity(
291             userId, fileEntry.getGroupId(), DLFileEntry.class.getName(),
292             fileEntryId, DLActivityKeys.ADD_FILE_ENTRY, StringPool.BLANK, 0);
293 
294         // Tags
295 
296         updateTagsAsset(
297             userId, fileEntry, serviceContext.getTagsCategories(),
298             serviceContext.getTagsEntries());
299 
300         // File
301 
302         dlLocalService.addFile(
303             user.getCompanyId(), PortletKeys.DOCUMENT_LIBRARY,
304             fileEntry.getGroupId(), folderId, name, fileEntryId,
305             fileEntry.getLuceneProperties(), fileEntry.getModifiedDate(),
306             serviceContext.getTagsCategories(), serviceContext.getTagsEntries(),
307             is);
308 
309         return fileEntry;
310     }
311 
312     public void addFileEntryResources(
313             DLFileEntry fileEntry, boolean addCommunityPermissions,
314             boolean addGuestPermissions)
315         throws PortalException, SystemException {
316 
317         resourceLocalService.addResources(
318             fileEntry.getCompanyId(), fileEntry.getGroupId(),
319             fileEntry.getUserId(), DLFileEntry.class.getName(),
320             fileEntry.getFileEntryId(), false, addCommunityPermissions,
321             addGuestPermissions);
322     }
323 
324     public void addFileEntryResources(
325             DLFileEntry fileEntry, String[] communityPermissions,
326             String[] guestPermissions)
327         throws PortalException, SystemException {
328 
329         resourceLocalService.addModelResources(
330             fileEntry.getCompanyId(), fileEntry.getGroupId(),
331             fileEntry.getUserId(), DLFileEntry.class.getName(),
332             fileEntry.getFileEntryId(), communityPermissions, guestPermissions);
333     }
334 
335     public void addFileEntryResources(
336             long fileEntryId, boolean addCommunityPermissions,
337             boolean addGuestPermissions)
338         throws PortalException, SystemException {
339 
340         DLFileEntry fileEntry = dlFileEntryPersistence.findByPrimaryKey(
341             fileEntryId);
342 
343         addFileEntryResources(
344             fileEntry, addCommunityPermissions, addGuestPermissions);
345     }
346 
347     public void addFileEntryResources(
348             long fileEntryId, String[] communityPermissions,
349             String[] guestPermissions)
350         throws PortalException, SystemException {
351 
352         DLFileEntry fileEntry = dlFileEntryPersistence.findByPrimaryKey(
353             fileEntryId);
354 
355         addFileEntryResources(
356             fileEntry, communityPermissions, guestPermissions);
357     }
358 
359     public DLFileEntry addOrOverwriteFileEntry(
360             long userId, long folderId, String name, String sourceName,
361             String title, String description, String extraSettings, File file,
362             ServiceContext serviceContext)
363         throws PortalException, SystemException {
364 
365         boolean update = false;
366 
367         String extension = FileUtil.getExtension(name);
368 
369         List<DLFileEntry> fileEntries = dlFileEntryPersistence.findByF_T(
370             folderId, title);
371 
372         for (DLFileEntry fileEntry : fileEntries) {
373             String curExtension = FileUtil.getExtension(fileEntry.getName());
374 
375             if (Validator.isNull(extension)) {
376                 if (Validator.isNull(curExtension)) {
377                     update = true;
378 
379                     name = fileEntry.getName();
380 
381                     break;
382                 }
383             }
384             else if (extension.equals(curExtension)) {
385                 update = true;
386 
387                 break;
388             }
389         }
390 
391         if (update) {
392             return updateFileEntry(
393                 userId, folderId, folderId, name, sourceName, title,
394                 description, extraSettings, file, serviceContext);
395         }
396         else {
397             return addFileEntry(
398                 userId, folderId, name, title, description, extraSettings, file,
399                 serviceContext);
400         }
401     }
402 
403     public void deleteFileEntries(long folderId)
404         throws PortalException, SystemException {
405 
406         List<DLFileEntry> fileEntries = dlFileEntryPersistence.findByFolderId(
407             folderId);
408 
409         for (DLFileEntry fileEntry : fileEntries) {
410             deleteFileEntry(fileEntry);
411         }
412     }
413 
414     public void deleteFileEntry(DLFileEntry fileEntry)
415         throws PortalException, SystemException {
416 
417         // File entry
418 
419         dlFileEntryPersistence.remove(fileEntry);
420 
421         // Resources
422 
423         resourceLocalService.deleteResource(
424             fileEntry.getCompanyId(), DLFileEntry.class.getName(),
425             ResourceConstants.SCOPE_INDIVIDUAL, fileEntry.getFileEntryId());
426 
427         // WebDAVProps
428 
429         webDAVPropsLocalService.deleteWebDAVProps(
430             DLFileEntry.class.getName(), fileEntry.getPrimaryKey());
431 
432         // File ranks
433 
434         dlFileRankLocalService.deleteFileRanks(
435             fileEntry.getFolderId(), fileEntry.getName());
436 
437         // File shortcuts
438 
439         dlFileShortcutLocalService.deleteFileShortcuts(
440             fileEntry.getFolderId(), fileEntry.getName());
441 
442         // File versions
443 
444         List<DLFileVersion> fileVersions = dlFileVersionPersistence.findByF_N(
445             fileEntry.getFolderId(), fileEntry.getName());
446 
447         for (DLFileVersion fileVersion : fileVersions) {
448             dlFileVersionPersistence.remove(fileVersion);
449         }
450 
451         // Expando
452 
453         expandoValueLocalService.deleteValues(
454             DLFileEntry.class.getName(), fileEntry.getFileEntryId());
455 
456         // Lock
457 
458         String lockId = DLUtil.getLockId(
459             fileEntry.getFolderId(), fileEntry.getName());
460 
461         lockLocalService.unlock(DLFileEntry.class.getName(), lockId);
462 
463         // Message boards
464 
465         mbMessageLocalService.deleteDiscussionMessages(
466             DLFileEntry.class.getName(), fileEntry.getFileEntryId());
467 
468         // Social
469 
470         socialActivityLocalService.deleteActivities(
471             DLFileEntry.class.getName(), fileEntry.getFileEntryId());
472 
473         // Ratings
474 
475         ratingsStatsLocalService.deleteStats(
476             DLFileEntry.class.getName(), fileEntry.getFileEntryId());
477 
478         // Tags
479 
480         tagsAssetLocalService.deleteAsset(
481             DLFileEntry.class.getName(), fileEntry.getFileEntryId());
482 
483         // File
484 
485         try {
486             dlService.deleteFile(
487                 fileEntry.getCompanyId(), PortletKeys.DOCUMENT_LIBRARY,
488                 fileEntry.getFolderId(), fileEntry.getName());
489         }
490         catch (Exception e) {
491             if (_log.isWarnEnabled()) {
492                 _log.warn(e, e);
493             }
494         }
495     }
496 
497     public void deleteFileEntry(long folderId, String name)
498         throws PortalException, SystemException {
499 
500         deleteFileEntry(folderId, name, -1);
501     }
502 
503     public void deleteFileEntry(long folderId, String name, double version)
504         throws PortalException, SystemException {
505 
506         DLFileEntry fileEntry = dlFileEntryPersistence.findByF_N(
507             folderId, name);
508 
509         if (version > 0) {
510             try {
511                 dlService.deleteFile(
512                     fileEntry.getCompanyId(), PortletKeys.DOCUMENT_LIBRARY,
513                     fileEntry.getFolderId(), fileEntry.getName(), version);
514             }
515             catch (Exception e) {
516                 if (_log.isWarnEnabled()) {
517                     _log.warn(e, e);
518                 }
519             }
520 
521             dlFileVersionPersistence.removeByF_N_V(folderId, name, version);
522 
523             if (version == fileEntry.getVersion()) {
524                 try {
525                     DLFileVersion fileVersion =
526                         dlFileVersionLocalService.getLatestFileVersion(
527                             folderId, name);
528 
529                     fileEntry.setVersion(fileVersion.getVersion());
530 
531                     dlFileEntryPersistence.update(fileEntry, false);
532                 }
533                 catch (NoSuchFileVersionException nsfve) {
534                 }
535             }
536         }
537         else {
538             deleteFileEntry(fileEntry);
539         }
540     }
541 
542     public List<DLFileEntry> getCompanyFileEntries(
543             long companyId, int start, int end)
544         throws SystemException {
545 
546         return dlFileEntryPersistence.findByCompanyId(companyId, start, end);
547     }
548 
549     public List<DLFileEntry> getCompanyFileEntries(
550             long companyId, int start, int end, OrderByComparator obc)
551         throws SystemException {
552 
553         return dlFileEntryPersistence.findByCompanyId(
554             companyId, start, end, obc);
555     }
556 
557     public int getCompanyFileEntriesCount(long companyId)
558         throws SystemException {
559 
560         return dlFileEntryPersistence.countByCompanyId(companyId);
561     }
562 
563     public InputStream getFileAsStream(
564             long companyId, long userId, long folderId, String name)
565         throws PortalException, SystemException {
566 
567         return getFileAsStream(companyId, userId, folderId, name, 0);
568     }
569 
570     public InputStream getFileAsStream(
571             long companyId, long userId, long folderId, String name,
572             double version)
573         throws PortalException, SystemException {
574 
575         DLFileEntry fileEntry = dlFileEntryPersistence.findByF_N(
576             folderId, name);
577 
578         if (userId > 0) {
579             dlFileRankLocalService.updateFileRank(
580                 fileEntry.getGroupId(), companyId, userId, folderId, name,
581                 new ServiceContext());
582         }
583 
584         if (PropsValues.DL_FILE_ENTRY_READ_COUNT_ENABLED) {
585             fileEntry.setReadCount(fileEntry.getReadCount() + 1);
586 
587             dlFileEntryPersistence.update(fileEntry, false);
588 
589             tagsAssetLocalService.incrementViewCounter(
590                 DLFileEntry.class.getName(), fileEntry.getFileEntryId());
591 
592             List<DLFileShortcut> fileShortcuts =
593                 dlFileShortcutPersistence.findByTF_TN(folderId, name);
594 
595             for (DLFileShortcut fileShortcut : fileShortcuts) {
596                 tagsAssetLocalService.incrementViewCounter(
597                     DLFileShortcut.class.getName(),
598                     fileShortcut.getFileShortcutId());
599             }
600         }
601 
602         if ((version > 0) && (fileEntry.getVersion() != version)) {
603             return dlLocalService.getFileAsStream(
604                 companyId, folderId, name, version);
605         }
606         else {
607             return dlLocalService.getFileAsStream(
608                 companyId, folderId, name, fileEntry.getVersion());
609         }
610     }
611 
612     public List<DLFileEntry> getFileEntries(long folderId)
613         throws SystemException {
614 
615         return dlFileEntryPersistence.findByFolderId(folderId);
616     }
617 
618     public List<DLFileEntry> getFileEntries(long folderId, int start, int end)
619         throws SystemException {
620 
621         return dlFileEntryPersistence.findByFolderId(folderId, start, end);
622     }
623 
624     public List<DLFileEntry> getFileEntries(
625             long folderId, int start, int end, OrderByComparator obc)
626         throws SystemException {
627 
628         return dlFileEntryPersistence.findByFolderId(folderId, start, end, obc);
629     }
630 
631     public int getFileEntriesCount(long folderId) throws SystemException {
632         return dlFileEntryPersistence.countByFolderId(folderId);
633     }
634 
635     public DLFileEntry getFileEntry(long fileEntryId)
636         throws PortalException, SystemException {
637 
638         return dlFileEntryPersistence.findByPrimaryKey(fileEntryId);
639     }
640 
641     public DLFileEntry getFileEntry(long folderId, String name)
642         throws PortalException, SystemException {
643 
644         return dlFileEntryPersistence.findByF_N(folderId, name);
645     }
646 
647     public DLFileEntry getFileEntryByTitle(
648             long folderId, String titleWithExtension)
649         throws PortalException, SystemException {
650 
651         String title = DLFileEntryImpl.stripExtension(
652             titleWithExtension, titleWithExtension);
653         String extension = FileUtil.getExtension(titleWithExtension);
654 
655         List<DLFileEntry> fileEntries = dlFileEntryPersistence.findByF_T(
656             folderId, title);
657 
658         for (DLFileEntry fileEntry : fileEntries) {
659             String curExtension = FileUtil.getExtension(fileEntry.getName());
660 
661             if (Validator.isNull(extension)) {
662                 if (Validator.isNull(curExtension)) {
663                     return fileEntry;
664                 }
665             }
666             else if (extension.equals(curExtension)) {
667                 return fileEntry;
668             }
669         }
670 
671         throw new NoSuchFileEntryException();
672     }
673 
674     public DLFileEntry getFileEntryByUuidAndGroupId(String uuid, long groupId)
675         throws PortalException, SystemException {
676 
677         return dlFileEntryPersistence.findByUUID_G(uuid, groupId);
678     }
679 
680     public int getFoldersFileEntriesCount(List<Long> folderIds)
681         throws SystemException {
682 
683         if (folderIds.size() <= PropsValues.SQL_DATA_MAX_PARAMETERS) {
684             return dlFileEntryFinder.countByFolderIds(folderIds);
685         }
686         else {
687             int start = 0;
688             int end = PropsValues.SQL_DATA_MAX_PARAMETERS;
689 
690             int filesCount = dlFileEntryFinder.countByFolderIds(
691                 folderIds.subList(start, end));
692 
693             folderIds.subList(start, end).clear();
694 
695             filesCount += getFoldersFileEntriesCount(folderIds);
696 
697             return filesCount;
698         }
699     }
700 
701     public List<DLFileEntry> getGroupFileEntries(
702             long groupId, int start, int end)
703         throws SystemException {
704 
705         return getGroupFileEntries(
706             groupId, start, end, new FileEntryModifiedDateComparator());
707     }
708 
709     public List<DLFileEntry> getGroupFileEntries(
710             long groupId, int start, int end, OrderByComparator obc)
711         throws SystemException {
712 
713         return dlFileEntryPersistence.findByGroupId(groupId, start, end, obc);
714     }
715 
716     public List<DLFileEntry> getGroupFileEntries(
717             long groupId, long userId, int start, int end)
718         throws SystemException {
719 
720         return getGroupFileEntries(
721             groupId, userId, start, end, new FileEntryModifiedDateComparator());
722     }
723 
724     public List<DLFileEntry> getGroupFileEntries(
725             long groupId, long userId, int start, int end,
726             OrderByComparator obc)
727         throws SystemException {
728 
729         if (userId <= 0) {
730             return dlFileEntryPersistence.findByGroupId(
731                 groupId, start, end, obc);
732         }
733         else {
734             return dlFileEntryPersistence.findByG_U(
735                 groupId, userId, start, end, obc);
736         }
737     }
738 
739     public int getGroupFileEntriesCount(long groupId) throws SystemException {
740         return dlFileEntryPersistence.countByGroupId(groupId);
741     }
742 
743     public int getGroupFileEntriesCount(long groupId, long userId)
744         throws SystemException {
745 
746         if (userId <= 0) {
747             return dlFileEntryPersistence.countByGroupId(groupId);
748         }
749         else {
750             return dlFileEntryPersistence.countByG_U(groupId, userId);
751         }
752     }
753 
754     public List<DLFileEntry> getNoAssetFileEntries() throws SystemException {
755         return dlFileEntryFinder.findByNoAssets();
756     }
757 
758     public void reIndex(long fileEntryId) throws SystemException {
759         if (SearchEngineUtil.isIndexReadOnly()) {
760             return;
761         }
762 
763         DLFileEntry fileEntry = dlFileEntryPersistence.fetchByPrimaryKey(
764             fileEntryId);
765 
766         if (fileEntry == null) {
767             return;
768         }
769 
770         DLFolder folder = fileEntry.getFolder();
771 
772         long companyId = fileEntry.getCompanyId();
773         String portletId = PortletKeys.DOCUMENT_LIBRARY;
774         long groupId = folder.getGroupId();
775         long userId = folder.getUserId();
776         long folderId = folder.getFolderId();
777         String fileName = fileEntry.getName();
778         String properties = fileEntry.getLuceneProperties();
779         Date modifiedDate = fileEntry.getModifiedDate();
780 
781         String[] tagsCategories = tagsEntryLocalService.getEntryNames(
782             DLFileEntry.class.getName(), fileEntryId,
783             TagsEntryConstants.FOLKSONOMY_CATEGORY);
784         String[] tagsEntries = tagsEntryLocalService.getEntryNames(
785             DLFileEntry.class.getName(), fileEntryId);
786 
787         try {
788             DLIndexerUtil.updateFile(
789                 companyId, portletId, groupId, userId, folderId, fileName,
790                 fileEntryId, properties, modifiedDate, tagsCategories,
791                 tagsEntries);
792         }
793         catch (SearchException se) {
794             _log.error("Reindexing " + fileEntryId, se);
795         }
796     }
797 
798     /**
799      * @deprecated
800      */
801     public DLFileEntry updateFileEntry(
802             long userId, long folderId, long newFolderId, String name,
803             String sourceFileName, String title, String description,
804             String extraSettings, byte[] bytes, ServiceContext serviceContext)
805         throws PortalException, SystemException {
806 
807         return updateFileEntry(
808             userId, folderId, newFolderId, name, sourceFileName, title,
809             description, null, extraSettings, bytes, serviceContext);
810     }
811 
812     /**
813      * @deprecated
814      */
815     public DLFileEntry updateFileEntry(
816             long userId, long folderId, long newFolderId, String name,
817             String sourceFileName, String title, String description,
818             String extraSettings, File file, ServiceContext serviceContext)
819         throws PortalException, SystemException {
820 
821         return updateFileEntry(
822             userId, folderId, newFolderId, name, sourceFileName, title,
823             description, null, extraSettings, file, serviceContext);
824     }
825 
826     public DLFileEntry updateFileEntry(
827             long userId, long folderId, long newFolderId, String name,
828             String sourceFileName, String title, String description,
829             String versionDescription, String extraSettings, byte[] bytes,
830             ServiceContext serviceContext)
831         throws PortalException, SystemException {
832 
833         InputStream is = null;
834         long size = 0;
835 
836         if (bytes != null) {
837             is = new UnsyncByteArrayInputStream(bytes);
838             size = bytes.length;
839         }
840 
841         return updateFileEntry(
842             userId, folderId, newFolderId, name, sourceFileName, title,
843             description, null, extraSettings, is, size, serviceContext);
844     }
845 
846     public DLFileEntry updateFileEntry(
847             long userId, long folderId, long newFolderId, String name,
848             String sourceFileName, String title, String description,
849             String versionDescription, String extraSettings, File file,
850             ServiceContext serviceContext)
851         throws PortalException, SystemException {
852 
853         try {
854             InputStream is = null;
855             long size = 0;
856 
857             if ((file != null) && file.exists()) {
858                 is = new UnsyncBufferedInputStream(new FileInputStream(file));
859                 size = file.length();
860             }
861 
862             return updateFileEntry(
863                 userId, folderId, newFolderId, name, sourceFileName, title,
864                 description, versionDescription, extraSettings, is, size,
865                 serviceContext);
866         }
867         catch (FileNotFoundException fnfe) {
868             throw new NoSuchFileException();
869         }
870     }
871 
872     public DLFileEntry updateFileEntry(
873             long userId, long folderId, long newFolderId, String name,
874             String sourceFileName, String title, String description,
875             String versionDescription, String extraSettings, InputStream is,
876             long size, ServiceContext serviceContext)
877         throws PortalException, SystemException {
878 
879         // File entry
880 
881         User user = userPersistence.findByPrimaryKey(userId);
882         DLFolder folder = dlFolderPersistence.findByPrimaryKey(folderId);
883 
884         if (Validator.isNull(title)) {
885             title = sourceFileName;
886 
887             if (Validator.isNull(title)) {
888                 title = name;
889             }
890         }
891 
892         title = DLFileEntryImpl.stripExtension(name, title);
893 
894         Date now = new Date();
895 
896         validate(
897             folder.getGroupId(), folderId, newFolderId, name, title,
898             sourceFileName, is);
899 
900         DLFileEntry fileEntry = dlFileEntryPersistence.findByF_N(
901             folderId, name);
902 
903         fileEntry.setTitle(title);
904         fileEntry.setDescription(description);
905         fileEntry.setExtraSettings(extraSettings);
906         fileEntry.setExpandoBridgeAttributes(serviceContext);
907 
908         dlFileEntryPersistence.update(fileEntry, false);
909 
910         // Move file entry
911 
912         if ((newFolderId > 0) && (folderId != newFolderId)) {
913             long oldFileEntryId = fileEntry.getFileEntryId();
914 
915             DLFolder newFolder = dlFolderPersistence.findByPrimaryKey(
916                 newFolderId);
917 
918             if (folder.getGroupId() != newFolder.getGroupId()) {
919                 throw new NoSuchFolderException();
920             }
921 
922             if (dlLocalService.hasFile(
923                     user.getCompanyId(), newFolderId, name, 0)) {
924 
925                 throw new DuplicateFileException(name);
926             }
927 
928             long newFileEntryId = counterLocalService.increment();
929 
930             DLFileEntry newFileEntry = dlFileEntryPersistence.create(
931                 newFileEntryId);
932 
933             newFileEntry.setGroupId(fileEntry.getGroupId());
934             newFileEntry.setCompanyId(fileEntry.getCompanyId());
935             newFileEntry.setUserId(fileEntry.getUserId());
936             newFileEntry.setUserName(fileEntry.getUserName());
937             newFileEntry.setVersionUserId(fileEntry.getVersionUserId());
938             newFileEntry.setVersionUserName(fileEntry.getVersionUserName());
939             newFileEntry.setCreateDate(fileEntry.getCreateDate());
940             newFileEntry.setModifiedDate(fileEntry.getModifiedDate());
941             newFileEntry.setFolderId(newFolderId);
942             newFileEntry.setName(name);
943             newFileEntry.setTitle(fileEntry.getTitle());
944             newFileEntry.setDescription(fileEntry.getDescription());
945             newFileEntry.setVersion(fileEntry.getVersion());
946             newFileEntry.setSize(fileEntry.getSize());
947             newFileEntry.setReadCount(fileEntry.getReadCount());
948             newFileEntry.setExtraSettings(extraSettings);
949 
950             dlFileEntryPersistence.update(newFileEntry, false);
951 
952             dlFileEntryPersistence.remove(fileEntry);
953 
954             List<DLFileVersion> fileVersions =
955                 dlFileVersionPersistence.findByF_N(folderId, name);
956 
957             for (DLFileVersion fileVersion : fileVersions) {
958                 long newFileVersionId = counterLocalService.increment();
959 
960                 DLFileVersion newFileVersion = dlFileVersionPersistence.create(
961                     newFileVersionId);
962 
963                 newFileVersion.setGroupId(fileVersion.getGroupId());
964                 newFileVersion.setCompanyId(fileVersion.getCompanyId());
965                 newFileVersion.setUserId(fileVersion.getUserId());
966                 newFileVersion.setUserName(fileVersion.getUserName());
967                 newFileVersion.setCreateDate(fileVersion.getCreateDate());
968                 newFileVersion.setFolderId(newFolderId);
969                 newFileVersion.setName(name);
970                 newFileVersion.setVersion(fileVersion.getVersion());
971                 newFileVersion.setSize(fileVersion.getSize());
972 
973                 dlFileVersionPersistence.update(newFileVersion, false);
974 
975                 dlFileVersionPersistence.remove(fileVersion);
976             }
977 
978             dlFileShortcutLocalService.updateFileShortcuts(
979                 folderId, name, newFolderId, name);
980 
981             // Resources
982 
983             Resource resource = resourceLocalService.getResource(
984                 fileEntry.getCompanyId(), DLFileEntry.class.getName(),
985                 ResourceConstants.SCOPE_INDIVIDUAL,
986                 String.valueOf(fileEntry.getPrimaryKey()));
987 
988             resource.setPrimKey(String.valueOf(newFileEntryId));
989 
990             resourcePersistence.update(resource, false);
991 
992             // Expando
993 
994             expandoValueLocalService.deleteValues(
995                 DLFileEntry.class.getName(), fileEntry.getFileEntryId());
996 
997             // Ratings
998 
999             RatingsStats stats = ratingsStatsLocalService.getStats(
1000                DLFileEntry.class.getName(), oldFileEntryId);
1001
1002            stats.setClassPK(newFileEntryId);
1003
1004            ratingsStatsPersistence.update(stats, false);
1005
1006            long classNameId = PortalUtil.getClassNameId(
1007                DLFileEntry.class.getName());
1008
1009            List<RatingsEntry> entries = ratingsEntryPersistence.findByC_C(
1010                classNameId, oldFileEntryId);
1011
1012            for (RatingsEntry entry : entries) {
1013                entry.setClassPK(newFileEntryId);
1014
1015                ratingsEntryPersistence.update(entry, false);
1016            }
1017
1018            // Message boards
1019
1020            MBDiscussion discussion = mbDiscussionPersistence.fetchByC_C(
1021                classNameId, oldFileEntryId);
1022
1023            if (discussion != null) {
1024                discussion.setClassPK(newFileEntryId);
1025
1026                mbDiscussionPersistence.update(discussion, false);
1027            }
1028
1029            // Social
1030
1031            socialActivityLocalService.deleteActivities(
1032                DLFileEntry.class.getName(), fileEntry.getFileEntryId());
1033
1034            // Tags
1035
1036            tagsAssetLocalService.deleteAsset(
1037                DLFileEntry.class.getName(), fileEntry.getFileEntryId());
1038
1039            List<DLFileShortcut> fileShortcuts =
1040                dlFileShortcutPersistence.findByTF_TN(folderId, name);
1041
1042            for (DLFileShortcut fileShortcut : fileShortcuts) {
1043                tagsAssetLocalService.deleteAsset(
1044                    DLFileShortcut.class.getName(),
1045                    fileShortcut.getFileShortcutId());
1046            }
1047
1048            // File
1049
1050            dlService.updateFile(
1051                user.getCompanyId(), PortletKeys.DOCUMENT_LIBRARY,
1052                newFileEntry.getGroupId(), folderId, newFolderId, name,
1053                newFileEntryId);
1054
1055            folderId = newFolderId;
1056            folder = newFolder;
1057            fileEntry = newFileEntry;
1058        }
1059
1060        // Social
1061
1062        socialActivityLocalService.addActivity(
1063            userId, fileEntry.getGroupId(), DLFileEntry.class.getName(),
1064            fileEntry.getFileEntryId(), DLActivityKeys.UPDATE_FILE_ENTRY,
1065            StringPool.BLANK, 0);
1066
1067        // Tags
1068
1069        updateTagsAsset(
1070            userId, fileEntry, serviceContext.getTagsCategories(),
1071            serviceContext.getTagsEntries());
1072
1073        // File version
1074
1075        double oldVersion = fileEntry.getVersion();
1076        double newVersion = MathUtil.format(oldVersion + 0.1, 1, 1);
1077
1078        if (is == null) {
1079            fileEntry.setVersion(newVersion);
1080
1081            dlFileEntryPersistence.update(fileEntry, false);
1082
1083            int fetchFailures = 0;
1084
1085            while (is == null) {
1086                try {
1087                    is = dlLocalService.getFileAsStream(
1088                        user.getCompanyId(), folderId, name);
1089                }
1090                catch (NoSuchFileException nsfe) {
1091                    fetchFailures++;
1092
1093                    if (PropsValues.DL_HOOK_IMPL.equals(
1094                            JCRHook.class.getName()) &&
1095                        (fetchFailures <
1096                            PropsValues.DL_HOOK_JCR_FETCH_MAX_FAILURES)) {
1097
1098                        try {
1099                            Thread.sleep(PropsValues.DL_HOOK_JCR_FETCH_DELAY);
1100                        }
1101                        catch (InterruptedException ie) {
1102                        }
1103                    }
1104                    else {
1105                        throw nsfe;
1106                    }
1107                }
1108            }
1109
1110            dlLocalService.updateFile(
1111                user.getCompanyId(), PortletKeys.DOCUMENT_LIBRARY,
1112                fileEntry.getGroupId(), folderId, name, newVersion, name,
1113                fileEntry.getFileEntryId(), fileEntry.getLuceneProperties(),
1114                fileEntry.getModifiedDate(), serviceContext.getTagsCategories(),
1115                serviceContext.getTagsEntries(), is);
1116
1117            return fileEntry;
1118        }
1119
1120        addFileVersion(
1121            user, fileEntry, serviceContext.getModifiedDate(now), newVersion,
1122            versionDescription);
1123
1124        // File entry
1125
1126        fileEntry.setVersionUserId(user.getUserId());
1127        fileEntry.setVersionUserName(user.getFullName());
1128        fileEntry.setModifiedDate(serviceContext.getModifiedDate(now));
1129        fileEntry.setVersion(newVersion);
1130        fileEntry.setSize((int)size);
1131
1132        dlFileEntryPersistence.update(fileEntry, false);
1133
1134        // Folder
1135
1136        folder.setLastPostDate(fileEntry.getModifiedDate());
1137
1138        dlFolderPersistence.update(folder, false);
1139
1140        // File
1141
1142        dlLocalService.updateFile(
1143            user.getCompanyId(), PortletKeys.DOCUMENT_LIBRARY,
1144            fileEntry.getGroupId(), folderId, name, newVersion, sourceFileName,
1145            fileEntry.getFileEntryId(), fileEntry.getLuceneProperties(),
1146            fileEntry.getModifiedDate(), serviceContext.getTagsCategories(),
1147            serviceContext.getTagsEntries(), is);
1148
1149        return fileEntry;
1150    }
1151
1152    public void updateTagsAsset(
1153            long userId, DLFileEntry fileEntry, String[] tagsCategories,
1154            String[] tagsEntries)
1155        throws PortalException, SystemException {
1156
1157        String mimeType = MimeTypesUtil.getContentType(fileEntry.getName());
1158
1159        tagsAssetLocalService.updateAsset(
1160            userId, fileEntry.getGroupId(), DLFileEntry.class.getName(),
1161            fileEntry.getFileEntryId(), tagsCategories, tagsEntries, true, null,
1162            null, null, null, mimeType, fileEntry.getTitle(),
1163            fileEntry.getDescription(), null, null, 0, 0, null, false);
1164
1165        List<DLFileShortcut> fileShortcuts =
1166            dlFileShortcutPersistence.findByTF_TN(
1167                fileEntry.getFolderId(), fileEntry.getName());
1168
1169        for (DLFileShortcut fileShortcut : fileShortcuts) {
1170            tagsAssetLocalService.updateAsset(
1171                userId, fileShortcut.getGroupId(),
1172                DLFileShortcut.class.getName(),
1173                fileShortcut.getFileShortcutId(), tagsCategories, tagsEntries,
1174                true, null, null, null, null, mimeType, fileEntry.getTitle(),
1175                fileEntry.getDescription(), null, null, 0, 0, null, false);
1176        }
1177    }
1178
1179    protected void addFileVersion(
1180            User user, DLFileEntry fileEntry, Date modifiedDate, double version,
1181            String description)
1182        throws SystemException {
1183
1184        long fileVersionId = counterLocalService.increment();
1185
1186        DLFileVersion fileVersion = dlFileVersionPersistence.create(
1187            fileVersionId);
1188
1189        long versionUserId = fileEntry.getVersionUserId();
1190
1191        if (versionUserId <= 0) {
1192            versionUserId = fileEntry.getUserId();
1193        }
1194
1195        String versionUserName = GetterUtil.getString(
1196            fileEntry.getVersionUserName(), fileEntry.getUserName());
1197
1198        fileVersion.setGroupId(fileEntry.getGroupId());
1199        fileVersion.setCompanyId(fileEntry.getCompanyId());
1200        fileVersion.setUserId(versionUserId);
1201        fileVersion.setUserName(versionUserName);
1202        fileVersion.setCreateDate(modifiedDate);
1203        fileVersion.setFolderId(fileEntry.getFolderId());
1204        fileVersion.setName(fileEntry.getName());
1205        fileVersion.setDescription(description);
1206        fileVersion.setVersion(version);
1207        fileVersion.setSize(fileEntry.getSize());
1208
1209        dlFileVersionPersistence.update(fileVersion, false);
1210    }
1211
1212    protected long getFolderId(long companyId, long folderId)
1213        throws SystemException {
1214
1215        if (folderId != DLFolderConstants.DEFAULT_PARENT_FOLDER_ID) {
1216
1217            // Ensure folder exists and belongs to the proper company
1218
1219            DLFolder folder = dlFolderPersistence.fetchByPrimaryKey(folderId);
1220
1221            if ((folder == null) || (companyId != folder.getCompanyId())) {
1222                folderId = DLFolderConstants.DEFAULT_PARENT_FOLDER_ID;
1223            }
1224        }
1225
1226        return folderId;
1227    }
1228
1229    protected String getName(String name) throws SystemException {
1230        String extension = StringPool.BLANK;
1231
1232        int pos = name.lastIndexOf(StringPool.PERIOD);
1233
1234        if (pos != -1) {
1235            extension = name.substring(pos + 1, name.length()).toLowerCase();
1236        }
1237
1238        name = String.valueOf(counterLocalService.increment(
1239            DLFileEntry.class.getName()));
1240
1241        if (Validator.isNotNull(extension)) {
1242            name = "DLFE-" + name + StringPool.PERIOD + extension;
1243        }
1244
1245        return name;
1246    }
1247
1248    protected void validate(
1249            long groupId, long folderId, long newFolderId, String name,
1250            String title, String sourceFileName, InputStream is)
1251        throws PortalException, SystemException {
1252
1253        if (Validator.isNotNull(sourceFileName)) {
1254            dlLocalService.validate(name, sourceFileName, is);
1255        }
1256
1257        if (newFolderId > 0 && (folderId != newFolderId)) {
1258            folderId = newFolderId;
1259        }
1260
1261        String extension = FileUtil.getExtension(name);
1262
1263        try {
1264            String titleWithExtension = title;
1265
1266            if (Validator.isNotNull(extension)) {
1267                titleWithExtension += StringPool.PERIOD + extension;
1268            }
1269
1270            dlFolderLocalService.getFolder(
1271                groupId, folderId, titleWithExtension);
1272
1273            throw new DuplicateFolderNameException();
1274        }
1275        catch (NoSuchFolderException nsfe) {
1276        }
1277
1278        List<DLFileEntry> fileEntries = dlFileEntryPersistence.findByF_T(
1279            folderId, title);
1280
1281        for (DLFileEntry fileEntry : fileEntries) {
1282            if (!name.equals(fileEntry.getName())) {
1283                String curExtension = FileUtil.getExtension(
1284                    fileEntry.getName());
1285
1286                if (Validator.isNull(extension)) {
1287                    if (Validator.isNull(curExtension)) {
1288                        throw new DuplicateFileException(
1289                            fileEntry.getTitleWithExtension());
1290                    }
1291                }
1292                else if (extension.equals(curExtension)) {
1293                    throw new DuplicateFileException(
1294                        fileEntry.getTitleWithExtension());
1295                }
1296            }
1297        }
1298    }
1299
1300    protected void validate(
1301            long groupId, long folderId, String name, String title,
1302            InputStream is)
1303        throws PortalException, SystemException {
1304
1305        dlLocalService.validate(name, is);
1306
1307        String extension = FileUtil.getExtension(name);
1308
1309        try {
1310            String titleWithExtension = title;
1311
1312            if (Validator.isNotNull(extension)) {
1313                titleWithExtension += StringPool.PERIOD + extension;
1314            }
1315
1316            dlFolderLocalService.getFolder(
1317                groupId, folderId, titleWithExtension);
1318
1319            throw new DuplicateFolderNameException();
1320        }
1321        catch (NoSuchFolderException nsfe) {
1322        }
1323
1324        List<DLFileEntry> fileEntries = dlFileEntryPersistence.findByF_T(
1325            folderId, title);
1326
1327        for (DLFileEntry fileEntry : fileEntries) {
1328            String curExtension = FileUtil.getExtension(fileEntry.getName());
1329
1330            if (Validator.isNull(extension)) {
1331                if (Validator.isNull(curExtension)) {
1332                    throw new DuplicateFileException(
1333                        fileEntry.getTitleWithExtension());
1334                }
1335            }
1336            else if (extension.equals(curExtension)) {
1337                throw new DuplicateFileException(
1338                    fileEntry.getTitleWithExtension());
1339            }
1340        }
1341    }
1342
1343    private static Log _log = LogFactoryUtil.getLog(
1344        DLFileEntryLocalServiceImpl.class);
1345
1346}