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