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