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