001    /**
002     * Copyright (c) 2000-present 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.backgroundtask.BackgroundTaskThreadLocal;
018    import com.liferay.portal.kernel.language.LanguageUtil;
019    import com.liferay.portal.kernel.lar.ExportImportHelperUtil;
020    import com.liferay.portal.kernel.lar.ExportImportPathUtil;
021    import com.liferay.portal.kernel.lar.ExportImportThreadLocal;
022    import com.liferay.portal.kernel.lar.ManifestSummary;
023    import com.liferay.portal.kernel.lar.PortletDataContext;
024    import com.liferay.portal.kernel.lar.PortletDataContextFactoryUtil;
025    import com.liferay.portal.kernel.lar.PortletDataHandler;
026    import com.liferay.portal.kernel.lar.PortletDataHandlerKeys;
027    import com.liferay.portal.kernel.lar.PortletDataHandlerStatusMessageSenderUtil;
028    import com.liferay.portal.kernel.lar.StagedModelDataHandlerUtil;
029    import com.liferay.portal.kernel.lar.StagedModelType;
030    import com.liferay.portal.kernel.lar.xstream.XStreamAliasRegistryUtil;
031    import com.liferay.portal.kernel.log.Log;
032    import com.liferay.portal.kernel.log.LogFactoryUtil;
033    import com.liferay.portal.kernel.settings.Settings;
034    import com.liferay.portal.kernel.settings.SettingsFactoryUtil;
035    import com.liferay.portal.kernel.staging.LayoutStagingUtil;
036    import com.liferay.portal.kernel.util.ArrayUtil;
037    import com.liferay.portal.kernel.util.Constants;
038    import com.liferay.portal.kernel.util.FileUtil;
039    import com.liferay.portal.kernel.util.LocaleUtil;
040    import com.liferay.portal.kernel.util.MapUtil;
041    import com.liferay.portal.kernel.util.ReleaseInfo;
042    import com.liferay.portal.kernel.util.StringPool;
043    import com.liferay.portal.kernel.util.StringUtil;
044    import com.liferay.portal.kernel.util.Time;
045    import com.liferay.portal.kernel.util.Validator;
046    import com.liferay.portal.kernel.xml.Document;
047    import com.liferay.portal.kernel.xml.Element;
048    import com.liferay.portal.kernel.xml.SAXReaderUtil;
049    import com.liferay.portal.kernel.zip.ZipWriter;
050    import com.liferay.portal.kernel.zip.ZipWriterFactoryUtil;
051    import com.liferay.portal.model.Group;
052    import com.liferay.portal.model.Image;
053    import com.liferay.portal.model.Layout;
054    import com.liferay.portal.model.LayoutConstants;
055    import com.liferay.portal.model.LayoutPrototype;
056    import com.liferay.portal.model.LayoutRevision;
057    import com.liferay.portal.model.LayoutSet;
058    import com.liferay.portal.model.LayoutSetBranch;
059    import com.liferay.portal.model.LayoutSetPrototype;
060    import com.liferay.portal.model.LayoutStagingHandler;
061    import com.liferay.portal.model.LayoutTypePortlet;
062    import com.liferay.portal.model.Portlet;
063    import com.liferay.portal.model.impl.LayoutImpl;
064    import com.liferay.portal.service.GroupLocalServiceUtil;
065    import com.liferay.portal.service.ImageLocalServiceUtil;
066    import com.liferay.portal.service.LayoutLocalServiceUtil;
067    import com.liferay.portal.service.LayoutPrototypeLocalServiceUtil;
068    import com.liferay.portal.service.LayoutRevisionLocalServiceUtil;
069    import com.liferay.portal.service.LayoutSetBranchLocalServiceUtil;
070    import com.liferay.portal.service.LayoutSetLocalServiceUtil;
071    import com.liferay.portal.service.LayoutSetPrototypeLocalServiceUtil;
072    import com.liferay.portal.service.PortletLocalServiceUtil;
073    import com.liferay.portal.service.ServiceContext;
074    import com.liferay.portal.service.ServiceContextThreadLocal;
075    import com.liferay.portal.service.UserLocalServiceUtil;
076    import com.liferay.portal.service.permission.PortletPermissionUtil;
077    
078    import java.io.File;
079    
080    import java.util.Collections;
081    import java.util.Date;
082    import java.util.Iterator;
083    import java.util.LinkedHashMap;
084    import java.util.List;
085    import java.util.Map;
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 List<Portlet> getDataSiteLevelPortlets(long companyId)
104                    throws Exception {
105    
106                    return getDataSiteLevelPortlets(companyId, false);
107            }
108    
109            public static List<Portlet> getDataSiteLevelPortlets(
110                            long companyId, boolean excludeDataAlwaysStaged)
111                    throws Exception {
112    
113                    List<Portlet> portlets = PortletLocalServiceUtil.getPortlets(companyId);
114    
115                    Iterator<Portlet> itr = portlets.iterator();
116    
117                    while (itr.hasNext()) {
118                            Portlet portlet = itr.next();
119    
120                            if (!portlet.isActive()) {
121                                    itr.remove();
122    
123                                    continue;
124                            }
125    
126                            PortletDataHandler portletDataHandler =
127                                    portlet.getPortletDataHandlerInstance();
128    
129                            if ((portletDataHandler == null) ||
130                                    !portletDataHandler.isDataSiteLevel() ||
131                                    (excludeDataAlwaysStaged &&
132                                     portletDataHandler.isDataAlwaysStaged())) {
133    
134                                    itr.remove();
135                            }
136                    }
137    
138                    return portlets;
139            }
140    
141            public static LayoutExporter getInstance() {
142                    return _instance;
143            }
144    
145            /**
146             * @deprecated As of 7.0.0, with no direct replacement
147             */
148            @Deprecated
149            public static List<Portlet> getPortletDataHandlerPortlets(
150                            long groupId, List<Layout> layouts)
151                    throws Exception {
152    
153                    return Collections.emptyList();
154            }
155    
156            /**
157             * @deprecated As of 7.0.0, with no direct replacement
158             */
159            @Deprecated
160            public byte[] exportLayouts(
161                            long groupId, boolean privateLayout, long[] layoutIds,
162                            Map<String, String[]> parameterMap, Date startDate, Date endDate)
163                    throws Exception {
164    
165                    File file = exportLayoutsAsFile(
166                            groupId, privateLayout, layoutIds, parameterMap, startDate,
167                            endDate);
168    
169                    try {
170                            return FileUtil.getBytes(file);
171                    }
172                    finally {
173                            file.delete();
174                    }
175            }
176    
177            public File exportLayoutsAsFile(
178                            long groupId, boolean privateLayout, long[] layoutIds,
179                            Map<String, String[]> parameterMap, Date startDate, Date endDate)
180                    throws Exception {
181    
182                    try {
183                            ExportImportThreadLocal.setLayoutExportInProcess(true);
184    
185                            return doExportLayoutsAsFile(
186                                    groupId, privateLayout, layoutIds, parameterMap, startDate,
187                                    endDate);
188                    }
189                    finally {
190                            ExportImportThreadLocal.setLayoutExportInProcess(false);
191                    }
192            }
193    
194            protected File doExportLayoutsAsFile(
195                            long groupId, boolean privateLayout, long[] layoutIds,
196                            Map<String, String[]> parameterMap, Date startDate, Date endDate)
197                    throws Exception {
198    
199                    boolean exportIgnoreLastPublishDate = MapUtil.getBoolean(
200                            parameterMap, PortletDataHandlerKeys.IGNORE_LAST_PUBLISH_DATE);
201                    boolean exportPermissions = MapUtil.getBoolean(
202                            parameterMap, PortletDataHandlerKeys.PERMISSIONS);
203                    boolean exportLogo = MapUtil.getBoolean(
204                            parameterMap, PortletDataHandlerKeys.LOGO);
205                    boolean exportLayoutSetSettings = MapUtil.getBoolean(
206                            parameterMap, PortletDataHandlerKeys.LAYOUT_SET_SETTINGS);
207    
208                    if (_log.isDebugEnabled()) {
209                            _log.debug("Export permissions " + exportPermissions);
210                    }
211    
212                    LayoutSet layoutSet = LayoutSetLocalServiceUtil.getLayoutSet(
213                            groupId, privateLayout);
214    
215                    long companyId = layoutSet.getCompanyId();
216                    long defaultUserId = UserLocalServiceUtil.getDefaultUserId(companyId);
217    
218                    ServiceContext serviceContext =
219                            ServiceContextThreadLocal.getServiceContext();
220    
221                    if (serviceContext == null) {
222                            serviceContext = new ServiceContext();
223    
224                            serviceContext.setCompanyId(companyId);
225                            serviceContext.setSignedIn(false);
226                            serviceContext.setUserId(defaultUserId);
227    
228                            ServiceContextThreadLocal.pushServiceContext(serviceContext);
229                    }
230    
231                    serviceContext.setAttribute("exporting", Boolean.TRUE);
232    
233                    long layoutSetBranchId = MapUtil.getLong(
234                            parameterMap, "layoutSetBranchId");
235    
236                    serviceContext.setAttribute("layoutSetBranchId", layoutSetBranchId);
237    
238                    if (exportIgnoreLastPublishDate) {
239                            endDate = null;
240                            startDate = null;
241                    }
242    
243                    StopWatch stopWatch = new StopWatch();
244    
245                    stopWatch.start();
246    
247                    ZipWriter zipWriter = ZipWriterFactoryUtil.getZipWriter();
248    
249                    PortletDataContext portletDataContext =
250                            PortletDataContextFactoryUtil.createExportPortletDataContext(
251                                    companyId, groupId, parameterMap, startDate, endDate,
252                                    zipWriter);
253    
254                    portletDataContext.setPortetDataContextListener(
255                            new PortletDataContextListenerImpl(portletDataContext));
256    
257                    Document document = SAXReaderUtil.createDocument();
258    
259                    Element rootElement = document.addElement("root");
260    
261                    portletDataContext.setExportDataRootElement(rootElement);
262    
263                    Element headerElement = rootElement.addElement("header");
264    
265                    headerElement.addAttribute(
266                            "available-locales",
267                            StringUtil.merge(
268                                    LanguageUtil.getAvailableLocales(
269                                            portletDataContext.getScopeGroupId())));
270                    headerElement.addAttribute(
271                            "build-number", String.valueOf(ReleaseInfo.getBuildNumber()));
272                    headerElement.addAttribute("export-date", Time.getRFC822());
273    
274                    if (portletDataContext.hasDateRange()) {
275                            headerElement.addAttribute(
276                                    "start-date",
277                                    String.valueOf(portletDataContext.getStartDate()));
278                            headerElement.addAttribute(
279                                    "end-date", String.valueOf(portletDataContext.getEndDate()));
280                    }
281    
282                    headerElement.addAttribute(
283                            "company-id", String.valueOf(portletDataContext.getCompanyId()));
284                    headerElement.addAttribute(
285                            "company-group-id",
286                            String.valueOf(portletDataContext.getCompanyGroupId()));
287                    headerElement.addAttribute("group-id", String.valueOf(groupId));
288                    headerElement.addAttribute(
289                            "user-personal-site-group-id",
290                            String.valueOf(portletDataContext.getUserPersonalSiteGroupId()));
291                    headerElement.addAttribute(
292                            "private-layout", String.valueOf(privateLayout));
293    
294                    Group group = layoutSet.getGroup();
295    
296                    String type = "layout-set";
297    
298                    if (group.isLayoutPrototype()) {
299                            type = "layout-prototype";
300    
301                            LayoutPrototype layoutPrototype =
302                                    LayoutPrototypeLocalServiceUtil.getLayoutPrototype(
303                                            group.getClassPK());
304    
305                            headerElement.addAttribute("type-uuid", layoutPrototype.getUuid());
306                    }
307                    else if (group.isLayoutSetPrototype()) {
308                            type ="layout-set-prototype";
309    
310                            LayoutSetPrototype layoutSetPrototype =
311                                    LayoutSetPrototypeLocalServiceUtil.getLayoutSetPrototype(
312                                            group.getClassPK());
313    
314                            headerElement.addAttribute(
315                                    "type-uuid", layoutSetPrototype.getUuid());
316                    }
317    
318                    headerElement.addAttribute("type", type);
319    
320                    LayoutSetBranch layoutSetBranch =
321                            LayoutSetBranchLocalServiceUtil.fetchLayoutSetBranch(
322                                    layoutSetBranchId);
323    
324                    if (exportLogo) {
325                            Image image = null;
326    
327                            if (layoutSetBranch != null) {
328                                    image = ImageLocalServiceUtil.getImage(
329                                            layoutSetBranch.getLogoId());
330                            }
331                            else {
332                                    image = ImageLocalServiceUtil.getImage(layoutSet.getLogoId());
333                            }
334    
335                            if ((image != null) && (image.getTextObj() != null)) {
336                                    String logoPath = ExportImportPathUtil.getRootPath(
337                                            portletDataContext);
338    
339                                    logoPath += "/logo";
340    
341                                    headerElement.addAttribute("logo-path", logoPath);
342    
343                                    portletDataContext.addZipEntry(logoPath, image.getTextObj());
344                            }
345                    }
346    
347                    Element missingReferencesElement = rootElement.addElement(
348                            "missing-references");
349    
350                    portletDataContext.setMissingReferencesElement(
351                            missingReferencesElement);
352    
353                    if (layoutSetBranch != null) {
354                            _themeExporter.exportTheme(portletDataContext, layoutSetBranch);
355                    }
356                    else {
357                            _themeExporter.exportTheme(portletDataContext, layoutSet);
358                    }
359    
360                    if (exportLayoutSetSettings) {
361                            Element settingsElement = headerElement.addElement("settings");
362    
363                            if (layoutSetBranch != null) {
364                                    settingsElement.addCDATA(layoutSetBranch.getSettings());
365                            }
366                            else {
367                                    settingsElement.addCDATA(layoutSet.getSettings());
368                            }
369                    }
370    
371                    Map<String, Object[]> portletIds =
372                            new LinkedHashMap<String, Object[]>();
373    
374                    List<Layout> layouts = LayoutLocalServiceUtil.getLayouts(
375                            groupId, privateLayout);
376    
377                    if (group.isStagingGroup()) {
378                            group = group.getLiveGroup();
379                    }
380    
381                    // Collect data portlets
382    
383                    for (Portlet portlet : getDataSiteLevelPortlets(companyId)) {
384                            String portletId = portlet.getRootPortletId();
385    
386                            if (!group.isStagedPortlet(portletId)) {
387                                    continue;
388                            }
389    
390                            // Calculate the amount of exported data
391    
392                            if (BackgroundTaskThreadLocal.hasBackgroundTask()) {
393                                    PortletDataHandler portletDataHandler =
394                                            portlet.getPortletDataHandlerInstance();
395    
396                                    portletDataHandler.prepareManifestSummary(portletDataContext);
397                            }
398    
399                            // Add portlet ID to exportable portlets list
400    
401                            portletIds.put(
402                                    PortletPermissionUtil.getPrimaryKey(0, portletId),
403                                    new Object[] {
404                                            portletId, LayoutConstants.DEFAULT_PLID, groupId,
405                                            StringPool.BLANK, StringPool.BLANK
406                                    });
407    
408                            if (!portlet.isScopeable()) {
409                                    continue;
410                            }
411    
412                            // Scoped data
413    
414                            for (Layout layout : layouts) {
415                                    if ((!ArrayUtil.contains(layoutIds, layout.getLayoutId()) &&
416                                             ArrayUtil.isNotEmpty(layoutIds)) ||
417                                            !layout.isTypePortlet() || !layout.hasScopeGroup()) {
418    
419                                            continue;
420                                    }
421    
422                                    Group scopeGroup = layout.getScopeGroup();
423    
424                                    portletIds.put(
425                                            PortletPermissionUtil.getPrimaryKey(
426                                                    layout.getPlid(), portlet.getPortletId()),
427                                            new Object[] {
428                                                    portlet.getPortletId(), layout.getPlid(),
429                                                    scopeGroup.getGroupId(), StringPool.BLANK,
430                                                    layout.getUuid()
431                                            });
432                            }
433                    }
434    
435                    portletDataContext.addDeletionSystemEventStagedModelTypes(
436                            new StagedModelType(Layout.class));
437    
438                    Element layoutsElement = portletDataContext.getExportDataGroupElement(
439                            Layout.class);
440    
441                    String layoutSetPrototypeUuid = layoutSet.getLayoutSetPrototypeUuid();
442    
443                    if (Validator.isNotNull(layoutSetPrototypeUuid)) {
444                            LayoutSetPrototype layoutSetPrototype =
445                                    LayoutSetPrototypeLocalServiceUtil.
446                                            getLayoutSetPrototypeByUuidAndCompanyId(
447                                                    layoutSetPrototypeUuid, companyId);
448    
449                            layoutsElement.addAttribute(
450                                    "layout-set-prototype-uuid", layoutSetPrototypeUuid);
451    
452                            layoutsElement.addAttribute(
453                                    "layout-set-prototype-name",
454                                    layoutSetPrototype.getName(LocaleUtil.getDefault()));
455                    }
456    
457                    for (Layout layout : layouts) {
458                            exportLayout(portletDataContext, layoutIds, portletIds, layout);
459                    }
460    
461                    if (BackgroundTaskThreadLocal.hasBackgroundTask()) {
462                            ManifestSummary manifestSummary =
463                                    portletDataContext.getManifestSummary();
464    
465                            PortletDataHandlerStatusMessageSenderUtil.sendStatusMessage(
466                                    "layout", ArrayUtil.toStringArray(portletIds.keySet()),
467                                    manifestSummary);
468    
469                            manifestSummary.resetCounters();
470                    }
471    
472                    Element portletsElement = rootElement.addElement("portlets");
473    
474                    Element servicesElement = rootElement.addElement("services");
475    
476                    long previousScopeGroupId = portletDataContext.getScopeGroupId();
477    
478                    for (Map.Entry<String, Object[]> portletIdsEntry :
479                                    portletIds.entrySet()) {
480    
481                            Object[] portletObjects = portletIdsEntry.getValue();
482    
483                            String portletId = null;
484                            long plid = LayoutConstants.DEFAULT_PLID;
485                            long scopeGroupId = 0;
486                            String scopeType = StringPool.BLANK;
487                            String scopeLayoutUuid = null;
488    
489                            if (portletObjects.length == 4) {
490                                    portletId = (String)portletIdsEntry.getValue()[0];
491                                    plid = (Long)portletIdsEntry.getValue()[1];
492                                    scopeGroupId = (Long)portletIdsEntry.getValue()[2];
493                                    scopeLayoutUuid = (String)portletIdsEntry.getValue()[3];
494                            }
495                            else {
496                                    portletId = (String)portletIdsEntry.getValue()[0];
497                                    plid = (Long)portletIdsEntry.getValue()[1];
498                                    scopeGroupId = (Long)portletIdsEntry.getValue()[2];
499                                    scopeType = (String)portletIdsEntry.getValue()[3];
500                                    scopeLayoutUuid = (String)portletIdsEntry.getValue()[4];
501                            }
502    
503                            Layout layout = LayoutLocalServiceUtil.fetchLayout(plid);
504    
505                            if (layout == null) {
506                                    layout = new LayoutImpl();
507    
508                                    layout.setCompanyId(companyId);
509                                    layout.setGroupId(groupId);
510                            }
511    
512                            portletDataContext.setPlid(plid);
513                            portletDataContext.setOldPlid(plid);
514                            portletDataContext.setScopeGroupId(scopeGroupId);
515                            portletDataContext.setScopeType(scopeType);
516                            portletDataContext.setScopeLayoutUuid(scopeLayoutUuid);
517    
518                            Map<String, Boolean> exportPortletControlsMap =
519                                    ExportImportHelperUtil.getExportPortletControlsMap(
520                                            companyId, portletId, parameterMap, type);
521    
522                            _portletExporter.exportPortlet(
523                                    portletDataContext, portletId, layout, portletsElement,
524                                    exportPermissions,
525                                    exportPortletControlsMap.get(
526                                            PortletDataHandlerKeys.PORTLET_ARCHIVED_SETUPS),
527                                    exportPortletControlsMap.get(
528                                            PortletDataHandlerKeys.PORTLET_DATA),
529                                    exportPortletControlsMap.get(
530                                            PortletDataHandlerKeys.PORTLET_SETUP),
531                                    exportPortletControlsMap.get(
532                                            PortletDataHandlerKeys.PORTLET_USER_PREFERENCES));
533                            _portletExporter.exportService(
534                                    portletDataContext, portletId, servicesElement,
535                                    exportPortletControlsMap.get(
536                                            PortletDataHandlerKeys.PORTLET_SETUP));
537                    }
538    
539                    portletDataContext.setScopeGroupId(previousScopeGroupId);
540    
541                    _portletExporter.exportAssetLinks(portletDataContext);
542                    _portletExporter.exportAssetTags(portletDataContext);
543                    _portletExporter.exportExpandoTables(portletDataContext);
544                    _portletExporter.exportLocks(portletDataContext);
545    
546                    _deletionSystemEventExporter.exportDeletionSystemEvents(
547                            portletDataContext);
548    
549                    if (exportPermissions) {
550                            _permissionExporter.exportPortletDataPermissions(
551                                    portletDataContext);
552                    }
553    
554                    ExportImportHelperUtil.writeManifestSummary(
555                            document, portletDataContext.getManifestSummary());
556    
557                    if (_log.isInfoEnabled()) {
558                            _log.info("Exporting layouts takes " + stopWatch.getTime() + " ms");
559                    }
560    
561                    portletDataContext.addZipEntry(
562                            "/manifest.xml", document.formattedString());
563    
564                    return zipWriter.getFile();
565            }
566    
567            protected void exportLayout(
568                            PortletDataContext portletDataContext, long[] layoutIds,
569                            Map<String, Object[]> portletIds, Layout layout)
570                    throws Exception {
571    
572                    if (!ArrayUtil.contains(layoutIds, layout.getLayoutId()) &&
573                            ArrayUtil.isNotEmpty(layoutIds)) {
574    
575                            Element layoutElement = portletDataContext.getExportDataElement(
576                                    layout);
577    
578                            layoutElement.addAttribute(Constants.ACTION, Constants.SKIP);
579    
580                            return;
581                    }
582    
583                    boolean exportLAR = MapUtil.getBoolean(
584                            portletDataContext.getParameterMap(), "exportLAR");
585    
586                    if (!exportLAR && LayoutStagingUtil.isBranchingLayout(layout)) {
587                            long layoutSetBranchId = MapUtil.getLong(
588                                    portletDataContext.getParameterMap(), "layoutSetBranchId");
589    
590                            if (layoutSetBranchId <= 0) {
591                                    return;
592                            }
593    
594                            LayoutRevision layoutRevision =
595                                    LayoutRevisionLocalServiceUtil.fetchLayoutRevision(
596                                            layoutSetBranchId, true, layout.getPlid());
597    
598                            if (layoutRevision == null) {
599                                    return;
600                            }
601    
602                            LayoutStagingHandler layoutStagingHandler =
603                                    LayoutStagingUtil.getLayoutStagingHandler(layout);
604    
605                            layoutStagingHandler.setLayoutRevision(layoutRevision);
606                    }
607    
608                    StagedModelDataHandlerUtil.exportStagedModel(
609                            portletDataContext, layout);
610    
611                    if (!layout.isSupportsEmbeddedPortlets()) {
612    
613                            // Only portlet type layouts support page scoping
614    
615                            return;
616                    }
617    
618                    LayoutTypePortlet layoutTypePortlet =
619                            (LayoutTypePortlet)layout.getLayoutType();
620    
621                    // The getAllPortlets method returns all effective nonsystem portlets
622                    // for any layout type, including embedded portlets, or in the case of
623                    // panel type layout, selected portlets
624    
625                    for (Portlet portlet : layoutTypePortlet.getAllPortlets(false)) {
626                            String portletId = portlet.getPortletId();
627    
628                            Settings portletInstanceSettings =
629                                    SettingsFactoryUtil.getPortletInstanceSettings(
630                                            layout, portletId);
631    
632                            String scopeType = portletInstanceSettings.getValue(
633                                    "lfrScopeType", null);
634                            String scopeLayoutUuid = portletInstanceSettings.getValue(
635                                    "lfrScopeLayoutUuid", null);
636    
637                            long scopeGroupId = portletDataContext.getScopeGroupId();
638    
639                            if (Validator.isNotNull(scopeType)) {
640                                    Group scopeGroup = null;
641    
642                                    if (scopeType.equals("company")) {
643                                            scopeGroup = GroupLocalServiceUtil.getCompanyGroup(
644                                                    layout.getCompanyId());
645                                    }
646                                    else if (scopeType.equals("layout")) {
647                                            Layout scopeLayout = null;
648    
649                                            scopeLayout =
650                                                    LayoutLocalServiceUtil.fetchLayoutByUuidAndGroupId(
651                                                            scopeLayoutUuid, portletDataContext.getGroupId(),
652                                                            portletDataContext.isPrivateLayout());
653    
654                                            if (scopeLayout == null) {
655                                                    continue;
656                                            }
657    
658                                            scopeGroup = scopeLayout.getScopeGroup();
659                                    }
660                                    else {
661                                            throw new IllegalArgumentException(
662                                                    "Scope type " + scopeType + " is invalid");
663                                    }
664    
665                                    if (scopeGroup != null) {
666                                            scopeGroupId = scopeGroup.getGroupId();
667                                    }
668                            }
669    
670                            String key = PortletPermissionUtil.getPrimaryKey(
671                                    layout.getPlid(), portletId);
672    
673                            portletIds.put(
674                                    key,
675                                    new Object[] {
676                                            portletId, layout.getPlid(), scopeGroupId, scopeType,
677                                            scopeLayoutUuid
678                                    }
679                            );
680                    }
681            }
682    
683            private LayoutExporter() {
684                    XStreamAliasRegistryUtil.register(LayoutImpl.class, "Layout");
685            }
686    
687            private static Log _log = LogFactoryUtil.getLog(LayoutExporter.class);
688    
689            private static LayoutExporter _instance = new LayoutExporter();
690    
691            private DeletionSystemEventExporter _deletionSystemEventExporter =
692                    DeletionSystemEventExporter.getInstance();
693            private PermissionExporter _permissionExporter =
694                    PermissionExporter.getInstance();
695            private PortletExporter _portletExporter = PortletExporter.getInstance();
696            private ThemeExporter _themeExporter = ThemeExporter.getInstance();
697    
698    }