001    /**
002     * Copyright (c) 2000-2012 Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
013     */
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.BasePortletDataHandler;
020    import com.liferay.portal.kernel.lar.PortletDataContext;
021    import com.liferay.portal.kernel.lar.PortletDataHandlerBoolean;
022    import com.liferay.portal.kernel.lar.PortletDataHandlerControl;
023    import com.liferay.portal.kernel.log.Log;
024    import com.liferay.portal.kernel.log.LogFactoryUtil;
025    import com.liferay.portal.kernel.repository.model.FileEntry;
026    import com.liferay.portal.kernel.repository.model.FileVersion;
027    import com.liferay.portal.kernel.repository.model.Folder;
028    import com.liferay.portal.kernel.search.Indexer;
029    import com.liferay.portal.kernel.search.IndexerRegistryUtil;
030    import com.liferay.portal.kernel.util.GetterUtil;
031    import com.liferay.portal.kernel.util.MapUtil;
032    import com.liferay.portal.kernel.util.StringBundler;
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.workflow.WorkflowConstants;
037    import com.liferay.portal.kernel.xml.Document;
038    import com.liferay.portal.kernel.xml.Element;
039    import com.liferay.portal.kernel.xml.SAXReaderUtil;
040    import com.liferay.portal.model.Group;
041    import com.liferay.portal.model.Repository;
042    import com.liferay.portal.repository.liferayrepository.model.LiferayFileEntry;
043    import com.liferay.portal.service.GroupLocalServiceUtil;
044    import com.liferay.portal.service.RepositoryLocalServiceUtil;
045    import com.liferay.portal.service.ServiceContext;
046    import com.liferay.portal.service.persistence.RepositoryUtil;
047    import com.liferay.portal.util.PortalUtil;
048    import com.liferay.portal.util.PortletKeys;
049    import com.liferay.portal.util.PropsValues;
050    import com.liferay.portlet.documentlibrary.DuplicateFileException;
051    import com.liferay.portlet.documentlibrary.NoSuchFileException;
052    import com.liferay.portlet.documentlibrary.model.DLFileEntry;
053    import com.liferay.portlet.documentlibrary.model.DLFileEntryMetadata;
054    import com.liferay.portlet.documentlibrary.model.DLFileEntryType;
055    import com.liferay.portlet.documentlibrary.model.DLFileRank;
056    import com.liferay.portlet.documentlibrary.model.DLFileShortcut;
057    import com.liferay.portlet.documentlibrary.model.DLFileVersion;
058    import com.liferay.portlet.documentlibrary.model.DLFolder;
059    import com.liferay.portlet.documentlibrary.model.DLFolderConstants;
060    import com.liferay.portlet.documentlibrary.service.DLAppLocalServiceUtil;
061    import com.liferay.portlet.documentlibrary.service.DLFileEntryMetadataLocalServiceUtil;
062    import com.liferay.portlet.documentlibrary.service.DLFileEntryTypeLocalServiceUtil;
063    import com.liferay.portlet.documentlibrary.service.DLFileEntryTypeServiceUtil;
064    import com.liferay.portlet.documentlibrary.service.DLFileVersionLocalServiceUtil;
065    import com.liferay.portlet.documentlibrary.service.persistence.DLFileEntryTypeUtil;
066    import com.liferay.portlet.documentlibrary.service.persistence.DLFileRankUtil;
067    import com.liferay.portlet.documentlibrary.service.persistence.DLFileShortcutUtil;
068    import com.liferay.portlet.documentlibrary.util.DLProcessorRegistryUtil;
069    import com.liferay.portlet.documentlibrary.util.DLProcessorThreadLocal;
070    import com.liferay.portlet.documentlibrary.util.DLUtil;
071    import com.liferay.portlet.dynamicdatamapping.lar.DDMPortletDataHandlerImpl;
072    import com.liferay.portlet.dynamicdatamapping.model.DDMStructure;
073    import com.liferay.portlet.dynamicdatamapping.service.persistence.DDMStructureUtil;
074    import com.liferay.portlet.dynamicdatamapping.storage.Fields;
075    import com.liferay.portlet.dynamicdatamapping.storage.StorageEngineUtil;
076    import com.liferay.util.PwdGenerator;
077    
078    import java.io.IOException;
079    import java.io.InputStream;
080    
081    import java.util.ArrayList;
082    import java.util.List;
083    import java.util.Map;
084    
085    import javax.portlet.PortletPreferences;
086    
087    /**
088     * @author Bruno Farache
089     * @author Raymond Augé
090     */
091    public class DLPortletDataHandlerImpl extends BasePortletDataHandler {
092    
093            public static void exportFileEntry(
094                            PortletDataContext portletDataContext,
095                            Element fileEntryTypesElement, Element foldersElement,
096                            Element fileEntriesElement, Element fileRanksElement,
097                            FileEntry fileEntry, boolean checkDateRange)
098                    throws Exception {
099    
100                    if (checkDateRange &&
101                            !portletDataContext.isWithinDateRange(
102                                    fileEntry.getModifiedDate())) {
103    
104                            return;
105                    }
106    
107                    FileVersion fileVersion = fileEntry.getFileVersion();
108    
109                    if (fileVersion.getStatus() != WorkflowConstants.STATUS_APPROVED) {
110                            return;
111                    }
112    
113                    String path = getFileEntryPath(portletDataContext, fileEntry);
114    
115                    if (!portletDataContext.isPathNotProcessed(path)) {
116                            return;
117                    }
118    
119                    Element fileEntryElement = fileEntriesElement.addElement("file-entry");
120    
121                    if (foldersElement != null) {
122                            exportParentFolder(
123                                    portletDataContext, fileEntryTypesElement, foldersElement,
124                                    fileEntry.getFolderId());
125                    }
126    
127                    if (!portletDataContext.isPerformDirectBinaryImport()) {
128                            String binPath = getFileEntryBinPath(portletDataContext, fileEntry);
129    
130                            fileEntryElement.addAttribute("bin-path", binPath);
131    
132                            InputStream is = null;
133    
134                            try {
135                                    is = FileEntryUtil.getContentStream(fileEntry);
136                            }
137                            catch (NoSuchFileException nsfe) {
138                            }
139    
140                            if (is == null) {
141                                    if (_log.isWarnEnabled()) {
142                                            _log.warn(
143                                                    "No file found for file entry " +
144                                                            fileEntry.getFileEntryId());
145                                    }
146    
147                                    fileEntryElement.detach();
148    
149                                    return;
150                            }
151    
152                            try {
153                                    portletDataContext.addZipEntry(binPath, is);
154                            }
155                            finally {
156                                    try {
157                                            is.close();
158                                    }
159                                    catch (IOException ioe) {
160                                            _log.error(ioe, ioe);
161                                    }
162                            }
163                    }
164    
165                    if (portletDataContext.getBooleanParameter(_NAMESPACE, "ranks")) {
166                            List<DLFileRank> fileRanks = DLFileRankUtil.findByFileEntryId(
167                                    fileEntry.getFileEntryId());
168    
169                            for (DLFileRank fileRank : fileRanks) {
170                                    exportFileRank(portletDataContext, fileRanksElement, fileRank);
171                            }
172                    }
173    
174                    if (portletDataContext.getBooleanParameter(
175                            _NAMESPACE, "previews-and-thumbnails")) {
176    
177                            DLProcessorRegistryUtil.exportGeneratedFiles(
178                                    portletDataContext, fileEntry, fileEntryElement);
179                    }
180    
181                    exportMetaData(
182                            portletDataContext, fileEntryTypesElement, fileEntryElement,
183                            fileEntry);
184    
185                    portletDataContext.addClassedModel(
186                            fileEntryElement, path, fileEntry, _NAMESPACE);
187            }
188    
189            public static String getFileEntryPath(
190                    PortletDataContext portletDataContext, FileEntry fileEntry) {
191    
192                    StringBundler sb = new StringBundler(6);
193    
194                    sb.append(
195                            portletDataContext.getPortletPath(PortletKeys.DOCUMENT_LIBRARY));
196                    sb.append("/file-entries/");
197                    sb.append(fileEntry.getFileEntryId());
198                    sb.append(StringPool.SLASH);
199                    sb.append(fileEntry.getVersion());
200                    sb.append(".xml");
201    
202                    return sb.toString();
203            }
204    
205            public static PortletDataHandlerControl[] getMetadataControls() {
206                    return _metadataControls;
207            }
208    
209            public static void importFileEntry(
210                            PortletDataContext portletDataContext, Element fileEntryElement)
211                    throws Exception {
212    
213                    String path = fileEntryElement.attributeValue("path");
214    
215                    if (!portletDataContext.isPathNotProcessed(path)) {
216                            return;
217                    }
218    
219                    boolean dlProcessorEnabled = DLProcessorThreadLocal.isEnabled();
220    
221                    try {
222                            DLProcessorThreadLocal.setEnabled(false);
223    
224                            importFileEntry(portletDataContext, fileEntryElement, path);
225                    }
226                    finally {
227                            DLProcessorThreadLocal.setEnabled(dlProcessorEnabled);
228                    }
229            }
230    
231            public static void importFileEntry(
232                            PortletDataContext portletDataContext, Element fileEntryElement,
233                            String path)
234                    throws Exception {
235    
236                    FileEntry fileEntry = (FileEntry)portletDataContext.getZipEntryAsObject(
237                            path);
238    
239                    long userId = portletDataContext.getUserId(fileEntry.getUserUuid());
240    
241                    Map<Long, Long> folderPKs =
242                            (Map<Long, Long>)portletDataContext.getNewPrimaryKeysMap(
243                                    DLFolder.class);
244    
245                    long folderId = MapUtil.getLong(
246                            folderPKs, fileEntry.getFolderId(), fileEntry.getFolderId());
247    
248                    long[] assetCategoryIds = null;
249                    String[] assetTagNames = null;
250    
251                    if (portletDataContext.getBooleanParameter(_NAMESPACE, "categories")) {
252                            assetCategoryIds = portletDataContext.getAssetCategoryIds(
253                                    DLFileEntry.class, fileEntry.getFileEntryId());
254                    }
255    
256                    if (portletDataContext.getBooleanParameter(_NAMESPACE, "tags")) {
257                            assetTagNames = portletDataContext.getAssetTagNames(
258                                    DLFileEntry.class, fileEntry.getFileEntryId());
259                    }
260    
261                    ServiceContext serviceContext = portletDataContext.createServiceContext(
262                            fileEntryElement, fileEntry, _NAMESPACE);
263    
264                    serviceContext.setAttribute(
265                            "sourceFileName", "A." + fileEntry.getExtension());
266                    serviceContext.setUserId(userId);
267    
268                    String binPath = fileEntryElement.attributeValue("bin-path");
269    
270                    InputStream is = null;
271    
272                    if (Validator.isNull(binPath) &&
273                            portletDataContext.isPerformDirectBinaryImport()) {
274    
275                            is = FileEntryUtil.getContentStream(fileEntry);
276                    }
277                    else {
278                            is = portletDataContext.getZipEntryAsInputStream(binPath);
279                    }
280    
281                    if ((folderId != DLFolderConstants.DEFAULT_PARENT_FOLDER_ID) &&
282                            (folderId == fileEntry.getFolderId())) {
283    
284                            String folderPath = getImportFolderPath(
285                                    portletDataContext, folderId);
286    
287                            Folder folder = (Folder)portletDataContext.getZipEntryAsObject(
288                                    folderPath);
289    
290                            Document document = fileEntryElement.getDocument();
291    
292                            Element rootElement = document.getRootElement();
293    
294                            Element folderElement = (Element)rootElement.selectSingleNode(
295                                    "//folder[@path='".concat(folderPath).concat("']"));
296    
297                            importFolder(portletDataContext, folderPath, folderElement, folder);
298    
299                            folderId = MapUtil.getLong(
300                                    folderPKs, fileEntry.getFolderId(), fileEntry.getFolderId());
301                    }
302    
303                    importMetaData(portletDataContext, fileEntryElement, serviceContext);
304    
305                    FileEntry importedFileEntry = null;
306    
307                    String titleWithExtension = fileEntry.getTitle();
308                    String extension = fileEntry.getExtension();
309    
310                    if (!titleWithExtension.endsWith(StringPool.PERIOD + extension)) {
311                            titleWithExtension += StringPool.PERIOD + extension;
312                    }
313    
314                    if (portletDataContext.isDataStrategyMirror()) {
315                            FileEntry existingFileEntry = FileEntryUtil.fetchByUUID_R(
316                                    fileEntry.getUuid(), portletDataContext.getScopeGroupId());
317    
318                            FileVersion fileVersion = fileEntry.getFileVersion();
319    
320                            if (existingFileEntry == null) {
321                                    FileEntry existingTitleFileEntry = FileEntryUtil.fetchByR_F_T(
322                                            portletDataContext.getScopeGroupId(), folderId,
323                                            fileEntry.getTitle());
324    
325                                    if (existingTitleFileEntry != null) {
326                                            if (portletDataContext.
327                                                            isDataStrategyMirrorWithOverwritting()) {
328    
329                                                    DLAppLocalServiceUtil.deleteFileEntry(
330                                                            existingTitleFileEntry.getFileEntryId());
331                                            }
332                                            else {
333                                                    String originalTitle = fileEntry.getTitle();
334                                                    String dotExtension = StringPool.PERIOD + extension;
335    
336                                                    if (originalTitle.endsWith(dotExtension)) {
337                                                            int pos = originalTitle.lastIndexOf(dotExtension);
338    
339                                                            originalTitle = originalTitle.substring(0, pos);
340                                                    }
341    
342                                                    for (int i = 1;; i++) {
343                                                            titleWithExtension =
344                                                                    originalTitle + StringPool.SPACE + i +
345                                                                            dotExtension;
346    
347                                                            existingTitleFileEntry = FileEntryUtil.findByR_F_T(
348                                                                    portletDataContext.getScopeGroupId(), folderId,
349                                                                    titleWithExtension);
350    
351                                                            if (existingTitleFileEntry == null) {
352                                                                    break;
353                                                            }
354                                                    }
355                                            }
356                                    }
357    
358                                    serviceContext.setUuid(fileEntry.getUuid());
359    
360                                    serviceContext.setAttribute(
361                                            "fileVersionUuid", fileVersion.getUuid());
362    
363                                    importedFileEntry = DLAppLocalServiceUtil.addFileEntry(
364                                            userId, portletDataContext.getScopeGroupId(), folderId,
365                                            titleWithExtension, fileEntry.getMimeType(),
366                                            fileEntry.getTitle(), fileEntry.getDescription(), null, is,
367                                            fileEntry.getSize(), serviceContext);
368                            }
369                            else {
370                                    FileVersion latestExistingFileVersion =
371                                            existingFileEntry.getLatestFileVersion();
372    
373                                    if (!fileVersion.getUuid().equals(
374                                                    latestExistingFileVersion.getUuid())) {
375    
376                                            DLFileVersion alreadyExistingFileVersion =
377                                                    DLFileVersionLocalServiceUtil.
378                                                            getFileVersionByUuidAndGroupId(
379                                                                    fileVersion.getUuid(),
380                                                                    existingFileEntry.getGroupId());
381    
382                                            if (alreadyExistingFileVersion != null) {
383                                                    serviceContext.setAttribute(
384                                                            "existingDLFileVersionId",
385                                                            alreadyExistingFileVersion.getFileVersionId());
386                                            }
387    
388                                            serviceContext.setUuid(fileVersion.getUuid());
389    
390                                            importedFileEntry =
391                                                    DLAppLocalServiceUtil.updateFileEntry(
392                                                            userId, existingFileEntry.getFileEntryId(),
393                                                            fileEntry.getTitle(), fileEntry.getMimeType(),
394                                                            fileEntry.getTitle(), fileEntry.getDescription(),
395                                                            null, false, is, fileEntry.getSize(),
396                                                            serviceContext);
397                                    }
398                                    else {
399                                            DLAppLocalServiceUtil.updateAsset(
400                                                    userId, existingFileEntry, latestExistingFileVersion,
401                                                    assetCategoryIds, assetTagNames, null);
402    
403                                            if (existingFileEntry instanceof LiferayFileEntry) {
404                                                    LiferayFileEntry liferayFileEntry =
405                                                            (LiferayFileEntry)existingFileEntry;
406    
407                                                    Indexer indexer = IndexerRegistryUtil.getIndexer(
408                                                            DLFileEntry.class);
409    
410                                                    indexer.reindex(liferayFileEntry.getModel());
411                                            }
412    
413                                            importedFileEntry = existingFileEntry;
414                                    }
415                            }
416                    }
417                    else {
418                            try {
419                                    importedFileEntry = DLAppLocalServiceUtil.addFileEntry(
420                                            userId, portletDataContext.getScopeGroupId(), folderId,
421                                            titleWithExtension, fileEntry.getMimeType(),
422                                            fileEntry.getTitle(), fileEntry.getDescription(), null, is,
423                                            fileEntry.getSize(), serviceContext);
424                            }
425                            catch (DuplicateFileException dfe) {
426                                    String title = fileEntry.getTitle();
427    
428                                    String[] titleParts = title.split("\\.", 2);
429    
430                                    title = titleParts[0] + PwdGenerator.getPassword();
431    
432                                    if (titleParts.length > 1) {
433                                            title += StringPool.PERIOD + titleParts[1];
434                                    }
435    
436                                    if (!title.endsWith(StringPool.PERIOD + extension)) {
437                                            title += StringPool.PERIOD + extension;
438                                    }
439    
440                                    importedFileEntry = DLAppLocalServiceUtil.addFileEntry(
441                                            userId, portletDataContext.getScopeGroupId(), folderId,
442                                            title, fileEntry.getMimeType(), title,
443                                            fileEntry.getDescription(), null, is, fileEntry.getSize(),
444                                            serviceContext);
445                            }
446                    }
447    
448                    if (portletDataContext.getBooleanParameter(
449                                    _NAMESPACE, "previews-and-thumbnails")) {
450    
451                            DLProcessorRegistryUtil.importGeneratedFiles(
452                                    portletDataContext, fileEntry, importedFileEntry,
453                                    fileEntryElement);
454                    }
455    
456                    Map<String, String> fileEntryTitles =
457                            (Map<String, String>)portletDataContext.getNewPrimaryKeysMap(
458                                    DLFileEntry.class.getName() + ".title");
459    
460                    fileEntryTitles.put(fileEntry.getTitle(), importedFileEntry.getTitle());
461    
462                    portletDataContext.importClassedModel(
463                            fileEntry, importedFileEntry, _NAMESPACE);
464            }
465    
466            public static void importFileRank(
467                            PortletDataContext portletDataContext, Element fileRankElement)
468                    throws Exception {
469    
470                    String path = fileRankElement.attributeValue("path");
471    
472                    if (!portletDataContext.isPathNotProcessed(path)) {
473                            return;
474                    }
475    
476                    DLFileRank fileRank =
477                            (DLFileRank)portletDataContext.getZipEntryAsObject(path);
478    
479                    String fileEntryUuid = fileRankElement.attributeValue(
480                            "file-entry-uuid");
481    
482                    importFileRank(portletDataContext, fileRank, fileEntryUuid);
483            }
484    
485            public static void importFolder(
486                            PortletDataContext portletDataContext, Element folderElement)
487                    throws Exception {
488    
489                    String path = folderElement.attributeValue("path");
490    
491                    if (!portletDataContext.isPathNotProcessed(path)) {
492                            return;
493                    }
494    
495                    Folder folder = (Folder)portletDataContext.getZipEntryAsObject(path);
496    
497                    importFolder(portletDataContext, path, folderElement, folder);
498            }
499    
500            @Override
501            public PortletDataHandlerControl[] getExportControls() {
502                    return new PortletDataHandlerControl[] {
503                            _repositories, _foldersAndDocuments, _shortcuts,
504                            _previewsAndThumbnails, _ranks
505                    };
506            }
507    
508            @Override
509            public PortletDataHandlerControl[] getExportMetadataControls() {
510                    return new PortletDataHandlerControl[] {
511                            new PortletDataHandlerBoolean(
512                                    _NAMESPACE, "folders-and-documents", true,
513                                    _metadataControls)
514                    };
515            }
516    
517            @Override
518            public PortletDataHandlerControl[] getImportControls() {
519                    return new PortletDataHandlerControl[] {
520                            _repositories, _foldersAndDocuments, _shortcuts,
521                            _previewsAndThumbnails, _ranks
522                    };
523            }
524    
525            @Override
526            public PortletDataHandlerControl[] getImportMetadataControls() {
527                    return new PortletDataHandlerControl[] {
528                            new PortletDataHandlerBoolean(
529                                    _NAMESPACE, "folders-and-documents", true, _metadataControls)
530                    };
531            }
532    
533            @Override
534            public boolean isAlwaysExportable() {
535                    return _ALWAYS_EXPORTABLE;
536            }
537    
538            @Override
539            public boolean isPublishToLiveByDefault() {
540                    return PropsValues.DL_PUBLISH_TO_LIVE_BY_DEFAULT;
541            }
542    
543            protected static void exportFileEntryType(
544                            PortletDataContext portletDataContext,
545                            Element fileEntryTypesElement, DLFileEntryType dlFileEntryType)
546                    throws Exception {
547    
548                    String path = getFileEntryTypePath(portletDataContext, dlFileEntryType);
549    
550                    if (!portletDataContext.isPathNotProcessed(path)) {
551                            return;
552                    }
553    
554                    Element fileEntryTypeElement = fileEntryTypesElement.addElement(
555                            "file-entry-type");
556    
557                    List<DDMStructure> ddmStructures = dlFileEntryType.getDDMStructures();
558    
559                    String[] ddmStructureUuids = new String[ddmStructures.size()];
560    
561                    for (int i = 0; i < ddmStructures.size(); i++) {
562                            DDMStructure ddmStructure = ddmStructures.get(i);
563    
564                            ddmStructureUuids[i] = ddmStructure.getUuid();
565    
566                            DDMPortletDataHandlerImpl.exportStructure(
567                                    portletDataContext, fileEntryTypeElement, ddmStructure);
568                    }
569    
570                    fileEntryTypeElement.addAttribute(
571                            "structureUuids", StringUtil.merge(ddmStructureUuids));
572    
573                    portletDataContext.addClassedModel(
574                            fileEntryTypeElement, path, dlFileEntryType, _NAMESPACE);
575            }
576    
577            protected static void exportFileRank(
578                            PortletDataContext portletDataContext, Element fileRanksElement,
579                            DLFileRank fileRank)
580                    throws Exception {
581    
582                    String path = getFileRankPath(portletDataContext, fileRank);
583    
584                    if (!portletDataContext.isPathNotProcessed(path)) {
585                            return;
586                    }
587    
588                    Element fileRankElement = fileRanksElement.addElement("file-rank");
589    
590                    FileEntry fileEntry = FileEntryUtil.fetchByPrimaryKey(
591                            fileRank.getFileEntryId());
592    
593                    String fileEntryUuid = fileEntry.getUuid();
594    
595                    fileRankElement.addAttribute("file-entry-uuid", fileEntryUuid);
596    
597                    portletDataContext.addClassedModel(
598                            fileRankElement, path, fileRank, _NAMESPACE);
599            }
600    
601            protected static void exportFileShortcut(
602                            PortletDataContext portletDataContext,
603                            Element fileEntryTypesElement, Element foldersElement,
604                            Element fileShortcutsElement, DLFileShortcut fileShortcut)
605                    throws Exception {
606    
607                    if (!portletDataContext.isWithinDateRange(
608                                    fileShortcut.getModifiedDate())) {
609    
610                            return;
611                    }
612    
613                    exportParentFolder(
614                            portletDataContext, fileEntryTypesElement, foldersElement,
615                            fileShortcut.getFolderId());
616    
617                    String path = getFileShortcutPath(portletDataContext, fileShortcut);
618    
619                    if (portletDataContext.isPathNotProcessed(path)) {
620                            Element fileShortcutElement = fileShortcutsElement.addElement(
621                                    "file-shortcut");
622    
623                            FileEntry fileEntry = FileEntryUtil.fetchByPrimaryKey(
624                                    fileShortcut.getToFileEntryId());
625    
626                            String fileEntryUuid = fileEntry.getUuid();
627    
628                            fileShortcutElement.addAttribute("file-entry-uuid", fileEntryUuid);
629    
630                            portletDataContext.addClassedModel(
631                                    fileShortcutElement, path, fileShortcut, _NAMESPACE);
632                    }
633            }
634    
635            protected static void exportFolder(
636                            PortletDataContext portletDataContext,
637                            Element fileEntryTypesElement, Element foldersElement,
638                            Element fileEntriesElement, Element fileShortcutsElement,
639                            Element fileRanksElement, Folder folder, boolean recurse)
640                    throws Exception {
641    
642                    if (!portletDataContext.isWithinDateRange(folder.getModifiedDate())) {
643                            return;
644                    }
645    
646                    exportParentFolder(
647                            portletDataContext, fileEntryTypesElement, foldersElement,
648                            folder.getParentFolderId());
649    
650                    String path = getFolderPath(portletDataContext, folder);
651    
652                    if (!portletDataContext.isPathNotProcessed(path)) {
653                            return;
654                    }
655    
656                    Element folderElement = foldersElement.addElement("folder");
657    
658                    exportFolderFileEntryTypes(
659                            portletDataContext, folder, fileEntryTypesElement, folderElement);
660    
661                    portletDataContext.addClassedModel(
662                            folderElement, path, folder, _NAMESPACE);
663    
664                    if (recurse) {
665                            List<Folder> folders = FolderUtil.findByR_P(
666                                    folder.getRepositoryId(), folder.getFolderId());
667    
668                            for (Folder curFolder : folders) {
669                                    exportFolder(
670                                            portletDataContext, fileEntryTypesElement, foldersElement,
671                                            fileEntriesElement, fileShortcutsElement, fileRanksElement,
672                                            curFolder, recurse);
673                            }
674                    }
675    
676                    List<FileEntry> fileEntries = FileEntryUtil.findByR_F(
677                            folder.getRepositoryId(), folder.getFolderId());
678    
679                    for (FileEntry fileEntry : fileEntries) {
680                            exportFileEntry(
681                                    portletDataContext, fileEntryTypesElement, foldersElement,
682                                    fileEntriesElement, fileRanksElement, fileEntry, true);
683                    }
684    
685                    if (portletDataContext.getBooleanParameter(_NAMESPACE, "shortcuts")) {
686                            List<DLFileShortcut> fileShortcuts = DLFileShortcutUtil.findByG_F(
687                                    folder.getRepositoryId(), folder.getFolderId());
688    
689                            for (DLFileShortcut fileShortcut : fileShortcuts) {
690                                    exportFileShortcut(
691                                            portletDataContext, fileEntryTypesElement, foldersElement,
692                                            fileShortcutsElement, fileShortcut);
693                            }
694                    }
695            }
696    
697            protected static void exportFolderFileEntryTypes(
698                            PortletDataContext portletDataContext, Folder folder,
699                            Element fileEntryTypesElement, Element folderElement)
700                    throws Exception {
701    
702                    List<DLFileEntryType> dlFileEntryTypes =
703                            DLFileEntryTypeLocalServiceUtil.getFolderFileEntryTypes(
704                                    new long[] {portletDataContext.getScopeGroupId()},
705                                    folder.getFolderId(), false);
706    
707                    String[] fileEntryTypeUuids = new String[dlFileEntryTypes.size()];
708    
709                    long defaultFileEntryTypeId =
710                            DLFileEntryTypeLocalServiceUtil.getDefaultFileEntryTypeId(
711                                    folder.getFolderId());
712    
713                    String defaultFileEntryTypeUuid = StringPool.BLANK;
714    
715                    for (int i = 0; i < dlFileEntryTypes.size(); i++) {
716                            DLFileEntryType dlFileEntryType = dlFileEntryTypes.get(i);
717    
718                            if (!isFileEntryTypeExportable(
719                                            portletDataContext.getCompanyId(), dlFileEntryType)) {
720    
721                                    continue;
722                            }
723    
724                            fileEntryTypeUuids[i] = dlFileEntryType.getUuid();
725    
726                            if (defaultFileEntryTypeId ==
727                                            dlFileEntryType.getFileEntryTypeId()) {
728    
729                                    defaultFileEntryTypeUuid = dlFileEntryType.getUuid();
730                            }
731    
732                            exportFileEntryType(
733                                    portletDataContext, fileEntryTypesElement, dlFileEntryType);
734                    }
735    
736                    folderElement.addAttribute(
737                            "fileEntryTypeUuids", StringUtil.merge(fileEntryTypeUuids));
738                    folderElement.addAttribute(
739                            "defaultFileEntryTypeUuid", defaultFileEntryTypeUuid);
740            }
741    
742            protected static void exportMetaData(
743                            PortletDataContext portletDataContext,
744                            Element fileEntryTypesElement, Element fileEntryElement,
745                            FileEntry fileEntry)
746                    throws Exception {
747    
748                    if (!(fileEntry instanceof LiferayFileEntry)) {
749                            return;
750                    }
751    
752                    LiferayFileEntry liferayFileEntry = (LiferayFileEntry)fileEntry;
753    
754                    DLFileEntry dlFileEntry = liferayFileEntry.getDLFileEntry();
755    
756                    long fileEntryTypeId = dlFileEntry.getFileEntryTypeId();
757    
758                    DLFileEntryType dlFileEntryType =
759                            DLFileEntryTypeLocalServiceUtil.fetchFileEntryType(fileEntryTypeId);
760    
761                    if (dlFileEntryType == null) {
762                            return;
763                    }
764    
765                    fileEntryElement.addAttribute(
766                            "fileEntryTypeUuid", dlFileEntryType.getUuid());
767    
768                    if (!isFileEntryTypeExportable(
769                                    portletDataContext.getCompanyId(), dlFileEntryType)) {
770    
771                            return;
772                    }
773    
774                    exportFileEntryType(
775                            portletDataContext, fileEntryTypesElement, dlFileEntryType);
776    
777                    List<DDMStructure> ddmStructures = dlFileEntryType.getDDMStructures();
778    
779                    for (DDMStructure ddmStructure : ddmStructures) {
780                            Element structureFields = fileEntryElement.addElement(
781                                    "structure-fields");
782    
783                            String path = getFileEntryFileEntryTypeStructureFieldsPath(
784                                    portletDataContext, fileEntry, dlFileEntryType.getUuid(),
785                                    ddmStructure.getStructureId());
786    
787                            structureFields.addAttribute("path", path);
788    
789                            structureFields.addAttribute(
790                                    "structureUuid", ddmStructure.getUuid());
791    
792                            FileVersion fileVersion = fileEntry.getFileVersion();
793    
794                            DLFileEntryMetadata dlFileEntryMetadata =
795                                    DLFileEntryMetadataLocalServiceUtil.getFileEntryMetadata(
796                                            ddmStructure.getStructureId(),
797                                            fileVersion.getFileVersionId());
798    
799                            Fields fields = StorageEngineUtil.getFields(
800                                    dlFileEntryMetadata.getDDMStorageId());
801    
802                            portletDataContext.addZipEntry(path, fields);
803                    }
804            }
805    
806            protected static void exportParentFolder(
807                            PortletDataContext portletDataContext,
808                            Element fileEntryTypesElement, Element foldersElement,
809                            long folderId)
810                    throws Exception {
811    
812                    if (folderId == DLFolderConstants.DEFAULT_PARENT_FOLDER_ID) {
813                            return;
814                    }
815    
816                    Folder folder = FolderUtil.findByPrimaryKey(folderId);
817    
818                    exportParentFolder(
819                            portletDataContext, fileEntryTypesElement, foldersElement,
820                            folder.getParentFolderId());
821    
822                    String path = getFolderPath(portletDataContext, folder);
823    
824                    if (portletDataContext.isPathNotProcessed(path)) {
825                            Element folderElement = foldersElement.addElement("folder");
826    
827                            exportFolderFileEntryTypes(
828                                    portletDataContext, folder, fileEntryTypesElement,
829                                    folderElement);
830    
831                            portletDataContext.addClassedModel(
832                                    folderElement, path, folder, _NAMESPACE);
833                    }
834            }
835    
836            protected static void exportRepository(
837                            PortletDataContext portletDataContext, Element repositoriesElement,
838                            Repository repository)
839                    throws Exception {
840    
841                    if (!portletDataContext.isWithinDateRange(
842                                    repository.getModifiedDate())) {
843    
844                            return;
845                    }
846    
847                    String path = getRepositoryPath(portletDataContext, repository);
848    
849                    if (!portletDataContext.isPathNotProcessed(path)) {
850                            return;
851                    }
852    
853                    Element repositoryElement = repositoriesElement.addElement(
854                            "repository");
855    
856                    repositoryElement.addAttribute(
857                            "repositoryClassName", repository.getClassName());
858    
859                    portletDataContext.addClassedModel(
860                            repositoryElement, path, repository, _NAMESPACE);
861            }
862    
863            protected static String getFileEntryBinPath(
864                    PortletDataContext portletDataContext, FileEntry fileEntry) {
865    
866                    StringBundler sb = new StringBundler(5);
867    
868                    sb.append(
869                            portletDataContext.getPortletPath(PortletKeys.DOCUMENT_LIBRARY));
870                    sb.append("/bin/");
871                    sb.append(fileEntry.getFileEntryId());
872                    sb.append(StringPool.SLASH);
873                    sb.append(fileEntry.getVersion());
874    
875                    return sb.toString();
876            }
877    
878            protected static String getFileEntryFileEntryTypeStructureFieldsPath(
879                    PortletDataContext portletDataContext, FileEntry fileEntry,
880                    String fileEntryTypeUuid, long structureId) {
881    
882                    StringBundler sb = new StringBundler(4);
883    
884                    String fileEntryPath = getFileEntryPath(portletDataContext, fileEntry);
885    
886                    sb.append(StringUtil.replace(fileEntryPath, ".xml", StringPool.BLANK));
887                    sb.append("/file-entry-type/");
888                    sb.append(fileEntryTypeUuid);
889                    sb.append("/structure-fields/");
890                    sb.append(structureId);
891                    sb.append(".xml");
892    
893                    return sb.toString();
894            }
895    
896            /**
897             * @see {@link PortletImporter#getAssetCategoryName(String, long, String,
898             *      int)}
899             * @see {@link PortletImporter#getAssetVocabularyName(String, long, String,
900             *      int)}
901             */
902            protected static String getFileEntryTypeName(
903                            String uuid, long companyId, long groupId, String name, int count)
904                    throws Exception {
905    
906                    DLFileEntryType dlFileEntryType = DLFileEntryTypeUtil.fetchByG_N(
907                            groupId, name);
908    
909                    if (dlFileEntryType == null) {
910                            return name;
911                    }
912    
913                    if (Validator.isNotNull(uuid) &&
914                            uuid.equals(dlFileEntryType.getUuid())) {
915    
916                            return name;
917                    }
918    
919                    name = StringUtil.appendParentheticalSuffix(name, count);
920    
921                    return getFileEntryTypeName(uuid, companyId, groupId, name, ++count);
922            }
923    
924            protected static String getFileEntryTypePath(
925                    PortletDataContext portletDataContext,
926                    DLFileEntryType dlFileEntryType) {
927    
928                    StringBundler sb = new StringBundler(4);
929    
930                    sb.append(
931                            portletDataContext.getPortletPath(PortletKeys.DOCUMENT_LIBRARY));
932                    sb.append("/entry-types/");
933                    sb.append(dlFileEntryType.getFileEntryTypeId());
934                    sb.append(".xml");
935    
936                    return sb.toString();
937            }
938    
939            protected static String getFileRankPath(
940                    PortletDataContext portletDataContext, DLFileRank fileRank) {
941    
942                    StringBundler sb = new StringBundler(4);
943    
944                    sb.append(
945                            portletDataContext.getPortletPath(PortletKeys.DOCUMENT_LIBRARY));
946                    sb.append("/ranks/");
947                    sb.append(fileRank.getFileRankId());
948                    sb.append(".xml");
949    
950                    return sb.toString();
951            }
952    
953            protected static String getFileShortcutPath(
954                    PortletDataContext portletDataContext, DLFileShortcut fileShortcut) {
955    
956                    StringBundler sb = new StringBundler(4);
957    
958                    sb.append(
959                            portletDataContext.getPortletPath(PortletKeys.DOCUMENT_LIBRARY));
960                    sb.append("/shortcuts/");
961                    sb.append(fileShortcut.getFileShortcutId());
962                    sb.append(".xml");
963    
964                    return sb.toString();
965            }
966    
967            /**
968             * @see {@link PortletImporter#getAssetCategoryName(String, long, String,
969             *      int)}
970             * @see {@link PortletImporter#getAssetVocabularyName(String, long, String,
971             *      int)}
972             */
973            protected static String getFolderName(
974                            String uuid, long groupId, long parentFolderId, String name,
975                            int count)
976                    throws Exception {
977    
978                    Folder folder = FolderUtil.fetchByR_P_N(groupId, parentFolderId, name);
979    
980                    if (folder == null) {
981                            return name;
982                    }
983    
984                    if (Validator.isNotNull(uuid) && uuid.equals(folder.getUuid())) {
985                            return name;
986                    }
987    
988                    name = StringUtil.appendParentheticalSuffix(name, count);
989    
990                    return getFolderName(uuid, groupId, parentFolderId, name, ++count);
991            }
992    
993            protected static String getFolderPath(
994                    PortletDataContext portletDataContext, Folder folder) {
995    
996                    StringBundler sb = new StringBundler(4);
997    
998                    sb.append(
999                            portletDataContext.getPortletPath(PortletKeys.DOCUMENT_LIBRARY));
1000                    sb.append("/folders/");
1001                    sb.append(folder.getFolderId());
1002                    sb.append(".xml");
1003    
1004                    return sb.toString();
1005            }
1006    
1007            protected static String getImportFolderPath(
1008                    PortletDataContext portletDataContext, long folderId) {
1009    
1010                    StringBundler sb = new StringBundler(4);
1011    
1012                    sb.append(
1013                            portletDataContext.getSourcePortletPath(
1014                                    PortletKeys.DOCUMENT_LIBRARY));
1015                    sb.append("/folders/");
1016                    sb.append(folderId);
1017                    sb.append(".xml");
1018    
1019                    return sb.toString();
1020            }
1021    
1022            protected static String getImportRepositoryPath(
1023                    PortletDataContext portletDataContext, long repositoryId) {
1024    
1025                    StringBundler sb = new StringBundler(4);
1026    
1027                    sb.append(
1028                            portletDataContext.getSourcePortletPath(
1029                                    PortletKeys.DOCUMENT_LIBRARY));
1030                    sb.append("/repositories/");
1031                    sb.append(repositoryId);
1032                    sb.append(".xml");
1033    
1034                    return sb.toString();
1035            }
1036    
1037            protected static String getRepositoryPath(
1038                    PortletDataContext portletDataContext, Repository repository) {
1039    
1040                    StringBundler sb = new StringBundler(4);
1041    
1042                    sb.append(
1043                            portletDataContext.getPortletPath(PortletKeys.DOCUMENT_LIBRARY));
1044                    sb.append("/repositories/");
1045                    sb.append(repository.getRepositoryId());
1046                    sb.append(".xml");
1047    
1048                    return sb.toString();
1049            }
1050    
1051            protected static void importFileEntryType(
1052                            PortletDataContext portletDataContext, Element fileEntryTypeElement)
1053                    throws Exception {
1054    
1055                    String path = fileEntryTypeElement.attributeValue("path");
1056    
1057                    if (!portletDataContext.isPathNotProcessed(path)) {
1058                            return;
1059                    }
1060    
1061                    DLFileEntryType dlFileEntryType =
1062                            (DLFileEntryType)portletDataContext.getZipEntryAsObject(path);
1063    
1064                    long userId = portletDataContext.getUserId(
1065                            dlFileEntryType.getUserUuid());
1066    
1067                    String name = getFileEntryTypeName(
1068                            dlFileEntryType.getUuid(), portletDataContext.getCompanyId(),
1069                            portletDataContext.getScopeGroupId(), dlFileEntryType.getName(), 2);
1070    
1071                    List<Element> structureElements = fileEntryTypeElement.elements(
1072                            "structure");
1073    
1074                    for (Element structureElement : structureElements) {
1075                            DDMPortletDataHandlerImpl.importStructure(
1076                                    portletDataContext, structureElement);
1077                    }
1078    
1079                    String[] ddmStructureUuids = StringUtil.split(
1080                            fileEntryTypeElement.attributeValue("structureUuids"));
1081    
1082                    long[] ddmStrutureIds = new long[ddmStructureUuids.length];
1083    
1084                    for (int i = 0; i < ddmStructureUuids.length; i++) {
1085                            DDMStructure existingStructure = DDMStructureUtil.fetchByUUID_G(
1086                                    ddmStructureUuids[i], portletDataContext.getScopeGroupId());
1087    
1088                            ddmStrutureIds[i] = existingStructure.getStructureId();
1089                    }
1090    
1091                    ServiceContext serviceContext = portletDataContext.createServiceContext(
1092                            path, dlFileEntryType, _NAMESPACE);
1093    
1094                    DLFileEntryType importedDLFileEntryType = null;
1095    
1096                    if (portletDataContext.isDataStrategyMirror()) {
1097                            DLFileEntryType existingDLFileEntryType =
1098                                    DLFileEntryTypeUtil.fetchByUUID_G(
1099                                            dlFileEntryType.getUuid(),
1100                                            portletDataContext.getScopeGroupId());
1101    
1102                            if (existingDLFileEntryType == null) {
1103                                    serviceContext.setUuid(dlFileEntryType.getUuid());
1104    
1105                                    importedDLFileEntryType =
1106                                            DLFileEntryTypeLocalServiceUtil.addFileEntryType(
1107                                                    userId, portletDataContext.getScopeGroupId(), name,
1108                                                    dlFileEntryType.getDescription(), ddmStrutureIds,
1109                                                    serviceContext);
1110                            }
1111                            else {
1112                                    DLFileEntryTypeLocalServiceUtil.updateFileEntryType(
1113                                            userId, existingDLFileEntryType.getFileEntryTypeId(), name,
1114                                            dlFileEntryType.getDescription(), ddmStrutureIds,
1115                                            serviceContext);
1116    
1117                                    importedDLFileEntryType = existingDLFileEntryType;
1118                            }
1119                    }
1120                    else {
1121                            importedDLFileEntryType =
1122                                    DLFileEntryTypeLocalServiceUtil.addFileEntryType(
1123                                            userId, portletDataContext.getScopeGroupId(), name,
1124                                            dlFileEntryType.getDescription(), ddmStrutureIds,
1125                                            serviceContext);
1126                    }
1127    
1128                    portletDataContext.importClassedModel(
1129                            dlFileEntryType, importedDLFileEntryType, _NAMESPACE);
1130            }
1131    
1132            protected static void importFileRank(
1133                            PortletDataContext portletDataContext, DLFileRank fileRank,
1134                            String fileEntryUuid)
1135                    throws Exception {
1136    
1137                    long userId = portletDataContext.getUserId(fileRank.getUserUuid());
1138    
1139                    long groupId = portletDataContext.getScopeGroupId();
1140    
1141                    FileEntry fileEntry = FileEntryUtil.fetchByUUID_R(
1142                            fileEntryUuid, groupId);
1143    
1144                    if (fileEntry == null) {
1145                            if (_log.isWarnEnabled()) {
1146                                    _log.warn(
1147                                            "Unable to retrieve file " + fileEntryUuid +
1148                                                    " to import file rank");
1149                            }
1150    
1151                            return;
1152                    }
1153    
1154                    long fileEntryId = fileEntry.getFileEntryId();
1155    
1156                    ServiceContext serviceContext = new ServiceContext();
1157    
1158                    serviceContext.setCreateDate(fileRank.getCreateDate());
1159    
1160                    DLAppLocalServiceUtil.updateFileRank(
1161                            portletDataContext.getScopeGroupId(),
1162                            portletDataContext.getCompanyId(), userId, fileEntryId,
1163                            serviceContext);
1164            }
1165    
1166            protected static void importFileShortcut(
1167                            PortletDataContext portletDataContext, Element fileShortcutElement)
1168                    throws Exception {
1169    
1170                    String path = fileShortcutElement.attributeValue("path");
1171    
1172                    if (!portletDataContext.isPathNotProcessed(path)) {
1173                            return;
1174                    }
1175    
1176                    DLFileShortcut fileShortcut =
1177                            (DLFileShortcut)portletDataContext.getZipEntryAsObject(path);
1178    
1179                    importFileShortcut(
1180                            portletDataContext, fileShortcutElement, fileShortcut);
1181            }
1182    
1183            protected static void importFileShortcut(
1184                            PortletDataContext portletDataContext, Element fileShortcutElement,
1185                            DLFileShortcut fileShortcut)
1186                    throws Exception {
1187    
1188                    long userId = portletDataContext.getUserId(fileShortcut.getUserUuid());
1189    
1190                    Map<Long, Long> folderPKs =
1191                            (Map<Long, Long>)portletDataContext.getNewPrimaryKeysMap(
1192                                    DLFolder.class);
1193    
1194                    long folderId = MapUtil.getLong(
1195                            folderPKs, fileShortcut.getFolderId(), fileShortcut.getFolderId());
1196    
1197                    long groupId = portletDataContext.getScopeGroupId();
1198    
1199                    if (folderId != DLFolderConstants.DEFAULT_PARENT_FOLDER_ID) {
1200                            Folder folder = FolderUtil.findByPrimaryKey(folderId);
1201    
1202                            groupId = folder.getRepositoryId();
1203                    }
1204    
1205                    String fileEntryUuid = fileShortcutElement.attributeValue(
1206                            "file-entry-uuid");
1207    
1208                    FileEntry fileEntry = FileEntryUtil.fetchByUUID_R(
1209                            fileEntryUuid, groupId);
1210    
1211                    if (fileEntry == null) {
1212                            if (_log.isWarnEnabled()) {
1213                                    _log.warn(
1214                                            "Unable to fetch file entry {uuid=" + fileEntryUuid +
1215                                                    ", groupId=" + groupId + "}");
1216                            }
1217    
1218                            return;
1219                    }
1220    
1221                    long fileEntryId = fileEntry.getFileEntryId();
1222    
1223                    ServiceContext serviceContext = portletDataContext.createServiceContext(
1224                            fileShortcutElement, fileShortcut, _NAMESPACE);
1225    
1226                    DLFileShortcut importedFileShortcut = null;
1227    
1228                    if (portletDataContext.isDataStrategyMirror()) {
1229                            DLFileShortcut existingFileShortcut =
1230                                    DLFileShortcutUtil.fetchByUUID_G(
1231                                            fileShortcut.getUuid(),
1232                                            portletDataContext.getScopeGroupId());
1233    
1234                            if (existingFileShortcut == null) {
1235                                    serviceContext.setUuid(fileShortcut.getUuid());
1236    
1237                                    importedFileShortcut = DLAppLocalServiceUtil.addFileShortcut(
1238                                            userId, groupId, folderId, fileEntryId, serviceContext);
1239                            }
1240                            else {
1241                                    importedFileShortcut = DLAppLocalServiceUtil.updateFileShortcut(
1242                                            userId, existingFileShortcut.getFileShortcutId(), folderId,
1243                                            fileEntryId, serviceContext);
1244                            }
1245                    }
1246                    else {
1247                            importedFileShortcut = DLAppLocalServiceUtil.addFileShortcut(
1248                                    userId, groupId, folderId, fileEntryId, serviceContext);
1249                    }
1250    
1251                    portletDataContext.importClassedModel(
1252                            fileShortcut, importedFileShortcut, _NAMESPACE);
1253            }
1254    
1255            protected static void importFolder(
1256                            PortletDataContext portletDataContext, String folderPath,
1257                            Element folderElement, Folder folder)
1258                    throws Exception {
1259    
1260                    long userId = portletDataContext.getUserId(folder.getUserUuid());
1261    
1262                    Map<Long, Long> folderPKs =
1263                            (Map<Long, Long>)portletDataContext.getNewPrimaryKeysMap(
1264                                    DLFolder.class);
1265    
1266                    long parentFolderId = MapUtil.getLong(
1267                            folderPKs, folder.getParentFolderId(), folder.getParentFolderId());
1268    
1269                    ServiceContext serviceContext = portletDataContext.createServiceContext(
1270                            folderPath, folder, _NAMESPACE);
1271    
1272                    if ((parentFolderId != DLFolderConstants.DEFAULT_PARENT_FOLDER_ID) &&
1273                            (parentFolderId == folder.getParentFolderId())) {
1274    
1275                            String path = getImportFolderPath(
1276                                    portletDataContext, parentFolderId);
1277    
1278                            Folder parentFolder =
1279                                    (Folder)portletDataContext.getZipEntryAsObject(path);
1280    
1281                            importFolder(portletDataContext, path, folderElement, parentFolder);
1282    
1283                            parentFolderId = MapUtil.getLong(
1284                                    folderPKs, folder.getParentFolderId(),
1285                                    folder.getParentFolderId());
1286                    }
1287    
1288                    Folder importedFolder = null;
1289    
1290                    if (portletDataContext.isDataStrategyMirror()) {
1291                            Folder existingFolder = FolderUtil.fetchByUUID_R(
1292                                    folder.getUuid(), portletDataContext.getScopeGroupId());
1293    
1294                            if (existingFolder == null) {
1295                                    String name = getFolderName(
1296                                            null, portletDataContext.getScopeGroupId(), parentFolderId,
1297                                            folder.getName(), 2);
1298    
1299                                    serviceContext.setUuid(folder.getUuid());
1300    
1301                                    importedFolder = DLAppLocalServiceUtil.addFolder(
1302                                            userId, portletDataContext.getScopeGroupId(),
1303                                            parentFolderId, name, folder.getDescription(),
1304                                            serviceContext);
1305                            }
1306                            else {
1307                                    String name = getFolderName(
1308                                            folder.getUuid(), portletDataContext.getScopeGroupId(),
1309                                            parentFolderId, folder.getName(), 2);
1310    
1311                                    importedFolder = DLAppLocalServiceUtil.updateFolder(
1312                                            existingFolder.getFolderId(), parentFolderId, name,
1313                                            folder.getDescription(), serviceContext);
1314                            }
1315                    }
1316                    else {
1317                            String name = getFolderName(
1318                                    null, portletDataContext.getScopeGroupId(), parentFolderId,
1319                                    folder.getName(), 2);
1320    
1321                            importedFolder = DLAppLocalServiceUtil.addFolder(
1322                                    userId, portletDataContext.getScopeGroupId(), parentFolderId,
1323                                    name, folder.getDescription(), serviceContext);
1324                    }
1325    
1326                    importFolderFileEntryTypes(
1327                            portletDataContext, folderElement, importedFolder, serviceContext);
1328    
1329                    portletDataContext.importClassedModel(
1330                            folder, importedFolder, _NAMESPACE);
1331            }
1332    
1333            protected static void importFolderFileEntryTypes(
1334                            PortletDataContext portletDataContext, Element folderElement,
1335                            Folder folder, ServiceContext serviceContext)
1336                    throws Exception {
1337    
1338                    String[] fileEntryTypeUuids = StringUtil.split(
1339                            folderElement.attributeValue("fileEntryTypeUuids"));
1340    
1341                    List<Long> fileEntryTypeIds = new ArrayList<Long>();
1342    
1343                    String defaultFileEntryTypeUuid = GetterUtil.getString(
1344                            folderElement.attributeValue("defaultFileEntryTypeUuid"));
1345    
1346                    long defaultFileEntryTypeId = 0;
1347    
1348                    for (String fileEntryTypeUuid : fileEntryTypeUuids) {
1349                            DLFileEntryType dlFileEntryType = DLFileEntryTypeUtil.fetchByUUID_G(
1350                                    fileEntryTypeUuid, portletDataContext.getScopeGroupId());
1351    
1352                            if (dlFileEntryType == null) {
1353                                    continue;
1354                            }
1355    
1356                            fileEntryTypeIds.add(dlFileEntryType.getFileEntryTypeId());
1357    
1358                            if (defaultFileEntryTypeUuid.equals(dlFileEntryType.getUuid())) {
1359                                    defaultFileEntryTypeId = dlFileEntryType.getFileEntryTypeId();
1360                            }
1361                    }
1362    
1363                    DLFileEntryTypeLocalServiceUtil.updateFolderFileEntryTypes(
1364                            (DLFolder)folder.getModel(), fileEntryTypeIds,
1365                            defaultFileEntryTypeId, serviceContext);
1366            }
1367    
1368            protected static void importMetaData(
1369                            PortletDataContext portletDataContext, Element fileEntryElement,
1370                            ServiceContext serviceContext)
1371                    throws Exception {
1372    
1373                    String fileEntryTypeUuid = fileEntryElement.attributeValue(
1374                            "fileEntryTypeUuid");
1375    
1376                    if (Validator.isNull(fileEntryTypeUuid)) {
1377                            return;
1378                    }
1379    
1380                    DLFileEntryType dlFileEntryType = DLFileEntryTypeUtil.fetchByUUID_G(
1381                            fileEntryTypeUuid, portletDataContext.getScopeGroupId());
1382    
1383                    if (dlFileEntryType == null) {
1384                            serviceContext.setAttribute("fileEntryTypeId", -1);
1385    
1386                            return;
1387                    }
1388    
1389                    serviceContext.setAttribute(
1390                            "fileEntryTypeId", dlFileEntryType.getFileEntryTypeId());
1391    
1392                    List<DDMStructure> ddmStructures = dlFileEntryType.getDDMStructures();
1393    
1394                    for (DDMStructure ddmStructure : ddmStructures) {
1395                            Element structureFieldsElement =
1396                                    (Element)fileEntryElement.selectSingleNode(
1397                                            "//structure-fields[@structureUuid='".concat(
1398                                                    ddmStructure.getUuid()).concat("']"));
1399    
1400                            if (structureFieldsElement == null) {
1401                                    continue;
1402                            }
1403    
1404                            String path = structureFieldsElement.attributeValue("path");
1405    
1406                            Fields fields = (Fields)portletDataContext.getZipEntryAsObject(
1407                                    path);
1408    
1409                            serviceContext.setAttribute(
1410                                    Fields.class.getName() + ddmStructure.getStructureId(), fields);
1411                    }
1412            }
1413    
1414            protected static void importRepository(
1415                            PortletDataContext portletDataContext, Element repositoryElement)
1416                    throws Exception {
1417    
1418                    String path = repositoryElement.attributeValue("path");
1419    
1420                    if (!portletDataContext.isPathNotProcessed(path)) {
1421                            return;
1422                    }
1423    
1424                    Repository repository =
1425                            (Repository)portletDataContext.getZipEntryAsObject(path);
1426    
1427                    long userId = portletDataContext.getUserId(repository.getUserUuid());
1428                    long classNameId = PortalUtil.getClassNameId(
1429                            repositoryElement.attributeValue("repositoryClassName"));
1430    
1431                    String repositoryPath = getImportRepositoryPath(
1432                            portletDataContext, repository.getRepositoryId());
1433    
1434                    ServiceContext serviceContext = portletDataContext.createServiceContext(
1435                            repositoryPath, repository, _NAMESPACE);
1436    
1437                    try {
1438                            RepositoryLocalServiceUtil.addRepository(
1439                                    userId, portletDataContext.getScopeGroupId(), classNameId,
1440                                    DLFolderConstants.DEFAULT_PARENT_FOLDER_ID,
1441                                    repository.getName(), repository.getDescription(),
1442                                    repository.getPortletId(),
1443                                    repository.getTypeSettingsProperties(), serviceContext);
1444                    }
1445                    catch (Exception e) {
1446                            if (_log.isWarnEnabled()) {
1447                                    _log.warn(
1448                                            "Unable to connect to repository {name=" +
1449                                                    repository.getName() + ",typeSettings=" +
1450                                                            repository.getTypeSettingsProperties() + "}",
1451                                            e);
1452                            }
1453                    }
1454            }
1455    
1456            protected static boolean isDuplicateFileEntry(
1457                    String folderUuid, FileEntry fileEntry1, FileEntry fileEntry2) {
1458    
1459                    try {
1460                            Folder folder2 = fileEntry2.getFolder();
1461    
1462                            if (folderUuid.equals(folder2.getUuid()) &&
1463                                    (fileEntry1.getSize() == fileEntry2.getSize()) &&
1464                                    (DLUtil.compareVersions(
1465                                            fileEntry1.getVersion(), fileEntry2.getVersion()) == 0) &&
1466                                    fileEntry1.getVersionUserUuid().equals(
1467                                            fileEntry2.getVersionUserUuid())) {
1468    
1469                                    return true;
1470                            }
1471                            else {
1472                                    return false;
1473                            }
1474                    }
1475                    catch (Exception e) {
1476                            return false;
1477                    }
1478            }
1479    
1480            protected static boolean isFileEntryTypeExportable(
1481                            long companyId, DLFileEntryType dlFileEntryType)
1482                    throws PortalException, SystemException {
1483    
1484                    if (dlFileEntryType.getFileEntryTypeId() == 0) {
1485                            return false;
1486                    }
1487    
1488                    Group group = GroupLocalServiceUtil.getCompanyGroup(companyId);
1489    
1490                    if (dlFileEntryType.getGroupId() == group.getGroupId()) {
1491                            return false;
1492                    }
1493    
1494                    return true;
1495            }
1496    
1497            @Override
1498            protected PortletPreferences doDeleteData(
1499                            PortletDataContext portletDataContext, String portletId,
1500                            PortletPreferences portletPreferences)
1501                    throws Exception {
1502    
1503                    if (!portletDataContext.addPrimaryKey(
1504                                    DLPortletDataHandlerImpl.class, "deleteData")) {
1505    
1506                            DLAppLocalServiceUtil.deleteAll(
1507                                    portletDataContext.getScopeGroupId());
1508                    }
1509    
1510                    return null;
1511            }
1512    
1513            @Override
1514            protected String doExportData(
1515                            PortletDataContext portletDataContext, String portletId,
1516                            PortletPreferences portletPreferences)
1517                    throws Exception {
1518    
1519                    portletDataContext.addPermissions(
1520                            "com.liferay.portlet.documentlibrary",
1521                            portletDataContext.getScopeGroupId());
1522    
1523                    Document document = SAXReaderUtil.createDocument();
1524    
1525                    Element rootElement = document.addElement("documentlibrary-data");
1526    
1527                    rootElement.addAttribute(
1528                            "group-id", String.valueOf(portletDataContext.getScopeGroupId()));
1529    
1530                    long rootFolderId = GetterUtil.getLong(
1531                            portletPreferences.getValue("rootFolderId", null));
1532    
1533                    if (rootFolderId != DLFolderConstants.DEFAULT_PARENT_FOLDER_ID) {
1534                            rootElement.addAttribute(
1535                                    "root-folder-id", String.valueOf(rootFolderId));
1536                    }
1537    
1538                    Element repositoryElement = rootElement.addElement("repositories");
1539                    Element fileEntryTypesElement = rootElement.addElement(
1540                            "file-entry-types");
1541                    Element foldersElement = rootElement.addElement("folders");
1542                    Element fileEntriesElement = rootElement.addElement("file-entries");
1543                    Element fileShortcutsElement = rootElement.addElement("file-shortcuts");
1544                    Element fileRanksElement = rootElement.addElement("file-ranks");
1545    
1546                    List<DLFileEntryType> dlFileEntryTypes =
1547                            DLFileEntryTypeServiceUtil.getFileEntryTypes(
1548                                    new long[] {portletDataContext.getScopeGroupId()});
1549    
1550                    for (DLFileEntryType dlFileEntryType : dlFileEntryTypes) {
1551                            if (!isFileEntryTypeExportable(
1552                                            portletDataContext.getCompanyId(), dlFileEntryType)) {
1553    
1554                                    continue;
1555                            }
1556    
1557                            exportFileEntryType(
1558                                    portletDataContext, fileEntryTypesElement, dlFileEntryType);
1559                    }
1560    
1561                    List<Folder> folders = FolderUtil.findByRepositoryId(
1562                            portletDataContext.getScopeGroupId());
1563    
1564                    for (Folder folder : folders) {
1565                            if (!folder.isMountPoint()) {
1566                                    exportFolder(
1567                                            portletDataContext, fileEntryTypesElement, foldersElement,
1568                                            fileEntriesElement, fileShortcutsElement, fileRanksElement,
1569                                            folder, false);
1570                            }
1571                            else {
1572                                    if (portletDataContext.getBooleanParameter(
1573                                                    _NAMESPACE, "repositories")) {
1574    
1575                                            Repository repository = RepositoryUtil.findByPrimaryKey(
1576                                                    folder.getRepositoryId());
1577    
1578                                            exportRepository(
1579                                                    portletDataContext, repositoryElement, repository);
1580                                    }
1581                            }
1582                    }
1583    
1584                    List<FileEntry> fileEntries = FileEntryUtil.findByR_F(
1585                            portletDataContext.getScopeGroupId(),
1586                            DLFolderConstants.DEFAULT_PARENT_FOLDER_ID);
1587    
1588                    for (FileEntry fileEntry : fileEntries) {
1589                            exportFileEntry(
1590                                    portletDataContext, fileEntryTypesElement, foldersElement,
1591                                    fileEntriesElement, fileRanksElement, fileEntry, true);
1592                    }
1593    
1594                    if (portletDataContext.getBooleanParameter(_NAMESPACE, "shortcuts")) {
1595                            List<DLFileShortcut> fileShortcuts = DLFileShortcutUtil.findByG_F(
1596                                    portletDataContext.getScopeGroupId(),
1597                                    DLFolderConstants.DEFAULT_PARENT_FOLDER_ID);
1598    
1599                            for (DLFileShortcut fileShortcut : fileShortcuts) {
1600                                    exportFileShortcut(
1601                                            portletDataContext, fileEntryTypesElement, foldersElement,
1602                                            fileShortcutsElement, fileShortcut);
1603                            }
1604                    }
1605    
1606                    return document.formattedString();
1607            }
1608    
1609            @Override
1610            protected PortletPreferences doImportData(
1611                            PortletDataContext portletDataContext, String portletId,
1612                            PortletPreferences portletPreferences, String data)
1613                    throws Exception {
1614    
1615                    portletDataContext.importPermissions(
1616                            "com.liferay.portlet.documentlibrary",
1617                            portletDataContext.getSourceGroupId(),
1618                            portletDataContext.getScopeGroupId());
1619    
1620                    Document document = SAXReaderUtil.read(data);
1621    
1622                    Element rootElement = document.getRootElement();
1623    
1624                    if (portletDataContext.getBooleanParameter(
1625                                    _NAMESPACE, "repositories")) {
1626    
1627                            Element repositoriesElement = rootElement.element("repositories");
1628    
1629                            if (repositoriesElement != null) {
1630                                    List<Element> repositoryElements = repositoriesElement.elements(
1631                                            "repository");
1632    
1633                                    for (Element repositoryElement : repositoryElements) {
1634                                            importRepository(portletDataContext, repositoryElement);
1635                                    }
1636                            }
1637                    }
1638    
1639                    Element fileEntryTypesElement = rootElement.element("file-entry-types");
1640    
1641                    List<Element> fileEntryTypeElements = fileEntryTypesElement.elements(
1642                            "file-entry-type");
1643    
1644                    for (Element fileEntryTypeElement : fileEntryTypeElements) {
1645                            importFileEntryType(portletDataContext, fileEntryTypeElement);
1646                    }
1647    
1648                    Element foldersElement = rootElement.element("folders");
1649    
1650                    List<Element> folderElements = foldersElement.elements("folder");
1651    
1652                    for (Element folderElement : folderElements) {
1653                            importFolder(portletDataContext, folderElement);
1654                    }
1655    
1656                    Element fileEntriesElement = rootElement.element("file-entries");
1657    
1658                    List<Element> fileEntryElements = fileEntriesElement.elements(
1659                            "file-entry");
1660    
1661                    for (Element fileEntryElement : fileEntryElements) {
1662                            importFileEntry(portletDataContext, fileEntryElement);
1663                    }
1664    
1665                    if (portletDataContext.getBooleanParameter(_NAMESPACE, "shortcuts")) {
1666                            List<Element> fileShortcutElements = rootElement.element(
1667                                    "file-shortcuts").elements("file-shortcut");
1668    
1669                            for (Element fileShortcutElement : fileShortcutElements) {
1670                                    importFileShortcut(portletDataContext, fileShortcutElement);
1671                            }
1672                    }
1673    
1674                    if (portletDataContext.getBooleanParameter(_NAMESPACE, "ranks")) {
1675                            Element fileRanksElement = rootElement.element("file-ranks");
1676    
1677                            List<Element> fileRankElements = fileRanksElement.elements(
1678                                    "file-rank");
1679    
1680                            for (Element fileRankElement : fileRankElements) {
1681                                    importFileRank(portletDataContext, fileRankElement);
1682                            }
1683                    }
1684    
1685                    long rootFolderId = GetterUtil.getLong(
1686                            rootElement.attributeValue("root-folder-id"));
1687    
1688                    if (rootFolderId > 0) {
1689                            Map<Long, Long> folderPKs =
1690                                    (Map<Long, Long>)portletDataContext.getNewPrimaryKeysMap(
1691                                            DLFolder.class);
1692    
1693                            rootFolderId = MapUtil.getLong(
1694                                    folderPKs, rootFolderId, rootFolderId);
1695    
1696                            portletPreferences.setValue(
1697                                    "rootFolderId", String.valueOf(rootFolderId));
1698                    }
1699    
1700                    return portletPreferences;
1701            }
1702    
1703            private static final boolean _ALWAYS_EXPORTABLE = true;
1704    
1705            private static final String _NAMESPACE = "document_library";
1706    
1707            private static Log _log = LogFactoryUtil.getLog(
1708                    DLPortletDataHandlerImpl.class);
1709    
1710            private static PortletDataHandlerBoolean _foldersAndDocuments =
1711                    new PortletDataHandlerBoolean(
1712                            _NAMESPACE, "folders-and-documents", true, true);
1713    
1714            private static PortletDataHandlerControl[] _metadataControls =
1715                    new PortletDataHandlerControl[] {
1716                            new PortletDataHandlerBoolean(_NAMESPACE, "categories"),
1717                            new PortletDataHandlerBoolean(_NAMESPACE, "comments"),
1718                            new PortletDataHandlerBoolean(_NAMESPACE, "ratings"),
1719                            new PortletDataHandlerBoolean(_NAMESPACE, "tags")
1720                    };
1721    
1722            private static PortletDataHandlerBoolean _previewsAndThumbnails =
1723                    new PortletDataHandlerBoolean(_NAMESPACE, "previews-and-thumbnails");
1724    
1725            private static PortletDataHandlerBoolean _ranks =
1726                    new PortletDataHandlerBoolean(_NAMESPACE, "ranks");
1727    
1728            private static PortletDataHandlerBoolean _repositories =
1729                    new PortletDataHandlerBoolean(_NAMESPACE, "repositories", false, false);
1730    
1731            private static PortletDataHandlerBoolean _shortcuts=
1732                    new PortletDataHandlerBoolean(_NAMESPACE, "shortcuts");
1733    
1734    }