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