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