001    /**
002     * Copyright (c) 2000-2013 Liferay, Inc. All rights reserved.
003     *
004     * The contents of this file are subject to the terms of the Liferay Enterprise
005     * Subscription License ("License"). You may not use this file except in
006     * compliance with the License. You can obtain a copy of the License by
007     * contacting Liferay, Inc. See the License for the specific language governing
008     * permissions and limitations under the License, including but not limited to
009     * distribution rights of the Software.
010     *
011     *
012     *
013     */
014    
015    package com.liferay.portal.lar;
016    
017    import com.liferay.portal.LayoutImportException;
018    import com.liferay.portal.NoSuchPortletPreferencesException;
019    import com.liferay.portal.kernel.backgroundtask.BackgroundTaskThreadLocal;
020    import com.liferay.portal.kernel.exception.PortalException;
021    import com.liferay.portal.kernel.exception.SystemException;
022    import com.liferay.portal.kernel.language.LanguageUtil;
023    import com.liferay.portal.kernel.lar.ExportImportHelperUtil;
024    import com.liferay.portal.kernel.lar.ExportImportPathUtil;
025    import com.liferay.portal.kernel.lar.ExportImportThreadLocal;
026    import com.liferay.portal.kernel.lar.ManifestSummary;
027    import com.liferay.portal.kernel.lar.PortletDataContext;
028    import com.liferay.portal.kernel.lar.PortletDataContextFactoryUtil;
029    import com.liferay.portal.kernel.lar.PortletDataException;
030    import com.liferay.portal.kernel.lar.PortletDataHandler;
031    import com.liferay.portal.kernel.lar.PortletDataHandlerKeys;
032    import com.liferay.portal.kernel.lar.PortletDataHandlerStatusMessageSenderUtil;
033    import com.liferay.portal.kernel.log.Log;
034    import com.liferay.portal.kernel.log.LogFactoryUtil;
035    import com.liferay.portal.kernel.staging.StagingUtil;
036    import com.liferay.portal.kernel.transaction.TransactionCommitCallbackRegistryUtil;
037    import com.liferay.portal.kernel.util.CharPool;
038    import com.liferay.portal.kernel.util.DateRange;
039    import com.liferay.portal.kernel.util.FileUtil;
040    import com.liferay.portal.kernel.util.GetterUtil;
041    import com.liferay.portal.kernel.util.MapUtil;
042    import com.liferay.portal.kernel.util.ReleaseInfo;
043    import com.liferay.portal.kernel.util.StringBundler;
044    import com.liferay.portal.kernel.util.StringPool;
045    import com.liferay.portal.kernel.util.StringUtil;
046    import com.liferay.portal.kernel.util.Time;
047    import com.liferay.portal.kernel.util.UnicodeProperties;
048    import com.liferay.portal.kernel.util.Validator;
049    import com.liferay.portal.kernel.xml.Document;
050    import com.liferay.portal.kernel.xml.Element;
051    import com.liferay.portal.kernel.xml.Node;
052    import com.liferay.portal.kernel.xml.SAXReaderUtil;
053    import com.liferay.portal.kernel.zip.ZipWriter;
054    import com.liferay.portal.model.Group;
055    import com.liferay.portal.model.Layout;
056    import com.liferay.portal.model.LayoutConstants;
057    import com.liferay.portal.model.LayoutTypePortlet;
058    import com.liferay.portal.model.Lock;
059    import com.liferay.portal.model.PersistedModel;
060    import com.liferay.portal.model.Portlet;
061    import com.liferay.portal.model.PortletConstants;
062    import com.liferay.portal.model.PortletItem;
063    import com.liferay.portal.model.PortletPreferences;
064    import com.liferay.portal.model.StagedModel;
065    import com.liferay.portal.model.User;
066    import com.liferay.portal.model.impl.LayoutImpl;
067    import com.liferay.portal.service.GroupLocalServiceUtil;
068    import com.liferay.portal.service.LayoutLocalServiceUtil;
069    import com.liferay.portal.service.PersistedModelLocalService;
070    import com.liferay.portal.service.PersistedModelLocalServiceRegistryUtil;
071    import com.liferay.portal.service.PortletItemLocalServiceUtil;
072    import com.liferay.portal.service.PortletLocalServiceUtil;
073    import com.liferay.portal.service.PortletPreferencesLocalServiceUtil;
074    import com.liferay.portal.service.ServiceContext;
075    import com.liferay.portal.service.ServiceContextThreadLocal;
076    import com.liferay.portal.service.UserLocalServiceUtil;
077    import com.liferay.portal.util.PortalUtil;
078    import com.liferay.portal.util.PortletKeys;
079    import com.liferay.portlet.PortletPreferencesFactoryUtil;
080    import com.liferay.portlet.asset.NoSuchTagException;
081    import com.liferay.portlet.asset.model.AssetCategory;
082    import com.liferay.portlet.asset.model.AssetCategoryConstants;
083    import com.liferay.portlet.asset.model.AssetCategoryProperty;
084    import com.liferay.portlet.asset.model.AssetEntry;
085    import com.liferay.portlet.asset.model.AssetLink;
086    import com.liferay.portlet.asset.model.AssetTag;
087    import com.liferay.portlet.asset.model.AssetTagProperty;
088    import com.liferay.portlet.asset.model.AssetVocabulary;
089    import com.liferay.portlet.asset.service.AssetCategoryLocalServiceUtil;
090    import com.liferay.portlet.asset.service.AssetCategoryPropertyLocalServiceUtil;
091    import com.liferay.portlet.asset.service.AssetEntryLocalServiceUtil;
092    import com.liferay.portlet.asset.service.AssetTagLocalServiceUtil;
093    import com.liferay.portlet.asset.service.AssetTagPropertyLocalServiceUtil;
094    import com.liferay.portlet.asset.service.persistence.AssetCategoryUtil;
095    import com.liferay.portlet.asset.service.persistence.AssetVocabularyUtil;
096    import com.liferay.portlet.documentlibrary.model.DLFileEntry;
097    import com.liferay.portlet.documentlibrary.service.DLAppLocalServiceUtil;
098    import com.liferay.portlet.expando.model.ExpandoColumn;
099    import com.liferay.portlet.messageboards.model.MBDiscussion;
100    import com.liferay.portlet.messageboards.model.MBMessage;
101    import com.liferay.portlet.messageboards.service.MBDiscussionLocalServiceUtil;
102    import com.liferay.portlet.ratings.model.RatingsEntry;
103    import com.liferay.util.xml.DocUtil;
104    
105    import java.io.File;
106    import java.io.IOException;
107    
108    import java.util.Date;
109    import java.util.List;
110    import java.util.Map;
111    import java.util.Map.Entry;
112    import java.util.concurrent.Callable;
113    
114    import org.apache.commons.lang.time.StopWatch;
115    
116    /**
117     * @author Brian Wing Shun Chan
118     * @author Joel Kozikowski
119     * @author Charles May
120     * @author Raymond Aug??
121     * @author Jorge Ferrer
122     * @author Bruno Farache
123     * @author Zsigmond Rab
124     * @author Douglas Wong
125     * @author Mate Thurzo
126     */
127    public class PortletExporter {
128    
129            public void exportPortletData(
130                            PortletDataContext portletDataContext, Portlet portlet,
131                            Layout layout,
132                            javax.portlet.PortletPreferences jxPortletPreferences,
133                            Element parentElement)
134                    throws Exception {
135    
136                    if (portlet == null) {
137                            return;
138                    }
139    
140                    PortletDataHandler portletDataHandler =
141                            portlet.getPortletDataHandlerInstance();
142    
143                    if ((portletDataHandler == null) ||
144                            portletDataHandler.isDataPortletInstanceLevel()) {
145    
146                            return;
147                    }
148    
149                    Group group = layout.getGroup();
150    
151                    if (group.isStagingGroup()) {
152                            group = group.getLiveGroup();
153                    }
154    
155                    String portletId = portlet.getPortletId();
156    
157                    if (ExportImportThreadLocal.isStagingInProcess() &&
158                            !group.isStagedPortlet(portletId)) {
159    
160                            if (_log.isDebugEnabled()) {
161                                    _log.debug(
162                                            "Not exporting data for " + portletId +
163                                                    " because it is configured not to be staged");
164                            }
165    
166                            return;
167                    }
168    
169                    if (_log.isDebugEnabled()) {
170                            _log.debug("Exporting data for " + portletId);
171                    }
172    
173                    StringBundler sb = new StringBundler(4);
174    
175                    sb.append(
176                            ExportImportPathUtil.getPortletPath(portletDataContext, portletId));
177                    sb.append(StringPool.SLASH);
178    
179                    if (portlet.isPreferencesUniquePerLayout()) {
180                            sb.append(layout.getPlid());
181                    }
182                    else {
183                            sb.append(portletDataContext.getScopeGroupId());
184                    }
185    
186                    sb.append("/portlet-data.xml");
187    
188                    String path = sb.toString();
189    
190                    Element portletDataElement = parentElement.addElement("portlet-data");
191    
192                    portletDataElement.addAttribute("path", path);
193    
194                    if (portletDataContext.isPathProcessed(path)) {
195                            return;
196                    }
197    
198                    Date originalStartDate = portletDataContext.getStartDate();
199    
200                    String range = MapUtil.getString(
201                            portletDataContext.getParameterMap(), "range");
202    
203                    Group portletDataContextGroup = GroupLocalServiceUtil.getGroup(
204                            portletDataContext.getGroupId());
205    
206                    Date startDate = originalStartDate;
207    
208                    if (!portletDataContextGroup.isStagedRemotely() &&
209                            range.equals("fromLastPublishDate")) {
210    
211                            Date lastPublishDate = StagingUtil.getLastPublishDate(
212                                    jxPortletPreferences);
213    
214                            if (lastPublishDate == null) {
215                                    startDate = null;
216                            }
217                            else if ((startDate == null) || lastPublishDate.before(startDate)) {
218                                    startDate = lastPublishDate;
219                            }
220                    }
221    
222                    portletDataContext.setStartDate(startDate);
223    
224                    long groupId = portletDataContext.getGroupId();
225    
226                    portletDataContext.setGroupId(portletDataContext.getScopeGroupId());
227    
228                    portletDataContext.clearScopedPrimaryKeys();
229    
230                    String data = null;
231    
232                    try {
233                            data = portletDataHandler.exportData(
234                                    portletDataContext, portletId, jxPortletPreferences);
235                    }
236                    catch (PortletDataException pde) {
237                            throw pde;
238                    }
239                    catch (Exception e) {
240                            throw new SystemException(e);
241                    }
242                    finally {
243                            portletDataContext.setGroupId(groupId);
244                            portletDataContext.setStartDate(originalStartDate);
245                    }
246    
247                    if (Validator.isNull(data)) {
248                            if (_log.isDebugEnabled()) {
249                                    _log.debug(
250                                            "Not exporting data for " + portletId +
251                                                    " because null data was returned");
252                            }
253    
254                            return;
255                    }
256    
257                    portletDataContext.addZipEntry(path, data);
258    
259                    boolean updateLastPublishDate = MapUtil.getBoolean(
260                            portletDataContext.getParameterMap(),
261                            PortletDataHandlerKeys.UPDATE_LAST_PUBLISH_DATE);
262    
263                    if (updateLastPublishDate) {
264                            DateRange adjustedDateRange = new DateRange(
265                                    startDate, portletDataContext.getEndDate());
266    
267                            TransactionCommitCallbackRegistryUtil.registerCallback(
268                                    new UpdatePortletLastPublishDateCallable(
269                                            adjustedDateRange, portletDataContext.getEndDate(),
270                                            portletDataContext.getGroupId(), layout.getPlid(),
271                                            portletId));
272                    }
273            }
274    
275            @Deprecated
276            public byte[] exportPortletInfo(
277                            long plid, long groupId, String portletId,
278                            Map<String, String[]> parameterMap, Date startDate, Date endDate)
279                    throws Exception {
280    
281                    File file = exportPortletInfoAsFile(
282                            plid, groupId, portletId, parameterMap, startDate, endDate);
283    
284                    try {
285                            return FileUtil.getBytes(file);
286                    }
287                    catch (IOException ioe) {
288                            throw new SystemException(ioe);
289                    }
290                    finally {
291                            file.delete();
292                    }
293            }
294    
295            public File exportPortletInfoAsFile(
296                            long plid, long groupId, String portletId,
297                            Map<String, String[]> parameterMap, Date startDate, Date endDate)
298                    throws Exception {
299    
300                    try {
301                            ExportImportThreadLocal.setPortletExportInProcess(true);
302    
303                            return doExportPortletInfoAsFile(
304                                    plid, groupId, portletId, parameterMap, startDate, endDate);
305                    }
306                    finally {
307                            ExportImportThreadLocal.setPortletExportInProcess(false);
308                    }
309            }
310    
311            protected File doExportPortletInfoAsFile(
312                            long plid, long groupId, String portletId,
313                            Map<String, String[]> parameterMap, Date startDate, Date endDate)
314                    throws Exception {
315    
316                    boolean exportPermissions = MapUtil.getBoolean(
317                            parameterMap, PortletDataHandlerKeys.PERMISSIONS);
318    
319                    if (_log.isDebugEnabled()) {
320                            _log.debug("Export permissions " + exportPermissions);
321                    }
322    
323                    StopWatch stopWatch = new StopWatch();
324    
325                    stopWatch.start();
326    
327                    LayoutCache layoutCache = new LayoutCache();
328    
329                    Layout layout = LayoutLocalServiceUtil.getLayout(plid);
330    
331                    if (!layout.isTypeControlPanel() && !layout.isTypePanel() &&
332                            !layout.isTypePortlet()) {
333    
334                            throw new LayoutImportException(
335                                    "Layout type " + layout.getType() + " is not valid");
336                    }
337    
338                    ServiceContext serviceContext =
339                            ServiceContextThreadLocal.getServiceContext();
340    
341                    if (serviceContext == null) {
342                            serviceContext = new ServiceContext();
343    
344                            serviceContext.setCompanyId(layout.getCompanyId());
345                            serviceContext.setSignedIn(false);
346    
347                            long defaultUserId = UserLocalServiceUtil.getDefaultUserId(
348                                    layout.getCompanyId());
349    
350                            serviceContext.setUserId(defaultUserId);
351    
352                            ServiceContextThreadLocal.pushServiceContext(serviceContext);
353                    }
354    
355                    long layoutSetBranchId = MapUtil.getLong(
356                            parameterMap, "layoutSetBranchId");
357    
358                    serviceContext.setAttribute("layoutSetBranchId", layoutSetBranchId);
359    
360                    ZipWriter zipWriter = ExportImportHelperUtil.getPortletZipWriter(
361                            portletId);
362    
363                    long scopeGroupId = groupId;
364    
365                    javax.portlet.PortletPreferences jxPortletPreferences =
366                            PortletPreferencesFactoryUtil.getLayoutPortletSetup(
367                                    layout, portletId);
368    
369                    String scopeType = GetterUtil.getString(
370                            jxPortletPreferences.getValue("lfrScopeType", null));
371                    String scopeLayoutUuid = GetterUtil.getString(
372                            jxPortletPreferences.getValue("lfrScopeLayoutUuid", null));
373    
374                    if (Validator.isNotNull(scopeType)) {
375                            Group scopeGroup = null;
376    
377                            if (scopeType.equals("company")) {
378                                    scopeGroup = GroupLocalServiceUtil.getCompanyGroup(
379                                            layout.getCompanyId());
380                            }
381                            else if (Validator.isNotNull(scopeLayoutUuid)) {
382                                    scopeGroup = layout.getScopeGroup();
383                            }
384    
385                            if (scopeGroup != null) {
386                                    scopeGroupId = scopeGroup.getGroupId();
387                            }
388                    }
389    
390                    PortletDataContext portletDataContext =
391                            PortletDataContextFactoryUtil.createExportPortletDataContext(
392                                    layout.getCompanyId(), scopeGroupId, parameterMap, startDate,
393                                    endDate, zipWriter);
394    
395                    portletDataContext.setPortetDataContextListener(
396                            new PortletDataContextListenerImpl(portletDataContext));
397    
398                    portletDataContext.setPlid(plid);
399                    portletDataContext.setOldPlid(plid);
400                    portletDataContext.setScopeType(scopeType);
401                    portletDataContext.setScopeLayoutUuid(scopeLayoutUuid);
402    
403                    Document document = SAXReaderUtil.createDocument();
404    
405                    Element rootElement = document.addElement("root");
406    
407                    Element headerElement = rootElement.addElement("header");
408    
409                    headerElement.addAttribute(
410                            "available-locales",
411                            StringUtil.merge(
412                                    LanguageUtil.getAvailableLocales(
413                                            PortalUtil.getSiteGroupId(
414                                                    portletDataContext.getScopeGroupId()))));
415                    headerElement.addAttribute(
416                            "build-number", String.valueOf(ReleaseInfo.getBuildNumber()));
417                    headerElement.addAttribute("export-date", Time.getRFC822());
418    
419                    if (portletDataContext.hasDateRange()) {
420                            headerElement.addAttribute(
421                                    "start-date",
422                                    String.valueOf(portletDataContext.getStartDate()));
423                            headerElement.addAttribute(
424                                    "end-date", String.valueOf(portletDataContext.getEndDate()));
425                    }
426    
427                    headerElement.addAttribute("type", "portlet");
428                    headerElement.addAttribute(
429                            "company-id", String.valueOf(portletDataContext.getCompanyId()));
430                    headerElement.addAttribute(
431                            "company-group-id",
432                            String.valueOf(portletDataContext.getCompanyGroupId()));
433                    headerElement.addAttribute("group-id", String.valueOf(scopeGroupId));
434                    headerElement.addAttribute(
435                            "user-personal-site-group-id",
436                            String.valueOf(portletDataContext.getUserPersonalSiteGroupId()));
437                    headerElement.addAttribute(
438                            "private-layout", String.valueOf(layout.isPrivateLayout()));
439                    headerElement.addAttribute(
440                            "root-portlet-id", PortletConstants.getRootPortletId(portletId));
441    
442                    Element missingReferencesElement = rootElement.addElement(
443                            "missing-references");
444    
445                    portletDataContext.setMissingReferencesElement(
446                            missingReferencesElement);
447    
448                    Map<String, Boolean> exportPortletControlsMap =
449                            LayoutExporter.getExportPortletControlsMap(
450                                    layout.getCompanyId(), portletId, parameterMap);
451    
452                    exportPortlet(
453                            portletDataContext, layoutCache, portletId, layout, rootElement,
454                            exportPermissions,
455                            exportPortletControlsMap.get(
456                                    PortletDataHandlerKeys.PORTLET_ARCHIVED_SETUPS),
457                            exportPortletControlsMap.get(PortletDataHandlerKeys.PORTLET_DATA),
458                            exportPortletControlsMap.get(PortletDataHandlerKeys.PORTLET_SETUP),
459                            exportPortletControlsMap.get(
460                                    PortletDataHandlerKeys.PORTLET_USER_PREFERENCES));
461    
462                    exportAssetCategories(portletDataContext);
463                    exportAssetLinks(portletDataContext);
464                    exportAssetTags(portletDataContext);
465                    exportComments(portletDataContext);
466                    exportExpandoTables(portletDataContext);
467                    exportLocks(portletDataContext);
468    
469                    _deletionSystemEventExporter.exportDeletionSystemEvents(
470                            portletDataContext);
471    
472                    if (exportPermissions) {
473                            _permissionExporter.exportPortletDataPermissions(
474                                    portletDataContext);
475                    }
476    
477                    exportRatingsEntries(portletDataContext, rootElement);
478    
479                    ExportImportHelperUtil.writeManifestSummary(
480                            document, portletDataContext.getManifestSummary());
481    
482                    if (_log.isInfoEnabled()) {
483                            _log.info("Exporting portlet took " + stopWatch.getTime() + " ms");
484                    }
485    
486                    try {
487                            portletDataContext.addZipEntry(
488                                    "/manifest.xml", document.formattedString());
489                    }
490                    catch (IOException ioe) {
491                            throw new SystemException(ioe);
492                    }
493    
494                    return zipWriter.getFile();
495            }
496    
497            protected void exportAssetCategories(PortletDataContext portletDataContext)
498                    throws Exception {
499    
500                    Document document = SAXReaderUtil.createDocument();
501    
502                    Element rootElement = document.addElement("categories-hierarchy");
503    
504                    exportAssetCategories(portletDataContext, rootElement);
505    
506                    portletDataContext.addZipEntry(
507                            ExportImportPathUtil.getRootPath(portletDataContext) +
508                                    "/categories-hierarchy.xml",
509                            document.formattedString());
510            }
511    
512            protected void exportAssetCategories(
513                            PortletDataContext portletDataContext, Element rootElement)
514                    throws Exception {
515    
516                    Element assetsElement = rootElement.element("assets");
517    
518                    if (assetsElement == null) {
519                            assetsElement = rootElement.addElement("assets");
520                    }
521    
522                    Element assetCategoriesElement = rootElement.element("categories");
523    
524                    if (assetCategoriesElement == null) {
525                            assetCategoriesElement = rootElement.addElement("categories");
526                    }
527    
528                    Element assetVocabulariesElement = rootElement.element("vocabularies");
529    
530                    if (assetVocabulariesElement == null) {
531                            assetVocabulariesElement = rootElement.addElement("vocabularies");
532                    }
533    
534                    Map<String, String[]> assetCategoryUuidsMap =
535                            portletDataContext.getAssetCategoryUuidsMap();
536    
537                    for (Map.Entry<String, String[]> entry :
538                                    assetCategoryUuidsMap.entrySet()) {
539    
540                            String[] assetCategoryEntryParts = StringUtil.split(
541                                    entry.getKey(), CharPool.POUND);
542    
543                            String className = assetCategoryEntryParts[0];
544                            String classPK = assetCategoryEntryParts[1];
545    
546                            Element assetElement = assetsElement.addElement("asset");
547    
548                            assetElement.addAttribute("class-name", className);
549                            assetElement.addAttribute("class-pk", classPK);
550                            assetElement.addAttribute(
551                                    "category-uuids", StringUtil.merge(entry.getValue()));
552    
553                            List<AssetCategory> assetCategories =
554                                    AssetCategoryLocalServiceUtil.getCategories(
555                                            className, GetterUtil.getLong(classPK));
556    
557                            for (AssetCategory assetCategory : assetCategories) {
558                                    if (portletDataContext.isCompanyStagedGroupedModel(
559                                                    assetCategory)) {
560    
561                                            if (assetCategoryEntryParts.length > 2) {
562                                                    classPK = assetCategoryEntryParts[2];
563                                            }
564    
565                                            PersistedModelLocalService persistedModelLocalService =
566                                                    PersistedModelLocalServiceRegistryUtil.
567                                                            getPersistedModelLocalService(className);
568    
569                                            PersistedModel persistedModel =
570                                                    persistedModelLocalService.getPersistedModel(
571                                                            Long.valueOf(classPK));
572    
573                                            StagedModel stagedModel = (StagedModel)persistedModel;
574    
575                                            if (stagedModel instanceof DLFileEntry) {
576                                                    DLFileEntry dlFileEntry = (DLFileEntry)stagedModel;
577    
578                                                    stagedModel = DLAppLocalServiceUtil.getFileEntry(
579                                                            dlFileEntry.getFileEntryId());
580                                            }
581    
582                                            portletDataContext.addReferenceElement(
583                                                    stagedModel,
584                                                    portletDataContext.getExportDataElement(stagedModel),
585                                                    assetCategory, AssetCategory.class,
586                                                    PortletDataContext.REFERENCE_TYPE_DEPENDENCY, true);
587    
588                                            continue;
589                                    }
590    
591                                    exportAssetCategory(
592                                            portletDataContext, assetVocabulariesElement,
593                                            assetCategoriesElement, assetCategory);
594                            }
595                    }
596            }
597    
598            protected void exportAssetCategory(
599                            PortletDataContext portletDataContext,
600                            Element assetVocabulariesElement, Element assetCategoriesElement,
601                            AssetCategory assetCategory)
602                    throws Exception {
603    
604                    exportAssetVocabulary(
605                            portletDataContext, assetVocabulariesElement,
606                            assetCategory.getVocabularyId());
607    
608                    if (assetCategory.getParentCategoryId() !=
609                                    AssetCategoryConstants.DEFAULT_PARENT_CATEGORY_ID) {
610    
611                            exportAssetCategory(
612                                    portletDataContext, assetVocabulariesElement,
613                                    assetCategoriesElement, assetCategory.getParentCategoryId());
614                    }
615    
616                    String path = getAssetCategoryPath(
617                            portletDataContext, assetCategory.getCategoryId());
618    
619                    if (!portletDataContext.isPathNotProcessed(path)) {
620                            return;
621                    }
622    
623                    Element assetCategoryElement = assetCategoriesElement.addElement(
624                            "category");
625    
626                    assetCategoryElement.addAttribute("path", path);
627    
628                    assetCategory.setUserUuid(assetCategory.getUserUuid());
629    
630                    portletDataContext.addZipEntry(path, assetCategory);
631    
632                    List<AssetCategoryProperty> assetCategoryProperties =
633                            AssetCategoryPropertyLocalServiceUtil.getCategoryProperties(
634                                    assetCategory.getCategoryId());
635    
636                    for (AssetCategoryProperty assetCategoryProperty :
637                                    assetCategoryProperties) {
638    
639                            Element propertyElement = assetCategoryElement.addElement(
640                                    "property");
641    
642                            propertyElement.addAttribute(
643                                    "userUuid", assetCategoryProperty.getUserUuid());
644                            propertyElement.addAttribute("key", assetCategoryProperty.getKey());
645                            propertyElement.addAttribute(
646                                    "value", assetCategoryProperty.getValue());
647                    }
648    
649                    portletDataContext.addPermissions(
650                            AssetCategory.class, assetCategory.getCategoryId());
651    
652                    portletDataContext.cleanUpMissingReferences(assetCategory);
653            }
654    
655            protected void exportAssetCategory(
656                            PortletDataContext portletDataContext,
657                            Element assetVocabulariesElement, Element assetCategoriesElement,
658                            long assetCategoryId)
659                    throws Exception {
660    
661                    AssetCategory assetCategory = AssetCategoryUtil.fetchByPrimaryKey(
662                            assetCategoryId);
663    
664                    if (assetCategory != null) {
665                            exportAssetCategory(
666                                    portletDataContext, assetVocabulariesElement,
667                                    assetCategoriesElement, assetCategory);
668                    }
669            }
670    
671            protected void exportAssetLinks(PortletDataContext portletDataContext)
672                    throws Exception {
673    
674                    Document document = SAXReaderUtil.createDocument();
675    
676                    Element rootElement = document.addElement("links");
677    
678                    Map<String, List<AssetLink>> assetLinksMap =
679                            portletDataContext.getAssetLinksMap();
680    
681                    for (Entry<String, List<AssetLink>> entry : assetLinksMap.entrySet()) {
682                            String[] assetLinkNameParts = StringUtil.split(
683                                    entry.getKey(), CharPool.POUND);
684    
685                            List<AssetLink> assetLinks = entry.getValue();
686    
687                            String sourceAssetEntryUuid = assetLinkNameParts[0];
688    
689                            Element assetElement = rootElement.addElement("asset-link-group");
690    
691                            assetElement.addAttribute("source-uuid", sourceAssetEntryUuid);
692    
693                            for (AssetLink assetLink : assetLinks) {
694                                    String path = getAssetLinkPath(
695                                            portletDataContext, assetLink.getLinkId());
696    
697                                    if (!portletDataContext.isPathNotProcessed(path)) {
698                                            return;
699                                    }
700    
701                                    Element assetLinkElement = assetElement.addElement(
702                                            "asset-link");
703    
704                                    assetLinkElement.addAttribute("path", path);
705    
706                                    AssetEntry targetAssetEntry =
707                                            AssetEntryLocalServiceUtil.fetchAssetEntry(
708                                                    assetLink.getEntryId2());
709    
710                                    assetLinkElement.addAttribute(
711                                            "target-uuid", targetAssetEntry.getClassUuid());
712    
713                                    portletDataContext.addZipEntry(path, assetLink);
714                            }
715                    }
716    
717                    portletDataContext.addZipEntry(
718                            ExportImportPathUtil.getRootPath(portletDataContext) + "/links.xml",
719                            document.formattedString());
720            }
721    
722            protected void exportAssetTag(
723                            PortletDataContext portletDataContext, AssetTag assetTag,
724                            Element assetTagsElement)
725                    throws PortalException, SystemException {
726    
727                    String path = getAssetTagPath(portletDataContext, assetTag.getTagId());
728    
729                    if (!portletDataContext.isPathNotProcessed(path)) {
730                            return;
731                    }
732    
733                    Element assetTagElement = assetTagsElement.addElement("tag");
734    
735                    assetTagElement.addAttribute("path", path);
736    
737                    assetTag.setUserUuid(assetTag.getUserUuid());
738    
739                    portletDataContext.addZipEntry(path, assetTag);
740    
741                    List<AssetTagProperty> assetTagProperties =
742                            AssetTagPropertyLocalServiceUtil.getTagProperties(
743                                    assetTag.getTagId());
744    
745                    for (AssetTagProperty assetTagProperty : assetTagProperties) {
746                            Element propertyElement = assetTagElement.addElement("property");
747    
748                            propertyElement.addAttribute("key", assetTagProperty.getKey());
749                            propertyElement.addAttribute("value", assetTagProperty.getValue());
750                    }
751    
752                    portletDataContext.addPermissions(AssetTag.class, assetTag.getTagId());
753            }
754    
755            protected void exportAssetTags(PortletDataContext portletDataContext)
756                    throws Exception {
757    
758                    Document document = SAXReaderUtil.createDocument();
759    
760                    Element rootElement = document.addElement("tags");
761    
762                    Map<String, String[]> assetTagNamesMap =
763                            portletDataContext.getAssetTagNamesMap();
764    
765                    if (assetTagNamesMap.isEmpty()) {
766                            return;
767                    }
768    
769                    for (Map.Entry<String, String[]> entry : assetTagNamesMap.entrySet()) {
770                            String[] assetTagNameParts = StringUtil.split(
771                                    entry.getKey(), CharPool.POUND);
772    
773                            String className = assetTagNameParts[0];
774                            String classPK = assetTagNameParts[1];
775    
776                            Element assetElement = rootElement.addElement("asset");
777    
778                            assetElement.addAttribute("class-name", className);
779                            assetElement.addAttribute("class-pk", classPK);
780                            assetElement.addAttribute(
781                                    "tags", StringUtil.merge(entry.getValue()));
782    
783                            for (String tagName : entry.getValue()) {
784                                    try {
785                                            AssetTag assetTag = AssetTagLocalServiceUtil.getTag(
786                                                    portletDataContext.getScopeGroupId(), tagName);
787    
788                                            exportAssetTag(portletDataContext, assetTag, rootElement);
789                                    }
790                                    catch (NoSuchTagException nste) {
791                                            if (_log.isWarnEnabled()) {
792                                                    _log.warn("Unable to export tag " + tagName);
793                                            }
794                                    }
795                            }
796                    }
797    
798                    portletDataContext.addZipEntry(
799                            ExportImportPathUtil.getRootPath(portletDataContext) + "/tags.xml",
800                            document.formattedString());
801            }
802    
803            protected void exportAssetVocabulary(
804                            PortletDataContext portletDataContext,
805                            Element assetVocabulariesElement, AssetVocabulary assetVocabulary)
806                    throws Exception {
807    
808                    String path = getAssetVocabulariesPath(
809                            portletDataContext, assetVocabulary.getVocabularyId());
810    
811                    if (!portletDataContext.isPathNotProcessed(path)) {
812                            return;
813                    }
814    
815                    Element assetVocabularyElement = assetVocabulariesElement.addElement(
816                            "vocabulary");
817    
818                    assetVocabularyElement.addAttribute("path", path);
819    
820                    assetVocabulary.setUserUuid(assetVocabulary.getUserUuid());
821    
822                    portletDataContext.addZipEntry(path, assetVocabulary);
823    
824                    portletDataContext.addPermissions(
825                            AssetVocabulary.class, assetVocabulary.getVocabularyId());
826    
827                    portletDataContext.cleanUpMissingReferences(assetVocabulary);
828            }
829    
830            protected void exportAssetVocabulary(
831                            PortletDataContext portletDataContext,
832                            Element assetVocabulariesElement, long assetVocabularyId)
833                    throws Exception {
834    
835                    AssetVocabulary assetVocabulary = AssetVocabularyUtil.findByPrimaryKey(
836                            assetVocabularyId);
837    
838                    exportAssetVocabulary(
839                            portletDataContext, assetVocabulariesElement, assetVocabulary);
840            }
841    
842            protected void exportComments(PortletDataContext portletDataContext)
843                    throws Exception {
844    
845                    Document document = SAXReaderUtil.createDocument();
846    
847                    Element rootElement = document.addElement("comments");
848    
849                    Map<String, List<MBMessage>> commentsMap =
850                            portletDataContext.getComments();
851    
852                    for (Map.Entry<String, List<MBMessage>> entry :
853                                    commentsMap.entrySet()) {
854    
855                            String[] commentParts = StringUtil.split(
856                                    entry.getKey(), CharPool.POUND);
857    
858                            String className = commentParts[0];
859                            String classPK = commentParts[1];
860    
861                            String commentsPath = getCommentsPath(
862                                    portletDataContext, className, classPK);
863    
864                            Element assetElement = rootElement.addElement("asset");
865    
866                            assetElement.addAttribute("path", commentsPath);
867                            assetElement.addAttribute("class-name", className);
868                            assetElement.addAttribute("class-pk", classPK);
869    
870                            List<MBMessage> mbMessages = entry.getValue();
871    
872                            for (MBMessage mbMessage : mbMessages) {
873                                    String commentPath = getCommentPath(
874                                            portletDataContext, className, classPK, mbMessage);
875    
876                                    if (portletDataContext.isPathNotProcessed(commentPath)) {
877                                            User user = UserLocalServiceUtil.fetchUser(
878                                                    mbMessage.getUserId());
879    
880                                            if (user == null) {
881                                                    continue;
882                                            }
883    
884                                            portletDataContext.addZipEntry(commentPath, mbMessage);
885    
886                                            MBDiscussion mbDiscussion =
887                                                    MBDiscussionLocalServiceUtil.getDiscussion(
888                                                            className, GetterUtil.getLong(classPK));
889    
890                                            portletDataContext.addReferenceElement(
891                                                    mbDiscussion, assetElement, user,
892                                                    PortletDataContext.REFERENCE_TYPE_WEAK, true);
893                                    }
894                            }
895                    }
896    
897                    portletDataContext.addZipEntry(
898                            ExportImportPathUtil.getRootPath(portletDataContext) +
899                                    "/comments.xml",
900                            document.formattedString());
901            }
902    
903            protected void exportExpandoTables(PortletDataContext portletDataContext)
904                    throws Exception {
905    
906                    Document document = SAXReaderUtil.createDocument();
907    
908                    Element rootElement = document.addElement("expando-tables");
909    
910                    Map<String, List<ExpandoColumn>> expandoColumnsMap =
911                            portletDataContext.getExpandoColumns();
912    
913                    for (Map.Entry<String, List<ExpandoColumn>> entry :
914                                    expandoColumnsMap.entrySet()) {
915    
916                            String className = entry.getKey();
917    
918                            Element expandoTableElement = rootElement.addElement(
919                                    "expando-table");
920    
921                            expandoTableElement.addAttribute("class-name", className);
922    
923                            List<ExpandoColumn> expandoColumns = entry.getValue();
924    
925                            for (ExpandoColumn expandoColumn : expandoColumns) {
926                                    Element expandoColumnElement = expandoTableElement.addElement(
927                                            "expando-column");
928    
929                                    expandoColumnElement.addAttribute(
930                                            "column-id", String.valueOf(expandoColumn.getColumnId()));
931                                    expandoColumnElement.addAttribute(
932                                            "name", expandoColumn.getName());
933                                    expandoColumnElement.addAttribute(
934                                            "type", String.valueOf(expandoColumn.getType()));
935    
936                                    DocUtil.add(
937                                            expandoColumnElement, "default-data",
938                                            expandoColumn.getDefaultData());
939    
940                                    Element typeSettingsElement = expandoColumnElement.addElement(
941                                            "type-settings");
942    
943                                    UnicodeProperties typeSettingsProperties =
944                                            expandoColumn.getTypeSettingsProperties();
945    
946                                    typeSettingsElement.addCDATA(typeSettingsProperties.toString());
947                            }
948                    }
949    
950                    portletDataContext.addZipEntry(
951                            ExportImportPathUtil.getRootPath(portletDataContext) +
952                                    "/expando-tables.xml",
953                            document.formattedString());
954            }
955    
956            protected void exportLocks(PortletDataContext portletDataContext)
957                    throws Exception {
958    
959                    Document document = SAXReaderUtil.createDocument();
960    
961                    Element rootElement = document.addElement("locks");
962    
963                    Map<String, Lock> locksMap = portletDataContext.getLocks();
964    
965                    for (Map.Entry<String, Lock> entry : locksMap.entrySet()) {
966                            Lock lock = entry.getValue();
967    
968                            String entryKey = entry.getKey();
969    
970                            int pos = entryKey.indexOf(CharPool.POUND);
971    
972                            String className = entryKey.substring(0, pos);
973                            String key = entryKey.substring(pos + 1);
974    
975                            String path = getLockPath(portletDataContext, className, key, lock);
976    
977                            Element assetElement = rootElement.addElement("asset");
978    
979                            assetElement.addAttribute("path", path);
980                            assetElement.addAttribute("class-name", className);
981                            assetElement.addAttribute("key", key);
982    
983                            if (portletDataContext.isPathNotProcessed(path)) {
984                                    portletDataContext.addZipEntry(path, lock);
985                            }
986                    }
987    
988                    portletDataContext.addZipEntry(
989                            ExportImportPathUtil.getRootPath(portletDataContext) + "/locks.xml",
990                            document.formattedString());
991            }
992    
993            protected void exportPortlet(
994                            PortletDataContext portletDataContext, LayoutCache layoutCache,
995                            String portletId, Layout layout, Element parentElement,
996                            boolean exportPermissions, boolean exportPortletArchivedSetups,
997                            boolean exportPortletData, boolean exportPortletSetup,
998                            boolean exportPortletUserPreferences)
999                    throws Exception {
1000    
1001                    long plid = PortletKeys.PREFS_OWNER_ID_DEFAULT;
1002                    long layoutId = LayoutConstants.DEFAULT_PARENT_LAYOUT_ID;
1003    
1004                    if (layout != null) {
1005                            plid = layout.getPlid();
1006                            layoutId = layout.getLayoutId();
1007                    }
1008    
1009                    Portlet portlet = PortletLocalServiceUtil.getPortletById(
1010                            portletDataContext.getCompanyId(), portletId);
1011    
1012                    if ((portlet == null) || portlet.isUndeployedPortlet()) {
1013                            if (_log.isDebugEnabled()) {
1014                                    _log.debug(
1015                                            "Do not export portlet " + portletId +
1016                                                    " because the portlet is not deployed");
1017                            }
1018    
1019                            return;
1020                    }
1021    
1022                    if (!portlet.isInstanceable() &&
1023                            !portlet.isPreferencesUniquePerLayout() &&
1024                            portletDataContext.hasNotUniquePerLayout(portletId)) {
1025    
1026                            return;
1027                    }
1028    
1029                    String rootPortletId = PortletConstants.getRootPortletId(portletId);
1030    
1031                    portletDataContext.setRootPortletId(rootPortletId);
1032    
1033                    if (BackgroundTaskThreadLocal.hasBackgroundTask()) {
1034                            PortletDataContext clonedPortletDataContext =
1035                                    PortletDataContextFactoryUtil.clonePortletDataContext(
1036                                            portletDataContext);
1037    
1038                            ManifestSummary manifestSummary =
1039                                    clonedPortletDataContext.getManifestSummary();
1040    
1041                            manifestSummary.resetCounters();
1042    
1043                            PortletDataHandler portletDataHandler =
1044                                    portlet.getPortletDataHandlerInstance();
1045    
1046                            portletDataHandler.prepareManifestSummary(clonedPortletDataContext);
1047    
1048                            PortletDataHandlerStatusMessageSenderUtil.sendStatusMessage(
1049                                    "portlet", portletId, manifestSummary);
1050                    }
1051    
1052                    Document document = SAXReaderUtil.createDocument();
1053    
1054                    Element portletElement = document.addElement("portlet");
1055    
1056                    portletElement.addAttribute("portlet-id", portletId);
1057                    portletElement.addAttribute("root-portlet-id", rootPortletId);
1058                    portletElement.addAttribute("old-plid", String.valueOf(plid));
1059                    portletElement.addAttribute(
1060                            "scope-layout-type", portletDataContext.getScopeType());
1061                    portletElement.addAttribute(
1062                            "scope-layout-uuid", portletDataContext.getScopeLayoutUuid());
1063                    portletElement.addAttribute(
1064                            "private-layout", String.valueOf(layout.isPrivateLayout()));
1065    
1066                    // Data
1067    
1068                    if (exportPortletData) {
1069                            javax.portlet.PortletPreferences jxPortletPreferences =
1070                                    PortletPreferencesFactoryUtil.getStrictPortletSetup(
1071                                            layout, portletId);
1072    
1073                            exportPortletData(
1074                                    portletDataContext, portlet, layout, jxPortletPreferences,
1075                                    portletElement);
1076                    }
1077    
1078                    // Portlet preferences
1079    
1080                    if (exportPortletSetup) {
1081    
1082                            // Company
1083    
1084                            exportPortletPreferences(
1085                                    portletDataContext, portletDataContext.getCompanyId(),
1086                                    PortletKeys.PREFS_OWNER_TYPE_COMPANY, false, layout, plid,
1087                                    portlet.getRootPortletId(), portletElement);
1088    
1089                            // Group
1090    
1091                            exportPortletPreferences(
1092                                    portletDataContext, portletDataContext.getScopeGroupId(),
1093                                    PortletKeys.PREFS_OWNER_TYPE_GROUP, false, layout,
1094                                    PortletKeys.PREFS_PLID_SHARED, portlet.getRootPortletId(),
1095                                    portletElement);
1096    
1097                            // Layout
1098    
1099                            exportPortletPreferences(
1100                                    portletDataContext, PortletKeys.PREFS_OWNER_ID_DEFAULT,
1101                                    PortletKeys.PREFS_OWNER_TYPE_LAYOUT, false, layout, plid,
1102                                    portletId, portletElement);
1103                    }
1104    
1105                    // Portlet user preferences
1106    
1107                    if (exportPortletUserPreferences) {
1108                            List<PortletPreferences> portletPreferencesList =
1109                                    PortletPreferencesLocalServiceUtil.getPortletPreferences(
1110                                            PortletKeys.PREFS_OWNER_TYPE_USER, plid, portletId);
1111    
1112                            for (PortletPreferences portletPreferences :
1113                                            portletPreferencesList) {
1114    
1115                                    boolean defaultUser = false;
1116    
1117                                    if (portletPreferences.getOwnerId() ==
1118                                                    PortletKeys.PREFS_OWNER_ID_DEFAULT) {
1119    
1120                                            defaultUser = true;
1121                                    }
1122    
1123                                    exportPortletPreferences(
1124                                            portletDataContext, portletPreferences.getOwnerId(),
1125                                            PortletKeys.PREFS_OWNER_TYPE_USER, defaultUser, layout,
1126                                            plid, portletId, portletElement);
1127                            }
1128    
1129                            try {
1130                                    PortletPreferences groupPortletPreferences =
1131                                            PortletPreferencesLocalServiceUtil.getPortletPreferences(
1132                                                    portletDataContext.getScopeGroupId(),
1133                                                    PortletKeys.PREFS_OWNER_TYPE_GROUP,
1134                                                    PortletKeys.PREFS_PLID_SHARED,
1135                                                    portlet.getRootPortletId());
1136    
1137                                    exportPortletPreference(
1138                                            portletDataContext, portletDataContext.getScopeGroupId(),
1139                                            PortletKeys.PREFS_OWNER_TYPE_GROUP, false,
1140                                            groupPortletPreferences, portlet.getRootPortletId(),
1141                                            PortletKeys.PREFS_PLID_SHARED, portletElement);
1142                            }
1143                            catch (NoSuchPortletPreferencesException nsppe) {
1144                            }
1145                    }
1146    
1147                    // Archived setups
1148    
1149                    if (exportPortletArchivedSetups) {
1150                            List<PortletItem> portletItems =
1151                                    PortletItemLocalServiceUtil.getPortletItems(
1152                                            portletDataContext.getGroupId(), rootPortletId,
1153                                            PortletPreferences.class.getName());
1154    
1155                            for (PortletItem portletItem : portletItems) {
1156                                    exportPortletPreferences(
1157                                            portletDataContext, portletItem.getPortletItemId(),
1158                                            PortletKeys.PREFS_OWNER_TYPE_ARCHIVED, false, null, plid,
1159                                            portletItem.getPortletId(), portletElement);
1160                            }
1161                    }
1162    
1163                    // Permissions
1164    
1165                    if (exportPermissions) {
1166                            _permissionExporter.exportPortletPermissions(
1167                                    portletDataContext, layoutCache, portletId, layout,
1168                                    portletElement);
1169                    }
1170    
1171                    // Zip
1172    
1173                    StringBundler pathSB = new StringBundler(4);
1174    
1175                    pathSB.append(
1176                            ExportImportPathUtil.getPortletPath(portletDataContext, portletId));
1177                    pathSB.append(StringPool.SLASH);
1178                    pathSB.append(plid);
1179                    pathSB.append("/portlet.xml");
1180    
1181                    String path = pathSB.toString();
1182    
1183                    Element element = parentElement.addElement("portlet");
1184    
1185                    element.addAttribute("portlet-id", portletId);
1186                    element.addAttribute("layout-id", String.valueOf(layoutId));
1187                    element.addAttribute("path", path);
1188                    element.addAttribute("portlet-data", String.valueOf(exportPortletData));
1189    
1190                    StringBundler configurationOptionsSB = new StringBundler(6);
1191    
1192                    if (exportPortletSetup) {
1193                            configurationOptionsSB.append("setup");
1194                            configurationOptionsSB.append(StringPool.COMMA);
1195                    }
1196    
1197                    if (exportPortletArchivedSetups) {
1198                            configurationOptionsSB.append("archived-setups");
1199                            configurationOptionsSB.append(StringPool.COMMA);
1200                    }
1201    
1202                    if (exportPortletUserPreferences) {
1203                            configurationOptionsSB.append("user-preferences");
1204                            configurationOptionsSB.append(StringPool.COMMA);
1205                    }
1206    
1207                    if (configurationOptionsSB.index() > 0) {
1208                            configurationOptionsSB.setIndex(configurationOptionsSB.index() -1);
1209                    }
1210    
1211                    element.addAttribute(
1212                            "portlet-configuration", configurationOptionsSB.toString());
1213    
1214                    if (portletDataContext.isPathNotProcessed(path)) {
1215                            try {
1216                                    portletDataContext.addZipEntry(
1217                                            path, document.formattedString());
1218                            }
1219                            catch (IOException ioe) {
1220                                    if (_log.isWarnEnabled()) {
1221                                            _log.warn(ioe.getMessage());
1222                                    }
1223                            }
1224    
1225                            portletDataContext.addPrimaryKey(String.class, path);
1226                    }
1227    
1228                    portletDataContext.setRootPortletId(StringPool.BLANK);
1229            }
1230    
1231            protected void exportPortletPreference(
1232                            PortletDataContext portletDataContext, long ownerId, int ownerType,
1233                            boolean defaultUser, PortletPreferences portletPreferences,
1234                            String portletId, long plid, Element parentElement)
1235                    throws Exception {
1236    
1237                    String preferencesXML = portletPreferences.getPreferences();
1238    
1239                    if (Validator.isNull(preferencesXML)) {
1240                            preferencesXML = PortletConstants.DEFAULT_PREFERENCES;
1241                    }
1242    
1243                    javax.portlet.PortletPreferences jxPortletPreferences =
1244                            PortletPreferencesFactoryUtil.fromDefaultXML(preferencesXML);
1245    
1246                    Portlet portlet = PortletLocalServiceUtil.getPortletById(
1247                            portletDataContext.getCompanyId(), portletId);
1248    
1249                    Element portletPreferencesElement = parentElement.addElement(
1250                            "portlet-preferences");
1251    
1252                    if ((portlet != null) &&
1253                            (portlet.getPortletDataHandlerInstance() != null)) {
1254    
1255                            Element exportDataRootElement =
1256                                    portletDataContext.getExportDataRootElement();
1257    
1258                            try {
1259                                    portletDataContext.clearScopedPrimaryKeys();
1260    
1261                                    Element preferenceDataElement =
1262                                            portletPreferencesElement.addElement("preference-data");
1263    
1264                                    portletDataContext.setExportDataRootElement(
1265                                            preferenceDataElement);
1266    
1267                                    PortletDataHandler portletDataHandler =
1268                                            portlet.getPortletDataHandlerInstance();
1269    
1270                                    jxPortletPreferences =
1271                                            portletDataHandler.processExportPortletPreferences(
1272                                                    portletDataContext, portletId, jxPortletPreferences);
1273                            }
1274                            finally {
1275                                    portletDataContext.setExportDataRootElement(
1276                                            exportDataRootElement);
1277                            }
1278                    }
1279    
1280                    Document document = SAXReaderUtil.read(
1281                            PortletPreferencesFactoryUtil.toXML(jxPortletPreferences));
1282    
1283                    Element rootElement = document.getRootElement();
1284    
1285                    rootElement.addAttribute("owner-id", String.valueOf(ownerId));
1286                    rootElement.addAttribute("owner-type", String.valueOf(ownerType));
1287                    rootElement.addAttribute("default-user", String.valueOf(defaultUser));
1288                    rootElement.addAttribute("plid", String.valueOf(plid));
1289                    rootElement.addAttribute("portlet-id", portletId);
1290    
1291                    if (ownerType == PortletKeys.PREFS_OWNER_TYPE_ARCHIVED) {
1292                            PortletItem portletItem =
1293                                    PortletItemLocalServiceUtil.getPortletItem(ownerId);
1294    
1295                            rootElement.addAttribute(
1296                                    "archive-user-uuid", portletItem.getUserUuid());
1297                            rootElement.addAttribute("archive-name", portletItem.getName());
1298                    }
1299                    else if (ownerType == PortletKeys.PREFS_OWNER_TYPE_USER) {
1300                            User user = UserLocalServiceUtil.fetchUserById(ownerId);
1301    
1302                            if (user == null) {
1303                                    return;
1304                            }
1305    
1306                            rootElement.addAttribute("user-uuid", user.getUserUuid());
1307                    }
1308    
1309                    List<Node> nodes = document.selectNodes(
1310                            "/portlet-preferences/preference[name/text() = " +
1311                                    "'last-publish-date']");
1312    
1313                    for (Node node : nodes) {
1314                            document.remove(node);
1315                    }
1316    
1317                    String path = getPortletPreferencesPath(
1318                            portletDataContext, portletId, ownerId, ownerType, plid);
1319    
1320                    portletPreferencesElement.addAttribute("path", path);
1321    
1322                    if (portletDataContext.isPathNotProcessed(path)) {
1323                            portletDataContext.addZipEntry(
1324                                    path, document.formattedString(StringPool.TAB, false, false));
1325                    }
1326            }
1327    
1328            protected void exportPortletPreferences(
1329                            PortletDataContext portletDataContext, long ownerId, int ownerType,
1330                            boolean defaultUser, Layout layout, long plid, String portletId,
1331                            Element parentElement)
1332                    throws Exception {
1333    
1334                    PortletPreferences portletPreferences = null;
1335    
1336                    try {
1337                            if ((ownerType == PortletKeys.PREFS_OWNER_TYPE_COMPANY) ||
1338                                    (ownerType == PortletKeys.PREFS_OWNER_TYPE_GROUP) ||
1339                                    (ownerType == PortletKeys.PREFS_OWNER_TYPE_ARCHIVED)) {
1340    
1341                                    portletPreferences =
1342                                            PortletPreferencesLocalServiceUtil.getPortletPreferences(
1343                                                    ownerId, ownerType, LayoutConstants.DEFAULT_PLID,
1344                                                    portletId);
1345                            }
1346                            else {
1347                                    portletPreferences =
1348                                            PortletPreferencesLocalServiceUtil.getPortletPreferences(
1349                                                    ownerId, ownerType, plid, portletId);
1350                            }
1351                    }
1352                    catch (NoSuchPortletPreferencesException nsppe) {
1353                            return;
1354                    }
1355    
1356                    LayoutTypePortlet layoutTypePortlet = null;
1357    
1358                    if (layout != null) {
1359                            layoutTypePortlet = (LayoutTypePortlet)layout.getLayoutType();
1360                    }
1361    
1362                    if ((layoutTypePortlet == null) ||
1363                            layoutTypePortlet.hasPortletId(portletId)) {
1364    
1365                            exportPortletPreference(
1366                                    portletDataContext, ownerId, ownerType, defaultUser,
1367                                    portletPreferences, portletId, plid, parentElement);
1368                    }
1369            }
1370    
1371            protected void exportRatingsEntries(
1372                            PortletDataContext portletDataContext, Element parentElement)
1373                    throws Exception {
1374    
1375                    Document document = SAXReaderUtil.createDocument();
1376    
1377                    Element rootElement = document.addElement("ratings");
1378    
1379                    Map<String, List<RatingsEntry>> ratingsEntriesMap =
1380                            portletDataContext.getRatingsEntries();
1381    
1382                    for (Map.Entry<String, List<RatingsEntry>> entry :
1383                                    ratingsEntriesMap.entrySet()) {
1384    
1385                            String[] ratingsEntryParts = StringUtil.split(
1386                                    entry.getKey(), CharPool.POUND);
1387    
1388                            String className = ratingsEntryParts[0];
1389                            String classPK = ratingsEntryParts[1];
1390    
1391                            String ratingsEntriesPath = getRatingsEntriesPath(
1392                                    portletDataContext, className, classPK);
1393    
1394                            Element assetElement = rootElement.addElement("asset");
1395    
1396                            assetElement.addAttribute("path", ratingsEntriesPath);
1397                            assetElement.addAttribute("class-name", className);
1398                            assetElement.addAttribute("class-pk", classPK);
1399    
1400                            List<RatingsEntry> ratingsEntries = entry.getValue();
1401    
1402                            for (RatingsEntry ratingsEntry : ratingsEntries) {
1403                                    String ratingsEntryPath = getRatingsEntryPath(
1404                                            portletDataContext, className, classPK, ratingsEntry);
1405    
1406                                    User user = UserLocalServiceUtil.fetchUser(
1407                                            ratingsEntry.getUserId());
1408    
1409                                    if (user == null) {
1410                                            continue;
1411                                    }
1412    
1413                                    portletDataContext.addZipEntry(ratingsEntryPath, ratingsEntry);
1414    
1415                                    portletDataContext.addReferenceElement(
1416                                            ratingsEntry, assetElement, user,
1417                                            PortletDataContext.REFERENCE_TYPE_WEAK, true);
1418                            }
1419                    }
1420    
1421                    portletDataContext.addZipEntry(
1422                            ExportImportPathUtil.getRootPath(portletDataContext) +
1423                                    "/ratings.xml",
1424                            document.formattedString());
1425            }
1426    
1427            protected String getAssetCategoryPath(
1428                    PortletDataContext portletDataContext, long assetCategoryId) {
1429    
1430                    StringBundler sb = new StringBundler(4);
1431    
1432                    sb.append(ExportImportPathUtil.getRootPath(portletDataContext));
1433                    sb.append("/categories/");
1434                    sb.append(assetCategoryId);
1435                    sb.append(".xml");
1436    
1437                    return sb.toString();
1438            }
1439    
1440            protected String getAssetLinkPath(
1441                    PortletDataContext portletDataContext, long assetLinkId) {
1442    
1443                    StringBundler sb = new StringBundler(4);
1444    
1445                    sb.append(ExportImportPathUtil.getRootPath(portletDataContext));
1446                    sb.append("/links/");
1447                    sb.append(assetLinkId);
1448                    sb.append(".xml");
1449    
1450                    return sb.toString();
1451            }
1452    
1453            protected String getAssetTagPath(
1454                    PortletDataContext portletDataContext, long assetCategoryId) {
1455    
1456                    StringBundler sb = new StringBundler(4);
1457    
1458                    sb.append(ExportImportPathUtil.getRootPath(portletDataContext));
1459                    sb.append("/tags/");
1460                    sb.append(assetCategoryId);
1461                    sb.append(".xml");
1462    
1463                    return sb.toString();
1464            }
1465    
1466            protected String getAssetVocabulariesPath(
1467                    PortletDataContext portletDataContext, long assetVocabularyId) {
1468    
1469                    StringBundler sb = new StringBundler(4);
1470    
1471                    sb.append(ExportImportPathUtil.getRootPath(portletDataContext));
1472                    sb.append("/vocabularies/");
1473                    sb.append(assetVocabularyId);
1474                    sb.append(".xml");
1475    
1476                    return sb.toString();
1477            }
1478    
1479            protected String getCommentPath(
1480                    PortletDataContext portletDataContext, String className, String classPK,
1481                    MBMessage mbMessage) {
1482    
1483                    StringBundler sb = new StringBundler(8);
1484    
1485                    sb.append(ExportImportPathUtil.getRootPath(portletDataContext));
1486                    sb.append("/comments/");
1487                    sb.append(PortalUtil.getClassNameId(className));
1488                    sb.append(CharPool.FORWARD_SLASH);
1489                    sb.append(classPK);
1490                    sb.append(CharPool.FORWARD_SLASH);
1491                    sb.append(mbMessage.getMessageId());
1492                    sb.append(".xml");
1493    
1494                    return sb.toString();
1495            }
1496    
1497            protected String getCommentsPath(
1498                    PortletDataContext portletDataContext, String className,
1499                    String classPK) {
1500    
1501                    StringBundler sb = new StringBundler(6);
1502    
1503                    sb.append(ExportImportPathUtil.getRootPath(portletDataContext));
1504                    sb.append("/comments/");
1505                    sb.append(PortalUtil.getClassNameId(className));
1506                    sb.append(CharPool.FORWARD_SLASH);
1507                    sb.append(classPK);
1508                    sb.append(CharPool.FORWARD_SLASH);
1509    
1510                    return sb.toString();
1511            }
1512    
1513            protected String getLockPath(
1514                    PortletDataContext portletDataContext, String className, String key,
1515                    Lock lock) {
1516    
1517                    StringBundler sb = new StringBundler(8);
1518    
1519                    sb.append(ExportImportPathUtil.getRootPath(portletDataContext));
1520                    sb.append("/locks/");
1521                    sb.append(PortalUtil.getClassNameId(className));
1522                    sb.append(CharPool.FORWARD_SLASH);
1523                    sb.append(key);
1524                    sb.append(CharPool.FORWARD_SLASH);
1525                    sb.append(lock.getLockId());
1526                    sb.append(".xml");
1527    
1528                    return sb.toString();
1529            }
1530    
1531            protected String getPortletPreferencesPath(
1532                    PortletDataContext portletDataContext, String portletId, long ownerId,
1533                    int ownerType, long plid) {
1534    
1535                    StringBundler sb = new StringBundler(8);
1536    
1537                    sb.append(
1538                            ExportImportPathUtil.getPortletPath(portletDataContext, portletId));
1539                    sb.append("/preferences/");
1540    
1541                    if (ownerType == PortletKeys.PREFS_OWNER_TYPE_COMPANY) {
1542                            sb.append("company/");
1543                    }
1544                    else if (ownerType == PortletKeys.PREFS_OWNER_TYPE_GROUP) {
1545                            sb.append("group/");
1546                    }
1547                    else if (ownerType == PortletKeys.PREFS_OWNER_TYPE_LAYOUT) {
1548                            sb.append("layout/");
1549                    }
1550                    else if (ownerType == PortletKeys.PREFS_OWNER_TYPE_USER) {
1551                            sb.append("user/");
1552                    }
1553                    else if (ownerType == PortletKeys.PREFS_OWNER_TYPE_ARCHIVED) {
1554                            sb.append("archived/");
1555                    }
1556    
1557                    sb.append(ownerId);
1558                    sb.append(CharPool.FORWARD_SLASH);
1559                    sb.append(plid);
1560                    sb.append(CharPool.FORWARD_SLASH);
1561                    sb.append("portlet-preferences.xml");
1562    
1563                    return sb.toString();
1564            }
1565    
1566            protected String getRatingsEntriesPath(
1567                    PortletDataContext portletDataContext, String className,
1568                    String classPK) {
1569    
1570                    StringBundler sb = new StringBundler(6);
1571    
1572                    sb.append(ExportImportPathUtil.getRootPath(portletDataContext));
1573                    sb.append("/ratings/");
1574                    sb.append(PortalUtil.getClassNameId(className));
1575                    sb.append(CharPool.FORWARD_SLASH);
1576                    sb.append(classPK);
1577                    sb.append(CharPool.FORWARD_SLASH);
1578    
1579                    return sb.toString();
1580            }
1581    
1582            protected String getRatingsEntryPath(
1583                    PortletDataContext portletDataContext, String className, String classPK,
1584                    RatingsEntry ratingsEntry) {
1585    
1586                    StringBundler sb = new StringBundler(8);
1587    
1588                    sb.append(ExportImportPathUtil.getRootPath(portletDataContext));
1589                    sb.append("/ratings/");
1590                    sb.append(PortalUtil.getClassNameId(className));
1591                    sb.append(CharPool.FORWARD_SLASH);
1592                    sb.append(classPK);
1593                    sb.append(CharPool.FORWARD_SLASH);
1594                    sb.append(ratingsEntry.getEntryId());
1595                    sb.append(".xml");
1596    
1597                    return sb.toString();
1598            }
1599    
1600            private static Log _log = LogFactoryUtil.getLog(PortletExporter.class);
1601    
1602            private DeletionSystemEventExporter _deletionSystemEventExporter =
1603                    new DeletionSystemEventExporter();
1604            private PermissionExporter _permissionExporter = new PermissionExporter();
1605    
1606            private class UpdatePortletLastPublishDateCallable
1607                    implements Callable<Void> {
1608    
1609                    public UpdatePortletLastPublishDateCallable(
1610                            DateRange dateRange, Date endDate, long groupId, long plid,
1611                            String portletId) {
1612    
1613                            _dateRange = dateRange;
1614                            _endDate = endDate;
1615                            _groupId = groupId;
1616                            _plid = plid;
1617                            _portletId = portletId;
1618                    }
1619    
1620                    @Override
1621                    public Void call() throws Exception {
1622                            Group group = GroupLocalServiceUtil.getGroup(_groupId);
1623    
1624                            if (group.isStagedRemotely()) {
1625                                    return null;
1626                            }
1627    
1628                            Layout layout = LayoutLocalServiceUtil.fetchLayout(_plid);
1629    
1630                            if (ExportImportThreadLocal.isStagingInProcess() &&
1631                                    group.hasStagingGroup()) {
1632    
1633                                    group = group.getStagingGroup();
1634    
1635                                    if (layout != null) {
1636                                            layout = LayoutLocalServiceUtil.fetchLayoutByUuidAndGroupId(
1637                                                    layout.getUuid(), group.getGroupId(),
1638                                                    layout.isPrivateLayout());
1639                                    }
1640                            }
1641    
1642                            if (layout == null) {
1643                                    layout = new LayoutImpl();
1644    
1645                                    layout.setCompanyId(group.getCompanyId());
1646                                    layout.setGroupId(group.getGroupId());
1647                            }
1648    
1649                            javax.portlet.PortletPreferences jxPortletPreferences =
1650                                    PortletPreferencesFactoryUtil.getStrictPortletSetup(
1651                                            layout, _portletId);
1652    
1653                            StagingUtil.updateLastPublishDate(
1654                                    _portletId, jxPortletPreferences, _dateRange, _endDate);
1655    
1656                            return null;
1657                    }
1658    
1659                    private final DateRange _dateRange;
1660                    private final Date _endDate;
1661                    private final long _groupId;
1662                    private final long _plid;
1663                    private final String _portletId;
1664    
1665            }
1666    
1667    }