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.service.impl;
016    
017    import com.liferay.portal.NoSuchLayoutException;
018    import com.liferay.portal.kernel.cache.ThreadLocalCachable;
019    import com.liferay.portal.kernel.exception.PortalException;
020    import com.liferay.portal.kernel.exception.SystemException;
021    import com.liferay.portal.kernel.lar.MissingReferences;
022    import com.liferay.portal.kernel.messaging.DestinationNames;
023    import com.liferay.portal.kernel.repository.model.FileEntry;
024    import com.liferay.portal.kernel.scheduler.CronTrigger;
025    import com.liferay.portal.kernel.scheduler.SchedulerEngineHelperUtil;
026    import com.liferay.portal.kernel.scheduler.StorageType;
027    import com.liferay.portal.kernel.scheduler.Trigger;
028    import com.liferay.portal.kernel.util.GetterUtil;
029    import com.liferay.portal.kernel.util.StringPool;
030    import com.liferay.portal.kernel.util.TempFileUtil;
031    import com.liferay.portal.kernel.util.Validator;
032    import com.liferay.portal.kernel.uuid.PortalUUIDUtil;
033    import com.liferay.portal.messaging.LayoutsLocalPublisherRequest;
034    import com.liferay.portal.messaging.LayoutsRemotePublisherRequest;
035    import com.liferay.portal.model.Group;
036    import com.liferay.portal.model.Layout;
037    import com.liferay.portal.model.LayoutConstants;
038    import com.liferay.portal.model.LayoutReference;
039    import com.liferay.portal.model.LayoutTypePortlet;
040    import com.liferay.portal.model.Plugin;
041    import com.liferay.portal.model.User;
042    import com.liferay.portal.security.permission.ActionKeys;
043    import com.liferay.portal.security.permission.PermissionChecker;
044    import com.liferay.portal.service.ServiceContext;
045    import com.liferay.portal.service.base.LayoutServiceBaseImpl;
046    import com.liferay.portal.service.permission.GroupPermissionUtil;
047    import com.liferay.portal.service.permission.LayoutPermissionUtil;
048    import com.liferay.portal.service.permission.PortletPermissionUtil;
049    import com.liferay.portal.util.PortletKeys;
050    import com.liferay.portlet.PortletPreferencesFactoryUtil;
051    
052    import java.io.File;
053    import java.io.InputStream;
054    
055    import java.util.ArrayList;
056    import java.util.Date;
057    import java.util.List;
058    import java.util.Locale;
059    import java.util.Map;
060    
061    /**
062     * Provides the remote service for accessing, adding, deleting, exporting,
063     * importing, scheduling publishing of, and updating layouts. Its methods
064     * include permission checks.
065     *
066     * @author Brian Wing Shun Chan
067     * @author Wesley Gong
068     * @author Tibor Lipusz
069     */
070    public class LayoutServiceImpl extends LayoutServiceBaseImpl {
071    
072            /**
073             * Adds a layout with additional parameters.
074             *
075             * <p>
076             * This method handles the creation of the layout including its resources,
077             * metadata, and internal data structures. It is not necessary to make
078             * subsequent calls to any methods to setup default groups, resources, ...
079             * etc.
080             * </p>
081             *
082             * @param      groupId the primary key of the group
083             * @param      privateLayout whether the layout is private to the group
084             * @param      parentLayoutId the primary key of the parent layout
085             *             (optionally {@link
086             *             com.liferay.portal.model.LayoutConstants#DEFAULT_PARENT_LAYOUT_ID})
087             * @param      localeNamesMap the layout's locales and localized names
088             * @param      localeTitlesMap the layout's locales and localized titles
089             * @param      descriptionMap the layout's locales and localized
090             *             descriptions
091             * @param      keywordsMap the layout's locales and localized keywords
092             * @param      robotsMap the layout's locales and localized robots
093             * @param      type the layout's type (optionally {@link
094             *             com.liferay.portal.model.LayoutConstants#TYPE_PORTLET}). The
095             *             possible types can be found in {@link
096             *             com.liferay.portal.model.LayoutConstants}.
097             * @param      hidden whether the layout is hidden
098             * @param      friendlyURL the layout's locales and localized friendly URLs.
099             *             To see how the URL is normalized when accessed, see {@link
100             *             com.liferay.portal.kernel.util.FriendlyURLNormalizerUtil#normalize(
101             *             String)}.
102             * @param      serviceContext the service context to be applied. Must set
103             *             the UUID for the layout. Can set the creation date,
104             *             modification date, and expando bridge attributes for the
105             *             layout. For layouts that belong to a layout set prototype, an
106             *             attribute named <code>layoutUpdateable</code> can be used to
107             *             specify whether site administrators can modify this page
108             *             within their site.
109             * @return     the layout
110             * @throws     PortalException if a group with the primary key could not be
111             *             found, if the group did not have permission to manage the
112             *             layouts involved, if layout values were invalid, or if a
113             *             portal exception occurred
114             * @throws     SystemException if a system exception occurred
115             * @deprecated As of 6.2.0, replaced by {@link #addLayout(long, boolean,
116             *             long, Map, Map, Map, Map, Map, String, String, boolean, Map,
117             *             ServiceContext)}
118             */
119            @Override
120            public Layout addLayout(
121                            long groupId, boolean privateLayout, long parentLayoutId,
122                            Map<Locale, String> localeNamesMap,
123                            Map<Locale, String> localeTitlesMap,
124                            Map<Locale, String> descriptionMap, Map<Locale, String> keywordsMap,
125                            Map<Locale, String> robotsMap, String type, boolean hidden,
126                            String friendlyURL, ServiceContext serviceContext)
127                    throws PortalException, SystemException {
128    
129                    PermissionChecker permissionChecker = getPermissionChecker();
130    
131                    if (parentLayoutId == LayoutConstants.DEFAULT_PARENT_LAYOUT_ID) {
132                            GroupPermissionUtil.check(
133                                    permissionChecker, groupId, ActionKeys.ADD_LAYOUT);
134                    }
135                    else {
136                            LayoutPermissionUtil.check(
137                                    permissionChecker, groupId, privateLayout, parentLayoutId,
138                                    ActionKeys.ADD_LAYOUT);
139                    }
140    
141                    return layoutLocalService.addLayout(
142                            getUserId(), groupId, privateLayout, parentLayoutId, localeNamesMap,
143                            localeTitlesMap, descriptionMap, keywordsMap, robotsMap, type,
144                            hidden, friendlyURL, serviceContext);
145            }
146    
147            /**
148             * Adds a layout with additional parameters.
149             *
150             * <p>
151             * This method handles the creation of the layout including its resources,
152             * metadata, and internal data structures. It is not necessary to make
153             * subsequent calls to any methods to setup default groups, resources, ...
154             * etc.
155             * </p>
156             *
157             * @param  groupId the primary key of the group
158             * @param  privateLayout whether the layout is private to the group
159             * @param  parentLayoutId the primary key of the parent layout (optionally
160             *         {@link
161             *         com.liferay.portal.model.LayoutConstants#DEFAULT_PARENT_LAYOUT_ID})
162             * @param  localeNamesMap the layout's locales and localized names
163             * @param  localeTitlesMap the layout's locales and localized titles
164             * @param  descriptionMap the layout's locales and localized descriptions
165             * @param  keywordsMap the layout's locales and localized keywords
166             * @param  robotsMap the layout's locales and localized robots
167             * @param  type the layout's type (optionally {@link
168             *         com.liferay.portal.model.LayoutConstants#TYPE_PORTLET}). The
169             *         possible types can be found in {@link
170             *         com.liferay.portal.model.LayoutConstants}.
171             * @param  typeSettings the settings to load the unicode properties object.
172             *         See {@link com.liferay.portal.kernel.util.UnicodeProperties
173             *         #fastLoad(String)}.
174             * @param  hidden whether the layout is hidden
175             * @param  friendlyURLMap the layout's locales and localized friendly URLs.
176             *         To see how the URL is normalized when accessed, see {@link
177             *         com.liferay.portal.kernel.util.FriendlyURLNormalizerUtil#normalize(
178             *         String)}.
179             * @param  serviceContext the service context to be applied. Must set the
180             *         UUID for the layout. Can set the creation date, modification
181             *         date, and expando bridge attributes for the layout. For layouts
182             *         that belong to a layout set prototype, an attribute named
183             *         <code>layoutUpdateable</code> can be used to specify whether site
184             *         administrators can modify this page within their site.
185             * @return the layout
186             * @throws PortalException if a group with the primary key could not be
187             *         found, if the group did not have permission to manage the layouts
188             *         involved, if layout values were invalid, or if a portal exception
189             *         occurred
190             * @throws SystemException if a system exception occurred
191             */
192            @Override
193            public Layout addLayout(
194                            long groupId, boolean privateLayout, long parentLayoutId,
195                            Map<Locale, String> localeNamesMap,
196                            Map<Locale, String> localeTitlesMap,
197                            Map<Locale, String> descriptionMap, Map<Locale, String> keywordsMap,
198                            Map<Locale, String> robotsMap, String type, String typeSettings,
199                            boolean hidden, Map<Locale, String> friendlyURLMap,
200                            ServiceContext serviceContext)
201                    throws PortalException, SystemException {
202    
203                    PermissionChecker permissionChecker = getPermissionChecker();
204    
205                    if (parentLayoutId == LayoutConstants.DEFAULT_PARENT_LAYOUT_ID) {
206                            GroupPermissionUtil.check(
207                                    permissionChecker, groupId, ActionKeys.ADD_LAYOUT);
208                    }
209                    else {
210                            LayoutPermissionUtil.check(
211                                    permissionChecker, groupId, privateLayout, parentLayoutId,
212                                    ActionKeys.ADD_LAYOUT);
213                    }
214    
215                    return layoutLocalService.addLayout(
216                            getUserId(), groupId, privateLayout, parentLayoutId, localeNamesMap,
217                            localeTitlesMap, descriptionMap, keywordsMap, robotsMap, type,
218                            typeSettings, hidden, friendlyURLMap, serviceContext);
219            }
220    
221            /**
222             * Adds a layout with single entry maps for name, title, and description to
223             * the default locale.
224             *
225             * <p>
226             * This method handles the creation of the layout including its resources,
227             * metadata, and internal data structures. It is not necessary to make
228             * subsequent calls to any methods to setup default groups, resources, ...
229             * etc.
230             * </p>
231             *
232             * @param  groupId the primary key of the group
233             * @param  privateLayout whether the layout is private to the group
234             * @param  parentLayoutId the primary key of the parent layout (optionally
235             *         {@link
236             *         com.liferay.portal.model.LayoutConstants#DEFAULT_PARENT_LAYOUT_ID})
237             * @param  name Map the layout's locales and localized names
238             * @param  title Map the layout's locales and localized titles
239             * @param  description Map the layout's locales and localized descriptions
240             * @param  type the layout's type (optionally {@link
241             *         com.liferay.portal.model.LayoutConstants#TYPE_PORTLET}). The
242             *         possible types can be found in {@link
243             *         com.liferay.portal.model.LayoutConstants}.
244             * @param  hidden whether the layout is hidden
245             * @param  friendlyURL the layout's locales and localized friendly URLs. To
246             *         see how the URL is normalized when accessed, see {@link
247             *         com.liferay.portal.kernel.util.FriendlyURLNormalizerUtil#normalize(
248             *         String)}.
249             * @param  serviceContext the service context to be applied. Must set the
250             *         UUID for the layout. Can specify the creation date, modification
251             *         date, and expando bridge attributes for the layout. For layouts
252             *         that belong to a layout set prototype, an attribute named
253             *         <code>layoutUpdateable</code> can be used to specify whether site
254             *         administrators can modify this page within their site.
255             * @return the layout
256             * @throws PortalException if a group with the primary key could not be
257             *         found, if the group did not have permission to manage the layouts
258             *         involved, if layout values were invalid, or if a portal exception
259             *         occurred
260             * @throws SystemException if a system exception occurred
261             */
262            @Override
263            public Layout addLayout(
264                            long groupId, boolean privateLayout, long parentLayoutId,
265                            String name, String title, String description, String type,
266                            boolean hidden, String friendlyURL, ServiceContext serviceContext)
267                    throws PortalException, SystemException {
268    
269                    PermissionChecker permissionChecker = getPermissionChecker();
270    
271                    if (parentLayoutId == LayoutConstants.DEFAULT_PARENT_LAYOUT_ID) {
272                            GroupPermissionUtil.check(
273                                    permissionChecker, groupId, ActionKeys.ADD_LAYOUT);
274                    }
275                    else {
276                            LayoutPermissionUtil.check(
277                                    permissionChecker, groupId, privateLayout, parentLayoutId,
278                                    ActionKeys.ADD_LAYOUT);
279                    }
280    
281                    return layoutLocalService.addLayout(
282                            getUserId(), groupId, privateLayout, parentLayoutId, name, title,
283                            description, type, hidden, friendlyURL, serviceContext);
284            }
285    
286            @Override
287            public FileEntry addTempFileEntry(
288                            long groupId, String fileName, String tempFolderName,
289                            InputStream inputStream, String mimeType)
290                    throws PortalException, SystemException {
291    
292                    GroupPermissionUtil.check(
293                            getPermissionChecker(), groupId, ActionKeys.EXPORT_IMPORT_LAYOUTS);
294    
295                    return TempFileUtil.addTempFile(
296                            groupId, getUserId(), fileName, tempFolderName, inputStream,
297                            mimeType);
298            }
299    
300            /**
301             * Deletes the layout with the primary key, also deleting the layout's child
302             * layouts, and associated resources.
303             *
304             * @param  groupId the primary key of the group
305             * @param  privateLayout whether the layout is private to the group
306             * @param  layoutId the primary key of the layout
307             * @param  serviceContext the service context to be applied
308             * @throws PortalException if the user did not have permission to delete the
309             *         layout, if a matching layout could not be found , or if some
310             *         other portal exception occurred
311             * @throws SystemException if a system exception occurred
312             */
313            @Override
314            public void deleteLayout(
315                            long groupId, boolean privateLayout, long layoutId,
316                            ServiceContext serviceContext)
317                    throws PortalException, SystemException {
318    
319                    LayoutPermissionUtil.check(
320                            getPermissionChecker(), groupId, privateLayout, layoutId,
321                            ActionKeys.DELETE);
322    
323                    layoutLocalService.deleteLayout(
324                            groupId, privateLayout, layoutId, serviceContext);
325            }
326    
327            /**
328             * Deletes the layout with the plid, also deleting the layout's child
329             * layouts, and associated resources.
330             *
331             * @param  plid the primary key of the layout
332             * @param  serviceContext the service context to be applied
333             * @throws PortalException if the user did not have permission to delete the
334             *         layout, if a layout with the primary key could not be found , or
335             *         if some other portal exception occurred
336             * @throws SystemException if a system exception occurred
337             */
338            @Override
339            public void deleteLayout(long plid, ServiceContext serviceContext)
340                    throws PortalException, SystemException {
341    
342                    LayoutPermissionUtil.check(
343                            getPermissionChecker(), plid, ActionKeys.DELETE);
344    
345                    layoutLocalService.deleteLayout(plid, serviceContext);
346            }
347    
348            @Override
349            public void deleteTempFileEntry(
350                            long groupId, String fileName, String tempFolderName)
351                    throws PortalException, SystemException {
352    
353                    GroupPermissionUtil.check(
354                            getPermissionChecker(), groupId, ActionKeys.EXPORT_IMPORT_LAYOUTS);
355    
356                    TempFileUtil.deleteTempFile(
357                            groupId, getUserId(), fileName, tempFolderName);
358            }
359    
360            /**
361             * Exports the layouts that match the primary keys and the criteria as a
362             * byte array.
363             *
364             * @param  groupId the primary key of the group
365             * @param  privateLayout whether the layout is private to the group
366             * @param  layoutIds the primary keys of the layouts to be exported
367             * @param  parameterMap the mapping of parameters indicating which
368             *         information to export. For information on the keys used in the
369             *         map see {@link
370             *         com.liferay.portal.kernel.lar.PortletDataHandlerKeys}.
371             * @param  startDate the export's start date
372             * @param  endDate the export's end date
373             * @return the layouts as a byte array
374             * @throws PortalException if a group or any layout with the primary key
375             *         could not be found, if the group did not have permission to
376             *         manage the layouts, or if some other portal exception occurred
377             * @throws SystemException if a system exception occurred
378             */
379            @Override
380            public byte[] exportLayouts(
381                            long groupId, boolean privateLayout, long[] layoutIds,
382                            Map<String, String[]> parameterMap, Date startDate, Date endDate)
383                    throws PortalException, SystemException {
384    
385                    GroupPermissionUtil.check(
386                            getPermissionChecker(), groupId, ActionKeys.EXPORT_IMPORT_LAYOUTS);
387    
388                    return layoutLocalService.exportLayouts(
389                            groupId, privateLayout, layoutIds, parameterMap, startDate,
390                            endDate);
391            }
392    
393            /**
394             * Exports all layouts that match the criteria as a byte array.
395             *
396             * @param  groupId the primary key of the group
397             * @param  privateLayout whether the layout is private to the group
398             * @param  parameterMap the mapping of parameters indicating which
399             *         information to export. For information on the keys used in the
400             *         map see {@link
401             *         com.liferay.portal.kernel.lar.PortletDataHandlerKeys}.
402             * @param  startDate the export's start date
403             * @param  endDate the export's end date
404             * @return the layout as a byte array
405             * @throws PortalException if a group with the primary key could not be
406             *         found, if the group did not have permission to manage the
407             *         layouts, or if some other portal exception occurred
408             * @throws SystemException if a system exception occurred
409             */
410            @Override
411            public byte[] exportLayouts(
412                            long groupId, boolean privateLayout,
413                            Map<String, String[]> parameterMap, Date startDate, Date endDate)
414                    throws PortalException, SystemException {
415    
416                    GroupPermissionUtil.check(
417                            getPermissionChecker(), groupId, ActionKeys.EXPORT_IMPORT_LAYOUTS);
418    
419                    return layoutLocalService.exportLayouts(
420                            groupId, privateLayout, parameterMap, startDate, endDate);
421            }
422    
423            /**
424             * Exports all layouts that match the primary keys and criteria as a file.
425             *
426             * @param  groupId the primary key of the group
427             * @param  privateLayout whether the layout is private to the group
428             * @param  layoutIds the primary keys of the layouts to be exported
429             *         (optionally <code>null</code>)
430             * @param  parameterMap the mapping of parameters indicating which
431             *         information to export. For information on the keys used in the
432             *         map see {@link
433             *         com.liferay.portal.kernel.lar.PortletDataHandlerKeys}.
434             * @param  startDate the export's start date
435             * @param  endDate the export's end date
436             * @return the layouts as a File
437             * @throws PortalException if a group or any layout with the primary key
438             *         could not be found, it the group did not have permission to
439             *         manage the layouts, or if some other portal exception occurred
440             * @throws SystemException if a system exception occurred
441             */
442            @Override
443            public File exportLayoutsAsFile(
444                            long groupId, boolean privateLayout, long[] layoutIds,
445                            Map<String, String[]> parameterMap, Date startDate, Date endDate)
446                    throws PortalException, SystemException {
447    
448                    GroupPermissionUtil.check(
449                            getPermissionChecker(), groupId, ActionKeys.EXPORT_IMPORT_LAYOUTS);
450    
451                    return layoutLocalService.exportLayoutsAsFile(
452                            groupId, privateLayout, layoutIds, parameterMap, startDate,
453                            endDate);
454            }
455    
456            @Override
457            public long exportLayoutsAsFileInBackground(
458                            String taskName, long groupId, boolean privateLayout,
459                            long[] layoutIds, Map<String, String[]> parameterMap,
460                            Date startDate, Date endDate, String fileName)
461                    throws PortalException, SystemException {
462    
463                    GroupPermissionUtil.check(
464                            getPermissionChecker(), groupId, ActionKeys.EXPORT_IMPORT_LAYOUTS);
465    
466                    return layoutLocalService.exportLayoutsAsFileInBackground(
467                            getUserId(), taskName, groupId, privateLayout, layoutIds,
468                            parameterMap, startDate, endDate, fileName);
469            }
470    
471            /**
472             * Exports the portlet information (categories, permissions, ... etc.) as a
473             * byte array.
474             *
475             * @param  plid the primary key of the layout
476             * @param  groupId the primary key of the group
477             * @param  portletId the primary key of the portlet
478             * @param  parameterMap the mapping of parameters indicating which
479             *         information to export. For information on the keys used in the
480             *         map see {@link
481             *         com.liferay.portal.kernel.lar.PortletDataHandlerKeys}.
482             * @param  startDate the export's start date
483             * @param  endDate the export's end date
484             * @return the portlet information as a byte array
485             * @throws PortalException if a layout, group, or portlet with the primary
486             *         key could not be found, if the group did not have permission to
487             *         manage the layouts involved, or if some other portal exception
488             *         occurred
489             * @throws SystemException if a system exception occurred
490             */
491            @Override
492            public byte[] exportPortletInfo(
493                            long plid, long groupId, String portletId,
494                            Map<String, String[]> parameterMap, Date startDate, Date endDate)
495                    throws PortalException, SystemException {
496    
497                    Layout layout = layoutLocalService.getLayout(plid);
498    
499                    GroupPermissionUtil.check(
500                            getPermissionChecker(), layout.getGroupId(),
501                            ActionKeys.EXPORT_IMPORT_PORTLET_INFO);
502    
503                    return layoutLocalService.exportPortletInfo(
504                            plid, groupId, portletId, parameterMap, startDate, endDate);
505            }
506    
507            @Override
508            public byte[] exportPortletInfo(
509                            long companyId, String portletId,
510                            Map<String, String[]> parameterMap, Date startDate, Date endDate)
511                    throws PortalException, SystemException {
512    
513                    Group companyGroup = groupLocalService.getCompanyGroup(companyId);
514    
515                    GroupPermissionUtil.check(
516                            getPermissionChecker(), companyGroup.getGroupId(),
517                            ActionKeys.EXPORT_IMPORT_PORTLET_INFO);
518    
519                    return layoutLocalService.exportPortletInfo(
520                            companyId, portletId, parameterMap, startDate, endDate);
521            }
522    
523            /**
524             * Exports the portlet information (categories, permissions, ... etc.) as a
525             * file.
526             *
527             * @param  plid the primary key of the layout
528             * @param  groupId the primary key of the group
529             * @param  portletId the primary key of the portlet
530             * @param  parameterMap the mapping of parameters indicating which
531             *         information to export. For information on the keys used in the
532             *         map see {@link
533             *         com.liferay.portal.kernel.lar.PortletDataHandlerKeys}.
534             * @param  startDate the export's start date
535             * @param  endDate the export's end date
536             * @return the portlet information as a file
537             * @throws PortalException if a layout, group, or portlet with the primary
538             *         key could not be found, it the group did not have permission to
539             *         manage the layouts involved, or if some other portal exception
540             *         occurred
541             * @throws SystemException if a system exception occurred
542             */
543            @Override
544            public File exportPortletInfoAsFile(
545                            long plid, long groupId, String portletId,
546                            Map<String, String[]> parameterMap, Date startDate, Date endDate)
547                    throws PortalException, SystemException {
548    
549                    Layout layout = layoutLocalService.getLayout(plid);
550    
551                    GroupPermissionUtil.check(
552                            getPermissionChecker(), layout.getGroupId(),
553                            ActionKeys.EXPORT_IMPORT_PORTLET_INFO);
554    
555                    return layoutLocalService.exportPortletInfoAsFile(
556                            plid, groupId, portletId, parameterMap, startDate, endDate);
557            }
558    
559            @Override
560            public File exportPortletInfoAsFile(
561                            String portletId, Map<String, String[]> parameterMap,
562                            Date startDate, Date endDate)
563                    throws PortalException, SystemException {
564    
565                    User user = userPersistence.findByPrimaryKey(getUserId());
566    
567                    Group companyGroup = groupLocalService.getCompanyGroup(
568                            user.getCompanyId());
569    
570                    GroupPermissionUtil.check(
571                            getPermissionChecker(), companyGroup.getGroupId(),
572                            ActionKeys.EXPORT_IMPORT_PORTLET_INFO);
573    
574                    return layoutLocalService.exportPortletInfoAsFile(
575                            user.getCompanyId(), portletId, parameterMap, startDate, endDate);
576            }
577    
578            @Override
579            public long exportPortletInfoAsFileInBackground(
580                            String taskName, long plid, long groupId, String portletId,
581                            Map<String, String[]> parameterMap, Date startDate, Date endDate,
582                            String fileName)
583                    throws PortalException, SystemException {
584    
585                    Layout layout = layoutLocalService.getLayout(plid);
586    
587                    GroupPermissionUtil.check(
588                            getPermissionChecker(), layout.getGroupId(),
589                            ActionKeys.EXPORT_IMPORT_PORTLET_INFO);
590    
591                    return layoutLocalService.exportPortletInfoAsFileInBackground(
592                            getUserId(), taskName, plid, groupId, portletId, parameterMap,
593                            startDate, endDate, fileName);
594            }
595    
596            @Override
597            public long exportPortletInfoAsFileInBackground(
598                            String taskName, String portletId,
599                            Map<String, String[]> parameterMap, Date startDate, Date endDate,
600                            String fileName)
601                    throws PortalException, SystemException {
602    
603                    User user = userPersistence.findByPrimaryKey(getUserId());
604    
605                    Group companyGroup = groupLocalService.getCompanyGroup(
606                            user.getCompanyId());
607    
608                    GroupPermissionUtil.check(
609                            getPermissionChecker(), companyGroup.getGroupId(),
610                            ActionKeys.EXPORT_IMPORT_PORTLET_INFO);
611    
612                    return layoutLocalService.exportPortletInfoAsFileInBackground(
613                            getUserId(), taskName, portletId, parameterMap, startDate, endDate,
614                            fileName);
615            }
616    
617            /**
618             * Returns all the ancestor layouts of the layout.
619             *
620             * @param  plid the primary key of the layout
621             * @return the ancestor layouts of the layout
622             * @throws PortalException if a matching layout could not be found or if a
623             *         portal exception occurred
624             * @throws SystemException if a system exception occurred
625             */
626            @Override
627            public List<Layout> getAncestorLayouts(long plid)
628                    throws PortalException, SystemException {
629    
630                    Layout layout = layoutLocalService.getLayout(plid);
631    
632                    List<Layout> ancestors = layout.getAncestors();
633    
634                    return filterLayouts(ancestors);
635            }
636    
637            /**
638             * Returns the primary key of the default layout for the group.
639             *
640             * @param  groupId the primary key of the group
641             * @param  scopeGroupId the primary key of the scope group. See {@link
642             *         com.liferay.portal.service.ServiceContext#getScopeGroupId()}.
643             * @param  privateLayout whether the layout is private to the group
644             * @param  portletId the primary key of the portlet
645             * @return Returns the primary key of the default layout group; {@link
646             *         com.liferay.portal.model.LayoutConstants#DEFAULT_PLID} otherwise
647             * @throws PortalException if a group, layout, or portlet with the primary
648             *         key could not be found
649             * @throws SystemException if a system exception occurred
650             */
651            @Override
652            public long getDefaultPlid(
653                            long groupId, long scopeGroupId, boolean privateLayout,
654                            String portletId)
655                    throws PortalException, SystemException {
656    
657                    if (groupId <= 0) {
658                            return LayoutConstants.DEFAULT_PLID;
659                    }
660    
661                    PermissionChecker permissionChecker = getPermissionChecker();
662    
663                    String scopeGroupLayoutUuid = null;
664    
665                    Group scopeGroup = groupLocalService.getGroup(scopeGroupId);
666    
667                    if (scopeGroup.isLayout()) {
668                            Layout scopeGroupLayout = layoutLocalService.getLayout(
669                                    scopeGroup.getClassPK());
670    
671                            scopeGroupLayoutUuid = scopeGroupLayout.getUuid();
672                    }
673    
674                    Map<Long, javax.portlet.PortletPreferences> jxPortletPreferencesMap =
675                            PortletPreferencesFactoryUtil.getPortletSetupMap(
676                                    scopeGroup.getCompanyId(), groupId,
677                                    PortletKeys.PREFS_OWNER_ID_DEFAULT,
678                                    PortletKeys.PREFS_OWNER_TYPE_LAYOUT, portletId, privateLayout);
679    
680                    for (Map.Entry<Long, javax.portlet.PortletPreferences> entry :
681                                    jxPortletPreferencesMap.entrySet()) {
682    
683                            long plid = entry.getKey();
684    
685                            Layout layout = null;
686    
687                            try {
688                                    layout = layoutLocalService.getLayout(plid);
689                            }
690                            catch (NoSuchLayoutException nsle) {
691                                    continue;
692                            }
693    
694                            if (!LayoutPermissionUtil.contains(
695                                            permissionChecker, layout, ActionKeys.VIEW)) {
696    
697                                    continue;
698                            }
699    
700                            if (!layout.isTypePortlet()) {
701                                    continue;
702                            }
703    
704                            LayoutTypePortlet layoutTypePortlet =
705                                    (LayoutTypePortlet)layout.getLayoutType();
706    
707                            if (!layoutTypePortlet.hasPortletId(portletId)) {
708                                    continue;
709                            }
710    
711                            javax.portlet.PortletPreferences jxPortletPreferences =
712                                    entry.getValue();
713    
714                            String scopeType = GetterUtil.getString(
715                                    jxPortletPreferences.getValue("lfrScopeType", null));
716    
717                            if (scopeGroup.isLayout()) {
718                                    String scopeLayoutUuid = GetterUtil.getString(
719                                            jxPortletPreferences.getValue("lfrScopeLayoutUuid", null));
720    
721                                    if (Validator.isNotNull(scopeType) &&
722                                            Validator.isNotNull(scopeLayoutUuid) &&
723                                            scopeLayoutUuid.equals(scopeGroupLayoutUuid)) {
724    
725                                            return layout.getPlid();
726                                    }
727                            }
728                            else if (scopeGroup.isCompany()) {
729                                    if (Validator.isNotNull(scopeType) &&
730                                            scopeType.equals("company")) {
731    
732                                            return layout.getPlid();
733                                    }
734                            }
735                            else {
736                                    if (Validator.isNull(scopeType)) {
737                                            return layout.getPlid();
738                                    }
739                            }
740                    }
741    
742                    return LayoutConstants.DEFAULT_PLID;
743            }
744    
745            @Override
746            @ThreadLocalCachable
747            public long getDefaultPlid(
748                            long groupId, long scopeGroupId, String portletId)
749                    throws PortalException, SystemException {
750    
751                    long plid = getDefaultPlid(groupId, scopeGroupId, false, portletId);
752    
753                    if (plid == 0) {
754                            plid = getDefaultPlid(groupId, scopeGroupId, true, portletId);
755                    }
756    
757                    return plid;
758            }
759    
760            /**
761             * Returns the layout matching the UUID, group, and privacy.
762             *
763             * @param  uuid the layout's UUID
764             * @param  groupId the primary key of the group
765             * @param  privateLayout whether the layout is private to the group
766             * @return the matching layout
767             * @throws PortalException if a matching layout could not be found, if the
768             *         user did not have permission to view the layout, or if some other
769             *         portal exception occurred
770             * @throws SystemException if a system exception occurred
771             */
772            @Override
773            public Layout getLayoutByUuidAndGroupId(
774                            String uuid, long groupId, boolean privateLayout)
775                    throws PortalException, SystemException {
776    
777                    Layout layout = layoutLocalService.getLayoutByUuidAndGroupId(
778                            uuid, groupId, privateLayout);
779    
780                    LayoutPermissionUtil.check(
781                            getPermissionChecker(), layout, ActionKeys.VIEW);
782    
783                    return layout;
784            }
785    
786            /**
787             * Returns the name of the layout.
788             *
789             * @param  groupId the primary key of the group
790             * @param  privateLayout whether the layout is private to the group
791             * @param  layoutId the primary key of the layout
792             * @param  languageId the primary key of the language. For more information
793             *         See {@link java.util.Locale}.
794             * @return the layout's name
795             * @throws PortalException if a matching layout could not be found
796             * @throws SystemException if a system exception occurred
797             */
798            @Override
799            public String getLayoutName(
800                            long groupId, boolean privateLayout, long layoutId,
801                            String languageId)
802                    throws PortalException, SystemException {
803    
804                    Layout layout = layoutLocalService.getLayout(
805                            groupId, privateLayout, layoutId);
806    
807                    return layout.getName(languageId);
808            }
809    
810            /**
811             * Returns the layout references for all the layouts that belong to the
812             * company and belong to the portlet that matches the preferences.
813             *
814             * @param  companyId the primary key of the company
815             * @param  portletId the primary key of the portlet
816             * @param  preferencesKey the portlet's preference key
817             * @param  preferencesValue the portlet's preference value
818             * @return the layout references of the matching layouts
819             * @throws SystemException if a system exception occurred
820             */
821            @Override
822            public LayoutReference[] getLayoutReferences(
823                            long companyId, String portletId, String preferencesKey,
824                            String preferencesValue)
825                    throws SystemException {
826    
827                    return layoutLocalService.getLayouts(
828                            companyId, portletId, preferencesKey, preferencesValue);
829            }
830    
831            @Override
832            public List<Layout> getLayouts(long groupId, boolean privateLayout)
833                    throws SystemException {
834    
835                    return layoutPersistence.filterFindByG_P(groupId, privateLayout);
836            }
837    
838            @Override
839            public List<Layout> getLayouts(
840                            long groupId, boolean privateLayout, long parentLayoutId)
841                    throws SystemException {
842    
843                    return layoutPersistence.filterFindByG_P_P(
844                            groupId, privateLayout, parentLayoutId);
845            }
846    
847            @Override
848            public List<Layout> getLayouts(
849                            long groupId, boolean privateLayout, long parentLayoutId,
850                            boolean incomplete, int start, int end)
851                    throws SystemException {
852    
853                    return layoutPersistence.filterFindByG_P_P(
854                            groupId, privateLayout, parentLayoutId, start, end);
855            }
856    
857            @Override
858            public int getLayoutsCount(
859                            long groupId, boolean privateLayout, long parentLayoutId)
860                    throws SystemException {
861    
862                    return layoutPersistence.filterCountByG_P_P(
863                            groupId, privateLayout, parentLayoutId);
864            }
865    
866            @Override
867            public String[] getTempFileEntryNames(long groupId, String tempFolderName)
868                    throws PortalException, SystemException {
869    
870                    GroupPermissionUtil.check(
871                            getPermissionChecker(), groupId, ActionKeys.EXPORT_IMPORT_LAYOUTS);
872    
873                    return TempFileUtil.getTempFileEntryNames(
874                            groupId, getUserId(), tempFolderName);
875            }
876    
877            /**
878             * Imports the layouts from the byte array.
879             *
880             * @param  groupId the primary key of the group
881             * @param  privateLayout whether the layout is private to the group
882             * @param  parameterMap the mapping of parameters indicating which
883             *         information will be imported. For information on the keys used in
884             *         the map see {@link
885             *         com.liferay.portal.kernel.lar.PortletDataHandlerKeys}.
886             * @param  bytes the byte array with the data
887             * @throws PortalException if a group with the primary key could not be
888             *         found, if the group did not have permission to manage the
889             *         layouts, or if some other portal exception occurred
890             * @throws SystemException if a system exception occurred
891             * @see    com.liferay.portal.lar.LayoutImporter
892             */
893            @Override
894            public void importLayouts(
895                            long groupId, boolean privateLayout,
896                            Map<String, String[]> parameterMap, byte[] bytes)
897                    throws PortalException, SystemException {
898    
899                    GroupPermissionUtil.check(
900                            getPermissionChecker(), groupId, ActionKeys.EXPORT_IMPORT_LAYOUTS);
901    
902                    layoutLocalService.importLayouts(
903                            getUserId(), groupId, privateLayout, parameterMap, bytes);
904            }
905    
906            /**
907             * Imports the layouts from the file.
908             *
909             * @param  groupId the primary key of the group
910             * @param  privateLayout whether the layout is private to the group
911             * @param  parameterMap the mapping of parameters indicating which
912             *         information will be imported. For information on the keys used in
913             *         the map see {@link
914             *         com.liferay.portal.kernel.lar.PortletDataHandlerKeys}.
915             * @param  file the LAR file with the data
916             * @throws PortalException if a group with the primary key could not be
917             *         found, if the group did not have permission to manage the layouts
918             *         and publish, or if some other portal exception occurred
919             * @throws SystemException if a system exception occurred
920             * @see    com.liferay.portal.lar.LayoutImporter
921             */
922            @Override
923            public void importLayouts(
924                            long groupId, boolean privateLayout,
925                            Map<String, String[]> parameterMap, File file)
926                    throws PortalException, SystemException {
927    
928                    GroupPermissionUtil.check(
929                            getPermissionChecker(), groupId, ActionKeys.EXPORT_IMPORT_LAYOUTS);
930    
931                    layoutLocalService.importLayouts(
932                            getUserId(), groupId, privateLayout, parameterMap, file);
933            }
934    
935            /**
936             * Imports the layouts from the input stream.
937             *
938             * @param  groupId the primary key of the group
939             * @param  privateLayout whether the layout is private to the group
940             * @param  parameterMap the mapping of parameters indicating which
941             *         information will be imported. For information on the keys used in
942             *         the map see {@link
943             *         com.liferay.portal.kernel.lar.PortletDataHandlerKeys}.
944             * @param  is the input stream
945             * @throws PortalException if a group with the primary key could not be
946             *         found, if the group did not have permission to manage the
947             *         layouts, or if some other portal exception occurred
948             * @throws SystemException if a system exception occurred
949             * @see    com.liferay.portal.lar.LayoutImporter
950             */
951            @Override
952            public void importLayouts(
953                            long groupId, boolean privateLayout,
954                            Map<String, String[]> parameterMap, InputStream is)
955                    throws PortalException, SystemException {
956    
957                    GroupPermissionUtil.check(
958                            getPermissionChecker(), groupId, ActionKeys.EXPORT_IMPORT_LAYOUTS);
959    
960                    layoutLocalService.importLayouts(
961                            getUserId(), groupId, privateLayout, parameterMap, is);
962            }
963    
964            @Override
965            public long importLayoutsInBackground(
966                            String taskName, long groupId, boolean privateLayout,
967                            Map<String, String[]> parameterMap, File file)
968                    throws PortalException, SystemException {
969    
970                    GroupPermissionUtil.check(
971                            getPermissionChecker(), groupId, ActionKeys.EXPORT_IMPORT_LAYOUTS);
972    
973                    return layoutLocalService.importLayoutsInBackground(
974                            getUserId(), taskName, groupId, privateLayout, parameterMap, file);
975            }
976    
977            @Override
978            public long importLayoutsInBackground(
979                            String taskName, long groupId, boolean privateLayout,
980                            Map<String, String[]> parameterMap, InputStream inputStream)
981                    throws PortalException, SystemException {
982    
983                    GroupPermissionUtil.check(
984                            getPermissionChecker(), groupId, ActionKeys.EXPORT_IMPORT_LAYOUTS);
985    
986                    return layoutLocalService.importLayoutsInBackground(
987                            getUserId(), taskName, groupId, privateLayout, parameterMap,
988                            inputStream);
989            }
990    
991            /**
992             * Imports the portlet information (categories, permissions, ... etc.) from
993             * the file.
994             *
995             * @param  plid the primary key of the layout
996             * @param  groupId the primary key of the group
997             * @param  portletId the primary key of the portlet
998             * @param  parameterMap the mapping of parameters indicating which
999             *         information will be imported. For information on the keys used in
1000             *         the map see {@link
1001             *         com.liferay.portal.kernel.lar.PortletDataHandlerKeys}.
1002             * @param  file the LAR file with the data
1003             * @throws PortalException if a group, layout, or portlet with the primary
1004             *         key could not be found, or if the group did not have permission
1005             *         to manage the layouts
1006             * @throws SystemException if a system exception occurred
1007             */
1008            @Override
1009            public void importPortletInfo(
1010                            long plid, long groupId, String portletId,
1011                            Map<String, String[]> parameterMap, File file)
1012                    throws PortalException, SystemException {
1013    
1014                    GroupPermissionUtil.check(
1015                            getPermissionChecker(), groupId,
1016                            ActionKeys.EXPORT_IMPORT_PORTLET_INFO);
1017    
1018                    layoutLocalService.importPortletInfo(
1019                            getUserId(), plid, groupId, portletId, parameterMap, file);
1020            }
1021    
1022            /**
1023             * Imports the portlet information (categories, permissions, ... etc.) from
1024             * the input stream.
1025             *
1026             * @param  plid the primary key of the layout
1027             * @param  groupId the primary key of the group
1028             * @param  portletId the primary key of the portlet
1029             * @param  parameterMap the mapping of parameters indicating which
1030             *         information will be imported. For information on the keys used in
1031             *         the map see {@link
1032             *         com.liferay.portal.kernel.lar.PortletDataHandlerKeys}.
1033             * @param  is the input stream
1034             * @throws PortalException if a group, portlet, or layout with the primary
1035             *         key could not be found or if the group did not have permission to
1036             *         manage the layouts
1037             * @throws SystemException if a system exception occurred
1038             */
1039            @Override
1040            public void importPortletInfo(
1041                            long plid, long groupId, String portletId,
1042                            Map<String, String[]> parameterMap, InputStream is)
1043                    throws PortalException, SystemException {
1044    
1045                    GroupPermissionUtil.check(
1046                            getPermissionChecker(), groupId,
1047                            ActionKeys.EXPORT_IMPORT_PORTLET_INFO);
1048    
1049                    layoutLocalService.importPortletInfo(
1050                            getUserId(), plid, groupId, portletId, parameterMap, is);
1051            }
1052    
1053            @Override
1054            public void importPortletInfo(
1055                            String portletId, Map<String, String[]> parameterMap, File file)
1056                    throws PortalException, SystemException {
1057    
1058                    User user = userPersistence.findByPrimaryKey(getUserId());
1059    
1060                    Group companyGroup = groupLocalService.getCompanyGroup(
1061                            user.getCompanyId());
1062    
1063                    GroupPermissionUtil.check(
1064                            getPermissionChecker(), companyGroup.getGroupId(),
1065                            ActionKeys.EXPORT_IMPORT_PORTLET_INFO);
1066    
1067                    layoutLocalService.importPortletInfo(
1068                            getUserId(), portletId, parameterMap, file);
1069            }
1070    
1071            @Override
1072            public void importPortletInfo(
1073                            String portletId, Map<String, String[]> parameterMap,
1074                            InputStream is)
1075                    throws PortalException, SystemException {
1076    
1077                    User user = userPersistence.findByPrimaryKey(getUserId());
1078    
1079                    Group companyGroup = groupLocalService.getCompanyGroup(
1080                            user.getCompanyId());
1081    
1082                    GroupPermissionUtil.check(
1083                            getPermissionChecker(), companyGroup.getGroupId(),
1084                            ActionKeys.EXPORT_IMPORT_PORTLET_INFO);
1085    
1086                    layoutLocalService.importPortletInfo(
1087                            getUserId(), portletId, parameterMap, is);
1088            }
1089    
1090            @Override
1091            public long importPortletInfoInBackground(
1092                            String taskName, long plid, long groupId, String portletId,
1093                            Map<String, String[]> parameterMap, File file)
1094                    throws PortalException, SystemException {
1095    
1096                    GroupPermissionUtil.check(
1097                            getPermissionChecker(), groupId,
1098                            ActionKeys.EXPORT_IMPORT_PORTLET_INFO);
1099    
1100                    return layoutLocalService.importPortletInfoInBackground(
1101                            getUserId(), taskName, plid, groupId, portletId, parameterMap,
1102                            file);
1103            }
1104    
1105            @Override
1106            public long importPortletInfoInBackground(
1107                            String taskName, long plid, long groupId, String portletId,
1108                            Map<String, String[]> parameterMap, InputStream is)
1109                    throws PortalException, SystemException {
1110    
1111                    GroupPermissionUtil.check(
1112                            getPermissionChecker(), groupId,
1113                            ActionKeys.EXPORT_IMPORT_PORTLET_INFO);
1114    
1115                    return layoutLocalService.importPortletInfoInBackground(
1116                            getUserId(), taskName, plid, groupId, portletId, parameterMap, is);
1117            }
1118    
1119            @Override
1120            public void importPortletInfoInBackground(
1121                            String taskName, String portletId,
1122                            Map<String, String[]> parameterMap, File file)
1123                    throws PortalException, SystemException {
1124    
1125                    User user = userPersistence.findByPrimaryKey(getUserId());
1126    
1127                    Group companyGroup = groupLocalService.getCompanyGroup(
1128                            user.getCompanyId());
1129    
1130                    GroupPermissionUtil.check(
1131                            getPermissionChecker(), companyGroup.getGroupId(),
1132                            ActionKeys.EXPORT_IMPORT_PORTLET_INFO);
1133    
1134                    layoutLocalService.importPortletInfoInBackground(
1135                            getUserId(), taskName, portletId, parameterMap, file);
1136            }
1137    
1138            @Override
1139            public void importPortletInfoInBackground(
1140                            String taskName, String portletId,
1141                            Map<String, String[]> parameterMap, InputStream is)
1142                    throws PortalException, SystemException {
1143    
1144                    User user = userPersistence.findByPrimaryKey(getUserId());
1145    
1146                    Group companyGroup = groupLocalService.getCompanyGroup(
1147                            user.getCompanyId());
1148    
1149                    GroupPermissionUtil.check(
1150                            getPermissionChecker(), companyGroup.getGroupId(),
1151                            ActionKeys.EXPORT_IMPORT_PORTLET_INFO);
1152    
1153                    layoutLocalService.importPortletInfoInBackground(
1154                            getUserId(), taskName, portletId, parameterMap, is);
1155            }
1156    
1157            /**
1158             * Schedules a range of layouts to be published.
1159             *
1160             * @param  sourceGroupId the primary key of the source group
1161             * @param  targetGroupId the primary key of the target group
1162             * @param  privateLayout whether the layout is private to the group
1163             * @param  layoutIdMap the layouts considered for publishing, specified by
1164             *         the layout IDs and booleans indicating whether they have children
1165             * @param  parameterMap the mapping of parameters indicating which
1166             *         information will be used. See {@link
1167             *         com.liferay.portal.kernel.lar.PortletDataHandlerKeys}
1168             * @param  scope the scope of the pages. It can be <code>all-pages</code> or
1169             *         <code>selected-pages</code>.
1170             * @param  startDate the start date
1171             * @param  endDate the end date
1172             * @param  groupName the group name (optionally {@link
1173             *         com.liferay.portal.kernel.messaging.DestinationNames#LAYOUTS_LOCAL_PUBLISHER}).
1174             *         See {@link com.liferay.portal.kernel.messaging.DestinationNames}.
1175             * @param  cronText the cron text. See {@link
1176             *         com.liferay.portal.kernel.cal.RecurrenceSerializer #toCronText}
1177             * @param  schedulerStartDate the scheduler start date
1178             * @param  schedulerEndDate the scheduler end date
1179             * @param  description the scheduler description
1180             * @throws PortalException if the group did not have permission to manage
1181             *         and publish
1182             * @throws SystemException if a system exception occurred
1183             */
1184            @Override
1185            public void schedulePublishToLive(
1186                            long sourceGroupId, long targetGroupId, boolean privateLayout,
1187                            Map<Long, Boolean> layoutIdMap, Map<String, String[]> parameterMap,
1188                            String scope, Date startDate, Date endDate, String groupName,
1189                            String cronText, Date schedulerStartDate, Date schedulerEndDate,
1190                            String description)
1191                    throws PortalException, SystemException {
1192    
1193                    GroupPermissionUtil.check(
1194                            getPermissionChecker(), targetGroupId, ActionKeys.PUBLISH_STAGING);
1195    
1196                    String jobName = PortalUUIDUtil.generate();
1197    
1198                    Trigger trigger = new CronTrigger(
1199                            jobName, groupName, schedulerStartDate, schedulerEndDate, cronText);
1200    
1201                    String command = StringPool.BLANK;
1202    
1203                    if (scope.equals("all-pages")) {
1204                            command = LayoutsLocalPublisherRequest.COMMAND_ALL_PAGES;
1205                    }
1206                    else if (scope.equals("selected-pages")) {
1207                            command = LayoutsLocalPublisherRequest.COMMAND_SELECTED_PAGES;
1208                    }
1209    
1210                    LayoutsLocalPublisherRequest publisherRequest =
1211                            new LayoutsLocalPublisherRequest(
1212                                    command, getUserId(), sourceGroupId, targetGroupId,
1213                                    privateLayout, layoutIdMap, parameterMap, startDate, endDate);
1214    
1215                    SchedulerEngineHelperUtil.schedule(
1216                            trigger, StorageType.PERSISTED, description,
1217                            DestinationNames.LAYOUTS_LOCAL_PUBLISHER, publisherRequest, 0);
1218            }
1219    
1220            /**
1221             * Schedules a range of layouts to be stored.
1222             *
1223             * @param  sourceGroupId the primary key of the source group
1224             * @param  privateLayout whether the layout is private to the group
1225             * @param  layoutIdMap the layouts considered for publishing, specified by
1226             *         the layout IDs and booleans indicating whether they have children
1227             * @param  parameterMap the mapping of parameters indicating which
1228             *         information will be used. See {@link
1229             *         com.liferay.portal.kernel.lar.PortletDataHandlerKeys}
1230             * @param  remoteAddress the remote address
1231             * @param  remotePort the remote port
1232             * @param  remotePathContext the remote path context
1233             * @param  secureConnection whether the connection is secure
1234             * @param  remoteGroupId the primary key of the remote group
1235             * @param  remotePrivateLayout whether remote group's layout is private
1236             * @param  startDate the start date
1237             * @param  endDate the end date
1238             * @param  groupName the group name. Optionally {@link
1239             *         com.liferay.portal.kernel.messaging.DestinationNames#LAYOUTS_LOCAL_PUBLISHER}).
1240             *         See {@link com.liferay.portal.kernel.messaging.DestinationNames}.
1241             * @param  cronText the cron text. See {@link
1242             *         com.liferay.portal.kernel.cal.RecurrenceSerializer #toCronText}
1243             * @param  schedulerStartDate the scheduler start date
1244             * @param  schedulerEndDate the scheduler end date
1245             * @param  description the scheduler description
1246             * @throws PortalException if a group with the source group primary key was
1247             *         not found or if the group did not have permission to publish
1248             * @throws SystemException if a system exception occurred
1249             */
1250            @Override
1251            public void schedulePublishToRemote(
1252                            long sourceGroupId, boolean privateLayout,
1253                            Map<Long, Boolean> layoutIdMap, Map<String, String[]> parameterMap,
1254                            String remoteAddress, int remotePort, String remotePathContext,
1255                            boolean secureConnection, long remoteGroupId,
1256                            boolean remotePrivateLayout, Date startDate, Date endDate,
1257                            String groupName, String cronText, Date schedulerStartDate,
1258                            Date schedulerEndDate, String description)
1259                    throws PortalException, SystemException {
1260    
1261                    GroupPermissionUtil.check(
1262                            getPermissionChecker(), sourceGroupId, ActionKeys.PUBLISH_STAGING);
1263    
1264                    LayoutsRemotePublisherRequest publisherRequest =
1265                            new LayoutsRemotePublisherRequest(
1266                                    getUserId(), sourceGroupId, privateLayout, layoutIdMap,
1267                                    parameterMap, remoteAddress, remotePort, remotePathContext,
1268                                    secureConnection, remoteGroupId, remotePrivateLayout, startDate,
1269                                    endDate);
1270    
1271                    String jobName = PortalUUIDUtil.generate();
1272    
1273                    Trigger trigger = new CronTrigger(
1274                            jobName, groupName, schedulerStartDate, schedulerEndDate, cronText);
1275    
1276                    SchedulerEngineHelperUtil.schedule(
1277                            trigger, StorageType.PERSISTED, description,
1278                            DestinationNames.LAYOUTS_REMOTE_PUBLISHER, publisherRequest, 0);
1279            }
1280    
1281            /**
1282             * Sets the layouts for the group, replacing and prioritizing all layouts of
1283             * the parent layout.
1284             *
1285             * @param  groupId the primary key of the group
1286             * @param  privateLayout whether the layout is private to the group
1287             * @param  parentLayoutId the primary key of the parent layout
1288             * @param  layoutIds the primary keys of the layouts
1289             * @param  serviceContext the service context to be applied
1290             * @throws PortalException if a group or layout with the primary key could
1291             *         not be found, if the group did not have permission to manage the
1292             *         layouts, if no layouts were specified, if the first layout was
1293             *         not page-able, if the first layout was hidden, or if some other
1294             *         portal exception occurred
1295             * @throws SystemException if a system exception occurred
1296             */
1297            @Override
1298            public void setLayouts(
1299                            long groupId, boolean privateLayout, long parentLayoutId,
1300                            long[] layoutIds, ServiceContext serviceContext)
1301                    throws PortalException, SystemException {
1302    
1303                    GroupPermissionUtil.check(
1304                            getPermissionChecker(), groupId, ActionKeys.UPDATE);
1305    
1306                    layoutLocalService.setLayouts(
1307                            groupId, privateLayout, parentLayoutId, layoutIds, serviceContext);
1308            }
1309    
1310            /**
1311             * Deletes the job from the scheduler's queue.
1312             *
1313             * @param  groupId the primary key of the group
1314             * @param  jobName the job name
1315             * @param  groupName the group name (optionally {@link
1316             *         com.liferay.portal.kernel.messaging.DestinationNames#LAYOUTS_LOCAL_PUBLISHER}).
1317             *         See {@link com.liferay.portal.kernel.messaging.DestinationNames}.
1318             * @throws PortalException if the group did not permission to manage staging
1319             *         and publish
1320             * @throws SystemException if a system exception occurred
1321             */
1322            @Override
1323            public void unschedulePublishToLive(
1324                            long groupId, String jobName, String groupName)
1325                    throws PortalException, SystemException {
1326    
1327                    GroupPermissionUtil.check(
1328                            getPermissionChecker(), groupId, ActionKeys.PUBLISH_STAGING);
1329    
1330                    SchedulerEngineHelperUtil.delete(
1331                            jobName, groupName, StorageType.PERSISTED);
1332            }
1333    
1334            /**
1335             * Deletes the job from the scheduler's persistent queue.
1336             *
1337             * @param  groupId the primary key of the group
1338             * @param  jobName the job name
1339             * @param  groupName the group name (optionally {@link
1340             *         com.liferay.portal.kernel.messaging.DestinationNames#LAYOUTS_LOCAL_PUBLISHER}).
1341             *         See {@link com.liferay.portal.kernel.messaging.DestinationNames}.
1342             * @throws PortalException if a group with the primary key could not be
1343             *         found or if the group did not have permission to publish
1344             * @throws SystemException if a system exception occurred
1345             */
1346            @Override
1347            public void unschedulePublishToRemote(
1348                            long groupId, String jobName, String groupName)
1349                    throws PortalException, SystemException {
1350    
1351                    GroupPermissionUtil.check(
1352                            getPermissionChecker(), groupId, ActionKeys.PUBLISH_STAGING);
1353    
1354                    SchedulerEngineHelperUtil.delete(
1355                            jobName, groupName, StorageType.PERSISTED);
1356            }
1357    
1358            /**
1359             * Updates the layout with additional parameters.
1360             *
1361             * @param  groupId the primary key of the group
1362             * @param  privateLayout whether the layout is private to the group
1363             * @param  layoutId the primary key of the layout
1364             * @param  parentLayoutId the primary key of the layout's new parent layout
1365             * @param  localeNamesMap the layout's locales and localized names
1366             * @param  localeTitlesMap the layout's locales and localized titles
1367             * @param  descriptionMap the locales and localized descriptions to merge
1368             *         (optionally <code>null</code>)
1369             * @param  keywordsMap the locales and localized keywords to merge
1370             *         (optionally <code>null</code>)
1371             * @param  robotsMap the locales and localized robots to merge (optionally
1372             *         <code>null</code>)
1373             * @param  type the layout's new type (optionally {@link
1374             *         com.liferay.portal.model.LayoutConstants#TYPE_PORTLET})
1375             * @param  hidden whether the layout is hidden
1376             * @param  friendlyURLMap the layout's locales and localized friendly URLs.
1377             *         To see how the URL is normalized when accessed see {@link
1378             *         com.liferay.portal.kernel.util.FriendlyURLNormalizerUtil#normalize(
1379             *         String)}.
1380             * @param  iconImage whether the icon image will be updated
1381             * @param  iconBytes the byte array of the layout's new icon image
1382             * @param  serviceContext the service context to be applied. Can set the
1383             *         modification date and expando bridge attributes for the layout.
1384             * @return the updated layout
1385             * @throws PortalException if a group or layout with the primary key could
1386             *         not be found, if the user did not have permission to update the
1387             *         layout, if a unique friendly URL could not be generated, if a
1388             *         valid parent layout ID to use could not be found, or if the
1389             *         layout parameters were invalid
1390             * @throws SystemException if a system exception occurred
1391             */
1392            @Override
1393            public Layout updateLayout(
1394                            long groupId, boolean privateLayout, long layoutId,
1395                            long parentLayoutId, Map<Locale, String> localeNamesMap,
1396                            Map<Locale, String> localeTitlesMap,
1397                            Map<Locale, String> descriptionMap, Map<Locale, String> keywordsMap,
1398                            Map<Locale, String> robotsMap, String type, boolean hidden,
1399                            Map<Locale, String> friendlyURLMap, Boolean iconImage,
1400                            byte[] iconBytes, ServiceContext serviceContext)
1401                    throws PortalException, SystemException {
1402    
1403                    LayoutPermissionUtil.check(
1404                            getPermissionChecker(), groupId, privateLayout, layoutId,
1405                            ActionKeys.UPDATE);
1406    
1407                    return layoutLocalService.updateLayout(
1408                            groupId, privateLayout, layoutId, parentLayoutId, localeNamesMap,
1409                            localeTitlesMap, descriptionMap, keywordsMap, robotsMap, type,
1410                            hidden, friendlyURLMap, iconImage, iconBytes, serviceContext);
1411            }
1412    
1413            /**
1414             * Updates the layout with additional parameters.
1415             *
1416             * @param      groupId the primary key of the group
1417             * @param      privateLayout whether the layout is private to the group
1418             * @param      layoutId the primary key of the layout
1419             * @param      parentLayoutId the primary key of the layout's new parent
1420             *             layout
1421             * @param      localeNamesMap the layout's locales and localized names
1422             * @param      localeTitlesMap the layout's locales and localized titles
1423             * @param      descriptionMap the locales and localized descriptions to
1424             *             merge (optionally <code>null</code>)
1425             * @param      keywordsMap the locales and localized keywords to merge
1426             *             (optionally <code>null</code>)
1427             * @param      robotsMap the locales and localized robots to merge
1428             *             (optionally <code>null</code>)
1429             * @param      type the layout's new type (optionally {@link
1430             *             com.liferay.portal.model.LayoutConstants#TYPE_PORTLET})
1431             * @param      hidden whether the layout is hidden
1432             * @param      friendlyURL the layout's locales and new friendly URLs. To
1433             *             see how the URL is normalized when accessed, see {@link
1434             *             com.liferay.portal.kernel.util.FriendlyURLNormalizerUtil#normalize(
1435             *             String)}.
1436             * @param      iconImage whether the icon image will be updated
1437             * @param      iconBytes the byte array of the layout's new icon image
1438             * @param      serviceContext the service context to be applied. Can set the
1439             *             modification date and expando bridge attributes for the
1440             *             layout.
1441             * @return     the updated layout
1442             * @throws     PortalException if a group or layout with the primary key
1443             *             could not be found, if the user did not have permission to
1444             *             update the layout, if a unique friendly URL could not be
1445             *             generated, if a valid parent layout ID to use could not be
1446             *             found, or if the layout parameters were invalid
1447             * @throws     SystemException if a system exception occurred
1448             * @deprecated As of 6.2.0, replaced by {@link #updateLayout(long, boolean,
1449             *             long, long, Map, Map, Map, Map, Map, String, boolean, Map,
1450             *             Boolean, byte[], ServiceContext)}
1451             */
1452            @Override
1453            public Layout updateLayout(
1454                            long groupId, boolean privateLayout, long layoutId,
1455                            long parentLayoutId, Map<Locale, String> localeNamesMap,
1456                            Map<Locale, String> localeTitlesMap,
1457                            Map<Locale, String> descriptionMap, Map<Locale, String> keywordsMap,
1458                            Map<Locale, String> robotsMap, String type, boolean hidden,
1459                            String friendlyURL, Boolean iconImage, byte[] iconBytes,
1460                            ServiceContext serviceContext)
1461                    throws PortalException, SystemException {
1462    
1463                    LayoutPermissionUtil.check(
1464                            getPermissionChecker(), groupId, privateLayout, layoutId,
1465                            ActionKeys.UPDATE);
1466    
1467                    return layoutLocalService.updateLayout(
1468                            groupId, privateLayout, layoutId, parentLayoutId, localeNamesMap,
1469                            localeTitlesMap, descriptionMap, keywordsMap, robotsMap, type,
1470                            hidden, friendlyURL, iconImage, iconBytes, serviceContext);
1471            }
1472    
1473            /**
1474             * Updates the layout replacing its type settings.
1475             *
1476             * @param  groupId the primary key of the group
1477             * @param  privateLayout whether the layout is private to the group
1478             * @param  layoutId the primary key of the layout
1479             * @param  typeSettings the settings to load the unicode properties object.
1480             *         See {@link com.liferay.portal.kernel.util.UnicodeProperties
1481             *         #fastLoad(String)}.
1482             * @return the updated layout
1483             * @throws PortalException if a matching layout could not be found or if the
1484             *         user did not have permission to update the layout
1485             * @throws SystemException if a system exception occurred
1486             */
1487            @Override
1488            public Layout updateLayout(
1489                            long groupId, boolean privateLayout, long layoutId,
1490                            String typeSettings)
1491                    throws PortalException, SystemException {
1492    
1493                    LayoutPermissionUtil.check(
1494                            getPermissionChecker(), groupId, privateLayout, layoutId,
1495                            ActionKeys.UPDATE);
1496    
1497                    return layoutLocalService.updateLayout(
1498                            groupId, privateLayout, layoutId, typeSettings);
1499            }
1500    
1501            /**
1502             * Updates the look and feel of the layout.
1503             *
1504             * @param  groupId the primary key of the group
1505             * @param  privateLayout whether the layout is private to the group
1506             * @param  layoutId the primary key of the layout
1507             * @param  themeId the primary key of the layout's new theme
1508             * @param  colorSchemeId the primary key of the layout's new color scheme
1509             * @param  css the layout's new CSS
1510             * @param  wapTheme whether the theme is for WAP browsers
1511             * @return the updated layout
1512             * @throws PortalException if a matching layout could not be found, or if
1513             *         the user did not have permission to update the layout and
1514             *         permission to apply the theme
1515             * @throws SystemException if a system exception occurred
1516             */
1517            @Override
1518            public Layout updateLookAndFeel(
1519                            long groupId, boolean privateLayout, long layoutId, String themeId,
1520                            String colorSchemeId, String css, boolean wapTheme)
1521                    throws PortalException, SystemException {
1522    
1523                    LayoutPermissionUtil.check(
1524                            getPermissionChecker(), groupId, privateLayout, layoutId,
1525                            ActionKeys.UPDATE);
1526    
1527                    if (Validator.isNotNull(themeId)) {
1528                            pluginSettingLocalService.checkPermission(
1529                                    getUserId(), themeId, Plugin.TYPE_THEME);
1530                    }
1531    
1532                    return layoutLocalService.updateLookAndFeel(
1533                            groupId, privateLayout, layoutId, themeId, colorSchemeId, css,
1534                            wapTheme);
1535            }
1536    
1537            /**
1538             * Updates the name of the layout matching the group, layout ID, and
1539             * privacy.
1540             *
1541             * @param  groupId the primary key of the group
1542             * @param  privateLayout whether the layout is private to the group
1543             * @param  layoutId the primary key of the layout
1544             * @param  name the layout's new name
1545             * @param  languageId the primary key of the language. For more information
1546             *         see {@link java.util.Locale}.
1547             * @return the updated layout
1548             * @throws PortalException if a matching layout could not be found, if the
1549             *         user did not have permission to update the layout, or if the new
1550             *         name was <code>null</code>
1551             * @throws SystemException if a system exception occurred
1552             */
1553            @Override
1554            public Layout updateName(
1555                            long groupId, boolean privateLayout, long layoutId, String name,
1556                            String languageId)
1557                    throws PortalException, SystemException {
1558    
1559                    LayoutPermissionUtil.check(
1560                            getPermissionChecker(), groupId, privateLayout, layoutId,
1561                            ActionKeys.UPDATE);
1562    
1563                    return layoutLocalService.updateName(
1564                            groupId, privateLayout, layoutId, name, languageId);
1565            }
1566    
1567            /**
1568             * Updates the name of the layout matching the primary key.
1569             *
1570             * @param  plid the primary key of the layout
1571             * @param  name the name to be assigned
1572             * @param  languageId the primary key of the language. For more information
1573             *         see {@link java.util.Locale}.
1574             * @return the updated layout
1575             * @throws PortalException if a layout with the primary key could not be
1576             *         found, or if the user did not have permission to update the
1577             *         layout, or if the name was <code>null</code>
1578             * @throws SystemException if a system exception occurred
1579             */
1580            @Override
1581            public Layout updateName(long plid, String name, String languageId)
1582                    throws PortalException, SystemException {
1583    
1584                    LayoutPermissionUtil.check(
1585                            getPermissionChecker(), plid, ActionKeys.UPDATE);
1586    
1587                    return layoutLocalService.updateName(plid, name, languageId);
1588            }
1589    
1590            /**
1591             * Updates the parent layout ID of the layout matching the group, layout ID,
1592             * and privacy.
1593             *
1594             * @param  groupId the primary key of the group
1595             * @param  privateLayout whether the layout is private to the group
1596             * @param  layoutId the primary key of the layout
1597             * @param  parentLayoutId the primary key to be assigned to the parent
1598             *         layout
1599             * @return the matching layout
1600             * @throws PortalException if a valid parent layout ID to use could not be
1601             *         found, if a matching layout could not be found, or if the user
1602             *         did not have permission to update the layout
1603             * @throws SystemException if a system exception occurred
1604             */
1605            @Override
1606            public Layout updateParentLayoutId(
1607                            long groupId, boolean privateLayout, long layoutId,
1608                            long parentLayoutId)
1609                    throws PortalException, SystemException {
1610    
1611                    LayoutPermissionUtil.check(
1612                            getPermissionChecker(), groupId, privateLayout, layoutId,
1613                            ActionKeys.UPDATE);
1614    
1615                    return layoutLocalService.updateParentLayoutId(
1616                            groupId, privateLayout, layoutId, parentLayoutId);
1617            }
1618    
1619            /**
1620             * Updates the parent layout ID of the layout matching the primary key. If a
1621             * layout matching the parent primary key is found, the layout ID of that
1622             * layout is assigned, otherwise {@link
1623             * com.liferay.portal.model.LayoutConstants#DEFAULT_PARENT_LAYOUT_ID} is
1624             * assigned.
1625             *
1626             * @param  plid the primary key of the layout
1627             * @param  parentPlid the primary key of the parent layout
1628             * @return the layout matching the primary key
1629             * @throws PortalException if a layout with the primary key could not be
1630             *         found, if the user did not have permission to update the layout,
1631             *         or if a valid parent layout ID to use could not be found
1632             * @throws SystemException if a system exception occurred
1633             */
1634            @Override
1635            public Layout updateParentLayoutId(long plid, long parentPlid)
1636                    throws PortalException, SystemException {
1637    
1638                    LayoutPermissionUtil.check(
1639                            getPermissionChecker(), plid, ActionKeys.UPDATE);
1640    
1641                    return layoutLocalService.updateParentLayoutId(plid, parentPlid);
1642            }
1643    
1644            @Override
1645            public Layout updateParentLayoutIdAndPriority(
1646                            long plid, long parentPlid, int priority)
1647                    throws PortalException, SystemException {
1648    
1649                    return layoutLocalService.updateParentLayoutIdAndPriority(
1650                            plid, parentPlid, priority);
1651            }
1652    
1653            /**
1654             * Updates the priority of the layout matching the group, layout ID, and
1655             * privacy.
1656             *
1657             * @param  groupId the primary key of the group
1658             * @param  privateLayout whether the layout is private to the group
1659             * @param  layoutId the primary key of the layout
1660             * @param  priority the layout's new priority
1661             * @return the updated layout
1662             * @throws PortalException if a matching layout could not be found or if the
1663             *         user did not have permission to update the layout
1664             * @throws SystemException if a system exception occurred
1665             */
1666            @Override
1667            public Layout updatePriority(
1668                            long groupId, boolean privateLayout, long layoutId, int priority)
1669                    throws PortalException, SystemException {
1670    
1671                    LayoutPermissionUtil.check(
1672                            getPermissionChecker(), groupId, privateLayout, layoutId,
1673                            ActionKeys.UPDATE);
1674    
1675                    return layoutLocalService.updatePriority(
1676                            groupId, privateLayout, layoutId, priority);
1677            }
1678    
1679            /**
1680             * Updates the priority of the layout matching the group, layout ID, and
1681             * privacy, setting the layout's priority based on the priorities of the
1682             * next and previous layouts.
1683             *
1684             * @param  groupId the primary key of the group
1685             * @param  privateLayout whether the layout is private to the group
1686             * @param  layoutId the primary key of the layout
1687             * @param  nextLayoutId the primary key of the next layout
1688             * @param  previousLayoutId the primary key of the previous layout
1689             * @return the updated layout
1690             * @throws PortalException if a matching layout could not be found or if the
1691             *         user did not have permission to update the layout
1692             * @throws SystemException if a system exception occurred
1693             */
1694            @Override
1695            public Layout updatePriority(
1696                            long groupId, boolean privateLayout, long layoutId,
1697                            long nextLayoutId, long previousLayoutId)
1698                    throws PortalException, SystemException {
1699    
1700                    LayoutPermissionUtil.check(
1701                            getPermissionChecker(), groupId, privateLayout, layoutId,
1702                            ActionKeys.UPDATE);
1703    
1704                    return layoutLocalService.updatePriority(
1705                            groupId, privateLayout, layoutId, nextLayoutId, previousLayoutId);
1706            }
1707    
1708            /**
1709             * Updates the priority of the layout matching the primary key.
1710             *
1711             * @param  plid the primary key of the layout
1712             * @param  priority the layout's new priority
1713             * @return the updated layout
1714             * @throws PortalException if a layout with the primary key could not be
1715             *         found
1716             * @throws SystemException if a system exception occurred
1717             */
1718            @Override
1719            public Layout updatePriority(long plid, int priority)
1720                    throws PortalException, SystemException {
1721    
1722                    LayoutPermissionUtil.check(
1723                            getPermissionChecker(), plid, ActionKeys.UPDATE);
1724    
1725                    return layoutLocalService.updatePriority(plid, priority);
1726            }
1727    
1728            @Override
1729            public MissingReferences validateImportLayoutsFile(
1730                            long groupId, boolean privateLayout,
1731                            Map<String, String[]> parameterMap, File file)
1732                    throws PortalException, SystemException {
1733    
1734                    GroupPermissionUtil.check(
1735                            getPermissionChecker(), groupId, ActionKeys.EXPORT_IMPORT_LAYOUTS);
1736    
1737                    return layoutLocalService.validateImportLayoutsFile(
1738                            getUserId(), groupId, privateLayout, parameterMap, file);
1739            }
1740    
1741            @Override
1742            public MissingReferences validateImportLayoutsFile(
1743                            long groupId, boolean privateLayout,
1744                            Map<String, String[]> parameterMap, InputStream inputStream)
1745                    throws PortalException, SystemException {
1746    
1747                    GroupPermissionUtil.check(
1748                            getPermissionChecker(), groupId, ActionKeys.EXPORT_IMPORT_LAYOUTS);
1749    
1750                    return layoutLocalService.validateImportLayoutsFile(
1751                            getUserId(), groupId, privateLayout, parameterMap, inputStream);
1752            }
1753    
1754            @Override
1755            public MissingReferences validateImportPortletInfo(
1756                            long plid, long groupId, String portletId,
1757                            Map<String, String[]> parameterMap, File file)
1758                    throws PortalException, SystemException {
1759    
1760                    PortletPermissionUtil.check(
1761                            getPermissionChecker(), plid, portletId, ActionKeys.CONFIGURATION);
1762    
1763                    return layoutLocalService.validateImportPortletInfo(
1764                            getUserId(), plid, groupId, portletId, parameterMap, file);
1765            }
1766    
1767            @Override
1768            public MissingReferences validateImportPortletInfo(
1769                            long plid, long groupId, String portletId,
1770                            Map<String, String[]> parameterMap, InputStream inputStream)
1771                    throws PortalException, SystemException {
1772    
1773                    PortletPermissionUtil.check(
1774                            getPermissionChecker(), plid, portletId, ActionKeys.CONFIGURATION);
1775    
1776                    return layoutLocalService.validateImportPortletInfo(
1777                            getUserId(), plid, groupId, portletId, parameterMap, inputStream);
1778            }
1779    
1780            protected List<Layout> filterLayouts(List<Layout> layouts)
1781                    throws PortalException, SystemException {
1782    
1783                    List<Layout> filteredLayouts = new ArrayList<Layout>();
1784    
1785                    for (Layout layout : layouts) {
1786                            if (LayoutPermissionUtil.contains(
1787                                            getPermissionChecker(), layout.getPlid(),
1788                                            ActionKeys.VIEW)) {
1789    
1790                                    filteredLayouts.add(layout);
1791                            }
1792                    }
1793    
1794                    return filteredLayouts;
1795            }
1796    
1797    }