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