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