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                    portletDataContext.setExportDataRootElement(rootElement);
408    
409                    Element headerElement = rootElement.addElement("header");
410    
411                    headerElement.addAttribute(
412                            "available-locales",
413                            StringUtil.merge(
414                                    LanguageUtil.getAvailableLocales(
415                                            PortalUtil.getSiteGroupId(
416                                                    portletDataContext.getScopeGroupId()))));
417                    headerElement.addAttribute(
418                            "build-number", String.valueOf(ReleaseInfo.getBuildNumber()));
419                    headerElement.addAttribute("export-date", Time.getRFC822());
420    
421                    if (portletDataContext.hasDateRange()) {
422                            headerElement.addAttribute(
423                                    "start-date",
424                                    String.valueOf(portletDataContext.getStartDate()));
425                            headerElement.addAttribute(
426                                    "end-date", String.valueOf(portletDataContext.getEndDate()));
427                    }
428    
429                    headerElement.addAttribute("type", "portlet");
430                    headerElement.addAttribute(
431                            "company-id", String.valueOf(portletDataContext.getCompanyId()));
432                    headerElement.addAttribute(
433                            "company-group-id",
434                            String.valueOf(portletDataContext.getCompanyGroupId()));
435                    headerElement.addAttribute("group-id", String.valueOf(scopeGroupId));
436                    headerElement.addAttribute(
437                            "user-personal-site-group-id",
438                            String.valueOf(portletDataContext.getUserPersonalSiteGroupId()));
439                    headerElement.addAttribute(
440                            "private-layout", String.valueOf(layout.isPrivateLayout()));
441                    headerElement.addAttribute(
442                            "root-portlet-id", PortletConstants.getRootPortletId(portletId));
443    
444                    Element missingReferencesElement = rootElement.addElement(
445                            "missing-references");
446    
447                    portletDataContext.setMissingReferencesElement(
448                            missingReferencesElement);
449    
450                    Map<String, Boolean> exportPortletControlsMap =
451                            LayoutExporter.getExportPortletControlsMap(
452                                    layout.getCompanyId(), portletId, parameterMap);
453    
454                    exportPortlet(
455                            portletDataContext, layoutCache, portletId, layout, rootElement,
456                            exportPermissions,
457                            exportPortletControlsMap.get(
458                                    PortletDataHandlerKeys.PORTLET_ARCHIVED_SETUPS),
459                            exportPortletControlsMap.get(PortletDataHandlerKeys.PORTLET_DATA),
460                            exportPortletControlsMap.get(PortletDataHandlerKeys.PORTLET_SETUP),
461                            exportPortletControlsMap.get(
462                                    PortletDataHandlerKeys.PORTLET_USER_PREFERENCES));
463    
464                    exportAssetCategories(portletDataContext);
465                    exportAssetLinks(portletDataContext);
466                    exportAssetTags(portletDataContext);
467                    exportComments(portletDataContext);
468                    exportExpandoTables(portletDataContext);
469                    exportLocks(portletDataContext);
470    
471                    _deletionSystemEventExporter.exportDeletionSystemEvents(
472                            portletDataContext);
473    
474                    if (exportPermissions) {
475                            _permissionExporter.exportPortletDataPermissions(
476                                    portletDataContext);
477                    }
478    
479                    exportRatingsEntries(portletDataContext, rootElement);
480    
481                    ExportImportHelperUtil.writeManifestSummary(
482                            document, portletDataContext.getManifestSummary());
483    
484                    if (_log.isInfoEnabled()) {
485                            _log.info("Exporting portlet took " + stopWatch.getTime() + " ms");
486                    }
487    
488                    try {
489                            portletDataContext.addZipEntry(
490                                    "/manifest.xml", document.formattedString());
491                    }
492                    catch (IOException ioe) {
493                            throw new SystemException(ioe);
494                    }
495    
496                    return zipWriter.getFile();
497            }
498    
499            protected void exportAssetCategories(PortletDataContext portletDataContext)
500                    throws Exception {
501    
502                    Document document = SAXReaderUtil.createDocument();
503    
504                    Element rootElement = document.addElement("categories-hierarchy");
505    
506                    exportAssetCategories(portletDataContext, rootElement);
507    
508                    portletDataContext.addZipEntry(
509                            ExportImportPathUtil.getRootPath(portletDataContext) +
510                                    "/categories-hierarchy.xml",
511                            document.formattedString());
512            }
513    
514            protected void exportAssetCategories(
515                            PortletDataContext portletDataContext, Element rootElement)
516                    throws Exception {
517    
518                    Element assetsElement = rootElement.element("assets");
519    
520                    if (assetsElement == null) {
521                            assetsElement = rootElement.addElement("assets");
522                    }
523    
524                    Element assetCategoriesElement = rootElement.element("categories");
525    
526                    if (assetCategoriesElement == null) {
527                            assetCategoriesElement = rootElement.addElement("categories");
528                    }
529    
530                    Element assetVocabulariesElement = rootElement.element("vocabularies");
531    
532                    if (assetVocabulariesElement == null) {
533                            assetVocabulariesElement = rootElement.addElement("vocabularies");
534                    }
535    
536                    Map<String, String[]> assetCategoryUuidsMap =
537                            portletDataContext.getAssetCategoryUuidsMap();
538    
539                    for (Map.Entry<String, String[]> entry :
540                                    assetCategoryUuidsMap.entrySet()) {
541    
542                            String[] assetCategoryEntryParts = StringUtil.split(
543                                    entry.getKey(), CharPool.POUND);
544    
545                            String className = assetCategoryEntryParts[0];
546                            String classPK = assetCategoryEntryParts[1];
547    
548                            Element assetElement = assetsElement.addElement("asset");
549    
550                            assetElement.addAttribute("class-name", className);
551                            assetElement.addAttribute("class-pk", classPK);
552                            assetElement.addAttribute(
553                                    "category-uuids", StringUtil.merge(entry.getValue()));
554    
555                            List<AssetCategory> assetCategories =
556                                    AssetCategoryLocalServiceUtil.getCategories(
557                                            className, GetterUtil.getLong(classPK));
558    
559                            for (AssetCategory assetCategory : assetCategories) {
560                                    if (portletDataContext.isCompanyStagedGroupedModel(
561                                                    assetCategory)) {
562    
563                                            if (assetCategoryEntryParts.length > 2) {
564                                                    classPK = assetCategoryEntryParts[2];
565                                            }
566    
567                                            PersistedModelLocalService persistedModelLocalService =
568                                                    PersistedModelLocalServiceRegistryUtil.
569                                                            getPersistedModelLocalService(className);
570    
571                                            PersistedModel persistedModel =
572                                                    persistedModelLocalService.getPersistedModel(
573                                                            Long.valueOf(classPK));
574    
575                                            StagedModel stagedModel = (StagedModel)persistedModel;
576    
577                                            if (stagedModel instanceof DLFileEntry) {
578                                                    DLFileEntry dlFileEntry = (DLFileEntry)stagedModel;
579    
580                                                    stagedModel = DLAppLocalServiceUtil.getFileEntry(
581                                                            dlFileEntry.getFileEntryId());
582                                            }
583    
584                                            portletDataContext.addReferenceElement(
585                                                    stagedModel,
586                                                    portletDataContext.getExportDataElement(stagedModel),
587                                                    assetCategory, AssetCategory.class,
588                                                    PortletDataContext.REFERENCE_TYPE_DEPENDENCY, true);
589    
590                                            continue;
591                                    }
592    
593                                    exportAssetCategory(
594                                            portletDataContext, assetVocabulariesElement,
595                                            assetCategoriesElement, assetCategory);
596                            }
597                    }
598            }
599    
600            protected void exportAssetCategory(
601                            PortletDataContext portletDataContext,
602                            Element assetVocabulariesElement, Element assetCategoriesElement,
603                            AssetCategory assetCategory)
604                    throws Exception {
605    
606                    exportAssetVocabulary(
607                            portletDataContext, assetVocabulariesElement,
608                            assetCategory.getVocabularyId());
609    
610                    if (assetCategory.getParentCategoryId() !=
611                                    AssetCategoryConstants.DEFAULT_PARENT_CATEGORY_ID) {
612    
613                            exportAssetCategory(
614                                    portletDataContext, assetVocabulariesElement,
615                                    assetCategoriesElement, assetCategory.getParentCategoryId());
616                    }
617    
618                    String path = getAssetCategoryPath(
619                            portletDataContext, assetCategory.getCategoryId());
620    
621                    if (!portletDataContext.isPathNotProcessed(path)) {
622                            return;
623                    }
624    
625                    Element assetCategoryElement = assetCategoriesElement.addElement(
626                            "category");
627    
628                    assetCategoryElement.addAttribute("path", path);
629    
630                    assetCategory.setUserUuid(assetCategory.getUserUuid());
631    
632                    portletDataContext.addZipEntry(path, assetCategory);
633    
634                    List<AssetCategoryProperty> assetCategoryProperties =
635                            AssetCategoryPropertyLocalServiceUtil.getCategoryProperties(
636                                    assetCategory.getCategoryId());
637    
638                    for (AssetCategoryProperty assetCategoryProperty :
639                                    assetCategoryProperties) {
640    
641                            Element propertyElement = assetCategoryElement.addElement(
642                                    "property");
643    
644                            propertyElement.addAttribute(
645                                    "userUuid", assetCategoryProperty.getUserUuid());
646                            propertyElement.addAttribute("key", assetCategoryProperty.getKey());
647                            propertyElement.addAttribute(
648                                    "value", assetCategoryProperty.getValue());
649                    }
650    
651                    portletDataContext.addPermissions(
652                            AssetCategory.class, assetCategory.getCategoryId());
653    
654                    portletDataContext.cleanUpMissingReferences(assetCategory);
655            }
656    
657            protected void exportAssetCategory(
658                            PortletDataContext portletDataContext,
659                            Element assetVocabulariesElement, Element assetCategoriesElement,
660                            long assetCategoryId)
661                    throws Exception {
662    
663                    AssetCategory assetCategory = AssetCategoryUtil.fetchByPrimaryKey(
664                            assetCategoryId);
665    
666                    if (assetCategory != null) {
667                            exportAssetCategory(
668                                    portletDataContext, assetVocabulariesElement,
669                                    assetCategoriesElement, assetCategory);
670                    }
671            }
672    
673            protected void exportAssetLinks(PortletDataContext portletDataContext)
674                    throws Exception {
675    
676                    Document document = SAXReaderUtil.createDocument();
677    
678                    Element rootElement = document.addElement("links");
679    
680                    Map<String, List<AssetLink>> assetLinksMap =
681                            portletDataContext.getAssetLinksMap();
682    
683                    for (Entry<String, List<AssetLink>> entry : assetLinksMap.entrySet()) {
684                            String[] assetLinkNameParts = StringUtil.split(
685                                    entry.getKey(), CharPool.POUND);
686    
687                            List<AssetLink> assetLinks = entry.getValue();
688    
689                            String sourceAssetEntryUuid = assetLinkNameParts[0];
690    
691                            Element assetElement = rootElement.addElement("asset-link-group");
692    
693                            assetElement.addAttribute("source-uuid", sourceAssetEntryUuid);
694    
695                            for (AssetLink assetLink : assetLinks) {
696                                    String path = getAssetLinkPath(
697                                            portletDataContext, assetLink.getLinkId());
698    
699                                    if (!portletDataContext.isPathNotProcessed(path)) {
700                                            return;
701                                    }
702    
703                                    Element assetLinkElement = assetElement.addElement(
704                                            "asset-link");
705    
706                                    assetLinkElement.addAttribute("path", path);
707    
708                                    AssetEntry targetAssetEntry =
709                                            AssetEntryLocalServiceUtil.fetchAssetEntry(
710                                                    assetLink.getEntryId2());
711    
712                                    assetLinkElement.addAttribute(
713                                            "target-uuid", targetAssetEntry.getClassUuid());
714    
715                                    portletDataContext.addZipEntry(path, assetLink);
716                            }
717                    }
718    
719                    portletDataContext.addZipEntry(
720                            ExportImportPathUtil.getRootPath(portletDataContext) + "/links.xml",
721                            document.formattedString());
722            }
723    
724            protected void exportAssetTag(
725                            PortletDataContext portletDataContext, AssetTag assetTag,
726                            Element assetTagsElement)
727                    throws PortalException, SystemException {
728    
729                    String path = getAssetTagPath(portletDataContext, assetTag.getTagId());
730    
731                    if (!portletDataContext.isPathNotProcessed(path)) {
732                            return;
733                    }
734    
735                    Element assetTagElement = assetTagsElement.addElement("tag");
736    
737                    assetTagElement.addAttribute("path", path);
738    
739                    assetTag.setUserUuid(assetTag.getUserUuid());
740    
741                    portletDataContext.addZipEntry(path, assetTag);
742    
743                    List<AssetTagProperty> assetTagProperties =
744                            AssetTagPropertyLocalServiceUtil.getTagProperties(
745                                    assetTag.getTagId());
746    
747                    for (AssetTagProperty assetTagProperty : assetTagProperties) {
748                            Element propertyElement = assetTagElement.addElement("property");
749    
750                            propertyElement.addAttribute("key", assetTagProperty.getKey());
751                            propertyElement.addAttribute("value", assetTagProperty.getValue());
752                    }
753    
754                    portletDataContext.addPermissions(AssetTag.class, assetTag.getTagId());
755            }
756    
757            protected void exportAssetTags(PortletDataContext portletDataContext)
758                    throws Exception {
759    
760                    Document document = SAXReaderUtil.createDocument();
761    
762                    Element rootElement = document.addElement("tags");
763    
764                    Map<String, String[]> assetTagNamesMap =
765                            portletDataContext.getAssetTagNamesMap();
766    
767                    if (assetTagNamesMap.isEmpty()) {
768                            return;
769                    }
770    
771                    for (Map.Entry<String, String[]> entry : assetTagNamesMap.entrySet()) {
772                            String[] assetTagNameParts = StringUtil.split(
773                                    entry.getKey(), CharPool.POUND);
774    
775                            String className = assetTagNameParts[0];
776                            String classPK = assetTagNameParts[1];
777    
778                            Element assetElement = rootElement.addElement("asset");
779    
780                            assetElement.addAttribute("class-name", className);
781                            assetElement.addAttribute("class-pk", classPK);
782                            assetElement.addAttribute(
783                                    "tags", StringUtil.merge(entry.getValue()));
784    
785                            for (String tagName : entry.getValue()) {
786                                    try {
787                                            AssetTag assetTag = AssetTagLocalServiceUtil.getTag(
788                                                    portletDataContext.getScopeGroupId(), tagName);
789    
790                                            exportAssetTag(portletDataContext, assetTag, rootElement);
791                                    }
792                                    catch (NoSuchTagException nste) {
793                                            if (_log.isWarnEnabled()) {
794                                                    _log.warn("Unable to export tag " + tagName);
795                                            }
796                                    }
797                            }
798                    }
799    
800                    portletDataContext.addZipEntry(
801                            ExportImportPathUtil.getRootPath(portletDataContext) + "/tags.xml",
802                            document.formattedString());
803            }
804    
805            protected void exportAssetVocabulary(
806                            PortletDataContext portletDataContext,
807                            Element assetVocabulariesElement, AssetVocabulary assetVocabulary)
808                    throws Exception {
809    
810                    String path = getAssetVocabulariesPath(
811                            portletDataContext, assetVocabulary.getVocabularyId());
812    
813                    if (!portletDataContext.isPathNotProcessed(path)) {
814                            return;
815                    }
816    
817                    Element assetVocabularyElement = assetVocabulariesElement.addElement(
818                            "vocabulary");
819    
820                    assetVocabularyElement.addAttribute("path", path);
821    
822                    assetVocabulary.setUserUuid(assetVocabulary.getUserUuid());
823    
824                    portletDataContext.addZipEntry(path, assetVocabulary);
825    
826                    portletDataContext.addPermissions(
827                            AssetVocabulary.class, assetVocabulary.getVocabularyId());
828    
829                    portletDataContext.cleanUpMissingReferences(assetVocabulary);
830            }
831    
832            protected void exportAssetVocabulary(
833                            PortletDataContext portletDataContext,
834                            Element assetVocabulariesElement, long assetVocabularyId)
835                    throws Exception {
836    
837                    AssetVocabulary assetVocabulary = AssetVocabularyUtil.findByPrimaryKey(
838                            assetVocabularyId);
839    
840                    exportAssetVocabulary(
841                            portletDataContext, assetVocabulariesElement, assetVocabulary);
842            }
843    
844            protected void exportComments(PortletDataContext portletDataContext)
845                    throws Exception {
846    
847                    Document document = SAXReaderUtil.createDocument();
848    
849                    Element rootElement = document.addElement("comments");
850    
851                    Map<String, List<MBMessage>> commentsMap =
852                            portletDataContext.getComments();
853    
854                    for (Map.Entry<String, List<MBMessage>> entry :
855                                    commentsMap.entrySet()) {
856    
857                            String[] commentParts = StringUtil.split(
858                                    entry.getKey(), CharPool.POUND);
859    
860                            String className = commentParts[0];
861                            String classPK = commentParts[1];
862    
863                            String commentsPath = getCommentsPath(
864                                    portletDataContext, className, classPK);
865    
866                            Element assetElement = rootElement.addElement("asset");
867    
868                            assetElement.addAttribute("path", commentsPath);
869                            assetElement.addAttribute("class-name", className);
870                            assetElement.addAttribute("class-pk", classPK);
871    
872                            List<MBMessage> mbMessages = entry.getValue();
873    
874                            for (MBMessage mbMessage : mbMessages) {
875                                    String commentPath = getCommentPath(
876                                            portletDataContext, className, classPK, mbMessage);
877    
878                                    if (portletDataContext.isPathNotProcessed(commentPath)) {
879                                            User user = UserLocalServiceUtil.fetchUser(
880                                                    mbMessage.getUserId());
881    
882                                            if (user == null) {
883                                                    continue;
884                                            }
885    
886                                            portletDataContext.addZipEntry(commentPath, mbMessage);
887    
888                                            MBDiscussion mbDiscussion =
889                                                    MBDiscussionLocalServiceUtil.getDiscussion(
890                                                            className, GetterUtil.getLong(classPK));
891    
892                                            portletDataContext.addReferenceElement(
893                                                    mbDiscussion, assetElement, user,
894                                                    PortletDataContext.REFERENCE_TYPE_WEAK, true);
895                                    }
896                            }
897                    }
898    
899                    portletDataContext.addZipEntry(
900                            ExportImportPathUtil.getRootPath(portletDataContext) +
901                                    "/comments.xml",
902                            document.formattedString());
903            }
904    
905            protected void exportExpandoTables(PortletDataContext portletDataContext)
906                    throws Exception {
907    
908                    Document document = SAXReaderUtil.createDocument();
909    
910                    Element rootElement = document.addElement("expando-tables");
911    
912                    Map<String, List<ExpandoColumn>> expandoColumnsMap =
913                            portletDataContext.getExpandoColumns();
914    
915                    for (Map.Entry<String, List<ExpandoColumn>> entry :
916                                    expandoColumnsMap.entrySet()) {
917    
918                            String className = entry.getKey();
919    
920                            Element expandoTableElement = rootElement.addElement(
921                                    "expando-table");
922    
923                            expandoTableElement.addAttribute("class-name", className);
924    
925                            List<ExpandoColumn> expandoColumns = entry.getValue();
926    
927                            for (ExpandoColumn expandoColumn : expandoColumns) {
928                                    Element expandoColumnElement = expandoTableElement.addElement(
929                                            "expando-column");
930    
931                                    expandoColumnElement.addAttribute(
932                                            "column-id", String.valueOf(expandoColumn.getColumnId()));
933                                    expandoColumnElement.addAttribute(
934                                            "name", expandoColumn.getName());
935                                    expandoColumnElement.addAttribute(
936                                            "type", String.valueOf(expandoColumn.getType()));
937    
938                                    DocUtil.add(
939                                            expandoColumnElement, "default-data",
940                                            expandoColumn.getDefaultData());
941    
942                                    Element typeSettingsElement = expandoColumnElement.addElement(
943                                            "type-settings");
944    
945                                    UnicodeProperties typeSettingsProperties =
946                                            expandoColumn.getTypeSettingsProperties();
947    
948                                    typeSettingsElement.addCDATA(typeSettingsProperties.toString());
949                            }
950                    }
951    
952                    portletDataContext.addZipEntry(
953                            ExportImportPathUtil.getRootPath(portletDataContext) +
954                                    "/expando-tables.xml",
955                            document.formattedString());
956            }
957    
958            protected void exportLocks(PortletDataContext portletDataContext)
959                    throws Exception {
960    
961                    Document document = SAXReaderUtil.createDocument();
962    
963                    Element rootElement = document.addElement("locks");
964    
965                    Map<String, Lock> locksMap = portletDataContext.getLocks();
966    
967                    for (Map.Entry<String, Lock> entry : locksMap.entrySet()) {
968                            Lock lock = entry.getValue();
969    
970                            String entryKey = entry.getKey();
971    
972                            int pos = entryKey.indexOf(CharPool.POUND);
973    
974                            String className = entryKey.substring(0, pos);
975                            String key = entryKey.substring(pos + 1);
976    
977                            String path = getLockPath(portletDataContext, className, key, lock);
978    
979                            Element assetElement = rootElement.addElement("asset");
980    
981                            assetElement.addAttribute("path", path);
982                            assetElement.addAttribute("class-name", className);
983                            assetElement.addAttribute("key", key);
984    
985                            if (portletDataContext.isPathNotProcessed(path)) {
986                                    portletDataContext.addZipEntry(path, lock);
987                            }
988                    }
989    
990                    portletDataContext.addZipEntry(
991                            ExportImportPathUtil.getRootPath(portletDataContext) + "/locks.xml",
992                            document.formattedString());
993            }
994    
995            protected void exportPortlet(
996                            PortletDataContext portletDataContext, LayoutCache layoutCache,
997                            String portletId, Layout layout, Element parentElement,
998                            boolean exportPermissions, boolean exportPortletArchivedSetups,
999                            boolean exportPortletData, boolean exportPortletSetup,
1000                            boolean exportPortletUserPreferences)
1001                    throws Exception {
1002    
1003                    long plid = PortletKeys.PREFS_OWNER_ID_DEFAULT;
1004                    long layoutId = LayoutConstants.DEFAULT_PARENT_LAYOUT_ID;
1005    
1006                    if (layout != null) {
1007                            plid = layout.getPlid();
1008                            layoutId = layout.getLayoutId();
1009                    }
1010    
1011                    Portlet portlet = PortletLocalServiceUtil.getPortletById(
1012                            portletDataContext.getCompanyId(), portletId);
1013    
1014                    if ((portlet == null) || portlet.isUndeployedPortlet()) {
1015                            if (_log.isDebugEnabled()) {
1016                                    _log.debug(
1017                                            "Do not export portlet " + portletId +
1018                                                    " because the portlet is not deployed");
1019                            }
1020    
1021                            return;
1022                    }
1023    
1024                    if (!portlet.isInstanceable() &&
1025                            !portlet.isPreferencesUniquePerLayout() &&
1026                            portletDataContext.hasNotUniquePerLayout(portletId)) {
1027    
1028                            return;
1029                    }
1030    
1031                    String rootPortletId = PortletConstants.getRootPortletId(portletId);
1032    
1033                    portletDataContext.setRootPortletId(rootPortletId);
1034    
1035                    if (BackgroundTaskThreadLocal.hasBackgroundTask()) {
1036                            PortletDataContext clonedPortletDataContext =
1037                                    PortletDataContextFactoryUtil.clonePortletDataContext(
1038                                            portletDataContext);
1039    
1040                            ManifestSummary manifestSummary =
1041                                    clonedPortletDataContext.getManifestSummary();
1042    
1043                            manifestSummary.resetCounters();
1044    
1045                            PortletDataHandler portletDataHandler =
1046                                    portlet.getPortletDataHandlerInstance();
1047    
1048                            portletDataHandler.prepareManifestSummary(clonedPortletDataContext);
1049    
1050                            PortletDataHandlerStatusMessageSenderUtil.sendStatusMessage(
1051                                    "portlet", portletId, manifestSummary);
1052                    }
1053    
1054                    Document document = SAXReaderUtil.createDocument();
1055    
1056                    Element portletElement = document.addElement("portlet");
1057    
1058                    portletElement.addAttribute("portlet-id", portletId);
1059                    portletElement.addAttribute("root-portlet-id", rootPortletId);
1060                    portletElement.addAttribute("old-plid", String.valueOf(plid));
1061                    portletElement.addAttribute(
1062                            "scope-layout-type", portletDataContext.getScopeType());
1063                    portletElement.addAttribute(
1064                            "scope-layout-uuid", portletDataContext.getScopeLayoutUuid());
1065                    portletElement.addAttribute(
1066                            "private-layout", String.valueOf(layout.isPrivateLayout()));
1067    
1068                    // Data
1069    
1070                    if (exportPortletData) {
1071                            javax.portlet.PortletPreferences jxPortletPreferences =
1072                                    PortletPreferencesFactoryUtil.getStrictPortletSetup(
1073                                            layout, portletId);
1074    
1075                            exportPortletData(
1076                                    portletDataContext, portlet, layout, jxPortletPreferences,
1077                                    portletElement);
1078                    }
1079    
1080                    // Portlet preferences
1081    
1082                    if (exportPortletSetup) {
1083    
1084                            // Company
1085    
1086                            exportPortletPreferences(
1087                                    portletDataContext, portletDataContext.getCompanyId(),
1088                                    PortletKeys.PREFS_OWNER_TYPE_COMPANY, false, layout, plid,
1089                                    portlet.getRootPortletId(), portletElement);
1090    
1091                            // Group
1092    
1093                            exportPortletPreferences(
1094                                    portletDataContext, portletDataContext.getScopeGroupId(),
1095                                    PortletKeys.PREFS_OWNER_TYPE_GROUP, false, layout,
1096                                    PortletKeys.PREFS_PLID_SHARED, portlet.getRootPortletId(),
1097                                    portletElement);
1098    
1099                            // Layout
1100    
1101                            exportPortletPreferences(
1102                                    portletDataContext, PortletKeys.PREFS_OWNER_ID_DEFAULT,
1103                                    PortletKeys.PREFS_OWNER_TYPE_LAYOUT, false, layout, plid,
1104                                    portletId, portletElement);
1105                    }
1106    
1107                    // Portlet user preferences
1108    
1109                    if (exportPortletUserPreferences) {
1110                            List<PortletPreferences> portletPreferencesList =
1111                                    PortletPreferencesLocalServiceUtil.getPortletPreferences(
1112                                            PortletKeys.PREFS_OWNER_TYPE_USER, plid, portletId);
1113    
1114                            for (PortletPreferences portletPreferences :
1115                                            portletPreferencesList) {
1116    
1117                                    boolean defaultUser = false;
1118    
1119                                    if (portletPreferences.getOwnerId() ==
1120                                                    PortletKeys.PREFS_OWNER_ID_DEFAULT) {
1121    
1122                                            defaultUser = true;
1123                                    }
1124    
1125                                    exportPortletPreferences(
1126                                            portletDataContext, portletPreferences.getOwnerId(),
1127                                            PortletKeys.PREFS_OWNER_TYPE_USER, defaultUser, layout,
1128                                            plid, portletId, portletElement);
1129                            }
1130    
1131                            try {
1132                                    PortletPreferences groupPortletPreferences =
1133                                            PortletPreferencesLocalServiceUtil.getPortletPreferences(
1134                                                    portletDataContext.getScopeGroupId(),
1135                                                    PortletKeys.PREFS_OWNER_TYPE_GROUP,
1136                                                    PortletKeys.PREFS_PLID_SHARED,
1137                                                    portlet.getRootPortletId());
1138    
1139                                    exportPortletPreference(
1140                                            portletDataContext, portletDataContext.getScopeGroupId(),
1141                                            PortletKeys.PREFS_OWNER_TYPE_GROUP, false,
1142                                            groupPortletPreferences, portlet.getRootPortletId(),
1143                                            PortletKeys.PREFS_PLID_SHARED, portletElement);
1144                            }
1145                            catch (NoSuchPortletPreferencesException nsppe) {
1146                            }
1147                    }
1148    
1149                    // Archived setups
1150    
1151                    if (exportPortletArchivedSetups) {
1152                            List<PortletItem> portletItems =
1153                                    PortletItemLocalServiceUtil.getPortletItems(
1154                                            portletDataContext.getGroupId(), rootPortletId,
1155                                            PortletPreferences.class.getName());
1156    
1157                            for (PortletItem portletItem : portletItems) {
1158                                    exportPortletPreferences(
1159                                            portletDataContext, portletItem.getPortletItemId(),
1160                                            PortletKeys.PREFS_OWNER_TYPE_ARCHIVED, false, null, plid,
1161                                            portletItem.getPortletId(), portletElement);
1162                            }
1163                    }
1164    
1165                    // Permissions
1166    
1167                    if (exportPermissions) {
1168                            _permissionExporter.exportPortletPermissions(
1169                                    portletDataContext, layoutCache, portletId, layout,
1170                                    portletElement);
1171                    }
1172    
1173                    // Zip
1174    
1175                    StringBundler pathSB = new StringBundler(4);
1176    
1177                    pathSB.append(
1178                            ExportImportPathUtil.getPortletPath(portletDataContext, portletId));
1179                    pathSB.append(StringPool.SLASH);
1180                    pathSB.append(plid);
1181                    pathSB.append("/portlet.xml");
1182    
1183                    String path = pathSB.toString();
1184    
1185                    Element element = parentElement.addElement("portlet");
1186    
1187                    element.addAttribute("portlet-id", portletId);
1188                    element.addAttribute("layout-id", String.valueOf(layoutId));
1189                    element.addAttribute("path", path);
1190                    element.addAttribute("portlet-data", String.valueOf(exportPortletData));
1191    
1192                    StringBundler configurationOptionsSB = new StringBundler(6);
1193    
1194                    if (exportPortletSetup) {
1195                            configurationOptionsSB.append("setup");
1196                            configurationOptionsSB.append(StringPool.COMMA);
1197                    }
1198    
1199                    if (exportPortletArchivedSetups) {
1200                            configurationOptionsSB.append("archived-setups");
1201                            configurationOptionsSB.append(StringPool.COMMA);
1202                    }
1203    
1204                    if (exportPortletUserPreferences) {
1205                            configurationOptionsSB.append("user-preferences");
1206                            configurationOptionsSB.append(StringPool.COMMA);
1207                    }
1208    
1209                    if (configurationOptionsSB.index() > 0) {
1210                            configurationOptionsSB.setIndex(configurationOptionsSB.index() -1);
1211                    }
1212    
1213                    element.addAttribute(
1214                            "portlet-configuration", configurationOptionsSB.toString());
1215    
1216                    if (portletDataContext.isPathNotProcessed(path)) {
1217                            try {
1218                                    portletDataContext.addZipEntry(
1219                                            path, document.formattedString());
1220                            }
1221                            catch (IOException ioe) {
1222                                    if (_log.isWarnEnabled()) {
1223                                            _log.warn(ioe.getMessage());
1224                                    }
1225                            }
1226    
1227                            portletDataContext.addPrimaryKey(String.class, path);
1228                    }
1229    
1230                    portletDataContext.setRootPortletId(StringPool.BLANK);
1231            }
1232    
1233            protected void exportPortletPreference(
1234                            PortletDataContext portletDataContext, long ownerId, int ownerType,
1235                            boolean defaultUser, PortletPreferences portletPreferences,
1236                            String portletId, long plid, Element parentElement)
1237                    throws Exception {
1238    
1239                    String preferencesXML = portletPreferences.getPreferences();
1240    
1241                    if (Validator.isNull(preferencesXML)) {
1242                            preferencesXML = PortletConstants.DEFAULT_PREFERENCES;
1243                    }
1244    
1245                    javax.portlet.PortletPreferences jxPortletPreferences =
1246                            PortletPreferencesFactoryUtil.fromDefaultXML(preferencesXML);
1247    
1248                    Portlet portlet = PortletLocalServiceUtil.getPortletById(
1249                            portletDataContext.getCompanyId(), portletId);
1250    
1251                    Element portletPreferencesElement = parentElement.addElement(
1252                            "portlet-preferences");
1253    
1254                    if ((portlet != null) &&
1255                            (portlet.getPortletDataHandlerInstance() != null)) {
1256    
1257                            Element exportDataRootElement =
1258                                    portletDataContext.getExportDataRootElement();
1259    
1260                            try {
1261                                    portletDataContext.clearScopedPrimaryKeys();
1262    
1263                                    Element preferenceDataElement =
1264                                            portletPreferencesElement.addElement("preference-data");
1265    
1266                                    portletDataContext.setExportDataRootElement(
1267                                            preferenceDataElement);
1268    
1269                                    PortletDataHandler portletDataHandler =
1270                                            portlet.getPortletDataHandlerInstance();
1271    
1272                                    jxPortletPreferences =
1273                                            portletDataHandler.processExportPortletPreferences(
1274                                                    portletDataContext, portletId, jxPortletPreferences);
1275                            }
1276                            finally {
1277                                    portletDataContext.setExportDataRootElement(
1278                                            exportDataRootElement);
1279                            }
1280                    }
1281    
1282                    Document document = SAXReaderUtil.read(
1283                            PortletPreferencesFactoryUtil.toXML(jxPortletPreferences));
1284    
1285                    Element rootElement = document.getRootElement();
1286    
1287                    rootElement.addAttribute("owner-id", String.valueOf(ownerId));
1288                    rootElement.addAttribute("owner-type", String.valueOf(ownerType));
1289                    rootElement.addAttribute("default-user", String.valueOf(defaultUser));
1290                    rootElement.addAttribute("plid", String.valueOf(plid));
1291                    rootElement.addAttribute("portlet-id", portletId);
1292    
1293                    if (ownerType == PortletKeys.PREFS_OWNER_TYPE_ARCHIVED) {
1294                            PortletItem portletItem =
1295                                    PortletItemLocalServiceUtil.getPortletItem(ownerId);
1296    
1297                            rootElement.addAttribute(
1298                                    "archive-user-uuid", portletItem.getUserUuid());
1299                            rootElement.addAttribute("archive-name", portletItem.getName());
1300                    }
1301                    else if (ownerType == PortletKeys.PREFS_OWNER_TYPE_USER) {
1302                            User user = UserLocalServiceUtil.fetchUserById(ownerId);
1303    
1304                            if (user == null) {
1305                                    return;
1306                            }
1307    
1308                            rootElement.addAttribute("user-uuid", user.getUserUuid());
1309                    }
1310    
1311                    List<Node> nodes = document.selectNodes(
1312                            "/portlet-preferences/preference[name/text() = " +
1313                                    "'last-publish-date']");
1314    
1315                    for (Node node : nodes) {
1316                            document.remove(node);
1317                    }
1318    
1319                    String path = getPortletPreferencesPath(
1320                            portletDataContext, portletId, ownerId, ownerType, plid);
1321    
1322                    portletPreferencesElement.addAttribute("path", path);
1323    
1324                    if (portletDataContext.isPathNotProcessed(path)) {
1325                            portletDataContext.addZipEntry(
1326                                    path, document.formattedString(StringPool.TAB, false, false));
1327                    }
1328            }
1329    
1330            protected void exportPortletPreferences(
1331                            PortletDataContext portletDataContext, long ownerId, int ownerType,
1332                            boolean defaultUser, Layout layout, long plid, String portletId,
1333                            Element parentElement)
1334                    throws Exception {
1335    
1336                    PortletPreferences portletPreferences = null;
1337    
1338                    try {
1339                            if ((ownerType == PortletKeys.PREFS_OWNER_TYPE_COMPANY) ||
1340                                    (ownerType == PortletKeys.PREFS_OWNER_TYPE_GROUP) ||
1341                                    (ownerType == PortletKeys.PREFS_OWNER_TYPE_ARCHIVED)) {
1342    
1343                                    portletPreferences =
1344                                            PortletPreferencesLocalServiceUtil.getPortletPreferences(
1345                                                    ownerId, ownerType, LayoutConstants.DEFAULT_PLID,
1346                                                    portletId);
1347                            }
1348                            else {
1349                                    portletPreferences =
1350                                            PortletPreferencesLocalServiceUtil.getPortletPreferences(
1351                                                    ownerId, ownerType, plid, portletId);
1352                            }
1353                    }
1354                    catch (NoSuchPortletPreferencesException nsppe) {
1355                            return;
1356                    }
1357    
1358                    LayoutTypePortlet layoutTypePortlet = null;
1359    
1360                    if (layout != null) {
1361                            layoutTypePortlet = (LayoutTypePortlet)layout.getLayoutType();
1362                    }
1363    
1364                    if ((layoutTypePortlet == null) ||
1365                            layoutTypePortlet.hasPortletId(portletId)) {
1366    
1367                            exportPortletPreference(
1368                                    portletDataContext, ownerId, ownerType, defaultUser,
1369                                    portletPreferences, portletId, plid, parentElement);
1370                    }
1371            }
1372    
1373            protected void exportRatingsEntries(
1374                            PortletDataContext portletDataContext, Element parentElement)
1375                    throws Exception {
1376    
1377                    Document document = SAXReaderUtil.createDocument();
1378    
1379                    Element rootElement = document.addElement("ratings");
1380    
1381                    Map<String, List<RatingsEntry>> ratingsEntriesMap =
1382                            portletDataContext.getRatingsEntries();
1383    
1384                    for (Map.Entry<String, List<RatingsEntry>> entry :
1385                                    ratingsEntriesMap.entrySet()) {
1386    
1387                            String[] ratingsEntryParts = StringUtil.split(
1388                                    entry.getKey(), CharPool.POUND);
1389    
1390                            String className = ratingsEntryParts[0];
1391                            String classPK = ratingsEntryParts[1];
1392    
1393                            String ratingsEntriesPath = getRatingsEntriesPath(
1394                                    portletDataContext, className, classPK);
1395    
1396                            Element assetElement = rootElement.addElement("asset");
1397    
1398                            assetElement.addAttribute("path", ratingsEntriesPath);
1399                            assetElement.addAttribute("class-name", className);
1400                            assetElement.addAttribute("class-pk", classPK);
1401    
1402                            List<RatingsEntry> ratingsEntries = entry.getValue();
1403    
1404                            for (RatingsEntry ratingsEntry : ratingsEntries) {
1405                                    String ratingsEntryPath = getRatingsEntryPath(
1406                                            portletDataContext, className, classPK, ratingsEntry);
1407    
1408                                    User user = UserLocalServiceUtil.fetchUser(
1409                                            ratingsEntry.getUserId());
1410    
1411                                    if (user == null) {
1412                                            continue;
1413                                    }
1414    
1415                                    portletDataContext.addZipEntry(ratingsEntryPath, ratingsEntry);
1416    
1417                                    portletDataContext.addReferenceElement(
1418                                            ratingsEntry, assetElement, user,
1419                                            PortletDataContext.REFERENCE_TYPE_WEAK, true);
1420                            }
1421                    }
1422    
1423                    portletDataContext.addZipEntry(
1424                            ExportImportPathUtil.getRootPath(portletDataContext) +
1425                                    "/ratings.xml",
1426                            document.formattedString());
1427            }
1428    
1429            protected String getAssetCategoryPath(
1430                    PortletDataContext portletDataContext, long assetCategoryId) {
1431    
1432                    StringBundler sb = new StringBundler(4);
1433    
1434                    sb.append(ExportImportPathUtil.getRootPath(portletDataContext));
1435                    sb.append("/categories/");
1436                    sb.append(assetCategoryId);
1437                    sb.append(".xml");
1438    
1439                    return sb.toString();
1440            }
1441    
1442            protected String getAssetLinkPath(
1443                    PortletDataContext portletDataContext, long assetLinkId) {
1444    
1445                    StringBundler sb = new StringBundler(4);
1446    
1447                    sb.append(ExportImportPathUtil.getRootPath(portletDataContext));
1448                    sb.append("/links/");
1449                    sb.append(assetLinkId);
1450                    sb.append(".xml");
1451    
1452                    return sb.toString();
1453            }
1454    
1455            protected String getAssetTagPath(
1456                    PortletDataContext portletDataContext, long assetCategoryId) {
1457    
1458                    StringBundler sb = new StringBundler(4);
1459    
1460                    sb.append(ExportImportPathUtil.getRootPath(portletDataContext));
1461                    sb.append("/tags/");
1462                    sb.append(assetCategoryId);
1463                    sb.append(".xml");
1464    
1465                    return sb.toString();
1466            }
1467    
1468            protected String getAssetVocabulariesPath(
1469                    PortletDataContext portletDataContext, long assetVocabularyId) {
1470    
1471                    StringBundler sb = new StringBundler(4);
1472    
1473                    sb.append(ExportImportPathUtil.getRootPath(portletDataContext));
1474                    sb.append("/vocabularies/");
1475                    sb.append(assetVocabularyId);
1476                    sb.append(".xml");
1477    
1478                    return sb.toString();
1479            }
1480    
1481            protected String getCommentPath(
1482                    PortletDataContext portletDataContext, String className, String classPK,
1483                    MBMessage mbMessage) {
1484    
1485                    StringBundler sb = new StringBundler(8);
1486    
1487                    sb.append(ExportImportPathUtil.getRootPath(portletDataContext));
1488                    sb.append("/comments/");
1489                    sb.append(PortalUtil.getClassNameId(className));
1490                    sb.append(CharPool.FORWARD_SLASH);
1491                    sb.append(classPK);
1492                    sb.append(CharPool.FORWARD_SLASH);
1493                    sb.append(mbMessage.getMessageId());
1494                    sb.append(".xml");
1495    
1496                    return sb.toString();
1497            }
1498    
1499            protected String getCommentsPath(
1500                    PortletDataContext portletDataContext, String className,
1501                    String classPK) {
1502    
1503                    StringBundler sb = new StringBundler(6);
1504    
1505                    sb.append(ExportImportPathUtil.getRootPath(portletDataContext));
1506                    sb.append("/comments/");
1507                    sb.append(PortalUtil.getClassNameId(className));
1508                    sb.append(CharPool.FORWARD_SLASH);
1509                    sb.append(classPK);
1510                    sb.append(CharPool.FORWARD_SLASH);
1511    
1512                    return sb.toString();
1513            }
1514    
1515            protected String getLockPath(
1516                    PortletDataContext portletDataContext, String className, String key,
1517                    Lock lock) {
1518    
1519                    StringBundler sb = new StringBundler(8);
1520    
1521                    sb.append(ExportImportPathUtil.getRootPath(portletDataContext));
1522                    sb.append("/locks/");
1523                    sb.append(PortalUtil.getClassNameId(className));
1524                    sb.append(CharPool.FORWARD_SLASH);
1525                    sb.append(key);
1526                    sb.append(CharPool.FORWARD_SLASH);
1527                    sb.append(lock.getLockId());
1528                    sb.append(".xml");
1529    
1530                    return sb.toString();
1531            }
1532    
1533            protected String getPortletPreferencesPath(
1534                    PortletDataContext portletDataContext, String portletId, long ownerId,
1535                    int ownerType, long plid) {
1536    
1537                    StringBundler sb = new StringBundler(8);
1538    
1539                    sb.append(
1540                            ExportImportPathUtil.getPortletPath(portletDataContext, portletId));
1541                    sb.append("/preferences/");
1542    
1543                    if (ownerType == PortletKeys.PREFS_OWNER_TYPE_COMPANY) {
1544                            sb.append("company/");
1545                    }
1546                    else if (ownerType == PortletKeys.PREFS_OWNER_TYPE_GROUP) {
1547                            sb.append("group/");
1548                    }
1549                    else if (ownerType == PortletKeys.PREFS_OWNER_TYPE_LAYOUT) {
1550                            sb.append("layout/");
1551                    }
1552                    else if (ownerType == PortletKeys.PREFS_OWNER_TYPE_USER) {
1553                            sb.append("user/");
1554                    }
1555                    else if (ownerType == PortletKeys.PREFS_OWNER_TYPE_ARCHIVED) {
1556                            sb.append("archived/");
1557                    }
1558    
1559                    sb.append(ownerId);
1560                    sb.append(CharPool.FORWARD_SLASH);
1561                    sb.append(plid);
1562                    sb.append(CharPool.FORWARD_SLASH);
1563                    sb.append("portlet-preferences.xml");
1564    
1565                    return sb.toString();
1566            }
1567    
1568            protected String getRatingsEntriesPath(
1569                    PortletDataContext portletDataContext, String className,
1570                    String classPK) {
1571    
1572                    StringBundler sb = new StringBundler(6);
1573    
1574                    sb.append(ExportImportPathUtil.getRootPath(portletDataContext));
1575                    sb.append("/ratings/");
1576                    sb.append(PortalUtil.getClassNameId(className));
1577                    sb.append(CharPool.FORWARD_SLASH);
1578                    sb.append(classPK);
1579                    sb.append(CharPool.FORWARD_SLASH);
1580    
1581                    return sb.toString();
1582            }
1583    
1584            protected String getRatingsEntryPath(
1585                    PortletDataContext portletDataContext, String className, String classPK,
1586                    RatingsEntry ratingsEntry) {
1587    
1588                    StringBundler sb = new StringBundler(8);
1589    
1590                    sb.append(ExportImportPathUtil.getRootPath(portletDataContext));
1591                    sb.append("/ratings/");
1592                    sb.append(PortalUtil.getClassNameId(className));
1593                    sb.append(CharPool.FORWARD_SLASH);
1594                    sb.append(classPK);
1595                    sb.append(CharPool.FORWARD_SLASH);
1596                    sb.append(ratingsEntry.getEntryId());
1597                    sb.append(".xml");
1598    
1599                    return sb.toString();
1600            }
1601    
1602            private static Log _log = LogFactoryUtil.getLog(PortletExporter.class);
1603    
1604            private DeletionSystemEventExporter _deletionSystemEventExporter =
1605                    new DeletionSystemEventExporter();
1606            private PermissionExporter _permissionExporter = new PermissionExporter();
1607    
1608            private class UpdatePortletLastPublishDateCallable
1609                    implements Callable<Void> {
1610    
1611                    public UpdatePortletLastPublishDateCallable(
1612                            DateRange dateRange, Date endDate, long groupId, long plid,
1613                            String portletId) {
1614    
1615                            _dateRange = dateRange;
1616                            _endDate = endDate;
1617                            _groupId = groupId;
1618                            _plid = plid;
1619                            _portletId = portletId;
1620                    }
1621    
1622                    @Override
1623                    public Void call() throws Exception {
1624                            Group group = GroupLocalServiceUtil.getGroup(_groupId);
1625    
1626                            if (group.isStagedRemotely()) {
1627                                    return null;
1628                            }
1629    
1630                            Layout layout = LayoutLocalServiceUtil.fetchLayout(_plid);
1631    
1632                            if (ExportImportThreadLocal.isStagingInProcess() &&
1633                                    group.hasStagingGroup()) {
1634    
1635                                    group = group.getStagingGroup();
1636    
1637                                    if (layout != null) {
1638                                            layout = LayoutLocalServiceUtil.fetchLayoutByUuidAndGroupId(
1639                                                    layout.getUuid(), group.getGroupId(),
1640                                                    layout.isPrivateLayout());
1641                                    }
1642                            }
1643    
1644                            if (layout == null) {
1645                                    layout = new LayoutImpl();
1646    
1647                                    layout.setCompanyId(group.getCompanyId());
1648                                    layout.setGroupId(group.getGroupId());
1649                            }
1650    
1651                            javax.portlet.PortletPreferences jxPortletPreferences =
1652                                    PortletPreferencesFactoryUtil.getStrictPortletSetup(
1653                                            layout, _portletId);
1654    
1655                            StagingUtil.updateLastPublishDate(
1656                                    _portletId, jxPortletPreferences, _dateRange, _endDate);
1657    
1658                            return null;
1659                    }
1660    
1661                    private final DateRange _dateRange;
1662                    private final Date _endDate;
1663                    private final long _groupId;
1664                    private final long _plid;
1665                    private final String _portletId;
1666    
1667            }
1668    
1669    }