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