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