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.exportReferenceStagedModel(
138 portletDataContext, fileEntry, FileEntry.class, repository,
139 Repository.class, PortletDataContext.REFERENCE_TYPE_STRONG);
140
141 portletDataContext.addClassedModel(
142 fileEntryElement, fileEntryPath, fileEntry,
143 DLPortletDataHandler.NAMESPACE);
144
145 long liferayRepositoryClassNameId = PortalUtil.getClassNameId(
146 LiferayRepository.class.getName());
147
148 if (repository.getClassNameId() != liferayRepositoryClassNameId) {
149 return;
150 }
151 }
152
153 FileVersion fileVersion = fileEntry.getFileVersion();
154
155 if (!fileVersion.isApproved() && !fileEntry.isInTrash()) {
156 return;
157 }
158
159 if (fileEntry.getFolderId() !=
160 DLFolderConstants.DEFAULT_PARENT_FOLDER_ID) {
161
162 StagedModelDataHandlerUtil.exportReferenceStagedModel(
163 portletDataContext, fileEntry, FileEntry.class,
164 fileEntry.getFolder(), Folder.class,
165 PortletDataContext.REFERENCE_TYPE_PARENT);
166 }
167
168 LiferayFileEntry liferayFileEntry = (LiferayFileEntry)fileEntry;
169
170 liferayFileEntry.setCachedFileVersion(fileVersion);
171
172 if (!portletDataContext.isPerformDirectBinaryImport()) {
173 InputStream is = null;
174
175 try {
176 is = FileEntryUtil.getContentStream(fileEntry);
177 }
178 catch (NoSuchFileException nsfe) {
179 }
180
181 if (is == null) {
182 if (_log.isWarnEnabled()) {
183 _log.warn(
184 "No file found for file entry " +
185 fileEntry.getFileEntryId());
186 }
187
188 fileEntryElement.detach();
189
190 return;
191 }
192
193 try {
194 String binPath = ExportImportPathUtil.getModelPath(
195 fileEntry, fileEntry.getVersion());
196
197 portletDataContext.addZipEntry(binPath, is);
198
199 fileEntryElement.addAttribute("bin-path", binPath);
200 }
201 finally {
202 try {
203 is.close();
204 }
205 catch (IOException ioe) {
206 _log.error(ioe, ioe);
207 }
208 }
209 }
210
211 if (portletDataContext.getBooleanParameter(
212 DLPortletDataHandler.NAMESPACE, "previews-and-thumbnails")) {
213
214 DLProcessorRegistryUtil.exportGeneratedFiles(
215 portletDataContext, fileEntry, fileEntryElement);
216 }
217
218 exportMetaData(portletDataContext, fileEntryElement, fileEntry);
219
220 portletDataContext.addClassedModel(
221 fileEntryElement, fileEntryPath, liferayFileEntry,
222 DLFileEntry.class, DLPortletDataHandler.NAMESPACE);
223 }
224
225 @Override
226 protected void doImportStagedModel(
227 PortletDataContext portletDataContext, FileEntry fileEntry)
228 throws Exception {
229
230 long userId = portletDataContext.getUserId(fileEntry.getUserUuid());
231
232 String path = ExportImportPathUtil.getModelPath(
233 portletDataContext, FileEntry.class.getName(),
234 fileEntry.getFileEntryId());
235
236 Element fileEntryElement =
237 portletDataContext.getImportDataElement(
238 FileEntry.class.getSimpleName(), "path", path);
239
240 Element referenceDataElement =
241 portletDataContext.getReferenceDataElement(
242 fileEntryElement, Repository.class,
243 fileEntry.getRepositoryId());
244
245 if (referenceDataElement != null) {
246 StagedModelDataHandlerUtil.importStagedModel(
247 portletDataContext, referenceDataElement);
248 }
249
250 if (fileEntry.getFolderId() !=
251 DLFolderConstants.DEFAULT_PARENT_FOLDER_ID) {
252
253 String folderPath = ExportImportPathUtil.getModelPath(
254 portletDataContext, Folder.class.getName(),
255 fileEntry.getFolderId());
256
257 Folder folder = (Folder)portletDataContext.getZipEntryAsObject(
258 folderPath);
259
260 StagedModelDataHandlerUtil.importStagedModel(
261 portletDataContext, folder);
262 }
263
264 Map<Long, Long> folderIds =
265 (Map<Long, Long>)portletDataContext.getNewPrimaryKeysMap(
266 Folder.class);
267
268 long folderId = MapUtil.getLong(
269 folderIds, fileEntry.getFolderId(), fileEntry.getFolderId());
270
271 long[] assetCategoryIds = portletDataContext.getAssetCategoryIds(
272 DLFileEntry.class, fileEntry.getFileEntryId());
273 String[] assetTagNames = portletDataContext.getAssetTagNames(
274 DLFileEntry.class, fileEntry.getFileEntryId());
275
276 ServiceContext serviceContext = portletDataContext.createServiceContext(
277 fileEntry, DLFileEntry.class, DLPortletDataHandler.NAMESPACE);
278
279 serviceContext.setAttribute(
280 "sourceFileName", "A." + fileEntry.getExtension());
281 serviceContext.setUserId(userId);
282
283 String binPath = fileEntryElement.attributeValue("bin-path");
284
285 InputStream is = null;
286
287 if (Validator.isNull(binPath) &&
288 portletDataContext.isPerformDirectBinaryImport()) {
289
290 try {
291 is = FileEntryUtil.getContentStream(fileEntry);
292 }
293 catch (NoSuchFileException nsfe) {
294 }
295 }
296 else {
297 is = portletDataContext.getZipEntryAsInputStream(binPath);
298 }
299
300 if (is == null) {
301 if (_log.isWarnEnabled()) {
302 _log.warn(
303 "No file found for file entry " +
304 fileEntry.getFileEntryId());
305 }
306
307 return;
308 }
309
310 importMetaData(
311 portletDataContext, fileEntryElement, fileEntry, serviceContext);
312
313 FileEntry importedFileEntry = null;
314
315 String titleWithExtension = DLUtil.getTitleWithExtension(fileEntry);
316 String extension = fileEntry.getExtension();
317
318 String periodAndExtension = StringPool.PERIOD.concat(extension);
319
320 if (portletDataContext.isDataStrategyMirror()) {
321 FileEntry existingFileEntry = FileEntryUtil.fetchByUUID_R(
322 fileEntry.getUuid(), portletDataContext.getScopeGroupId());
323
324 FileVersion fileVersion = fileEntry.getFileVersion();
325
326 if (existingFileEntry == null) {
327 String fileEntryTitle = fileEntry.getTitle();
328
329 FileEntry existingTitleFileEntry = FileEntryUtil.fetchByR_F_T(
330 portletDataContext.getScopeGroupId(), folderId,
331 fileEntryTitle);
332
333 if (existingTitleFileEntry != null) {
334 if ((fileEntry.getGroupId() ==
335 portletDataContext.getSourceGroupId()) &&
336 portletDataContext.
337 isDataStrategyMirrorWithOverwriting()) {
338
339 DLAppLocalServiceUtil.deleteFileEntry(
340 existingTitleFileEntry.getFileEntryId());
341 }
342 else {
343 boolean titleHasExtension = false;
344
345 if (fileEntryTitle.endsWith(periodAndExtension)) {
346 fileEntryTitle = FileUtil.stripExtension(
347 fileEntryTitle);
348
349 titleHasExtension = true;
350 }
351
352 for (int i = 1;; i++) {
353 fileEntryTitle += StringPool.SPACE + i;
354
355 titleWithExtension =
356 fileEntryTitle + periodAndExtension;
357
358 existingTitleFileEntry = FileEntryUtil.fetchByR_F_T(
359 portletDataContext.getScopeGroupId(), folderId,
360 titleWithExtension);
361
362 if (existingTitleFileEntry == null) {
363 if (titleHasExtension) {
364 fileEntryTitle += periodAndExtension;
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 (fileEntry.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(periodAndExtension)) {
472 title += periodAndExtension;
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.exportReferenceStagedModel(
522 portletDataContext, fileEntry, FileEntry.class, dlFileEntryType,
523 DLFileEntryType.class, PortletDataContext.REFERENCE_TYPE_STRONG);
524
525 List<DDMStructure> ddmStructures = dlFileEntryType.getDDMStructures();
526
527 for (DDMStructure ddmStructure : ddmStructures) {
528 Element structureFields = fileEntryElement.addElement(
529 "structure-fields");
530
531 String path = ExportImportPathUtil.getModelPath(
532 ddmStructure, String.valueOf(ddmStructure.getStructureId()));
533
534 structureFields.addAttribute("path", path);
535
536 structureFields.addAttribute(
537 "structureUuid", ddmStructure.getUuid());
538
539 FileVersion fileVersion = fileEntry.getFileVersion();
540
541 DLFileEntryMetadata dlFileEntryMetadata =
542 DLFileEntryMetadataLocalServiceUtil.getFileEntryMetadata(
543 ddmStructure.getStructureId(),
544 fileVersion.getFileVersionId());
545
546 Fields fields = StorageEngineUtil.getFields(
547 dlFileEntryMetadata.getDDMStorageId());
548
549 portletDataContext.addZipEntry(path, fields);
550 }
551 }
552
553 protected void importMetaData(
554 PortletDataContext portletDataContext, Element fileEntryElement,
555 FileEntry fileEntry, ServiceContext serviceContext)
556 throws Exception {
557
558 LiferayFileEntry liferayFileEntry = (LiferayFileEntry)fileEntry;
559
560 DLFileEntry dlFileEntry = liferayFileEntry.getDLFileEntry();
561
562 Element fileEntryTypeElement =
563 portletDataContext.getReferenceDataElement(
564 fileEntryElement, DLFileEntryType.class,
565 dlFileEntry.getFileEntryTypeId());
566
567 if (fileEntryTypeElement == null) {
568 return;
569 }
570
571 String fileEntryTypePath = fileEntryTypeElement.attributeValue("path");
572
573 DLFileEntryType dlFileEntryType =
574 (DLFileEntryType)portletDataContext.getZipEntryAsObject(
575 fileEntryTypePath);
576
577 StagedModelDataHandlerUtil.importReferenceStagedModel(
578 portletDataContext, dlFileEntryType);
579
580 Map<Long, Long> dlFileEntryTypeIds =
581 (Map<Long, Long>)portletDataContext.getNewPrimaryKeysMap(
582 DLFileEntryType.class);
583
584 long dlFileEntryTypeId = MapUtil.getLong(
585 dlFileEntryTypeIds, dlFileEntryType.getFileEntryTypeId(),
586 dlFileEntryType.getFileEntryTypeId());
587
588 DLFileEntryType existingDLFileEntryType =
589 DLFileEntryTypeLocalServiceUtil.fetchDLFileEntryType(
590 dlFileEntryTypeId);
591
592 if (existingDLFileEntryType == null) {
593 serviceContext.setAttribute("fileEntryTypeId", -1);
594
595 return;
596 }
597
598 serviceContext.setAttribute(
599 "fileEntryTypeId", existingDLFileEntryType.getFileEntryTypeId());
600
601 List<DDMStructure> ddmStructures =
602 existingDLFileEntryType.getDDMStructures();
603
604 for (DDMStructure ddmStructure : ddmStructures) {
605 Element structureFieldsElement =
606 (Element)fileEntryElement.selectSingleNode(
607 "structure-fields[@structureUuid='".concat(
608 ddmStructure.getUuid()).concat("']"));
609
610 if (structureFieldsElement == null) {
611 continue;
612 }
613
614 String path = structureFieldsElement.attributeValue("path");
615
616 Fields fields = (Fields)portletDataContext.getZipEntryAsObject(
617 path);
618
619 serviceContext.setAttribute(
620 Fields.class.getName() + ddmStructure.getStructureId(), fields);
621 }
622 }
623
624 @Override
625 protected boolean validateMissingReference(
626 String uuid, long companyId, long groupId)
627 throws Exception {
628
629 DLFileEntry dlFileEntry =
630 DLFileEntryLocalServiceUtil.fetchDLFileEntryByUuidAndGroupId(
631 uuid, groupId);
632
633 if (dlFileEntry == null) {
634 return false;
635 }
636
637 return true;
638 }
639
640 private static Log _log = LogFactoryUtil.getLog(
641 FileEntryStagedModelDataHandler.class);
642
643 }