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