001    /**
002     * Copyright (c) 2000-2011 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.LayoutFriendlyURLException;
018    import com.liferay.portal.LayoutHiddenException;
019    import com.liferay.portal.LayoutNameException;
020    import com.liferay.portal.LayoutParentLayoutIdException;
021    import com.liferay.portal.LayoutTypeException;
022    import com.liferay.portal.NoSuchLayoutException;
023    import com.liferay.portal.RequiredLayoutException;
024    import com.liferay.portal.kernel.exception.PortalException;
025    import com.liferay.portal.kernel.exception.SystemException;
026    import com.liferay.portal.kernel.io.unsync.UnsyncByteArrayInputStream;
027    import com.liferay.portal.kernel.language.LanguageUtil;
028    import com.liferay.portal.kernel.log.Log;
029    import com.liferay.portal.kernel.log.LogFactoryUtil;
030    import com.liferay.portal.kernel.util.FileUtil;
031    import com.liferay.portal.kernel.util.GetterUtil;
032    import com.liferay.portal.kernel.util.ListUtil;
033    import com.liferay.portal.kernel.util.LocaleUtil;
034    import com.liferay.portal.kernel.util.StringBundler;
035    import com.liferay.portal.kernel.util.StringPool;
036    import com.liferay.portal.kernel.util.Validator;
037    import com.liferay.portal.kernel.workflow.WorkflowConstants;
038    import com.liferay.portal.lar.LayoutExporter;
039    import com.liferay.portal.lar.LayoutImporter;
040    import com.liferay.portal.lar.PortletExporter;
041    import com.liferay.portal.lar.PortletImporter;
042    import com.liferay.portal.model.Group;
043    import com.liferay.portal.model.Layout;
044    import com.liferay.portal.model.LayoutConstants;
045    import com.liferay.portal.model.LayoutReference;
046    import com.liferay.portal.model.LayoutTypePortlet;
047    import com.liferay.portal.model.PortletConstants;
048    import com.liferay.portal.model.Resource;
049    import com.liferay.portal.model.ResourceConstants;
050    import com.liferay.portal.model.User;
051    import com.liferay.portal.model.impl.LayoutImpl;
052    import com.liferay.portal.service.ServiceContext;
053    import com.liferay.portal.service.base.LayoutLocalServiceBaseImpl;
054    import com.liferay.portal.service.persistence.BatchSessionUtil;
055    import com.liferay.portal.util.FriendlyURLNormalizer;
056    import com.liferay.portal.util.PortalUtil;
057    import com.liferay.portal.util.PortletKeys;
058    import com.liferay.portal.util.PropsValues;
059    import com.liferay.portal.util.comparator.LayoutComparator;
060    import com.liferay.portal.util.comparator.LayoutPriorityComparator;
061    import com.liferay.portlet.documentlibrary.DuplicateFolderNameException;
062    import com.liferay.portlet.documentlibrary.NoSuchFolderException;
063    import com.liferay.portlet.documentlibrary.model.DLFolder;
064    import com.liferay.portlet.documentlibrary.model.DLFolderConstants;
065    import com.liferay.portlet.expando.model.ExpandoBridge;
066    
067    import java.io.File;
068    import java.io.IOException;
069    import java.io.InputStream;
070    
071    import java.util.ArrayList;
072    import java.util.Date;
073    import java.util.HashMap;
074    import java.util.HashSet;
075    import java.util.LinkedHashSet;
076    import java.util.List;
077    import java.util.Locale;
078    import java.util.Map;
079    import java.util.Set;
080    
081    /**
082     * @author Brian Wing Shun Chan
083     * @author Joel Kozikowski
084     * @author Charles May
085     * @author Raymond Augé
086     * @author Jorge Ferrer
087     * @author Bruno Farache
088     */
089    public class LayoutLocalServiceImpl extends LayoutLocalServiceBaseImpl {
090    
091            public static String getCounterName(long groupId, boolean privateLayout) {
092                    StringBundler sb = new StringBundler();
093    
094                    sb.append(Layout.class.getName());
095                    sb.append(StringPool.POUND);
096                    sb.append(groupId);
097                    sb.append(StringPool.POUND);
098                    sb.append(privateLayout);
099    
100                    return sb.toString();
101            }
102    
103            public Layout addLayout(
104                            long userId, long groupId, boolean privateLayout,
105                            long parentLayoutId, Map<Locale, String> localeNamesMap,
106                            Map<Locale, String> localeTitlesMap, String description,
107                            String type, boolean hidden, String friendlyURL, long dlFolderId,
108                            ServiceContext serviceContext)
109                    throws PortalException, SystemException {
110    
111                    // Layout
112    
113                    User user = userPersistence.findByPrimaryKey(userId);
114                    long layoutId = getNextLayoutId(groupId, privateLayout);
115                    parentLayoutId = getParentLayoutId(
116                            groupId, privateLayout, parentLayoutId);
117                    String name = localeNamesMap.get(LocaleUtil.getDefault());
118                    friendlyURL = getFriendlyURL(
119                            groupId, privateLayout, layoutId, name, friendlyURL);
120                    int priority = getNextPriority(groupId, privateLayout, parentLayoutId);
121    
122                    validate(
123                            groupId, privateLayout, layoutId, parentLayoutId, name, type,
124                            hidden, friendlyURL);
125    
126                    long plid = counterLocalService.increment();
127    
128                    Layout layout = layoutPersistence.create(plid);
129    
130                    layout.setUuid(serviceContext.getUuid());
131                    layout.setGroupId(groupId);
132                    layout.setCompanyId(user.getCompanyId());
133                    layout.setPrivateLayout(privateLayout);
134                    layout.setLayoutId(layoutId);
135                    layout.setParentLayoutId(parentLayoutId);
136                    layout.setDescription(description);
137                    layout.setType(type);
138                    layout.setHidden(hidden);
139                    layout.setFriendlyURL(friendlyURL);
140                    layout.setPriority(priority);
141                    layout.setDlFolderId(dlFolderId);
142    
143                    setLocalizedAttributes(layout, localeNamesMap, localeTitlesMap);
144    
145                    if (type.equals(LayoutConstants.TYPE_PORTLET)) {
146                            LayoutTypePortlet layoutTypePortlet =
147                                    (LayoutTypePortlet)layout.getLayoutType();
148    
149                            layoutTypePortlet.setLayoutTemplateId(
150                                    0, PropsValues.LAYOUT_DEFAULT_TEMPLATE_ID, false);
151                    }
152    
153                    layoutPersistence.update(layout, false);
154    
155                    // Resources
156    
157                    resourceLocalService.addResources(
158                            user.getCompanyId(), groupId, user.getUserId(),
159                            Layout.class.getName(), layout.getPlid(), false, true, true);
160    
161                    // Layout set
162    
163                    layoutSetLocalService.updatePageCount(groupId, privateLayout);
164    
165                    // Expando
166    
167                    ExpandoBridge expandoBridge = layout.getExpandoBridge();
168    
169                    expandoBridge.setAttributes(serviceContext);
170    
171                    // Message boards
172    
173                    if (PropsValues.LAYOUT_COMMENTS_ENABLED) {
174                            mbMessageLocalService.addDiscussionMessage(
175                                    userId, user.getFullName(), groupId, Layout.class.getName(),
176                                    plid, WorkflowConstants.ACTION_PUBLISH);
177                    }
178    
179                    return layout;
180            }
181    
182            public Layout addLayout(
183                            long userId, long groupId, boolean privateLayout,
184                            long parentLayoutId, Map<Locale, String> localeNamesMap,
185                            Map<Locale, String> localeTitlesMap, String description,
186                            String type, boolean hidden, String friendlyURL,
187                            ServiceContext serviceContext)
188                    throws PortalException, SystemException {
189    
190                    return addLayout(
191                            userId, groupId, privateLayout, parentLayoutId, localeNamesMap,
192                            localeTitlesMap, description, type, hidden, friendlyURL,
193                            DLFolderConstants.DEFAULT_PARENT_FOLDER_ID, serviceContext);
194            }
195    
196            public Layout addLayout(
197                            long userId, long groupId, boolean privateLayout,
198                            long parentLayoutId, String name, String title, String description,
199                            String type, boolean hidden, String friendlyURL, long dlFolderId,
200                            ServiceContext serviceContext)
201                    throws PortalException, SystemException {
202    
203                    Map<Locale, String> localeNamesMap = new HashMap<Locale, String>();
204    
205                    Locale defaultLocale = LocaleUtil.getDefault();
206    
207                    localeNamesMap.put(defaultLocale, name);
208    
209                    return addLayout(
210                            userId, groupId, privateLayout, parentLayoutId, localeNamesMap,
211                            null, description, type, hidden, friendlyURL, dlFolderId,
212                            serviceContext);
213            }
214    
215            public Layout addLayout(
216                            long userId, long groupId, boolean privateLayout,
217                            long parentLayoutId, String name, String title, String description,
218                            String type, boolean hidden, String friendlyURL,
219                            ServiceContext serviceContext)
220                    throws PortalException, SystemException {
221    
222                    Map<Locale, String> localeNamesMap = new HashMap<Locale, String>();
223    
224                    Locale defaultLocale = LocaleUtil.getDefault();
225    
226                    localeNamesMap.put(defaultLocale, name);
227    
228                    return addLayout(
229                            userId, groupId, privateLayout, parentLayoutId, localeNamesMap,
230                            new HashMap<Locale, String>(), description, type, hidden,
231                            friendlyURL, serviceContext);
232            }
233    
234            public void deleteLayout(Layout layout, boolean updateLayoutSet)
235                    throws PortalException, SystemException {
236    
237                    // Child layouts
238    
239                    List<Layout> childLayouts = layoutPersistence.findByG_P_P(
240                            layout.getGroupId(), layout.isPrivateLayout(),
241                            layout.getLayoutId());
242    
243                    for (Layout childLayout : childLayouts) {
244                            deleteLayout(childLayout, updateLayoutSet);
245                    }
246    
247                    // Portlet preferences
248    
249                    portletPreferencesLocalService.deletePortletPreferences(
250                            PortletKeys.PREFS_OWNER_ID_DEFAULT,
251                            PortletKeys.PREFS_OWNER_TYPE_LAYOUT, layout.getPlid());
252    
253                    // Tasks
254    
255                    tasksProposalLocalService.deleteProposal(
256                            Layout.class.getName(), String.valueOf(layout.getPlid()));
257    
258                    // Ratings
259    
260                    ratingsStatsLocalService.deleteStats(
261                            Layout.class.getName(), layout.getPlid());
262    
263                    // Message boards
264    
265                    mbMessageLocalService.deleteDiscussionMessages(
266                            Layout.class.getName(), layout.getPlid());
267    
268                    // Journal content searches
269    
270                    journalContentSearchLocalService.deleteLayoutContentSearches(
271                            layout.getGroupId(), layout.isPrivateLayout(),
272                            layout.getLayoutId());
273    
274                    // Expando
275    
276                    expandoValueLocalService.deleteValues(
277                            Layout.class.getName(), layout.getPlid());
278    
279                    // Icon
280    
281                    imageLocalService.deleteImage(layout.getIconImageId());
282    
283                    // Scope group
284    
285                    Group scopeGroup = layout.getScopeGroup();
286    
287                    if (scopeGroup != null) {
288                            groupLocalService.deleteGroup(scopeGroup.getGroupId());
289                    }
290    
291                    // Resources
292    
293                    String primKey =
294                            layout.getPlid() + PortletConstants.LAYOUT_SEPARATOR + "%";
295    
296                    List<Resource> resources = resourceFinder.findByC_P(
297                            layout.getCompanyId(), primKey);
298    
299                    for (Resource resource : resources) {
300                            resourceLocalService.deleteResource(resource);
301                    }
302    
303                    resourceLocalService.deleteResource(
304                            layout.getCompanyId(), Layout.class.getName(),
305                            ResourceConstants.SCOPE_INDIVIDUAL, layout.getPlid());
306    
307                    // Layout
308    
309                    layoutPersistence.remove(layout);
310    
311                    // Layout set
312    
313                    if (updateLayoutSet) {
314                            layoutSetLocalService.updatePageCount(
315                                    layout.getGroupId(), layout.isPrivateLayout());
316                    }
317            }
318    
319            public void deleteLayout(long plid)
320                    throws PortalException, SystemException {
321    
322                    Layout layout = layoutPersistence.findByPrimaryKey(plid);
323    
324                    deleteLayout(layout, true);
325            }
326    
327            public void deleteLayout(long groupId, boolean privateLayout, long layoutId)
328                    throws PortalException, SystemException {
329    
330                    Layout layout = layoutPersistence.findByG_P_L(
331                            groupId, privateLayout, layoutId);
332    
333                    deleteLayout(layout, true);
334            }
335    
336            public void deleteLayouts(long groupId, boolean privateLayout)
337                    throws PortalException, SystemException {
338    
339                    // Layouts
340    
341                    List<Layout> layouts = layoutPersistence.findByG_P_P(
342                            groupId, privateLayout, LayoutConstants.DEFAULT_PARENT_LAYOUT_ID);
343    
344                    for (Layout layout : layouts) {
345                            try {
346                                    deleteLayout(layout, false);
347                            }
348                            catch (NoSuchLayoutException nsle) {
349                            }
350                    }
351    
352                    // Layout set
353    
354                    layoutSetLocalService.updatePageCount(groupId, privateLayout);
355    
356                    // Counter
357    
358                    counterLocalService.reset(getCounterName(groupId, privateLayout));
359            }
360    
361            public byte[] exportLayouts(
362                            long groupId, boolean privateLayout, long[] layoutIds,
363                            Map<String, String[]> parameterMap, Date startDate, Date endDate)
364                    throws PortalException, SystemException {
365    
366                    File file = exportLayoutsAsFile(
367                            groupId, privateLayout, layoutIds, parameterMap, startDate,
368                            endDate);
369    
370                    try {
371                            return FileUtil.getBytes(file);
372                    }
373                    catch (IOException ioe) {
374                            throw new SystemException(ioe);
375                    }
376                    finally {
377                            file.delete();
378                    }
379            }
380    
381            public byte[] exportLayouts(
382                            long groupId, boolean privateLayout,
383                            Map<String, String[]> parameterMap, Date startDate, Date endDate)
384                    throws PortalException, SystemException {
385    
386                    return exportLayouts(
387                            groupId, privateLayout, null, parameterMap, startDate, endDate);
388            }
389    
390            public File exportLayoutsAsFile(
391                            long groupId, boolean privateLayout, long[] layoutIds,
392                            Map<String, String[]> parameterMap, Date startDate, Date endDate)
393                    throws PortalException, SystemException {
394    
395                    try {
396                            LayoutExporter layoutExporter = new LayoutExporter();
397    
398                            return layoutExporter.exportLayoutsAsFile(
399                                    groupId, privateLayout, layoutIds, parameterMap, startDate,
400                                    endDate);
401                    }
402                    catch (PortalException pe) {
403                            throw pe;
404                    }
405                    catch (SystemException se) {
406                            throw se;
407                    }
408                    catch (Exception e) {
409                            throw new SystemException(e);
410                    }
411            }
412    
413            public byte[] exportPortletInfo(
414                            long plid, long groupId, String portletId,
415                            Map<String, String[]> parameterMap, Date startDate, Date endDate)
416                    throws PortalException, SystemException {
417    
418                    File file = exportPortletInfoAsFile(
419                            plid, groupId, portletId, parameterMap, startDate, endDate);
420    
421                    try {
422                            return FileUtil.getBytes(file);
423                    }
424                    catch (IOException ioe) {
425                            throw new SystemException(ioe);
426                    }
427                    finally {
428                            file.delete();
429                    }
430            }
431    
432            public File exportPortletInfoAsFile(
433                            long plid, long groupId, String portletId,
434                            Map<String, String[]> parameterMap, Date startDate, Date endDate)
435                    throws PortalException, SystemException {
436    
437                    try {
438                            PortletExporter portletExporter = new PortletExporter();
439    
440                            return portletExporter.exportPortletInfoAsFile(
441                                    plid, groupId, portletId, parameterMap, startDate, endDate);
442                    }
443                    catch (PortalException pe) {
444                            throw pe;
445                    }
446                    catch (SystemException se) {
447                            throw se;
448                    }
449                    catch (Exception e) {
450                            throw new SystemException(e);
451                    }
452            }
453    
454            public long getDefaultPlid(long groupId) throws SystemException {
455                    if (groupId > 0) {
456                            List<Layout> layouts = layoutPersistence.findByGroupId(
457                                    groupId, 0, 1);
458    
459                            if (layouts.size() > 0) {
460                                    Layout layout = layouts.get(0);
461    
462                                    return layout.getPlid();
463                            }
464                    }
465    
466                    return LayoutConstants.DEFAULT_PLID;
467            }
468    
469            public long getDefaultPlid(long groupId, boolean privateLayout)
470                    throws SystemException {
471    
472                    if (groupId > 0) {
473                            List<Layout> layouts = layoutPersistence.findByG_P(
474                                    groupId, privateLayout, 0, 1);
475    
476                            if (layouts.size() > 0) {
477                                    Layout layout = layouts.get(0);
478    
479                                    return layout.getPlid();
480                            }
481                    }
482    
483                    return LayoutConstants.DEFAULT_PLID;
484            }
485    
486            public long getDefaultPlid(
487                            long groupId, boolean privateLayout, String portletId)
488                    throws PortalException, SystemException {
489    
490                    if (groupId > 0) {
491                            List<Layout> layouts = layoutPersistence.findByG_P(
492                                    groupId, privateLayout);
493    
494                            for (Layout layout : layouts) {
495                                    if (layout.isTypePortlet()) {
496                                            LayoutTypePortlet layoutTypePortlet =
497                                                    (LayoutTypePortlet)layout.getLayoutType();
498    
499                                            if (layoutTypePortlet.hasPortletId(portletId)) {
500                                                    return layout.getPlid();
501                                            }
502                                    }
503                            }
504                    }
505    
506                    return LayoutConstants.DEFAULT_PLID;
507            }
508    
509            public Layout getDLFolderLayout(long dlFolderId)
510                    throws PortalException, SystemException {
511    
512                    return layoutPersistence.findByDLFolderId(dlFolderId);
513            }
514    
515            public Layout getFriendlyURLLayout(
516                            long groupId, boolean privateLayout, String friendlyURL)
517                    throws PortalException, SystemException {
518    
519                    if (Validator.isNull(friendlyURL)) {
520                            throw new NoSuchLayoutException();
521                    }
522    
523                    friendlyURL = getFriendlyURL(friendlyURL);
524    
525                    Layout layout = layoutPersistence.fetchByG_P_F(
526                            groupId, privateLayout, friendlyURL);
527    
528                    if ((layout == null) &&
529                            (friendlyURL.startsWith(StringPool.SLASH))) {
530    
531                            long layoutId = GetterUtil.getLong(friendlyURL.substring(1));
532    
533                            layout = layoutPersistence.fetchByG_P_L(
534                                    groupId, privateLayout, layoutId);
535                    }
536    
537                    if (layout == null) {
538                            throw new NoSuchLayoutException();
539                    }
540    
541                    return layout;
542            }
543    
544            public Layout getLayout(long plid)
545                    throws PortalException, SystemException {
546    
547                    return layoutPersistence.findByPrimaryKey(plid);
548            }
549    
550            public Layout getLayout(long groupId, boolean privateLayout, long layoutId)
551                    throws PortalException, SystemException {
552    
553                    return layoutPersistence.findByG_P_L(groupId, privateLayout, layoutId);
554            }
555    
556            public Layout getLayoutByIconImageId(long iconImageId)
557                    throws PortalException, SystemException {
558    
559                    return layoutPersistence.findByIconImageId(iconImageId);
560            }
561    
562            public Layout getLayoutByUuidAndGroupId(String uuid, long groupId)
563                    throws PortalException, SystemException {
564    
565                    return layoutPersistence.findByUUID_G(uuid, groupId);
566            }
567    
568            public List<Layout> getLayouts(long groupId, boolean privateLayout)
569                    throws SystemException {
570    
571                    return layoutPersistence.findByG_P(groupId, privateLayout);
572            }
573    
574            public List<Layout> getLayouts(
575                            long groupId, boolean privateLayout, long parentLayoutId)
576                    throws SystemException {
577    
578                    return layoutPersistence.findByG_P_P(
579                            groupId, privateLayout, parentLayoutId);
580            }
581    
582            public List<Layout> getLayouts(
583                            long groupId, boolean privateLayout, long parentLayoutId, int start,
584                            int end)
585                    throws SystemException {
586    
587                    return layoutPersistence.findByG_P_P(
588                            groupId, privateLayout, parentLayoutId, start, end);
589            }
590    
591            public List<Layout> getLayouts(
592                            long groupId, boolean privateLayout, long[] layoutIds)
593                    throws PortalException, SystemException {
594    
595                    List<Layout> layouts = new ArrayList<Layout>();
596    
597                    for (long layoutId : layoutIds) {
598                            Layout layout = getLayout(groupId, privateLayout, layoutId);
599    
600                            layouts.add(layout);
601                    }
602    
603                    return layouts;
604            }
605    
606            public List<Layout> getLayouts(
607                            long groupId, boolean privateLayout, String type)
608                    throws SystemException {
609    
610                    return layoutPersistence.findByG_P_T(groupId, privateLayout, type);
611            }
612    
613            public LayoutReference[] getLayouts(
614                            long companyId, String portletId, String preferencesKey,
615                            String preferencesValue)
616                    throws SystemException {
617    
618                    List<LayoutReference> layoutReferences = layoutFinder.findByC_P_P(
619                            companyId, portletId, preferencesKey, preferencesValue);
620    
621                    return layoutReferences.toArray(
622                            new LayoutReference[layoutReferences.size()]);
623            }
624    
625            public long getNextLayoutId(long groupId, boolean privateLayout)
626                    throws SystemException {
627    
628                    long nextLayoutId = counterLocalService.increment(
629                            getCounterName(groupId, privateLayout));
630    
631                    if (nextLayoutId == 1) {
632                            List<Layout> layouts = layoutPersistence.findByG_P(
633                                    groupId, privateLayout, 0, 1, new LayoutComparator());
634    
635                            if (!layouts.isEmpty()) {
636                                    Layout layout = layouts.get(0);
637    
638                                    nextLayoutId = layout.getLayoutId() + 1;
639    
640                                    counterLocalService.reset(
641                                            getCounterName(groupId, privateLayout), nextLayoutId);
642                            }
643                    }
644    
645                    return nextLayoutId;
646            }
647    
648            public List<Layout> getNullFriendlyURLLayouts() throws SystemException {
649                    return layoutFinder.findByNullFriendlyURL();
650            }
651    
652            public boolean hasLayouts(
653                            long groupId, boolean privateLayout, long parentLayoutId)
654                    throws SystemException {
655    
656                    return layoutPersistence.countByG_P_P(
657                            groupId, privateLayout, parentLayoutId) > 0;
658            }
659    
660            public void importLayouts(
661                            long userId, long groupId, boolean privateLayout,
662                            Map<String, String[]> parameterMap, byte[] bytes)
663                    throws PortalException, SystemException {
664    
665                    importLayouts(
666                            userId, groupId, privateLayout, parameterMap,
667                            new UnsyncByteArrayInputStream(bytes));
668            }
669    
670            public void importLayouts(
671                            long userId, long groupId, boolean privateLayout,
672                            Map<String, String[]> parameterMap, File file)
673                    throws PortalException, SystemException {
674    
675                    BatchSessionUtil.setEnabled(true);
676    
677                    try {
678                            LayoutImporter layoutImporter = new LayoutImporter();
679    
680                            layoutImporter.importLayouts(
681                                    userId, groupId, privateLayout, parameterMap, file);
682                    }
683                    catch (PortalException pe) {
684                            throw pe;
685                    }
686                    catch (SystemException se) {
687                            throw se;
688                    }
689                    catch (Exception e) {
690                            throw new SystemException(e);
691                    }
692                    finally {
693                            BatchSessionUtil.setEnabled(false);
694                    }
695            }
696    
697            public void importLayouts(
698                            long userId, long groupId, boolean privateLayout,
699                            Map<String, String[]> parameterMap, InputStream is)
700                    throws PortalException, SystemException {
701    
702                    try {
703                            File file = FileUtil.createTempFile("lar");
704    
705                            FileUtil.write(file, is);
706    
707                            importLayouts(userId, groupId, privateLayout, parameterMap, file);
708                    }
709                    catch (IOException e) {
710                            throw new SystemException(e);
711                    }
712            }
713    
714            public void importPortletInfo(
715                            long userId, long plid, long groupId, String portletId,
716                            Map<String, String[]> parameterMap, File file)
717                    throws PortalException, SystemException {
718    
719                    BatchSessionUtil.setEnabled(true);
720    
721                    try {
722                            PortletImporter portletImporter = new PortletImporter();
723    
724                            portletImporter.importPortletInfo(
725                                    userId, plid, groupId, portletId, parameterMap, file);
726                    }
727                    finally {
728                            BatchSessionUtil.setEnabled(false);
729                    }
730            }
731    
732            public void importPortletInfo(
733                            long userId, long plid, long groupId, String portletId,
734                            Map<String, String[]> parameterMap, InputStream is)
735                    throws PortalException, SystemException {
736    
737                    try {
738                            File file = FileUtil.createTempFile("lar");
739    
740                            FileUtil.write(file, is);
741    
742                            importPortletInfo(
743                                    userId, plid, groupId, portletId, parameterMap, file);
744                    }
745                    catch (IOException e) {
746                            throw new SystemException(e);
747                    }
748            }
749    
750            public void setLayouts(
751                            long groupId, boolean privateLayout, long parentLayoutId,
752                            long[] layoutIds)
753                    throws PortalException, SystemException {
754    
755                    if (layoutIds == null) {
756                            return;
757                    }
758    
759                    if (parentLayoutId == LayoutConstants.DEFAULT_PARENT_LAYOUT_ID) {
760                            if (layoutIds.length < 1) {
761                                    throw new RequiredLayoutException(
762                                            RequiredLayoutException.AT_LEAST_ONE);
763                            }
764    
765                            Layout layout = layoutPersistence.findByG_P_L(
766                                    groupId, privateLayout, layoutIds[0]);
767    
768                            if (!PortalUtil.isLayoutFirstPageable(layout.getType())) {
769                                    throw new RequiredLayoutException(
770                                            RequiredLayoutException.FIRST_LAYOUT_TYPE);
771                            }
772    
773                            if (layout.isHidden()) {
774                                    throw new RequiredLayoutException(
775                                            RequiredLayoutException.FIRST_LAYOUT_HIDDEN);
776                            }
777                    }
778    
779                    Set<Long> layoutIdsSet = new LinkedHashSet<Long>();
780    
781                    for (int i = 0; i < layoutIds.length; i++) {
782                            layoutIdsSet.add(layoutIds[i]);
783                    }
784    
785                    Set<Long> newLayoutIdsSet = new HashSet<Long>();
786    
787                    List<Layout> layouts = layoutPersistence.findByG_P_P(
788                            groupId, privateLayout, parentLayoutId);
789    
790                    for (Layout layout : layouts) {
791                            if (!layoutIdsSet.contains(layout.getLayoutId())) {
792                                    deleteLayout(layout, true);
793                            }
794                            else {
795                                    newLayoutIdsSet.add(layout.getLayoutId());
796                            }
797                    }
798    
799                    int priority = 0;
800    
801                    for (long layoutId : layoutIdsSet) {
802                            Layout layout = layoutPersistence.findByG_P_L(
803                                    groupId, privateLayout, layoutId);
804    
805                            layout.setPriority(priority++);
806    
807                            layoutPersistence.update(layout, false);
808                    }
809    
810                    layoutSetLocalService.updatePageCount(groupId, privateLayout);
811            }
812    
813            public Layout updateFriendlyURL(long plid, String friendlyURL)
814                    throws PortalException, SystemException {
815    
816                    Layout layout = layoutPersistence.findByPrimaryKey(plid);
817    
818                    friendlyURL = getFriendlyURL(
819                            layout.getGroupId(), layout.getPrivateLayout(),
820                            layout.getLayoutId(), StringPool.BLANK, friendlyURL);
821    
822                    validateFriendlyURL(
823                            layout.getGroupId(), layout.isPrivateLayout(), layout.getLayoutId(),
824                            friendlyURL);
825    
826                    layout.setFriendlyURL(friendlyURL);
827    
828                    layoutPersistence.update(layout, false);
829    
830                    return layout;
831            }
832    
833            public Layout updateLayout(
834                            long groupId, boolean privateLayout, long layoutId,
835                            long parentLayoutId, Map<Locale, String> localeNamesMap,
836                            Map<Locale, String> localeTitlesMap, String description,
837                            String type, boolean hidden, String friendlyURL, Boolean iconImage,
838                            byte[] iconBytes, ServiceContext serviceContext)
839                    throws PortalException, SystemException {
840    
841                    // Layout
842    
843                    parentLayoutId = getParentLayoutId(
844                            groupId, privateLayout, parentLayoutId);
845                    String name = localeNamesMap.get(LocaleUtil.getDefault());
846                    friendlyURL = getFriendlyURL(
847                            groupId, privateLayout, layoutId, StringPool.BLANK, friendlyURL);
848    
849                    validate(
850                            groupId, privateLayout, layoutId, parentLayoutId, name, type,
851                            hidden, friendlyURL);
852    
853                    validateParentLayoutId(
854                            groupId, privateLayout, layoutId, parentLayoutId);
855    
856                    Layout layout = layoutPersistence.findByG_P_L(
857                            groupId, privateLayout, layoutId);
858    
859                    if (parentLayoutId != layout.getParentLayoutId()) {
860                            layout.setPriority(
861                                    getNextPriority(groupId, privateLayout, parentLayoutId));
862                    }
863    
864                    layout.setParentLayoutId(parentLayoutId);
865                    layout.setDescription(description);
866                    layout.setType(type);
867                    layout.setHidden(hidden);
868                    layout.setFriendlyURL(friendlyURL);
869    
870                    setLocalizedAttributes(layout, localeNamesMap, localeTitlesMap);
871    
872                    if (iconImage != null) {
873                            layout.setIconImage(iconImage.booleanValue());
874    
875                            if (iconImage.booleanValue()) {
876                                    long iconImageId = layout.getIconImageId();
877    
878                                    if (iconImageId <= 0) {
879                                            iconImageId = counterLocalService.increment();
880    
881                                            layout.setIconImageId(iconImageId);
882                                    }
883                            }
884                    }
885    
886                    layoutPersistence.update(layout, false);
887    
888                    // Icon
889    
890                    if (iconImage != null) {
891                            if (!iconImage.booleanValue()) {
892                                    imageLocalService.deleteImage(layout.getIconImageId());
893                            }
894                            else if ((iconBytes != null) && (iconBytes.length > 0)) {
895                                    imageLocalService.updateImage(
896                                            layout.getIconImageId(), iconBytes);
897                            }
898                    }
899    
900                    // Document library
901    
902                    try {
903                            if (layout.getDlFolderId() > 0) {
904                                    DLFolder folder = dlFolderLocalService.getFolder(
905                                            layout.getDlFolderId());
906    
907                                    if (!name.equals(folder.getName())) {
908                                            dlFolderLocalService.updateFolder(
909                                                    folder.getFolderId(), folder.getParentFolderId(), name,
910                                                    folder.getDescription(), new ServiceContext());
911                                    }
912                            }
913                    }
914                    catch (DuplicateFolderNameException dfne) {
915                            if (_log.isDebugEnabled()) {
916                                    _log.debug(dfne);
917                            }
918                    }
919                    catch (NoSuchFolderException nsfe) {
920                    }
921    
922                    // Expando
923    
924                    ExpandoBridge expandoBridge = layout.getExpandoBridge();
925    
926                    expandoBridge.setAttributes(serviceContext);
927    
928                    return layout;
929            }
930    
931            public Layout updateLayout(
932                            long groupId, boolean privateLayout, long layoutId,
933                            long parentLayoutId, Map<Locale, String> localeNamesMap,
934                            Map<Locale, String> localeTitlesMap, String description,
935                            String type, boolean hidden, String friendlyURL,
936                            ServiceContext serviceContext)
937                    throws PortalException, SystemException {
938    
939                    return updateLayout(
940                            groupId, privateLayout, layoutId, parentLayoutId, localeNamesMap,
941                            localeTitlesMap, description, type, hidden, friendlyURL, null,
942                            null, serviceContext);
943            }
944    
945            public Layout updateLayout(
946                            long groupId, boolean privateLayout, long layoutId,
947                            String typeSettings)
948                    throws PortalException, SystemException {
949    
950                    Layout layout = layoutPersistence.findByG_P_L(
951                            groupId, privateLayout, layoutId);
952    
953                    layout.setTypeSettings(typeSettings);
954    
955                    layoutPersistence.update(layout, false);
956    
957                    return layout;
958            }
959    
960            public Layout updateLookAndFeel(
961                            long groupId, boolean privateLayout, long layoutId, String themeId,
962                            String colorSchemeId, String css, boolean wapTheme)
963                    throws PortalException, SystemException {
964    
965                    Layout layout = layoutPersistence.findByG_P_L(
966                            groupId, privateLayout, layoutId);
967    
968                    if (wapTheme) {
969                            layout.setWapThemeId(themeId);
970                            layout.setWapColorSchemeId(colorSchemeId);
971                    }
972                    else {
973                            layout.setThemeId(themeId);
974                            layout.setColorSchemeId(colorSchemeId);
975                            layout.setCss(css);
976                    }
977    
978                    layoutPersistence.update(layout, false);
979    
980                    return layout;
981            }
982    
983            public Layout updateName(Layout layout, String name, String languageId)
984                    throws PortalException, SystemException {
985    
986                    validateName(name, languageId);
987    
988                    layout.setName(name, LocaleUtil.fromLanguageId(languageId));
989    
990                    layoutPersistence.update(layout, false);
991    
992                    try {
993                            if (layout.getDlFolderId() > 0) {
994                                    DLFolder folder = dlFolderLocalService.getFolder(
995                                            layout.getDlFolderId());
996    
997                                    ServiceContext serviceContext = new ServiceContext();
998    
999                                    dlFolderLocalService.updateFolder(
1000                                            folder.getFolderId(), folder.getParentFolderId(),
1001                                            layout.getName(LocaleUtil.getDefault()),
1002                                            folder.getDescription(), serviceContext);
1003                            }
1004                    }
1005                    catch (NoSuchFolderException nsfe) {
1006                    }
1007    
1008                    return layout;
1009            }
1010    
1011            public Layout updateName(
1012                            long groupId, boolean privateLayout, long layoutId, String name,
1013                            String languageId)
1014                    throws PortalException, SystemException {
1015    
1016                    Layout layout = layoutPersistence.findByG_P_L(
1017                            groupId, privateLayout, layoutId);
1018    
1019                    return updateName(layout, name, languageId);
1020            }
1021    
1022            public Layout updateName(long plid, String name, String languageId)
1023                    throws PortalException, SystemException {
1024    
1025                    Layout layout = layoutPersistence.findByPrimaryKey(plid);
1026    
1027                    return updateName(layout, name, languageId);
1028            }
1029    
1030            public Layout updateParentLayoutId(
1031                            long groupId, boolean privateLayout, long layoutId,
1032                            long parentLayoutId)
1033                    throws PortalException, SystemException {
1034    
1035                    parentLayoutId = getParentLayoutId(
1036                            groupId, privateLayout, parentLayoutId);
1037    
1038                    validateParentLayoutId(
1039                            groupId, privateLayout, layoutId, parentLayoutId);
1040    
1041                    Layout layout = layoutPersistence.findByG_P_L(
1042                            groupId, privateLayout, layoutId);
1043    
1044                    if (parentLayoutId != layout.getParentLayoutId()) {
1045                            layout.setPriority(
1046                                    getNextPriority(groupId, privateLayout, parentLayoutId));
1047                    }
1048    
1049                    layout.setParentLayoutId(parentLayoutId);
1050    
1051                    layoutPersistence.update(layout, false);
1052    
1053                    return layout;
1054            }
1055    
1056            public Layout updateParentLayoutId(long plid, long parentPlid)
1057                    throws PortalException, SystemException {
1058    
1059                    Layout layout = layoutPersistence.findByPrimaryKey(plid);
1060    
1061                    long parentLayoutId = LayoutConstants.DEFAULT_PARENT_LAYOUT_ID;
1062    
1063                    if (parentPlid > 0) {
1064                            Layout parentLayout = layoutPersistence.fetchByPrimaryKey(
1065                                    parentPlid);
1066    
1067                            if (parentLayout != null) {
1068                                    parentLayoutId = parentLayout.getLayoutId();
1069                            }
1070                    }
1071    
1072                    parentLayoutId = getParentLayoutId(
1073                            layout.getGroupId(), layout.isPrivateLayout(), parentLayoutId);
1074    
1075                    validateParentLayoutId(
1076                            layout.getGroupId(), layout.isPrivateLayout(), layout.getLayoutId(),
1077                            parentLayoutId);
1078    
1079                    if (parentLayoutId != layout.getParentLayoutId()) {
1080                            int priority = getNextPriority(
1081                                    layout.getGroupId(), layout.isPrivateLayout(), parentLayoutId);
1082    
1083                            layout.setPriority(priority);
1084                    }
1085    
1086                    layout.setParentLayoutId(parentLayoutId);
1087    
1088                    layoutPersistence.update(layout, false);
1089    
1090                    return layout;
1091            }
1092    
1093            public Layout updatePriority(Layout layout, int priority)
1094                    throws SystemException {
1095    
1096                    if (layout.getPriority() == priority) {
1097                            return layout;
1098                    }
1099    
1100                    boolean lessThan = false;
1101    
1102                    if (layout.getPriority() < priority) {
1103                            lessThan = true;
1104                    }
1105    
1106                    layout.setPriority(priority);
1107    
1108                    layoutPersistence.update(layout, false);
1109    
1110                    priority = 0;
1111    
1112                    List<Layout> layouts = layoutPersistence.findByG_P_P(
1113                            layout.getGroupId(), layout.isPrivateLayout(),
1114                            layout.getParentLayoutId());
1115    
1116                    layouts = ListUtil.sort(
1117                            layouts, new LayoutPriorityComparator(layout, lessThan));
1118    
1119                    for (Layout curLayout : layouts) {
1120                            curLayout.setPriority(priority++);
1121    
1122                            layoutPersistence.update(curLayout, false);
1123    
1124                            if (curLayout.equals(layout)) {
1125                                    layout = curLayout;
1126                            }
1127                    }
1128    
1129                    return layout;
1130            }
1131    
1132            public Layout updatePriority(
1133                            long groupId, boolean privateLayout, long layoutId, int priority)
1134                    throws PortalException, SystemException {
1135    
1136                    Layout layout = layoutPersistence.findByG_P_L(
1137                            groupId, privateLayout, layoutId);
1138    
1139                    return updatePriority(layout, priority);
1140            }
1141    
1142            public Layout updatePriority(long plid, int priority)
1143                    throws PortalException, SystemException {
1144    
1145                    Layout layout = layoutPersistence.findByPrimaryKey(plid);
1146    
1147                    return updatePriority(layout, priority);
1148            }
1149    
1150            protected String getFriendlyURL(
1151                            long groupId, boolean privateLayout, long layoutId,
1152                            String name, String friendlyURL)
1153                    throws PortalException, SystemException {
1154    
1155                    friendlyURL = getFriendlyURL(friendlyURL);
1156    
1157                    if (Validator.isNull(friendlyURL)) {
1158                            friendlyURL = StringPool.SLASH + getFriendlyURL(name);
1159    
1160                            String originalFriendlyURL = friendlyURL;
1161    
1162                            for (int i = 1;; i++) {
1163                                    try {
1164                                            validateFriendlyURL(
1165                                                    groupId, privateLayout, layoutId, friendlyURL);
1166    
1167                                            break;
1168                                    }
1169                                    catch (LayoutFriendlyURLException lfurle) {
1170                                            int type = lfurle.getType();
1171    
1172                                            if (type == LayoutFriendlyURLException.DUPLICATE) {
1173                                                    friendlyURL = originalFriendlyURL + i;
1174                                            }
1175                                            else {
1176                                                    friendlyURL = StringPool.SLASH + layoutId;
1177    
1178                                                    break;
1179                                            }
1180                                    }
1181                            }
1182                    }
1183    
1184                    return friendlyURL;
1185            }
1186    
1187            protected String getFriendlyURL(String friendlyURL) {
1188                    return FriendlyURLNormalizer.normalize(friendlyURL);
1189            }
1190    
1191            protected int getNextPriority(
1192                            long groupId, boolean privateLayout, long parentLayoutId)
1193                    throws SystemException {
1194    
1195                    List<Layout> layouts = layoutPersistence.findByG_P_P(
1196                            groupId, privateLayout, parentLayoutId);
1197    
1198                    if (layouts.size() == 0) {
1199                            return 0;
1200                    }
1201    
1202                    Layout layout = layouts.get(layouts.size() - 1);
1203    
1204                    return layout.getPriority() + 1;
1205            }
1206    
1207            protected long getParentLayoutId(
1208                            long groupId, boolean privateLayout, long parentLayoutId)
1209                    throws SystemException {
1210    
1211                    if (parentLayoutId != LayoutConstants.DEFAULT_PARENT_LAYOUT_ID) {
1212    
1213                            // Ensure parent layout exists
1214    
1215                            Layout parentLayout = layoutPersistence.fetchByG_P_L(
1216                                    groupId, privateLayout, parentLayoutId);
1217    
1218                            if (parentLayout == null) {
1219                                    parentLayoutId = LayoutConstants.DEFAULT_PARENT_LAYOUT_ID;
1220                            }
1221                    }
1222    
1223                    return parentLayoutId;
1224            }
1225    
1226            protected boolean isDescendant(Layout layout, long layoutId)
1227                    throws PortalException, SystemException {
1228    
1229                    if (layout.getLayoutId() == layoutId) {
1230                            return true;
1231                    }
1232                    else {
1233                            for (Layout childLayout : layout.getChildren()) {
1234                                    if (isDescendant(childLayout, layoutId)) {
1235                                            return true;
1236                                    }
1237                            }
1238    
1239                            return false;
1240                    }
1241            }
1242    
1243            protected void setLocalizedAttributes(
1244                    Layout layout, Map<Locale, String> localeNamesMap,
1245                    Map<Locale, String> localeTitlesMap) {
1246    
1247                    if (localeNamesMap == null) {
1248                            return;
1249                    }
1250    
1251                    if (localeTitlesMap == null) {
1252                            return;
1253                    }
1254    
1255                    Locale[] locales = LanguageUtil.getAvailableLocales();
1256    
1257                    for (Locale locale : locales) {
1258                            String name = localeNamesMap.get(locale);
1259                            String title = localeTitlesMap.get(locale);
1260    
1261                            layout.setName(name, locale);
1262                            layout.setTitle(title, locale);
1263                    }
1264            }
1265    
1266            protected void validate(
1267                            long groupId, boolean privateLayout, long layoutId,
1268                            long parentLayoutId, String name, String type, boolean hidden,
1269                            String friendlyURL)
1270                    throws PortalException, SystemException {
1271    
1272                    validateName(name);
1273    
1274                    boolean firstLayout = false;
1275    
1276                    if (parentLayoutId == LayoutConstants.DEFAULT_PARENT_LAYOUT_ID) {
1277                            List<Layout> layouts = layoutPersistence.findByG_P_P(
1278                                    groupId, privateLayout, parentLayoutId, 0, 1);
1279    
1280                            if (layouts.size() == 0) {
1281                                    firstLayout = true;
1282                            }
1283                            else {
1284                                    long firstLayoutId = layouts.get(0).getLayoutId();
1285    
1286                                    if (firstLayoutId == layoutId) {
1287                                            firstLayout = true;
1288                                    }
1289                            }
1290                    }
1291    
1292                    if (firstLayout) {
1293                            validateFirstLayout(type, hidden);
1294                    }
1295    
1296                    if (!PortalUtil.isLayoutParentable(type)) {
1297                            if (layoutPersistence.countByG_P_P(
1298                                            groupId, privateLayout, layoutId) > 0) {
1299    
1300                                    throw new LayoutTypeException(
1301                                            LayoutTypeException.NOT_PARENTABLE);
1302                            }
1303                    }
1304    
1305                    validateFriendlyURL(groupId, privateLayout, layoutId, friendlyURL);
1306            }
1307    
1308            protected void validateFirstLayout(String type, boolean hidden)
1309                    throws PortalException {
1310    
1311                    if (!PortalUtil.isLayoutFirstPageable(type)) {
1312                            throw new LayoutTypeException(LayoutTypeException.FIRST_LAYOUT);
1313                    }
1314    
1315                    if (hidden) {
1316                            throw new LayoutHiddenException();
1317                    }
1318            }
1319    
1320            protected void validateFriendlyURL(
1321                            long groupId, boolean privateLayout, long layoutId,
1322                            String friendlyURL)
1323                    throws PortalException, SystemException {
1324    
1325                    if (Validator.isNull(friendlyURL)) {
1326                            return;
1327                    }
1328    
1329                    int exceptionType = LayoutImpl.validateFriendlyURL(friendlyURL);
1330    
1331                    if (exceptionType != -1) {
1332                            throw new LayoutFriendlyURLException(exceptionType);
1333                    }
1334    
1335                    Layout layout = layoutPersistence.fetchByG_P_F(
1336                            groupId, privateLayout, friendlyURL);
1337    
1338                    if ((layout != null) && (layout.getLayoutId() != layoutId)) {
1339                            throw new LayoutFriendlyURLException(
1340                                    LayoutFriendlyURLException.DUPLICATE);
1341                    }
1342    
1343                    LayoutImpl.validateFriendlyURLKeyword(friendlyURL);
1344    
1345                    /*List<FriendlyURLMapper> friendlyURLMappers =
1346                            portletLocalService.getFriendlyURLMappers();
1347    
1348                    for (FriendlyURLMapper friendlyURLMapper : friendlyURLMappers) {
1349                            if (friendlyURL.indexOf(friendlyURLMapper.getMapping()) != -1) {
1350                                    LayoutFriendlyURLException lfurle =
1351                                            new LayoutFriendlyURLException(
1352                                                    LayoutFriendlyURLException.KEYWORD_CONFLICT);
1353    
1354                                    lfurle.setKeywordConflict(friendlyURLMapper.getMapping());
1355    
1356                                    throw lfurle;
1357                            }
1358                    }*/
1359    
1360                    String layoutIdFriendlyURL = friendlyURL.substring(1);
1361    
1362                    if (Validator.isNumber(layoutIdFriendlyURL) &&
1363                            !layoutIdFriendlyURL.equals(String.valueOf(layoutId))) {
1364    
1365                            LayoutFriendlyURLException lfurle = new LayoutFriendlyURLException(
1366                                    LayoutFriendlyURLException.POSSIBLE_DUPLICATE);
1367    
1368                            lfurle.setKeywordConflict(layoutIdFriendlyURL);
1369    
1370                            throw lfurle;
1371                    }
1372            }
1373    
1374            protected void validateName(String name) throws PortalException {
1375                    if (Validator.isNull(name)) {
1376                            throw new LayoutNameException();
1377                    }
1378            }
1379    
1380            protected void validateName(String name, String languageId)
1381                    throws PortalException {
1382    
1383                    String defaultLanguageId = LocaleUtil.toLanguageId(
1384                            LocaleUtil.getDefault());
1385    
1386                    if (defaultLanguageId.equals(languageId)) {
1387                            validateName(name);
1388                    }
1389            }
1390    
1391            protected void validateParentLayoutId(
1392                            long groupId, boolean privateLayout, long layoutId,
1393                            long parentLayoutId)
1394                    throws PortalException, SystemException {
1395    
1396                    Layout layout = layoutPersistence.findByG_P_L(
1397                            groupId, privateLayout, layoutId);
1398    
1399                    if (parentLayoutId != layout.getParentLayoutId()) {
1400    
1401                            // Layouts can always be moved to the root level
1402    
1403                            if (parentLayoutId == LayoutConstants.DEFAULT_PARENT_LAYOUT_ID) {
1404                                    return;
1405                            }
1406    
1407                            // Layout cannot become a child of a layout that is not parentable
1408    
1409                            Layout parentLayout = layoutPersistence.findByG_P_L(
1410                                    groupId, privateLayout, parentLayoutId);
1411    
1412                            if (!PortalUtil.isLayoutParentable(parentLayout)) {
1413                                    throw new LayoutParentLayoutIdException(
1414                                            LayoutParentLayoutIdException.NOT_PARENTABLE);
1415                            }
1416    
1417                            // Layout cannot become descendant of itself
1418    
1419                            if (isDescendant(layout, parentLayoutId)) {
1420                                    throw new LayoutParentLayoutIdException(
1421                                            LayoutParentLayoutIdException.SELF_DESCENDANT);
1422                            }
1423    
1424                            // If layout is moved, the new first layout must be valid
1425    
1426                            if (layout.getParentLayoutId() ==
1427                                            LayoutConstants.DEFAULT_PARENT_LAYOUT_ID) {
1428    
1429                                    List<Layout> layouts = layoutPersistence.findByG_P_P(
1430                                            groupId, privateLayout,
1431                                            LayoutConstants.DEFAULT_PARENT_LAYOUT_ID, 0, 2);
1432    
1433                                    // You can only reach this point if there are more than two
1434                                    // layouts at the root level because of the descendant check
1435    
1436                                    long firstLayoutId = layouts.get(0).getLayoutId();
1437    
1438                                    if (firstLayoutId == layoutId) {
1439                                            Layout secondLayout = layouts.get(1);
1440    
1441                                            try {
1442                                                    validateFirstLayout(
1443                                                            secondLayout.getType(), secondLayout.getHidden());
1444                                            }
1445                                            catch (LayoutHiddenException lhe) {
1446                                                    throw new LayoutParentLayoutIdException(
1447                                                            LayoutParentLayoutIdException.FIRST_LAYOUT_HIDDEN);
1448                                            }
1449                                            catch (LayoutTypeException lte) {
1450                                                    throw new LayoutParentLayoutIdException(
1451                                                            LayoutParentLayoutIdException.FIRST_LAYOUT_TYPE);
1452                                            }
1453                                    }
1454                            }
1455                    }
1456            }
1457    
1458            private static Log _log = LogFactoryUtil.getLog(
1459                    LayoutLocalServiceImpl.class);
1460    
1461    }