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