001
014
015 package com.liferay.portal.verify;
016
017 import com.liferay.counter.service.CounterLocalServiceUtil;
018 import com.liferay.portal.kernel.dao.orm.ActionableDynamicQuery;
019 import com.liferay.portal.kernel.dao.orm.Criterion;
020 import com.liferay.portal.kernel.dao.orm.DynamicQuery;
021 import com.liferay.portal.kernel.dao.orm.DynamicQueryFactoryUtil;
022 import com.liferay.portal.kernel.dao.orm.RestrictionsFactoryUtil;
023 import com.liferay.portal.kernel.exception.PortalException;
024 import com.liferay.portal.kernel.exception.SystemException;
025 import com.liferay.portal.kernel.log.Log;
026 import com.liferay.portal.kernel.log.LogFactoryUtil;
027 import com.liferay.portal.kernel.repository.model.FileEntry;
028 import com.liferay.portal.kernel.repository.model.FileVersion;
029 import com.liferay.portal.kernel.repository.model.Folder;
030 import com.liferay.portal.kernel.util.ContentTypes;
031 import com.liferay.portal.kernel.util.ListUtil;
032 import com.liferay.portal.kernel.util.LocaleUtil;
033 import com.liferay.portal.kernel.util.MimeTypesUtil;
034 import com.liferay.portal.kernel.util.StreamUtil;
035 import com.liferay.portal.kernel.util.StringPool;
036 import com.liferay.portal.kernel.util.StringUtil;
037 import com.liferay.portal.kernel.workflow.WorkflowConstants;
038 import com.liferay.portal.repository.liferayrepository.model.LiferayFileEntry;
039 import com.liferay.portal.repository.liferayrepository.model.LiferayFileVersion;
040 import com.liferay.portal.repository.liferayrepository.model.LiferayFolder;
041 import com.liferay.portal.util.PortalInstances;
042 import com.liferay.portlet.documentlibrary.DuplicateFileException;
043 import com.liferay.portlet.documentlibrary.DuplicateFolderNameException;
044 import com.liferay.portlet.documentlibrary.model.DLFileEntry;
045 import com.liferay.portlet.documentlibrary.model.DLFileEntryType;
046 import com.liferay.portlet.documentlibrary.model.DLFileEntryTypeConstants;
047 import com.liferay.portlet.documentlibrary.model.DLFileVersion;
048 import com.liferay.portlet.documentlibrary.model.DLFolder;
049 import com.liferay.portlet.documentlibrary.service.DLAppHelperLocalServiceUtil;
050 import com.liferay.portlet.documentlibrary.service.DLFileEntryLocalServiceUtil;
051 import com.liferay.portlet.documentlibrary.service.DLFileEntryTypeLocalServiceUtil;
052 import com.liferay.portlet.documentlibrary.service.DLFileVersionLocalServiceUtil;
053 import com.liferay.portlet.documentlibrary.service.DLFolderLocalServiceUtil;
054 import com.liferay.portlet.documentlibrary.service.persistence.DLFileEntryActionableDynamicQuery;
055 import com.liferay.portlet.documentlibrary.service.persistence.DLFileVersionActionableDynamicQuery;
056 import com.liferay.portlet.documentlibrary.store.DLStoreUtil;
057 import com.liferay.portlet.documentlibrary.util.DLUtil;
058 import com.liferay.portlet.documentlibrary.util.comparator.FileVersionVersionComparator;
059 import com.liferay.portlet.documentlibrary.webdav.DLWebDAVStorageImpl;
060 import com.liferay.portlet.trash.model.TrashEntry;
061 import com.liferay.portlet.trash.service.TrashEntryLocalServiceUtil;
062
063 import java.io.InputStream;
064
065 import java.util.Collections;
066 import java.util.Date;
067 import java.util.List;
068
069
074 public class VerifyDocumentLibrary extends VerifyProcess {
075
076 protected void addDLFileVersion(DLFileEntry dlFileEntry)
077 throws SystemException {
078
079 long fileVersionId = CounterLocalServiceUtil.increment();
080
081 DLFileVersion dlFileVersion =
082 DLFileVersionLocalServiceUtil.createDLFileVersion(fileVersionId);
083
084 dlFileVersion.setGroupId(dlFileEntry.getGroupId());
085 dlFileVersion.setCompanyId(dlFileEntry.getCompanyId());
086
087 long userId = dlFileEntry.getUserId();
088
089 dlFileVersion.setUserId(userId);
090
091 String userName = dlFileEntry.getUserName();
092
093 dlFileVersion.setUserName(userName);
094
095 dlFileVersion.setCreateDate(dlFileEntry.getModifiedDate());
096 dlFileVersion.setModifiedDate(dlFileEntry.getModifiedDate());
097 dlFileVersion.setRepositoryId(dlFileEntry.getRepositoryId());
098 dlFileVersion.setFolderId(dlFileEntry.getFolderId());
099 dlFileVersion.setFileEntryId(dlFileEntry.getFileEntryId());
100 dlFileVersion.setExtension(dlFileEntry.getExtension());
101 dlFileVersion.setMimeType(dlFileEntry.getMimeType());
102 dlFileVersion.setTitle(dlFileEntry.getTitle());
103 dlFileVersion.setDescription(dlFileEntry.getDescription());
104 dlFileVersion.setExtraSettings(dlFileEntry.getExtraSettings());
105 dlFileVersion.setFileEntryTypeId(dlFileEntry.getFileEntryTypeId());
106 dlFileVersion.setVersion(dlFileEntry.getVersion());
107 dlFileVersion.setSize(dlFileEntry.getSize());
108 dlFileVersion.setStatus(WorkflowConstants.STATUS_APPROVED);
109 dlFileVersion.setStatusByUserId(userId);
110 dlFileVersion.setStatusByUserName(userName);
111 dlFileVersion.setStatusDate(new Date());
112
113 DLFileVersionLocalServiceUtil.updateDLFileVersion(dlFileVersion);
114 }
115
116 protected void checkDLFileEntryType() throws Exception {
117 DLFileEntryType dlFileEntryType =
118 DLFileEntryTypeLocalServiceUtil.fetchDLFileEntryType(
119 DLFileEntryTypeConstants.FILE_ENTRY_TYPE_ID_BASIC_DOCUMENT);
120
121 if (dlFileEntryType != null) {
122 return;
123 }
124
125 Date now = new Date();
126
127 dlFileEntryType = DLFileEntryTypeLocalServiceUtil.createDLFileEntryType(
128 DLFileEntryTypeConstants.FILE_ENTRY_TYPE_ID_BASIC_DOCUMENT);
129
130 dlFileEntryType.setCreateDate(now);
131 dlFileEntryType.setModifiedDate(now);
132 dlFileEntryType.setFileEntryTypeKey(
133 StringUtil.toUpperCase(
134 DLFileEntryTypeConstants.NAME_BASIC_DOCUMENT));
135 dlFileEntryType.setName(
136 DLFileEntryTypeConstants.NAME_BASIC_DOCUMENT,
137 LocaleUtil.getDefault());
138
139 DLFileEntryTypeLocalServiceUtil.updateDLFileEntryType(dlFileEntryType);
140 }
141
142 protected void checkDuplicateTitles() throws Exception {
143 ActionableDynamicQuery actionableDynamicQuery =
144 new DLFileEntryActionableDynamicQuery() {
145
146 @Override
147 public void performAction(Object object) {
148 DLFileEntry dlFileEntry = (DLFileEntry)object;
149
150 if (dlFileEntry.isInTrash()) {
151 return;
152 }
153
154 try {
155 DLFileEntryLocalServiceUtil.validateFile(
156 dlFileEntry.getGroupId(), dlFileEntry.getFolderId(),
157 dlFileEntry.getFileEntryId(),
158 dlFileEntry.getTitle(), dlFileEntry.getExtension());
159 }
160 catch (Exception e1) {
161 if (!(e1 instanceof DuplicateFileException) &&
162 !(e1 instanceof DuplicateFolderNameException)) {
163
164 return;
165 }
166
167 try {
168 renameDuplicateTitle(dlFileEntry);
169 }
170 catch (Exception e2) {
171 if (_log.isWarnEnabled()) {
172 _log.warn(
173 "Unable to rename duplicate title for " +
174 "file entry " +
175 dlFileEntry.getFileEntryId() +
176 ": " + e2.getMessage(),
177 e2);
178 }
179 }
180 }
181 }
182
183 };
184
185 actionableDynamicQuery.performActions();
186 }
187
188 protected void checkFileEntryMimeTypes(final String originalMimeType)
189 throws Exception {
190
191 ActionableDynamicQuery actionableDynamicQuery =
192 new DLFileEntryActionableDynamicQuery() {
193
194 @Override
195 protected void performAction(Object object)
196 throws PortalException, SystemException {
197
198 DLFileEntry dlFileEntry = (DLFileEntry)object;
199
200 InputStream inputStream = null;
201
202 try {
203 inputStream = DLFileEntryLocalServiceUtil.getFileAsStream(
204 dlFileEntry.getFileEntryId(), dlFileEntry.getVersion(),
205 false);
206 }
207 catch (Exception e) {
208 if (_log.isWarnEnabled()) {
209 _log.warn(
210 "Unable to find file entry " +
211 dlFileEntry.getName(),
212 e);
213 }
214
215 return;
216 }
217
218 String title = DLUtil.getTitleWithExtension(
219 dlFileEntry.getTitle(), dlFileEntry.getExtension());
220
221 String mimeType = getMimeType(inputStream, title);
222
223 if (mimeType.equals(originalMimeType)) {
224 return;
225 }
226
227 dlFileEntry.setMimeType(mimeType);
228
229 DLFileEntryLocalServiceUtil.updateDLFileEntry(dlFileEntry);
230
231 DLFileVersion dlFileVersion = dlFileEntry.getFileVersion();
232
233 dlFileVersion.setMimeType(mimeType);
234
235 DLFileVersionLocalServiceUtil.updateDLFileVersion(
236 dlFileVersion);
237 }
238
239 };
240
241 actionableDynamicQuery.performActions();
242 }
243
244 protected void checkFileVersionMimeTypes(final String originalMimeType)
245 throws Exception {
246
247 ActionableDynamicQuery actionableDynamicQuery =
248 new DLFileVersionActionableDynamicQuery() {
249
250 @Override
251 protected void performAction(Object object) throws SystemException {
252 DLFileVersion dlFileVersion = (DLFileVersion)object;
253
254 InputStream inputStream = null;
255
256 try {
257 inputStream = DLFileEntryLocalServiceUtil.getFileAsStream(
258 dlFileVersion.getFileEntryId(),
259 dlFileVersion.getVersion(), false);
260 }
261 catch (Exception e) {
262 if (_log.isWarnEnabled()) {
263 DLFileEntry dlFileEntry =
264 DLFileEntryLocalServiceUtil.fetchDLFileEntry(
265 dlFileVersion.getFileEntryId());
266
267 if (dlFileEntry == null) {
268 _log.warn(
269 "Unable to find file entry associated with " +
270 "file version " +
271 dlFileVersion.getFileVersionId(),
272 e);
273 }
274 else {
275 _log.warn(
276 "Unable to find file version " +
277 dlFileVersion.getVersion() + " for file " +
278 "entry " + dlFileEntry.getName(),
279 e);
280 }
281 }
282
283 return;
284 }
285
286 String title = DLUtil.getTitleWithExtension(
287 dlFileVersion.getTitle(), dlFileVersion.getExtension());
288
289 String mimeType = getMimeType(inputStream, title);
290
291 if (mimeType.equals(originalMimeType)) {
292 return;
293 }
294
295 dlFileVersion.setMimeType(mimeType);
296
297 DLFileVersionLocalServiceUtil.updateDLFileVersion(
298 dlFileVersion);
299 }
300
301 };
302
303 actionableDynamicQuery.performActions();
304 }
305
306 protected void checkMimeTypes() throws Exception {
307 String[] mimeTypes = {
308 ContentTypes.APPLICATION_OCTET_STREAM,
309 DLWebDAVStorageImpl.MS_OFFICE_2010_TEXT_XML_UTF8
310 };
311
312 for (String mimeType : mimeTypes) {
313 checkFileEntryMimeTypes(mimeType);
314 checkFileVersionMimeTypes(mimeType);
315 }
316
317 if (_log.isDebugEnabled()) {
318 _log.debug("Fixed file entries with invalid mime types");
319 }
320 }
321
322 protected void checkMisversionedDLFileEntries() throws Exception {
323 List<DLFileEntry> dlFileEntries =
324 DLFileEntryLocalServiceUtil.getMisversionedFileEntries();
325
326 if (_log.isDebugEnabled()) {
327 _log.debug(
328 "Processing " + dlFileEntries.size() +
329 " misversioned file entries");
330 }
331
332 for (DLFileEntry dlFileEntry : dlFileEntries) {
333 copyDLFileEntry(dlFileEntry);
334
335 addDLFileVersion(dlFileEntry);
336 }
337
338 if (_log.isDebugEnabled()) {
339 _log.debug("Fixed misversioned file entries");
340 }
341 }
342
343 protected void checkTitles() throws Exception {
344 DynamicQuery dynamicQuery = DynamicQueryFactoryUtil.forClass(
345 DLFileEntry.class);
346
347 Criterion criterion1 = RestrictionsFactoryUtil.like("title", "%/%");
348 Criterion criterion2 = RestrictionsFactoryUtil.like("title", "%\\\\%");
349
350 dynamicQuery.add(RestrictionsFactoryUtil.or(criterion1, criterion2));
351
352 List<DLFileEntry> dlFileEntries =
353 DLFileEntryLocalServiceUtil.dynamicQuery(dynamicQuery);
354
355 for (DLFileEntry dlFileEntry : dlFileEntries) {
356 TrashEntry trashEntry = TrashEntryLocalServiceUtil.fetchEntry(
357 dlFileEntry.getModelClassName(), dlFileEntry.getFileEntryId());
358
359 if (trashEntry != null) {
360 continue;
361 }
362
363 String title = dlFileEntry.getTitle();
364
365 String newTitle = title.replace(StringPool.SLASH, StringPool.BLANK);
366
367 newTitle = newTitle.replace(
368 StringPool.BACK_SLASH, StringPool.UNDERLINE);
369
370 renameTitle(dlFileEntry, newTitle);
371 }
372
373 checkDuplicateTitles();
374 }
375
376 protected void copyDLFileEntry(DLFileEntry dlFileEntry)
377 throws PortalException, SystemException {
378
379 long companyId = dlFileEntry.getCompanyId();
380 long dataRepositoryId = dlFileEntry.getDataRepositoryId();
381 String name = dlFileEntry.getName();
382 String version = dlFileEntry.getVersion();
383
384 if (DLStoreUtil.hasFile(companyId, dataRepositoryId, name, version)) {
385 return;
386 }
387
388 FileVersionVersionComparator comparator =
389 new FileVersionVersionComparator();
390
391 List<DLFileVersion> dlFileVersions = dlFileEntry.getFileVersions(
392 WorkflowConstants.STATUS_APPROVED);
393
394 if (dlFileVersions.isEmpty()) {
395 dlFileVersions = dlFileEntry.getFileVersions(
396 WorkflowConstants.STATUS_ANY);
397 }
398
399 if (dlFileVersions.isEmpty()) {
400 DLStoreUtil.addFile(companyId, dataRepositoryId, name, new byte[0]);
401
402 return;
403 }
404
405 dlFileVersions = ListUtil.copy(dlFileVersions);
406
407 Collections.sort(dlFileVersions, comparator);
408
409 DLFileVersion dlFileVersion = dlFileVersions.get(0);
410
411 DLStoreUtil.copyFileVersion(
412 companyId, dataRepositoryId, name, dlFileVersion.getVersion(),
413 version);
414 }
415
416 @Override
417 protected void doVerify() throws Exception {
418 checkMisversionedDLFileEntries();
419
420 checkDLFileEntryType();
421 checkMimeTypes();
422 checkTitles();
423 removeOrphanedDLFileEntries();
424 updateClassNameId();
425 updateFileEntryAssets();
426 updateFolderAssets();
427 verifyTree();
428 }
429
430 protected String getMimeType(InputStream inputStream, String title) {
431 String mimeType = null;
432
433 try {
434 mimeType = MimeTypesUtil.getContentType(inputStream, title);
435 }
436 finally {
437 StreamUtil.cleanUp(inputStream);
438 }
439
440 return mimeType;
441 }
442
443 protected void updateClassNameId() {
444 try {
445 runSQL(
446 "update DLFileEntry set classNameId = 0 where classNameId is " +
447 "null");
448 }
449 catch (Exception e) {
450 if (_log.isWarnEnabled()) {
451 _log.warn(
452 "Unable to fix file entries where class name ID is null",
453 e);
454 }
455 }
456 }
457
458 protected void removeOrphanedDLFileEntries() throws Exception {
459 List<DLFileEntry> dlFileEntries =
460 DLFileEntryLocalServiceUtil.getOrphanedFileEntries();
461
462 if (_log.isDebugEnabled()) {
463 _log.debug(
464 "Processing " + dlFileEntries.size() +
465 " file entries with no group");
466 }
467
468 for (DLFileEntry dlFileEntry : dlFileEntries) {
469 try {
470 DLFileEntryLocalServiceUtil.deleteFileEntry(
471 dlFileEntry.getFileEntryId());
472 }
473 catch (Exception e) {
474 if (_log.isWarnEnabled()) {
475 _log.warn(
476 "Unable to remove file entry " +
477 dlFileEntry.getFileEntryId() + ": " +
478 e.getMessage());
479 }
480 }
481 }
482
483 if (_log.isDebugEnabled()) {
484 _log.debug("Removed orphaned file entries");
485 }
486 }
487
488 protected void renameDuplicateTitle(DLFileEntry dlFileEntry)
489 throws PortalException, SystemException {
490
491 String uniqueTitle = DLFileEntryLocalServiceUtil.getUniqueTitle(
492 dlFileEntry.getGroupId(), dlFileEntry.getFolderId(),
493 dlFileEntry.getFileEntryId(), dlFileEntry.getTitle(),
494 dlFileEntry.getExtension());
495
496 renameTitle(dlFileEntry, uniqueTitle);
497 }
498
499 protected void renameTitle(DLFileEntry dlFileEntry, String newTitle)
500 throws PortalException, SystemException {
501
502 String title = dlFileEntry.getTitle();
503
504 dlFileEntry.setTitle(newTitle);
505
506 DLFileEntryLocalServiceUtil.updateDLFileEntry(dlFileEntry);
507
508 DLFileVersion dlFileVersion = dlFileEntry.getFileVersion();
509
510 dlFileVersion.setTitle(newTitle);
511
512 DLFileVersionLocalServiceUtil.updateDLFileVersion(dlFileVersion);
513
514 if (_log.isDebugEnabled()) {
515 _log.debug(
516 "Invalid title " + title + " renamed to " + newTitle +
517 " for file entry " + dlFileEntry.getFileEntryId());
518 }
519 }
520
521 protected void updateFileEntryAssets() throws Exception {
522 List<DLFileEntry> dlFileEntries =
523 DLFileEntryLocalServiceUtil.getNoAssetFileEntries();
524
525 if (_log.isDebugEnabled()) {
526 _log.debug(
527 "Processing " + dlFileEntries.size() +
528 " file entries with no asset");
529 }
530
531 for (DLFileEntry dlFileEntry : dlFileEntries) {
532 FileEntry fileEntry = new LiferayFileEntry(dlFileEntry);
533 FileVersion fileVersion = new LiferayFileVersion(
534 dlFileEntry.getFileVersion());
535
536 try {
537 DLAppHelperLocalServiceUtil.updateAsset(
538 dlFileEntry.getUserId(), fileEntry, fileVersion, null, null,
539 null);
540 }
541 catch (Exception e) {
542 if (_log.isWarnEnabled()) {
543 _log.warn(
544 "Unable to update asset for file entry " +
545 dlFileEntry.getFileEntryId() + ": " +
546 e.getMessage());
547 }
548 }
549 }
550
551 if (_log.isDebugEnabled()) {
552 _log.debug("Assets verified for file entries");
553 }
554 }
555
556 protected void updateFolderAssets() throws Exception {
557 List<DLFolder> dlFolders = DLFolderLocalServiceUtil.getNoAssetFolders();
558
559 if (_log.isDebugEnabled()) {
560 _log.debug(
561 "Processing " + dlFolders.size() + " folders with no asset");
562 }
563
564 for (DLFolder dlFolder : dlFolders) {
565 Folder folder = new LiferayFolder(dlFolder);
566
567 try {
568 DLAppHelperLocalServiceUtil.updateAsset(
569 dlFolder.getUserId(), folder, null, null, null);
570 }
571 catch (Exception e) {
572 if (_log.isWarnEnabled()) {
573 _log.warn(
574 "Unable to update asset for folder " +
575 dlFolder.getFolderId() + ": " + e.getMessage());
576 }
577 }
578 }
579
580 if (_log.isDebugEnabled()) {
581 _log.debug("Assets verified for folders");
582 }
583 }
584
585 protected void verifyTree() throws Exception {
586 long[] companyIds = PortalInstances.getCompanyIdsBySQL();
587
588 for (long companyId : companyIds) {
589 DLFolderLocalServiceUtil.rebuildTree(companyId);
590 }
591 }
592
593 private static Log _log = LogFactoryUtil.getLog(
594 VerifyDocumentLibrary.class);
595
596 }