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