001
014
015 package com.liferay.portlet.documentlibrary.lar;
016
017 import com.liferay.portal.kernel.exception.PortalException;
018 import com.liferay.portal.kernel.exception.SystemException;
019 import com.liferay.portal.kernel.lar.BaseStagedModelDataHandler;
020 import com.liferay.portal.kernel.lar.ExportImportPathUtil;
021 import com.liferay.portal.kernel.lar.PortletDataContext;
022 import com.liferay.portal.kernel.lar.PortletDataException;
023 import com.liferay.portal.kernel.lar.StagedModelDataHandlerUtil;
024 import com.liferay.portal.kernel.log.Log;
025 import com.liferay.portal.kernel.log.LogFactoryUtil;
026 import com.liferay.portal.kernel.repository.model.FileEntry;
027 import com.liferay.portal.kernel.repository.model.FileVersion;
028 import com.liferay.portal.kernel.repository.model.Folder;
029 import com.liferay.portal.kernel.search.Indexer;
030 import com.liferay.portal.kernel.search.IndexerRegistryUtil;
031 import com.liferay.portal.kernel.trash.TrashHandler;
032 import com.liferay.portal.kernel.trash.TrashHandlerRegistryUtil;
033 import com.liferay.portal.kernel.util.FileUtil;
034 import com.liferay.portal.kernel.util.MapUtil;
035 import com.liferay.portal.kernel.util.StringPool;
036 import com.liferay.portal.kernel.util.StringUtil;
037 import com.liferay.portal.kernel.util.Validator;
038 import com.liferay.portal.kernel.xml.Element;
039 import com.liferay.portal.model.Repository;
040 import com.liferay.portal.repository.liferayrepository.LiferayRepository;
041 import com.liferay.portal.repository.liferayrepository.model.LiferayFileEntry;
042 import com.liferay.portal.service.RepositoryLocalServiceUtil;
043 import com.liferay.portal.service.ServiceContext;
044 import com.liferay.portal.util.PortalUtil;
045 import com.liferay.portlet.documentlibrary.DuplicateFileException;
046 import com.liferay.portlet.documentlibrary.NoSuchFileException;
047 import com.liferay.portlet.documentlibrary.model.DLFileEntry;
048 import com.liferay.portlet.documentlibrary.model.DLFileEntryMetadata;
049 import com.liferay.portlet.documentlibrary.model.DLFileEntryType;
050 import com.liferay.portlet.documentlibrary.model.DLFileVersion;
051 import com.liferay.portlet.documentlibrary.model.DLFolderConstants;
052 import com.liferay.portlet.documentlibrary.service.DLAppLocalServiceUtil;
053 import com.liferay.portlet.documentlibrary.service.DLAppServiceUtil;
054 import com.liferay.portlet.documentlibrary.service.DLFileEntryLocalServiceUtil;
055 import com.liferay.portlet.documentlibrary.service.DLFileEntryMetadataLocalServiceUtil;
056 import com.liferay.portlet.documentlibrary.service.DLFileEntryTypeLocalServiceUtil;
057 import com.liferay.portlet.documentlibrary.service.DLFileVersionLocalServiceUtil;
058 import com.liferay.portlet.documentlibrary.util.DLProcessorRegistryUtil;
059 import com.liferay.portlet.documentlibrary.util.DLProcessorThreadLocal;
060 import com.liferay.portlet.documentlibrary.util.DLUtil;
061 import com.liferay.portlet.dynamicdatamapping.model.DDMStructure;
062 import com.liferay.portlet.dynamicdatamapping.storage.Fields;
063 import com.liferay.portlet.dynamicdatamapping.storage.StorageEngineUtil;
064
065 import java.io.IOException;
066 import java.io.InputStream;
067
068 import java.util.List;
069 import java.util.Map;
070
071
074 public class FileEntryStagedModelDataHandler
075 extends BaseStagedModelDataHandler<FileEntry> {
076
077 public static final String[] CLASS_NAMES = {
078 DLFileEntry.class.getName(), FileEntry.class.getName(),
079 LiferayFileEntry.class.getName()
080 };
081
082 @Override
083 public void deleteStagedModel(
084 String uuid, long groupId, String className, String extraData)
085 throws PortalException, SystemException {
086
087 DLFileEntry dlFileEntry =
088 DLFileEntryLocalServiceUtil.fetchDLFileEntryByUuidAndGroupId(
089 uuid, groupId);
090
091 if (dlFileEntry != null) {
092 DLFileEntryLocalServiceUtil.deleteFileEntry(dlFileEntry);
093 }
094 }
095
096 @Override
097 public String[] getClassNames() {
098 return CLASS_NAMES;
099 }
100
101 @Override
102 public String getDisplayName(FileEntry fileEntry) {
103 return fileEntry.getTitle();
104 }
105
106 @Override
107 public void importStagedModel(
108 PortletDataContext portletDataContext, FileEntry fileEntry)
109 throws PortletDataException {
110
111 boolean dlProcessorEnabled = DLProcessorThreadLocal.isEnabled();
112
113 try {
114 DLProcessorThreadLocal.setEnabled(false);
115
116 super.importStagedModel(portletDataContext, fileEntry);
117 }
118 finally {
119 DLProcessorThreadLocal.setEnabled(dlProcessorEnabled);
120 }
121 }
122
123 @Override
124 protected void doExportStagedModel(
125 PortletDataContext portletDataContext, FileEntry fileEntry)
126 throws Exception {
127
128 Element fileEntryElement = portletDataContext.getExportDataElement(
129 fileEntry, FileEntry.class);
130
131 String fileEntryPath = ExportImportPathUtil.getModelPath(fileEntry);
132
133 if (!fileEntry.isDefaultRepository()) {
134 Repository repository = RepositoryLocalServiceUtil.getRepository(
135 fileEntry.getRepositoryId());
136
137 StagedModelDataHandlerUtil.exportReferenceStagedModel(
138 portletDataContext, fileEntry, FileEntry.class, repository,
139 Repository.class, PortletDataContext.REFERENCE_TYPE_STRONG);
140
141 portletDataContext.addClassedModel(
142 fileEntryElement, fileEntryPath, fileEntry);
143
144 long liferayRepositoryClassNameId = PortalUtil.getClassNameId(
145 LiferayRepository.class.getName());
146
147 if (repository.getClassNameId() != liferayRepositoryClassNameId) {
148 return;
149 }
150 }
151
152 FileVersion fileVersion = fileEntry.getFileVersion();
153
154 if (!fileVersion.isApproved() && !fileEntry.isInTrash()) {
155 return;
156 }
157
158 if (fileEntry.getFolderId() !=
159 DLFolderConstants.DEFAULT_PARENT_FOLDER_ID) {
160
161 StagedModelDataHandlerUtil.exportReferenceStagedModel(
162 portletDataContext, fileEntry, FileEntry.class,
163 fileEntry.getFolder(), Folder.class,
164 PortletDataContext.REFERENCE_TYPE_PARENT);
165 }
166
167 LiferayFileEntry liferayFileEntry = (LiferayFileEntry)fileEntry;
168
169 liferayFileEntry.setCachedFileVersion(fileVersion);
170
171 if (!portletDataContext.isPerformDirectBinaryImport()) {
172 InputStream is = null;
173
174 try {
175 is = FileEntryUtil.getContentStream(fileEntry);
176 }
177 catch (NoSuchFileException nsfe) {
178 }
179
180 if (is == null) {
181 if (_log.isWarnEnabled()) {
182 _log.warn(
183 "No file found for file entry " +
184 fileEntry.getFileEntryId());
185 }
186
187 fileEntryElement.detach();
188
189 return;
190 }
191
192 try {
193 String binPath = ExportImportPathUtil.getModelPath(
194 fileEntry, fileEntry.getVersion());
195
196 portletDataContext.addZipEntry(binPath, is);
197
198 fileEntryElement.addAttribute("bin-path", binPath);
199 }
200 finally {
201 try {
202 is.close();
203 }
204 catch (IOException ioe) {
205 _log.error(ioe, ioe);
206 }
207 }
208 }
209
210 if (portletDataContext.getBooleanParameter(
211 DLPortletDataHandler.NAMESPACE, "previews-and-thumbnails")) {
212
213 DLProcessorRegistryUtil.exportGeneratedFiles(
214 portletDataContext, fileEntry, fileEntryElement);
215 }
216
217 exportMetaData(portletDataContext, fileEntryElement, fileEntry);
218
219 portletDataContext.addClassedModel(
220 fileEntryElement, fileEntryPath, liferayFileEntry,
221 DLFileEntry.class);
222 }
223
224 @Override
225 protected void doImportStagedModel(
226 PortletDataContext portletDataContext, FileEntry fileEntry)
227 throws Exception {
228
229 long userId = portletDataContext.getUserId(fileEntry.getUserUuid());
230
231 String path = ExportImportPathUtil.getModelPath(
232 portletDataContext, FileEntry.class.getName(),
233 fileEntry.getFileEntryId());
234
235 Element fileEntryElement =
236 portletDataContext.getImportDataElement(
237 FileEntry.class.getSimpleName(), "path", path);
238
239 Element referenceDataElement =
240 portletDataContext.getReferenceDataElement(
241 fileEntryElement, Repository.class,
242 fileEntry.getRepositoryId());
243
244 if (referenceDataElement != null) {
245 StagedModelDataHandlerUtil.importStagedModel(
246 portletDataContext, referenceDataElement);
247 }
248
249 if (fileEntry.getFolderId() !=
250 DLFolderConstants.DEFAULT_PARENT_FOLDER_ID) {
251
252 String folderPath = ExportImportPathUtil.getModelPath(
253 portletDataContext, Folder.class.getName(),
254 fileEntry.getFolderId());
255
256 Folder folder = (Folder)portletDataContext.getZipEntryAsObject(
257 folderPath);
258
259 StagedModelDataHandlerUtil.importStagedModel(
260 portletDataContext, folder);
261 }
262
263 Map<Long, Long> folderIds =
264 (Map<Long, Long>)portletDataContext.getNewPrimaryKeysMap(
265 Folder.class);
266
267 long folderId = MapUtil.getLong(
268 folderIds, fileEntry.getFolderId(), fileEntry.getFolderId());
269
270 long[] assetCategoryIds = portletDataContext.getAssetCategoryIds(
271 DLFileEntry.class, fileEntry.getFileEntryId());
272 String[] assetTagNames = portletDataContext.getAssetTagNames(
273 DLFileEntry.class, fileEntry.getFileEntryId());
274
275 ServiceContext serviceContext = portletDataContext.createServiceContext(
276 fileEntry, DLFileEntry.class);
277
278 serviceContext.setAttribute(
279 "sourceFileName", "A." + fileEntry.getExtension());
280 serviceContext.setUserId(userId);
281
282 String binPath = fileEntryElement.attributeValue("bin-path");
283
284 InputStream is = null;
285
286 if (Validator.isNull(binPath) &&
287 portletDataContext.isPerformDirectBinaryImport()) {
288
289 try {
290 is = FileEntryUtil.getContentStream(fileEntry);
291 }
292 catch (NoSuchFileException nsfe) {
293 }
294 }
295 else {
296 is = portletDataContext.getZipEntryAsInputStream(binPath);
297 }
298
299 if (is == null) {
300 if (_log.isWarnEnabled()) {
301 _log.warn(
302 "No file found for file entry " +
303 fileEntry.getFileEntryId());
304 }
305
306 return;
307 }
308
309 importMetaData(
310 portletDataContext, fileEntryElement, fileEntry, serviceContext);
311
312 FileEntry importedFileEntry = null;
313
314 String titleWithExtension = DLUtil.getTitleWithExtension(fileEntry);
315 String extension = fileEntry.getExtension();
316
317 String periodAndExtension = StringPool.PERIOD.concat(extension);
318
319 if (portletDataContext.isDataStrategyMirror()) {
320 FileEntry existingFileEntry = FileEntryUtil.fetchByUUID_R(
321 fileEntry.getUuid(), portletDataContext.getScopeGroupId());
322
323 FileVersion fileVersion = fileEntry.getFileVersion();
324
325 if (existingFileEntry == null) {
326 String fileEntryTitle = fileEntry.getTitle();
327
328 FileEntry existingTitleFileEntry = FileEntryUtil.fetchByR_F_T(
329 portletDataContext.getScopeGroupId(), folderId,
330 fileEntryTitle);
331
332 if (existingTitleFileEntry != null) {
333 if ((fileEntry.getGroupId() ==
334 portletDataContext.getSourceGroupId()) &&
335 portletDataContext.
336 isDataStrategyMirrorWithOverwriting()) {
337
338 DLAppLocalServiceUtil.deleteFileEntry(
339 existingTitleFileEntry.getFileEntryId());
340 }
341 else {
342 boolean titleHasExtension = false;
343
344 if (fileEntryTitle.endsWith(periodAndExtension)) {
345 fileEntryTitle = FileUtil.stripExtension(
346 fileEntryTitle);
347
348 titleHasExtension = true;
349 }
350
351 for (int i = 1;; i++) {
352 fileEntryTitle += StringPool.SPACE + i;
353
354 titleWithExtension =
355 fileEntryTitle + periodAndExtension;
356
357 existingTitleFileEntry = FileEntryUtil.fetchByR_F_T(
358 portletDataContext.getScopeGroupId(), folderId,
359 titleWithExtension);
360
361 if (existingTitleFileEntry == null) {
362 if (titleHasExtension) {
363 fileEntryTitle += periodAndExtension;
364 }
365
366 break;
367 }
368 }
369 }
370 }
371
372 serviceContext.setAttribute(
373 "fileVersionUuid", fileVersion.getUuid());
374 serviceContext.setUuid(fileEntry.getUuid());
375
376 importedFileEntry = DLAppLocalServiceUtil.addFileEntry(
377 userId, portletDataContext.getScopeGroupId(), folderId,
378 titleWithExtension, fileEntry.getMimeType(), fileEntryTitle,
379 fileEntry.getDescription(), null, is, fileEntry.getSize(),
380 serviceContext);
381
382 if (fileEntry.isInTrash()) {
383 importedFileEntry = DLAppServiceUtil.moveFileEntryToTrash(
384 importedFileEntry.getFileEntryId());
385 }
386 }
387 else {
388 FileVersion latestExistingFileVersion =
389 existingFileEntry.getLatestFileVersion();
390
391 boolean indexEnabled = serviceContext.isIndexingEnabled();
392
393 try {
394 serviceContext.setIndexingEnabled(false);
395
396 if (!fileVersion.getUuid().equals(
397 latestExistingFileVersion.getUuid())) {
398
399 DLFileVersion alreadyExistingFileVersion =
400 DLFileVersionLocalServiceUtil.
401 getFileVersionByUuidAndGroupId(
402 fileVersion.getUuid(),
403 existingFileEntry.getGroupId());
404
405 if (alreadyExistingFileVersion != null) {
406 serviceContext.setAttribute(
407 "existingDLFileVersionId",
408 alreadyExistingFileVersion.getFileVersionId());
409 }
410
411 serviceContext.setUuid(fileVersion.getUuid());
412
413 importedFileEntry =
414 DLAppLocalServiceUtil.updateFileEntry(
415 userId, existingFileEntry.getFileEntryId(),
416 fileEntry.getTitle(), fileEntry.getMimeType(),
417 fileEntry.getTitle(),
418 fileEntry.getDescription(), null, false, is,
419 fileEntry.getSize(), serviceContext);
420 }
421 else {
422 DLAppLocalServiceUtil.updateAsset(
423 userId, existingFileEntry,
424 latestExistingFileVersion, assetCategoryIds,
425 assetTagNames, null);
426
427 importedFileEntry = existingFileEntry;
428 }
429
430 if (importedFileEntry.getFolderId() != folderId) {
431 importedFileEntry = DLAppLocalServiceUtil.moveFileEntry(
432 userId, importedFileEntry.getFileEntryId(),
433 folderId, serviceContext);
434 }
435
436 if (importedFileEntry instanceof LiferayFileEntry) {
437 LiferayFileEntry liferayFileEntry =
438 (LiferayFileEntry)importedFileEntry;
439
440 Indexer indexer = IndexerRegistryUtil.getIndexer(
441 DLFileEntry.class);
442
443 indexer.reindex(liferayFileEntry.getModel());
444 }
445 }
446 finally {
447 serviceContext.setIndexingEnabled(indexEnabled);
448 }
449 }
450 }
451 else {
452 try {
453 importedFileEntry = DLAppLocalServiceUtil.addFileEntry(
454 userId, portletDataContext.getScopeGroupId(), folderId,
455 titleWithExtension, fileEntry.getMimeType(),
456 fileEntry.getTitle(), fileEntry.getDescription(), null, is,
457 fileEntry.getSize(), serviceContext);
458 }
459 catch (DuplicateFileException dfe) {
460 String title = fileEntry.getTitle();
461
462 String[] titleParts = title.split("\\.", 2);
463
464 title = titleParts[0] + StringUtil.randomString();
465
466 if (titleParts.length > 1) {
467 title += StringPool.PERIOD + titleParts[1];
468 }
469
470 if (!title.endsWith(periodAndExtension)) {
471 title += periodAndExtension;
472 }
473
474 importedFileEntry = DLAppLocalServiceUtil.addFileEntry(
475 userId, portletDataContext.getScopeGroupId(), folderId,
476 title, fileEntry.getMimeType(), title,
477 fileEntry.getDescription(), null, is, fileEntry.getSize(),
478 serviceContext);
479 }
480 }
481
482 if (portletDataContext.getBooleanParameter(
483 DLPortletDataHandler.NAMESPACE, "previews-and-thumbnails")) {
484
485 DLProcessorRegistryUtil.importGeneratedFiles(
486 portletDataContext, fileEntry, importedFileEntry,
487 fileEntryElement);
488 }
489
490 portletDataContext.importClassedModel(
491 fileEntry, importedFileEntry, DLFileEntry.class);
492
493 Map<Long, Long> fileEntryIds =
494 (Map<Long, Long>)portletDataContext.getNewPrimaryKeysMap(
495 FileEntry.class);
496
497 fileEntryIds.put(
498 fileEntry.getFileEntryId(), importedFileEntry.getFileEntryId());
499 }
500
501 @Override
502 protected void doRestoreStagedModel(
503 PortletDataContext portletDataContext, FileEntry fileEntry)
504 throws Exception {
505
506 long userId = portletDataContext.getUserId(fileEntry.getUserUuid());
507
508 FileEntry existingFileEntry = FileEntryUtil.fetchByUUID_R(
509 fileEntry.getUuid(), portletDataContext.getScopeGroupId());
510
511 if ((existingFileEntry == null) || !existingFileEntry.isInTrash()) {
512 return;
513 }
514
515 TrashHandler trashHandler = TrashHandlerRegistryUtil.getTrashHandler(
516 DLFileEntry.class.getName());
517
518 if (trashHandler.isRestorable(existingFileEntry.getFileEntryId())) {
519 trashHandler.restoreTrashEntry(
520 userId, existingFileEntry.getFileEntryId());
521 }
522 }
523
524 protected void exportMetaData(
525 PortletDataContext portletDataContext, Element fileEntryElement,
526 FileEntry fileEntry)
527 throws Exception {
528
529 LiferayFileEntry liferayFileEntry = (LiferayFileEntry)fileEntry;
530
531 DLFileEntry dlFileEntry = liferayFileEntry.getDLFileEntry();
532
533 long fileEntryTypeId = dlFileEntry.getFileEntryTypeId();
534
535 DLFileEntryType dlFileEntryType =
536 DLFileEntryTypeLocalServiceUtil.fetchFileEntryType(fileEntryTypeId);
537
538 if ((dlFileEntryType == null) || !dlFileEntryType.isExportable()) {
539 return;
540 }
541
542 StagedModelDataHandlerUtil.exportReferenceStagedModel(
543 portletDataContext, fileEntry, FileEntry.class, dlFileEntryType,
544 DLFileEntryType.class, PortletDataContext.REFERENCE_TYPE_STRONG);
545
546 List<DDMStructure> ddmStructures = dlFileEntryType.getDDMStructures();
547
548 for (DDMStructure ddmStructure : ddmStructures) {
549 Element structureFields = fileEntryElement.addElement(
550 "structure-fields");
551
552 String path = ExportImportPathUtil.getModelPath(
553 ddmStructure, String.valueOf(ddmStructure.getStructureId()));
554
555 structureFields.addAttribute("path", path);
556
557 structureFields.addAttribute(
558 "structureUuid", ddmStructure.getUuid());
559
560 FileVersion fileVersion = fileEntry.getFileVersion();
561
562 DLFileEntryMetadata dlFileEntryMetadata =
563 DLFileEntryMetadataLocalServiceUtil.getFileEntryMetadata(
564 ddmStructure.getStructureId(),
565 fileVersion.getFileVersionId());
566
567 Fields fields = StorageEngineUtil.getFields(
568 dlFileEntryMetadata.getDDMStorageId());
569
570 portletDataContext.addZipEntry(path, fields);
571 }
572 }
573
574 protected void importMetaData(
575 PortletDataContext portletDataContext, Element fileEntryElement,
576 FileEntry fileEntry, ServiceContext serviceContext)
577 throws Exception {
578
579 LiferayFileEntry liferayFileEntry = (LiferayFileEntry)fileEntry;
580
581 DLFileEntry dlFileEntry = liferayFileEntry.getDLFileEntry();
582
583 Element fileEntryTypeElement =
584 portletDataContext.getReferenceDataElement(
585 fileEntryElement, DLFileEntryType.class,
586 dlFileEntry.getFileEntryTypeId());
587
588 if (fileEntryTypeElement == null) {
589 return;
590 }
591
592 String fileEntryTypePath = fileEntryTypeElement.attributeValue("path");
593
594 DLFileEntryType dlFileEntryType =
595 (DLFileEntryType)portletDataContext.getZipEntryAsObject(
596 fileEntryTypePath);
597
598 StagedModelDataHandlerUtil.importReferenceStagedModel(
599 portletDataContext, dlFileEntryType);
600
601 Map<Long, Long> dlFileEntryTypeIds =
602 (Map<Long, Long>)portletDataContext.getNewPrimaryKeysMap(
603 DLFileEntryType.class);
604
605 long dlFileEntryTypeId = MapUtil.getLong(
606 dlFileEntryTypeIds, dlFileEntryType.getFileEntryTypeId(),
607 dlFileEntryType.getFileEntryTypeId());
608
609 DLFileEntryType existingDLFileEntryType =
610 DLFileEntryTypeLocalServiceUtil.fetchDLFileEntryType(
611 dlFileEntryTypeId);
612
613 if (existingDLFileEntryType == null) {
614 serviceContext.setAttribute("fileEntryTypeId", -1);
615
616 return;
617 }
618
619 serviceContext.setAttribute(
620 "fileEntryTypeId", existingDLFileEntryType.getFileEntryTypeId());
621
622 List<DDMStructure> ddmStructures =
623 existingDLFileEntryType.getDDMStructures();
624
625 for (DDMStructure ddmStructure : ddmStructures) {
626 Element structureFieldsElement =
627 (Element)fileEntryElement.selectSingleNode(
628 "structure-fields[@structureUuid='".concat(
629 ddmStructure.getUuid()).concat("']"));
630
631 if (structureFieldsElement == null) {
632 continue;
633 }
634
635 String path = structureFieldsElement.attributeValue("path");
636
637 Fields fields = (Fields)portletDataContext.getZipEntryAsObject(
638 path);
639
640 serviceContext.setAttribute(
641 Fields.class.getName() + ddmStructure.getStructureId(), fields);
642 }
643 }
644
645 @Override
646 protected boolean validateMissingReference(
647 String uuid, long companyId, long groupId)
648 throws Exception {
649
650 DLFileEntry dlFileEntry =
651 DLFileEntryLocalServiceUtil.fetchDLFileEntryByUuidAndGroupId(
652 uuid, groupId);
653
654 if (dlFileEntry == null) {
655 return false;
656 }
657
658 return true;
659 }
660
661 private static Log _log = LogFactoryUtil.getLog(
662 FileEntryStagedModelDataHandler.class);
663
664 }