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.exportReferenceStagedModel(
101                                    portletDataContext, folder, Folder.class, repository,
102                                    Repository.class, PortletDataContext.REFERENCE_TYPE_STRONG);
103    
104                            portletDataContext.addClassedModel(
105                                    folderElement, folderPath, folder,
106                                    DLPortletDataHandler.NAMESPACE);
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                            DLPortletDataHandler.NAMESPACE);
136            }
137    
138            @Override
139            protected void doImportStagedModel(
140                            PortletDataContext portletDataContext, Folder folder)
141                    throws Exception {
142    
143                    long userId = portletDataContext.getUserId(folder.getUserUuid());
144    
145                    String path = ExportImportPathUtil.getModelPath(
146                            portletDataContext, Folder.class.getName(), folder.getFolderId());
147    
148                    Element folderElement = portletDataContext.getImportDataElement(
149                            Folder.class.getSimpleName(), "path", path);
150    
151                    Element referenceDataElement =
152                            portletDataContext.getReferenceDataElement(
153                                    folderElement, Repository.class, folder.getRepositoryId());
154    
155                    if (referenceDataElement != null) {
156                            StagedModelDataHandlerUtil.importReferenceStagedModel(
157                                    portletDataContext, referenceDataElement);
158    
159                            return;
160                    }
161    
162                    if (folder.getParentFolderId() !=
163                                    DLFolderConstants.DEFAULT_PARENT_FOLDER_ID) {
164    
165                            String parentFolderPath = ExportImportPathUtil.getModelPath(
166                                    portletDataContext, Folder.class.getName(),
167                                    folder.getParentFolderId());
168    
169                            Folder parentFolder =
170                                    (Folder)portletDataContext.getZipEntryAsObject(
171                                            parentFolderPath);
172    
173                            StagedModelDataHandlerUtil.importReferenceStagedModel(
174                                    portletDataContext, parentFolder);
175                    }
176    
177                    Map<Long, Long> folderIds =
178                            (Map<Long, Long>)portletDataContext.getNewPrimaryKeysMap(
179                                    Folder.class);
180    
181                    long parentFolderId = MapUtil.getLong(
182                            folderIds, folder.getParentFolderId(), folder.getParentFolderId());
183    
184                    ServiceContext serviceContext = portletDataContext.createServiceContext(
185                            folder, DLFolder.class, DLPortletDataHandler.NAMESPACE);
186    
187                    serviceContext.setUserId(userId);
188    
189                    Folder importedFolder = null;
190    
191                    if (portletDataContext.isDataStrategyMirror()) {
192                            Folder existingFolder = FolderUtil.fetchByUUID_R(
193                                    folder.getUuid(), portletDataContext.getScopeGroupId());
194    
195                            if (existingFolder == null) {
196                                    String name = getFolderName(
197                                            null, portletDataContext.getScopeGroupId(), parentFolderId,
198                                            folder.getName(), 2);
199    
200                                    serviceContext.setUuid(folder.getUuid());
201    
202                                    importedFolder = DLAppLocalServiceUtil.addFolder(
203                                            userId, portletDataContext.getScopeGroupId(),
204                                            parentFolderId, name, folder.getDescription(),
205                                            serviceContext);
206                            }
207                            else {
208                                    String name = getFolderName(
209                                            folder.getUuid(), portletDataContext.getScopeGroupId(),
210                                            parentFolderId, folder.getName(), 2);
211    
212                                    importedFolder = DLAppLocalServiceUtil.updateFolder(
213                                            existingFolder.getFolderId(), parentFolderId, name,
214                                            folder.getDescription(), serviceContext);
215                            }
216                    }
217                    else {
218                            String name = getFolderName(
219                                    null, portletDataContext.getScopeGroupId(), parentFolderId,
220                                    folder.getName(), 2);
221    
222                            importedFolder = DLAppLocalServiceUtil.addFolder(
223                                    userId, portletDataContext.getScopeGroupId(), parentFolderId,
224                                    name, folder.getDescription(), serviceContext);
225                    }
226    
227                    importFolderFileEntryTypes(
228                            portletDataContext, folderElement, folder, serviceContext);
229    
230                    portletDataContext.importClassedModel(
231                            folder, importedFolder, DLFolder.class,
232                            DLPortletDataHandler.NAMESPACE);
233    
234                    folderIds.put(folder.getFolderId(), importedFolder.getFolderId());
235            }
236    
237            protected void exportFolderFileEntryTypes(
238                            PortletDataContext portletDataContext, Element folderElement,
239                            Folder folder)
240                    throws Exception {
241    
242                    List<DLFileEntryType> dlFileEntryTypes =
243                            DLFileEntryTypeLocalServiceUtil.getFolderFileEntryTypes(
244                                    new long[] {
245                                            portletDataContext.getCompanyGroupId(),
246                                            portletDataContext.getScopeGroupId()
247                                    },
248                                    folder.getFolderId(), false);
249    
250                    long defaultFileEntryTypeId =
251                            DLFileEntryTypeLocalServiceUtil.getDefaultFileEntryTypeId(
252                                    folder.getFolderId());
253    
254                    String defaultFileEntryTypeUuid = StringPool.BLANK;
255    
256                    for (DLFileEntryType dlFileEntryType : dlFileEntryTypes) {
257                            if (dlFileEntryType.getFileEntryTypeId() ==
258                                            DLFileEntryTypeConstants.
259                                                    FILE_ENTRY_TYPE_ID_BASIC_DOCUMENT) {
260    
261                                    folderElement.addAttribute("basic-document", "true");
262    
263                                    continue;
264                            }
265    
266                            if (defaultFileEntryTypeId ==
267                                            dlFileEntryType.getFileEntryTypeId()) {
268    
269                                    defaultFileEntryTypeUuid = dlFileEntryType.getUuid();
270                            }
271    
272                            if (dlFileEntryType.isExportable()) {
273                                    StagedModelDataHandlerUtil.exportReferenceStagedModel(
274                                            portletDataContext, folder, Folder.class, dlFileEntryType,
275                                            DLFileEntryType.class,
276                                            PortletDataContext.REFERENCE_TYPE_STRONG);
277                            }
278                    }
279    
280                    folderElement.addAttribute(
281                            "defaultFileEntryTypeUuid", defaultFileEntryTypeUuid);
282            }
283    
284            /**
285             * @see com.liferay.portal.lar.PortletImporter#getAssetCategoryName(String,
286             *      long, long, String, long, int)
287             * @see com.liferay.portal.lar.PortletImporter#getAssetVocabularyName(
288             *      String, long, String, int)
289             */
290            protected String getFolderName(
291                            String uuid, long groupId, long parentFolderId, String name,
292                            int count)
293                    throws Exception {
294    
295                    Folder folder = FolderUtil.fetchByR_P_N(groupId, parentFolderId, name);
296    
297                    if (folder == null) {
298                            return name;
299                    }
300    
301                    if (Validator.isNotNull(uuid) && uuid.equals(folder.getUuid())) {
302                            return name;
303                    }
304    
305                    name = StringUtil.appendParentheticalSuffix(name, count);
306    
307                    return getFolderName(uuid, groupId, parentFolderId, name, ++count);
308            }
309    
310            protected void importFolderFileEntryTypes(
311                            PortletDataContext portletDataContext, Element folderElement,
312                            Folder folder, ServiceContext serviceContext)
313                    throws Exception {
314    
315                    List<Long> currentFolderFileEntryTypeIds = new ArrayList<Long>();
316    
317                    String defaultFileEntryTypeUuid = GetterUtil.getString(
318                            folderElement.attributeValue("defaultFileEntryTypeUuid"));
319    
320                    long defaultFileEntryTypeId = 0;
321    
322                    List<Element> referenceDataElements =
323                            portletDataContext.getReferenceDataElements(
324                                    folderElement, DLFileEntryType.class);
325    
326                    for (Element referenceDataElement : referenceDataElements) {
327                            String referencePath = referenceDataElement.attributeValue("path");
328    
329                            DLFileEntryType referenceDLFileEntryType =
330                                    (DLFileEntryType)portletDataContext.getZipEntryAsObject(
331                                            referencePath);
332    
333                            StagedModelDataHandlerUtil.importReferenceStagedModel(
334                                    portletDataContext, referenceDLFileEntryType);
335    
336                            Map<Long, Long> fileEntryTypeIds =
337                                    (Map<Long, Long>)portletDataContext.getNewPrimaryKeysMap(
338                                            DLFileEntryType.class);
339    
340                            long dlFileEntryTypeId = MapUtil.getLong(
341                                    fileEntryTypeIds, referenceDLFileEntryType.getFileEntryTypeId(),
342                                    referenceDLFileEntryType.getFileEntryTypeId());
343    
344                            DLFileEntryType existingDLFileEntryType =
345                                    DLFileEntryTypeLocalServiceUtil.fetchDLFileEntryType(
346                                            dlFileEntryTypeId);
347    
348                            if (existingDLFileEntryType == null) {
349                                    continue;
350                            }
351    
352                            currentFolderFileEntryTypeIds.add(
353                                    existingDLFileEntryType.getFileEntryTypeId());
354    
355                            if (defaultFileEntryTypeUuid.equals(
356                                            referenceDLFileEntryType.getUuid())) {
357    
358                                    defaultFileEntryTypeId =
359                                            existingDLFileEntryType.getFileEntryTypeId();
360                            }
361                    }
362    
363                    if (GetterUtil.getBoolean(
364                                    folderElement.attributeValue("basic-document"))) {
365    
366                            currentFolderFileEntryTypeIds.add(
367                                    DLFileEntryTypeConstants.FILE_ENTRY_TYPE_ID_BASIC_DOCUMENT);
368                    }
369    
370                    if (!currentFolderFileEntryTypeIds.isEmpty()) {
371                            DLFolder dlFolder = (DLFolder)folder.getModel();
372    
373                            dlFolder.setDefaultFileEntryTypeId(defaultFileEntryTypeId);
374                            dlFolder.setOverrideFileEntryTypes(true);
375    
376                            DLFolderLocalServiceUtil.updateDLFolder(dlFolder);
377    
378                            DLFileEntryTypeLocalServiceUtil.updateFolderFileEntryTypes(
379                                    dlFolder, currentFolderFileEntryTypeIds, defaultFileEntryTypeId,
380                                    serviceContext);
381                    }
382            }
383    
384            @Override
385            protected boolean validateMissingReference(
386                            String uuid, long companyId, long groupId)
387                    throws Exception {
388    
389                    DLFolder dlFolder =
390                            DLFolderLocalServiceUtil.fetchDLFolderByUuidAndGroupId(
391                                    uuid, groupId);
392    
393                    if (dlFolder == null) {
394                            return false;
395                    }
396    
397                    return true;
398            }
399    
400    }