001    /**
002     * Copyright (c) 2000-2013 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.BaseStagedModelDataHandler;
020    import com.liferay.portal.kernel.lar.ExportImportPathUtil;
021    import com.liferay.portal.kernel.lar.PortletDataContext;
022    import com.liferay.portal.kernel.lar.StagedModelDataHandlerUtil;
023    import com.liferay.portal.kernel.repository.model.Folder;
024    import com.liferay.portal.kernel.util.GetterUtil;
025    import com.liferay.portal.kernel.util.MapUtil;
026    import com.liferay.portal.kernel.util.StringPool;
027    import com.liferay.portal.kernel.util.StringUtil;
028    import com.liferay.portal.kernel.util.Validator;
029    import com.liferay.portal.kernel.xml.Element;
030    import com.liferay.portal.model.Repository;
031    import com.liferay.portal.repository.liferayrepository.LiferayRepository;
032    import com.liferay.portal.repository.liferayrepository.model.LiferayFolder;
033    import com.liferay.portal.service.RepositoryLocalServiceUtil;
034    import com.liferay.portal.service.ServiceContext;
035    import com.liferay.portal.util.PortalUtil;
036    import com.liferay.portlet.documentlibrary.model.DLFileEntryType;
037    import com.liferay.portlet.documentlibrary.model.DLFileEntryTypeConstants;
038    import com.liferay.portlet.documentlibrary.model.DLFolder;
039    import com.liferay.portlet.documentlibrary.model.DLFolderConstants;
040    import com.liferay.portlet.documentlibrary.service.DLAppLocalServiceUtil;
041    import com.liferay.portlet.documentlibrary.service.DLFileEntryTypeLocalServiceUtil;
042    import com.liferay.portlet.documentlibrary.service.DLFolderLocalServiceUtil;
043    
044    import java.util.ArrayList;
045    import java.util.List;
046    import java.util.Map;
047    
048    /**
049     * @author Mate Thurzo
050     */
051    public class FolderStagedModelDataHandler
052            extends BaseStagedModelDataHandler<Folder> {
053    
054            public static final String[] CLASS_NAMES = {
055                    DLFolder.class.getName(), Folder.class.getName(),
056                    LiferayFolder.class.getName()
057            };
058    
059            @Override
060            public void deleteStagedModel(
061                            String uuid, long groupId, String className, String extraData)
062                    throws PortalException, SystemException {
063    
064                    DLFolder dlFolder =
065                            DLFolderLocalServiceUtil.fetchDLFolderByUuidAndGroupId(
066                                    uuid, groupId);
067    
068                    if (dlFolder != null) {
069                            DLFolderLocalServiceUtil.deleteFolder(dlFolder);
070                    }
071            }
072    
073            @Override
074            public String[] getClassNames() {
075                    return CLASS_NAMES;
076            }
077    
078            @Override
079            public String getDisplayName(Folder folder) {
080                    return folder.getName();
081            }
082    
083            @Override
084            protected void doExportStagedModel(
085                            PortletDataContext portletDataContext, Folder folder)
086                    throws Exception {
087    
088                    Element folderElement = portletDataContext.getExportDataElement(
089                            folder, Folder.class);
090    
091                    String folderPath = ExportImportPathUtil.getModelPath(
092                            folder.getGroupId(), Folder.class.getName(), folder.getFolderId());
093    
094                    Repository repository = null;
095    
096                    if (folder.isMountPoint() || !folder.isDefaultRepository()) {
097                            repository = RepositoryLocalServiceUtil.getRepository(
098                                    folder.getRepositoryId());
099    
100                            StagedModelDataHandlerUtil.exportStagedModel(
101                                    portletDataContext, repository);
102    
103                            portletDataContext.addReferenceElement(
104                                    folder, folderElement, repository,
105                                    PortletDataContext.REFERENCE_TYPE_STRONG, false);
106    
107                            portletDataContext.addClassedModel(
108                                    folderElement, folderPath, folder,
109                                    DLPortletDataHandler.NAMESPACE);
110                    }
111    
112                    long liferayRepositoryClassNameId = PortalUtil.getClassNameId(
113                            LiferayRepository.class.getName());
114    
115                    if (((repository != null) &&
116                             (repository.getClassNameId() != liferayRepositoryClassNameId)) ||
117                            folder.isMountPoint()) {
118    
119                            // No need to export non-Liferay repository items since they would
120                            // be exported as part of repository export
121    
122                            return;
123                    }
124    
125                    if (folder.getParentFolderId() !=
126                                    DLFolderConstants.DEFAULT_PARENT_FOLDER_ID) {
127    
128                            StagedModelDataHandlerUtil.exportStagedModel(
129                                    portletDataContext, folder.getParentFolder());
130                    }
131    
132                    exportFolderFileEntryTypes(portletDataContext, folderElement, folder);
133    
134                    portletDataContext.addClassedModel(
135                            folderElement, folderPath, folder, DLFolder.class,
136                            DLPortletDataHandler.NAMESPACE);
137            }
138    
139            @Override
140            protected void doImportStagedModel(
141                            PortletDataContext portletDataContext, Folder folder)
142                    throws Exception {
143    
144                    long userId = portletDataContext.getUserId(folder.getUserUuid());
145    
146                    String path = ExportImportPathUtil.getModelPath(
147                            portletDataContext, Folder.class.getName(), folder.getFolderId());
148    
149                    Element folderElement = portletDataContext.getImportDataElement(
150                            Folder.class.getSimpleName(), "path", path);
151    
152                    Element referenceDataElement =
153                            portletDataContext.getReferenceDataElement(
154                                    folderElement, Repository.class, folder.getRepositoryId());
155    
156                    if (referenceDataElement != null) {
157                            StagedModelDataHandlerUtil.importStagedModel(
158                                    portletDataContext, referenceDataElement);
159    
160                            return;
161                    }
162    
163                    if (folder.getParentFolderId() !=
164                                    DLFolderConstants.DEFAULT_PARENT_FOLDER_ID) {
165    
166                            String parentFolderPath = ExportImportPathUtil.getModelPath(
167                                    portletDataContext, Folder.class.getName(),
168                                    folder.getParentFolderId());
169    
170                            Folder parentFolder =
171                                    (Folder)portletDataContext.getZipEntryAsObject(
172                                            parentFolderPath);
173    
174                            StagedModelDataHandlerUtil.importStagedModel(
175                                    portletDataContext, parentFolder);
176                    }
177    
178                    Map<Long, Long> folderIds =
179                            (Map<Long, Long>)portletDataContext.getNewPrimaryKeysMap(
180                                    Folder.class);
181    
182                    long parentFolderId = MapUtil.getLong(
183                            folderIds, folder.getParentFolderId(), folder.getParentFolderId());
184    
185                    ServiceContext serviceContext = portletDataContext.createServiceContext(
186                            folder, DLFolder.class, DLPortletDataHandler.NAMESPACE);
187    
188                    serviceContext.setUserId(userId);
189    
190                    Folder importedFolder = null;
191    
192                    if (portletDataContext.isDataStrategyMirror()) {
193                            Folder existingFolder = FolderUtil.fetchByUUID_R(
194                                    folder.getUuid(), portletDataContext.getScopeGroupId());
195    
196                            if (existingFolder == null) {
197                                    String name = getFolderName(
198                                            null, portletDataContext.getScopeGroupId(), parentFolderId,
199                                            folder.getName(), 2);
200    
201                                    serviceContext.setUuid(folder.getUuid());
202    
203                                    importedFolder = DLAppLocalServiceUtil.addFolder(
204                                            userId, portletDataContext.getScopeGroupId(),
205                                            parentFolderId, name, folder.getDescription(),
206                                            serviceContext);
207                            }
208                            else {
209                                    String name = getFolderName(
210                                            folder.getUuid(), portletDataContext.getScopeGroupId(),
211                                            parentFolderId, folder.getName(), 2);
212    
213                                    importedFolder = DLAppLocalServiceUtil.updateFolder(
214                                            existingFolder.getFolderId(), parentFolderId, name,
215                                            folder.getDescription(), serviceContext);
216                            }
217                    }
218                    else {
219                            String name = getFolderName(
220                                    null, portletDataContext.getScopeGroupId(), parentFolderId,
221                                    folder.getName(), 2);
222    
223                            importedFolder = DLAppLocalServiceUtil.addFolder(
224                                    userId, portletDataContext.getScopeGroupId(), parentFolderId,
225                                    name, folder.getDescription(), serviceContext);
226                    }
227    
228                    importFolderFileEntryTypes(
229                            portletDataContext, folderElement, folder, serviceContext);
230    
231                    portletDataContext.importClassedModel(
232                            folder, importedFolder, DLFolder.class,
233                            DLPortletDataHandler.NAMESPACE);
234    
235                    folderIds.put(folder.getFolderId(), importedFolder.getFolderId());
236            }
237    
238            protected void exportFolderFileEntryTypes(
239                            PortletDataContext portletDataContext, Element folderElement,
240                            Folder folder)
241                    throws Exception {
242    
243                    List<DLFileEntryType> dlFileEntryTypes =
244                            DLFileEntryTypeLocalServiceUtil.getFolderFileEntryTypes(
245                                    new long[] {
246                                            portletDataContext.getCompanyGroupId(),
247                                            portletDataContext.getScopeGroupId()
248                                    },
249                                    folder.getFolderId(), false);
250    
251                    long defaultFileEntryTypeId =
252                            DLFileEntryTypeLocalServiceUtil.getDefaultFileEntryTypeId(
253                                    folder.getFolderId());
254    
255                    String defaultFileEntryTypeUuid = StringPool.BLANK;
256    
257                    for (DLFileEntryType dlFileEntryType : dlFileEntryTypes) {
258                            if (dlFileEntryType.getFileEntryTypeId() ==
259                                            DLFileEntryTypeConstants.
260                                                    FILE_ENTRY_TYPE_ID_BASIC_DOCUMENT) {
261    
262                                    folderElement.addAttribute("basic-document", "true");
263    
264                                    continue;
265                            }
266    
267                            if (defaultFileEntryTypeId ==
268                                            dlFileEntryType.getFileEntryTypeId()) {
269    
270                                    defaultFileEntryTypeUuid = dlFileEntryType.getUuid();
271                            }
272    
273                            if (dlFileEntryType.isExportable()) {
274                                    StagedModelDataHandlerUtil.exportStagedModel(
275                                            portletDataContext, dlFileEntryType);
276    
277                                    portletDataContext.addReferenceElement(
278                                            folder, folderElement, dlFileEntryType,
279                                            PortletDataContext.REFERENCE_TYPE_STRONG, false);
280                            }
281                    }
282    
283                    folderElement.addAttribute(
284                            "defaultFileEntryTypeUuid", defaultFileEntryTypeUuid);
285            }
286    
287            /**
288             * @see com.liferay.portal.lar.PortletImporter#getAssetCategoryName(String,
289             *      long, long, String, long, int)
290             * @see com.liferay.portal.lar.PortletImporter#getAssetVocabularyName(
291             *      String, long, String, int)
292             */
293            protected String getFolderName(
294                            String uuid, long groupId, long parentFolderId, String name,
295                            int count)
296                    throws Exception {
297    
298                    Folder folder = FolderUtil.fetchByR_P_N(groupId, parentFolderId, name);
299    
300                    if (folder == null) {
301                            return name;
302                    }
303    
304                    if (Validator.isNotNull(uuid) && uuid.equals(folder.getUuid())) {
305                            return name;
306                    }
307    
308                    name = StringUtil.appendParentheticalSuffix(name, count);
309    
310                    return getFolderName(uuid, groupId, parentFolderId, name, ++count);
311            }
312    
313            protected void importFolderFileEntryTypes(
314                            PortletDataContext portletDataContext, Element folderElement,
315                            Folder folder, ServiceContext serviceContext)
316                    throws Exception {
317    
318                    List<Long> currentFolderFileEntryTypeIds = new ArrayList<Long>();
319    
320                    Map<Long, Long> fileEntryTypeIds =
321                            (Map<Long, Long>)portletDataContext.getNewPrimaryKeysMap(
322                                    DLFileEntryType.class);
323    
324                    String defaultFileEntryTypeUuid = GetterUtil.getString(
325                            folderElement.attributeValue("defaultFileEntryTypeUuid"));
326    
327                    long defaultFileEntryTypeId = 0;
328    
329                    List<Element> referenceDataElements =
330                            portletDataContext.getReferenceDataElements(
331                                    folderElement, DLFileEntryType.class);
332    
333                    for (Element referenceDataElement : referenceDataElements) {
334                            String referencePath = referenceDataElement.attributeValue("path");
335    
336                            DLFileEntryType referenceDLFileEntryType =
337                                    (DLFileEntryType)portletDataContext.getZipEntryAsObject(
338                                            referencePath);
339    
340                            String fileEntryTypeUuid = referenceDLFileEntryType.getUuid();
341    
342                            DLFileEntryType existingDLFileEntryType =
343                                    DLFileEntryTypeLocalServiceUtil.
344                                            fetchDLFileEntryTypeByUuidAndGroupId(
345                                                    fileEntryTypeUuid,
346                                                    portletDataContext.getScopeGroupId());
347    
348                            if (existingDLFileEntryType == null) {
349                                    existingDLFileEntryType =
350                                            DLFileEntryTypeLocalServiceUtil.
351                                                    fetchDLFileEntryTypeByUuidAndGroupId(
352                                                            fileEntryTypeUuid,
353                                                            portletDataContext.getCompanyGroupId());
354                            }
355    
356                            if (existingDLFileEntryType == null) {
357                                    StagedModelDataHandlerUtil.importStagedModel(
358                                            portletDataContext, referenceDLFileEntryType);
359    
360                                    long dlFileEntryTypeId = MapUtil.getLong(
361                                            fileEntryTypeIds,
362                                            referenceDLFileEntryType.getFileEntryTypeId(),
363                                            referenceDLFileEntryType.getFileEntryTypeId());
364    
365                                    existingDLFileEntryType =
366                                            DLFileEntryTypeLocalServiceUtil.fetchDLFileEntryType(
367                                                    dlFileEntryTypeId);
368                            }
369    
370                            if (existingDLFileEntryType == null) {
371                                    continue;
372                            }
373    
374                            currentFolderFileEntryTypeIds.add(
375                                    existingDLFileEntryType.getFileEntryTypeId());
376    
377                            if (defaultFileEntryTypeUuid.equals(fileEntryTypeUuid)) {
378                                    defaultFileEntryTypeId =
379                                            existingDLFileEntryType.getFileEntryTypeId();
380                            }
381                    }
382    
383                    if (GetterUtil.getBoolean(
384                                    folderElement.attributeValue("basic-document"))) {
385    
386                            currentFolderFileEntryTypeIds.add(
387                                    DLFileEntryTypeConstants.FILE_ENTRY_TYPE_ID_BASIC_DOCUMENT);
388                    }
389    
390                    if (!currentFolderFileEntryTypeIds.isEmpty()) {
391                            DLFolder dlFolder = (DLFolder)folder.getModel();
392    
393                            dlFolder.setDefaultFileEntryTypeId(defaultFileEntryTypeId);
394                            dlFolder.setOverrideFileEntryTypes(true);
395    
396                            DLFolderLocalServiceUtil.updateDLFolder(dlFolder);
397    
398                            DLFileEntryTypeLocalServiceUtil.updateFolderFileEntryTypes(
399                                    dlFolder, currentFolderFileEntryTypeIds, defaultFileEntryTypeId,
400                                    serviceContext);
401                    }
402            }
403    
404            @Override
405            protected boolean validateMissingReference(
406                            String uuid, long companyId, long groupId)
407                    throws Exception {
408    
409                    DLFolder dlFolder =
410                            DLFolderLocalServiceUtil.fetchDLFolderByUuidAndGroupId(
411                                    uuid, groupId);
412    
413                    if (dlFolder == null) {
414                            return false;
415                    }
416    
417                    return true;
418            }
419    
420    }