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