001    /**
002     * Copyright (c) 2000-2013 Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
013     */
014    
015    package com.liferay.portal.lar;
016    
017    import com.liferay.portal.kernel.language.LanguageUtil;
018    import com.liferay.portal.kernel.lar.ExportImportHelperUtil;
019    import com.liferay.portal.kernel.lar.ExportImportPathUtil;
020    import com.liferay.portal.kernel.lar.ExportImportThreadLocal;
021    import com.liferay.portal.kernel.lar.PortletDataContext;
022    import com.liferay.portal.kernel.lar.PortletDataContextFactoryUtil;
023    import com.liferay.portal.kernel.lar.PortletDataHandler;
024    import com.liferay.portal.kernel.lar.PortletDataHandlerControl;
025    import com.liferay.portal.kernel.lar.PortletDataHandlerKeys;
026    import com.liferay.portal.kernel.lar.StagedModelDataHandlerUtil;
027    import com.liferay.portal.kernel.lar.StagedModelType;
028    import com.liferay.portal.kernel.log.Log;
029    import com.liferay.portal.kernel.log.LogFactoryUtil;
030    import com.liferay.portal.kernel.util.ArrayUtil;
031    import com.liferay.portal.kernel.util.Constants;
032    import com.liferay.portal.kernel.util.FileUtil;
033    import com.liferay.portal.kernel.util.GetterUtil;
034    import com.liferay.portal.kernel.util.LocaleUtil;
035    import com.liferay.portal.kernel.util.MapUtil;
036    import com.liferay.portal.kernel.util.ReleaseInfo;
037    import com.liferay.portal.kernel.util.StringPool;
038    import com.liferay.portal.kernel.util.StringUtil;
039    import com.liferay.portal.kernel.util.Time;
040    import com.liferay.portal.kernel.util.UnicodeProperties;
041    import com.liferay.portal.kernel.util.Validator;
042    import com.liferay.portal.kernel.xml.Document;
043    import com.liferay.portal.kernel.xml.Element;
044    import com.liferay.portal.kernel.xml.SAXReaderUtil;
045    import com.liferay.portal.kernel.zip.ZipWriter;
046    import com.liferay.portal.kernel.zip.ZipWriterFactoryUtil;
047    import com.liferay.portal.model.Group;
048    import com.liferay.portal.model.Image;
049    import com.liferay.portal.model.Layout;
050    import com.liferay.portal.model.LayoutConstants;
051    import com.liferay.portal.model.LayoutPrototype;
052    import com.liferay.portal.model.LayoutSet;
053    import com.liferay.portal.model.LayoutSetBranch;
054    import com.liferay.portal.model.LayoutSetPrototype;
055    import com.liferay.portal.model.LayoutTypePortlet;
056    import com.liferay.portal.model.Portlet;
057    import com.liferay.portal.model.impl.LayoutImpl;
058    import com.liferay.portal.service.GroupLocalServiceUtil;
059    import com.liferay.portal.service.ImageLocalServiceUtil;
060    import com.liferay.portal.service.LayoutLocalServiceUtil;
061    import com.liferay.portal.service.LayoutPrototypeLocalServiceUtil;
062    import com.liferay.portal.service.LayoutSetBranchLocalServiceUtil;
063    import com.liferay.portal.service.LayoutSetLocalServiceUtil;
064    import com.liferay.portal.service.LayoutSetPrototypeLocalServiceUtil;
065    import com.liferay.portal.service.PortletLocalServiceUtil;
066    import com.liferay.portal.service.ServiceContext;
067    import com.liferay.portal.service.ServiceContextThreadLocal;
068    import com.liferay.portal.service.UserLocalServiceUtil;
069    import com.liferay.portal.service.permission.PortletPermissionUtil;
070    import com.liferay.portlet.PortletPreferencesFactoryUtil;
071    import com.liferay.portlet.asset.model.AssetCategory;
072    import com.liferay.portlet.asset.model.AssetVocabulary;
073    import com.liferay.portlet.asset.service.AssetVocabularyLocalServiceUtil;
074    import com.liferay.portlet.asset.service.persistence.AssetCategoryUtil;
075    
076    import java.io.File;
077    
078    import java.util.ArrayList;
079    import java.util.Date;
080    import java.util.HashSet;
081    import java.util.Iterator;
082    import java.util.LinkedHashMap;
083    import java.util.List;
084    import java.util.Map;
085    import java.util.Set;
086    
087    import org.apache.commons.lang.time.StopWatch;
088    
089    /**
090     * @author Brian Wing Shun Chan
091     * @author Joel Kozikowski
092     * @author Charles May
093     * @author Raymond Aug??
094     * @author Jorge Ferrer
095     * @author Bruno Farache
096     * @author Karthik Sudarshan
097     * @author Zsigmond Rab
098     * @author Douglas Wong
099     * @author Mate Thurzo
100     */
101    public class LayoutExporter {
102    
103            public static final String SAME_GROUP_FRIENDLY_URL =
104                    "/[$SAME_GROUP_FRIENDLY_URL$]";
105    
106            public static List<Portlet> getDataSiteLevelPortlets(long companyId)
107                    throws Exception {
108    
109                    List<Portlet> portlets = PortletLocalServiceUtil.getPortlets(companyId);
110    
111                    Iterator<Portlet> itr = portlets.iterator();
112    
113                    while (itr.hasNext()) {
114                            Portlet portlet = itr.next();
115    
116                            if (!portlet.isActive()) {
117                                    itr.remove();
118    
119                                    continue;
120                            }
121    
122                            PortletDataHandler portletDataHandler =
123                                    portlet.getPortletDataHandlerInstance();
124    
125                            if ((portletDataHandler == null) ||
126                                    !portletDataHandler.isDataSiteLevel()) {
127    
128                                    itr.remove();
129                            }
130                    }
131    
132                    return portlets;
133            }
134    
135            public static List<Portlet> getPortletDataHandlerPortlets(
136                            List<Layout> layouts)
137                    throws Exception {
138    
139                    List<Portlet> portlets = new ArrayList<Portlet>();
140                    Set<String> rootPortletIds = new HashSet<String>();
141    
142                    for (Layout layout : layouts) {
143                            if (!layout.isTypePortlet()) {
144                                    continue;
145                            }
146    
147                            LayoutTypePortlet layoutTypePortlet =
148                                    (LayoutTypePortlet)layout.getLayoutType();
149    
150                            for (String portletId : layoutTypePortlet.getPortletIds()) {
151                                    Portlet portlet = PortletLocalServiceUtil.getPortletById(
152                                            layout.getCompanyId(), portletId);
153    
154                                    if ((portlet == null) ||
155                                            rootPortletIds.contains(portlet.getRootPortletId())) {
156    
157                                            continue;
158                                    }
159    
160                                    PortletDataHandler portletDataHandler =
161                                            portlet.getPortletDataHandlerInstance();
162    
163                                    if (portletDataHandler == null) {
164                                            continue;
165                                    }
166    
167                                    PortletDataHandlerControl[] portletDataHandlerControls =
168                                            portletDataHandler.getExportConfigurationControls(
169                                                    layout.getCompanyId(), layout.getGroupId(), portlet,
170                                                    layout.getPlid(), layout.getPrivateLayout());
171    
172                                    if (ArrayUtil.isNotEmpty(portletDataHandlerControls)) {
173                                            rootPortletIds.add(portlet.getRootPortletId());
174    
175                                            portlets.add(portlet);
176                                    }
177                            }
178                    }
179    
180                    return portlets;
181            }
182    
183            public static List<Portlet> getPortletDataHandlerPortlets(
184                            long groupId, boolean privateLayout)
185                    throws Exception {
186    
187                    return getPortletDataHandlerPortlets(
188                            LayoutLocalServiceUtil.getLayouts(groupId, privateLayout));
189            }
190    
191            public static void updateLastPublishDate(
192                            LayoutSet layoutSet, long lastPublishDate)
193                    throws Exception {
194    
195                    UnicodeProperties settingsProperties =
196                            layoutSet.getSettingsProperties();
197    
198                    if (lastPublishDate <= 0) {
199                            settingsProperties.remove("last-publish-date");
200                    }
201                    else {
202                            settingsProperties.setProperty(
203                                    "last-publish-date", String.valueOf(lastPublishDate));
204                    }
205    
206                    LayoutSetLocalServiceUtil.updateSettings(
207                            layoutSet.getGroupId(), layoutSet.isPrivateLayout(),
208                            settingsProperties.toString());
209            }
210    
211            public byte[] exportLayouts(
212                            long groupId, boolean privateLayout, long[] layoutIds,
213                            Map<String, String[]> parameterMap, Date startDate, Date endDate)
214                    throws Exception {
215    
216                    File file = exportLayoutsAsFile(
217                            groupId, privateLayout, layoutIds, parameterMap, startDate,
218                            endDate);
219    
220                    try {
221                            return FileUtil.getBytes(file);
222                    }
223                    finally {
224                            file.delete();
225                    }
226            }
227    
228            public File exportLayoutsAsFile(
229                            long groupId, boolean privateLayout, long[] layoutIds,
230                            Map<String, String[]> parameterMap, Date startDate, Date endDate)
231                    throws Exception {
232    
233                    try {
234                            ExportImportThreadLocal.setLayoutExportInProcess(true);
235    
236                            return doExportLayoutsAsFile(
237                                    groupId, privateLayout, layoutIds, parameterMap, startDate,
238                                    endDate);
239                    }
240                    finally {
241                            ExportImportThreadLocal.setLayoutExportInProcess(false);
242                    }
243            }
244    
245            protected File doExportLayoutsAsFile(
246                            long groupId, boolean privateLayout, long[] layoutIds,
247                            Map<String, String[]> parameterMap, Date startDate, Date endDate)
248                    throws Exception {
249    
250                    boolean exportCategories = MapUtil.getBoolean(
251                            parameterMap, PortletDataHandlerKeys.CATEGORIES);
252                    boolean exportIgnoreLastPublishDate = MapUtil.getBoolean(
253                            parameterMap, PortletDataHandlerKeys.IGNORE_LAST_PUBLISH_DATE);
254                    boolean exportPermissions = MapUtil.getBoolean(
255                            parameterMap, PortletDataHandlerKeys.PERMISSIONS);
256                    boolean exportPortletDataAll = MapUtil.getBoolean(
257                            parameterMap, PortletDataHandlerKeys.PORTLET_DATA_ALL);
258                    boolean exportLogo = MapUtil.getBoolean(
259                            parameterMap, PortletDataHandlerKeys.LOGO);
260                    boolean exportLayoutSetSettings = MapUtil.getBoolean(
261                            parameterMap, PortletDataHandlerKeys.LAYOUT_SET_SETTINGS);
262                    boolean updateLastPublishDate = MapUtil.getBoolean(
263                            parameterMap, PortletDataHandlerKeys.UPDATE_LAST_PUBLISH_DATE);
264    
265                    if (_log.isDebugEnabled()) {
266                            _log.debug("Export permissions " + exportPermissions);
267                    }
268    
269                    LayoutSet layoutSet = LayoutSetLocalServiceUtil.getLayoutSet(
270                            groupId, privateLayout);
271    
272                    long companyId = layoutSet.getCompanyId();
273                    long defaultUserId = UserLocalServiceUtil.getDefaultUserId(companyId);
274    
275                    ServiceContext serviceContext =
276                            ServiceContextThreadLocal.getServiceContext();
277    
278                    if (serviceContext == null) {
279                            serviceContext = new ServiceContext();
280    
281                            serviceContext.setCompanyId(companyId);
282                            serviceContext.setSignedIn(false);
283                            serviceContext.setUserId(defaultUserId);
284    
285                            ServiceContextThreadLocal.pushServiceContext(serviceContext);
286                    }
287    
288                    serviceContext.setAttribute("exporting", Boolean.TRUE);
289    
290                    long layoutSetBranchId = MapUtil.getLong(
291                            parameterMap, "layoutSetBranchId");
292    
293                    serviceContext.setAttribute("layoutSetBranchId", layoutSetBranchId);
294    
295                    long lastPublishDate = System.currentTimeMillis();
296    
297                    if (endDate != null) {
298                            lastPublishDate = endDate.getTime();
299                    }
300    
301                    if (exportIgnoreLastPublishDate) {
302                            endDate = null;
303                            startDate = null;
304                    }
305    
306                    StopWatch stopWatch = null;
307    
308                    if (_log.isInfoEnabled()) {
309                            stopWatch = new StopWatch();
310    
311                            stopWatch.start();
312                    }
313    
314                    LayoutCache layoutCache = new LayoutCache();
315    
316                    ZipWriter zipWriter = ZipWriterFactoryUtil.getZipWriter();
317    
318                    PortletDataContext portletDataContext =
319                            PortletDataContextFactoryUtil.createExportPortletDataContext(
320                                    companyId, groupId, parameterMap, startDate, endDate,
321                                    zipWriter);
322    
323                    portletDataContext.setPortetDataContextListener(
324                            new PortletDataContextListenerImpl(portletDataContext));
325    
326                    Document document = SAXReaderUtil.createDocument();
327    
328                    Element rootElement = document.addElement("root");
329    
330                    portletDataContext.setExportDataRootElement(rootElement);
331    
332                    Element headerElement = rootElement.addElement("header");
333    
334                    headerElement.addAttribute(
335                            "available-locales",
336                            StringUtil.merge(
337                                    LanguageUtil.getAvailableLocales(
338                                            portletDataContext.getScopeGroupId())));
339                    headerElement.addAttribute(
340                            "build-number", String.valueOf(ReleaseInfo.getBuildNumber()));
341                    headerElement.addAttribute("export-date", Time.getRFC822());
342    
343                    if (portletDataContext.hasDateRange()) {
344                            headerElement.addAttribute(
345                                    "start-date",
346                                    String.valueOf(portletDataContext.getStartDate()));
347                            headerElement.addAttribute(
348                                    "end-date", String.valueOf(portletDataContext.getEndDate()));
349                    }
350    
351                    headerElement.addAttribute(
352                            "company-id", String.valueOf(portletDataContext.getCompanyId()));
353                    headerElement.addAttribute(
354                            "company-group-id",
355                            String.valueOf(portletDataContext.getCompanyGroupId()));
356                    headerElement.addAttribute("group-id", String.valueOf(groupId));
357                    headerElement.addAttribute(
358                            "user-personal-site-group-id",
359                            String.valueOf(portletDataContext.getUserPersonalSiteGroupId()));
360                    headerElement.addAttribute(
361                            "private-layout", String.valueOf(privateLayout));
362    
363                    Group group = layoutSet.getGroup();
364    
365                    String type = "layout-set";
366    
367                    if (group.isLayoutPrototype()) {
368                            type = "layout-prototype";
369    
370                            LayoutPrototype layoutPrototype =
371                                    LayoutPrototypeLocalServiceUtil.getLayoutPrototype(
372                                            group.getClassPK());
373    
374                            headerElement.addAttribute("type-uuid", layoutPrototype.getUuid());
375                    }
376                    else if (group.isLayoutSetPrototype()) {
377                            type ="layout-set-prototype";
378    
379                            LayoutSetPrototype layoutSetPrototype =
380                                    LayoutSetPrototypeLocalServiceUtil.getLayoutSetPrototype(
381                                            group.getClassPK());
382    
383                            headerElement.addAttribute(
384                                    "type-uuid", layoutSetPrototype.getUuid());
385                    }
386    
387                    headerElement.addAttribute("type", type);
388    
389                    LayoutSetBranch layoutSetBranch =
390                            LayoutSetBranchLocalServiceUtil.fetchLayoutSetBranch(
391                                    layoutSetBranchId);
392    
393                    if (exportLogo) {
394                            Image image = null;
395    
396                            if (layoutSetBranch != null) {
397                                    image = ImageLocalServiceUtil.getImage(
398                                            layoutSetBranch.getLogoId());
399                            }
400                            else {
401                                    image = ImageLocalServiceUtil.getImage(layoutSet.getLogoId());
402                            }
403    
404                            if ((image != null) && (image.getTextObj() != null)) {
405                                    String logoPath = ExportImportPathUtil.getRootPath(
406                                            portletDataContext);
407    
408                                    logoPath += "/logo";
409    
410                                    headerElement.addAttribute("logo-path", logoPath);
411    
412                                    portletDataContext.addZipEntry(logoPath, image.getTextObj());
413                            }
414                    }
415    
416                    if (layoutSetBranch != null) {
417                            _themeExporter.exportTheme(portletDataContext, layoutSetBranch);
418                    }
419                    else {
420                            _themeExporter.exportTheme(portletDataContext, layoutSet);
421                    }
422    
423                    if (exportLayoutSetSettings) {
424                            Element settingsElement = headerElement.addElement("settings");
425    
426                            if (layoutSetBranch != null) {
427                                    settingsElement.addCDATA(layoutSetBranch.getSettings());
428                            }
429                            else {
430                                    settingsElement.addCDATA(layoutSet.getSettings());
431                            }
432                    }
433    
434                    Map<String, Object[]> portletIds =
435                            new LinkedHashMap<String, Object[]>();
436    
437                    List<Layout> layouts = LayoutLocalServiceUtil.getLayouts(
438                            groupId, privateLayout);
439    
440                    List<Portlet> portlets = getDataSiteLevelPortlets(companyId);
441    
442                    long plid = LayoutConstants.DEFAULT_PLID;
443    
444                    if (!layouts.isEmpty()) {
445                            Layout firstLayout = layouts.get(0);
446    
447                            plid = firstLayout.getPlid();
448                    }
449    
450                    if (group.isStagingGroup()) {
451                            group = group.getLiveGroup();
452                    }
453    
454                    for (Portlet portlet : portlets) {
455                            String portletId = portlet.getRootPortletId();
456    
457                            if (!group.isStagedPortlet(portletId)) {
458                                    continue;
459                            }
460    
461                            String key = PortletPermissionUtil.getPrimaryKey(0, portletId);
462    
463                            if (portletIds.get(key) == null) {
464                                    portletIds.put(
465                                            key,
466                                            new Object[] {
467                                                    portletId, plid, groupId, StringPool.BLANK,
468                                                    StringPool.BLANK
469                                            });
470                            }
471                    }
472    
473                    Element missingReferencesElement = rootElement.addElement(
474                            "missing-references");
475    
476                    portletDataContext.setMissingReferencesElement(
477                            missingReferencesElement);
478    
479                    portletDataContext.addDeletionSystemEventStagedModelTypes(
480                            new StagedModelType(Layout.class));
481    
482                    Element layoutsElement = portletDataContext.getExportDataGroupElement(
483                            Layout.class);
484    
485                    String layoutSetPrototypeUuid = layoutSet.getLayoutSetPrototypeUuid();
486    
487                    if (Validator.isNotNull(layoutSetPrototypeUuid)) {
488                            LayoutSetPrototype layoutSetPrototype =
489                                    LayoutSetPrototypeLocalServiceUtil.
490                                            getLayoutSetPrototypeByUuidAndCompanyId(
491                                                    layoutSetPrototypeUuid, companyId);
492    
493                            layoutsElement.addAttribute(
494                                    "layout-set-prototype-uuid", layoutSetPrototypeUuid);
495    
496                            layoutsElement.addAttribute(
497                                    "layout-set-prototype-name",
498                                    layoutSetPrototype.getName(LocaleUtil.getDefault()));
499                    }
500    
501                    for (Layout layout : layouts) {
502                            exportLayout(
503                                    portletDataContext, portlets, layoutIds, portletIds, layout,
504                                    zipWriter);
505                    }
506    
507                    long previousScopeGroupId = portletDataContext.getScopeGroupId();
508    
509                    Element portletsElement = rootElement.addElement("portlets");
510    
511                    for (Map.Entry<String, Object[]> portletIdsEntry :
512                                    portletIds.entrySet()) {
513    
514                            Object[] portletObjects = portletIdsEntry.getValue();
515    
516                            String portletId = null;
517                            plid = LayoutConstants.DEFAULT_PLID;
518                            long scopeGroupId = 0;
519                            String scopeType = StringPool.BLANK;
520                            String scopeLayoutUuid = null;
521    
522                            if (portletObjects.length == 4) {
523                                    portletId = (String)portletIdsEntry.getValue()[0];
524                                    plid = (Long)portletIdsEntry.getValue()[1];
525                                    scopeGroupId = (Long)portletIdsEntry.getValue()[2];
526                                    scopeLayoutUuid = (String)portletIdsEntry.getValue()[3];
527                            }
528                            else {
529                                    portletId = (String)portletIdsEntry.getValue()[0];
530                                    plid = (Long)portletIdsEntry.getValue()[1];
531                                    scopeGroupId = (Long)portletIdsEntry.getValue()[2];
532                                    scopeType = (String)portletIdsEntry.getValue()[3];
533                                    scopeLayoutUuid = (String)portletIdsEntry.getValue()[4];
534                            }
535    
536                            Layout layout = LayoutLocalServiceUtil.fetchLayout(plid);
537    
538                            if (layout == null) {
539                                    layout = new LayoutImpl();
540    
541                                    layout.setGroupId(groupId);
542                                    layout.setCompanyId(companyId);
543                            }
544    
545                            portletDataContext.setPlid(plid);
546                            portletDataContext.setOldPlid(plid);
547                            portletDataContext.setScopeGroupId(scopeGroupId);
548                            portletDataContext.setScopeType(scopeType);
549                            portletDataContext.setScopeLayoutUuid(scopeLayoutUuid);
550    
551                            boolean[] exportPortletControls = getExportPortletControls(
552                                    companyId, portletId, parameterMap, type);
553    
554                            _portletExporter.exportPortlet(
555                                    portletDataContext, layoutCache, portletId, layout,
556                                    portletsElement, defaultUserId, exportPermissions,
557                                    exportPortletControls[0], exportPortletControls[1],
558                                    exportPortletControls[2], exportPortletControls[3]);
559                    }
560    
561                    portletDataContext.setScopeGroupId(previousScopeGroupId);
562    
563                    exportAssetCategories(
564                            portletDataContext, exportPortletDataAll, exportCategories,
565                            group.isCompany());
566    
567                    _portletExporter.exportAssetLinks(portletDataContext);
568                    _portletExporter.exportAssetTags(portletDataContext);
569                    _portletExporter.exportComments(portletDataContext);
570                    _portletExporter.exportExpandoTables(portletDataContext);
571                    _portletExporter.exportLocks(portletDataContext);
572    
573                    _deletionSystemEventExporter.exportDeletionSystemEvents(
574                            portletDataContext);
575    
576                    if (exportPermissions) {
577                            _permissionExporter.exportPortletDataPermissions(
578                                    portletDataContext);
579                    }
580    
581                    _portletExporter.exportRatingsEntries(portletDataContext, rootElement);
582    
583                    ExportImportHelperUtil.writeManifestSummary(
584                            document, portletDataContext.getManifestSummary());
585    
586                    if (_log.isInfoEnabled()) {
587                            if (stopWatch != null) {
588                                    _log.info(
589                                            "Exporting layouts takes " + stopWatch.getTime() + " ms");
590                            }
591                            else {
592                                    _log.info("Exporting layouts is finished");
593                            }
594                    }
595    
596                    portletDataContext.addZipEntry(
597                            "/manifest.xml", document.formattedString());
598    
599                    try {
600                            return zipWriter.getFile();
601                    }
602                    finally {
603                            if (updateLastPublishDate) {
604                                    updateLastPublishDate(layoutSet, lastPublishDate);
605                            }
606                    }
607            }
608    
609            protected void exportAssetCategories(
610                            PortletDataContext portletDataContext, boolean exportPortletDataAll,
611                            boolean exportCategories, boolean companyGroup)
612                    throws Exception {
613    
614                    Document document = SAXReaderUtil.createDocument();
615    
616                    Element rootElement = document.addElement("categories-hierarchy");
617    
618                    if (exportPortletDataAll || exportCategories || companyGroup) {
619                            if (_log.isDebugEnabled()) {
620                                    _log.debug("Export categories");
621                            }
622    
623                            Element assetVocabulariesElement = rootElement.addElement(
624                                    "vocabularies");
625    
626                            List<AssetVocabulary> assetVocabularies =
627                                    AssetVocabularyLocalServiceUtil.getGroupVocabularies(
628                                            portletDataContext.getGroupId());
629    
630                            for (AssetVocabulary assetVocabulary : assetVocabularies) {
631                                    _portletExporter.exportAssetVocabulary(
632                                            portletDataContext, assetVocabulariesElement,
633                                            assetVocabulary);
634                            }
635    
636                            Element categoriesElement = rootElement.addElement("categories");
637    
638                            List<AssetCategory> assetCategories =
639                                    AssetCategoryUtil.findByGroupId(
640                                            portletDataContext.getGroupId());
641    
642                            for (AssetCategory assetCategory : assetCategories) {
643                                    _portletExporter.exportAssetCategory(
644                                            portletDataContext, assetVocabulariesElement,
645                                            categoriesElement, assetCategory);
646                            }
647                    }
648    
649                    _portletExporter.exportAssetCategories(portletDataContext, rootElement);
650    
651                    portletDataContext.addZipEntry(
652                            ExportImportPathUtil.getRootPath(portletDataContext) +
653                                    "/categories-hierarchy.xml",
654                            document.formattedString());
655            }
656    
657            protected void exportLayout(
658                            PortletDataContext portletDataContext, List<Portlet> portlets,
659                            long[] layoutIds, Map<String, Object[]> portletIds, Layout layout,
660                            ZipWriter zipWriter)
661                    throws Exception {
662    
663                    if (!ArrayUtil.contains(layoutIds, layout.getLayoutId()) &&
664                            (layoutIds != null) && (layoutIds.length > 0)) {
665    
666                            Element layoutElement = portletDataContext.getExportDataElement(
667                                    layout);
668    
669                            layoutElement.addAttribute("action", Constants.SKIP);
670    
671                            return;
672                    }
673    
674                    StagedModelDataHandlerUtil.exportStagedModel(
675                            portletDataContext, layout);
676    
677                    if (!layout.isSupportsEmbeddedPortlets()) {
678    
679                            // Only portlet type layouts support page scoping
680    
681                            return;
682                    }
683    
684                    if (layout.isTypePortlet()) {
685                            for (Portlet portlet : portlets) {
686                                    if (portlet.isScopeable() && layout.hasScopeGroup()) {
687                                            String key = PortletPermissionUtil.getPrimaryKey(
688                                                    layout.getPlid(), portlet.getPortletId());
689    
690                                            Group scopeGroup = layout.getScopeGroup();
691    
692                                            portletIds.put(
693                                                    key,
694                                                    new Object[] {
695                                                            portlet.getPortletId(), layout.getPlid(),
696                                                            scopeGroup.getGroupId(), StringPool.BLANK,
697                                                            layout.getUuid()
698                                                    });
699                                    }
700                            }
701                    }
702    
703                    LayoutTypePortlet layoutTypePortlet =
704                            (LayoutTypePortlet)layout.getLayoutType();
705    
706                    // The getAllPortlets method returns all effective nonsystem portlets
707                    // for any layout type, including embedded portlets, or in the case of
708                    // panel type layout, selected portlets
709    
710                    for (Portlet portlet : layoutTypePortlet.getAllPortlets(false)) {
711                            String portletId = portlet.getPortletId();
712    
713                            javax.portlet.PortletPreferences jxPortletPreferences =
714                                    PortletPreferencesFactoryUtil.getLayoutPortletSetup(
715                                            layout, portletId);
716    
717                            String scopeType = GetterUtil.getString(
718                                    jxPortletPreferences.getValue("lfrScopeType", null));
719                            String scopeLayoutUuid = GetterUtil.getString(
720                                    jxPortletPreferences.getValue("lfrScopeLayoutUuid", null));
721    
722                            long scopeGroupId = portletDataContext.getScopeGroupId();
723    
724                            if (Validator.isNotNull(scopeType)) {
725                                    Group scopeGroup = null;
726    
727                                    if (scopeType.equals("company")) {
728                                            scopeGroup = GroupLocalServiceUtil.getCompanyGroup(
729                                                    layout.getCompanyId());
730                                    }
731                                    else if (scopeType.equals("layout")) {
732                                            Layout scopeLayout = null;
733    
734                                            scopeLayout =
735                                                    LayoutLocalServiceUtil.fetchLayoutByUuidAndGroupId(
736                                                            scopeLayoutUuid, portletDataContext.getGroupId(),
737                                                            portletDataContext.isPrivateLayout());
738    
739                                            if (scopeLayout == null) {
740                                                    continue;
741                                            }
742    
743                                            scopeGroup = scopeLayout.getScopeGroup();
744                                    }
745                                    else {
746                                            throw new IllegalArgumentException(
747                                                    "Scope type " + scopeType + " is invalid");
748                                    }
749    
750                                    if (scopeGroup != null) {
751                                            scopeGroupId = scopeGroup.getGroupId();
752                                    }
753                            }
754    
755                            String key = PortletPermissionUtil.getPrimaryKey(
756                                    layout.getPlid(), portletId);
757    
758                            portletIds.put(
759                                    key,
760                                    new Object[] {
761                                            portletId, layout.getPlid(), scopeGroupId, scopeType,
762                                            scopeLayoutUuid
763                                    }
764                            );
765                    }
766            }
767    
768            protected boolean[] getExportPortletControls(
769                            long companyId, String portletId,
770                            Map<String, String[]> parameterMap, String type)
771                    throws Exception {
772    
773                    boolean exportPortletConfiguration = MapUtil.getBoolean(
774                            parameterMap, PortletDataHandlerKeys.PORTLET_CONFIGURATION);
775                    boolean exportPortletConfigurationAll = MapUtil.getBoolean(
776                            parameterMap, PortletDataHandlerKeys.PORTLET_CONFIGURATION_ALL);
777                    boolean exportPortletData = MapUtil.getBoolean(
778                            parameterMap, PortletDataHandlerKeys.PORTLET_DATA);
779                    boolean exportPortletDataAll = MapUtil.getBoolean(
780                            parameterMap, PortletDataHandlerKeys.PORTLET_DATA_ALL);
781    
782                    if (_log.isDebugEnabled()) {
783                            _log.debug("Export portlet data " + exportPortletData);
784                            _log.debug("Export all portlet data " + exportPortletDataAll);
785                            _log.debug(
786                                    "Export portlet configuration " + exportPortletConfiguration);
787                    }
788    
789                    boolean exportCurPortletData = exportPortletData;
790    
791                    String rootPortletId =
792                            ExportImportHelperUtil.getExportableRootPortletId(
793                                    companyId, portletId);
794    
795                    if (exportPortletDataAll) {
796                            exportCurPortletData = true;
797                    }
798                    else if (rootPortletId != null) {
799    
800                            // PORTLET_DATA and the PORTLET_DATA for this specific data handler
801                            // must be true
802    
803                            exportCurPortletData =
804                                    exportPortletData &&
805                                    MapUtil.getBoolean(
806                                            parameterMap,
807                                            PortletDataHandlerKeys.PORTLET_DATA +
808                                                    StringPool.UNDERLINE + rootPortletId);
809                    }
810    
811                    boolean exportCurPortletArchivedSetups = exportPortletConfiguration;
812                    boolean exportCurPortletSetup = exportPortletConfiguration;
813                    boolean exportCurPortletUserPreferences = exportPortletConfiguration;
814    
815                    if (exportPortletConfigurationAll ||
816                            (exportPortletConfiguration && type.equals("layout-prototype"))) {
817    
818                            exportCurPortletArchivedSetups =
819                                    MapUtil.getBoolean(
820                                            parameterMap,
821                                            PortletDataHandlerKeys.PORTLET_ARCHIVED_SETUPS_ALL);
822                            exportCurPortletSetup =
823                                    MapUtil.getBoolean(
824                                            parameterMap, PortletDataHandlerKeys.PORTLET_SETUP_ALL);
825                            exportCurPortletUserPreferences =
826                                    MapUtil.getBoolean(
827                                            parameterMap,
828                                            PortletDataHandlerKeys.PORTLET_USER_PREFERENCES_ALL);
829                    }
830                    else if (rootPortletId != null) {
831                            boolean exportCurPortletConfiguration =
832                                    exportPortletConfiguration &&
833                                    MapUtil.getBoolean(
834                                            parameterMap,
835                                            PortletDataHandlerKeys.PORTLET_CONFIGURATION +
836                                                    StringPool.UNDERLINE + rootPortletId);
837    
838                            exportCurPortletArchivedSetups =
839                                    exportCurPortletConfiguration &&
840                                    MapUtil.getBoolean(
841                                            parameterMap,
842                                            PortletDataHandlerKeys.PORTLET_ARCHIVED_SETUPS +
843                                                    StringPool.UNDERLINE + rootPortletId);
844                            exportCurPortletSetup =
845                                    exportCurPortletConfiguration &&
846                                    MapUtil.getBoolean(
847                                            parameterMap,
848                                            PortletDataHandlerKeys.PORTLET_SETUP +
849                                                    StringPool.UNDERLINE + rootPortletId);
850                            exportCurPortletUserPreferences =
851                                    exportCurPortletConfiguration &&
852                                    MapUtil.getBoolean(
853                                            parameterMap,
854                                            PortletDataHandlerKeys.PORTLET_USER_PREFERENCES +
855                                                    StringPool.UNDERLINE + rootPortletId);
856                    }
857    
858                    return new boolean[] {
859                            exportCurPortletArchivedSetups, exportCurPortletData,
860                            exportCurPortletSetup, exportCurPortletUserPreferences};
861            }
862    
863            private static Log _log = LogFactoryUtil.getLog(LayoutExporter.class);
864    
865            private DeletionSystemEventExporter _deletionSystemEventExporter =
866                    new DeletionSystemEventExporter();
867            private PermissionExporter _permissionExporter = new PermissionExporter();
868            private PortletExporter _portletExporter = new PortletExporter();
869            private ThemeExporter _themeExporter = new ThemeExporter();
870    
871    }