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