001    /**
002     * Copyright (c) 2000-2012 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.LocaleException;
018    import com.liferay.portal.NoSuchLayoutException;
019    import com.liferay.portal.RequiredLayoutException;
020    import com.liferay.portal.kernel.bean.BeanReference;
021    import com.liferay.portal.kernel.dao.orm.Criterion;
022    import com.liferay.portal.kernel.dao.orm.DynamicQuery;
023    import com.liferay.portal.kernel.dao.orm.DynamicQueryFactoryUtil;
024    import com.liferay.portal.kernel.dao.orm.Junction;
025    import com.liferay.portal.kernel.dao.orm.Projection;
026    import com.liferay.portal.kernel.dao.orm.ProjectionFactoryUtil;
027    import com.liferay.portal.kernel.dao.orm.Property;
028    import com.liferay.portal.kernel.dao.orm.PropertyFactoryUtil;
029    import com.liferay.portal.kernel.dao.orm.RestrictionsFactoryUtil;
030    import com.liferay.portal.kernel.exception.PortalException;
031    import com.liferay.portal.kernel.exception.SystemException;
032    import com.liferay.portal.kernel.io.unsync.UnsyncByteArrayInputStream;
033    import com.liferay.portal.kernel.language.LanguageUtil;
034    import com.liferay.portal.kernel.util.FileUtil;
035    import com.liferay.portal.kernel.util.GetterUtil;
036    import com.liferay.portal.kernel.util.ListUtil;
037    import com.liferay.portal.kernel.util.LocaleUtil;
038    import com.liferay.portal.kernel.util.LocalizationUtil;
039    import com.liferay.portal.kernel.util.ParamUtil;
040    import com.liferay.portal.kernel.util.StringBundler;
041    import com.liferay.portal.kernel.util.StringPool;
042    import com.liferay.portal.kernel.util.UnicodeProperties;
043    import com.liferay.portal.kernel.util.Validator;
044    import com.liferay.portal.kernel.workflow.WorkflowConstants;
045    import com.liferay.portal.lar.LayoutExporter;
046    import com.liferay.portal.lar.LayoutImporter;
047    import com.liferay.portal.lar.PortletExporter;
048    import com.liferay.portal.lar.PortletImporter;
049    import com.liferay.portal.model.Group;
050    import com.liferay.portal.model.Layout;
051    import com.liferay.portal.model.LayoutConstants;
052    import com.liferay.portal.model.LayoutPrototype;
053    import com.liferay.portal.model.LayoutReference;
054    import com.liferay.portal.model.LayoutSet;
055    import com.liferay.portal.model.LayoutSetPrototype;
056    import com.liferay.portal.model.LayoutTypePortlet;
057    import com.liferay.portal.model.Portlet;
058    import com.liferay.portal.model.PortletConstants;
059    import com.liferay.portal.model.PortletPreferences;
060    import com.liferay.portal.model.ResourceConstants;
061    import com.liferay.portal.model.ResourcePermission;
062    import com.liferay.portal.model.User;
063    import com.liferay.portal.model.UserGroup;
064    import com.liferay.portal.model.impl.LayoutImpl;
065    import com.liferay.portal.model.impl.PortletPreferencesImpl;
066    import com.liferay.portal.service.ServiceContext;
067    import com.liferay.portal.service.base.LayoutLocalServiceBaseImpl;
068    import com.liferay.portal.util.ClassLoaderUtil;
069    import com.liferay.portal.util.PortalUtil;
070    import com.liferay.portal.util.PropsValues;
071    import com.liferay.portal.util.comparator.LayoutComparator;
072    import com.liferay.portal.util.comparator.LayoutPriorityComparator;
073    import com.liferay.portlet.PortletPreferencesFactoryUtil;
074    import com.liferay.portlet.expando.model.ExpandoBridge;
075    import com.liferay.portlet.mobiledevicerules.model.MDRRuleGroupInstance;
076    import com.liferay.portlet.sites.util.SitesUtil;
077    
078    import java.io.File;
079    import java.io.IOException;
080    import java.io.InputStream;
081    
082    import java.util.ArrayList;
083    import java.util.Date;
084    import java.util.HashMap;
085    import java.util.HashSet;
086    import java.util.LinkedHashSet;
087    import java.util.List;
088    import java.util.Locale;
089    import java.util.Map;
090    import java.util.Set;
091    
092    import javax.portlet.PortletException;
093    
094    /**
095     * The implementation of the layout local service.
096     *
097     * @author Brian Wing Shun Chan
098     * @author Jorge Ferrer
099     * @author Joel Kozikowski
100     * @author Charles May
101     * @author Raymond Augé
102     * @author Jorge Ferrer
103     * @author Bruno Farache
104     * @author Vilmos Papp
105     * @author James Lefeu
106     */
107    public class LayoutLocalServiceImpl extends LayoutLocalServiceBaseImpl {
108    
109            /**
110             * Returns the object counter's name.
111             *
112             * @param  groupId the primary key of the group
113             * @param  privateLayout whether layout is private to the group
114             * @return the object counter's name
115             */
116            public static String getCounterName(long groupId, boolean privateLayout) {
117                    StringBundler sb = new StringBundler();
118    
119                    sb.append(Layout.class.getName());
120                    sb.append(StringPool.POUND);
121                    sb.append(groupId);
122                    sb.append(StringPool.POUND);
123                    sb.append(privateLayout);
124    
125                    return sb.toString();
126            }
127    
128            /**
129             * Adds a layout with additional parameters.
130             *
131             * <p>
132             * This method handles the creation of the layout including its resources,
133             * metadata, and internal data structures. It is not necessary to make
134             * subsequent calls to any methods to setup default groups, resources, ...
135             * etc.
136             * </p>
137             *
138             * @param  userId the primary key of the user
139             * @param  groupId the primary key of the group
140             * @param  privateLayout whether the layout is private to the group
141             * @param  parentLayoutId the primary key of the parent layout (optionally
142             *         {@link
143             *         com.liferay.portal.model.LayoutConstants#DEFAULT_PARENT_LAYOUT_ID})
144             * @param  nameMap the layout's locales and localized names
145             * @param  titleMap the layout's locales and localized titles
146             * @param  descriptionMap the layout's locales and localized descriptions
147             * @param  keywordsMap the layout's locales and localized keywords
148             * @param  robotsMap the layout's locales and localized robots
149             * @param  type the layout's type (optionally {@link
150             *         com.liferay.portal.model.LayoutConstants#TYPE_PORTLET}). The
151             *         possible types can be found in {@link
152             *         com.liferay.portal.model.LayoutConstants}.
153             * @param  hidden whether the layout is hidden
154             * @param  friendlyURL the layout's friendly URL (optionally {@link
155             *         com.liferay.portal.util.PropsValues#DEFAULT_USER_PRIVATE_LAYOUT_FRIENDLY_URL}
156             *         or {@link
157             *         com.liferay.portal.util.PropsValues#DEFAULT_USER_PUBLIC_LAYOUT_FRIENDLY_URL}).
158             *         The default values can be overridden in
159             *         <code>portal-ext.properties</code> by specifying new values for
160             *         the corresponding properties defined in {@link
161             *         com.liferay.portal.util.PropsValues}. To see how the URL is
162             *         normalized when accessed see {@link
163             *         com.liferay.portal.kernel.util.FriendlyURLNormalizerUtil#normalize(
164             *         String)}.
165             * @param  serviceContext the service context. Must set the UUID for the
166             *         layout. Can set the creation date, modification date and the
167             *         expando bridge attributes for the layout. For layouts that belong
168             *         to a layout set prototype, an attribute named 'layoutUpdateable'
169             *         can be set to specify whether site administrators can modify this
170             *         page within their site. For layouts that are created from a
171             *         layout prototype, attributes named 'layoutPrototypeUuid' and
172             *         'layoutPrototypeLinkedEnabled' can be specified to provide the
173             *         unique identifier of the source prototype and a boolean to
174             *         determined whether a link to it should be enabled to activate
175             *         propagation of changes made to the linked page in the prototype.
176             * @return the layout
177             * @throws PortalException if a group or user with the primary key could not
178             *         be found, or if layout values were invalid
179             * @throws SystemException if a system exception occurred
180             */
181            public Layout addLayout(
182                            long userId, long groupId, boolean privateLayout,
183                            long parentLayoutId, Map<Locale, String> nameMap,
184                            Map<Locale, String> titleMap, Map<Locale, String> descriptionMap,
185                            Map<Locale, String> keywordsMap, Map<Locale, String> robotsMap,
186                            String type, boolean hidden, String friendlyURL,
187                            ServiceContext serviceContext)
188                    throws PortalException, SystemException {
189    
190                    // Layout
191    
192                    User user = userPersistence.findByPrimaryKey(userId);
193                    long layoutId = getNextLayoutId(groupId, privateLayout);
194                    parentLayoutId = layoutLocalServiceHelper.getParentLayoutId(
195                            groupId, privateLayout, parentLayoutId);
196                    String name = nameMap.get(LocaleUtil.getDefault());
197                    friendlyURL = layoutLocalServiceHelper.getFriendlyURL(
198                            groupId, privateLayout, layoutId, name, friendlyURL);
199                    int priority = layoutLocalServiceHelper.getNextPriority(
200                            groupId, privateLayout, parentLayoutId, null, -1);
201    
202                    layoutLocalServiceHelper.validate(
203                            groupId, privateLayout, layoutId, parentLayoutId, name, type,
204                            hidden, friendlyURL);
205    
206                    Date now = new Date();
207    
208                    long plid = counterLocalService.increment();
209    
210                    Layout layout = layoutPersistence.create(plid);
211    
212                    layout.setUuid(serviceContext.getUuid());
213                    layout.setGroupId(groupId);
214                    layout.setCompanyId(user.getCompanyId());
215                    layout.setCreateDate(serviceContext.getCreateDate(now));
216                    layout.setModifiedDate(serviceContext.getModifiedDate(now));
217                    layout.setPrivateLayout(privateLayout);
218                    layout.setLayoutId(layoutId);
219                    layout.setParentLayoutId(parentLayoutId);
220                    layout.setNameMap(nameMap);
221                    layout.setTitleMap(titleMap);
222                    layout.setDescriptionMap(descriptionMap);
223                    layout.setKeywordsMap(keywordsMap);
224                    layout.setRobotsMap(robotsMap);
225                    layout.setType(type);
226                    layout.setHidden(hidden);
227                    layout.setFriendlyURL(friendlyURL);
228                    layout.setPriority(priority);
229    
230                    boolean layoutUpdateable = ParamUtil.getBoolean(
231                            serviceContext, SitesUtil.LAYOUT_UPDATEABLE, true);
232    
233                    if (!layoutUpdateable) {
234                            UnicodeProperties typeSettingsProperties =
235                                    layout.getTypeSettingsProperties();
236    
237                            typeSettingsProperties.put(
238                                    SitesUtil.LAYOUT_UPDATEABLE, String.valueOf(layoutUpdateable));
239    
240                            layout.setTypeSettingsProperties(typeSettingsProperties);
241                    }
242    
243                    String layoutPrototypeUuid = ParamUtil.getString(
244                            serviceContext, "layoutPrototypeUuid");
245                    boolean layoutPrototypeLinkEnabled = ParamUtil.getBoolean(
246                            serviceContext, "layoutPrototypeLinkEnabled",
247                            PropsValues.LAYOUT_PROTOTYPE_LINK_ENABLED_DEFAULT);
248    
249                    if (Validator.isNotNull(layoutPrototypeUuid)) {
250                            layout.setLayoutPrototypeUuid(layoutPrototypeUuid);
251                            layout.setLayoutPrototypeLinkEnabled(layoutPrototypeLinkEnabled);
252                    }
253    
254                    if (type.equals(LayoutConstants.TYPE_PORTLET)) {
255                            LayoutTypePortlet layoutTypePortlet =
256                                    (LayoutTypePortlet)layout.getLayoutType();
257    
258                            layoutTypePortlet.setLayoutTemplateId(
259                                    0, PropsValues.LAYOUT_DEFAULT_TEMPLATE_ID, false);
260                    }
261    
262                    layoutPersistence.update(layout);
263    
264                    if (Validator.isNotNull(layoutPrototypeUuid) &&
265                            !layoutPrototypeLinkEnabled) {
266    
267                            LayoutPrototype layoutPrototype =
268                                    layoutPrototypeLocalService.
269                                            getLayoutPrototypeByUuidAndCompanyId(
270                                                    layoutPrototypeUuid, layout.getCompanyId());
271    
272                            try {
273                                    SitesUtil.applyLayoutPrototype(
274                                            layoutPrototype, layout, layoutPrototypeLinkEnabled);
275                            }
276                            catch (PortalException pe) {
277                                    throw pe;
278                            }
279                            catch (SystemException se) {
280                                    throw se;
281                            }
282                            catch (Exception e) {
283                                    throw new SystemException(e);
284                            }
285                    }
286    
287                    // Resources
288    
289                    boolean addGroupPermissions = true;
290    
291                    Group group = groupLocalService.getGroup(groupId);
292    
293                    if (privateLayout && group.isUser()) {
294                            addGroupPermissions = false;
295                    }
296    
297                    boolean addGuestPermissions = false;
298    
299                    if (!privateLayout ||
300                            type.equals(LayoutConstants.TYPE_CONTROL_PANEL) ||
301                            group.isLayoutSetPrototype()) {
302    
303                            addGuestPermissions = true;
304                    }
305    
306                    resourceLocalService.addResources(
307                            user.getCompanyId(), groupId, user.getUserId(),
308                            Layout.class.getName(), layout.getPlid(), false,
309                            addGroupPermissions, addGuestPermissions);
310    
311                    // Group
312    
313                    groupLocalService.updateSite(groupId, true);
314    
315                    // Layout set
316    
317                    layoutSetLocalService.updatePageCount(groupId, privateLayout);
318    
319                    LayoutSet layoutSet = layoutSetPersistence.findByG_P(
320                            groupId, privateLayout);
321    
322                    layout.setLayoutSet(layoutSet);
323    
324                    // Expando
325    
326                    ExpandoBridge expandoBridge = layout.getExpandoBridge();
327    
328                    expandoBridge.setAttributes(serviceContext);
329    
330                    // Message boards
331    
332                    if (PropsValues.LAYOUT_COMMENTS_ENABLED) {
333                            mbMessageLocalService.addDiscussionMessage(
334                                    userId, user.getFullName(), groupId, Layout.class.getName(),
335                                    plid, WorkflowConstants.ACTION_PUBLISH);
336                    }
337    
338                    return layout;
339            }
340    
341            /**
342             * Adds a layout with single entry maps for name, title, and description to
343             * the default locale.
344             *
345             * <p>
346             * This method handles the creation of the layout including its resources,
347             * metadata, and internal data structures. It is not necessary to make
348             * subsequent calls to any methods to setup default groups, resources, ...
349             * etc.
350             * </p>
351             *
352             * @param  userId the primary key of the user
353             * @param  groupId the primary key of the group
354             * @param  privateLayout whether the layout is private to the group
355             * @param  parentLayoutId the primary key of the parent layout (optionally
356             *         {@link
357             *         com.liferay.portal.model.LayoutConstants#DEFAULT_PARENT_LAYOUT_ID}).
358             *         The possible values can be found in {@link
359             *         com.liferay.portal.model.LayoutConstants}.
360             * @param  name the layout's name (optionally {@link
361             *         com.liferay.portal.util.PropsValues#DEFAULT_USER_PRIVATE_LAYOUT_NAME}
362             *         or {@link
363             *         com.liferay.portal.util.PropsValues#DEFAULT_USER_PUBLIC_LAYOUT_NAME}).
364             *         The default values can be overridden in
365             *         <code>portal-ext.properties</code> by specifying new values for
366             *         the corresponding properties defined in {@link
367             *         com.liferay.portal.util.PropsValues}
368             * @param  title the layout's title
369             * @param  description the layout's description
370             * @param  type the layout's type (optionally {@link
371             *         com.liferay.portal.model.LayoutConstants#TYPE_PORTLET}). The
372             *         possible types can be found in {@link
373             *         com.liferay.portal.model.LayoutConstants}.
374             * @param  hidden whether the layout is hidden
375             * @param  friendlyURL the friendly URL of the layout (optionally {@link
376             *         com.liferay.portal.util.PropsValues#DEFAULT_USER_PRIVATE_LAYOUT_FRIENDLY_URL}
377             *         or {@link
378             *         com.liferay.portal.util.PropsValues#DEFAULT_USER_PUBLIC_LAYOUT_FRIENDLY_URL}).
379             *         The default values can be overridden in
380             *         <code>portal-ext.properties</code> by specifying new values for
381             *         the corresponding properties defined in {@link
382             *         com.liferay.portal.util.PropsValues}. To see how the URL is
383             *         normalized when accessed see {@link
384             *         com.liferay.portal.kernel.util.FriendlyURLNormalizerUtil#normalize(
385             *         String)}.
386             * @param  serviceContext the service context. Must set the UUID for the
387             *         layout. Can set the creation date and modification date for the
388             *         layout. For layouts that belong to a layout set prototype, an
389             *         attribute named 'layoutUpdateable' can be set to specify whether
390             *         site administrators can modify this page within their site.
391             * @return the layout
392             * @throws PortalException if a group or user with the primary key could not
393             *         be found
394             * @throws SystemException if a system exception occurred
395             */
396            public Layout addLayout(
397                            long userId, long groupId, boolean privateLayout,
398                            long parentLayoutId, String name, String title, String description,
399                            String type, boolean hidden, String friendlyURL,
400                            ServiceContext serviceContext)
401                    throws PortalException, SystemException {
402    
403                    Locale locale = LocaleUtil.getDefault();
404    
405                    Map<Locale, String> descriptionMap = new HashMap<Locale, String>();
406    
407                    descriptionMap.put(locale, description);
408    
409                    Map<Locale, String> nameMap = new HashMap<Locale, String>();
410    
411                    nameMap.put(locale, name);
412    
413                    Map<Locale, String> titleMap = new HashMap<Locale, String>();
414    
415                    titleMap.put(locale, title);
416    
417                    return addLayout(
418                            userId, groupId, privateLayout, parentLayoutId, nameMap, titleMap,
419                            descriptionMap, new HashMap<Locale, String>(),
420                            new HashMap<Locale, String>(), type, hidden, friendlyURL,
421                            serviceContext);
422            }
423    
424            /**
425             * Deletes the layout, its child layouts, and its associated resources.
426             *
427             * @param  layout the layout
428             * @param  updateLayoutSet whether the layout set's page counter needs to be
429             *         updated
430             * @param  serviceContext the service context
431             * @throws PortalException if a portal exception occurred
432             * @throws SystemException if a system exception occurred
433             */
434            public void deleteLayout(
435                            Layout layout, boolean updateLayoutSet,
436                            ServiceContext serviceContext)
437                    throws PortalException, SystemException {
438    
439                    // First layout validation
440    
441                    if (layout.getParentLayoutId() ==
442                                    LayoutConstants.DEFAULT_PARENT_LAYOUT_ID) {
443    
444                            List<Layout> rootLayouts = layoutPersistence.findByG_P_P(
445                                    layout.getGroupId(), layout.isPrivateLayout(),
446                                    LayoutConstants.DEFAULT_PARENT_LAYOUT_ID, 0, 2);
447    
448                            if (rootLayouts.size() > 1) {
449                                    Layout firstLayout = rootLayouts.get(0);
450    
451                                    if (firstLayout.getLayoutId() == layout.getLayoutId()) {
452                                            Layout secondLayout = rootLayouts.get(1);
453    
454                                            layoutLocalServiceHelper.validateFirstLayout(
455                                                    secondLayout.getType());
456                                    }
457                            }
458                    }
459    
460                    // Child layouts
461    
462                    List<Layout> childLayouts = layoutPersistence.findByG_P_P(
463                            layout.getGroupId(), layout.isPrivateLayout(),
464                            layout.getLayoutId());
465    
466                    for (Layout childLayout : childLayouts) {
467                            deleteLayout(childLayout, updateLayoutSet, serviceContext);
468                    }
469    
470                    // Portlet preferences
471    
472                    portletPreferencesLocalService.deletePortletPreferencesByPlid(
473                            layout.getPlid());
474    
475                    // Subscriptions
476    
477                    subscriptionLocalService.deleteSubscriptions(
478                            layout.getCompanyId(), Layout.class.getName(), layout.getPlid());
479    
480                    // Ratings
481    
482                    ratingsStatsLocalService.deleteStats(
483                            Layout.class.getName(), layout.getPlid());
484    
485                    // Mobile device rules
486    
487                    long layoutClassNameId = classNameLocalService.getClassNameId(
488                            Layout.class);
489    
490                    List<MDRRuleGroupInstance> mdrRuleGroupInstances =
491                            mdrRuleGroupInstancePersistence.findByC_C(
492                                    layoutClassNameId, layout.getPlid());
493    
494                    for (MDRRuleGroupInstance mdrRuleGroupInstance :
495                                    mdrRuleGroupInstances) {
496    
497                            mdrRuleGroupInstanceLocalService.deleteMDRRuleGroupInstance(
498                                    mdrRuleGroupInstance);
499                    }
500    
501                    // Message boards
502    
503                    mbMessageLocalService.deleteDiscussionMessages(
504                            Layout.class.getName(), layout.getPlid());
505    
506                    // Journal articles
507    
508                    journalArticleLocalService.deleteLayoutArticleReferences(
509                            layout.getGroupId(), layout.getUuid());
510    
511                    // Journal content searches
512    
513                    journalContentSearchLocalService.deleteLayoutContentSearches(
514                            layout.getGroupId(), layout.isPrivateLayout(),
515                            layout.getLayoutId());
516    
517                    // Expando
518    
519                    expandoValueLocalService.deleteValues(
520                            Layout.class.getName(), layout.getPlid());
521    
522                    // Icon
523    
524                    imageLocalService.deleteImage(layout.getIconImageId());
525    
526                    // Scope group
527    
528                    Group scopeGroup = layout.getScopeGroup();
529    
530                    if (scopeGroup != null) {
531                            groupLocalService.deleteGroup(scopeGroup.getGroupId());
532                    }
533    
534                    // Resources
535    
536                    String primKey =
537                            layout.getPlid() + PortletConstants.LAYOUT_SEPARATOR + "%";
538    
539                    List<ResourcePermission> resourcePermissions =
540                            resourcePermissionPersistence.findByC_LikeP(
541                                    layout.getCompanyId(), primKey);
542    
543                    for (ResourcePermission resourcePermission : resourcePermissions) {
544                            resourcePermissionLocalService.deleteResourcePermission(
545                                    resourcePermission);
546                    }
547    
548                    resourceLocalService.deleteResource(
549                            layout.getCompanyId(), Layout.class.getName(),
550                            ResourceConstants.SCOPE_INDIVIDUAL, layout.getPlid());
551    
552                    // Layout
553    
554                    layoutPersistence.remove(layout);
555    
556                    // Layout set
557    
558                    if (updateLayoutSet) {
559                            layoutSetLocalService.updatePageCount(
560                                    layout.getGroupId(), layout.isPrivateLayout());
561                    }
562            }
563    
564            /**
565             * Deletes the layout with the primary key, also deleting the layout's child
566             * layouts, and associated resources.
567             *
568             * @param  groupId the primary key of the group
569             * @param  privateLayout whether the layout is private to the group
570             * @param  layoutId the primary key of the layout
571             * @param  serviceContext the service context
572             * @throws PortalException if a matching layout could not be found , or if
573             *         some other portal exception occurred
574             * @throws SystemException if a system exception occurred
575             */
576            public void deleteLayout(
577                            long groupId, boolean privateLayout, long layoutId,
578                            ServiceContext serviceContext)
579                    throws PortalException, SystemException {
580    
581                    Layout layout = layoutPersistence.findByG_P_L(
582                            groupId, privateLayout, layoutId);
583    
584                    deleteLayout(layout, true, serviceContext);
585            }
586    
587            /**
588             * Deletes the layout with the plid, also deleting the layout's child
589             * layouts, and associated resources.
590             *
591             * @param  plid the primary key of the layout
592             * @param  serviceContext the service context
593             * @throws PortalException if a layout with the primary key could not be
594             *         found , or if some other portal exception occurred
595             * @throws SystemException if a system exception occurred
596             */
597            public void deleteLayout(long plid, ServiceContext serviceContext)
598                    throws PortalException, SystemException {
599    
600                    Layout layout = layoutPersistence.findByPrimaryKey(plid);
601    
602                    deleteLayout(layout, true, serviceContext);
603            }
604    
605            /**
606             * Deletes the group's private or non-private layouts, also deleting the
607             * layouts' child layouts, and associated resources.
608             *
609             * @param  groupId the primary key of the group
610             * @param  privateLayout whether the layout is private to the group
611             * @param  serviceContext the service context
612             * @throws PortalException if a group with the primary key could not be
613             *         found or if a layout set for the group and privacy could not be
614             *         found
615             * @throws SystemException if a system exception occurred
616             */
617            public void deleteLayouts(
618                            long groupId, boolean privateLayout, ServiceContext serviceContext)
619                    throws PortalException, SystemException {
620    
621                    // Layouts
622    
623                    List<Layout> layouts = layoutPersistence.findByG_P_P(
624                            groupId, privateLayout, LayoutConstants.DEFAULT_PARENT_LAYOUT_ID);
625    
626                    for (Layout layout : layouts) {
627                            try {
628                                    deleteLayout(layout, false, serviceContext);
629                            }
630                            catch (NoSuchLayoutException nsle) {
631                            }
632                    }
633    
634                    // Layout set
635    
636                    layoutSetLocalService.updatePageCount(groupId, privateLayout);
637    
638                    // Counter
639    
640                    counterLocalService.reset(getCounterName(groupId, privateLayout));
641            }
642    
643            /**
644             * Exports layouts with the primary keys and criteria as a byte array.
645             *
646             * @param  groupId the primary key of the group
647             * @param  privateLayout whether the layout is private to the group
648             * @param  layoutIds the primary keys of the layouts to be exported
649             * @param  parameterMap the mapping of parameters indicating which
650             *         information to export. For information on the keys used in the
651             *         map see {@link
652             *         com.liferay.portal.kernel.lar.PortletDataHandlerKeys}.
653             * @param  startDate the export's start date
654             * @param  endDate the export's end date
655             * @return the layouts as a byte array
656             * @throws PortalException if a group or any layout with the primary key
657             *         could not be found, or if some other portal exception occurred
658             * @throws SystemException if a system exception occurred
659             */
660            public byte[] exportLayouts(
661                            long groupId, boolean privateLayout, long[] layoutIds,
662                            Map<String, String[]> parameterMap, Date startDate, Date endDate)
663                    throws PortalException, SystemException {
664    
665                    File file = exportLayoutsAsFile(
666                            groupId, privateLayout, layoutIds, parameterMap, startDate,
667                            endDate);
668    
669                    try {
670                            return FileUtil.getBytes(file);
671                    }
672                    catch (IOException ioe) {
673                            throw new SystemException(ioe);
674                    }
675                    finally {
676                            file.delete();
677                    }
678            }
679    
680            /**
681             * Exports all layouts that match the criteria as a byte array.
682             *
683             * @param  groupId the primary key of the group
684             * @param  privateLayout whether the layout is private to the group
685             * @param  parameterMap the mapping of parameters indicating which
686             *         information to export. For information on the keys used in the
687             *         map see {@link
688             *         com.liferay.portal.kernel.lar.PortletDataHandlerKeys}.
689             * @param  startDate the export's start date
690             * @param  endDate the export's end date
691             * @return the layout as a byte array
692             * @throws PortalException if a group with the primary key could not be
693             *         found or if some other portal exception occurred
694             * @throws SystemException if a system exception occurred
695             */
696            public byte[] exportLayouts(
697                            long groupId, boolean privateLayout,
698                            Map<String, String[]> parameterMap, Date startDate, Date endDate)
699                    throws PortalException, SystemException {
700    
701                    return exportLayouts(
702                            groupId, privateLayout, null, parameterMap, startDate, endDate);
703            }
704    
705            /**
706             * Exports the layouts that match the primary keys and criteria as a file.
707             *
708             * @param  groupId the primary key of the group
709             * @param  privateLayout whether the layout is private to the group
710             * @param  layoutIds the primary keys of the layouts to be exported
711             *         (optionally <code>null</code>)
712             * @param  parameterMap the mapping of parameters indicating which
713             *         information to export. For information on the keys used in the
714             *         map see {@link
715             *         com.liferay.portal.kernel.lar.PortletDataHandlerKeys}.
716             * @param  startDate the export's start date
717             * @param  endDate the export's end date
718             * @return the layouts as a File
719             * @throws PortalException if a group or any layout with the primary key
720             *         could not be found, or if some other portal exception occurred
721             * @throws SystemException if a system exception occurred
722             */
723            public File exportLayoutsAsFile(
724                            long groupId, boolean privateLayout, long[] layoutIds,
725                            Map<String, String[]> parameterMap, Date startDate, Date endDate)
726                    throws PortalException, SystemException {
727    
728                    try {
729                            LayoutExporter layoutExporter = new LayoutExporter();
730    
731                            return layoutExporter.exportLayoutsAsFile(
732                                    groupId, privateLayout, layoutIds, parameterMap, startDate,
733                                    endDate);
734                    }
735                    catch (PortalException pe) {
736                            throw pe;
737                    }
738                    catch (SystemException se) {
739                            throw se;
740                    }
741                    catch (Exception e) {
742                            throw new SystemException(e);
743                    }
744            }
745    
746            /**
747             * Exports the portlet information (categories, permissions, ... etc.) as a
748             * byte array.
749             *
750             * @param  plid the primary key of the layout
751             * @param  groupId the primary key of the group
752             * @param  portletId the primary key of the portlet
753             * @param  parameterMap the mapping of parameters indicating which
754             *         information to export. For information on the keys used in the
755             *         map see {@link
756             *         com.liferay.portal.kernel.lar.PortletDataHandlerKeys}.
757             * @param  startDate the export's start date
758             * @param  endDate the export's end date
759             * @return the portlet information as a byte array
760             * @throws PortalException if a group or portlet with the primary key could
761             *         not be found, or if some other portal exception occurred
762             * @throws SystemException if a system exception occurred
763             */
764            public byte[] exportPortletInfo(
765                            long plid, long groupId, String portletId,
766                            Map<String, String[]> parameterMap, Date startDate, Date endDate)
767                    throws PortalException, SystemException {
768    
769                    File file = exportPortletInfoAsFile(
770                            plid, groupId, portletId, parameterMap, startDate, endDate);
771    
772                    try {
773                            return FileUtil.getBytes(file);
774                    }
775                    catch (IOException ioe) {
776                            throw new SystemException(ioe);
777                    }
778                    finally {
779                            file.delete();
780                    }
781            }
782    
783            /**
784             * Exports the portlet information (categories, permissions, ... etc.) as a
785             * file.
786             *
787             * @param  plid the primary key of the layout
788             * @param  groupId the primary key of the group
789             * @param  portletId the primary key of the portlet
790             * @param  parameterMap the mapping of parameters indicating which
791             *         information to export. For information on the keys used in the
792             *         map see {@link
793             *         com.liferay.portal.kernel.lar.PortletDataHandlerKeys}.
794             * @param  startDate the export's start date
795             * @param  endDate the export's end date
796             * @return the portlet information as a file
797             * @throws PortalException if a group or portlet with the primary key could
798             *         not be found, or if some other portal exception occurred
799             * @throws SystemException if a system exception occurred
800             */
801            public File exportPortletInfoAsFile(
802                            long plid, long groupId, String portletId,
803                            Map<String, String[]> parameterMap, Date startDate, Date endDate)
804                    throws PortalException, SystemException {
805    
806                    try {
807                            PortletExporter portletExporter = new PortletExporter();
808    
809                            return portletExporter.exportPortletInfoAsFile(
810                                    plid, groupId, portletId, parameterMap, startDate, endDate);
811                    }
812                    catch (PortalException pe) {
813                            throw pe;
814                    }
815                    catch (SystemException se) {
816                            throw se;
817                    }
818                    catch (Exception e) {
819                            throw new SystemException(e);
820                    }
821            }
822    
823            public Layout fetchFirstLayout(
824                            long groupId, boolean privateLayout, long parentLayoutId)
825                    throws SystemException {
826    
827                    return layoutPersistence.fetchByG_P_P_First(
828                            groupId, privateLayout, parentLayoutId,
829                            new LayoutPriorityComparator());
830            }
831    
832            public Layout fetchLayout(
833                            long groupId, boolean privateLayout, long layoutId)
834                    throws SystemException {
835    
836                    return layoutPersistence.fetchByG_P_L(groupId, privateLayout, layoutId);
837            }
838    
839            /**
840             * @param  uuid the layout's UUID
841             * @param  groupId the primary key of the group
842             * @param  privateLayout whether the layout is private to the group
843             * @return the layout, or <code>null</code> if a matching layout could not
844             *         be found
845             * @throws SystemException if a system exception occurred
846             */
847            public Layout fetchLayoutByUuidAndGroupId(
848                            String uuid, long groupId, boolean privateLayout)
849                    throws SystemException {
850    
851                    return layoutPersistence.fetchByUUID_G_P(uuid, groupId, privateLayout);
852            }
853    
854            /**
855             * Returns the primary key of the default layout for the group
856             *
857             * @param  groupId the primary key of the group
858             * @return the primary key of the default layout for the group (optionally
859             *         {@link com.liferay.portal.model.LayoutConstants#DEFAULT_PLID})
860             * @throws SystemException if a system exception occurred
861             */
862            public long getDefaultPlid(long groupId) throws SystemException {
863                    if (groupId > 0) {
864                            List<Layout> layouts = layoutPersistence.findByGroupId(
865                                    groupId, 0, 1);
866    
867                            if (layouts.size() > 0) {
868                                    Layout layout = layouts.get(0);
869    
870                                    return layout.getPlid();
871                            }
872                    }
873    
874                    return LayoutConstants.DEFAULT_PLID;
875            }
876    
877            /**
878             * Returns primary key of the matching default layout for the group
879             *
880             * @param  groupId the primary key of the group
881             * @param  privateLayout whether the layout is private to the group
882             * @return the primary key of the default layout for the group; {@link
883             *         com.liferay.portal.model.LayoutConstants#DEFAULT_PLID}) otherwise
884             * @throws SystemException if a system exception occurred
885             */
886            public long getDefaultPlid(long groupId, boolean privateLayout)
887                    throws SystemException {
888    
889                    if (groupId > 0) {
890                            List<Layout> layouts = layoutPersistence.findByG_P(
891                                    groupId, privateLayout, 0, 1);
892    
893                            if (layouts.size() > 0) {
894                                    Layout layout = layouts.get(0);
895    
896                                    return layout.getPlid();
897                            }
898                    }
899    
900                    return LayoutConstants.DEFAULT_PLID;
901            }
902    
903            /**
904             * Returns primary key of the default portlet layout for the group
905             *
906             * @param  groupId the primary key of the group
907             * @param  privateLayout whether the layout is private to the group
908             * @param  portletId the primary key of the portlet
909             * @return the primary key of the default portlet layout for the group;
910             *         {@link com.liferay.portal.model.LayoutConstants#DEFAULT_PLID}
911             *         otherwise
912             * @throws PortalException if a portlet with the primary key could not be
913             *         found
914             * @throws SystemException if a system exception occurred
915             */
916            public long getDefaultPlid(
917                            long groupId, boolean privateLayout, String portletId)
918                    throws PortalException, SystemException {
919    
920                    if (groupId > 0) {
921                            List<Layout> layouts = layoutPersistence.findByG_P(
922                                    groupId, privateLayout);
923    
924                            for (Layout layout : layouts) {
925                                    if (layout.isTypePortlet()) {
926                                            LayoutTypePortlet layoutTypePortlet =
927                                                    (LayoutTypePortlet)layout.getLayoutType();
928    
929                                            if (layoutTypePortlet.hasPortletId(portletId)) {
930                                                    return layout.getPlid();
931                                            }
932                                    }
933                            }
934                    }
935    
936                    return LayoutConstants.DEFAULT_PLID;
937            }
938    
939            /**
940             * Returns the layout for the friendly URL
941             *
942             * @param  groupId the primary key of the group
943             * @param  privateLayout whether the layout is private to the group
944             * @param  friendlyURL the friendly URL of the layout
945             * @return the layout for the friendly URL
946             * @throws PortalException if the friendly URL is <code>null</code> or a
947             *         matching layout could not be found
948             * @throws SystemException if a system exception occurred
949             */
950            public Layout getFriendlyURLLayout(
951                            long groupId, boolean privateLayout, String friendlyURL)
952                    throws PortalException, SystemException {
953    
954                    if (Validator.isNull(friendlyURL)) {
955                            throw new NoSuchLayoutException();
956                    }
957    
958                    friendlyURL = layoutLocalServiceHelper.getFriendlyURL(friendlyURL);
959    
960                    Layout layout = layoutPersistence.fetchByG_P_F(
961                            groupId, privateLayout, friendlyURL);
962    
963                    if ((layout == null) &&
964                            friendlyURL.startsWith(StringPool.SLASH) &&
965                            Validator.isNumber(friendlyURL.substring(1))) {
966    
967                            long layoutId = GetterUtil.getLong(friendlyURL.substring(1));
968    
969                            layout = layoutPersistence.fetchByG_P_L(
970                                    groupId, privateLayout, layoutId);
971                    }
972    
973                    if (layout == null) {
974                            throw new NoSuchLayoutException();
975                    }
976    
977                    return layout;
978            }
979    
980            /**
981             * Returns the layout matching the primary key, group, and privacy; throws a
982             * {@link com.liferay.portal.NoSuchLayoutException} otherwise.
983             *
984             * @param  groupId the primary key of the group
985             * @param  privateLayout whether the layout is private to the group
986             * @param  layoutId the primary key of the layout
987             * @return the matching layout
988             * @throws PortalException if a matching layout could not be found
989             * @throws SystemException if a system exception occurred
990             */
991            public Layout getLayout(long groupId, boolean privateLayout, long layoutId)
992                    throws PortalException, SystemException {
993    
994                    return layoutPersistence.findByG_P_L(groupId, privateLayout, layoutId);
995            }
996    
997            /**
998             * Returns the layout for the icon image; throws a {@link
999             * com.liferay.portal.NoSuchLayoutException} otherwise.
1000             *
1001             * @param  iconImageId the primary key of the icon image
1002             * @return Returns the layout for the icon image
1003             * @throws PortalException if an icon image with the primary key could not
1004             *         be found
1005             * @throws SystemException if a system exception occurred
1006             */
1007            public Layout getLayoutByIconImageId(long iconImageId)
1008                    throws PortalException, SystemException {
1009    
1010                    return layoutPersistence.findByIconImageId(iconImageId);
1011            }
1012    
1013            /**
1014             * Returns all the layouts belonging to the group.
1015             *
1016             * @param  groupId the primary key of the group
1017             * @param  privateLayout whether the layout is private to the group
1018             * @return the matching layouts, or <code>null</code> if no matches were
1019             *         found
1020             * @throws SystemException if a system exception occurred
1021             */
1022            public List<Layout> getLayouts(long groupId, boolean privateLayout)
1023                    throws SystemException {
1024    
1025                    return layoutPersistence.findByG_P(groupId, privateLayout);
1026            }
1027    
1028            /**
1029             * Returns all the layouts belonging to the group that are children of the
1030             * parent layout.
1031             *
1032             * @param  groupId the primary key of the group
1033             * @param  privateLayout whether the layout is private to the group
1034             * @param  parentLayoutId the primary key of the parent layout
1035             * @return the matching layouts, or <code>null</code> if no matches were
1036             *         found
1037             * @throws SystemException if a system exception occurred
1038             */
1039            public List<Layout> getLayouts(
1040                            long groupId, boolean privateLayout, long parentLayoutId)
1041                    throws SystemException {
1042    
1043                    return layoutPersistence.findByG_P_P(
1044                            groupId, privateLayout, parentLayoutId);
1045            }
1046    
1047            /**
1048             * Returns a range of all the layouts belonging to the group that are
1049             * children of the parent layout.
1050             *
1051             * <p>
1052             * Useful when paginating results. Returns a maximum of <code>end -
1053             * start</code> instances. <code>start</code> and <code>end</code> are not
1054             * primary keys, they are indexes in the result set. Thus, <code>0</code>
1055             * refers to the first result in the set. Setting both <code>start</code>
1056             * and <code>end</code> to {@link
1057             * com.liferay.portal.kernel.dao.orm.QueryUtil#ALL_POS} will return the full
1058             * result set.
1059             * </p>
1060             *
1061             * @param  groupId the primary key of the group
1062             * @param  privateLayout whether the layout is private to the group
1063             * @param  parentLayoutId the primary key of the parent layout
1064             * @param  incomplete whether the layout is incomplete
1065             * @param  start the lower bound of the range of layouts
1066             * @param  end the upper bound of the range of layouts (not inclusive)
1067             * @return the matching layouts, or <code>null</code> if no matches were
1068             *         found
1069             * @throws SystemException if a system exception occurred
1070             */
1071            public List<Layout> getLayouts(
1072                            long groupId, boolean privateLayout, long parentLayoutId,
1073                            boolean incomplete, int start, int end)
1074                    throws SystemException {
1075    
1076                    return layoutPersistence.findByG_P_P(
1077                            groupId, privateLayout, parentLayoutId, start, end);
1078            }
1079    
1080            /**
1081             * Returns all the layouts that match the layout IDs and belong to the
1082             * group.
1083             *
1084             * @param  groupId the primary key of the group
1085             * @param  privateLayout whether the layout is private to the group
1086             * @param  layoutIds the primary keys of the layouts
1087             * @return the matching layouts, or <code>null</code> if no matches were
1088             *         found
1089             * @throws PortalException if a group or layout with the primary key could
1090             *         not be found
1091             * @throws SystemException if a system exception occurred
1092             */
1093            public List<Layout> getLayouts(
1094                            long groupId, boolean privateLayout, long[] layoutIds)
1095                    throws PortalException, SystemException {
1096    
1097                    List<Layout> layouts = new ArrayList<Layout>();
1098    
1099                    for (long layoutId : layoutIds) {
1100                            Layout layout = getLayout(groupId, privateLayout, layoutId);
1101    
1102                            layouts.add(layout);
1103                    }
1104    
1105                    return layouts;
1106            }
1107    
1108            /**
1109             * Returns all the layouts that match the type and belong to the group.
1110             *
1111             * @param  groupId the primary key of the group
1112             * @param  privateLayout whether the layout is private to the group
1113             * @param  type the type of the layouts (optionally {@link
1114             *         com.liferay.portal.model.LayoutConstants#TYPE_PORTLET})
1115             * @return the matching layouts, or <code>null</code> if no matches were
1116             *         found
1117             * @throws SystemException if a system exception occurred
1118             */
1119            public List<Layout> getLayouts(
1120                            long groupId, boolean privateLayout, String type)
1121                    throws SystemException {
1122    
1123                    return layoutPersistence.findByG_P_T(groupId, privateLayout, type);
1124            }
1125    
1126            /**
1127             * Returns the layout references for all the layouts that belong to the
1128             * company and belong to the portlet that matches the preferences.
1129             *
1130             * @param  companyId the primary key of the company
1131             * @param  portletId the primary key of the portlet
1132             * @param  preferencesKey the portlet's preference key
1133             * @param  preferencesValue the portlet's preference value
1134             * @return the layout references of the matching layouts
1135             * @throws SystemException if a system exception occurred
1136             */
1137            public LayoutReference[] getLayouts(
1138                            long companyId, String portletId, String preferencesKey,
1139                            String preferencesValue)
1140                    throws SystemException {
1141    
1142                    List<LayoutReference> layoutReferences = layoutFinder.findByC_P_P(
1143                            companyId, portletId, preferencesKey, preferencesValue);
1144    
1145                    return layoutReferences.toArray(
1146                            new LayoutReference[layoutReferences.size()]);
1147            }
1148    
1149            public int getLayoutsByLayoutPrototypeUuidCount(String layoutPrototypeUuid)
1150                    throws SystemException {
1151    
1152                    return layoutPersistence.countByLayoutPrototypeUuid(
1153                            layoutPrototypeUuid);
1154            }
1155    
1156            public int getLayoutsCount(Group group, boolean privateLayout)
1157                    throws PortalException, SystemException {
1158    
1159                    return getLayoutsCount(group, privateLayout, true);
1160            }
1161    
1162            public int getLayoutsCount(
1163                            Group group, boolean privateLayout, boolean includeUserGroups)
1164                    throws PortalException, SystemException {
1165    
1166                    LayoutSet layoutSet = layoutSetPersistence.findByG_P(
1167                            group.getGroupId(), privateLayout);
1168    
1169                    int count = layoutSet.getPageCount();
1170    
1171                    if (!group.isUser() || !includeUserGroups) {
1172                            return count;
1173                    }
1174    
1175                    List<UserGroup> userGroups = userPersistence.getUserGroups(
1176                            group.getClassPK());
1177    
1178                    if (!userGroups.isEmpty()) {
1179                            long userGroupClassNameId = classNameLocalService.getClassNameId(
1180                                    UserGroup.class);
1181    
1182                            for (UserGroup userGroup : userGroups) {
1183                                    Group userGroupGroup = groupPersistence.findByC_C_C(
1184                                            group.getCompanyId(), userGroupClassNameId,
1185                                            userGroup.getUserGroupId());
1186    
1187                                    layoutSet = layoutSetPersistence.findByG_P(
1188                                            userGroupGroup.getGroupId(), privateLayout);
1189    
1190                                    count += layoutSet.getPageCount();
1191                            }
1192                    }
1193    
1194                    return count;
1195            }
1196    
1197            public int getLayoutsCount(User user, boolean privateLayout)
1198                    throws PortalException, SystemException {
1199    
1200                    return getLayoutsCount(user, privateLayout, true);
1201            }
1202    
1203            public int getLayoutsCount(
1204                            User user, boolean privateLayout, boolean includeUserGroups)
1205                    throws PortalException, SystemException {
1206    
1207                    long classNameId = classNameLocalService.getClassNameId(User.class);
1208    
1209                    Group group = groupPersistence.findByC_C_C(
1210                            user.getCompanyId(), classNameId, user.getUserId());
1211    
1212                    return getLayoutsCount(group, privateLayout, includeUserGroups);
1213            }
1214    
1215            /**
1216             * Returns the primary key to use for the next layout.
1217             *
1218             * @param  groupId the primary key of the group
1219             * @param  privateLayout whether the layout is private to the group
1220             * @return the primary key to use for the next layout
1221             * @throws SystemException if a system exception occurred
1222             */
1223            public long getNextLayoutId(long groupId, boolean privateLayout)
1224                    throws SystemException {
1225    
1226                    long nextLayoutId = counterLocalService.increment(
1227                            getCounterName(groupId, privateLayout));
1228    
1229                    if (nextLayoutId == 1) {
1230                            List<Layout> layouts = layoutPersistence.findByG_P(
1231                                    groupId, privateLayout, 0, 1, new LayoutComparator());
1232    
1233                            if (!layouts.isEmpty()) {
1234                                    Layout layout = layouts.get(0);
1235    
1236                                    nextLayoutId = layout.getLayoutId() + 1;
1237    
1238                                    counterLocalService.reset(
1239                                            getCounterName(groupId, privateLayout), nextLayoutId);
1240                            }
1241                    }
1242    
1243                    return nextLayoutId;
1244            }
1245    
1246            /**
1247             * Returns all the layouts without resource permissions
1248             *
1249             * @param  roleId the primary key of the role
1250             * @return all the layouts without resource permissions
1251             * @throws SystemException if a system exception occurred
1252             */
1253            public List<Layout> getNoPermissionLayouts(long roleId)
1254                    throws SystemException {
1255    
1256                    return layoutFinder.findByNoPermissions(roleId);
1257            }
1258    
1259            /**
1260             * Returns all the layouts whose friendly URLs are <code>null</code>
1261             *
1262             * @return all the layouts whose friendly URLs are <code>null</code>
1263             * @throws SystemException if a system exception occurred
1264             */
1265            public List<Layout> getNullFriendlyURLLayouts() throws SystemException {
1266                    return layoutFinder.findByNullFriendlyURL();
1267            }
1268    
1269            /**
1270             * Returns all the layouts within scope of the group
1271             *
1272             * @param  groupId the primary key of the group
1273             * @param  privateLayout whether the layout is private to the group
1274             * @return the layouts within scope of the group
1275             * @throws SystemException if a system exception occurred
1276             */
1277            public List<Layout> getScopeGroupLayouts(
1278                            long groupId, boolean privateLayout)
1279                    throws SystemException {
1280    
1281                    return layoutFinder.findByScopeGroup(groupId, privateLayout);
1282            }
1283    
1284            public boolean hasLayouts(Group group, boolean privateLayout)
1285                    throws PortalException, SystemException {
1286    
1287                    return hasLayouts(group, privateLayout, true);
1288            }
1289    
1290            public boolean hasLayouts(
1291                            Group group, boolean privateLayout, boolean includeUserGroups)
1292                    throws PortalException, SystemException {
1293    
1294                    LayoutSet layoutSet = layoutSetPersistence.findByG_P(
1295                            group.getGroupId(), privateLayout);
1296    
1297                    if (layoutSet.getPageCount() > 0) {
1298                            return true;
1299                    }
1300    
1301                    if (!group.isUser() || !includeUserGroups) {
1302                            return false;
1303                    }
1304    
1305                    List<UserGroup> userGroups = userPersistence.getUserGroups(
1306                            group.getClassPK());
1307    
1308                    if (!userGroups.isEmpty()) {
1309                            long userGroupClassNameId = classNameLocalService.getClassNameId(
1310                                    UserGroup.class);
1311    
1312                            for (UserGroup userGroup : userGroups) {
1313                                    Group userGroupGroup = groupPersistence.findByC_C_C(
1314                                            group.getCompanyId(), userGroupClassNameId,
1315                                            userGroup.getUserGroupId());
1316    
1317                                    layoutSet = layoutSetPersistence.findByG_P(
1318                                            userGroupGroup.getGroupId(), privateLayout);
1319    
1320                                    if (layoutSet.getPageCount() > 0) {
1321                                            return true;
1322                                    }
1323                            }
1324                    }
1325    
1326                    return false;
1327            }
1328    
1329            /**
1330             * Returns <code>true</code> if the group has any layouts;
1331             * <code>false</code> otherwise.
1332             *
1333             * @param  groupId the primary key of the group
1334             * @param  privateLayout whether the layout is private to the group
1335             * @param  parentLayoutId the primary key of the parent layout
1336             * @return <code>true</code> if the group has any layouts;
1337             *         <code>false</code> otherwise
1338             * @throws SystemException if a system exception occurred
1339             */
1340            public boolean hasLayouts(
1341                            long groupId, boolean privateLayout, long parentLayoutId)
1342                    throws SystemException {
1343    
1344                    return layoutPersistence.countByG_P_P(
1345                            groupId, privateLayout, parentLayoutId) > 0;
1346            }
1347    
1348            public boolean hasLayouts(User user, boolean privateLayout)
1349                    throws PortalException, SystemException {
1350    
1351                    return hasLayouts(user, privateLayout, true);
1352            }
1353    
1354            public boolean hasLayouts(
1355                            User user, boolean privateLayout, boolean includeUserGroups)
1356                    throws PortalException, SystemException {
1357    
1358                    long classNameId = classNameLocalService.getClassNameId(User.class);
1359    
1360                    Group group = groupPersistence.findByC_C_C(
1361                            user.getCompanyId(), classNameId, user.getUserId());
1362    
1363                    return hasLayouts(group, privateLayout, includeUserGroups);
1364            }
1365    
1366            public boolean hasLayoutSetPrototypeLayout(
1367                            long layoutSetPrototypeId, String layoutUuid)
1368                    throws PortalException, SystemException {
1369    
1370                    LayoutSetPrototype layoutSetPrototype =
1371                            layoutSetPrototypeLocalService.getLayoutSetPrototype(
1372                                    layoutSetPrototypeId);
1373    
1374                    return layoutLocalServiceHelper.hasLayoutSetPrototypeLayout(
1375                            layoutSetPrototype, layoutUuid);
1376            }
1377    
1378            public boolean hasLayoutSetPrototypeLayout(
1379                            String layoutSetPrototypeUuid, long companyId, String layoutUuid)
1380                    throws PortalException, SystemException {
1381    
1382                    LayoutSetPrototype layoutSetPrototype =
1383                            layoutSetPrototypeLocalService.
1384                                    getLayoutSetPrototypeByUuidAndCompanyId(
1385                                            layoutSetPrototypeUuid, companyId);
1386    
1387                    return layoutLocalServiceHelper.hasLayoutSetPrototypeLayout(
1388                            layoutSetPrototype, layoutUuid);
1389            }
1390    
1391            /**
1392             * Imports the layouts from the byte array.
1393             *
1394             * @param  userId the primary key of the user
1395             * @param  groupId the primary key of the group
1396             * @param  privateLayout whether the layout is private to the group
1397             * @param  parameterMap the mapping of parameters indicating which
1398             *         information will be imported. For information on the keys used in
1399             *         the map see {@link
1400             *         com.liferay.portal.kernel.lar.PortletDataHandlerKeys}.
1401             * @param  bytes the byte array with the data
1402             * @throws PortalException if a group or user with the primary key could not
1403             *         be found, or if some other portal exception occurred
1404             * @throws SystemException if a system exception occurred
1405             * @see    com.liferay.portal.lar.LayoutImporter
1406             */
1407            public void importLayouts(
1408                            long userId, long groupId, boolean privateLayout,
1409                            Map<String, String[]> parameterMap, byte[] bytes)
1410                    throws PortalException, SystemException {
1411    
1412                    importLayouts(
1413                            userId, groupId, privateLayout, parameterMap,
1414                            new UnsyncByteArrayInputStream(bytes));
1415            }
1416    
1417            /**
1418             * Imports the layouts from the file.
1419             *
1420             * @param  userId the primary key of the user
1421             * @param  groupId the primary key of the group
1422             * @param  privateLayout whether the layout is private to the group
1423             * @param  parameterMap the mapping of parameters indicating which
1424             *         information will be imported. For information on the keys used in
1425             *         the map see {@link
1426             *         com.liferay.portal.kernel.lar.PortletDataHandlerKeys}.
1427             * @param  file the LAR file with the data
1428             * @throws PortalException if a group or user with the primary key could not
1429             *         be found, or if some other portal exception occurred
1430             * @throws SystemException if a system exception occurred
1431             * @see    com.liferay.portal.lar.LayoutImporter
1432             */
1433            public void importLayouts(
1434                            long userId, long groupId, boolean privateLayout,
1435                            Map<String, String[]> parameterMap, File file)
1436                    throws PortalException, SystemException {
1437    
1438                    try {
1439                            LayoutImporter layoutImporter = new LayoutImporter();
1440    
1441                            layoutImporter.importLayouts(
1442                                    userId, groupId, privateLayout, parameterMap, file);
1443                    }
1444                    catch (PortalException pe) {
1445                            Throwable cause = pe.getCause();
1446    
1447                            if (cause instanceof LocaleException) {
1448                                    throw (PortalException)cause;
1449                            }
1450    
1451                            throw pe;
1452                    }
1453                    catch (SystemException se) {
1454                            throw se;
1455                    }
1456                    catch (Exception e) {
1457                            throw new SystemException(e);
1458                    }
1459            }
1460    
1461            /**
1462             * Imports the layouts from the input stream.
1463             *
1464             * @param  userId the primary key of the user
1465             * @param  groupId the primary key of the group
1466             * @param  privateLayout whether the layout is private to the group
1467             * @param  parameterMap the mapping of parameters indicating which
1468             *         information will be imported. For information on the keys used in
1469             *         the map see {@link
1470             *         com.liferay.portal.kernel.lar.PortletDataHandlerKeys}.
1471             * @param  is the input stream
1472             * @throws PortalException if a group or user with the primary key could not
1473             *         be found, or if some other portal exception occurred
1474             * @throws SystemException if a system exception occurred
1475             * @see    com.liferay.portal.lar.LayoutImporter
1476             */
1477            public void importLayouts(
1478                            long userId, long groupId, boolean privateLayout,
1479                            Map<String, String[]> parameterMap, InputStream is)
1480                    throws PortalException, SystemException {
1481    
1482                    File file = null;
1483    
1484                    try {
1485                            file = FileUtil.createTempFile("lar");
1486    
1487                            FileUtil.write(file, is);
1488    
1489                            importLayouts(userId, groupId, privateLayout, parameterMap, file);
1490                    }
1491                    catch (IOException ioe) {
1492                            throw new SystemException(ioe);
1493                    }
1494                    finally {
1495                            FileUtil.delete(file);
1496                    }
1497            }
1498    
1499            /**
1500             * Imports the portlet information (categories, permissions, ... etc.) from
1501             * the file.
1502             *
1503             * @param  userId the primary key of the user
1504             * @param  plid the primary key of the target layout
1505             * @param  groupId the primary key of the target group
1506             * @param  portletId the primary key of the portlet
1507             * @param  parameterMap the mapping of parameters indicating which
1508             *         information will be imported. For information on the keys used in
1509             *         the map see {@link
1510             *         com.liferay.portal.kernel.lar.PortletDataHandlerKeys}.
1511             * @param  file the LAR file with the data
1512             * @throws PortalException if a group, layout, portlet or user with the
1513             *         primary key could not be found
1514             * @throws SystemException if a system exception occurred
1515             */
1516            public void importPortletInfo(
1517                            long userId, long plid, long groupId, String portletId,
1518                            Map<String, String[]> parameterMap, File file)
1519                    throws PortalException, SystemException {
1520    
1521                    try {
1522                            PortletImporter portletImporter = new PortletImporter();
1523    
1524                            portletImporter.importPortletInfo(
1525                                    userId, plid, groupId, portletId, parameterMap, file);
1526                    }
1527                    catch (PortalException pe) {
1528                            Throwable cause = pe.getCause();
1529    
1530                            if (cause instanceof LocaleException) {
1531                                    throw (PortalException)cause;
1532                            }
1533    
1534                            throw pe;
1535                    }
1536                    catch (SystemException se) {
1537                            throw se;
1538                    }
1539                    catch (Exception e) {
1540                            throw new SystemException(e);
1541                    }
1542            }
1543    
1544            /**
1545             * Imports the portlet information (categories, permissions, ... etc.) from
1546             * the input stream.
1547             *
1548             * @param  userId the primary key of the user
1549             * @param  plid the primary key of the layout
1550             * @param  groupId the primary key of the group
1551             * @param  portletId the primary key of the portlet
1552             * @param  parameterMap the mapping of parameters indicating which
1553             *         information will be imported. For information on the keys used in
1554             *         the map see {@link
1555             *         com.liferay.portal.kernel.lar.PortletDataHandlerKeys}.
1556             * @param  is the input stream
1557             * @throws PortalException if a group, portlet, layout or user with the
1558             *         primary key could not be found
1559             * @throws SystemException if a system exception occurred
1560             */
1561            public void importPortletInfo(
1562                            long userId, long plid, long groupId, String portletId,
1563                            Map<String, String[]> parameterMap, InputStream is)
1564                    throws PortalException, SystemException {
1565    
1566                    File file = null;
1567    
1568                    try {
1569                            file = FileUtil.createTempFile("lar");
1570    
1571                            FileUtil.write(file, is);
1572    
1573                            importPortletInfo(
1574                                    userId, plid, groupId, portletId, parameterMap, file);
1575                    }
1576                    catch (IOException ioe) {
1577                            throw new SystemException(ioe);
1578                    }
1579                    finally {
1580                            FileUtil.delete(file);
1581                    }
1582            }
1583    
1584            /**
1585             * Sets the layouts for the group, replacing and prioritizing all layouts of
1586             * the parent layout.
1587             *
1588             * @param  groupId the primary key of the group
1589             * @param  privateLayout whether the layout is private to the group
1590             * @param  parentLayoutId the primary key of the parent layout
1591             * @param  layoutIds the primary keys of the layouts
1592             * @param  serviceContext the service context
1593             * @throws PortalException if a group or layout with the primary key could
1594             *         not be found, if no layouts were specified, if the first layout
1595             *         was not page-able, if the first layout was hidden, or if some
1596             *         other portal exception occurred
1597             * @throws SystemException if a system exception occurred
1598             */
1599            public void setLayouts(
1600                            long groupId, boolean privateLayout, long parentLayoutId,
1601                            long[] layoutIds, ServiceContext serviceContext)
1602                    throws PortalException, SystemException {
1603    
1604                    if (layoutIds == null) {
1605                            return;
1606                    }
1607    
1608                    if (parentLayoutId == LayoutConstants.DEFAULT_PARENT_LAYOUT_ID) {
1609                            if (layoutIds.length < 1) {
1610                                    throw new RequiredLayoutException(
1611                                            RequiredLayoutException.AT_LEAST_ONE);
1612                            }
1613    
1614                            Layout layout = layoutPersistence.findByG_P_L(
1615                                    groupId, privateLayout, layoutIds[0]);
1616    
1617                            if (!PortalUtil.isLayoutFirstPageable(layout.getType())) {
1618                                    throw new RequiredLayoutException(
1619                                            RequiredLayoutException.FIRST_LAYOUT_TYPE);
1620                            }
1621    
1622                            if (layout.isHidden()) {
1623                                    throw new RequiredLayoutException(
1624                                            RequiredLayoutException.FIRST_LAYOUT_HIDDEN);
1625                            }
1626                    }
1627    
1628                    Set<Long> layoutIdsSet = new LinkedHashSet<Long>();
1629    
1630                    for (long layoutId : layoutIds) {
1631                            layoutIdsSet.add(layoutId);
1632                    }
1633    
1634                    Set<Long> newLayoutIdsSet = new HashSet<Long>();
1635    
1636                    List<Layout> layouts = layoutPersistence.findByG_P_P(
1637                            groupId, privateLayout, parentLayoutId);
1638    
1639                    for (Layout layout : layouts) {
1640                            if (!layoutIdsSet.contains(layout.getLayoutId())) {
1641                                    deleteLayout(layout, true, serviceContext);
1642                            }
1643                            else {
1644                                    newLayoutIdsSet.add(layout.getLayoutId());
1645                            }
1646                    }
1647    
1648                    int priority = 0;
1649    
1650                    for (long layoutId : layoutIdsSet) {
1651                            Layout layout = layoutPersistence.findByG_P_L(
1652                                    groupId, privateLayout, layoutId);
1653    
1654                            layout.setPriority(priority++);
1655    
1656                            layoutPersistence.update(layout);
1657                    }
1658    
1659                    layoutSetLocalService.updatePageCount(groupId, privateLayout);
1660            }
1661    
1662            /**
1663             * Updates the friendly URL of the layout.
1664             *
1665             * @param  plid the primary key of the layout
1666             * @param  friendlyURL the friendly URL to be assigned
1667             * @return the updated layout
1668             * @throws PortalException if a group or layout with the primary key could
1669             *         not be found
1670             * @throws SystemException if a system exception occurred
1671             */
1672            public Layout updateFriendlyURL(long plid, String friendlyURL)
1673                    throws PortalException, SystemException {
1674    
1675                    Date now = new Date();
1676    
1677                    Layout layout = layoutPersistence.findByPrimaryKey(plid);
1678    
1679                    friendlyURL = layoutLocalServiceHelper.getFriendlyURL(
1680                            layout.getGroupId(), layout.isPrivateLayout(), layout.getLayoutId(),
1681                            StringPool.BLANK, friendlyURL);
1682    
1683                    layoutLocalServiceHelper.validateFriendlyURL(
1684                            layout.getGroupId(), layout.isPrivateLayout(), layout.getLayoutId(),
1685                            friendlyURL);
1686    
1687                    layout.setModifiedDate(now);
1688                    layout.setFriendlyURL(friendlyURL);
1689    
1690                    layoutPersistence.update(layout);
1691    
1692                    return layout;
1693            }
1694    
1695            /**
1696             * Updates the layout.
1697             *
1698             * @param  groupId the primary key of the group
1699             * @param  privateLayout whether the layout is private to the group
1700             * @param  layoutId the primary key of the layout
1701             * @param  parentLayoutId the primary key of the layout's new parent layout
1702             * @param  nameMap the locales and localized names to merge (optionally
1703             *         <code>null</code>)
1704             * @param  titleMap the locales and localized titles to merge (optionally
1705             *         <code>null</code>)
1706             * @param  descriptionMap the locales and localized descriptions to merge
1707             *         (optionally <code>null</code>)
1708             * @param  keywordsMap the locales and localized keywords to merge
1709             *         (optionally <code>null</code>)
1710             * @param  robotsMap the locales and localized robots to merge (optionally
1711             *         <code>null</code>)
1712             * @param  type the layout's new type (optionally {@link
1713             *         com.liferay.portal.model.LayoutConstants#TYPE_PORTLET})
1714             * @param  hidden whether the layout is hidden
1715             * @param  friendlyURL the layout's new friendly URL (optionally {@link
1716             *         com.liferay.portal.util.PropsValues#DEFAULT_USER_PRIVATE_LAYOUT_FRIENDLY_URL}
1717             *         or {@link
1718             *         com.liferay.portal.util.PropsValues#DEFAULT_USER_PRIVATE_LAYOUT_FRIENDLY_URL}).
1719             *         The default values can be overridden in
1720             *         <code>portal-ext.properties</code> by specifying new values for
1721             *         the corresponding properties defined in {@link
1722             *         com.liferay.portal.util.PropsValues}. To see how the URL is
1723             *         normalized when accessed see {@link
1724             *         com.liferay.portal.kernel.util.FriendlyURLNormalizerUtil#normalize(
1725             *         String)}.
1726             * @param  iconImage whether the icon image will be updated
1727             * @param  iconBytes the byte array of the layout's new icon image
1728             * @param  serviceContext the service context. Can set the modification date
1729             *         and expando bridge attributes for the layout. For layouts that
1730             *         are linked to a layout prototype, attributes named
1731             *         'layoutPrototypeUuid' and 'layoutPrototypeLinkedEnabled' can be
1732             *         specified to provide the unique identifier of the source
1733             *         prototype and a boolean to determined whether a link to it should
1734             *         be enabled to activate propagation of changes made to the linked
1735             *         page in the prototype.
1736             * @return the updated layout
1737             * @throws PortalException if a group or layout with the primary key could
1738             *         not be found, if a unique friendly URL could not be generated, if
1739             *         a valid parent layout ID to use could not be found, or if the
1740             *         layout parameters were invalid
1741             * @throws SystemException if a system exception occurred
1742             */
1743            public Layout updateLayout(
1744                            long groupId, boolean privateLayout, long layoutId,
1745                            long parentLayoutId, Map<Locale, String> nameMap,
1746                            Map<Locale, String> titleMap, Map<Locale, String> descriptionMap,
1747                            Map<Locale, String> keywordsMap, Map<Locale, String> robotsMap,
1748                            String type, boolean hidden, String friendlyURL, Boolean iconImage,
1749                            byte[] iconBytes, ServiceContext serviceContext)
1750                    throws PortalException, SystemException {
1751    
1752                    // Layout
1753    
1754                    parentLayoutId = layoutLocalServiceHelper.getParentLayoutId(
1755                            groupId, privateLayout, parentLayoutId);
1756                    String name = nameMap.get(LocaleUtil.getDefault());
1757                    friendlyURL = layoutLocalServiceHelper.getFriendlyURL(
1758                            groupId, privateLayout, layoutId, StringPool.BLANK, friendlyURL);
1759    
1760                    layoutLocalServiceHelper.validate(
1761                            groupId, privateLayout, layoutId, parentLayoutId, name, type,
1762                            hidden, friendlyURL);
1763    
1764                    layoutLocalServiceHelper.validateParentLayoutId(
1765                            groupId, privateLayout, layoutId, parentLayoutId);
1766    
1767                    Date now = new Date();
1768    
1769                    Layout layout = layoutPersistence.findByG_P_L(
1770                            groupId, privateLayout, layoutId);
1771    
1772                    List<Locale> modifiedLocales = LocalizationUtil.getModifiedLocales(
1773                            layout.getNameMap(), nameMap);
1774    
1775                    if (parentLayoutId != layout.getParentLayoutId()) {
1776                            int priority = layoutLocalServiceHelper.getNextPriority(
1777                                    groupId, privateLayout, parentLayoutId,
1778                                    layout.getSourcePrototypeLayoutUuid(), -1);
1779    
1780                            layout.setPriority(priority);
1781                    }
1782    
1783                    layout.setModifiedDate(serviceContext.getModifiedDate(now));
1784                    layout.setParentLayoutId(parentLayoutId);
1785                    layout.setNameMap(nameMap);
1786                    layout.setTitleMap(titleMap);
1787                    layout.setDescriptionMap(descriptionMap);
1788                    layout.setKeywordsMap(keywordsMap);
1789                    layout.setRobotsMap(robotsMap);
1790                    layout.setType(type);
1791                    layout.setHidden(hidden);
1792                    layout.setFriendlyURL(friendlyURL);
1793    
1794                    if (iconImage != null) {
1795                            layout.setIconImage(iconImage.booleanValue());
1796    
1797                            if (iconImage.booleanValue()) {
1798                                    long iconImageId = layout.getIconImageId();
1799    
1800                                    if (iconImageId <= 0) {
1801                                            iconImageId = counterLocalService.increment();
1802    
1803                                            layout.setIconImageId(iconImageId);
1804                                    }
1805                            }
1806                    }
1807    
1808                    boolean layoutUpdateable = ParamUtil.getBoolean(
1809                            serviceContext, SitesUtil.LAYOUT_UPDATEABLE, true);
1810    
1811                    UnicodeProperties typeSettingsProperties =
1812                            layout.getTypeSettingsProperties();
1813    
1814                    typeSettingsProperties.put(
1815                            SitesUtil.LAYOUT_UPDATEABLE, String.valueOf(layoutUpdateable));
1816    
1817                    layout.setTypeSettingsProperties(typeSettingsProperties);
1818    
1819                    String layoutPrototypeUuid = ParamUtil.getString(
1820                            serviceContext, "layoutPrototypeUuid");
1821                    boolean layoutPrototypeLinkEnabled = ParamUtil.getBoolean(
1822                            serviceContext, "layoutPrototypeLinkEnabled");
1823    
1824                    if (Validator.isNotNull(layoutPrototypeUuid)) {
1825                            layout.setLayoutPrototypeUuid(layoutPrototypeUuid);
1826                            layout.setLayoutPrototypeLinkEnabled(layoutPrototypeLinkEnabled);
1827                    }
1828    
1829                    layoutPersistence.update(layout);
1830    
1831                    // Icon
1832    
1833                    if (iconImage != null) {
1834                            if (!iconImage.booleanValue()) {
1835                                    imageLocalService.deleteImage(layout.getIconImageId());
1836                            }
1837                            else if ((iconBytes != null) && (iconBytes.length > 0)) {
1838                                    imageLocalService.updateImage(
1839                                            layout.getIconImageId(), iconBytes);
1840                            }
1841                    }
1842    
1843                    // Portlet preferences
1844    
1845                    if (!modifiedLocales.isEmpty()) {
1846                            updateScopedPortletNames(
1847                                    groupId, privateLayout, layoutId, nameMap, modifiedLocales);
1848                    }
1849    
1850                    // Expando
1851    
1852                    ExpandoBridge expandoBridge = layout.getExpandoBridge();
1853    
1854                    expandoBridge.setAttributes(serviceContext);
1855    
1856                    return layout;
1857            }
1858    
1859            /**
1860             * Updates the layout replacing its type settings.
1861             *
1862             * @param  groupId the primary key of the group
1863             * @param  privateLayout whether the layout is private to the group
1864             * @param  layoutId the primary key of the layout
1865             * @param  typeSettings the settings to load the unicode properties object.
1866             *         See {@link com.liferay.portal.kernel.util.UnicodeProperties
1867             *         #fastLoad(String)}.
1868             * @return the updated layout
1869             * @throws PortalException if a matching layout could not be found
1870             * @throws SystemException if a system exception occurred
1871             */
1872            public Layout updateLayout(
1873                            long groupId, boolean privateLayout, long layoutId,
1874                            String typeSettings)
1875                    throws PortalException, SystemException {
1876    
1877                    Date now = new Date();
1878    
1879                    UnicodeProperties typeSettingsProperties = new UnicodeProperties();
1880    
1881                    typeSettingsProperties.fastLoad(typeSettings);
1882    
1883                    Layout layout = layoutPersistence.findByG_P_L(
1884                            groupId, privateLayout, layoutId);
1885    
1886                    layout.setModifiedDate(now);
1887                    layout.setTypeSettings(typeSettingsProperties.toString());
1888    
1889                    layoutPersistence.update(layout);
1890    
1891                    return layout;
1892            }
1893    
1894            /**
1895             * Updates the look and feel of the layout.
1896             *
1897             * @param  groupId the primary key of the group
1898             * @param  privateLayout whether the layout is private to the group
1899             * @param  layoutId the primary key of the layout
1900             * @param  themeId the primary key of the layout's new theme
1901             * @param  colorSchemeId the primary key of the layout's new color scheme
1902             * @param  css the layout's new CSS
1903             * @param  wapTheme whether the theme is for WAP browsers
1904             * @return the updated layout
1905             * @throws PortalException if a matching layout could not be found
1906             * @throws SystemException if a system exception occurred
1907             */
1908            public Layout updateLookAndFeel(
1909                            long groupId, boolean privateLayout, long layoutId, String themeId,
1910                            String colorSchemeId, String css, boolean wapTheme)
1911                    throws PortalException, SystemException {
1912    
1913                    Date now = new Date();
1914    
1915                    Layout layout = layoutPersistence.findByG_P_L(
1916                            groupId, privateLayout, layoutId);
1917    
1918                    layout.setModifiedDate(now);
1919    
1920                    if (wapTheme) {
1921                            layout.setWapThemeId(themeId);
1922                            layout.setWapColorSchemeId(colorSchemeId);
1923                    }
1924                    else {
1925                            layout.setThemeId(themeId);
1926                            layout.setColorSchemeId(colorSchemeId);
1927                            layout.setCss(css);
1928                    }
1929    
1930                    layoutPersistence.update(layout);
1931    
1932                    return layout;
1933            }
1934    
1935            /**
1936             * Updates the name of the layout.
1937             *
1938             * @param  layout the layout to be updated
1939             * @param  name the layout's new name
1940             * @param  languageId the primary key of the language. For more information
1941             *         see {@link java.util.Locale}.
1942             * @return the updated layout
1943             * @throws PortalException if the new name was <code>null</code>
1944             * @throws SystemException if a system exception occurred
1945             */
1946            public Layout updateName(Layout layout, String name, String languageId)
1947                    throws PortalException, SystemException {
1948    
1949                    Date now = new Date();
1950    
1951                    layoutLocalServiceHelper.validateName(name, languageId);
1952    
1953                    layout.setModifiedDate(now);
1954                    layout.setName(name, LocaleUtil.fromLanguageId(languageId));
1955    
1956                    layoutPersistence.update(layout);
1957    
1958                    return layout;
1959            }
1960    
1961            /**
1962             * Updates the name of the layout matching the group, layout ID, and
1963             * privacy.
1964             *
1965             * @param  groupId the primary key of the group
1966             * @param  privateLayout whether the layout is private to the group
1967             * @param  layoutId the primary key of the layout
1968             * @param  name the layout's new name
1969             * @param  languageId the primary key of the language. For more information
1970             *         see {@link java.util.Locale}.
1971             * @return the updated layout
1972             * @throws PortalException if a matching layout could not be found or if the
1973             *         new name was <code>null</code>
1974             * @throws SystemException if a system exception occurred
1975             */
1976            public Layout updateName(
1977                            long groupId, boolean privateLayout, long layoutId, String name,
1978                            String languageId)
1979                    throws PortalException, SystemException {
1980    
1981                    Layout layout = layoutPersistence.findByG_P_L(
1982                            groupId, privateLayout, layoutId);
1983    
1984                    return layoutLocalService.updateName(layout, name, languageId);
1985            }
1986    
1987            /**
1988             * Updates the name of the layout matching the primary key.
1989             *
1990             * @param  plid the primary key of the layout
1991             * @param  name the name to be assigned
1992             * @param  languageId the primary key of the language. For more information
1993             *         see {@link java.util.Locale}.
1994             * @return the updated layout
1995             * @throws PortalException if a layout with the primary key could not be
1996             *         found or if the name was <code>null</code>
1997             * @throws SystemException if a system exception occurred
1998             */
1999            public Layout updateName(long plid, String name, String languageId)
2000                    throws PortalException, SystemException {
2001    
2002                    Layout layout = layoutPersistence.findByPrimaryKey(plid);
2003    
2004                    return layoutLocalService.updateName(layout, name, languageId);
2005            }
2006    
2007            /**
2008             * Updates the parent layout ID of the layout matching the group, layout ID,
2009             * and privacy.
2010             *
2011             * @param  groupId the primary key of the group
2012             * @param  privateLayout whether the layout is private to the group
2013             * @param  layoutId the primary key of the layout
2014             * @param  parentLayoutId the primary key to be assigned to the parent
2015             *         layout
2016             * @return the matching layout
2017             * @throws PortalException if a valid parent layout ID to use could not be
2018             *         found or if a matching layout could not be found
2019             * @throws SystemException if a system exception occurred
2020             */
2021            public Layout updateParentLayoutId(
2022                            long groupId, boolean privateLayout, long layoutId,
2023                            long parentLayoutId)
2024                    throws PortalException, SystemException {
2025    
2026                    parentLayoutId = layoutLocalServiceHelper.getParentLayoutId(
2027                            groupId, privateLayout, parentLayoutId);
2028    
2029                    layoutLocalServiceHelper.validateParentLayoutId(
2030                            groupId, privateLayout, layoutId, parentLayoutId);
2031    
2032                    Date now = new Date();
2033    
2034                    Layout layout = layoutPersistence.findByG_P_L(
2035                            groupId, privateLayout, layoutId);
2036    
2037                    if (parentLayoutId != layout.getParentLayoutId()) {
2038                            int priority = layoutLocalServiceHelper.getNextPriority(
2039                                    groupId, privateLayout, parentLayoutId,
2040                                    layout.getSourcePrototypeLayoutUuid(), -1);
2041    
2042                            layout.setPriority(priority);
2043                    }
2044    
2045                    layout.setModifiedDate(now);
2046                    layout.setParentLayoutId(parentLayoutId);
2047    
2048                    layoutPersistence.update(layout);
2049    
2050                    return layout;
2051            }
2052    
2053            /**
2054             * Updates the parent layout ID of the layout matching the primary key. If a
2055             * layout matching the parent primary key is found, the layout ID of that
2056             * layout is assigned, otherwise {@link
2057             * com.liferay.portal.model.LayoutConstants#DEFAULT_PARENT_LAYOUT_ID} is
2058             * assigned.
2059             *
2060             * @param  plid the primary key of the layout
2061             * @param  parentPlid the primary key of the parent layout
2062             * @return the layout matching the primary key
2063             * @throws PortalException if a layout with the primary key could not be
2064             *         found or if a valid parent layout ID to use could not be found
2065             * @throws SystemException if a system exception occurred
2066             */
2067            public Layout updateParentLayoutId(long plid, long parentPlid)
2068                    throws PortalException, SystemException {
2069    
2070                    Date now = new Date();
2071    
2072                    Layout layout = layoutPersistence.findByPrimaryKey(plid);
2073    
2074                    long parentLayoutId = LayoutConstants.DEFAULT_PARENT_LAYOUT_ID;
2075    
2076                    if (parentPlid > 0) {
2077                            Layout parentLayout = layoutPersistence.fetchByPrimaryKey(
2078                                    parentPlid);
2079    
2080                            if (parentLayout != null) {
2081                                    parentLayoutId = parentLayout.getLayoutId();
2082                            }
2083                    }
2084    
2085                    parentLayoutId = layoutLocalServiceHelper.getParentLayoutId(
2086                            layout.getGroupId(), layout.isPrivateLayout(), parentLayoutId);
2087    
2088                    layoutLocalServiceHelper.validateParentLayoutId(
2089                            layout.getGroupId(), layout.isPrivateLayout(), layout.getLayoutId(),
2090                            parentLayoutId);
2091    
2092                    if (parentLayoutId != layout.getParentLayoutId()) {
2093                            int priority = layoutLocalServiceHelper.getNextPriority(
2094                                    layout.getGroupId(), layout.isPrivateLayout(), parentLayoutId,
2095                                    layout.getSourcePrototypeLayoutUuid(), -1);
2096    
2097                            layout.setPriority(priority);
2098                    }
2099    
2100                    layout.setModifiedDate(now);
2101                    layout.setParentLayoutId(parentLayoutId);
2102    
2103                    layoutPersistence.update(layout);
2104    
2105                    return layout;
2106            }
2107    
2108            /**
2109             * Updates the priorities of the layouts.
2110             *
2111             * @param  groupId the primary key of the group
2112             * @param  privateLayout whether the layout is private to the group
2113             * @throws PortalException if a matching layout could not be found
2114             * @throws SystemException if a system exception occurred
2115             */
2116            public void updatePriorities(long groupId, boolean privateLayout)
2117                    throws PortalException, SystemException {
2118    
2119                    List<Layout> layouts = layoutPersistence.findByG_P(
2120                            groupId, privateLayout);
2121    
2122                    for (Layout layout : layouts) {
2123                            int nextPriority = layoutLocalServiceHelper.getNextPriority(
2124                                    layout.getGroupId(), layout.isPrivateLayout(),
2125                                    layout.getParentLayoutId(),
2126                                    layout.getSourcePrototypeLayoutUuid(), layout.getPriority());
2127    
2128                            layout.setPriority(nextPriority);
2129    
2130                            layoutPersistence.update(layout);
2131                    }
2132            }
2133    
2134            /**
2135             * Updates the priority of the layout.
2136             *
2137             * @param  layout the layout to be updated
2138             * @param  priority the layout's new priority
2139             * @return the updated layout
2140             * @throws SystemException if a system exception occurred
2141             */
2142            public Layout updatePriority(Layout layout, int priority)
2143                    throws SystemException {
2144    
2145                    if (layout.getPriority() == priority) {
2146                            return layout;
2147                    }
2148    
2149                    Date now = new Date();
2150    
2151                    layout.setModifiedDate(now);
2152    
2153                    int oldPriority = layout.getPriority();
2154    
2155                    int nextPriority = layoutLocalServiceHelper.getNextPriority(
2156                            layout.getGroupId(), layout.isPrivateLayout(),
2157                            layout.getParentLayoutId(), layout.getSourcePrototypeLayoutUuid(),
2158                            priority);
2159    
2160                    layout.setPriority(nextPriority);
2161    
2162                    layoutPersistence.update(layout);
2163    
2164                    List<Layout> layouts = layoutPersistence.findByG_P_P(
2165                            layout.getGroupId(), layout.isPrivateLayout(),
2166                            layout.getParentLayoutId());
2167    
2168                    boolean lessThan = false;
2169    
2170                    if (oldPriority < nextPriority) {
2171                            lessThan = true;
2172                    }
2173    
2174                    layouts = ListUtil.sort(
2175                            layouts, new LayoutPriorityComparator(layout, lessThan));
2176    
2177                    priority = 0;
2178    
2179                    for (Layout curLayout : layouts) {
2180                            curLayout.setModifiedDate(now);
2181    
2182                            int curNextPriority = layoutLocalServiceHelper.getNextPriority(
2183                                    layout.getGroupId(), layout.isPrivateLayout(),
2184                                    layout.getParentLayoutId(),
2185                                    curLayout.getSourcePrototypeLayoutUuid(), priority++);
2186    
2187                            curLayout.setPriority(curNextPriority);
2188    
2189                            layoutPersistence.update(curLayout);
2190    
2191                            if (curLayout.equals(layout)) {
2192                                    layout = curLayout;
2193                            }
2194                    }
2195    
2196                    return layout;
2197            }
2198    
2199            /**
2200             * Updates the priority of the layout matching the group, layout ID, and
2201             * privacy.
2202             *
2203             * @param  groupId the primary key of the group
2204             * @param  privateLayout whether the layout is private to the group
2205             * @param  layoutId the primary key of the layout
2206             * @param  priority the layout's new priority
2207             * @return the updated layout
2208             * @throws PortalException if a matching layout could not be found
2209             * @throws SystemException if a system exception occurred
2210             */
2211            public Layout updatePriority(
2212                            long groupId, boolean privateLayout, long layoutId, int priority)
2213                    throws PortalException, SystemException {
2214    
2215                    Layout layout = layoutPersistence.findByG_P_L(
2216                            groupId, privateLayout, layoutId);
2217    
2218                    return updatePriority(layout, priority);
2219            }
2220    
2221            /**
2222             * Updates the priority of the layout matching the primary key.
2223             *
2224             * @param  plid the primary key of the layout
2225             * @param  priority the layout's new priority
2226             * @return the updated layout
2227             * @throws PortalException if a layout with the primary key could not be
2228             *         found
2229             * @throws SystemException if a system exception occurred
2230             */
2231            public Layout updatePriority(long plid, int priority)
2232                    throws PortalException, SystemException {
2233    
2234                    Layout layout = layoutPersistence.findByPrimaryKey(plid);
2235    
2236                    return updatePriority(layout, priority);
2237            }
2238    
2239            public void updateScopedPortletNames(
2240                            long groupId, boolean privateLayout, long layoutId,
2241                            Map<Locale, String> nameMap, List<Locale> nameMapModifiedLocales)
2242                    throws PortalException, SystemException {
2243    
2244                    Layout layout = layoutPersistence.findByG_P_L(
2245                            groupId, privateLayout, layoutId);
2246    
2247                    DynamicQuery portletPreferencesDynamicQuery =
2248                            DynamicQueryFactoryUtil.forClass(
2249                                    PortletPreferences.class, PortletPreferencesImpl.TABLE_NAME,
2250                                    ClassLoaderUtil.getPortalClassLoader());
2251    
2252                    Property plidProperty = PropertyFactoryUtil.forName("plid");
2253    
2254                    DynamicQuery layoutDynamicQuery = DynamicQueryFactoryUtil.forClass(
2255                            Layout.class, LayoutImpl.TABLE_NAME,
2256                            ClassLoaderUtil.getPortalClassLoader());
2257    
2258                    Projection plidProjection = ProjectionFactoryUtil.property("plid");
2259    
2260                    layoutDynamicQuery.setProjection(plidProjection, false);
2261    
2262                    Property groupIdProperty = PropertyFactoryUtil.forName("groupId");
2263    
2264                    layoutDynamicQuery.add(groupIdProperty.eq(groupId));
2265    
2266                    Property privateLayoutProperty = PropertyFactoryUtil.forName(
2267                            "privateLayout");
2268    
2269                    layoutDynamicQuery.add(privateLayoutProperty.eq(privateLayout));
2270    
2271                    portletPreferencesDynamicQuery.add(plidProperty.in(layoutDynamicQuery));
2272    
2273                    Junction junction = RestrictionsFactoryUtil.disjunction();
2274    
2275                    List<Portlet> scopablePortlets =
2276                            portletLocalService.getScopablePortlets();
2277    
2278                    for (Portlet scopablePortlet :scopablePortlets) {
2279                            if (scopablePortlet.isInstanceable()) {
2280                                    Criterion criterion = RestrictionsFactoryUtil.like(
2281                                            "portletId",
2282                                            scopablePortlet.getPortletId() +
2283                                                    PortletConstants.INSTANCE_SEPARATOR +
2284                                                            StringPool.PERCENT);
2285    
2286                                    junction.add(criterion);
2287                            }
2288                            else {
2289                                    Criterion criterion = RestrictionsFactoryUtil.eq(
2290                                            "portletId", scopablePortlet.getPortletId());
2291    
2292                                    junction.add(criterion);
2293                            }
2294                    }
2295    
2296                    portletPreferencesDynamicQuery.add(junction);
2297    
2298                    List<PortletPreferences> portletPreferencesList =
2299                            portletPreferencesLocalService.dynamicQuery(
2300                                    portletPreferencesDynamicQuery);
2301    
2302                    for (PortletPreferences portletPreferences : portletPreferencesList) {
2303                            if (portletPreferences.getPortletId() == null) {
2304                                    continue;
2305                            }
2306    
2307                            Layout curLayout = layoutPersistence.findByPrimaryKey(
2308                                    portletPreferences.getPlid());
2309    
2310                            javax.portlet.PortletPreferences jxPreferences =
2311                                    PortletPreferencesFactoryUtil.getLayoutPortletSetup(
2312                                            curLayout, portletPreferences.getPortletId());
2313    
2314                            String scopeLayoutUuid = GetterUtil.getString(
2315                                    jxPreferences.getValue("lfrScopeLayoutUuid", null));
2316    
2317                            if (!scopeLayoutUuid.equals(layout.getUuid())) {
2318                                    continue;
2319                            }
2320    
2321                            for (Locale locale : nameMapModifiedLocales) {
2322                                    String languageId = LanguageUtil.getLanguageId(locale);
2323    
2324                                    String portletTitle = PortalUtil.getPortletTitle(
2325                                            PortletConstants.getRootPortletId(
2326                                                    portletPreferences.getPortletId()), languageId);
2327    
2328                                    String newPortletTitle = PortalUtil.getNewPortletTitle(
2329                                            portletTitle, curLayout.getName(languageId),
2330                                            nameMap.get(locale));
2331    
2332                                    if (newPortletTitle.equals(portletTitle)) {
2333                                            continue;
2334                                    }
2335    
2336                                    try {
2337                                            jxPreferences.setValue(
2338                                                    "portletSetupTitle_" + languageId, newPortletTitle);
2339                                            jxPreferences.setValue(
2340                                                    "portletSetupUseCustomTitle", Boolean.TRUE.toString());
2341    
2342                                            jxPreferences.store();
2343                                    }
2344                                    catch (IOException ioe) {
2345                                            throw new SystemException(ioe);
2346                                    }
2347                                    catch (PortletException pe) {
2348                                            throw new SystemException(pe);
2349                                    }
2350                            }
2351                    }
2352            }
2353    
2354            /**
2355             * Updates the names of the portlets within scope of the group, the scope of
2356             * the layout's UUID, and the privacy.
2357             *
2358             * @param  groupId the primary key of the group
2359             * @param  privateLayout whether the layout is private to the group
2360             * @param  layoutId the primary key of the layout whose UUID to match
2361             * @param  name the new name for the portlets
2362             * @param  languageId the primary key of the language
2363             * @throws PortalException if a matching layout could not be found
2364             * @throws SystemException if a system exception occurred
2365             * @see    com.liferay.portlet.portletconfiguration.action.EditScopeAction
2366             */
2367            public void updateScopedPortletNames(
2368                            long groupId, boolean privateLayout, long layoutId, String name,
2369                            String languageId)
2370                    throws PortalException, SystemException {
2371    
2372                    Map<Locale, String> map = new HashMap<Locale, String>();
2373    
2374                    Locale locale = LocaleUtil.fromLanguageId(languageId);
2375    
2376                    map.put(locale, name);
2377    
2378                    List<Locale> locales = new ArrayList<Locale>();
2379    
2380                    locales.add(locale);
2381    
2382                    updateScopedPortletNames(
2383                            groupId, privateLayout, layoutId, map, locales);
2384            }
2385    
2386            @BeanReference(type = LayoutLocalServiceHelper.class)
2387            protected LayoutLocalServiceHelper layoutLocalServiceHelper;
2388    
2389    }