001    /**
002     * Copyright (c) 2000-present 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.dao.orm.QueryUtil;
018    import com.liferay.portal.kernel.exception.PortalException;
019    import com.liferay.portal.kernel.repository.model.Folder;
020    import com.liferay.portal.kernel.trash.TrashHandler;
021    import com.liferay.portal.kernel.trash.TrashHandlerRegistryUtil;
022    import com.liferay.portal.kernel.util.GetterUtil;
023    import com.liferay.portal.kernel.util.MapUtil;
024    import com.liferay.portal.kernel.util.StringPool;
025    import com.liferay.portal.kernel.util.StringUtil;
026    import com.liferay.portal.kernel.util.Validator;
027    import com.liferay.portal.kernel.xml.Element;
028    import com.liferay.portal.model.Repository;
029    import com.liferay.portal.model.RepositoryEntry;
030    import com.liferay.portal.repository.liferayrepository.model.LiferayFolder;
031    import com.liferay.portal.repository.portletrepository.PortletRepository;
032    import com.liferay.portal.service.RepositoryLocalServiceUtil;
033    import com.liferay.portal.service.ServiceContext;
034    import com.liferay.portal.util.PortalUtil;
035    import com.liferay.portlet.documentlibrary.model.DLFileEntryType;
036    import com.liferay.portlet.documentlibrary.model.DLFileEntryTypeConstants;
037    import com.liferay.portlet.documentlibrary.model.DLFolder;
038    import com.liferay.portlet.documentlibrary.model.DLFolderConstants;
039    import com.liferay.portlet.documentlibrary.service.DLAppLocalServiceUtil;
040    import com.liferay.portlet.documentlibrary.service.DLFileEntryTypeLocalServiceUtil;
041    import com.liferay.portlet.documentlibrary.service.DLFolderLocalServiceUtil;
042    import com.liferay.portlet.exportimport.lar.BaseStagedModelDataHandler;
043    import com.liferay.portlet.exportimport.lar.ExportImportPathUtil;
044    import com.liferay.portlet.exportimport.lar.PortletDataContext;
045    import com.liferay.portlet.exportimport.lar.PortletDataException;
046    import com.liferay.portlet.exportimport.lar.StagedModelDataHandlerUtil;
047    import com.liferay.portlet.exportimport.lar.StagedModelModifiedDateComparator;
048    
049    import java.util.ArrayList;
050    import java.util.List;
051    import java.util.Map;
052    
053    /**
054     * @author Mate Thurzo
055     */
056    public class FolderStagedModelDataHandler
057            extends BaseStagedModelDataHandler<Folder> {
058    
059            public static final String[] CLASS_NAMES = {
060                    DLFolder.class.getName(), Folder.class.getName(),
061                    LiferayFolder.class.getName()
062            };
063    
064            @Override
065            public void deleteStagedModel(Folder folder) throws PortalException {
066                    DLAppLocalServiceUtil.deleteFolder(folder.getFolderId());
067            }
068    
069            @Override
070            public void deleteStagedModel(
071                            String uuid, long groupId, String className, String extraData)
072                    throws PortalException {
073    
074                    Folder folder = fetchStagedModelByUuidAndGroupId(uuid, groupId);
075    
076                    if (folder != null) {
077                            deleteStagedModel(folder);
078                    }
079            }
080    
081            @Override
082            public Folder fetchStagedModelByUuidAndGroupId(String uuid, long groupId) {
083                    return FolderUtil.fetchByUUID_R(uuid, groupId);
084            }
085    
086            @Override
087            public List<Folder> fetchStagedModelsByUuidAndCompanyId(
088                    String uuid, long companyId) {
089    
090                    List<DLFolder> dlFolders =
091                            DLFolderLocalServiceUtil.getDLFoldersByUuidAndCompanyId(
092                                    uuid, companyId, QueryUtil.ALL_POS, QueryUtil.ALL_POS,
093                                    new StagedModelModifiedDateComparator<DLFolder>());
094    
095                    List<Folder> folders = new ArrayList<>();
096    
097                    for (DLFolder dlFolder : dlFolders) {
098                            folders.add(new LiferayFolder(dlFolder));
099                    }
100    
101                    return folders;
102            }
103    
104            @Override
105            public String[] getClassNames() {
106                    return CLASS_NAMES;
107            }
108    
109            @Override
110            public String getDisplayName(Folder folder) {
111                    return folder.getName();
112            }
113    
114            @Override
115            public void restoreStagedModel(
116                            PortletDataContext portletDataContext, Folder stagedModel)
117                    throws PortletDataException {
118    
119                    try {
120                            doRestoreStagedModel(portletDataContext, stagedModel);
121                    }
122                    catch (PortletDataException pde) {
123                            throw pde;
124                    }
125                    catch (Exception e) {
126                            throw new PortletDataException(e);
127                    }
128            }
129    
130            @Override
131            protected void doExportStagedModel(
132                            PortletDataContext portletDataContext, Folder folder)
133                    throws Exception {
134    
135                    Element folderElement = portletDataContext.getExportDataElement(folder);
136    
137                    String folderPath = ExportImportPathUtil.getModelPath(folder);
138    
139                    if (!folder.isDefaultRepository()) {
140                            Repository repository = RepositoryLocalServiceUtil.getRepository(
141                                    folder.getRepositoryId());
142    
143                            StagedModelDataHandlerUtil.exportReferenceStagedModel(
144                                    portletDataContext, folder, repository,
145                                    PortletDataContext.REFERENCE_TYPE_STRONG);
146    
147                            portletDataContext.addClassedModel(
148                                    folderElement, folderPath, folder);
149    
150                            long portletRepositoryClassNameId = PortalUtil.getClassNameId(
151                                    PortletRepository.class.getName());
152    
153                            if (repository.getClassNameId() != portletRepositoryClassNameId) {
154                                    return;
155                            }
156                    }
157    
158                    if (folder.getParentFolderId() !=
159                                    DLFolderConstants.DEFAULT_PARENT_FOLDER_ID) {
160    
161                            StagedModelDataHandlerUtil.exportReferenceStagedModel(
162                                    portletDataContext, folder, folder.getParentFolder(),
163                                    PortletDataContext.REFERENCE_TYPE_PARENT);
164                    }
165    
166                    exportFolderFileEntryTypes(portletDataContext, folderElement, folder);
167    
168                    portletDataContext.addClassedModel(
169                            folderElement, folderPath, folder, DLFolder.class);
170            }
171    
172            @Override
173            protected void doImportMissingReference(
174                            PortletDataContext portletDataContext, String uuid, long groupId,
175                            long folderId)
176                    throws Exception {
177    
178                    Folder existingFolder = fetchMissingReference(uuid, groupId);
179    
180                    Map<Long, Long> folderIds =
181                            (Map<Long, Long>)portletDataContext.getNewPrimaryKeysMap(
182                                    Folder.class);
183    
184                    folderIds.put(folderId, existingFolder.getFolderId());
185            }
186    
187            @Override
188            protected void doImportStagedModel(
189                            PortletDataContext portletDataContext, Folder folder)
190                    throws Exception {
191    
192                    Map<Long, Long> folderIdsAndRepositoryEntryIds =
193                            (Map<Long, Long>)portletDataContext.getNewPrimaryKeysMap(
194                                    Folder.class + ".folderIdsAndRepositoryEntryIds");
195    
196                    if (!folder.isDefaultRepository()) {
197                            Map<Long, Long> repositoryEntryIds =
198                                    (Map<Long, Long>)portletDataContext.getNewPrimaryKeysMap(
199                                            RepositoryEntry.class);
200    
201                            folderIdsAndRepositoryEntryIds.put(
202                                    folder.getFolderId(),
203                                    repositoryEntryIds.get(folder.getFolderId()));
204    
205                            return;
206                    }
207    
208                    long userId = portletDataContext.getUserId(folder.getUserUuid());
209    
210                    Map<Long, Long> folderIds =
211                            (Map<Long, Long>)portletDataContext.getNewPrimaryKeysMap(
212                                    Folder.class);
213    
214                    long parentFolderId = MapUtil.getLong(
215                            folderIds, folder.getParentFolderId(), folder.getParentFolderId());
216    
217                    ServiceContext serviceContext = portletDataContext.createServiceContext(
218                            folder, DLFolder.class);
219    
220                    serviceContext.setUserId(userId);
221    
222                    Folder importedFolder = null;
223    
224                    if (portletDataContext.isDataStrategyMirror()) {
225                            Folder existingFolder = fetchStagedModelByUuidAndGroupId(
226                                    folder.getUuid(), portletDataContext.getScopeGroupId());
227    
228                            if (existingFolder == null) {
229                                    String name = getFolderName(
230                                            null, portletDataContext.getScopeGroupId(), parentFolderId,
231                                            folder.getName(), 2);
232    
233                                    serviceContext.setUuid(folder.getUuid());
234    
235                                    importedFolder = DLAppLocalServiceUtil.addFolder(
236                                            userId, portletDataContext.getScopeGroupId(),
237                                            parentFolderId, name, folder.getDescription(),
238                                            serviceContext);
239                            }
240                            else {
241                                    String name = getFolderName(
242                                            folder.getUuid(), portletDataContext.getScopeGroupId(),
243                                            parentFolderId, folder.getName(), 2);
244    
245                                    importedFolder = DLAppLocalServiceUtil.updateFolder(
246                                            existingFolder.getFolderId(), parentFolderId, name,
247                                            folder.getDescription(), serviceContext);
248                            }
249                    }
250                    else {
251                            String name = getFolderName(
252                                    null, portletDataContext.getScopeGroupId(), parentFolderId,
253                                    folder.getName(), 2);
254    
255                            importedFolder = DLAppLocalServiceUtil.addFolder(
256                                    userId, portletDataContext.getScopeGroupId(), parentFolderId,
257                                    name, folder.getDescription(), serviceContext);
258                    }
259    
260                    Element folderElement = portletDataContext.getImportDataElement(folder);
261    
262                    importFolderFileEntryTypes(
263                            portletDataContext, folderElement, folder, importedFolder,
264                            serviceContext);
265    
266                    portletDataContext.importClassedModel(
267                            folder, importedFolder, DLFolder.class);
268    
269                    folderIds.put(folder.getFolderId(), importedFolder.getFolderId());
270                    folderIdsAndRepositoryEntryIds.put(
271                            folder.getFolderId(), importedFolder.getFolderId());
272            }
273    
274            @Override
275            protected void doRestoreStagedModel(
276                            PortletDataContext portletDataContext, Folder folder)
277                    throws Exception {
278    
279                    long userId = portletDataContext.getUserId(folder.getUserUuid());
280    
281                    Folder existingFolder = fetchStagedModelByUuidAndGroupId(
282                            folder.getUuid(), portletDataContext.getScopeGroupId());
283    
284                    if ((existingFolder == null) ||
285                            !(existingFolder.getModel() instanceof DLFolder)) {
286    
287                            return;
288                    }
289    
290                    DLFolder dlFolder = (DLFolder)existingFolder.getModel();
291    
292                    if (!dlFolder.isInTrash()) {
293                            return;
294                    }
295    
296                    TrashHandler trashHandler = TrashHandlerRegistryUtil.getTrashHandler(
297                            DLFolder.class.getName());
298    
299                    if (trashHandler.isRestorable(existingFolder.getFolderId())) {
300                            trashHandler.restoreTrashEntry(
301                                    userId, existingFolder.getFolderId());
302                    }
303            }
304    
305            protected void exportFolderFileEntryTypes(
306                            PortletDataContext portletDataContext, Element folderElement,
307                            Folder folder)
308                    throws Exception {
309    
310                    if (!folder.isDefaultRepository()) {
311                            return;
312                    }
313    
314                    List<DLFileEntryType> dlFileEntryTypes =
315                            DLFileEntryTypeLocalServiceUtil.getFolderFileEntryTypes(
316                                    new long[] {
317                                            portletDataContext.getCompanyGroupId(),
318                                            portletDataContext.getScopeGroupId()
319                                    },
320                                    folder.getFolderId(), false);
321    
322                    long defaultFileEntryTypeId =
323                            DLFileEntryTypeLocalServiceUtil.getDefaultFileEntryTypeId(
324                                    folder.getFolderId());
325    
326                    String defaultFileEntryTypeUuid = StringPool.BLANK;
327    
328                    for (DLFileEntryType dlFileEntryType : dlFileEntryTypes) {
329                            if (dlFileEntryType.getFileEntryTypeId() ==
330                                            DLFileEntryTypeConstants.
331                                                    FILE_ENTRY_TYPE_ID_BASIC_DOCUMENT) {
332    
333                                    folderElement.addAttribute("basic-document", "true");
334    
335                                    continue;
336                            }
337    
338                            if (defaultFileEntryTypeId ==
339                                            dlFileEntryType.getFileEntryTypeId()) {
340    
341                                    defaultFileEntryTypeUuid = dlFileEntryType.getUuid();
342                            }
343    
344                            if (dlFileEntryType.isExportable()) {
345                                    StagedModelDataHandlerUtil.exportReferenceStagedModel(
346                                            portletDataContext, folder, dlFileEntryType,
347                                            PortletDataContext.REFERENCE_TYPE_STRONG);
348                            }
349                    }
350    
351                    folderElement.addAttribute(
352                            "defaultFileEntryTypeUuid", defaultFileEntryTypeUuid);
353            }
354    
355            protected String getFolderName(
356                            String uuid, long groupId, long parentFolderId, String name,
357                            int count)
358                    throws Exception {
359    
360                    Folder folder = FolderUtil.fetchByR_P_N(groupId, parentFolderId, name);
361    
362                    if (folder == null) {
363                            return name;
364                    }
365    
366                    if (Validator.isNotNull(uuid) && uuid.equals(folder.getUuid())) {
367                            return name;
368                    }
369    
370                    name = StringUtil.appendParentheticalSuffix(name, count);
371    
372                    return getFolderName(uuid, groupId, parentFolderId, name, ++count);
373            }
374    
375            protected void importFolderFileEntryTypes(
376                            PortletDataContext portletDataContext, Element folderElement,
377                            Folder folder, Folder importedFolder, ServiceContext serviceContext)
378                    throws Exception {
379    
380                    if (!folder.isDefaultRepository()) {
381                            return;
382                    }
383    
384                    List<Long> currentFolderFileEntryTypeIds = new ArrayList<>();
385    
386                    String defaultFileEntryTypeUuid = GetterUtil.getString(
387                            folderElement.attributeValue("defaultFileEntryTypeUuid"));
388    
389                    long defaultFileEntryTypeId = 0;
390    
391                    List<Element> referenceElements =
392                            portletDataContext.getReferenceElements(
393                                    folder, DLFileEntryType.class);
394    
395                    for (Element referenceElement : referenceElements) {
396                            long referenceDlFileEntryTypeId = GetterUtil.getLong(
397                                    referenceElement.attributeValue("class-pk"));
398                            String referenceDlFileEntryTypeUuid =
399                                    referenceElement.attributeValue("uuid");
400    
401                            Map<Long, Long> dlFileEntryTypeIds =
402                                    (Map<Long, Long>)portletDataContext.getNewPrimaryKeysMap(
403                                            DLFileEntryType.class);
404    
405                            long dlFileEntryTypeId = MapUtil.getLong(
406                                    dlFileEntryTypeIds, referenceDlFileEntryTypeId,
407                                    referenceDlFileEntryTypeId);
408    
409                            DLFileEntryType existingDLFileEntryType =
410                                    DLFileEntryTypeLocalServiceUtil.fetchDLFileEntryType(
411                                            dlFileEntryTypeId);
412    
413                            if (existingDLFileEntryType == null) {
414                                    continue;
415                            }
416    
417                            currentFolderFileEntryTypeIds.add(
418                                    existingDLFileEntryType.getFileEntryTypeId());
419    
420                            if (defaultFileEntryTypeUuid.equals(referenceDlFileEntryTypeUuid)) {
421                                    defaultFileEntryTypeId =
422                                            existingDLFileEntryType.getFileEntryTypeId();
423                            }
424                    }
425    
426                    if (GetterUtil.getBoolean(
427                                    folderElement.attributeValue("basic-document"))) {
428    
429                            currentFolderFileEntryTypeIds.add(
430                                    DLFileEntryTypeConstants.FILE_ENTRY_TYPE_ID_BASIC_DOCUMENT);
431                    }
432    
433                    if (!currentFolderFileEntryTypeIds.isEmpty()) {
434                            DLFolder dlFolder = (DLFolder)importedFolder.getModel();
435    
436                            dlFolder.setDefaultFileEntryTypeId(defaultFileEntryTypeId);
437                            dlFolder.setRestrictionType(
438                                    DLFolderConstants.
439                                            RESTRICTION_TYPE_FILE_ENTRY_TYPES_AND_WORKFLOW);
440    
441                            DLFolderLocalServiceUtil.updateDLFolder(dlFolder);
442    
443                            DLFileEntryTypeLocalServiceUtil.updateFolderFileEntryTypes(
444                                    dlFolder, currentFolderFileEntryTypeIds, defaultFileEntryTypeId,
445                                    serviceContext);
446                    }
447            }
448    
449            @Override
450            protected void validateExport(
451                            PortletDataContext portletDataContext, Folder folder)
452                    throws PortletDataException {
453    
454                    if ((folder.getGroupId() != portletDataContext.getGroupId()) &&
455                            (folder.getGroupId() != portletDataContext.getScopeGroupId())) {
456    
457                            PortletDataException pde = new PortletDataException(
458                                    PortletDataException.INVALID_GROUP);
459    
460                            pde.setStagedModel(folder);
461    
462                            throw pde;
463                    }
464    
465                    if (folder instanceof LiferayFolder) {
466                            LiferayFolder liferayFolder = (LiferayFolder)folder;
467    
468                            DLFolder dlFolder = (DLFolder)liferayFolder.getModel();
469    
470                            if (dlFolder.isInTrash() || dlFolder.isInTrashContainer()) {
471                                    PortletDataException pde = new PortletDataException(
472                                            PortletDataException.STATUS_IN_TRASH);
473    
474                                    pde.setStagedModel(folder);
475    
476                                    throw pde;
477                            }
478                    }
479            }
480    
481    }