1   /**
2    * Copyright (c) 2000-2009 Liferay, Inc. All rights reserved.
3    *
4    *
5    *
6    *
7    * The contents of this file are subject to the terms of the Liferay Enterprise
8    * Subscription License ("License"). You may not use this file except in
9    * compliance with the License. You can obtain a copy of the License by
10   * contacting Liferay, Inc. See the License for the specific language governing
11   * permissions and limitations under the License, including but not limited to
12   * distribution rights 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.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.DLFileShortcut;
55  import com.liferay.portlet.documentlibrary.model.DLFileVersion;
56  import com.liferay.portlet.documentlibrary.model.DLFolder;
57  import com.liferay.portlet.documentlibrary.model.DLFolderConstants;
58  import com.liferay.portlet.documentlibrary.model.impl.DLFileEntryImpl;
59  import com.liferay.portlet.documentlibrary.service.base.DLFileEntryLocalServiceBaseImpl;
60  import com.liferay.portlet.documentlibrary.social.DLActivityKeys;
61  import com.liferay.portlet.documentlibrary.util.comparator.FileEntryModifiedDateComparator;
62  import com.liferay.portlet.expando.model.ExpandoBridge;
63  import com.liferay.portlet.messageboards.model.MBDiscussion;
64  import com.liferay.portlet.ratings.model.RatingsEntry;
65  import com.liferay.portlet.ratings.model.RatingsStats;
66  import com.liferay.portlet.tags.model.TagsEntryConstants;
67  
68  import java.io.BufferedInputStream;
69  import java.io.ByteArrayInputStream;
70  import java.io.File;
71  import java.io.FileInputStream;
72  import java.io.FileNotFoundException;
73  import java.io.IOException;
74  import java.io.InputStream;
75  
76  import java.util.Date;
77  import java.util.List;
78  
79  /**
80   * <a href="DLFileEntryLocalServiceImpl.java.html"><b><i>View Source</i></b></a>
81   *
82   * <p>
83   * For DLFileEntries, the naming convention for some of the variables is not
84   * very informative, due to legacy code. Each DLFileEntry has a corresponding
85   * name and title. The "name" is a unique identifier for a given file and
86   * usually follows the format "DLFE-1234.xls" whereas the "title" is the actual
87   * name specified by the user (e.g., "Budget.xls").
88   * </p>
89   *
90   * @author Brian Wing Shun Chan
91   * @author Harry Mark
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         List<DLFileShortcut> fileShortcuts =
525             dlFileShortcutPersistence.findByTF_TN(folderId, name);
526 
527         for (DLFileShortcut fileShortcut : fileShortcuts) {
528             tagsAssetLocalService.incrementViewCounter(
529                 DLFileShortcut.class.getName(),
530                 fileShortcut.getFileShortcutId());
531         }
532 
533         if ((version > 0) && (fileEntry.getVersion() != version)) {
534             return dlLocalService.getFileAsStream(
535                 companyId, folderId, name, version);
536         }
537         else {
538             return dlLocalService.getFileAsStream(companyId, folderId, name);
539         }
540     }
541 
542     public List<DLFileEntry> getFileEntries(long folderId)
543         throws SystemException {
544 
545         return dlFileEntryPersistence.findByFolderId(folderId);
546     }
547 
548     public List<DLFileEntry> getFileEntries(long folderId, int start, int end)
549         throws SystemException {
550 
551         return dlFileEntryPersistence.findByFolderId(folderId, start, end);
552     }
553 
554     public List<DLFileEntry> getFileEntries(
555             long folderId, int start, int end, OrderByComparator obc)
556         throws SystemException {
557 
558         return dlFileEntryPersistence.findByFolderId(folderId, start, end, obc);
559     }
560 
561     public int getFileEntriesCount(long folderId) throws SystemException {
562         return dlFileEntryPersistence.countByFolderId(folderId);
563     }
564 
565     public DLFileEntry getFileEntry(long fileEntryId)
566         throws PortalException, SystemException {
567 
568         return dlFileEntryPersistence.findByPrimaryKey(fileEntryId);
569     }
570 
571     public DLFileEntry getFileEntry(long folderId, String name)
572         throws PortalException, SystemException {
573 
574         return dlFileEntryPersistence.findByF_N(folderId, name);
575     }
576 
577     public DLFileEntry getFileEntryByUuidAndGroupId(String uuid, long groupId)
578         throws PortalException, SystemException {
579 
580         return dlFileEntryPersistence.findByUUID_G(uuid, groupId);
581     }
582 
583     public DLFileEntry getFileEntryByTitle(
584             long folderId, String titleWithExtension)
585         throws PortalException, SystemException {
586 
587         String title = DLFileEntryImpl.stripExtension(
588             titleWithExtension, titleWithExtension);
589         String extension = FileUtil.getExtension(titleWithExtension);
590 
591         List<DLFileEntry> fileEntries = dlFileEntryPersistence.findByF_T(
592             folderId, title);
593 
594         for (DLFileEntry fileEntry : fileEntries) {
595             String curExtension = FileUtil.getExtension(fileEntry.getName());
596 
597             if (PropsValues.WEBDAV_LITMUS && Validator.isNull(extension)) {
598                 if (Validator.isNull(curExtension)) {
599                     return fileEntry;
600                 }
601             }
602             else if (extension.equals(curExtension)) {
603                 return fileEntry;
604             }
605         }
606 
607         throw new NoSuchFileEntryException();
608     }
609 
610     public int getFoldersFileEntriesCount(List<Long> folderIds)
611         throws SystemException {
612 
613         return dlFileEntryFinder.countByFolderIds(folderIds);
614     }
615 
616     public List<DLFileEntry> getGroupFileEntries(
617             long groupId, int start, int end)
618         throws SystemException {
619 
620         return getGroupFileEntries(
621             groupId, start, end, new FileEntryModifiedDateComparator());
622     }
623 
624     public List<DLFileEntry> getGroupFileEntries(
625             long groupId, int start, int end, OrderByComparator obc)
626         throws SystemException {
627 
628         return dlFileEntryPersistence.findByGroupId(groupId, start, end, obc);
629     }
630 
631     public List<DLFileEntry> getGroupFileEntries(
632             long groupId, long userId, int start, int end)
633         throws SystemException {
634 
635         return getGroupFileEntries(
636             groupId, userId, start, end, new FileEntryModifiedDateComparator());
637     }
638 
639     public List<DLFileEntry> getGroupFileEntries(
640             long groupId, long userId, int start, int end,
641             OrderByComparator obc)
642         throws SystemException {
643 
644         if (userId <= 0) {
645             return dlFileEntryPersistence.findByGroupId(
646                 groupId, start, end, obc);
647         }
648         else {
649             return dlFileEntryPersistence.findByG_U(
650                 groupId, userId, start, end, obc);
651         }
652     }
653 
654     public int getGroupFileEntriesCount(long groupId) throws SystemException {
655         return dlFileEntryPersistence.countByGroupId(groupId);
656     }
657 
658     public int getGroupFileEntriesCount(long groupId, long userId)
659         throws SystemException {
660 
661         if (userId <= 0) {
662             return dlFileEntryPersistence.countByGroupId(groupId);
663         }
664         else {
665             return dlFileEntryPersistence.countByG_U(groupId, userId);
666         }
667     }
668 
669     public List<DLFileEntry> getNoAssetFileEntries() throws SystemException {
670         return dlFileEntryFinder.findByNoAssets();
671     }
672 
673     public void reIndex(long fileEntryId) throws SystemException {
674         if (SearchEngineUtil.isIndexReadOnly()) {
675             return;
676         }
677 
678         DLFileEntry fileEntry = dlFileEntryPersistence.fetchByPrimaryKey(
679             fileEntryId);
680 
681         if (fileEntry == null) {
682             return;
683         }
684 
685         DLFolder folder = fileEntry.getFolder();
686 
687         long companyId = fileEntry.getCompanyId();
688         String portletId = PortletKeys.DOCUMENT_LIBRARY;
689         long groupId = folder.getGroupId();
690         long folderId = folder.getFolderId();
691         String fileName = fileEntry.getName();
692         String properties = fileEntry.getLuceneProperties();
693         Date modifiedDate = fileEntry.getModifiedDate();
694 
695         String[] tagsCategories = tagsEntryLocalService.getEntryNames(
696             DLFileEntry.class.getName(), fileEntryId,
697             TagsEntryConstants.FOLKSONOMY_CATEGORY);
698         String[] tagsEntries = tagsEntryLocalService.getEntryNames(
699             DLFileEntry.class.getName(), fileEntryId);
700 
701         try {
702             DLIndexerUtil.updateFile(
703                 companyId, portletId, groupId, folderId, fileName, fileEntryId,
704                 properties, modifiedDate, tagsCategories, tagsEntries);
705         }
706         catch (SearchException se) {
707             _log.error("Reindexing " + fileEntryId, se);
708         }
709     }
710 
711     public DLFileEntry updateFileEntry(
712             long userId, long folderId, long newFolderId, String name,
713             String sourceFileName, String title, String description,
714             String extraSettings, File file, ServiceContext serviceContext)
715         throws PortalException, SystemException {
716 
717         InputStream is = null;
718 
719         try {
720             long size = 0;
721 
722             if ((file != null) && (file.length() > 0)) {
723                 is = new BufferedInputStream(new FileInputStream(file));
724                 size = file.length();
725             }
726 
727             return updateFileEntry(
728                 userId, folderId, newFolderId, name, sourceFileName, title,
729                 description, extraSettings, is, size, serviceContext);
730         }
731         catch (FileNotFoundException fnfe) {
732             throw new NoSuchFileException();
733         }
734         finally {
735             try {
736                 if (is != null) {
737                     is.close();
738                 }
739             }
740             catch (IOException ioe) {
741                 _log.error(ioe);
742             }
743         }
744     }
745 
746     public DLFileEntry updateFileEntry(
747             long userId, long folderId, long newFolderId, String name,
748             String sourceFileName, String title, String description,
749             String extraSettings, byte[] bytes, ServiceContext serviceContext)
750         throws PortalException, SystemException {
751 
752         InputStream is = null;
753         long size = 0;
754 
755         if ((bytes != null) && (bytes.length > 0)) {
756             is = new ByteArrayInputStream(bytes);
757             size = bytes.length;
758         }
759 
760         return updateFileEntry(
761             userId, folderId, newFolderId, name, sourceFileName, title,
762             description, extraSettings, is, size, serviceContext);
763     }
764 
765     public DLFileEntry updateFileEntry(
766             long userId, long folderId, long newFolderId, String name,
767             String sourceFileName, String title, String description,
768             String extraSettings, InputStream is, long size,
769             ServiceContext serviceContext)
770         throws PortalException, SystemException {
771 
772         // File entry
773 
774         User user = userPersistence.findByPrimaryKey(userId);
775         DLFolder folder = dlFolderPersistence.findByPrimaryKey(folderId);
776 
777         if (Validator.isNull(title)) {
778             title = sourceFileName;
779 
780             if (Validator.isNull(title)) {
781                 title = name;
782             }
783         }
784 
785         title = DLFileEntryImpl.stripExtension(name, title);
786 
787         validate(
788             folder.getGroupId(), folderId, newFolderId, name, title,
789             sourceFileName, is);
790 
791         DLFileEntry fileEntry = dlFileEntryPersistence.findByF_N(
792             folderId, name);
793 
794         fileEntry.setTitle(title);
795         fileEntry.setDescription(description);
796         fileEntry.setExtraSettings(extraSettings);
797 
798         dlFileEntryPersistence.update(fileEntry, false);
799 
800         // Move file entry
801 
802         if ((newFolderId > 0) && (folderId != newFolderId)) {
803             long oldFileEntryId = fileEntry.getFileEntryId();
804 
805             DLFolder newFolder = dlFolderPersistence.findByPrimaryKey(
806                 newFolderId);
807 
808             if (folder.getGroupId() != newFolder.getGroupId()) {
809                 throw new NoSuchFolderException();
810             }
811 
812             if (dlLocalService.hasFile(
813                     user.getCompanyId(), newFolderId, name, 0)) {
814 
815                 throw new DuplicateFileException(name);
816             }
817 
818             long newFileEntryId = counterLocalService.increment();
819 
820             DLFileEntry newFileEntry = dlFileEntryPersistence.create(
821                 newFileEntryId);
822 
823             newFileEntry.setGroupId(fileEntry.getGroupId());
824             newFileEntry.setCompanyId(fileEntry.getCompanyId());
825             newFileEntry.setUserId(fileEntry.getUserId());
826             newFileEntry.setUserName(fileEntry.getUserName());
827             newFileEntry.setVersionUserId(fileEntry.getVersionUserId());
828             newFileEntry.setVersionUserName(fileEntry.getVersionUserName());
829             newFileEntry.setCreateDate(fileEntry.getCreateDate());
830             newFileEntry.setModifiedDate(fileEntry.getModifiedDate());
831             newFileEntry.setFolderId(newFolderId);
832             newFileEntry.setName(name);
833             newFileEntry.setTitle(fileEntry.getTitle());
834             newFileEntry.setDescription(fileEntry.getDescription());
835             newFileEntry.setVersion(fileEntry.getVersion());
836             newFileEntry.setSize(fileEntry.getSize());
837             newFileEntry.setReadCount(fileEntry.getReadCount());
838             newFileEntry.setExtraSettings(extraSettings);
839 
840             dlFileEntryPersistence.update(newFileEntry, false);
841 
842             dlFileEntryPersistence.remove(fileEntry);
843 
844             List<DLFileVersion> fileVersions =
845                 dlFileVersionPersistence.findByF_N(folderId, name);
846 
847             for (DLFileVersion fileVersion : fileVersions) {
848                 long newFileVersionId = counterLocalService.increment();
849 
850                 DLFileVersion newFileVersion = dlFileVersionPersistence.create(
851                     newFileVersionId);
852 
853                 newFileVersion.setGroupId(fileVersion.getGroupId());
854                 newFileVersion.setCompanyId(fileVersion.getCompanyId());
855                 newFileVersion.setUserId(fileVersion.getUserId());
856                 newFileVersion.setUserName(fileVersion.getUserName());
857                 newFileVersion.setCreateDate(fileVersion.getCreateDate());
858                 newFileVersion.setFolderId(newFolderId);
859                 newFileVersion.setName(name);
860                 newFileVersion.setVersion(fileVersion.getVersion());
861                 newFileVersion.setSize(fileVersion.getSize());
862 
863                 dlFileVersionPersistence.update(newFileVersion, false);
864 
865                 dlFileVersionPersistence.remove(fileVersion);
866             }
867 
868             dlFileShortcutLocalService.updateFileShortcuts(
869                 folderId, name, newFolderId, name);
870 
871             // Resources
872 
873             Resource resource = resourceLocalService.getResource(
874                 fileEntry.getCompanyId(), DLFileEntry.class.getName(),
875                 ResourceConstants.SCOPE_INDIVIDUAL,
876                 String.valueOf(fileEntry.getPrimaryKey()));
877 
878             resource.setPrimKey(String.valueOf(newFileEntryId));
879 
880             resourcePersistence.update(resource, false);
881 
882             // Expando
883 
884             expandoValueLocalService.deleteValues(
885                 DLFileEntry.class.getName(), fileEntry.getFileEntryId());
886 
887             // File
888 
889             dlService.updateFile(
890                 user.getCompanyId(), PortletKeys.DOCUMENT_LIBRARY,
891                 newFileEntry.getGroupId(), folderId, newFolderId, name,
892                 newFileEntryId);
893 
894             // Ratings
895 
896             RatingsStats stats = ratingsStatsLocalService.getStats(
897                 DLFileEntry.class.getName(), oldFileEntryId);
898 
899             stats.setClassPK(newFileEntryId);
900 
901             ratingsStatsPersistence.update(stats, false);
902 
903             long classNameId = PortalUtil.getClassNameId(
904                 DLFileEntry.class.getName());
905 
906             List<RatingsEntry> entries = ratingsEntryPersistence.findByC_C(
907                 classNameId, oldFileEntryId);
908 
909             for (RatingsEntry entry : entries) {
910                 entry.setClassPK(newFileEntryId);
911 
912                 ratingsEntryPersistence.update(entry, false);
913             }
914 
915             // Message boards
916 
917             MBDiscussion discussion = mbDiscussionPersistence.fetchByC_C(
918                 classNameId, oldFileEntryId);
919 
920             if (discussion != null) {
921                 discussion.setClassPK(newFileEntryId);
922 
923                 mbDiscussionPersistence.update(discussion, false);
924             }
925 
926             // Social
927 
928             socialActivityLocalService.deleteActivities(
929                 DLFileEntry.class.getName(), fileEntry.getFileEntryId());
930 
931             // Tags
932 
933             tagsAssetLocalService.deleteAsset(
934                 DLFileEntry.class.getName(), fileEntry.getFileEntryId());
935 
936             List<DLFileShortcut> fileShortcuts =
937                 dlFileShortcutPersistence.findByTF_TN(folderId, name);
938 
939             for (DLFileShortcut fileShortcut : fileShortcuts) {
940                 tagsAssetLocalService.deleteAsset(
941                     DLFileShortcut.class.getName(),
942                     fileShortcut.getFileShortcutId());
943             }
944 
945             folderId = newFolderId;
946             folder = newFolder;
947             fileEntry = newFileEntry;
948         }
949 
950         // Expando
951 
952         ExpandoBridge expandoBridge = fileEntry.getExpandoBridge();
953 
954         expandoBridge.setAttributes(serviceContext);
955 
956         // Social
957 
958         socialActivityLocalService.addActivity(
959             userId, fileEntry.getGroupId(), DLFileEntry.class.getName(),
960             fileEntry.getFileEntryId(), DLActivityKeys.UPDATE_FILE_ENTRY,
961             StringPool.BLANK, 0);
962 
963         // Tags
964 
965         updateTagsAsset(
966             userId, fileEntry, serviceContext.getTagsCategories(),
967             serviceContext.getTagsEntries());
968 
969         // File version
970 
971         double oldVersion = fileEntry.getVersion();
972         double newVersion = MathUtil.format(oldVersion + 0.1, 1, 1);
973 
974         if (is == null) {
975             fileEntry.setVersion(newVersion);
976 
977             dlFileEntryPersistence.update(fileEntry, false);
978 
979             is = dlLocalService.getFileAsStream(
980                 user.getCompanyId(), folderId, name);
981 
982             dlLocalService.updateFile(
983                 user.getCompanyId(), PortletKeys.DOCUMENT_LIBRARY,
984                 fileEntry.getGroupId(), folderId, name, newVersion, name,
985                 fileEntry.getFileEntryId(), fileEntry.getLuceneProperties(),
986                 fileEntry.getModifiedDate(), serviceContext.getTagsCategories(),
987                 serviceContext.getTagsEntries(), is);
988 
989             return fileEntry;
990         }
991 
992         long fileVersionId = counterLocalService.increment();
993 
994         DLFileVersion fileVersion = dlFileVersionPersistence.create(
995             fileVersionId);
996 
997         long versionUserId = fileEntry.getVersionUserId();
998 
999         if (versionUserId <= 0) {
1000            versionUserId = fileEntry.getUserId();
1001        }
1002
1003        String versionUserName = GetterUtil.getString(
1004            fileEntry.getVersionUserName(), fileEntry.getUserName());
1005
1006        fileVersion.setGroupId(fileEntry.getGroupId());
1007        fileVersion.setCompanyId(fileEntry.getCompanyId());
1008        fileVersion.setUserId(versionUserId);
1009        fileVersion.setUserName(versionUserName);
1010        fileVersion.setCreateDate(fileEntry.getModifiedDate());
1011        fileVersion.setFolderId(folderId);
1012        fileVersion.setName(name);
1013        fileVersion.setVersion(oldVersion);
1014        fileVersion.setSize(fileEntry.getSize());
1015
1016        dlFileVersionPersistence.update(fileVersion, false);
1017
1018        // File entry
1019
1020        fileEntry.setVersionUserId(user.getUserId());
1021        fileEntry.setVersionUserName(user.getFullName());
1022        fileEntry.setModifiedDate(new Date());
1023        fileEntry.setVersion(newVersion);
1024        fileEntry.setSize((int)size);
1025
1026        dlFileEntryPersistence.update(fileEntry, false);
1027
1028        // File
1029
1030        dlLocalService.updateFile(
1031            user.getCompanyId(), PortletKeys.DOCUMENT_LIBRARY,
1032            fileEntry.getGroupId(), folderId, name, newVersion, sourceFileName,
1033            fileEntry.getFileEntryId(), fileEntry.getLuceneProperties(),
1034            fileEntry.getModifiedDate(), serviceContext.getTagsCategories(),
1035            serviceContext.getTagsEntries(), is);
1036
1037        // Folder
1038
1039        folder.setLastPostDate(fileEntry.getModifiedDate());
1040
1041        dlFolderPersistence.update(folder, false);
1042
1043        return fileEntry;
1044    }
1045
1046    public void updateTagsAsset(
1047            long userId, DLFileEntry fileEntry, String[] tagsCategories,
1048            String[] tagsEntries)
1049        throws PortalException, SystemException {
1050
1051        String mimeType = MimeTypesUtil.getContentType(fileEntry.getName());
1052
1053        tagsAssetLocalService.updateAsset(
1054            userId, fileEntry.getGroupId(), DLFileEntry.class.getName(),
1055            fileEntry.getFileEntryId(), tagsCategories, tagsEntries, true, null,
1056            null, null, null, mimeType, fileEntry.getTitle(),
1057            fileEntry.getDescription(), null, null, 0, 0, null, false);
1058
1059        List<DLFileShortcut> fileShortcuts =
1060            dlFileShortcutPersistence.findByTF_TN(
1061                fileEntry.getFolderId(), fileEntry.getName());
1062
1063        for (DLFileShortcut fileShortcut : fileShortcuts) {
1064            tagsAssetLocalService.updateAsset(
1065                userId, fileShortcut.getGroupId(),
1066                DLFileShortcut.class.getName(),
1067                fileShortcut.getFileShortcutId(), tagsCategories, tagsEntries,
1068                true, null, null, null, null, mimeType, fileEntry.getTitle(),
1069                fileEntry.getDescription(), null, null, 0, 0, null, false);
1070        }
1071    }
1072
1073    protected long getFolderId(long companyId, long folderId)
1074        throws SystemException {
1075
1076        if (folderId != DLFolderConstants.DEFAULT_PARENT_FOLDER_ID) {
1077
1078            // Ensure folder exists and belongs to the proper company
1079
1080            DLFolder folder = dlFolderPersistence.fetchByPrimaryKey(folderId);
1081
1082            if ((folder == null) || (companyId != folder.getCompanyId())) {
1083                folderId = DLFolderConstants.DEFAULT_PARENT_FOLDER_ID;
1084            }
1085        }
1086
1087        return folderId;
1088    }
1089
1090    protected String getName(String name) throws SystemException {
1091        String extension = StringPool.BLANK;
1092
1093        int pos = name.lastIndexOf(StringPool.PERIOD);
1094
1095        if (pos != -1) {
1096            extension = name.substring(pos + 1, name.length()).toLowerCase();
1097        }
1098
1099        name = String.valueOf(counterLocalService.increment(
1100            DLFileEntry.class.getName()));
1101
1102        if (Validator.isNotNull(extension)) {
1103            name = "DLFE-" + name + StringPool.PERIOD + extension;
1104        }
1105
1106        return name;
1107    }
1108
1109    protected void validate(
1110            long groupId, long folderId, long newFolderId, String name,
1111            String title, String sourceFileName, InputStream is)
1112        throws PortalException, SystemException {
1113
1114        if (Validator.isNotNull(sourceFileName)) {
1115            dlLocalService.validate(name, sourceFileName, is);
1116        }
1117
1118        if (newFolderId > 0 && (folderId != newFolderId)) {
1119            folderId = newFolderId;
1120        }
1121
1122        String extension = FileUtil.getExtension(name);
1123
1124        try {
1125            String titleWithExtension = title;
1126
1127            if (Validator.isNotNull(extension)) {
1128                titleWithExtension += StringPool.PERIOD + extension;
1129            }
1130
1131            dlFolderLocalService.getFolder(
1132                groupId, folderId, titleWithExtension);
1133
1134            throw new DuplicateFolderNameException();
1135        }
1136        catch (NoSuchFolderException nsfe) {
1137        }
1138
1139        List<DLFileEntry> fileEntries = dlFileEntryPersistence.findByF_T(
1140            folderId, title);
1141
1142        for (DLFileEntry fileEntry : fileEntries) {
1143            if (!name.equals(fileEntry.getName())) {
1144                String curExtension = FileUtil.getExtension(
1145                    fileEntry.getName());
1146
1147                if (PropsValues.WEBDAV_LITMUS && Validator.isNull(extension)) {
1148                    if (Validator.isNull(curExtension)) {
1149                        throw new DuplicateFileException(
1150                            fileEntry.getTitleWithExtension());
1151                    }
1152                }
1153                else if (extension.equals(curExtension)) {
1154                    throw new DuplicateFileException(
1155                        fileEntry.getTitleWithExtension());
1156                }
1157            }
1158        }
1159    }
1160
1161    protected void validate(
1162            long groupId, long folderId, String name, String title,
1163            InputStream is)
1164        throws PortalException, SystemException {
1165
1166        dlLocalService.validate(name, is);
1167
1168        String extension = FileUtil.getExtension(name);
1169
1170        try {
1171            String titleWithExtension = title;
1172
1173            if (Validator.isNotNull(extension)) {
1174                titleWithExtension += StringPool.PERIOD + extension;
1175            }
1176
1177            dlFolderLocalService.getFolder(
1178                groupId, folderId, titleWithExtension);
1179
1180            throw new DuplicateFolderNameException();
1181        }
1182        catch (NoSuchFolderException nsfe) {
1183        }
1184
1185        List<DLFileEntry> fileEntries = dlFileEntryPersistence.findByF_T(
1186            folderId, title);
1187
1188        for (DLFileEntry fileEntry : fileEntries) {
1189            String curExtension = FileUtil.getExtension(fileEntry.getName());
1190
1191            if (PropsValues.WEBDAV_LITMUS && Validator.isNull(extension)) {
1192                if (Validator.isNull(curExtension)) {
1193                    throw new DuplicateFileException(
1194                        fileEntry.getTitleWithExtension());
1195                }
1196            }
1197            else if (extension.equals(curExtension)) {
1198                throw new DuplicateFileException(
1199                    fileEntry.getTitleWithExtension());
1200            }
1201        }
1202    }
1203
1204    private static Log _log =
1205        LogFactoryUtil.getLog(DLFileEntryLocalServiceImpl.class);
1206
1207}